Set up a robot

CLI reference

Every arc command with its options, the files the command uses, and its environment variables.

arc is the one command on the robot computer. Activate the Python environment first, in every new shell:

source ~/arc_env/bin/activate

arc --help starts with the list of commands:

usage: arc run [CONFIG] [--log-dir DIR | --no-log] [relay flags...]
       arc doctor [CONFIG] [--identify] [relay flags...]
       arc setup [--output PATH] [--force] [--template PATH]
                 [--answers FILE] [--non-interactive]
       arc lagdiag LOG|LOG_DIR
       arc enroll [KEY] [--name NAME] [--backend BACKEND] [--yes]
       arc config status|sync|pull [CONFIG] [relay flags...]
       arc --version

CONFIG is the path of a robot.toml. When it is left out, ./robot.toml is used, so run the commands from the directory that holds the file. A message from a command starts with [arc]. A message from the running client starts with [yam-relay], whatever the arm type.

arc enroll

Registers this robot in your account and stores its identity in ~/.config/arc/identity/. See Enroll.

usage: arc enroll
       arc enroll KEY [--name NAME] [--backend BACKEND] [--yes]

arc enroll with nothing after it is the usual way: it asks for the key, the robot's name and the arm type, shows a summary and asks before it enrolls. arc enroll KEY is the form for a script.

ArgumentMeaning
KEYThe account's enrollment key. Asked for when left out.
--name NAMEThe robot's name in the account. Default: the computer's hostname.
--backend BACKENDThe arm type: yam, trossen, makermods or feather. Default: the one in ./robot.toml when that file exists, otherwise asked.
--yesReplace an existing identity, and enroll, without asking.

Exit code 0 when the robot is enrolled, 1 otherwise. Nothing is written when enrollment fails.

arc setup

Writes robot.toml for this robot, one step at a time. See Configure your robot.

usage: arc setup [-h] [--output PATH] [--force] [--template PATH]
                 [--backend {yam,makermods}] [--relay-config FILE]
                 [--answers FILE] [--non-interactive]
OptionMeaning
--output PATHThe file to write. Default: ./robot.toml. An existing file is resumed from: its values are kept and only the blanks are asked for.
--forceStart over from the template. The old file is kept as robot.toml.bak.
--template PATHStart from this file.
--backend {yam,makermods}The template to start from when there is no file to resume: makermods for MakerMods Metal arms, otherwise YAM.
--relay-config FILEFor a robot that is not enrolled: a file from Northstar with the relay values. Not needed on an enrolled robot.
--answers FILEA TOML or JSON file of answers, with keys such as arms.can_left or cameras.wristL.index. A key that is not in it is asked for.
--non-interactiveNever ask. A value with no answer stays blank, the file is written anyway, and one WARNING line names every blank.
-h, --helpShow the options and the steps.

The steps, as arc setup --help lists them:

steps, in order:
  cameras  find the cameras, save a snapshot of each, assign roles
  arms     list the CAN buses that are up, ask which is the left arm
  relay    nothing to ask on an enrolled robot (arc enroll); otherwise relay host, CA cert path and robot id, and the robot's identity cert
  review   every value and where it came from, then confirm
  write    write the file, blanks included and named; an existing file is kept as .bak

arc doctor

Checks what arc run with the same arguments would use, and starts nothing. It prints one line per check and a summary, and exits with code 1 if any check failed.

ArgumentMeaning
CONFIGThe robot.toml to check. Default: ./robot.toml.
--identifyAfter the checks, save one frame per camera to doctor-snapshots/ next to CONFIG, and for each YAM arm read its joint positions for two seconds while you move it by hand. Enables no motor and commands no motion.
relay flagsAny option of arc run. Doctor then checks the run with that option.

Each line is PASS, WARN, FAIL or SKIP, the name of the check, and a detail. SKIP means the check does not apply here, for example the arm address check on a robot with CAN arms. A FAIL line says what is missing and, where there is one, the command that fixes it.

CheckWhat it looks at
configThe file exists, loads, and has no blank value.
identityThe enrollment: robot id, account, certificate, and whether it is in use. SKIP on a robot that is not enrolled.
relay cert, client certThe certificates the run would use, and the expiry date.
relay address, check-inThe relay address resolves. Nothing is contacted.
config syncThe same state as arc config status. WARN when out of sync. Only on an enrolled robot.
can <link>The CAN link of each arm is up.
can busesThe two arms are not on the same CAN link.
can adaptersEach CAN link is still on the USB adapter it was on when arc setup wrote the file.
arm right, arm leftTrossen arms: each arm's address answers a ping.
camera exo, camera wristL, camera wristRA USB camera's device exists. A RealSense camera is not checked here. Use --identify.
camera slotsNo two roles name the same camera.
arm backendThe arm software for your arm type is installed.
client lockNo other arc run is running.
wifi bssid, wifi retries, wifi profiles, wifi powersave, net watchdogWi-Fi settings that can keep a robot offline after a drop. See Run as a service.

