SMACC
Loading...
Searching...
No Matches
cb_circular_pivot_motion.cpp
Go to the documentation of this file.
1/*****************************************************************************************************************
2 * ReelRobotix Inc. - Software License Agreement Copyright (c) 2018-2020
3 * Authors: Pablo Inigo Blasco, Brett Aldrich
4 *
5 ******************************************************************************************************************/
6
8
10{
13 {
14 }
15
16 CbCircularPivotMotion::CbCircularPivotMotion(const geometry_msgs::PoseStamped &planePivotPose, double deltaRadians, std::string tipLink)
17 : planePivotPose_(planePivotPose), deltaRadians_(deltaRadians), CbMoveEndEffectorTrajectory(tipLink)
18 {
19 }
20
21 CbCircularPivotMotion::CbCircularPivotMotion(const geometry_msgs::PoseStamped &planePivotPose, const geometry_msgs::Pose &relativeInitialPose, double deltaRadians, std::string tipLink)
22 : planePivotPose_(planePivotPose), relativeInitialPose_(relativeInitialPose), deltaRadians_(deltaRadians), CbMoveEndEffectorTrajectory(tipLink)
23 {
24 }
25
27 {
29 {
31 }
32
33 // project offset into the xy-plane
34 // get the radius
35 double radius = sqrt(relativeInitialPose_->position.z * relativeInitialPose_->position.z + relativeInitialPose_->position.y * relativeInitialPose_->position.y);
36 double initialAngle = atan2(relativeInitialPose_->position.z, relativeInitialPose_->position.y);
37
38 double totallineardist = fabs(radius * deltaRadians_);
39 double totalangulardist = fabs(deltaRadians_);
40
41 // at least 1 sample per centimeter (average)
42 // at least 1 sample per ~1.1 degrees (average)
43
44 const double RADS_PER_SAMPLE = 0.02;
45 const double METERS_PER_SAMPLE = 0.01;
46
47 int totalSamplesCount = std::max(totallineardist / METERS_PER_SAMPLE, totalangulardist / RADS_PER_SAMPLE);
48
49 double linearSecondsPerSample;
50 double angularSecondsPerSamples;
51 double secondsPerSample;
52
54 {
55 linearSecondsPerSample = METERS_PER_SAMPLE / (*linearSpeed_m_s_);
56 }
57 else
58 {
59 linearSecondsPerSample = std::numeric_limits<double>::max();
60 }
61
63 {
64 angularSecondsPerSamples = RADS_PER_SAMPLE / (*angularSpeed_rad_s_);
65 }
66 else
67 {
68 angularSecondsPerSamples = std::numeric_limits<double>::max();
69 }
70
72 {
73 secondsPerSample = 0.5;
74 }
75 else
76 {
77 secondsPerSample = std::min(linearSecondsPerSample, angularSecondsPerSamples);
78 }
79
80 double currentAngle = initialAngle;
81
82 double angleStep = deltaRadians_ / (double)totalSamplesCount;
83
84 tf::Transform tfBasePose;
85 tf::poseMsgToTF(planePivotPose_.pose, tfBasePose);
86
87 for (int i = 0; i < totalSamplesCount; i++)
88 {
89 // relativePose i
90 currentAngle += angleStep;
91 double y = radius * cos(currentAngle);
92 double z = radius * sin(currentAngle);
93
94 geometry_msgs::Pose relativeCurrentPose;
95
96 relativeCurrentPose.position.x = relativeInitialPose_->position.x;
97 relativeCurrentPose.position.y = y;
98 relativeCurrentPose.position.z = z;
99
100 auto localquat = tf::createQuaternionFromRPY(currentAngle, 0, 0);
101 //relativeCurrentPose.orientation = relativeInitialPose_.orientation;
102 //tf::quaternionTFToMsg(localquat, relativeCurrentPose.orientation);
103 relativeCurrentPose.orientation.w = 1;
104
105 tf::Transform tfRelativeCurrentPose;
106 tf::poseMsgToTF(relativeCurrentPose, tfRelativeCurrentPose);
107
108 tf::Transform tfGlobalPose = tfRelativeCurrentPose * tfBasePose;
109
110 tfGlobalPose.setRotation(tfGlobalPose.getRotation() * localquat);
111
112 geometry_msgs::PoseStamped globalPose;
113 tf::poseTFToMsg(tfGlobalPose, globalPose.pose);
114 globalPose.header.frame_id = planePivotPose_.header.frame_id;
115 globalPose.header.stamp = planePivotPose_.header.stamp + ros::Duration(i * secondsPerSample);
116
117 this->endEffectorTrajectory_.push_back(globalPose);
118 }
119 }
120
122 {
123 //auto currentRobotEndEffectorPose = this->movegroupClient_->moveGroupClientInterface.getCurrentPose();
124
125 tf::TransformListener tfListener;
126 // tf::StampedTransform globalBaseLink;
127 tf::StampedTransform endEffectorInPivotFrame;
128
129 try
130 {
131 if (!tipLink_ || *tipLink_ == "")
132 {
133 tipLink_ = this->movegroupClient_->moveGroupClientInterface.getEndEffectorLink();
134 }
135
136 tfListener.waitForTransform(planePivotPose_.header.frame_id, *tipLink_, ros::Time(0), ros::Duration(10));
137 tfListener.lookupTransform(planePivotPose_.header.frame_id, *tipLink_, ros::Time(0), endEffectorInPivotFrame);
138
139 // we define here the global frame as the pivot frame id
140 // tfListener.waitForTransform(currentRobotEndEffectorPose.header.frame_id, planePivotPose_.header.frame_id, ros::Time(0), ros::Duration(10));
141 // tfListener.lookupTransform(currentRobotEndEffectorPose.header.frame_id, planePivotPose_.header.frame_id, ros::Time(0), globalBaseLink);
142 }
143 catch (const std::exception &e)
144 {
145 std::cerr << e.what() << '\n';
146 }
147
148 // tf::Transform endEffectorInBaseLinkFrame;
149 // tf::poseMsgToTF(currentRobotEndEffectorPose.pose, endEffectorInBaseLinkFrame);
150
151 // tf::Transform endEffectorInPivotFrame = globalBaseLink * endEffectorInBaseLinkFrame; // pose composition
152
153 // now pivot and EndEffector share a common reference frame (let say map)
154 // now get the current pose from the pivot reference frame with inverse composition
155 tf::Transform pivotTransform;
156 tf::poseMsgToTF(planePivotPose_.pose, pivotTransform);
157 tf::Transform invertedNewReferenceFrame = pivotTransform.inverse();
158
159 tf::Transform currentPoseRelativeToPivot = invertedNewReferenceFrame * endEffectorInPivotFrame;
160
161 geometry_msgs::Pose finalEndEffectorRelativePose;
162 tf::poseTFToMsg(currentPoseRelativeToPivot, finalEndEffectorRelativePose);
163 relativeInitialPose_ = finalEndEffectorRelativePose;
164 }
165
167 {
169
170 tf::Transform localdirection;
171 localdirection.setIdentity();
172 localdirection.setOrigin(tf::Vector3(0.12, 0, 0));
173 auto frameid = planePivotPose_.header.frame_id;
174
175 visualization_msgs::Marker marker;
176 marker.header.frame_id = frameid;
177 marker.header.stamp = ros::Time::now();
178 marker.ns = "trajectory";
179 marker.id = beahiorMarkers_.markers.size();
180 marker.type = visualization_msgs::Marker::ARROW;
181 marker.action = visualization_msgs::Marker::ADD;
182 marker.scale.x = 0.01;
183 marker.scale.y = 0.02;
184 marker.scale.z = 0.02;
185 marker.color.a = 1.0;
186 marker.color.r = 0.0;
187 marker.color.g = 0;
188 marker.color.b = 1.0;
189
190 geometry_msgs::Point start, end;
191 start.x = planePivotPose_.pose.position.x;
192 start.y = planePivotPose_.pose.position.y;
193 start.z = planePivotPose_.pose.position.z;
194
195 tf::Transform basetransform;
196 tf::poseMsgToTF(planePivotPose_.pose, basetransform);
197 tf::Transform endarrow = localdirection * basetransform;
198
199 end.x = endarrow.getOrigin().x();
200 end.y = endarrow.getOrigin().y();
201 end.z = endarrow.getOrigin().z();
202
203 marker.pose.orientation.w = 1;
204 marker.points.push_back(start);
205 marker.points.push_back(end);
206
207 beahiorMarkers_.markers.push_back(marker);
208 }
209
210} // namespace cl_move_group_interface
boost::optional< geometry_msgs::Pose > relativeInitialPose_
std::vector< geometry_msgs::PoseStamped > endEffectorTrajectory_
moveit::planning_interface::MoveGroupInterface moveGroupClientInterface
Definition: cl_movegroup.h:74