lerobot¶
One adapter for every architecture lerobot ships: ACT, Diffusion, SmolVLA, pi0 / pi05, GR00T N1.7, xVLA and the rest. No per-model file in this tree.
from strands_robots import Robot, make_policy
robot = Robot("aloha", mode="sim")
joints = list(robot.joint_names)
policy = make_policy("lerobot/act_aloha_sim_transfer_cube_human", # hub id or a local checkpoint dir
state_keys=joints, action_keys=joints) # the checkpoint's 14 state keys -> the arm's joints
robot.preflight(policy) # refuses INVALID_ACTION naming the camera `top` the checkpoint needs and this observation lacks
The refusal is the contract: a checkpoint runs only when every state key and camera it was
trained on is present in observe(). Camera frames in Observation.images are not wired
in this build (FINDINGS F25), so PolicyRunner with a vision checkpoint waits on that; the
runner itself is exercised in first robot with mock:
import asyncio
from strands_robots import PolicyRunner, Robot, make_policy
robot = Robot("so101", mode="sim")
policy = make_policy("mock", dof=6)
robot.preflight(policy)
report = asyncio.run(PolicyRunner(control_hz=30).run(robot, policy, "wave", max_steps=60))
print(report.stop_reason, report.steps, report.clamped_steps)
robot.close()
| fact | value |
|---|---|
| provider | lerobot_local |
| frame | read from the checkpoint's meta/stats; refused if absent |
| model extras | a VLM policy needs lerobot's own extra too, e.g. pip install "lerobot[smolvla]"; the refusal names it |
| inputs | state keys and camera names mapped by EmbodimentMap; preflight names a missing key |
| chunks | actions_per_step > 1 engages RTC in the runner |
| warm handle | a checkpoint loads once per process |
Training and async inference belong to lerobot: strands_robots.policies.train_spec builds
the lerobot-train argv from a TrainSpec, nothing more.