3636
3737// ROS
3838#include < ros/ros.h>
39+ #include < ros/console.h>
3940
4041// MoveIt
4142#include < moveit/planning_scene_interface/planning_scene_interface.h>
@@ -54,8 +55,8 @@ const double tau = 2 * M_PI;
5455// Creating the planning request
5556// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5657// In this tutorial, we use a small helper function to create our planning requests and move the robot.
57- bool moveToCartPose (const geometry_msgs::PoseStamped& pose, moveit::planning_interface::MoveGroupInterface& group,
58- const std::string& end_effector_link)
58+ bool moveToCartesianPose (const geometry_msgs::PoseStamped& pose, moveit::planning_interface::MoveGroupInterface& group,
59+ const std::string& end_effector_link)
5960{
6061 // To use subframes of objects that are attached to the robot in planning, you need to set the end effector of your
6162 // move_group to the subframe of the object. The format has to be ``object_name/subframe_name``, as shown
@@ -101,84 +102,64 @@ void spawnCollisionObjects(moveit::planning_interface::PlanningSceneInterface& p
101102 moveit_msgs::CollisionObject box;
102103 box.id = " box" ;
103104 box.header .frame_id = " panda_hand" ;
105+ box.pose .position .z = z_offset_box;
106+ box.pose .orientation .w = 1.0 ; // Neutral orientation
107+
104108 box.primitives .resize (1 );
105- box.primitive_poses .resize (1 );
106109 box.primitives [0 ].type = box.primitives [0 ].BOX ;
107110 box.primitives [0 ].dimensions .resize (3 );
108111 box.primitives [0 ].dimensions [0 ] = 0.05 ;
109112 box.primitives [0 ].dimensions [1 ] = 0.1 ;
110113 box.primitives [0 ].dimensions [2 ] = 0.02 ;
111- box.primitive_poses [0 ].position .z = z_offset_box;
112114
113115 // Then, we define the subframes of the CollisionObject. The subframes are defined in the ``frame_id`` coordinate
114116 // system, just like the shapes that make up the object. Each subframe consists of a name and a pose.
115117 // In this tutorial, we set the orientation of the subframes so that the z-axis of the subframe
116118 // points away from the object.
117119 // This is not strictly necessary, but it is helpful to follow a convention, and it avoids confusion when
118120 // setting the orientation of the target pose later on.
119- box.subframe_names .resize (5 );
120- box.subframe_poses .resize (5 );
121+ box.subframe_names .resize (3 );
122+ box.subframe_poses .resize (3 );
121123
122124 box.subframe_names [0 ] = " bottom" ;
123125 box.subframe_poses [0 ].position .y = -.05 ;
124- box.subframe_poses [0 ].position .z = 0.0 + z_offset_box;
125126
126127 tf2::Quaternion orientation;
127- orientation.setRPY (tau / 4 , 0 , 0 ); // A quarter turn about the x-axis
128+ orientation.setRPY (tau / 4.0 , 0 , 0 ); // A quarter turn about the x-axis
128129 box.subframe_poses [0 ].orientation = tf2::toMsg (orientation);
129130 // END_SUB_TUTORIAL
130131
131132 box.subframe_names [1 ] = " top" ;
132133 box.subframe_poses [1 ].position .y = .05 ;
133- box.subframe_poses [1 ].position .z = 0.0 + z_offset_box;
134- orientation.setRPY (-tau / 4 , 0 , 0 );
134+ orientation.setRPY (-tau / 4.0 , 0 , 0 );
135135 box.subframe_poses [1 ].orientation = tf2::toMsg (orientation);
136136
137- box.subframe_names [2 ] = " corner_1 " ;
138- box.subframe_poses [2 ].position .x = - .025 ;
137+ box.subframe_names [2 ] = " corner " ;
138+ box.subframe_poses [2 ].position .x = .025 ;
139139 box.subframe_poses [2 ].position .y = -.05 ;
140- box.subframe_poses [2 ].position .z = -.01 + z_offset_box ;
141- orientation.setRPY (tau / 4 , 0 , 0 );
140+ box.subframe_poses [2 ].position .z = -.01 ;
141+ orientation.setRPY (tau / 8.0 , 5.0 / 8.0 * tau, 0. 0 );
142142 box.subframe_poses [2 ].orientation = tf2::toMsg (orientation);
143143
144- box.subframe_names [3 ] = " corner_2" ;
145- box.subframe_poses [3 ].position .x = .025 ;
146- box.subframe_poses [3 ].position .y = -.05 ;
147- box.subframe_poses [3 ].position .z = -.01 + z_offset_box;
148- orientation.setRPY (tau / 4 , 0 , 0 );
149- box.subframe_poses [3 ].orientation = tf2::toMsg (orientation);
150-
151- box.subframe_names [4 ] = " side" ;
152- box.subframe_poses [4 ].position .x = .0 ;
153- box.subframe_poses [4 ].position .y = .0 ;
154- box.subframe_poses [4 ].position .z = -.01 + z_offset_box;
155- orientation.setRPY (0 , tau / 2 , 0 );
156- box.subframe_poses [4 ].orientation = tf2::toMsg (orientation);
157-
158144 // Next, define the cylinder
159145 moveit_msgs::CollisionObject cylinder;
160146 cylinder.id = " cylinder" ;
161147 cylinder.header .frame_id = " panda_hand" ;
148+ cylinder.pose .position .z = z_offset_cylinder;
149+ orientation.setRPY (0 , tau / 4.0 , 0 );
150+ cylinder.pose .orientation = tf2::toMsg (orientation);
151+
162152 cylinder.primitives .resize (1 );
163- cylinder.primitive_poses .resize (1 );
164153 cylinder.primitives [0 ].type = box.primitives [0 ].CYLINDER ;
165154 cylinder.primitives [0 ].dimensions .resize (2 );
166155 cylinder.primitives [0 ].dimensions [0 ] = 0.06 ; // height (along x)
167156 cylinder.primitives [0 ].dimensions [1 ] = 0.005 ; // radius
168- cylinder.primitive_poses [0 ].position .x = 0.0 ;
169- cylinder.primitive_poses [0 ].position .y = 0.0 ;
170- cylinder.primitive_poses [0 ].position .z = 0.0 + z_offset_cylinder;
171- orientation.setRPY (0 , tau / 4 , 0 );
172- cylinder.primitive_poses [0 ].orientation = tf2::toMsg (orientation);
173157
174158 cylinder.subframe_poses .resize (1 );
175159 cylinder.subframe_names .resize (1 );
176160 cylinder.subframe_names [0 ] = " tip" ;
177- cylinder.subframe_poses [0 ].position .x = 0.03 ;
178- cylinder.subframe_poses [0 ].position .y = 0.0 ;
179- cylinder.subframe_poses [0 ].position .z = 0.0 + z_offset_cylinder;
180- orientation.setRPY (0 , tau / 4 , 0 );
181- cylinder.subframe_poses [0 ].orientation = tf2::toMsg (orientation);
161+ cylinder.subframe_poses [0 ].position .z = 0.03 ;
162+ cylinder.subframe_poses [0 ].orientation .w = 1.0 ; // Neutral orientation
182163
183164 // BEGIN_SUB_TUTORIAL object2
184165 // Lastly, the objects are published to the PlanningScene. In this tutorial, we publish a box and a cylinder.
@@ -188,47 +169,6 @@ void spawnCollisionObjects(moveit::planning_interface::PlanningSceneInterface& p
188169}
189170// END_SUB_TUTORIAL
190171
191- void createArrowMarker (visualization_msgs::Marker& marker, const geometry_msgs::Pose& pose, const Eigen::Vector3d& dir,
192- int id, double scale = 0.1 )
193- {
194- marker.action = visualization_msgs::Marker::ADD;
195- marker.type = visualization_msgs::Marker::CYLINDER;
196- marker.id = id;
197- marker.scale .x = 0.1 * scale;
198- marker.scale .y = 0.1 * scale;
199- marker.scale .z = scale;
200-
201- Eigen::Isometry3d pose_eigen;
202- tf2::fromMsg (pose, pose_eigen);
203- marker.pose = tf2::toMsg (pose_eigen * Eigen::Translation3d (dir * (0.5 * scale)) *
204- Eigen::Quaterniond::FromTwoVectors (Eigen::Vector3d::UnitZ (), dir));
205-
206- marker.color .r = 0.0 ;
207- marker.color .g = 0.0 ;
208- marker.color .b = 0.0 ;
209- marker.color .a = 1.0 ;
210- }
211-
212- void createFrameMarkers (visualization_msgs::MarkerArray& markers, const geometry_msgs::PoseStamped& target,
213- const std::string& ns, bool locked = false )
214- {
215- int id = markers.markers .size ();
216- visualization_msgs::Marker m;
217- m.header .frame_id = target.header .frame_id ;
218- m.ns = ns;
219- m.frame_locked = locked;
220-
221- createArrowMarker (m, target.pose , Eigen::Vector3d::UnitX (), ++id);
222- m.color .r = 1.0 ;
223- markers.markers .push_back (m);
224- createArrowMarker (m, target.pose , Eigen::Vector3d::UnitY (), ++id);
225- m.color .g = 1.0 ;
226- markers.markers .push_back (m);
227- createArrowMarker (m, target.pose , Eigen::Vector3d::UnitZ (), ++id);
228- m.color .b = 1.0 ;
229- markers.markers .push_back (m);
230- }
231-
232172int main (int argc, char ** argv)
233173{
234174 ros::init (argc, argv, " panda_arm_subframes" );
@@ -259,27 +199,7 @@ int main(int argc, char** argv)
259199 planning_scene_monitor->requestPlanningSceneState ();
260200 planning_scene_monitor::LockedPlanningSceneRO planning_scene (planning_scene_monitor);
261201
262- // Visualize frames as rviz markers
263- ros::Publisher marker_publisher = nh.advertise <visualization_msgs::MarkerArray>(" visualization_marker_array" , 10 );
264- auto showFrames = [&](geometry_msgs::PoseStamped target, const std::string& eef) {
265- visualization_msgs::MarkerArray markers;
266- // convert target pose into planning frame
267- Eigen::Isometry3d tf;
268- tf2::fromMsg (target.pose , tf);
269- target.pose = tf2::toMsg (planning_scene->getFrameTransform (target.header .frame_id ) * tf);
270- target.header .frame_id = planning_scene->getPlanningFrame ();
271- createFrameMarkers (markers, target, " target" );
272-
273- // convert eef in pose relative to panda_hand
274- target.header .frame_id = " panda_hand" ;
275- target.pose = tf2::toMsg (planning_scene->getFrameTransform (target.header .frame_id ).inverse () *
276- planning_scene->getFrameTransform (eef));
277- createFrameMarkers (markers, target, " eef" , true );
278-
279- marker_publisher.publish (markers);
280- };
281-
282- // Define a pose in the robot base.
202+ // Define a pose near the robot base.
283203 tf2::Quaternion target_orientation;
284204 geometry_msgs::PoseStamped fixed_pose, target_pose;
285205 fixed_pose.header .frame_id = " panda_link0" ;
@@ -295,11 +215,13 @@ int main(int argc, char** argv)
295215 ROS_INFO (" ==========================\n "
296216 " Press a key and hit Enter to execute an action. \n 0 to exit"
297217 " \n 1 to move cylinder tip to box bottom \n 2 to move cylinder tip to box top"
298- " \n 3 to move cylinder tip to box corner 1 \n 4 to move cylinder tip to box corner 2"
299- " \n 5 to move cylinder tip to side of box"
300- " \n 6 to return the robot to the start pose"
301- " \n 7 to move the robot's wrist to a cartesian pose"
218+ " \n 3 to move cylinder tip to box corner"
219+ " \n "
220+ " \n 5 to return the robot to the start pose"
221+ " \n "
222+ " \n 7 to move the robot's wrist to a cartesian pose near the robot base"
302223 " \n 8 to move cylinder/tip to the same cartesian pose"
224+ " \n 9 to move panda_link8 near box/bottom"
303225 " \n ----------"
304226 " \n 10 to remove box and cylinder from the scene"
305227 " \n 11 to spawn box and cylinder"
@@ -319,12 +241,11 @@ int main(int argc, char** argv)
319241 // The target pose is given relative to a box subframe:
320242 target_pose.header .frame_id = " box/bottom" ;
321243 // The orientation is determined by RPY angles to align the cylinder and box subframes:
322- target_orientation.setRPY (0 , tau / 2 , tau / 4 );
244+ target_orientation.setRPY (0 , tau / 2.0 , tau / 4.0 );
323245 target_pose.pose .orientation = tf2::toMsg (target_orientation);
324246 // To keep some distance to the box, we use a small offset:
325247 target_pose.pose .position .z = 0.01 ;
326- showFrames (target_pose, " cylinder/tip" );
327- moveToCartPose (target_pose, group, " cylinder/tip" );
248+ moveToCartesianPose (target_pose, group, " cylinder/tip" );
328249 // END_SUB_TUTORIAL
329250 }
330251 // BEGIN_SUB_TUTORIAL move_example
@@ -333,42 +254,22 @@ int main(int argc, char** argv)
333254 {
334255 ROS_INFO_STREAM (" Moving to top of box with cylinder tip" );
335256 target_pose.header .frame_id = " box/top" ;
336- target_orientation.setRPY (tau / 2 , 0 , tau / 4 );
257+ target_orientation.setRPY (tau / 2.0 , 0 , tau / 4.0 );
337258 target_pose.pose .orientation = tf2::toMsg (target_orientation);
338259 target_pose.pose .position .z = 0.01 ;
339- showFrames (target_pose, " cylinder/tip" );
340- moveToCartPose (target_pose, group, " cylinder/tip" );
260+ moveToCartesianPose (target_pose, group, " cylinder/tip" );
341261 }
342262 // END_SUB_TUTORIAL
343263 else if (character_input == 3 )
344264 {
345- ROS_INFO_STREAM (" Moving to corner1 of box with cylinder tip" );
346- target_pose.header .frame_id = " box/corner_1 " ;
347- target_orientation.setRPY (0 , tau / 2 , tau / 4 );
265+ ROS_INFO_STREAM (" Moving to box corner with cylinder tip" );
266+ target_pose.header .frame_id = " box/corner " ;
267+ target_orientation.setRPY (tau / 2.0 , 0 , 0 );
348268 target_pose.pose .orientation = tf2::toMsg (target_orientation);
349269 target_pose.pose .position .z = 0.01 ;
350- showFrames (target_pose, " cylinder/tip" );
351- moveToCartPose (target_pose, group, " cylinder/tip" );
352- }
353- else if (character_input == 4 )
354- {
355- target_pose.header .frame_id = " box/corner_2" ;
356- target_orientation.setRPY (0 , tau / 2 , tau / 4 );
357- target_pose.pose .orientation = tf2::toMsg (target_orientation);
358- target_pose.pose .position .z = 0.01 ;
359- showFrames (target_pose, " cylinder/tip" );
360- moveToCartPose (target_pose, group, " cylinder/tip" );
270+ moveToCartesianPose (target_pose, group, " cylinder/tip" );
361271 }
362272 else if (character_input == 5 )
363- {
364- target_pose.header .frame_id = " box/side" ;
365- target_orientation.setRPY (0 , tau / 2 , tau / 4 );
366- target_pose.pose .orientation = tf2::toMsg (target_orientation);
367- target_pose.pose .position .z = 0.01 ;
368- showFrames (target_pose, " cylinder/tip" );
369- moveToCartPose (target_pose, group, " cylinder/tip" );
370- }
371- else if (character_input == 6 )
372273 {
373274 // Go to neutral home pose
374275 group.clearPoseTargets ();
@@ -378,14 +279,21 @@ int main(int argc, char** argv)
378279 else if (character_input == 7 )
379280 {
380281 ROS_INFO_STREAM (" Moving to a pose with robot wrist" );
381- showFrames (fixed_pose, " panda_hand" );
382- moveToCartPose (fixed_pose, group, " panda_hand" );
282+ moveToCartesianPose (fixed_pose, group, " panda_hand" );
383283 }
384284 else if (character_input == 8 )
385285 {
386286 ROS_INFO_STREAM (" Moving to a pose with cylinder tip" );
387- showFrames (fixed_pose, " cylinder/tip" );
388- moveToCartPose (fixed_pose, group, " cylinder/tip" );
287+ moveToCartesianPose (fixed_pose, group, " cylinder/tip" );
288+ }
289+ else if (character_input == 9 )
290+ {
291+ target_pose.header .frame_id = " box/bottom" ;
292+ target_orientation.setRPY (0 , tau / 2.0 , 0 );
293+ target_pose.pose .orientation = tf2::toMsg (target_orientation);
294+ target_pose.pose .position .z = 0.15 ;
295+ ROS_INFO_STREAM (" Moving to box bottom with panda link 8" );
296+ moveToCartesianPose (target_pose, group, " panda_link8" );
389297 }
390298 else if (character_input == 10 )
391299 {
@@ -458,3 +366,5 @@ int main(int argc, char** argv)
458366// CALL_SUB_TUTORIAL orientation
459367//
460368// END_TUTORIAL
369+
370+ // TODO(felixvd): Add explanation about the TfPublisher MoveGroupCapability.
0 commit comments