Motion planning · repose-motion-planning
The planner task
Every planner runs inside one generic Copper task, CuJointPlannerTask<P, N, M>. It owns everything planners would otherwise each reimplement: config, budgets, seeding, publishing, and state for replay.
Anytime planning
The task is a Copper anytime task. It can do a little work per cycle, publish a usable answer early and improve it while time allows:
base()runs when a new request arrives: start a job with a fresh seed, then spendbase_budgetwork units.refine()runs on later cycles and spendsrefine_budgetmore each time, until the job is final or Copper's anytime budget stops it.- Publishing: the output changes only when the path cost strictly improves, so downstream tasks see each better path exactly once. A final failure is published too.
In RON, background: true runs the planner off the main loop, and anytime: sets the time budget and the quality at which to stop early:
(
id: "planner",
type: "repose_joint_rrt_star::CuJointRrtStarTask<6>",
background: true,
anytime: (time_budget_ms: 250.0, quality_target: 0.95),
resources: {"rng": "planner_rng.rng"},
config: {
"chain": "igus_rebel",
"collision_model": "igus_rebel",
"params": {"step_size": 0.3, "max_nodes": 200},
"base_budget": 256,
"refine_budget": 64,
},
),Config: CuJointPlannerParams
chain (required) | Preset or inline chain. |
collision_model (required) | Preset or inline collision model. |
params | The planner's own parameters. Omit for defaults. See Choosing a planner. |
base_budget, refine_budget | Work units per base() and refine(). Default 64 and 32 unless the planner sets its own. Must be positive. |
Quality
Quality is straight-line cost divided by path cost, from 0 to 1. A path of quality 1 is the straight joint line; 0.95 means at most about 5 % longer. quality_target in the anytime config uses this number.
Seeds and replay
Sampling planners draw randomness only from the job seed. The task takes a base seed once from its rng resource (a cu_rng::CuRngBundle with a fixed seed) and derives each job's seed from it and a job counter. The base seed and counter are frozen into Copper's log, so replaying a .copper log reproduces every plan exactly.
resources: [
(id: "planner_rng", provider: "cu_rng::CuRngBundle", config: {"seed": 42}),
],Task aliases
Add M for robots with more collision shapes than joints: CuJointPrmTask<6, 12>.
Choosing the planner by name
The umbrella crate's CuAnyPlanner<N> dispatches to any planner chosen in config, which is how the robot-app template's "planner": "rrt_connect" works. Run it as CuJointPlannerTask<CuAnyPlanner<N>, N> with "params": "rrt_star" (or any name from CuPlannerChoice::ALL). Each planner then uses its default parameters.
Inspecting progress
task.status() and task.debug_state() (status, effort, published cost and quality) are available in Rust and through Copper's debug-state registry for remote inspection.