Read State and React
One snapshot of everything the robot reports, and how to wait on it.
robot.state is one snapshot of everything the robot last reported — already decoded. Read
it as often as you like; it costs nothing, because the robot is streaming anyway.
s = robot.state
s.mode # Mode.MOVE
s.gravity # projected into the body frame; z ≈ -1.0 standing straight up
s.yaw # heading, rad, counter-clockwise; None without an IMU
s.joint_pos # one radian value per motor, firmware order
s.joint("L_Knee").pos
s.battery # None when the robot reports no BMS
s.alerts # severity 0 is CRITICAL
s.age_s # how old this sample is, in secondsDon't Sleep and Hope
Blocking on the robot's own report is better than guessing how long something takes:
robot.stand()
robot.wait_for(Mode.STAND, timeout=20.0)
robot.wait_until(lambda s: s.mode is Mode.MOVE, timeout=10.0, stale_after=0.5)A quiet link raises StateStaleError rather than a plain WaitTimeoutError. The difference
matters: "the robot never got there" and "the robot stopped talking" need different fixes. A
fault is checked before your predicate, so a fall is never read as success.
Is It Still Upright?
state.upright is a convenience over the measured gravity vector, true when
gravity[2] < -0.8 — about 37° of tilt. It is None, not False, when the robot did not
report gravity at all: unknown and fallen are different answers.
That threshold is not the robot's
The firmware's own fall detector latches at gravity[2] > -0.5, about 60°. So upright can
read False on a robot the firmware still considers fine. If the distinction matters, read
state.gravity[2] and pick your own angle.
Faults
s.faulted # an error flag, or any critical alertAlerts are sent every 20th frame and carried forward for a short window, so a read between
two alert frames still sees them. The firmware's own fault latch does not clear on its own:
after a fall it keeps the robot DAMPed until it restarts, and stand() is refused until then.
See Troubleshooting.
What the SDK Knows About the Body
info = robot.info
info.dof, info.joint_names # 25 and the firmware's motor order on Asimov 1
info.capabilities # frozenset({'drive', 'state', 'camera', ...})
info.protocol_version, info.limits, info.endpointFields the robot does not report are None, never a guessed zero. Joint names come from a
table in the SDK keyed by the reported joint count; state.joint(name) raises KeyError on a
body the SDK has no table for.
Callbacks
For event-driven code, register a callback instead of polling. These fire on the transport thread — keep them short, and don't call back into the robot from inside one.
robot.on_state = lambda s: ...
robot.on_mode_change = lambda prev, now: print(prev, "->", now)
robot.on_alert = lambda alert, change: print(change, alert.id) # "raised" | "cleared"
robot.on_refused = lambda refused: ...
robot.on_link_lost = lambda exc: shutdown()Next
- Reference — every field and type
How is this guide?