Motion Planning using C++¶
In this exercise, we’ll explore MoveIt’s C++ interface to programatically move a robot.
Motivation¶
Now that we’ve got a working MoveIt! configuration for your workcell and we’ve played a bit in RViz with the planning tools, let’s perform planning and motion in code. This exercise will introduce you to the basic C++ interface for interacting with the MoveIt! node in your own program. There are lots of ways to use MoveIt!, but for simple applications this is the most straight forward.
Reference Example¶
3. Further Information and Resources¶
Scan-N-Plan Application: Problem Statement¶
In this exercise, your goal is to modify the myworkcell_core node to:
- Move the robot’s tool frame to the center of the part location as reported by the service call to your vision node.
Scan-N-Plan Application: Guidance¶
Edit your
myworkcell_node.cppfile.Add
#include <tf/tf.h>to allow access to the tf library (for frame transforms/utilities).- Remember that we already added a dependency on the
tfpackage in a previous exercise.
- Remember that we already added a dependency on the
In the
ScanNPlanclass’sstartmethod, use the response from theLocalizePartservice to initialize a newmove_targetvariable:geometry_msgs::Pose move_target = srv.response.pose;
- make sure to place this code after the call to the vision_node’s service.
Use the
MoveGroupInterfaceto plan/execute a move to themove_targetposition:In order to use the
MoveGroupInterfaceclass it is necessary to add themoveit_ros_planning_interfacepackage as a dependency of yourmyworkcell_corepackage. Add themoveit_ros_planning_interfacedependency by modifying your package’sCMakeLists.txt(2 lines) andpackage.xml(1 line) as in previous exercises.Add the appropriate “include” reference to allow use of the
MoveGroupInterface:#include <moveit/move_group_interface/move_group_interface.h>
Create a
moveit::planning_interface::MoveGroupInterfaceobject in theScanNPlanclass’sstart()method. It has a single constructor that takes the name of the planning group you defined when creating the workcell moveit package (“manipulator”).moveit::planning_interface::MoveGroupInterface move_group("manipulator");
Set the desired cartesian target position using the
move_groupobject’ssetPoseTargetfunction. Call the object’smove()function to plan and execute a move to the target position.// Plan for robot to move to part move_group.setPoseReferenceFrame(base_frame); move_group.setPoseTarget(move_target); move_group.move();
As described here, the
move_group.move()command requires use of an “asynchronous” spinner, to allow processing of ROS messages during the blockingmove()command. Initialize the spinner near the start of themain()routine afterros::init(argc, argv, "myworkcell_node"), and replace the existingros::spin()command withros::waitForShutdown(), as shown:ros::AsyncSpinner async_spinner(1); async_spinner.start(); ... ros::waitForShutdown();
Test the system!
catkin build roslaunch myworkcell_moveit_config myworkcell_planning_execution.launch roslaunch myworkcell_support workcell.launch
More to explore…
- In RViz, add a “Marker” display of topic “/ar_pose_visual” to confirm that the final robot position matches the position published by
fake_ar_publisher - Try repeating the motion planning sequence:
- Use the MoveIt rviz interface to move the arm back to the “allZeros” position
- Ctrl+C the
workcell.launchfile, then rerun
- Try updating the
workcell_node’sstartmethod to automatically move back to theallZerosposition after moving to the AR_target position. See here for a list ofmove_group’s available methods. - Try moving to an “approach position” located a few inches away from the target position, prior to the final move-to-target.
- In RViz, add a “Marker” display of topic “/ar_pose_visual” to confirm that the final robot position matches the position published by