This document covers motion execution in the grasping_control package.
For calibration of the workspace file consumed by this node, see creation.md.
motion_execution_node owns all robot-motion details after a client submits a grasp-pose or named-pose action goal.
Its major features are:
- Transforming the incoming pose into the configured planning frame
- Validating that the target lies inside the calibrated workspace area, when configured
- Seeding MoveIt's IK with the current arm joint state and preferring a nearby joint-space solution
- Loading collision objects from workspace ROS parameters at startup
- Applying those objects to MoveIt through
ApplyPlanningScene - Loading named motion poses from ROS parameters provided by
motion_config.yaml - Publishing the calibrated workspace area as an RViz marker
- Building MoveIt joint-goal or pose-goal constraints depending on the nearby-IK result
- Submitting the final motion request to
moveit_msgs/action/MoveGroup
This keeps MoveIt, TF, and workspace handling centralized in one server.
motion_execution_node exposes two action interfaces:
grasping_msgs/action/MoveToPosefor arbitrary target posesgrasping_msgs/action/MoveToNamedPosefor configured named poses
For each MoveToPose goal, the node performs the following sequence:
- Publish feedback state
transforming_target_pose. - Reject the request if
target_pose.header.frame_idis empty. - Transform the requested pose into
planning_frame. - Publish feedback state
validating_workspace_area. - Reject the goal if the target is outside the calibrated workspace area.
- Publish feedback state
planning_and_executing. - Read the latest configured planning-joint state from
joint_state_topic. - Call
compute_ik_servicewith the current arm state as the IK seed. - If IK succeeds, unwrap the returned joint angles toward the current branch and send a joint-space
MotionPlanRequest. - If IK fails and fallback is enabled, log the IK reason and fall back to the original pose-constrained
MotionPlanRequest.
If the goal succeeds, the action returns success=true. If it fails, the action aborts with a status message describing the cause.
For each MoveToNamedPose goal, the node:
- Looks up
pose_namein theposes_namesROS parameter. - Reads the matching pose data from
poses_values.<name>. - Converts the configured
[x, y, z, roll, pitch, yaw]values into aPoseStamped. - Sends the target directly to MoveIt without applying the workspace-area filter.
The workspace_center name is a manually configured pose. Other named poses, including pre_grasp and post_grasp, use their configured position and orientation directly.
To move the arm to any configured named pose from the ROS 2 CLI:
source install/setup.bash
ros2 action send_goal /move_arm_to_named_pose grasping_msgs/action/MoveToNamedPose "{pose_name: workspace_center}"Replace workspace_center with any configured entry from poses_names, for example pre_grasp or post_grasp.
Use the following command to read the current pose of a link/joint.
source install/setup.bash
ros2 run grasping_control read_pose_node --ros-args -p from:=base_link -p to:=camera_linkTo read current joint positions instead, use:
source install/setup.bash
ros2 run grasping_control read_pose_node --ros-args -p mode:=jointThen update motion_config.yaml and restart motion_execution_node.
poses_names: ["workspace_center", "pre_grasp", "post_grasp", "<new_named_pose>"]
poses_values:
workspace_center:
pose: [0.0, 0.0, 0.30, 0.0, 0.0, 0.0]
target_frame: camera_link
pre_grasp:
pose: [0.0, 0.0, 0.30, 0.0, 0.0, 0.0]
target_frame: tcp
post_grasp:
pose: [0.0, 0.0, 0.30, 0.0, 0.0, 0.0]
target_frame: tcp
<new_named_pose>:
pose: [0.0, 0.0, 0.30, 0.0, 0.0, 0.0]
target_frame: tcpThe robot launch files load motion_config.yaml as a ROS parameter file for motion_execution_node.
That file contains:
poses_names, which controls which pose names the named-pose action acceptsposes_values.<name>, which stores each named pose as[x, y, z, roll, pitch, yaw]plus itstarget_frame- planning settings such as
planning_group, tolerances, planner selection, IK settings, and joint-goal behavior
At startup, the node reads workspace configuration from ROS parameters. The robot launch files load the selected workspace YAML, such as crlab_table.yaml, as a ROS parameter file.
From the workspace configuration it reads:
workspace_objectsandworkspace_object, which are converted into MoveIt collision objects- optional
workspace_object.<name>.allowed_collision_links, which allows configured object-link collision pairs in MoveIt's allowed collision matrix workspace_area, which is used as an acceptance filter for incoming goalsbase_frame, which is used as the workspace-area reference frame when needed
Workspace objects may allow collision with specific robot links when a fixed obstacle touches robot mounting hardware. For example:
workspace_object:
table:
allowed_collision_links: [ur10_base_link]This still keeps table as a collision object for every other robot link.
Unsupported geometry types are skipped with a warning. Supported runtime collision geometry types are:
boxcylinder
If workspace_area is not configured, the node accepts targets anywhere in the planning frame.
If workspace_area is configured, the node:
- checks the transformed target position against the saved four-corner polygon
- aborts
MoveToPosegoals withTarget pose lies outside the calibrated workspace area.when the pose is outside - treats the check as planar, using the XY polygon only
Named poses bypass this filter.
The current filter does not enforce a Z band.
When a valid workspace area is present, the node publishes it as a semi-transparent green marker on workspace_area_marker_topic.
Marker details:
- frame: workspace base frame from the workspace YAML
- type: triangle-list plane built from the four saved corner points
- color: green with partial transparency
If no workspace area exists, the node publishes a delete marker so stale visuals are cleared.
The node first tries to convert a target TCP pose into a nearby joint-space goal.
- The latest
planning_joint_namesstate is read fromjoint_state_topicand used as the IK seed. compute_ik_serviceis called for the configuredplanning_groupandend_effector_linkor named-pose target frame.- Returned joint angles are shifted by whole turns so each revolute joint stays as close as possible to the current arm configuration.
- When nearby IK succeeds, the final
MotionPlanRequestusesJointConstraints instead of TCP pose constraints. - When nearby IK fails and fallback is enabled, the node logs the IK reason and falls back to a pose-constrained request.
- During pose-constrained fallback, position is represented as a spherical tolerance region around the requested pose.
- During pose-constrained fallback, orientation is normalized before building the orientation constraint.
- The request uses the configured planning group, planner, pipeline, planning time, and scaling factors.
The node sends the request to the configured MoveGroup action and reports any non-success MoveIt error code back to the caller.
action_name: action server name, defaultmove_arm_to_posenamed_pose_action_name: named-pose action server name, defaultmove_arm_to_named_posemove_group_action_name: MoveIt action name, defaultmove_actionplanning_group: MoveIt group, defaultmanipulatorplanning_frame: planning frame, defaultbase_linkend_effector_link: constrained link, defaulttool0in the node andtcpin soft-gripper launch files
poses_names: accepted named-pose identifiersposes_values.<name>.pose: configured pose as[x, y, z, roll, pitch, yaw]poses_values.<name>.target_frame: link expected to reach the configured pose
allowed_planning_time: default5.0num_planning_attempts: default5max_velocity_scaling: default0.2max_acceleration_scaling: default0.2position_tolerance_m: default0.005orientation_tolerance_rad: default0.1planning_pipeline_id: optional planner pipeline overrideplanner_id: optional planner overridecompute_ik_service: default/compute_ikjoint_state_topic: default/joint_statesplanning_joint_names: ordered arm joints used to seed IK and build the final joint goalprefer_nearby_ik: when true, compute a nearby IK solution before sending a MoveIt requestfallback_to_pose_planning_on_ik_failure: when true, use the old pose-constrained planning path if nearby IK failsjoint_state_timeout_sec: maximum age for cached planning joints before nearby IK is skippedik_timeout_sec: timeout passed to MoveIt's IK requestjoint_goal_tolerance_rad: tolerance applied to each joint when a joint-goal request is builtlog_joint_goal_deltas: when true, log per-joint deltas between current state and the selected nearby IK goal
apply_planning_scene_service: default/apply_planning_sceneget_planning_scene_service: default/get_planning_scene, used to preserve the existing MoveIt allowed-collision matrix before appending workspace object-link allowancesworkspace_area_marker_topic: default/workspace_area_marker
On startup the node:
- reads configured named poses from ROS parameters loaded by the launch file
- reads workspace objects and optional workspace area from ROS parameters
- publishes the workspace marker state
- applies collision objects to the planning scene if
ApplyPlanningSceneis available, appending configured workspace object-link allowances to the existing MoveIt allowed-collision matrix - starts the
MoveToPoseandMoveToNamedPoseaction servers
If ApplyPlanningScene is unavailable, the node logs a warning and continues running without loading the planning scene.
Common failure sources are:
- incoming pose cannot be transformed into
planning_frame - named pose is not listed in
motion_config.yaml - workspace area is configured but invalid
MoveToPosetarget lies outside the calibrated workspace area- no fresh
joint_state_topicsample is available forplanning_joint_names compute_ik_serviceis unavailable, times out, or returns a non-success MoveIt error codeMoveGroupaction server is unavailable- MoveIt rejects or fails the motion request
The nearby-IK path depends on live /joint_states and a running /compute_ik service from MoveIt. Without a robot or demo stack running, the new code can still be validated statically, but the runtime path will naturally fall back or abort depending on fallback_to_pose_planning_on_ik_failure.
For offline verification, temporarily set:
prefer_nearby_ik: true
fallback_to_pose_planning_on_ik_failure: true
log_joint_goal_deltas: trueThen inspect the node logs while running against either the MoveIt demo launch or hardware bringup.