Planning Groups
August 27, 2026 ยท View on GitHub
Planning groups are named, selectable kinematic chains used by manipulation planning. They let APIs target a specific part of a robot, such as an arm or torso, without confusing that group with the robot's hardware identity.
Concepts
| Concept | Meaning |
|---|---|
| Model | The single configured RobotModelConfig. |
| Planning group | A named subset of the model's controllable joints. |
| Planning group ID | Stable declared group name, such as left_arm. |
| Canonical joint name | Joint name used unchanged by the model, planner, coordinator, and visualization. |
| Generated plan | Planning artifact containing selected group IDs, geometric waypoints, and one synchronized canonical trajectory. |
| Auxiliary group | A selected group that contributes free DOFs to a pose plan without receiving its own pose target. |
The configured model owns one canonical joint namespace. Planning groups select subsets of that namespace; they do not rename or prefix joints.
Discovering planning groups
Robot configs can provide planning groups explicitly with
RobotModelConfig.planning_groups. Direct RobotModelConfig(...) construction
does not run discovery or synthesize groups in model_post_init; callers must
pass explicit planning_groups there.
When code uses the discovery helper instead of explicit config, dimOS discovers groups in this order:
- Explicit
srdf_pathprovided to the helper. - Conservative SRDF auto-discovery near the model path, with a warning.
- Fallback generation of one
manipulatorgroup when the configured controllable joints form exactly one unambiguous serial chain. - Error if no SRDF or fallback chain can provide a single valid group.
Supported SRDF group forms:
<group name="arm">
<chain base_link="base_link" tip_link="tool0" />
</group>
<group name="arm">
<joint name="joint1" />
<joint name="joint2" />
<joint name="joint3" />
</group>
Unsupported SRDF forms are skipped with warnings: link groups, nested group
references, mixed group declarations, branching or non-serial groups, and SRDF
<end_effector> metadata. A chain group's tip_link is its pose target frame.
An ordered joint-list group can be pose-targeted only when dimOS can validate a
unique serial target frame.
Fallback behavior
When discovery runs without an SRDF, fallback uses
RobotModelConfig.joint_names as the candidate controllable set.
This field is the model's ordered canonical joint set, not an implicit
planning group.
Fallback removes terminal prismatic leaves first, including branched finger
joints, and then requires the remaining joints to form one unambiguous serial
chain. Internal prismatic axes remain part of the arm. The generated group name
is always manipulator.
Current APIs
Use list_planning_groups() to discover group IDs and capabilities before
planning:
groups = manip.list_planning_groups()
pose_groups = [group for group in groups if group.has_pose_target]
group_id = pose_groups[0].id
Joint-space planning targets group IDs. Each target JointState may be
unnamed in the group's joint order or named with the group's canonical joints.
ok = manip.plan_to_joint_targets(
{
"left_arm": JointState(
name=["left/joint1", "left/joint2", "left/joint3"],
position=[0.0, -0.4, 0.2],
)
}
)
Pose planning targets pose-capable group IDs. Add auxiliary groups when another
chain should participate as free DOFs but does not have its own pose target.
Pose targets are Pose values keyed by planning group ID:
ok = manip.plan_to_pose_targets(
{"left_arm": target_pose},
auxiliary_groups=["torso"],
)
After a successful planning call, preview and execution use the module's current stored plan:
manip.preview_plan()
manip.execute_plan()
Callers that already hold a GeneratedPlan may pass it explicitly:
manip.preview_plan(plan)
manip.execute_plan(plan)
A generated plan is the execution boundary. The canonical trajectory is sent unchanged to the coordinator. To execute a subset, first plan only that subset's planning group.
Generated plans and execution
A GeneratedPlan stores:
- selected planning group IDs;
- a geometric path of
JointStatewaypoints keyed by canonical joint names; - one materialized synchronized
JointTrajectoryover the same selected canonical joint names; - status, timing, path length, iteration count, and message metadata.
Preview and execution consume the stored trajectory; they do not lazily parameterize the geometric path. Preview and execution forward the canonical trajectory without renaming, splitting, or merging it. The coordinator's trajectory task remains planning-group agnostic and holds omitted joints while executing the selected subset.
Robot placement config
RobotModelConfig.base_pose and RobotModelConfig.base_link describe robot
placement: base_pose places base_link in the world and current backends
use that link for weld/placement and optional model-authored world-joint
stripping. This is model placement metadata, not planning-chain metadata.
Planning-group base_link and tip_link values are the source for chain bases
and pose target frames. Convenience pose APIs require an explicit group when
the model has multiple pose-targetable groups.
Robot placement can be encoded either in model assets or in base_pose,
depending on the blueprint. joint_names describes the ordered controllable
canonical model joint set.