Robot factory¶
Robot(...) returns a Simulation or HardwareRobot based on mode.
from strands_robots import Robot
robot = Robot("so100") # Simulation (default, safe)
robot = Robot("so100", mode="real") # HardwareRobot
robot = Robot("so100", mode="auto") # probes USB, falls back to sim
Parameters¶
| Param | Type | Default | What |
|---|---|---|---|
name |
str | required | Catalog name or alias. Resolved via registry/robots.json. |
mode |
str | "sim" |
"sim" / "real" / "auto". Overridden by STRANDS_ROBOT_MODE. |
backend |
str | "mujoco" |
Sim backend. Ignored when mode="real". |
urdf_path |
str | None |
Explicit MJCF/URDF path - bypasses registry. |
cameras |
dict | None |
Real-hardware camera config. Rejected in mode="sim" - raises ValueError. |
position |
list | None |
Robot position [x, y, z] in sim world. |
data_config |
str | None |
GR00T data_config name. |
mesh |
bool | True |
Auto-join Zenoh mesh. |
peer_id |
str | None |
Stable mesh peer id. Auto-generated if omitted. |
**kwargs |
Forwarded to backend constructor. Unknown kwargs raise ValueError. |
Name resolution¶
from strands_robots.registry import resolve_name
resolve_name("SO-100") # 'so100'
resolve_name("franka") # 'panda'
resolve_name("g1") # 'unitree_g1'
Case-insensitive, hyphens/underscores interchangeable. Full alias map in registry/robots.json.
Real hardware¶
robot = Robot(
"so100",
mode="real",
cameras={"wrist": {"type": "opencv", "index_or_path": "/dev/video0"}},
port="/dev/tty.usbserial-A50285BI",
control_frequency=50.0,
)
control_frequency (Hz) sets the control loop's per-action period,
1 / control_frequency - the only throttle between two servo commands. It must be a
positive finite number: 0, a negative rate, nan or inf raises ValueError at
construction, before the serial port is opened, rather than leaving the loop free-running
against the arm. This is the same domain the simulation applies to run_policy's
control_frequency, so a rollout rehearsed in sim is honored identically on hardware.
Forwardable kwargs: port, robot_ip, kp, kd, default_positions, control_dt,
is_simulation, gravity_compensation, controller, calibration_dir, mock,
use_degrees, max_relative_target, disable_torque_on_disconnect.
Forwardable values are passed to the driver as given, because their accepted domains are
robot-specific. max_relative_target is the exception: it caps how far each commanded goal
position may move from the joint's present position, so it must be a positive finite number
(or a mapping of motor name to one). 0, a negative limit, nan, inf, a bool or a
non-numeric value raises ValueError when the config is built, before the serial port is
opened - a non-finite limit would otherwise disable the clamp with no signal, and a negative
one inverts it into a fixed-magnitude step that ignores the policy. An int limit is
normalized to float so it reaches the motors. Omit the parameter (or pass None) to leave
the clamp disabled.
Mesh¶
sim = Robot("so100")
sim.mesh.peer_id # 'so100_sim-a1b2c3d4'
sim.mesh.alive # True
Robot("so100", mesh=False) # per-robot off
# STRANDS_MESH=false # process-wide off
Mesh failure is non-fatal; .mesh = None if Zenoh unavailable.
See also¶
- Robot catalog - 68 catalog names.
- Architecture - factory in the module map.
- Multi-robot mesh - mesh peer discovery.