Menlo
Python SDK

Safety

The rules that decide whether the robot stays upright — and what stops it when your code doesn't.

Asimov 1 is a 25-joint humanoid that can fall on itself or on you. This page is the short list of rules that decide whether it stays up. Everything else in this section links here rather than repeating it.

damp() is not an emergency stop

It is a software state, sent over the same link as everything else. Use a robot with an independent hardware emergency stop, and reach for that one.

STAND Is a Stiffen, Not a Balance

stand() blends every joint into a fixed pose and holds it there with position gains. Nothing balances the robot while it does — there is no feedback term in it at all.

Use it to wake a robot up, or on a robot that is held, craned or on its stand. A free-standing robot asked to stiffen after walking tips over, and the fall latches a fault-DAMP that lasts until the firmware restarts.

After a walk, stay in MOVE at zero velocity — stop() — where the walking policy keeps balancing.

The Ladder Is One-Way

damp() → stand() → set_velocity(). A velocity command sent to a DAMPed robot is dropped by the edge before it reaches the firmware — the robot simply stays limp. Always stand() first, and wait_for(Mode.STAND).

Whatever Streams Setpoints Owns the Robot

The firmware obeys the last command it received. A goto() is fenced: any verb from any thread stops it before its next setpoint leaves. A trajectory() loop you clock yourself is not: a mode verb from another thread is overwritten by your next setpoint. Measured: a damp() fired into a 50 Hz loop left the robot in MOVE and upright, and nothing raised.

Stop the stream, then send the verb. In an emergency, kill the process — the edge damps on its own about two seconds after the last setpoint stops arriving, and that path does not depend on your loop still working.

What Stops the Robot Without You

If your program stops, the robot stops. The edge zeroes the velocity itself two seconds after the last one it received. That happens on the robot, so it holds even if Python crashes mid-command, on every lane.

duration= bounds a movement. The SDK sends the zero when time is up.

close() zeroes velocity, then drops the link. On every exit path from the with block, exceptions included. It never damps.

LinkLostError after two seconds of silence. Every verb raises until you close() and connect() again, and nothing latched carries into the next session.

The robot ending the drive releases the hold. A fault-DAMP or a firmware restart drops a held velocity so the keepalive stops re-sending it; nothing is sent in its place.

Speeds are clamped to Limits(vx=0.6, vy=0.6, vyaw=1.5) before they leave; Sent.clamped says so. The robot clamps again on its side.

Posture commands go out once. A script cannot out-shout an operator by volume — except while it is streaming setpoints, per the rule above.

Protocol version is checked on connect. A mismatch raises ProtocolMismatchError up front rather than halfway through a run.

After a Fall

The firmware latches a fault-DAMP and refuses stand() until it restarts. state.faulted is true and RobotFaultedError is raised by any wait. Set the robot upright, restart the firmware, then bring it up again — retrying the verb will not clear it.

Before You Let Go

  • An independent hardware emergency stop, within reach, tested.
  • Crane, stand or a hand on the robot for anything using goto() or trajectory().
  • duration= on movements you are not watching.
  • Version-matched software: menlo-sdk is pre-1.0.

How is this guide?

On this page