Connect a robot
One guide per robot: the Axol pairs with one line; a reBot B601, a Maker Arm Station or any LeRobot arm records with a recording code in the task string and delivers from the browser or the command line.
Latent Energy is an independent marketplace, not affiliated with Almond or any other robot maker.
On this page
Almond Axol
One line installs the Latent agent and the control panel hooks, then pairs the robot with your provider account.
Install
The easy way: open your provider console, press Connect a robot and copy the line it shows. That line carries a single-use enrollment token (valid 60 minutes), so the robot appears in your console for one-click approval. On the robot, over SSH:
curl -fsSL https://latentenergy.com/robot/install.sh | sudo bash -s -- --enroll enr_...Without a token the same script installs and prints a pairing code; enter it at latentenergy.com/pair:
curl -fsSL https://latentenergy.com/robot/install.sh | sudo bashThe script checks that it runs on Linux with systemd, as root, on a robot where Almond's installer ran once, and refuses while an operation runs in the control panel. When almond-axol is missing or on a version Latent has not checked, it installs the verified one the way Almond does, with its provisioning and no reboot. It then downloads latent-axol 0.3.2 from https://latentenergy.com/tools and checks it against the hash written into the script, installs the hooks and the agent, starts them, and pairs. Read it first at /robot/install.sh. Nothing is typed but the robot's sudo password, once. The agent gets a fresh recording code for every take, puts it in the take's task string and delivers the take by itself. A robot that already runs latent-axol pairs without sudo: Connect a robot shows that line too.
First take
Once per headset, before the first take:
- Create or join a developer team (organization) on the Meta Horizon Developer Dashboard and verify the account there (SMS or a payment method). Meta shows the Developer mode switch only after that.
- Turn on Developer Mode for the Quest in the Meta Horizon app on your phone (Devices, Headset settings, Developer mode).
- Use a USB-C data cable from the Quest to the robot's USB port. A charge-only cable shows as "Quest not seen on the robot's USB".
- The first time you plug it in, put the headset on, press the Meta button, then Allow USB debugging and tick Always allow.
Every take, at the robot:
- Accept the order in the console, or press Practice take on the robot there to test the whole path with no buyer and no credits. There is no recording code to issue.
- Switch the power on, clear about 1 m around each shoulder, plug the Quest into the robot and put it on. The Latent start page opens in the headset within about 5 seconds, with the order and its Ready check. A red row names one fix.
- Tick Workspace clear and Power switch in reach, then hold Start for 2 seconds. Nothing moves before that. The page then narrates Almond's startup: arm hub firmware when one is due (arms quiet about a minute, do not touch), gripper calibration, the move to rest.
- When the page says the VR link is up, tap Approve the VR certificate (each time the headset browser restarts), then Open Axol VR, Quest over USB, Connect and Enter VR. To come back to the start page from VR, press the Meta button, exit VR, then switch to the Latent start tab.
- Record as usual: both grips to engage, A to record, A to save. Every take carries its code, shown on the station screen for the first 3 seconds. With no code armed, A does nothing and the start page says why.
- To try again, discard the take: its code goes back to the robot for the next attempt. A code is never added to a take after it was recorded.
- Delivery is automatic about 20 seconds after each save; the start page and the order page then say which unit was delivered and how its checks went.
- When the order is complete, press Y to return to rest, hold Stop on the start page, then switch the power off. If the start page tab was closed, plug the headset in again: the page comes back, also while a session runs.
A robot starts in observe mode after the install (LATENT_START=observe in /etc/latent-axol/env): holding Start only records what it would do and starts nothing, and the start page offers no Stop. Until Latent switches that robot to starting from the headset, start Collect data in the Axol control panel with Latent order set to auto (the start page links the panel), and end the session there: press Y, then Stop in the Axol panel, then switch the power off. The rest above stays the same.
The arms have no brakes, and the power supply's AC switch is the only stop. Keep it in reach whenever the power is on. Switching it off drops the arms, so do it with the arms at rest, or at once when something goes wrong. Closing a browser tab stops nothing, and the website never starts or stops the robot.
Contact stop: when an arm pushes harder than the station's contact limit, it stops and the start page and the station screen say "Contact stop: free the arms by hand, press X". The limit is the one Almond ships, or one you set for the station between 4 and 20 Nm; the start page shows it before the hold, and Latent never raises it.
Never press Update in the Axol control panel. It moves Almond's software off the version Latent checked, and the robot stops recording for Latent until it puts the verified version back, which it does by itself once the panel has been idle for 2 minutes, at most every 6 hours. While it does, the control panel is stopped for a few minutes and nothing can start; the Ready check says so.
Verified almond-axol versions
No signed release list is published yet. Until Latent publishes one, a robot accepts only the almond-axol versions compiled into its latent-axol (0.2.25 for latent-axol 0.3.0) and never installs anything by itself. When the control panel is updated to another almond-axol version, Latent recording turns off and the robot says so in the console, by email and at the SSH login.
Updates
A maintenance run on the robot reads the signed list every 30 minutes. With the default policy (LATENT_AUTO_UPDATE=needed) it installs a newer signed latent-axol only when the hooks are off for an unverified almond-axol version or the installed version was withdrawn, and restarts the control panel only when it is idle. off keeps the installed version; always takes every release. Set it in /etc/latent-axol/env.
A second timer, latent-almond-pin, puts almond-axol back on the verified version after a control panel Update moved it: only when the panel has answered idle for 2 minutes, at most every 6 hours, and never with a reboot. LATENT_ALMOND_REPIN=off in the same file turns it off.
Roll back and remove
sudo -u <operator> /opt/latent/bin/latent-axol unpair # revoke first
sudo systemctl disable --now latent-axol-maint.timer latent-almond-pin.timer
sudo rm /etc/systemd/system/axol.service.d/latent.conf && sudo systemctl daemon-reload && sudo systemctl restart axol # stock panel
sudo systemctl disable --now latent-axol-agent
sudo /usr/local/bin/uv pip uninstall --python /opt/axol/uv/tools/almond-axol/bin/python latent-axol
sudo env UV_TOOL_DIR=/opt/latent/uv/tools UV_TOOL_BIN_DIR=/opt/latent/bin /usr/local/bin/uv tool uninstall latent-axol
sudo rm -rf /opt/latent /etc/latent-axol /var/lib/latent-axol /etc/update-motd.d/90-latent-axol \
/etc/systemd/system/latent-axol-agent.service /etc/systemd/system/latent-axol-maint.service \
/etc/systemd/system/latent-axol-maint.timer /etc/systemd/system/latent-almond-pin.service \
/etc/systemd/system/latent-almond-pin.timer
sudo systemctl daemon-reloadRevoking the robot in the console (Robots, Revoke) stops its credential and key at once, also when the robot is offline. A robot can be connected again later; within 24 hours it can still deliver the takes it recorded before the revocation, unless it was revoked as compromised.
Seeed reBot B601
LeRobot main, lerobot-record, a recording code in the task string, one dataset per code.
Seeed Studio's reBot Arm B601 is a 6-joint arm with a gripper, sold as a DM build (Damiao motors, 24 V, a serial bridge on /dev/ttyACM0) or an RS build (RobStride motors, 48 V, native CAN on can0), single or bimanual, led by a reBot Arm 102 leader. It is in LeRobot main, so a take is a plain LeRobot v3 dataset: 7 or 14 values in degrees and one video per camera. Latent lists it as Seeed reBot B601.
Before the first take
- Power and mounting are not in the kit: a 24 V supply for DM (Seeed recommends a Mean Well LRS-350-24) or 48 V for RS (LRS-350-48; 25 A for full performance), two G clamps or a modified base, and the leader's own 12 V 10 A supply. Set the supply's mains selector before plugging in.
- There is no emergency stop in the kit or in the software. When the leader read fails, LeRobot logs an emergency-stop message and keeps sending the last positions; with torque off the arm moves under gravity, so support it. Seeed sells a protection and e-stop module for the DM build. Keep clear of the arm while debugging, never hot-plug the XT30 power, and after any power loss stop the program and return the arm to zero before reconnecting.
- Host: Ubuntu 22.04 or 24.04 on x86, or a Jetson Orin on JetPack 6.0 or 6.1, with Python 3.12. No virtual machine.
- Calibrate once per arm after assembly, at the zero pose with the gripper closed; the calibration is reused by
--robot.idand--teleop.id. - Cameras: any OpenCV camera; 640 x 480 MJPG at 30 fps is the documented setting, and two cameras on one USB hub is not recommended. Name the overview
topand the wristwrist(bimanual:top,left_wrist,right_wrist). The names become the dataset keys; the checker and the task review readtop,overhead,frontandsideas the overview andwristas a wrist, and a cell profile overrides the names.
pip install -e ".[rebot]" # on huggingface/lerobot main: motorbridge and motorbridge-smart-servo
lerobot-find-port # DM serial bridge /dev/ttyACM*, leader /dev/ttyUSB*; remove brltty on Linux
sudo ip link set can0 type can bitrate 1000000 && sudo ip link set can0 up # RS only, every boot
lerobot-calibrate --robot.type=rebot_b601_follower --robot.motor_family=dm --robot.port=/dev/ttyACM0 --robot.id=follower
lerobot-calibrate --teleop.type=rebot_102_leader --teleop.port=/dev/ttyUSB0 --teleop.id=leader
lerobot-find-cameras opencvTwo code paths, four robot types
The LeRobot docs page installs huggingface/lerobot main and records with rebot_b601_follower or bi_rebot_b601_follower (leaders rebot_102_leader, bi_rebot_102_leader). The Seeed wiki installs Seeed's fork with two plugin packages and records with seeed_b601_dm_follower or seeed_b601_rs_follower (leader rebot_arm_102_leader, single arm only). The dataset's robot_type is whichever you used; the checker knows all four. Seeed's no-code SenseCraft Robotics app also records for this arm; what it writes is not documented. A SenseCraft Robotics recording delivers like any LeRobot v3 folder; its robot_type is not one the checker knows, so platform_profile reports a note, or a warning when the state names differ, and the buyer decides.
Latent setup
An API key from Account settings with Read, Order and Cell keys ticked, a cell key file registered and activated in the provider console, a cell profile on that key (Cell keys, the key, Profile: pick reBot Arm B601, single arm or bimanual from the Robot platform select; it drafts the streams and the state mode), then the recording codes. The provider guide has the key and seed steps in full.
export LATENT_API_KEY=vc_... # account settings: tick Read, Order and Cell keys
node latent.mjs keygen
node latent.mjs key register --label "reBot bench" --robot b601-01 # then activate it in the console (Cell keys)
node latent.mjs seeds <order> 3 # one card per recording codeOne take, single arm, DM build
One dataset per recording code. The code rides in the task string, so it is inside the hashed bytes; the order page prints this line with the real code and instruction under each open seed (Record command). --dataset.rgb_encoder.vcodec=h264 matters: lerobot-record writes AV1 by default, and an order that excludes AV1 fails the video check. Show the printed card to a camera for the first 3 seconds of the take.
lerobot-record \
--robot.type=rebot_b601_follower --robot.motor_family=dm --robot.port=/dev/ttyACM0 --robot.id=follower \
--robot.cameras='{"top": {"type": "opencv", "index_or_path": 0, "width": 640, "height": 480, "fps": 30, "fourcc": "MJPG"}, "wrist": {"type": "opencv", "index_or_path": 2, "width": 640, "height": 480, "fps": 30, "fourcc": "MJPG"}}' \
--teleop.type=rebot_102_leader --teleop.port=/dev/ttyUSB0 --teleop.id=leader \
--dataset.repo_id='local/<episode id>' --dataset.root='/home/<user>/latent/takes/<episode id>' --dataset.no_stamp=true \
--dataset.single_task='<instruction> [latent:<nonce>]' \
--dataset.fps=30 --dataset.num_episodes=1 --dataset.episode_time_s=60 \
--dataset.rgb_encoder.vcodec=h264 --dataset.push_to_hub=false --display_data=falseRS build: --robot.motor_family=rs --robot.port=can0. Seeed wiki path: the same flags with --robot.type=seeed_b601_dm_follower --robot.can_adapter=damiao (or seeed_b601_rs_follower --robot.port=can0 --robot.can_adapter=socketcan) and --teleop.type=rebot_arm_102_leader; whether that fork has --dataset.no_stamp and --dataset.rgb_encoder.vcodec is not verified, so without them the folder gets a timestamp suffix and the codec is the fork's default.
One take, bimanual
lerobot-record \
--robot.type=bi_rebot_b601_follower --robot.id=bi_follower \
--robot.left_arm_config.motor_family=dm --robot.left_arm_config.port=/dev/ttyACM0 \
--robot.right_arm_config.motor_family=dm --robot.right_arm_config.port=/dev/ttyACM1 \
--robot.cameras='{"top": {"type": "opencv", "index_or_path": 0, "width": 640, "height": 480, "fps": 30, "fourcc": "MJPG"}}' \
--robot.left_arm_config.cameras='{"wrist": {"type": "opencv", "index_or_path": 2, "width": 640, "height": 480, "fps": 30, "fourcc": "MJPG"}}' \
--robot.right_arm_config.cameras='{"wrist": {"type": "opencv", "index_or_path": 4, "width": 640, "height": 480, "fps": 30, "fourcc": "MJPG"}}' \
--teleop.type=bi_rebot_102_leader --teleop.id=bi_leader \
--teleop.left_arm_config.port=/dev/ttyUSB0 --teleop.right_arm_config.port=/dev/ttyUSB1 \
--dataset.repo_id='local/<episode id>' --dataset.root='/home/<user>/latent/takes/<episode id>' --dataset.no_stamp=true \
--dataset.single_task='<instruction> [latent:<nonce>]' \
--dataset.fps=30 --dataset.num_episodes=1 --dataset.episode_time_s=60 \
--dataset.rgb_encoder.vcodec=h264 --dataset.push_to_hub=false --display_data=falseTwo arms on CAN need separate channels (can0, can1) because both use the same motor ids. The dataset keys are observation.images.top, left_wrist and right_wrist; the state carries 14 values, left_ then right_.
Deliver
node latent.mjs deliver <order> /home/<user>/latent/takes/<episode id> --seed <episode id>Or drop the folder on the order page: the browser reads meta/info.json, says whether it reads as a reBot Arm B601 take, refuses a root with more than one episode, hashes every file and uploads into Latent custody. Manifest values: format lerobot_v3, camera count equal to the number of observation.images.* keys (2 single, 3 bimanual), robot id your --robot.id.
What the checks say
| Check | On a reBot B601 take |
|---|---|
platform_profile | pass when robot_type is one of the four and the 7 or 14 names fit; a note for an unknown robot_type; a warning on a mismatch (under the buyer's platform term, anything but a match pauses the unit) |
lerobot_structure | the LeRobot v3 layout lerobot-record writes, named for the platform |
idle | reads degrees: the thresholds are scaled, so a still arm is still |
torque_contact | skipped, no effort stream (the follower publishes positions only) |
imu_fk | skipped, no IMU stream |
stereo_planarity, stereo_identical | skipped, no stereo pair |
frame_count | near zero drop: the recorder repeats a slow camera's last frame rather than dropping it, so repeated frames are the honest camera-health signal (not measured yet) |
task_nonce, seed_in_frame | the code in the task string and the card in the overview camera's first 3 seconds |
Open items
- SenseCraft Robotics output: its format and robot_type are unread, so a take from it gets a platform_profile note, never a match, until one has been seen.
- Seeed's fork: the no_stamp and vcodec flags are unverified there.
- Seed card size at 640 x 480: the printed sizes assume the Axol's lens; the first take's seed_in_frame row reports the pixels per module the camera saw.
- Gripper sign: 0 closed and -270 open on LeRobot main, 0 to +270 on the Seeed RS plugin; no joint range rule exists until this is read from a real take.
Maker Arm Station (MakerMods)
MakerMods Lab or the makermods-robotics fork of LeRobot; name the cameras first, keep the take off the Hub.
MakerMods' Maker Arm Station is two Maker Arms (6 RobStride joints plus a gripper each, 1.5 kg payload), two Star Arm 102 leaders, two wrist cameras and one overhead camera, 48 V supplies and a hardware e-stop. It records as LeRobot v3 through MakerMods Lab or through MakerMods' fork of LeRobot; the robot types maker_follower and bi_maker_follower exist only in that fork, not in LeRobot main. A take carries 7 or 14 values in degrees. Latent lists it as Maker Arm Station (MakerMods).
Before the first take
- The motors must be in the RobStride MIT protocol for LeRobot. The switch is one documented CAN frame, persistent, followed by a power cycle; after it the vendor
maker-armCLI no longer sees the motors (the two protocols are exclusive). Whether stations ship already switched is not stated. - One CAN bus per arm, so a bimanual rig needs two adapters: slcan serial by default (
/dev/ttyACM0,/dev/cu.usbmodem...), SocketCANcan0on Linux, or ags_usb:<serial>adapter through the Lab. Two UART ports for the leaders. Classic CAN at 1 Mbps, motor ids 1 to 7. - A Linux or macOS computer; Python 3.12 or 3.13 for the Lab. The record loop runs at the dataset fps (30); the page's 200 Hz loop belongs to the vendor SDK.
- Name the cameras before the first take: the names become the dataset keys. In the Lab's bimanual mode every camera, the overhead included, is keyed
left_<name>(record namestop,left_wrist,right_wristgiveleft_top,left_left_wrist,left_right_wrist). The fork's CLI keeps a top-level camera unprefixed. Order terms and cell profiles must use the keys as written. - Calibration is a zero pose (the folded resting pose, no range sweep). The Lab's prompt says gripper fully closed and its measured open readings are about -99 to -102 degrees; the fork's prompt says fully open at zero. Follow the Lab until MakerMods settles it; Latent has no joint range rule for this arm yet.
- No brakes: torque off lets the arm fall. The Lab returns the arm to rest before releasing torque.
Path A: MakerMods Lab
uv tool install "git+https://github.com/makermods-robotics/makermodslab"
makermodslab # the UI and the API on port 8000; makermodslab-station = --lan --offlineCreate the robot record in Robot settings (arm type maker, mode bimanual, the follower and leader ports, leader kind star, the three cameras with their names, width, height and fps), calibrate each arm and leader in the wizard, then start a recording session with these fields. One dataset per recording code: a fresh dataset_repo_id per seed with num_episodes: 1, or per_episode_task on and each episode's instruction typed with its own code at the naming prompt. The order page prints the fields with the real code under each open seed.
# MakerMods Lab, recording session (Record, or POST /api/v1/sessions with kind recording)
dataset_repo_id: <episode id>
single_task: <instruction> [latent:<nonce>]
num_episodes: 1
fps: 30
video: true
push_to_hub: false
streaming_encoding: trueThe Lab writes H.264 and keeps the dataset under ~/.cache/huggingface/lerobot/<dataset_repo_id>_<stamp>/. Do not press Upload to Hub, and never start a training run on Hugging Face Jobs or hand one to a LAN peer from a Latent take: both push a local-only dataset to the Hub as public, by the Lab's own design. Local training only, or --offline. Remote inference streams the cameras to a Modal GPU; keep it off during a take.
Path B: the fork's lerobot-record
git clone https://github.com/makermods-robotics/lerobot && cd lerobot
git checkout 5ce2fe41a63647c20b2ab6e84bcb4cc7295a9b21
pip install -e ".[maker,rebot]"
lerobot-calibrate --robot.type=maker_follower --robot.port=/dev/ttyACM0 --robot.id=left
lerobot-calibrate --robot.type=maker_follower --robot.port=/dev/ttyACM1 --robot.id=right
lerobot-calibrate --teleop.type=rebot_102_leader_maker --teleop.port=/dev/ttyUSB0 --teleop.id=star_left
lerobot-calibrate --teleop.type=rebot_102_leader_maker --teleop.port=/dev/ttyUSB1 --teleop.id=star_rightlerobot-record \
--robot.type=bi_maker_follower --robot.id=station \
--robot.left_arm_config.port=/dev/ttyACM0 --robot.right_arm_config.port=/dev/ttyACM1 \
--robot.cameras='{"top": {"type": "opencv", "index_or_path": 0, "width": 640, "height": 480, "fps": 30}}' \
--robot.left_arm_config.cameras='{"wrist": {"type": "opencv", "index_or_path": 2, "width": 640, "height": 480, "fps": 30}}' \
--robot.right_arm_config.cameras='{"wrist": {"type": "opencv", "index_or_path": 4, "width": 640, "height": 480, "fps": 30}}' \
--teleop.type=bi_rebot_102_leader_maker --teleop.id=bi_star \
--teleop.left_arm_config.port=/dev/ttyUSB0 --teleop.right_arm_config.port=/dev/ttyUSB1 \
--dataset.repo_id='local/<episode id>' --dataset.root='/home/<user>/latent/takes/<episode id>' --dataset.no_stamp=true \
--dataset.single_task='<instruction> [latent:<nonce>]' \
--dataset.fps=30 --dataset.num_episodes=1 --dataset.episode_time_s=60 \
--dataset.rgb_encoder.vcodec=h264 --dataset.push_to_hub=false --display_data=false--dataset.push_to_hub=false because the CLI's default is to push; --dataset.rgb_encoder.vcodec=h264 because the default is AV1; --dataset.no_stamp=true because the fork, like LeRobot main, stamps the repo id with the time unless told not to (stamp_repo_id in its dataset config), and with --dataset.root the folder is the one you name. One arm: --robot.type=maker_follower with --teleop.type=rebot_102_leader_maker (the Record command on the order page has it). Cameras are OpenCV indexes in every line, as lerobot-find-cameras lists them; on Linux a /dev/video path works too.
Latent setup and delivery
As for any cell: an API key with Read, Order and Cell keys ticked, a cell key file registered and activated in the console, a cell profile on the key (pick Maker Arm Station, MakerMods Lab, bimanual or a lerobot-record variant from the Robot platform select; the Lab variant drafts the left_ keys), the recording codes, the card in the overhead camera for the first 3 seconds. The provider guide has the steps.
node latent.mjs deliver <order> ~/.cache/huggingface/lerobot/<episode id>_<stamp> --seed <episode id> # a Lab recording
node latent.mjs deliver <order> /home/<user>/latent/takes/<episode id> --seed <episode id> # a lerobot-record takeWhat the checks say
| Check | On a Maker Arm Station take |
|---|---|
platform_profile | pass when robot_type is maker_follower or bi_maker_follower and the 7 or 14 names fit; a warning on a mismatch (under the buyer's platform term, anything but a match pauses the unit) |
cell_profile | warns when the delivered keys differ from the profile's (the left_ prefix is the usual cause) |
idle | reads degrees; a missed CAN reply repeats one joint value for a frame, which the filter tolerates |
torque_contact, imu_fk | skipped: no effort stream, no IMU stream |
stereo_planarity, stereo_identical | skipped, no stereo pair |
video_decodable | H.264 from the Lab; a CLI take without the codec flag is AV1 and may be excluded by the order |
Open items
- The gripper zero convention (closed by the Lab's numbers, open by the fork's words) blocks any joint range rule.
- Which CAN adapters ship, and in which protocol the motors arrive.
- Camera models and resolutions, so the seed card sizes can be stated for the overhead and wrist views.
- The fork is pinned by commit 5ce2fe41a; the Lab's staging branch may differ from main.
Other LeRobot arms
Any LeRobot v3 recorder delivers; the checker reads an unknown robot type as a note.
An SO-101, a reBot Arm 102 pair, a Koch, a LeKiwi or any other arm LeRobot drives records with lerobot-record and delivers the same way: a LeRobot v3 folder, one episode per recording code, hashed in the browser or by the cell CLI, signed by the cell key. List it as SO-101 / reBot, Universal Robots or similar cobot, Franka FR3 / DROID, xArm or Other, whichever fits.
Latent setup
export LATENT_API_KEY=vc_... # account settings: tick Read, Order and Cell keys
node latent.mjs keygen && node latent.mjs key register --label "<cell>" --robot <robot id>
node latent.mjs seeds <order> 3Activate the key in the provider console and give it a cell profile (Cell keys, the key, Profile): the stream keys with their roles (overview, wrist) and the state mode. The Robot platform select drafts the common two-camera layout under Other LeRobot arm; edit the keys to match yours. The provider guide and the cell setup page in the repository have the long form.
The flags that matter
lerobot-record \
--robot.type=<robot type> --robot.port=<port> --robot.id=follower \
--robot.cameras='{"top": {"type": "opencv", "index_or_path": 0, "width": 640, "height": 480, "fps": 30}, "wrist": {"type": "opencv", "index_or_path": 2, "width": 640, "height": 480, "fps": 30}}' \
--teleop.type=<leader type> --teleop.port=<port> --teleop.id=leader \
--dataset.repo_id='local/<episode id>' --dataset.root='/home/<user>/latent/takes/<episode id>' --dataset.no_stamp=true \
--dataset.single_task='<instruction> [latent:<nonce>]' \
--dataset.fps=30 --dataset.num_episodes=1 --dataset.episode_time_s=60 \
--dataset.rgb_encoder.vcodec=h264 --dataset.push_to_hub=false --display_data=false--dataset.single_taskcarries the recording code as[latent:<nonce>]: it lands inmeta/tasks.parquetand the data parquet's task index, inside the hashed bytes, so thetask_noncecheck passes. Tags only reach the Hub card.--dataset.num_episodes=1and a fresh folder per code: the browser refuses a root with several episodes, and the recorder rewrites shared metadata on every save.--dataset.push_to_hub=false: the default pushes your take to the Hugging Face Hub.--dataset.rgb_encoder.vcodec=h264: the default is AV1, which an order may exclude and which Latent's checker is not required to decode.- Name the overview camera
top(oroverhead,front,side) and the wristswrist,left_wrist,right_wrist: the checker reads roles from the names when the key has no profile.
What the checks say
Everything structural runs as for any LeRobot v3 dataset. platform_profile is skipped (no platform profile applies) unless the order names a reBot B601 or a Maker Arm Station, and an unknown robot_type is a note, never a fail. Joint values are read as radians when no profile says otherwise, so an arm that reports degrees may read as always active in the idle row; a cell profile that declares one of the platforms above fixes that for those arms.
What the checker expects
Per platform: the robot_type strings its recorders write, the state values, the default camera keys and the units. The reBot B601 and the Maker Arm Station are compared; the Axol's comparison is off until a real take has been read.
| Platform | robot_type | State | Default cameras | Units | Compared |
|---|---|---|---|---|---|
| Almond Axol | axol | 14 or 16 values: shoulder_1, shoulder_2, shoulder_3, elbow, wrist_1, wrist_2, wrist_3, gripper per arm | overhead_left, overhead_right, left_arm, right_arm | radians; gripper span 1 | not yet |
| reBot Arm B601 | rebot_b601_follower, seeed_b601_dm_follower, seeed_b601_rs_follower, bi_rebot_b601_follower | 7 or 14 values: shoulder_pan, shoulder_lift, elbow_flex, wrist_flex, wrist_yaw, wrist_roll, gripper per arm | top, wrist; top, left_wrist, right_wrist | degrees; gripper span 270 | yes |
| Maker Arm Station | bi_maker_follower, maker_follower | 7 or 14 values: shoulder_pan, shoulder_lift, elbow_flex, wrist_flex, wrist_yaw, wrist_roll, gripper per arm | left_top, left_left_wrist, left_right_wrist; top, left_wrist, right_wrist; top, wrist | degrees; gripper span 120 | yes |
The platform_profile row compares a delivered dataset's meta/info.json with the platform the signing key declares, or the order names: a match, a note when only the robot type is unknown, a warning when the robot type belongs to another platform or the state names or dimensions differ. It pauses auto-accept only when the buyer set the order term platform_match_required; under that term it fails closed, so a mismatch, an unknown robot type, a dataset it could not read or a check that did not run all pause the unit for a Latent review, and only a match is accepted at the deadline. Camera keys and fps are reported, never judged. Nothing here moves credits.
Sources
Where each guide's facts come from, read on 28 October 2026. Nothing above has been measured on hardware by Latent yet.
- tools/latent-checker/latent_checker/synth.py
- tools/latent-axol/tests/fixtures.py
- docs/verification-p2p3-contract.md section 10
- https://huggingface.co/docs/lerobot/main/rebot_b601
- huggingface/lerobot main: src/lerobot/robots/rebot_b601_follower, bi_rebot_b601_follower, teleoperators/rebot_102_leader
- https://wiki.seeedstudio.com/rebot_arm_b601_dm_lerobot/ and rebot_arm_b601_rs_lerobot/
- github.com/Seeed-Projects/reBot-DevArm, lerobot-robot-seeed-b601, lerobot-teleoperator-rebot-arm-102
- https://www.makermods.ai/maker-arm-station
- github.com/makermods-robotics/makermodslab (main, 28 October 2026)
- github.com/makermods-robotics/lerobot at 5ce2fe41a63647c20b2ab6e84bcb4cc7295a9b21 (arm/makermods-combined)
- github.com/makermods-robotics/maker-arm-sdk
- docs/cells.md