Drive ~2 min read
Poses¶
A pose is where the arm rests, relative to its fold. strands-arm pose goto up tilts the head 30° from wherever
autocal put home, walks there in the guard's ≤10° legs at 30°/s, and writes every leg to motion.log. Nothing
here bypasses the guard.
Five built-ins¶
| name | what | rel (servo deg from home) |
|---|---|---|
home |
folded rest, torque off after | all 0 |
attention |
head level, arm folded (home's angles, named so an agent can ask for it) | all 0 |
look_around_left |
pan +40 | 5: +40 |
look_around_right |
pan −40 | 5: −40 |
up |
tilt +30 | 6: +30 |
Built-ins never touch the disk and cannot be deleted or overwritten. Whether up looks up or down on your
head depends on the tilt servo's sign: try it once before an agent scripts it.
Save your own¶
strands-arm pose # the six angles now
strands-arm pose save peek --desc "head a hair right"
strands-arm pose list
strands-arm pose goto peek --i-know
strands-arm pose nudge 6 -5 --i-know # one guarded step, at most 10 deg
strands-arm pose delete peek
save captures the current angles and stores two things in ~/.strands-arm/poses.json: deg (what the
servos read) and rel (deg − the home of that moment). goto uses rel re-based on the current home, so a
pose survives autocal moving home by a degree or two, and pan/tilt poses stay inside the head window the guard
measures from the calibrated zero. deg is kept for you to read.
Refused, not clamped¶
A pose the guard would not accept — head outside its window, a joint outside its measured window, a target on the
tick wrap — is refused before the first write, with the joint and the number in the message. GET /api/poses
carries the same verdict as ok/why, and the dashboard greys the button with that reason. The step rule is not
applied to the target: a body joint 40° away is walked in four legs; each leg re-reads the arm first (a hand may
have moved it).
Who owns the bus¶
The dashboard owns the serial port when it runs. pose goto and nudge post to it (POST /api/control/pose,
/api/control/joint) and the walk is a job: state.arm.job shows pose up, every other control answers
409 while it runs, and STOP (or /api/control/stop) aborts it mid-leg. Without a dashboard the tool opens the
bus itself and drives a local Guard, so the same rules and the same log apply. seconds only slows a walk down,
never speeds it past 30°/s.
The same tool is pose for an agent or an MCP client (strands-arm serve --mcp), and pose(action, name, …)
inside the dashboard's chat. Motion needs the gate like everything else: i_know=true, STRANDS_ARM_I_KNOW=1, or
~/.strands-arm/bench.json with ok: true.