Transforms in MoveIt!

This page is intended to give some insight into coordinate frames and transforms used in MoveIt!.

TF knows the current state of the world.
TF is a big topic on its own, see the the TF docs for more details. The important point for MoveIt! users is that TF represents the *current* state of the world (or technically the last few seconds of the state of the world). Many MoveIt! users are thinking about planning motions which have not happened yet, so they need some mix of the current state of the world and other possible future states of the world.

Planning Frame
TF keeps a collection of named coordinate frames, and you can get the pose of any frame relative to any other. In MoveIt!, much of the work is done in a single coordinate frame, often called the "planning frame". For a mobile robot this could be "odom", "odom_combined", "map", or similar. The name of some reference frame which is external to the robot. The name of this frame can be found by calling [/classmoveit_1_1core_1_1RobotModel.html RobotModel]::getModelFrame. This is set in the ".srdf" file for the robot.

MoveIt!'s cache of TF transforms
Various code in MoveIt! needs access to TF transform data, so for efficiency and convenience there is a class ([/classmoveit_1_1core_1_1Transforms.html Transforms]) which stores copies of all the TF transforms relative to the planning frame without the timing data. Those transform values are updated by the [/classplanning__scene__monitor_1_1PlanningSceneMonitor.html PlanningSceneMonitor] class's updateFrameTransforms function. The updated instance of Transforms is stored in the [/classplanning__scene_1_1PlanningScene.html PlanningScene] and is accessible via the getTransforms function. If you aren't using a PlanningSceneMonitor but want to use the Transforms object stored in the PlanningScene, you can compute the poses yourself (or get them from TF separately) and call.

RobotState and TF transforms
The [/classmoveit_1_1core_1_1RobotState.html RobotState] class has functions called getGlobalLinkTransform. These return the pose of the given link relative to the planning frame, given that particular robot state. Since RobotState is often used to plan motions which have not happened yet, the poses returned will often not match those from TF. The root joint of any RobotModel is a virtual joint which captures the pose of the robot relative to the planning frame. This virtual joint is specified in the robot's .srdf file, often via the MoveIt! setup assistant. The name of the planning frame is given by the "parent_frame" attribute of the virtual joint in the .srdf file. Every RobotState instance has some value for the offset specified in that root joint.

Updating the root joint
The PlanningSceneMonitor automatically updates the value of the root joint when it handles JointState messages, which typically arrive very frequently from the robot controller or simulator. The value updated is in the RobotState instance inside the PlanningScene, which is accessible by calling.

If you are not using the PlanningSceneMonitor or if you want to consider a state in which the robot's base is positioned differently, you must update the root joint of your own RobotState. For instance:

RobotModelPtr my_robot_model; // load robot model here... RobotState my_state(my_robot_model); Eigen::Affine3d base_rel_planning_frame; // compute desired base pose here... my_state.setJointPositions(my_robot_model->getRootJoint, base_rel_planning_frame);

If you want to use the automatically updated base pose from the PlanningSceneMonitor but also want to plan future arm motions which do not involve moving the base, you need to make sure and initialize the RobotState instances used for your planning (like starting state) with a copy of the state maintained in the PlanningScene. For example:

RobotState target_pose( planning_scene_monitor_->getPlanningScene->getCurrentState ); Eigen::Affine3d new_end_effector_pose_rel_planning_frame; // compute new end-effector pose here... target_pose.setFromIK(my_robot_model->getJointModelGroup("right_arm"), new_end_effector_pose_rel_planning_frame);

Then  will have the current base pose relative to the planning frame, but will also have the right arm with joint values computed to reach.