
Build and configure a Koch v1.1 arm: XL330 and XL430 servos, the 5 V and 12 V rails, the LeRobot koch_follower commands, and why the dataset is identical to an SO-100.
What you need to know
- •The Koch v1.1 is the Dynamixel cousin of the SO-100: six servos, five arm joints plus a gripper, same LeRobot software, different motors and power topology.
- •Leader: six XL330-M077-T on 5 V. Follower: two XL430-W250-T on 12 V plus four XL330-M288-T on 5 V from a step-down converter, all six on one TTL data line.
- •The XL330 family is rated 3.7 to 6.0 V. Putting the follower's 12 V rail on an XL330 branch is the wiring mistake that costs real money.
- •Arm joints run Extended Position mode (4), the gripper Current-based Position mode (5), which the XL430 cannot do at all.
- •Downstream nothing changes: the dataset carries the same shoulder_pan.pos to gripper.pos keys as an SO-100 recording.
The SO-100 is the arm most LeRobot tutorials assume. The Koch v1.1 came first: a six-servo, 3D-printed, leader-follower arm built around ROBOTIS Dynamixel motors. This page covers what differs: the servo lineup, the two power rails, the operating modes LeRobot burns into motor EEPROM, and the large part of the stack that does not change.
Everything below was checked against the Koch v1.1 build repository and its wiring diagram PDF (drawn 2024-07-08 by Jess Moss for Hugging Face), the ROBOTIS e-Manual pages for the three servo models, and the LeRobot sources on main, version string 0.6.2, with the newest tagged release at v0.6.1. Where those sources disagree, and they do in one place, it is flagged.
The arm, and where it came from
The original low-cost arm is Alexander Koch's low_cost_robot from Tau Robotics, credited as such in LeRobot's class docstrings. Jess Moss rebuilt it for Hugging Face as Koch v1.1: fixed screw interferences, standardised hole sizes, no screws into plastic, a printed leader platform so the follower can reach the ground, and a replacement DC converter that removes the soldering iron and the manual voltage trim. LeRobot names both versions, so koch_follower covers each.
| Part | Leader | Follower |
|---|---|---|
| Primary servos | 6x XL330-M077-T (18 g each) | 2x XL430-W250-T at the shoulders (57.2 g each) |
| Secondary servos | none | 4x XL330-M288-T (elbow, wrist flex, wrist roll, gripper) |
| Horn / idler hardware | XL330 frame and idler wheel set | XL330 set plus a separate XL430 idler wheel set |
| Controller board | Waveshare Serial Bus Servo Driver Board | Waveshare Serial Bus Servo Driver Board |
| Power supply | 5 V | 12 V |
| Voltage conversion | none | 12 V to 5 V reducer (EP-JY-DC5) |
| Repo BOM total (US / EU / UK) | 199 USD / 305 EUR / 222 GBP | 278 USD / 368 EUR / 285 GBP |
AY-Robots treats the SO-100 as the reference arm and the Koch v1.1 as a compatible one: the flows work, but the reference and demo hardware are SO-100. Undecided on hardware? Read SO-100 vs Koch v1.1 first, and the SO-100 complete guide for the reference flow this page keeps referring back to. The catalog lists the Koch at roughly 250 to 350 EUR of parts; the repo BOM sums to 305 EUR leader and 368 EUR follower because it also counts clamps, screwdrivers and cables, which its footnotes say you buy once across both arms.
Dynamixel bus versus Feetech bus
Both are serial bus arms: one three-wire chain carrying power, ground and a half-duplex TTL data line, each servo answering on its own ID. That is where the similarity ends. Protocol, SDK, model numbers and control modes all differ, which is why LeRobot keeps two bus implementations.
| Koch v1.1 (Dynamixel) | SO-100 / SO-101 (Feetech) | |
|---|---|---|
| Servos | xl330-m077, xl330-m288, xl430-w250 | sts3215 on all six joints |
| Wire protocol in LeRobot | PROTOCOL_VERSION = 2.0 | DEFAULT_PROTOCOL_VERSION = 0 |
| Python SDK extra | dynamixel-sdk >=3.7.31,<3.9.0 | feetech-servo-sdk >=1.0.0,<2.0.0 |
| Model numbers LeRobot checks | 1190 / 1200 / 1060 | 777 |
| Encoder resolution | 4096 counts per revolution | 4096 counts per revolution |
| Baud rate | Factory 57,600 bps, LeRobot writes 1,000,000 | LeRobot writes 1,000,000 |
| Arm joint operating mode | Extended Position, value 4 | Position, value 0 in the Feetech enum |
| Gripper operating mode | Current-based Position, value 5 | Position, value 0, plus torque and current limits |
| Per-joint gains LeRobot writes | Position P/I/D on elbow_flex only | P/I/D 16 / 0 / 32 on every motor |
| Power rails | 5 V and 12 V | single 7.4 V rail |
Two rows deserve a second look. Operating-mode numbers are not comparable across the buses: the Dynamixel enum numbers position control 3 and extended position 4, while the Feetech enum starts at POSITION = 0 and uses 1, 2, 3 for velocity, PWM and step mode. And LeRobot drives both at 1 Mbps although Dynamixel servos ship at 57,600 bps with ID 1, so lerobot-setup-motors is not cosmetics: it writes ID and baud rate into EEPROM once per motor, and a motor you skip will not answer afterwards.
The XL430-W250-T is the hard constraint. Its e-Manual lists four operating modes, velocity, position, extended position and PWM, with no current control and no current-based position control. LeRobot's table agrees, giving it 1, 3, 4, 16 against 0, 1, 3, 4, 5, 16 for the XL330s. That is why the gripper is an XL330-M288 and the XL430s sit at the shoulder.
Two rails on one bus, and the mistake that ends a build
The leader is the simple one: six XL330-M077-T motors, one Waveshare driver board, one 5 V supply, daisy-chained. The repo notes that the board's data sheet asks for 9 to 12.6 V input, and that running it at 5 V anyway is harmless to the board and necessary, because the board's servo rail is what reaches the motors.
The follower is where the topology forks, and the driver board is the distribution point rather than a bystander. The 12 V supply goes into the board's power input. The board presents two three-pin servo headers carrying DATA, 12 V and GND: one runs to the two XL430 shoulder motors, the other feeds the step-down converter, whose 5 V output powers the four XL330s further out while the data line passes through. One bus, two power domains, boundary between joint 2 and joint 3.
The XL330-M077-T and XL330-M288-T are rated 3.7 to 6.0 V input, recommended 5.0 V. The XL430-W250-T is rated 6.5 to 12.0 V, recommended 11.1 V. Wire an XL330 branch to the raw 12 V rail, or swap the converter input and output, and you apply exactly double the maximum rated voltage to an 18 g servo. Meter the converter output before the first XL330 goes on the chain. The same error kills the 7.4 V STS3215 servos on an SO-100, so the habit transfers.
12 V PSU
|
+--> Waveshare Serial Bus Servo Driver Board, PWR input
(board data sheet asks for 9 to 12.6 V)
|
|-- servo header: DATA / 12 V / GND
| +--> XL430-W250-T id 1 shoulder_pan 12 V
| +--> XL430-W250-T id 2 shoulder_lift 12 V
|
+-- servo header: DATA / 12 V / GND
+--> Voltage reducer EP-JY-DC5
| IN+ 12 V -> OUT+ 5 V
| IN- GND -> OUT- GND
|
+--> DATA passes through; the 5 V output powers:
XL330-M288-T id 3 elbow_flex 5 V
XL330-M288-T id 4 wrist_flex 5 V
XL330-M288-T id 5 wrist_roll 5 V
XL330-M288-T id 6 gripper 5 V
One half-duplex TTL DATA line reaches all six motors, Protocol 2.0.
USB-C from the driver board to the host computer.
Leader arm: same board, one 5 V supply, six XL330-M077-T, no converter.Bring-up, command by command
The commands below are the console entry points LeRobot installs on main. Anything that still calls python lerobot/scripts/control_robot.py with a --control.type flag describes an older release; that file is gone. Python 3.12 or newer is required, enforced by the package metadata.
- 1Install LeRobot with the Dynamixel SDK
The base package is thin. You need the composite extra that maps to the CLI scripts, plus the Dynamixel motor extra. SO-100 owners install the Feetech extra instead.
bashconda create -y -n lerobot python=3.12 conda activate lerobot git clone https://github.com/huggingface/lerobot.git cd lerobot pip install -e ".[core_scripts]" pip install -e ".[dynamixel]" - 2Find the two serial ports
One port per arm. The script has you unplug a cable so it can diff the port list, which beats guessing between two identical usbmodem names. On Linux the device is usually /dev/ttyACM0; on a permission error, add your user to the dialout group.
bashlerobot-find-port # Example output on macOS: # ['/dev/tty.usbmodem575E0032081', '/dev/tty.usbmodem575E0031751'] # Remove the USB cable from your MotorsBus and press Enter when done. - 3Write IDs and baud rate, one motor at a time
Every motor ships as ID 1 at 57,600 bps. The script walks the joints in reverse, gripper first, and each must be the only motor on the board when you press Enter. On a Waveshare board, both jumpers go on the B channel (USB).
bashlerobot-setup-motors \ --robot.type=koch_follower \ --robot.port=/dev/tty.usbmodem575E0031751 lerobot-setup-motors \ --teleop.type=koch_leader \ --teleop.port=/dev/tty.usbmodem575E0032081 - 4Calibrate both arms
Move the arm to the middle of its range, press Enter, then sweep every joint through its travel. LeRobot pins shoulder_pan and wrist_roll to 0 and 4095 rather than recording them, since those two turn freely. The calibration file is keyed by the id you pass.
bashlerobot-calibrate \ --robot.type=koch_follower \ --robot.port=/dev/tty.usbmodem575E0031751 \ --robot.id=my_koch_follower lerobot-calibrate \ --teleop.type=koch_leader \ --teleop.port=/dev/tty.usbmodem575E0032081 \ --teleop.id=my_koch_leader - 5Teleoperate and check the mapping
Drive the follower from the leader with the camera feeds on screen before recording. If a joint runs backwards, the calibration is wrong, not the code.
bashlerobot-teleoperate \ --robot.type=koch_follower \ --robot.port=/dev/tty.usbmodem575E0031751 \ --robot.id=my_koch_follower \ --robot.cameras="{front: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}}" \ --teleop.type=koch_leader \ --teleop.port=/dev/tty.usbmodem575E0032081 \ --teleop.id=my_koch_leader \ --display_data=true - 6Record a dataset
Same command shape as an SO-100. Documented defaults are 60 s per episode, 60 s reset, 50 episodes. Right arrow or n moves on, left arrow or r re-records, ESC or q stops and uploads.
bashlerobot-record \ --robot.type=koch_follower \ --robot.port=/dev/tty.usbmodem575E0031751 \ --robot.id=my_koch_follower \ --robot.cameras="{front: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}}" \ --teleop.type=koch_leader \ --teleop.port=/dev/tty.usbmodem575E0032081 \ --teleop.id=my_koch_leader \ --dataset.repo_id=${HF_USER}/koch-pick-place \ --dataset.num_episodes=50 \ --dataset.episode_time_s=60 \ --dataset.single_task="Pick up the block and drop it in the bin" \ --display_data=true
The LeRobot Koch page tells you to connect "the usb cable from your computer and the 5V power supply to the follower arm's controller board". The build repo and its wiring diagram show the assembled follower running on 12 V, with a step-down converter for the XL330 branch. Trust the wiring diagram. A 5 V bench setup hurts nothing, but it puts the XL430 shoulder motors below their 6.5 V minimum input voltage, which is out of spec and a confusing symptom.
What LeRobot writes into the motors
Reading the two classes side by side is the fastest way to understand the arm: the follower is a mixed bus, the leader uniform. Both use the same six joint names in the same order, and both normalise the gripper to 0 to 100 and the other five to -100 to 100. One asymmetry: the follower config exposes use_degrees, which switches those five to degrees for older datasets. The leader config has no such flag.
# src/lerobot/robots/koch_follower/koch_follower.py
norm_mode_body = MotorNormMode.DEGREES if config.use_degrees else MotorNormMode.RANGE_M100_100
motors={
"shoulder_pan": Motor(1, "xl430-w250", norm_mode_body),
"shoulder_lift": Motor(2, "xl430-w250", norm_mode_body),
"elbow_flex": Motor(3, "xl330-m288", norm_mode_body),
"wrist_flex": Motor(4, "xl330-m288", norm_mode_body),
"wrist_roll": Motor(5, "xl330-m288", norm_mode_body),
"gripper": Motor(6, "xl330-m288", MotorNormMode.RANGE_0_100),
}
# src/lerobot/teleoperators/koch_leader/koch_leader.py
motors={
"shoulder_pan": Motor(1, "xl330-m077", MotorNormMode.RANGE_M100_100),
...
"gripper": Motor(6, "xl330-m077", MotorNormMode.RANGE_0_100),
}| What is written | Value | Why |
|---|---|---|
| Operating_Mode, five arm joints | EXTENDED_POSITION (4) | Joint mode caps at 0 to 4095; extended position supports 512 turns, so a servo assembled near a wrap point does not fight itself. |
| Operating_Mode, gripper | CURRENT_POSITION (5) | The follower closes onto an object without forcing; on the leader it makes the handle a trigger. |
| Goal_Position, leader gripper | gripper_open_pos, default 50.0 | The rest position the trigger springs back to. |
| Drive_Mode, leader elbow_flex | INVERTED (1) | The leader elbow is mirrored. Leader only; the follower stores drive_mode 0. |
| Position_P_Gain / I / D, follower elbow_flex | 1500 / 0 / 600 | Commented in the source as closing the gap between states and actions. That joint only. |
| ID and Baud_Rate, all motors | sequential ids, 1,000,000 bps | Written to EEPROM by lerobot-setup-motors, replacing the factory ID 1 at 57,600. |
That elbow PID line matters for data quality. In a LeRobot dataset, action is what the leader commanded and observation.state is where the follower actually was. A soft joint pulls those apart, and a policy trained on it learns to compensate for a lag that will not exist at inference time.
What stays exactly the same: the data pipeline
This is what people get wrong when they assume a different arm means a different training path. KochFollower and the generic SOFollower behind both so100_follower and so101_follower build their features from the same comprehension over motor names, so the tensors reaching a policy are identical in shape, ordering and key naming.
@property
def _motors_ft(self) -> dict[str, type]:
return {f"{motor}.pos": float for motor in self.bus.motors}
# resulting action / state keys, both arms:
# shoulder_pan.pos, shoulder_lift.pos, elbow_flex.pos,
# wrist_flex.pos, wrist_roll.pos, gripper.pos
One field does change. The recorder writes robot_type from robot.name, the class attribute, not the --robot.type string you typed. A Koch recording is tagged koch_follower, while SO-100 and SO-101 recordings are both tagged so_follower, since they share one generic class. Nothing in the trainer keys off it, which is a trap: a Koch-trained policy loads and runs on an SO-100 without complaining, and it is wrong. For moving data between arms, see how to collect high-quality VLA training data.
Two ways to get from a built Koch to a working policy
- Assemble both arms from the repo STLs and BOM, wire the two rails, meter the converter output before any XL330 goes on the chain.
- Install the core_scripts and dynamixel extras in a Python 3.12 environment.
- lerobot-find-port, then lerobot-setup-motors twice, then lerobot-calibrate twice.
- lerobot-record 50 episodes with a fixed scene camera and, if you can mount one, a wrist camera.
- Rent or own a GPU: lerobot-train --policy.type=act, or smolvla for the pretrained route.
- lerobot-rollout on the follower, next to the servos, and watch what breaks.
lerobot-train \
--dataset.repo_id=${HF_USER}/koch-pick-place \
--policy.type=act \
--output_dir=outputs/train/act_koch \
--job_name=act_koch \
--policy.device=cuda \
--policy.repo_id=${HF_USER}/act_koch
lerobot-rollout \
--strategy.type=base \
--policy.path=${HF_USER}/act_koch \
--robot.type=koch_follower \
--robot.port=/dev/ttyACM0 \
--robot.id=my_koch_follower \
--task="Pick up the block and drop it in the bin" \
--duration=60The --strategy.type flag picks the rollout mode: base is autonomous with no recording, sentry records continuously, highlight keeps a ring buffer, dagger is human in the loop, episodic records with reset phases. The two underestimated costs are the hours of motor bring-up before the first episode exists, and the day lost when a v3.0 dataset meets a loader wanting v2.1.
- Assemble and wire the arm yourself. Nobody does that step for you, and the voltage check is yours.
- Install the desktop client from /download. It records LeRobot-format datasets out of a teleoperation session: episodes, camera streams and joint states.
- Pick a model and an arm in the /train matrix. Koch v1.1 is one of the four arm columns.
- The training form sends the hyperparameters; the backend rents a spot GPU by required VRAM and writes checkpoints to object storage.
- Inference auto-provisions a GPU pod serving the policy. Pods carry an idle watchdog and destroy themselves.
| Step | Where it happens |
|---|---|
| Record | Desktop client, /download |
| Inspect or reuse data | /directory |
| Pick a model | /policies |
| Train | /train/act-on-koch-v1-1 and the other Koch guides |
| Serve the policy | Auto-provisioned pod with an idle watchdog |
| Terminal or agent access | /cli and /mcp |
The honest caveat: Koch v1.1 is compatible rather than the reference arm. The demo arm on /live is an SO-100, and so is the hardware behind the deepest failure-mode coverage. The client guide and training docs use SO-100 screenshots, but the commands are arm-agnostic.
Which policy to train on Koch data
The arm does not change the model choice. These are the five trainable policies, with the numbers that matter once you have 50 episodes and a deadline.
| Policy | Params | Inference per action step | GPU tier | Min episodes | Dataset format |
|---|---|---|---|---|---|
| ACT | ~80 M, trained from scratch | 20 ms | RTX 4090 or any 24 GB card | 50 | LeRobot v3.0 |
| SmolVLA | ~450 M | 245 ms | RTX 4090 or any 24 GB card | 30 | LeRobot v3.0 |
| GR00T N1.7 | ~3 B, ~40 M trained during fine-tuning | 152 ms | A100 80 GB or H100 80 GB | 50 | LeRobot v2.0 or v2.1 |
| GR00T N1.5 | ~3 B | 165 ms | A100 80 GB or H100 80 GB | 50 | LeRobot v2.0 or v2.1 |
| Pi0.5 | ~3 B, PaliGemma backbone | 485 ms | A100 80 GB or H100 80 GB | 50 | LeRobot v3.0 |