The config sync line on a robot whose file matches the console's copy:

[arc] PASS  config sync: in sync

On an enrolled robot doctor asks Northstar for that one state and changes nothing. It makes no other connection.

Do not run --identify while arc run is running. It refuses when another client holds the lock. See Troubleshooting for what to do about a failed check.

arc run

Checks that the robot can start, then starts the client: it opens the arms and the cameras, connects to the relay and waits for an operator. It runs until it is stopped. Ctrl+C stops it.

Before it starts anything, run stops with a one-line error if the file is missing or has a blank value, if the robot is not enrolled, or if another arc run is already running on this computer. A CAN link that is down is a warning with the command that brings it up. The client then keeps trying that arm until it opens.

On an enrolled robot run syncs robot.toml with the console first. See how settings sync.

ArgumentMeaning
CONFIGThe robot.toml to run from. Default: ./robot.toml.
--log-dir DIRWrite the session log to DIR instead of logs/ next to CONFIG.
--no-logDo not write a session log.
--local-config-onlySkip the settings sync for this start: do not upload the file and do not apply a change from the console.

Every other option overrides one value of robot.toml for this run. The file is not changed. The ones you may need:

OptionOverridesMeaning
--can-right NAME, --can-left NAME[arms] can_right, can_leftThe CAN link of each arm.
--arm-right-address IP, --arm-left-address IP[arms] right_address, left_addressTrossen arm addresses, or none.
--gripper NAME[arms] gripperThe YAM gripper type.
--gravity-comp[arms] gravity_compStart in gravity compensation: the arms are moved by hand and ignore the operator.
--startup-fault-reset[arms] startup_fault_resetClear one latched 0xD fault per motor at start.
--arm-isolation {process,thread}[arms] isolationWhere the arm drivers run.
--camera-exo N, --camera-wristl N, --camera-wristr N[[cameras]] indexA USB camera's device number or path.
--camera-exo-realsense SERIAL, --camera-wristl-realsense SERIAL, --camera-wristr-realsense SERIAL[[cameras]] serialA RealSense camera's serial number.
--camera-isolation {process,thread}[[cameras]] isolationFor all cameras at once.
--camera-color-format {bgr8,yuyv}[[cameras]] color_formatFor all RealSense cameras at once.
--camera-backend {auto,gst,cv2}(no key)How USB camera video is decoded. auto tries hardware decoding and falls back to the CPU. cv2 uses the CPU only.
--no-hwaccel(no key)The same as --camera-backend cv2.
--sim(no key)Mock arms on both sides. Nothing moves. Cameras and the connection run as usual.
--policy-port PORT[relay] policy_portSee Configure your robot.

arc run --help prints every option, including the connection options (--relay-host, --relay-cert and others). An enrolled robot gets those values from its identity, so leave them out.

Every run writes a session log, one file per start, to logs/ next to CONFIG. Its path is the first line printed:

[arc] Session log: ~/robot/logs/arc-20261007-214853-98807.log

The log holds everything the terminal shows and is readable only by your user. Old logs are not deleted.

arc config status

Shows whether robot.toml and the console's copy match, and whether a change from the console is waiting. Changes nothing.

arc config --help describes the three config commands:

usage: arc config status [CONFIG] [relay flags...]
       arc config sync   [CONFIG] [relay flags...]
       arc config pull   [CONFIG] [relay flags...]

  The console keeps a copy of this robot's robot.toml. Only a robot that
  uses its enrolled identity (arc enroll, [relay] cert blank) syncs.
  CONFIG is a robot.toml (default: ./robot.toml), as for arc run.

  status  the local hash, the hash and time of the synced copy, and whether
          a change made in the console is waiting. Changes nothing.
  sync    upload the local file now. It becomes the copy the console shows.
  pull    what arc run does at each start, without starting: upload
          when the file changed, or write a waiting change into robot.toml
          (the old file is kept as robot.toml.<date>-<time>.bak).
arc config status
[arc] config: ~/robot/robot.toml
[arc] local hash: 9c3534ec...
[arc] baseline hash: 9c3534ec..., synced 2026-10-08T02:47:58.254604+00:00
[arc] pending change: none
[arc] state: in sync

The hashes are shortened here. With a change waiting, the fourth line names it:

[arc] pending change: 8e2dc98d-c310-4e0e-9cee-ca1e304f597b, 2 setting(s), made 2026-10-08T02:48:19.754299+00:00
[arc] state: a change is waiting for the next start

Configure your robot lists the four states. Exit code 0, or 1 when the state could not be read.

