-
Notifications
You must be signed in to change notification settings - Fork 6
5. Moveit API
As seen in the previous page, with Moveit we can command the robot to a desired pose using the Moveit plugin for RViz and it's interactive marker, however this method doesn't allow to give a exact pose, and the fact that it's done manually doesn't help much when talking of an automated solution. But this is not a problem as the Moveit framework offers an API with which you can use pretty much every aspect of Moveit regarding motion planning through actual code, and with the magic of ROS, you can control this from a C++ or Python script or even both.
So to take on this topic, we present you the package we made for this task, the Robot commander package made for this project, it allows, trough ROS topics, to publish a desired goal message to the Moveit framework and the to the robot, be it a Cartesian space Pose goal or a Joint space goal. there is also the possibility to queue and execute a whole trajectory composed of aa array of Poses using the Moveit function computeCartesianPath()
.
These scripts are based on the Move Group C++ Interface Moveit tutorial.
To test these scripts you can execute roslaunch irb140_commander commander_rviz.launch
or roslaunch irb140_commander commander_gazebo.launch
, as you may notice these are the simulations environments presented previously, but the motion task relies in Moveit for both, so it doesn't matter which one you chose, the commanders will work in either case. These launch files will execute the bringups, the commander codes for each task (joint, pose and path) and will make available topics for publishing command requests, to use them you have the following options:
This script creates the robot_commander/cmd_joint
topic and subscribes to it, you or any ROS application can publish a joints[6]
message type to this topic to execute a motion plan with Moveit to a robot Joint space goal (in radians).
Topic: /cmd_joint | Message: joints[6] | |||||
---|---|---|---|---|---|---|
joint_1 | joint_2 | joint_3 | joint_4 | joint_5 | joint_6 |
Here is a piece of the code responsible for this, just to show that each joint target is saved to a C++ std::vector
variable and then passed to the Moveit function setJointValueTarget()
, then the plan is calculated and later executed if possible.
You can publish Joint goals to this topic using the rqt GUI, like in the shown animation, or with a Python script.
The Pose commander creates the robot_commander/cmd_pose
topic and subscribes to it, as already stated, any ROS application that can publish to ROS topics can request a motion plan based on a pose goal, only that in this case the topic uses a PoseRPY
message type, with which a Cartesian 3D Pose (Position and Orientation) can be specified (in meters).
Topic: /cmd_pose | Message: PoseRPY | |||||
---|---|---|---|---|---|---|
Position | Orientation | |||||
X | Y | Z | Roll | Pitch | Yaw |
This fragment shows only how the position/orientation is handled, they pass on to a geometry_msgs::Pose
object so that the Moveit function setPoseTarget()
loads it as a target and then the motion plan can be calculated and executed if possible. We recommend to check the complete code for a better understanding.
You can publish a Pose goals to this topic using the rqt GUI, like in the shown animation, or with a Python script.
As its name indicates, the Path commander allows the request of a motion plan for a set of given Poses, that is, a Path. When executed, it creates the robot_commander/cmd_path
topic on wich you can publish a PoseRPYarray message type containing the desired path for the robot.
The code will subscribe to this topic and wait for a path to be requested, when the path is published on the cmd_path topic, after some processing of the message, the trajectory is generated using the Moveit computeCartesianPath()
function, which returns the needed angular joint positions to achieve the desired path.
Topic: /cmd_path | Message: PoseRPYarray | |||||
---|---|---|---|---|---|---|
PoseRPY[0] |
PoseRPY[1] | PoseRPY[2] | PoseRPY[3] | ... | PoseRPY[n] |
Here is a snippet of the code used for the path planning request, when the PoseRPYarray message is received each individual Pose of the path is extracted from the message and then pushed in a list (waypoints
), then passed on to the computeCartesianPath()
function.
Note how in the animation there is no GUI showing the message sent like in the Joint commander or in the Pose commander, this is because the structure of the PoseRPYarray messsage is a bit more complex as it is an array, so the best way of using it is through a Python script. In this section you can see how to achieve this.
As you may have seen in the previous animations for the Joint and Pose commander, you can send the Joint or PoseRPY messages using a GUI, this the rqt interface. It's a tool that allows the use of several ROS utilities with a GUI, in this case we use the Message Publisher
to publish the desired messages to its respective topics.
Finally the message template is added using the plus sign, and then is ready to be modified, when the message data is ready just right click it and the click the publish
option.
The rqt GUI provides and easy way of publishing messages to topics, but with Python it's a more clean and automated way of doing it through code. To use the robot_commander
it is only a matter of publishing messages to topics using Python. This is a widely covered method by the ROS developers and community in their Tutorials Writing a Simple Publisher and Subscriber (Python).
In this project there are three Python code examples to publish to the robot_commander
topics for Joint, Pose and Path motion requests. All three of them follow the same structure:
- Create the ROS publisher object
- Define the message object for the desired topic
- Fill the object with the data needed, like the angular value for each joint in the joint[6] message.
- Publish the message object using the ROS publisher object created at the start.
The first example is the sendJoints.py script, it is a very simple one that follows the listed steps.
The next one is the sendPose.py script, pretty much similar to the sendJoints.py one, with the difference just in the message object, that this time it's a PoseRPY
type. Notice how the values of X, Y, Z, roll, pitch
and yaw
are properties of the object message. The python object has the same structure as the ROS message.
The last one is then the sendPoseArray.py script in which the object message is handled more like a Python list, where the multiple Pose goals of the Path are appended, and once the last Pose is appended, the message is published.