For a first Koch policy, ACT is the default answer. It has no base model at all, which is the point: it exists only after training on your task, and at 20 ms per action step it is the fastest of the five. SmolVLA is the next step up if you want a pretrained backbone and can live with 245 ms and a 30-episode floor. Start at ACT on Koch v1.1, then SmolVLA on Koch v1.1; the GR00T N1.7 and Pi0.5 guides sit alongside.
A LeRobot v3.0 dataset crashes the GR00T loader and has to be converted down to v2.1 first, while ACT, SmolVLA and Pi0.5 want v3.0. The format you record today decides which models will load it; dataset rejected as v3 is the shortest route out. GR00T exposes no seed in its fine-tuning entry point, so its runs are not bit-for-bit reproducible; lerobot's default seed is 1000.
Is the Koch v1.1 the right arm for you
- Extended Position mode on every arm joint: a servo landing near the 0 or 4095 wrap point does not force a rebuild.
- Current-based Position mode on the gripper: the follower closes against a current ceiling, the leader handle springs back like a trigger.
- Dynamixel Protocol 2.0 and the vendor's SDK, pinned by LeRobot as dynamixel-sdk >=3.7.31,<3.9.0.
- XL430 shoulders give 1.4 Nm stall torque at 11.1 V against 0.52 Nm from an XL330-M288-T at 5.0 V, so torque sits where the mass is.
- A first-class robot and teleoperator type in LeRobot, not a community fork.
- Roughly twice the parts cost of an SO-100 for the same six-servo layout.
- Two rails plus a converter means more wiring and a failure mode that destroys parts rather than just not working.
- Mixed servo families mean two horn and idler sets, and no swapping a spare from wrist to shoulder.
- A compatible arm here, not the reference one, so demo hardware and the deepest failure-mode coverage assume an SO-100.
- The XL430 supports neither current control nor current-based position control, so the mixed lineup is forced.
Where none of this helps
Four limits are worth stating plainly, because neither the arm nor the platform fixes them.
- Remote inference does not rescue a fast task. The loop is 20 to 485 ms per action step, and public-internet round trips on top turn a working policy into a hesitant one. Cloud inference suits slow pick-and-place; reactive motion needs the policy next to the servos. See inference latency.
- Better hardware does not fix bad data. If the wrist camera moved between episode 12 and 30, a 3 B parameter model learns the artefact.
- A Koch-trained policy is not an SO-100 policy. Same tensor shapes, different link geometry. Nothing errors; it just misses. See degrees of freedom.
- Extended Position mode hides assembly errors rather than preventing them. Calibration records whatever range you sweep, so a joint mounted 90 degrees off still calibrates.

