Controller · repose-controller
Controller
CuControllerTask<N> is the last task before the robot. It takes the follower's setpoint and the measured state, decides what is safe to command, and emits the one command type every bridge understands: CuJointCommandPayload<N>.
Where it sits
follower ──CuTrajectoryFollowOutput──►┐
├─► CuControllerTask ──CuJointCommandPayload──► bridge/joint_command
bridge/joint_state ─CuJointStatePayload─►┘Each cycle
| No setpoint yet | Idle, commanding the last measured state (zeros before any state). |
| Setpoint + fresh state | Command follows the setpoint. Status mirrors the follower: Running → Running, Finished → Holding, ErrorEmptyTrajectory → Fault. |
| Tracking error too large | |setpoint − measured| above tracking_error_limit on any joint → Fault, and the command holds the measured state instead of chasing. |
| Setpoint, no state | Fault, holding the last command. |
| Stale state | With state_timeout set, a state older than that (or from the future, or untimed) → Fault. |
The payload also reports max_tracking_error for the cycle, useful for tuning and dashboards. Last command and status are frozen into Copper's log, so replay resumes correctly.
Config: CuControllerParams
mode = position | position, velocity or effort. See Command modes. |
tracking_error_limit = 0.5 | Per joint, in rad (revolute) or m (prismatic). |
state_timeout | Seconds. Unset disables the watchdog. Set it on hardware. |
rate_limit | {"max_speed": .., "max_acceleration": ..} per joint in SI. Position mode only. |
effort_gains = kp 20, kv 0.8 | Effort mode PD gains. |
(id: "controller", type: "repose_controller::CuControllerTask<6>",
config: {
"mode": "position",
"tracking_error_limit": 0.5,
"state_timeout": 0.2,
"rate_limit": {"max_speed": 1.5, "max_acceleration": 6.0},
}),Tuning
tracking_error_limit: run your program, note the largestmax_tracking_error, set the limit a comfortable margin above it. Too tight faults on normal lag; too loose lets a stuck joint go unnoticed.state_timeout: a few bridge cycles. If the bridge stops publishing, the controller stops chasing.rate_limit: a last line of defence against setpoint jumps, set at or below what the trajectory limits already allow.