armnet CLI¶
armnet-client installs several CLI entrypoints:
armnet --help # identity, secrets, volumes
armnet-policy-eval --help # evaluate a policy backend on a cell
armnet-lerobot-eval --help # evaluate a LeRobot policy on a cell
armnet-lerobot-train --help # train locally with background remote evals
armnet-openpi-eval --help # evaluate an OpenPI (pi0/pi0.5) policy on a cell
armnet-lerobot-teleop --help # remote-teleoperate a cell from a leader arm
armnet-lerobot-record --help # record a dataset via remote teleoperation
armnet-current-gate-derive --help # derive current safety limits from telemetry
The policy and teleoperation commands have dedicated guides: Teleoperate and Record Datasets, Train and Deploy a LeRobot Policy, and Evaluate Policies. The sections below are a quick reference for the most common invocations.
Identity¶
armnet whoami
Prints the username associated with your API key.
Jobs¶
armnet jobs list # your most recent jobs
armnet jobs get <job-id> # one job's status and result
armnet jobs logs <job-id> # follow one of your jobs' live logs
jobs logs prints stdout in blue and stderr in red, the same way a job you
submitted from this machine does. You can connect to a job that is already
running, including from more than one machine. It only follows jobs submitted
with your API key. A missing id, or a job submitted by someone else, is
reported as job <id> not found. Lines from before you connect are not stored
yet.
The connection counts as a log stream. A non-detached job stays up while one is connected, and closing the last one asks the cell to stop the job after a short grace period, same as closing the terminal that submitted it. A detached job is left running.
Useful for detached runs — manual-environment evals in particular, since those wait for an operator and can finish days after you submit them.
Secrets¶
armnet secret list
armnet secret create huggingface-token hf_...
armnet secret delete huggingface-token
Secret values are not printed by list.
Volumes¶
armnet volume upload ./checkpoint openpi/checkpoints/my-checkpoint
armnet volume cp openpi/checkpoints/my-checkpoint ./checkpoint
armnet volume ls # list the whole volume as a tree
armnet volume ls openpi/checkpoints # list a sub-tree
armnet volume delete openpi/checkpoints/my-checkpoint
Uploads skip files that already exist in the cloud volume with the same hash,
unless --overwrite is provided, and show a progress bar for large transfers.
When a job references a volume:// path, the cell mirrors it down from the
cloud (source of truth) before running and mirrors job outputs back up
afterwards — see Volumes.
Current-gate profile derivation¶
Install the optional dependency and derive a cell current-safety profile from the robot-telemetry sidecars in one or more Hugging Face datasets:
pip install 'armnet-client[current-gate]'
armnet-current-gate-derive \
--datasets datasets.json \
--output current_gate_profile.json
datasets.json is a JSON list of Hugging Face dataset repo IDs. Use
--cache-dir to reuse a specific Hub cache. The generated profile contains
per-arm, per-joint percentiles and maxima suitable for the cell's
robot.current_gate configuration; fleet operators should review it before
deploying it.
LeRobot Evaluation¶
armnet-policy-eval \
--policy.path=volume://policies/my-policy \
--armnet.embodiment=lerobot/so-101 \
--armnet.task=push_green_button \
--eval.n_episodes=10
Each eval episode is recorded as a LeRobot dataset using the same streaming
video encoding as data collection (software libsvtav1, which keeps episode
saves fast and produces training-friendly video). Override with
--armnet.vcodec, --armnet.encoder-threads, or disable streaming with
--armnet.streaming-encoding=false. The same options apply to
armnet-openpi-eval.
If your checkpoint is local, upload it while launching:
armnet-lerobot-eval \
--policy.path=./outputs/train/my_policy/checkpoints/005000/pretrained_model \
--armnet.volume_policy_path=policies/my-policy \
--armnet.embodiment=lerobot/so-101 \
--armnet.task=push_green_button \
--armnet.rail=0.3
--armnet.rail homes and positions a calibrated rail before evaluation; its
range is 0–1 from left to right. Only cells fitted with a rail accept it; omit
it to use the cell's own default position. The value is checked before the job
is queued against every cell that could take it, and rejected if it is outside
what structured variation would itself produce there.
Add --armnet.variation=true to perturb rail position, camera aim, and lighting
between episodes, and --armnet.variation-seed (default 42) to fix the
sequence. Use --armnet.variation-rail, --armnet.variation-cameras, and
--armnet.variation-lighting to isolate individual dimensions. See
Evaluate Policies
for the spread on each axis and what reproduces across runs.
OpenPI Evaluation¶
Evaluate an OpenPI (pi0 / pi0.5) checkpoint on a CUDA-capable cell. See Evaluate Policies:
armnet-policy-eval \
--policy.type=openpi \
--policy.path=volume://openpi/checkpoints/5000 \
--policy.config_name=pi05_so101_stacking_rings \
--armnet.n_episodes=3 \
--armnet.task=ring_insert \
--armnet.secrets="{HF_TOKEN: huggingface-token}"
GR00T Evaluation¶
Evaluate a NVIDIA GR00T N1.7 checkpoint by selecting the GR00T backend:
armnet-policy-eval \
--policy.type=groot \
--policy.path=https://huggingface.co/pravsels/groot1.7_insert_candle \
--armnet.embodiment=lerobot/so-101 \
--armnet.task=insert_candle \
--armnet.n_episodes=1
--policy.type=groot is N1.7. CRA GR00T N2 is --policy.type=cra and is
SO-101 BusyBox only.
CRA GR00T N2 Evaluation¶
armnet-policy-eval \
--policy.type=cra \
--policy.path=pravsels/cra_busybox_multitask_h48_cosine_20k \
--policy.num_inference_timesteps=4 \
--policy.actions_to_execute=16 \
--armnet.embodiment=lerobot/so-101 \
--armnet.task=busybox_left_toggle_down \
--armnet.n_episodes=1 \
--armnet.language_instruction='Turn the left toggle switch down to "Off" position' \
--armnet.secrets="{HF_TOKEN: huggingface-token}"
Each image build fetches CRA origin/main from external/cra (GitHub access
to NVIDIA/Isaac-GR00T-CRA is required). --policy.path may be a Hub repo id
(cached under the cell HF_HOME) or volume://cra/checkpoints/... (never
Hub-downloaded).
--policy.action_ticket_seed samples one action-noise tensor for the job.
--policy.action_ticket_path loads a volume:// .npz instead. They are
mutually exclusive, and either one rejects --policy.use_torch_compile. With
neither flag, action noise stays on the fixed policy seed 42. The result
reports an action_ticket fingerprint and does not include the raw tensor.
See
Evaluate Policies
for sampling, volume upload, and the hardware commands. Do not run those
commands until a human authorizes real hardware.
LeRobot Training with Remote Evals¶
armnet-lerobot-train \
--output_dir=outputs/train/my_policy \
--save_freq=2000 \
--armnet.eval.n_episodes=10 \
--armnet.eval.embodiment=lerobot/so-101 \
--armnet.eval.task=push_green_button
Remote Teleoperation¶
Drive a remote cell's follower from locally-attached leader arm(s), streaming the
follower back into Rerun — no data recorded (requires
pip install 'armnet-client[teleop]'). See
Teleoperate and Record Datasets:
armnet-lerobot-teleop \
--teleop.port=/dev/ttyACM0 \
--teleop.id=my_leader \
--armnet.duration_s=300
For a bimanual YAM cell, pass both local leader ports instead of
--teleop.port and set --armnet.embodiment=lerobot/bimanual_yam.
Use --rail 0.3 with teleoperation or recording to home and position the
cell's calibrated rail at 30% before the session starts. The accepted range is
0–1. Omit it to use the cell JSON rail.default_position_percent default
(0–100 percent); cells without rail calibration do not move.
Each configured rail homes once before the job container starts, moves to the job's requested position, and keeps torque enabled to hold that position. Later position requests within the job move directly only when the persisted settled position still matches both the rail calibration and stable live encoder continuity. Missing or interrupted state, changed calibration, or an encoder mismatch/unstable reading makes the rail safely re-home before continuing; the recovery is reported once in the job output. A request already at its target restores holding torque without traversing the rail. Environment reset plans may temporarily stage a rail at another pose, but the runtime restores the job position directly before the reset returns and the next episode begins.
Use --lightbox-brightness 30 and --lightbox-frequency 4000 to override the
cell's lightbox brightness (percent 0–100) and PWM frequency (Hz) for the
session. Omit either flag to keep that cell default. Cells without a lightbox
ignore both.
For an SO-101 session, --goal-velocity-limit 1001 and
--acceleration-limit 40 request per-job servo caps. Both values are raw
STS3215 register units: goal velocity accepts 1–3250 and acceleration accepts
1–254. The edge still enforces the cell-configured caps, so a job cannot loosen
them. These flags are rejected for bimanual YAM. A torque re-enable restores
the cell caps, so use these per-job flags for uninterrupted sweep runs rather
than as persistent safety settings.
During armnet-lerobot-teleop, press Right Arrow to print a ready-to-paste
joint keypoint (for authoring BusyBox reset motion plans). Pass
--capture-interval-s=1 to also auto-print a keypoint every second while the
leader is commanding.
LeRobot Dataset Recording (Remote Teleop)¶
Record a LeRobot dataset on a remote cell by driving its follower from a
locally-attached leader arm, or a left/right leader pair for bimanual cells
(requires pip install 'armnet-client[teleop]'):
armnet-lerobot-record \
--teleop.port=/dev/ttyACM0 \
--teleop.id=my_leader \
--dataset.repo_id=my_user/so101_pick_place \
--dataset.single_task="Grab the black cube" \
--dataset.num_episodes=10 \
--secret HF_TOKEN=huggingface-token
For bimanual recording, use --teleop.left-port and --teleop.right-port, and
name the task with --armnet.task; the orchestrator routes it to a cell set up
for that task's environment.
The dataset is recorded inside the cell — your machine only streams leader joint
positions — and pushed to the Hugging Face Hub when the session ends
(--no-push-to-hub to skip). Camera frames are encoded to video in real time so
saving an episode is near-instant.
LeRobot's standard recording shortcuts work during the session:
- Right Arrow: save the episode; the remote arm returns to rest and the next episode starts once the workspace is reset.
- Left Arrow: discard the episode and re-record it (same reset flow).
- Esc: stop the session, finalize and upload the dataset.
See Teleoperate and Record Datasets for the dataset options and the arm-current safety gate.