Skip to content

5. Moveit API

Sebastian edited this page Jul 25, 2021 · 12 revisions

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.

Robot Commander

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:

Joint commander

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.

Pose commander

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.

Path Commander

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.

Using rqt to publish to robot_commander topics

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.

Then we have to choose the topic we want to publish to, be it the `robot_commander/joint_cmd` or the `robot_commander/pose_cmd` (the message type has to be chosen too, and it has to match the message type of the topic).

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.

Using Python to publish to robot_commander topics

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:

  1. Create the ROS publisher object
  2. Define the message object for the desired topic
  3. Fill the object with the data needed, like the angular value for each joint in the joint[6] message.
  4. 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.