Three pages to bookmark: arm not detected (a port permission or a Waveshare jumper on the wrong channel), servo not responding (a motor that missed its turn during setup and is still ID 1 at 57,600), and joint stops early (a calibration sweep that never reached the mechanical limit). None are Koch-specific, which is the point.
What the whole loop costs
| Item | Cost | Source |
|---|---|---|
| Koch v1.1 leader arm parts | 199 USD / 305 EUR / 222 GBP | Build repo bill of materials |
| Koch v1.1 follower arm parts | 278 USD / 368 EUR / 285 GBP | Build repo bill of materials |
| Koch v1.1 parts, platform catalog | ~250 to 350 EUR | AY-Robots arm catalog |
| One ACT or SmolVLA run | ~1 to 3 USD (2 to 5 h at 0.30 to 0.60 USD/h) | RTX 4090 / 24 GB spot tier |
| One GR00T or Pi0.5 run | ~4 to 12 USD (3 to 6 h at 1.20 to 2.00 USD/h) | A100 / H100 spot tier |
| 3D printing | Filament only, 0.2 mm layers, ~30 % infill | Build repo print settings |
The asymmetry is the useful bit. The arm is a few hundred euros once; a run is the price of a coffee. The expensive resource is recording time, so record more episodes and retrain often rather than tune hyperparameters. See pricing, /try for starting without hardware, and the dataset directory for what other recordings look like.
Ready to train on your Koch v1.1 recordings?
The training matrix pairs each of the five policies with each of the four arms, Koch v1.1 included. Every cell is a guide with the GPU tier, dataset format and trainer defaults.
Open the training matrixCan I run a policy trained on an SO-100 dataset on a Koch v1.1?▾
It will load and run, because both arms expose the same six action keys with the same normalisation. It will not work well. The same normalised number maps onto different link lengths and joint travel, so it is a different physical pose. Record fresh episodes on the arm you deploy on.
Why does the follower need both a 12 V supply and a step-down converter?▾
Because it mixes servo families. The XL430-W250-T at the shoulders is rated 6.5 to 12.0 V, recommended 11.1 V. The XL330-M288-T further out is rated 3.7 to 6.0 V, recommended 5.0 V. The 12 V supply feeds the driver board; one servo header runs to the two XL430s, the other feeds the converter making the 5 V branch for the four XL330s. The data line is shared by all six.
Do I need a U2D2 or an OpenRB-150 for a Koch v1.1?▾
The build repository does not use one. Its bill of materials specifies a Waveshare Serial Bus Servo Driver Board per arm, about 10 USD or 6 EUR, over USB-C, and the repo adds a printed platform on the leader base to carry that board. Set both jumpers to the B channel so the board talks over USB. Other Dynamixel interfaces are outside what the repo documents.
My XL430 shoulder motors do not respond but the XL330s do. What is wrong?▾
Check the rail before the software. The XL430-W250-T has a 6.5 V minimum input voltage, so a bench setup at 5 V runs it out of spec while every XL330 on the same bus sits inside its 3.7 to 6.0 V range and answers normally. The other candidate is a motor skipped during lerobot-setup-motors, still ID 1 at 57,600 bps while the bus runs at 1,000,000.
Which LeRobot version do these commands apply to?▾
The LeRobot sources on main, version string 0.6.2; newest tagged release v0.6.1. Console entry points include lerobot-find-port, lerobot-setup-motors, lerobot-calibrate, lerobot-teleoperate, lerobot-record, lerobot-train and lerobot-rollout. Older tutorials call python lerobot/scripts/control_robot.py with a --control.type flag; that file is gone. Python 3.12 or newer is required.
Sources
- jess-moss/koch-v1-1: Koch v1.1 build repository, bill of materials, print settings and assembly notes
- Alexander Koch Robot Arm Wiring Diagram V1.1, Hugging Face, drawn 2024-07-08
- LeRobot documentation: Koch v1.1 assembly, motor configuration and calibration
- LeRobot documentation: imitation learning on real-world robots (teleoperate, record, train, rollout)
- LeRobot documentation: installation and optional extras
- LeRobot pyproject.toml: version, Python floor, console entry points, dynamixel and feetech extras
- LeRobot source: KochFollower motor table, operating modes, calibration and elbow PID gains
- LeRobot source: KochLeader motor table, inverted elbow drive mode and gripper trigger
- LeRobot source: Dynamixel PROTOCOL_VERSION, DEFAULT_BAUDRATE and the OperatingMode / DriveMode enums
- LeRobot source: Dynamixel model numbers, resolutions, baud-rate table and per-model operating modes
- LeRobot source: Feetech DEFAULT_PROTOCOL_VERSION and the Feetech OperatingMode enum, where POSITION is 0
- LeRobot source: the generic SOFollower behind so100_follower and so101_follower
- ROBOTIS e-Manual: XL330-M077-T specifications, input voltage and EEPROM defaults
- ROBOTIS e-Manual: XL330-M288-T specifications, stall torque and operating modes
- ROBOTIS e-Manual: XL430-W250-T specifications, 6.5 to 12.0 V input and supported operating modes
Ready for high-quality robotics data?
AY-Robots connects your robots to skilled operators worldwide.
Get Started