The three config commands work on a robot that uses its enrolled identity. On a robot that was set up before enrollment they print one line saying that its settings are not synced.

arc config sync

Uploads robot.toml now. It becomes the copy the console shows.

arc config sync
[arc] config sync: settings uploaded (9c3534ec...), synced 2026-10-08T02:47:58.254604+00:00

If a change from the console was waiting and no longer fits the file, a second line says that it now needs review in the console. Exit code 0 when the file was uploaded, 1 otherwise.

arc config pull

Does what arc run does at each start, without starting: uploads the file if it changed, or writes a waiting change from the console into robot.toml. The old file is kept as robot.toml.<date>-<time>.bak.

arc config pull

With nothing to do:

[arc] config sync: in sync (9c3534ec7970)

With a change waiting:

[arc] config sync: applied 2 changes from the console to ~/robot/robot.toml (relay.record_fps = 20, relay.record_stream = true); the old file is kept as ~/robot/robot.toml.20261007-214820.bak

Exit code 1 when Northstar could not be asked, 0 otherwise. A change that was refused or that no longer fits the file is reported in one line and the exit code is still 0. Use arc config status to read the state in a script.

Run it while arc run is stopped. A running client read the file when it started and does not read it again.

arc lagdiag

Summarizes the timing lines of a session log. While it runs, the client prints one line per second that starts with [diag:loop]. lagdiag reads them and prints one row per measurement.

usage: arc lagdiag RELAY_LOG|LOG_DIR
ArgumentMeaning
RELAY_LOGA session log file.
LOG_DIRA directory of logs, such as logs/. The newest .log file in it is used.
arc lagdiag logs/

The first rows, from a ten second log with nobody driving:

log: logs/arc-20261007-214853-98807.log
10 [diag:loop] lines (one per second). worst is min for ctrl_pps and *_hz; for the rest it is max.
field                     median       min       max      n     worst
lag_p50_ms                   0.5       0.4       0.6     10       0.6
lag_p99_ms                   3.1       2.6      22.5     10      22.5
lag_max_ms                   3.1       2.6      22.5     10      22.5

More rows follow, one per field. na means there was no sample, for example no commands while nobody is driving.

FieldMeaning
lag_p50_ms, lag_p99_ms, lag_max_msHow late the client's main loop wakes up. High values mean something is holding it up.
getpos_<side>_*, faults_<side>_*, cmd_<side>_*Time spent reading an arm's position, reading its faults, and sending it a command.
cmd_age_p50_ms, cmd_age_p99_msFrom a command arriving at the robot to the arm command that follows it.
ctrl_ppsCommands received per second.
server_hz_<side>, dm_hz_<side>, overruns_<side>Loop rates of the arm's own process, and how many of its loop turns ran late.

<side> is right or left. Northstar may ask for this output when a session feels slow.

arc --version

Prints arc and the installed version. -V does the same.

Files

Paths that start with ./ are next to robot.toml.

PathWritten byWhat it is
./robot.tomlsetup, config pull, run at startThe robot's settings. See Configure your robot.
./robot.toml.baksetupThe file before the last arc setup.
./robot.toml.<date>-<time>.bakconfig pull, run at startThe file before a change from the console was applied. One per applied change. Not deleted for you.
./robot.toml.sync-appliedconfig pull, run at startA short note that exists only while an applied change has not been reported to the console yet. Leave it.
./logs/runSession logs, arc-<date>-<time>-<pid>.log.
./setup-snapshots/setupOne picture per camera found.
./doctor-snapshots/doctor --identifyOne picture per camera role.
~/.config/arc/identity/enrollThe robot's certificate, its private key, the relay's certificate and identity.json. See Enroll. Do not copy it to another robot.
~/.cache/larp/record-spool/runRecording frames that wait to be sent, with record_stream = true. Emptied at every start.
~/.cache/larp/depth-spool/runDepth frames that wait to be sent. Kept across restarts.
/etc/arc/net-watchdog.confthe installerSettings of the network watchdog. See Run as a service.

arc run also holds a lock file, arc-robot.lock, in $XDG_RUNTIME_DIR (or in an arc-<uid> directory under the system's temporary directory) while it runs. The lock is released when the process ends, also after a crash.

Environment variables

VariableUsed byMeaning
ARC_ENROLL_URLenrollThe address of the enrollment server. It is built into the command. Set it only when Northstar gives you another address.
XDG_CACHE_HOMErunWhen set, the two spool directories are under $XDG_CACHE_HOME/larp/ instead of ~/.cache/larp/.
XDG_RUNTIME_DIRrun, doctorWhere the lock file is kept.
HOMEallThe identity is read from ~/.config/arc/identity/ of the user that runs the command. Run every command, and the service, as the user that enrolled.

On this page

Robot client 0.2.8
docs.northstarrobotics.ai