
A published SO-100 pick-and-place cycle runs 9.7 seconds, about 370 attempts an hour. Here is how that compares to 400-600 for a human picker and 1,200 for a piece-picking cell.
A published pick-and-place cycle on an SO-100 takes 9.7 seconds. That figure comes from the SmolVLA paper, measured over ten trials with the cube starting in five different positions, with the model running in asynchronous mode. Synchronous mode took 13.75 seconds for the same task. Those two numbers are the honest starting point for any conversation about warehouse picking on cheap hardware, because everything else people say about low-cost arms is either a demo video or a press release.
9.7 seconds per cycle is about 371 attempts per hour if the arm never stops moving. A human order picker runs 400 to 600 picks per hour. A production piece-picking cell quotes a three second cycle. A packaging delta robot does a 25/305/25 mm cycle in 0.36 seconds with a 1 kg payload. So the low-cost arm is not off the chart. It is on the chart, at the bottom of it, on a much easier task than any of the others were measured on. This article works through where exactly it lands and what the gap is made of.
The short version
- •The best published SO-100 pick-and-place cycle is 9.7 s (async) versus 13.75 s (sync), from the SmolVLA paper. That is roughly 370 versus 260 attempts per hour before any success discount.
- •Multiply by the reported 75 percent Pick-Place score and you land near 270 successful transfers per hour, in the same band as the 2017 Amazon Robotics Challenge best of 272 picks per hour and below Dex-Net 4.0's 300 mean picks per hour.
- •Those benchmarks were on cluttered bins of novel objects. The SO-100 number was one known cube into one fixed box. Same order of magnitude, very different difficulty.
- •Cycle time is set by how fast your demonstrations were, not by GPU speed. Inference latency only costs you the idle frames, and asynchronous inference removes most of those.
- •The hard gap is not throughput. It is payload (well under 200 g), no published repeatability, no IP rating, no safety-rated stop functions, and no duty cycle spec.
- •An SO-100 is 110 to 150 EUR in parts. A UR5e lists at roughly 39,000 to 43,500 USD from a distributor. In a picking cell, neither number is the dominant cost.
Everyone publishes a different picks-per-hour
Picks per hour is the metric warehouses use, and it is close to useless without the conditions attached. Mean picks per hour (MPPH) as Berkeley uses it counts successful grasps per hour over a bin-clearing run, so failures already cost you throughput. A vendor machine rate counts the arm cycling between two totes with nothing going wrong. A challenge score counts items moved inside a fixed time window. Here are the figures I could verify, each with what it actually measured.
| System | Rate | Task it was measured on | Source |
|---|---|---|---|
| ABB IRB 360-1/1130 delta | 0.36 s per cycle at 1 kg (10,000/h on paper); ABB text says up to 100 cycles/min for the 8 kg variant | 25/305/25 mm cycle, item presented in a known pose on a conveyor | ABB datasheet ROB0082EN_F, May 2013 |
| RightHand Robotics RightPick | as fast as a 3 s cycle, so about 1,200/h | Tote to tote piece picking, vendor machine rate | righthandrobotics.com product page |
| Human order picker | 400 to 600 picks/h (400/h average cited) | Real shelves, real orders | IEEE Spectrum and The Robot Report |
| Dex-Net 4.0 on an ABB YuMi | over 300 MPPH at over 95 percent reliability | Bins of up to 25 novel objects, suction plus parallel jaw | Science Robotics, January 2019 |
| Amazon Robotics Challenge 2017, best | up to 272 picks/h; stowing 25 to 160/h | Mixed items from clutter, unknown poses | The Robot Report, August 2017 |
| Amazon Picking Challenge 2016 winner | about 100 picks/h at a 17 percent failure rate | Shelf picking, mixed items | The Robot Report, August 2017 |
| SO-100 with SmolVLA, async | 9.7 s per cycle, so about 371 attempts/h | One known cube, five start positions, one fixed box, no clutter | SmolVLA paper, arXiv 2506.01844 |
| SO-100 with SmolVLA, sync | 13.75 s per cycle, so about 262 attempts/h | Same task | SmolVLA paper, arXiv 2506.01844 |
Read the fourth column before the second. The delta robot is fast because the item arrives in a known pose and the arm never has to decide anything. Dex-Net 4.0 and the challenge entries are slow because they are solving perception in clutter. The SO-100 number sits near the challenge entries while doing far less work, which tells you the bottleneck on cheap hardware is not the same bottleneck as in a warehouse.
The paper also reports a fixed-time experiment: asynchronous inference completed 19 successful pick-and-place cycles against 9 for synchronous, with the time limit written as "e.g., 60 seconds". Nineteen cycles in 60 seconds implies a 3.2 s cycle, which contradicts the 9.7 s mean from the same section. Treat the roughly 2x ratio as the reliable claim and the 9.7 s mean as the reliable absolute. Do not quote 19 cycles per minute at anyone.
What an SO-100 class arm actually is, next to the alternatives
The interesting thing about the SO-100 spec sheet is that there is no spec sheet. The build repository lists servos, gear ratios and prices. It does not publish a payload, a reach, a repeatability figure, a duty cycle or an ingress rating, because the arm was designed as a research and teaching platform, not as a machine you buy against a requirement. Compare that to what the two industrial reference points publish.
| SO-100 / SO-101 | Universal Robots UR5e | ABB IRB 360-1/1130 | |
|---|---|---|---|
| Cost | about 110 to 150 EUR in parts (SO-100), 130 to 170 EUR (SO-101) | roughly 39,083 to 43,544 USD, distributor list, arm and controller | not publicly listed |
| Payload | not published | 5 kg | 1 kg (3 kg and 8 kg variants exist) |
| Reach | not published | 850 mm | 1130 mm work area diameter |
| Repeatability | not published | plus or minus 0.03 mm per ISO 9283 | 0.1 mm position repeatability |
| Mass | 3D printed plastic plus six bus servos | 20.6 kg arm including cable | 120 kg (145 kg stainless) |
| Ingress protection | none | IP54 arm, IP44 control box | IP55, IP67 or IP69K depending on build |
| Safety functions | none | 21 configurable, EN ISO 13849-1 PLd Cat 3, EN ISO 10218-1 | dual-circuit e-stop with supervision, 3-position enabling device |
| Actuation | Feetech STS3215 bus servos at 7.4 V | harmonic-drive joints, built-in force/torque sensor | parallel-kinematic delta, IRC5 controller |
The row that ends the conversation for most warehouse deployments is the safety row, not the payload row. A UR5e ships 21 configurable safety functions certified to EN ISO 13849-1 PLd Category 3. An SO-100 ships none, because it is six hobby servos on a serial bus. You cannot put it next to a picker without a risk assessment that concludes it cannot hurt anyone, and the honest way to reach that conclusion is a fence or a cell.
The SO-100 and SO-101 use Feetech STS3215 bus servos on a 7.4 V rail. There is a 12 V variant of the same servo with a higher stall torque, and the two look identical. Feeding 12 V into 7.4 V servos destroys them, quietly and permanently. Check the label on every servo before you power the bus for the first time, and check it again after any replacement. The Koch v1.1 uses Dynamixel motors on 5 V and 12 V rails, so if you own both arms you have two incompatible supplies on the same bench.
There is no payload figure, so do the arithmetic yourself
The build repository does give you one number to work from: the 7.4 V STS3215 has a stall torque of 16.5 kg.cm measured at 6 V, while the 12 V version is rated 30 kg.cm. Stall torque is not usable torque. A servo held near stall heats up and either derates or dies, so plan on a fraction of it. Reach is not published either, so measure your own arm.
# Static payload budget for the shoulder servo of a 7.4 V SO-100.
# Only input taken from a published source:
# SO-ARM100 README: 7.4 V STS3215 stall torque 16.5 kg.cm (measured at 6 V).
stall_kgcm = 16.5
# Everything below is an assumption you should replace with your own measurement.
duty_fraction = 0.30 # what you dare hold continuously without cooking the servo
lever_cm = 25.0 # horizontal shoulder-axis to gripper distance, arm extended
usable_kgcm = stall_kgcm * duty_fraction # 4.95 kg.cm
payload_kg = usable_kgcm / lever_cm # 0.198 kg
print(f"{payload_kg*1000:.0f} g at full extension, BEFORE subtracting the mass")
print("of the forearm, wrist, gripper and cable that hang off the same joint.")Under 200 g at full extension, before the arm carries its own forearm and gripper. In practice that means small parts, empty boxes, blister packs, cable ties and lab samples. It does not mean a 500 g shampoo bottle, and it certainly does not mean a case. If your pick list has a mass distribution, plot it before you plan anything else. The SO-100 against SO-101 comparison goes through where the newer arm helps, and it is mostly assembly and smoothness rather than load.
Cycle time is set by your demonstrations, not by your GPU
This is the part people get backwards. A policy trained by imitation learning moves at the speed of the data it was shown. If you teleoperated the demonstrations at a comfortable human pace, the policy reproduces that pace. Buying a faster card does not make the arm move faster; it only shortens the pause between action chunks.
The five policies you can train differ a lot in inference latency per action step, but action chunking amortises that cost. One forward pass produces a whole sequence of actions, which the arm then plays out at the recording frame rate. The table below shows what each model's latency costs as a share of a 50-action chunk played at 30 fps, which is the LeRobot async default.
| Policy | Latency per action step | Share of a 50-action chunk at 30 fps (1.67 s) | GPU tier | Min episodes |
|---|---|---|---|---|
| ACT | 20 ms | about 1 percent | RTX 4090 or any 24 GB card | 50 |
| GR00T N1.7 | 152 ms | about 9 percent | A100 80 GB or H100 80 GB | 50 |
| GR00T N1.5 | 165 ms | about 10 percent | A100 80 GB or H100 80 GB | 50 |
| SmolVLA | 245 ms | about 15 percent | RTX 4090 or any 24 GB card | 30 |
| Pi0.5 | 485 ms | about 29 percent | A100 80 GB or H100 80 GB | 50 |
Two readings follow from that column. First, none of these models is latency-bound for a slow pick cycle: even Pi0.5 finishes the next chunk with 70 percent of the current chunk still queued. Second, Pi0.5 is the one where a network hop starts to matter. Add 100 ms of public-internet round trip and it is using 35 percent of the window. The side-by-side policy comparison has the rest of the numbers.

In synchronous mode the arm sits still while the policy thinks, then executes the whole chunk, then sits still again. Asynchronous inference computes the next chunk while the current one is still playing, so the idle frames disappear. That is the entire difference between the SmolVLA paper's 13.75 s and 9.7 s cycles, roughly 30 percent, with no change to the model or the hardware. LeRobot ships it as lerobot.async_inference.policy_server and lerobot.async_inference.robot_client, with --actions_per_chunk defaulting to 50 and --chunk_size_threshold to 0.7.
So if you want a shorter cycle, the lever is the data. Record demonstrations faster, at the edge of what you can teleoperate cleanly. The cost is that fast motion produces motion blur and fewer frames per unit of travel, which makes the task harder to learn. There is a real trade-off there, and the data collection guide covers how to find the edge without falling off it.
Measure your own cycle before you trust anyone's number
Everything above is somebody else's cell, gripper and object. The only number that matters for your pick list is the one you measure. This is the shortest honest path from a bare arm to a cycle time, using the current LeRobot command-line tools as they exist in the repository's docs today.
- 1Find the port and set the servo IDs
Every STS3215 leaves the factory with the same bus ID, so you write IDs once, per arm. Run the port finder with the arm unplugged, then plugged in, and it tells you which device appeared.
bashlerobot-find-port lerobot-setup-motors \ --robot.type=so101_follower \ --robot.port=/dev/tty.usbmodem585A0076841 - 2Calibrate both arms
Calibration writes the joint limits and zero offsets to a file keyed by --robot.id. Skip it and the policy will learn your offsets as part of the task, which is one of the classic reasons a policy only works in one setup.
bashlerobot-calibrate \ --robot.type=so101_follower \ --robot.port=/dev/tty.usbmodem58760431551 \ --robot.id=picker_follower lerobot-calibrate \ --teleop.type=so101_leader \ --teleop.port=/dev/tty.usbmodem575E0031751 \ --teleop.id=picker_leader - 3Record the pick, timed to your actual cycle
The defaults are --dataset.episode_time_s=60, --dataset.reset_time_s=60 and --dataset.num_episodes=50, which is 100 minutes of wall clock. If your pick takes 12 seconds, cut the episode to 20 s and the reset to 10 s and you record the same 50 episodes in 25 minutes.
bashlerobot-record \ --robot.type=so101_follower \ --robot.port=/dev/tty.usbmodem585A0076841 \ --robot.id=picker_follower \ --robot.cameras="{ top: {type: opencv, index_or_path: 0, width: 640, height: 480, fps: 30}, wrist: {type: opencv, index_or_path: 1, width: 640, height: 480, fps: 30} }" \ --teleop.type=so101_leader \ --teleop.port=/dev/tty.usbmodem575E0031751 \ --teleop.id=picker_leader \ --dataset.repo_id=${HF_USER}/tote-transfer \ --dataset.single_task="Pick the part from the left tote and drop it in the right tote" \ --dataset.num_episodes=50 \ --dataset.episode_time_s=20 \ --dataset.reset_time_s=10 \ --dataset.fps=30 - 4Check the cadence report before you train
lerobot-record paces the loop at --dataset.fps and prints what it actually achieved, per episode and for the session. If your effective cadence is well under target, the dataset already encodes stalls that the policy will learn to imitate.
textCadence (episode 0): 29.88 Hz vs 30 Hz target - 600 ticks, 20.0 s measured 8/599 ticks over the 33.3 ms budget (work mean 18.4 ms, worst 45.1 ms) - 5Train, then roll out for a fixed duration and count
lerobot-rollout takes a --duration in seconds. Run it for 600 s, count the successful transfers, and multiply by six. That is your picks per hour, measured the same way the benchmarks above measure theirs.
bashlerobot-train \ --dataset.repo_id=${HF_USER}/tote-transfer \ --policy.type=smolvla \ --policy.device=cuda \ --policy.repo_id=${HF_USER}/tote-policy lerobot-rollout \ --strategy.type=base \ --policy.path=${HF_USER}/tote-policy \ --robot.type=so101_follower \ --robot.port=/dev/tty.usbmodem585A0076841 \ --task="Pick the part from the left tote and drop it in the right tote" \ --duration=600 - 6Repeat with the async stack and compare
Start the policy server, point the robot client at it, and run the same 600 s window. The delta between the two runs is your version of the 13.75 s to 9.7 s result.
bash# terminal 1, on the machine with the GPU python -m lerobot.async_inference.policy_server \ --host=127.0.0.1 \ --port=8080 # terminal 2, on the machine holding the arm python -m lerobot.async_inference.robot_client \ --server_address=127.0.0.1:8080 \ --robot.type=so101_follower \ --robot.port=/dev/tty.usbmodem585A0076841 \ --robot.id=picker_follower \ --policy_type=smolvla \ --pretrained_name_or_path=${HF_USER}/tote-policy \ --policy_device=cuda \ --actions_per_chunk=50 \ --chunk_size_threshold=0.7 \ --task="Pick the part from the left tote and drop it in the right tote"
If the arm sags between cycles or a joint stops short of where the demonstration went, stop and fix the hardware before you blame the policy. The failure-mode pages for an arm that twitches then sags and for a gripper that will not close cover the two that eat the most time on a picking task, because both look exactly like a bad policy from the outside.
Two routes to the same measured number
Everything above runs on your own machine. You need the arms built and calibrated, a GPU that fits the model, and the patience to keep a recording session consistent for an hour.
- Build or buy the arm. The parts bill is public, and the build repository lists every servo, screw and 3D printed part with sources.
- Install LeRobot, wire the servo IDs with
lerobot-setup-motors, calibrate withlerobot-calibrate. - Record 30 to 50 episodes with
lerobot-record, watching the cadence report. - Train with
lerobot-train --policy.type=smolvlaoracton a local 24 GB card, or rent one. - Roll out with
lerobot-rollout --duration=600and count successes by hand. - Repeat under
lerobot.async_inferenceto recover the idle frames.
A LeRobot v3.0 dataset crashes the GR00T loader. If you record with a current LeRobot and then decide to try GR00T, you have to convert the dataset down to v2.1 first. Nothing warns you before the run fails. GR00T's fine-tuning entry point (Isaac-GR00T launch_finetune.py, a tyro CLI) also exposes no seed, so two GR00T runs on identical data are not bit-for-bit reproducible. lerobot's default seed is 1000.
The trade you are making is control against calendar time. Nobody is in your way, and nobody has set the hyperparameters for you either.
Same measurement, fewer moving parts. The desktop client records LeRobot datasets straight from a teleoperation session, the training form rents a GPU by required VRAM, and inference pods provision themselves and shut themselves down.
- 1Record
The desktop client writes episodes, camera streams and joint states in LeRobot format from a leader-follower session. The recording walkthrough is the short version.
- 2Pick a dataset or bring your own
The public dataset directory lists datasets you can train against, and you can also point at a Hugging Face repo id or a folder on your own machine.
- 3Train
The form picks model, dataset and hyperparameters. The backend rents a GPU on a spot market by required VRAM and writes checkpoints to object storage. The SmolVLA on SO-100 guide is the relevant combination for a picking cycle.
- 4Serve
/api/inference/podauto-provisions a pod that serves the policy and the local robot client talks to that endpoint. Pods carry an idle watchdog and destroy themselves after an idle period, so a forgotten pod does not bill overnight. - 5Script it
The CLI and the MCP server expose the same operations, so the 600 second rollout can be a cron job rather than a person with a stopwatch.
The platform trains and serves policies. It does not sell you a picking cell, does not do your risk assessment, and does not make a 7.4 V servo lift 500 g. Remote inference is viable for a 10 second pick cycle and not for fast reactive motion: the control loop is 20 to 485 ms per action step depending on the model, and public-internet round trips on top of that turn a working policy into a hesitant one.
Where the gap actually is
- Throughput is in the right order of magnitude for slow, single-station transfer work: roughly 250 to 370 attempts per hour measured, against 400 to 600 for a human picker.
- Perception generalisation comes from the model, not the arm. The SmolVLA paper reports 78.3 percent average across three SO-100 tasks against 61.7 for a 7x larger model and 48.3 for ACT.
- The ACT result that started this whole line of work was explicitly about getting precise behaviour out of imprecise hardware, with 80 to 90 percent success on six tasks from ten minutes of demonstrations.
- Capital risk is near zero. 110 to 150 EUR of parts lets you find out whether a task is learnable before anyone signs a purchase order.
- Slow cycles make remote inference genuinely workable, which is the one case where cloud GPUs are not a latency problem.
- A failed pilot costs a weekend, not a quarter.
- Payload is well under 200 g at extension. Most warehouse SKUs are heavier than that.
- No published repeatability, no ingress rating, no duty cycle, no thermal derating curve. You cannot write a requirement against a spec that does not exist.
- No safety-rated stop functions at all, against 21 configurable ones on a UR5e certified to EN ISO 13849-1 PLd Cat 3.
- Position is held by servo torque alone. Cut the power and the arm sags, along with whatever it was holding.
- Published SO-100 results are single known objects into fixed containers. Nobody has shown cluttered-bin novel-object picking at these rates on this hardware.
- The 9.7 s figure excludes tote presentation, barcode scanning, exception handling and the reset that a human performed between trials.
Notice which of those are hardware and which are evidence. The payload, the brakes and the safety functions are physics and certification, and no amount of training fixes them. The cluttered-bin gap is an evidence gap: it may well close, and the model arena, which tracks 85 VLA models across 332 benchmark results with every value linked to its paper or model card, is where you would see it close first.

The picking work a cheap arm does fit
Rather than asking whether a 130 EUR arm can replace a picker, ask which jobs have the shape it is good at: light parts, a fixed station, a slow rate, a human nearby anyway, and no consequence if a cycle fails. There are more of those in a real building than people expect.
- Kitting light components into a tray. Fixed geometry, one SKU per run, parts under 200 g. This is the shape the published results actually match.
- Feeding a test rig or an inspection station. The rate is set by the instrument, not the arm, and it is usually one item every 20 to 60 seconds.
- Sample handling in a lab. Small, light, repetitive, already inside a fume hood or an enclosure, so the safety question is answered by the room.
- Proving a task is learnable before buying a cell. Record 50 episodes, train, roll out for ten minutes, count. That answers the feasibility question for the price of a weekend.
- Collecting demonstration data for a policy you intend to run on better hardware later. The cross-embodiment argument is that the data has value beyond the arm that recorded it.
- Training and evaluating operators. A bench arm is a cheap way to find out who can teleoperate cleanly before you put them on real equipment.
What all six have in common is that they do not need the arm to be reliable in the industrial sense. They need it to be cheap enough that a 20 percent failure rate is an annoyance rather than a line stoppage. A vision-language-action model on a 130 EUR arm is a good answer to a feasibility question and a bad answer to a throughput question.
What the experiment costs
The arm is not the expensive part, and neither is the training. Both are rounding errors against the cost of a single day of somebody's time integrating anything.
| Item | Cost | Note |
|---|---|---|
| SO-100 parts | about 110 to 150 EUR | Feetech STS3215 bus servos, 7.4 V, full support as the reference arm |
| SO-101 parts | about 130 to 170 EUR | Same servo family, easier assembly |
| Koch v1.1 parts | about 250 to 350 EUR | Dynamixel XL330 / XL430, 5 V and 12 V rails, compatible |
| LeKiwi parts | about 400 to 500 EUR | Mobile base, 7.4 V arm and 12 V base, compatible |
| One SmolVLA or ACT run | about 1 to 3 USD | RTX 4090 or any 24 GB card, 2 to 5 hours at 0.30 to 0.60 USD/hour on the spot market |
| One GR00T or Pi0.5 run | about 4 to 12 USD | A100 80 GB or H100 tier, 3 to 6 hours at 1.20 to 2.00 USD/hour |

Five runs to find hyperparameters that work is 15 USD on the small tier. That budget is the actual argument for cheap arms in picking research: not that they will run your warehouse, but that finding out costs less than the meeting where you discuss whether to find out. The training documentation covers what the form sends, and the three ways to start without a robot covers the case where you do not have an arm on the bench yet.
What would have to change
If you want to know whether this gets better, watch four things rather than the demo videos. First, payload: a 12 V servo variant already exists at 30 kg.cm stall against 16.5, and a redesign around it moves the ceiling without changing the software. Second, cluttered-bin results on low-cost hardware, which is where the published evidence stops today. Third, whether async inference plus faster demonstrations pushes the measured cycle below about 6 seconds, which would put a single station near 600 attempts per hour. Fourth, safety, which is the one that cannot be solved by better models and will decide whether any of it ever leaves a fenced cell.
None of that is close. It is also not the reason to ignore the hardware. The reason to keep an SO-100 on the bench is that it turns an argument about feasibility into a measurement, for the price of a takeaway meal. If you want to see one move before you buy anything, there is a physical arm streaming with no signup, and the full SO-100 setup guide covers the build end to end.
Questions people actually ask
How many picks per hour can an SO-100 actually do?▾
The best published figure is 9.7 seconds per pick-and-place cycle with SmolVLA in asynchronous mode, from the SmolVLA paper, which is about 371 attempts per hour if the arm never stops. The same paper reports 13.75 seconds in synchronous mode, about 262 per hour. Apply the reported 75 percent Pick-Place score and you land near 270 successful transfers per hour. That was one known cube into one fixed box with a human resetting between trials, so treat it as a ceiling for an easy task rather than a warehouse rate.
Does a faster GPU give me a shorter cycle time?▾
Barely. The policy plays out a chunk of actions at the recording frame rate, so the arm moves at the speed of your demonstrations. A faster card only shortens the pause between chunks, and asynchronous inference removes most of that pause anyway. If you want a faster cycle, record faster demonstrations, and accept that motion blur and fewer frames per unit of travel make the task harder to learn.
How much can an SO-100 lift?▾
Nobody publishes a payload for it. Working from the one figure the build repository does give, a 16.5 kg.cm stall torque for the 7.4 V STS3215 measured at 6 V, and assuming you hold no more than 30 percent of stall at a 25 cm lever, you get under 200 g at full extension before the arm's own forearm and gripper are subtracted. Measure your own lever arm and redo the arithmetic; the order of magnitude is the point.
Can I run inference in the cloud for a picking task?▾
For a slow pick-and-place cycle, yes. The control loop is 20 to 485 ms per action step depending on the model, and action chunking means one inference covers seconds of motion, so a network round trip fits inside the window. For fast reactive motion it does not work: public-internet latency on top of a 485 ms Pi0.5 step turns a working policy into a hesitant one. Pods carry an idle watchdog and destroy themselves after an idle period, so a forgotten pod does not keep billing.
Is a low-cost arm safe to run next to warehouse staff?▾
Not without a risk assessment that you conduct yourself. A UR5e ships 21 configurable safety functions certified to EN ISO 13849-1 PLd Category 3 and EN ISO 10218-1. An SO-100 ships none, has no ingress rating, and holds position only while the servos are powered, so a power cut drops the arm and whatever it holds. The realistic deployment is inside a cell or an enclosure that answers the question on the arm's behalf.
Which policy should I train first for a picking task?▾
SmolVLA, because it needs only 30 episodes against 50 for the others, runs on an RTX 4090 or any 24 GB card, costs about 1 to 3 USD per run, and is the model the published SO-100 cycle-time numbers were measured with. ACT is the cheapest to serve at 20 ms per action step but has no base model, so it only exists after you train it on your task. Start with SmolVLA, then compare.
Find out what your pick cycle costs before you commit to anything
A SmolVLA or ACT run is 1 to 3 USD on a 24 GB card. A GR00T or Pi0.5 run is 4 to 12 USD on the A100 tier. Five runs to find working hyperparameters costs less than the meeting about whether to try.
See what a run costsSources
- SmolVLA: A Vision-Language-Action Model for Affordable and Efficient Robotics
- ABB IRB 360 FlexPicker datasheet, ROB0082EN_F, May 2013
- Universal Robots UR5e technical specification, updated May 2025
- Dex-Net 4.0: over 300 mean picks per hour at over 95 percent reliability
- Amazon Picking Challenge throughput figures, The Robot Report, August 2017
- SO-ARM100: the SO-100 and SO-101 build repository
- LeRobot asynchronous inference documentation
- Learning Fine-Grained Bimanual Manipulation with Low-Cost Hardware (ACT)
Sources
- SmolVLA: A Vision-Language-Action Model for Affordable and Efficient Robotics (Shukor et al., 2025)
- ABB IRB 360 FlexPicker datasheet ROB0082EN_F, May 2013: 25/305/25 cycle times, 0.1 mm repeatability
- Universal Robots UR5e technical specification, updated May 2025: 5 kg, 850 mm, 0.03 mm, 21 safety functions
- Dex-Net 4.0, UC Berkeley AUTOLAB: over 300 MPPH at over 95 percent reliability on an ABB YuMi
- IEEE Spectrum on Dex-Net 4.0, January 2019: 300 picks per hour against 400 to 600 for a human
- The Robot Report, August 2017: ARC 2017 picking up to 272/h, stowing 25 to 160/h, 2016 winner about 100/h
- RightHand Robotics RightPick product page: as fast as a 3 second cycle time
- TheRobotStudio/SO-ARM100: SO-100 and SO-101 build repository, 7.4 V STS3215 at 16.5 kg.cm stall
- LeRobot SO-101 documentation: lerobot-find-port, lerobot-setup-motors, lerobot-calibrate
- LeRobot imitation learning docs: lerobot-record defaults, cadence reporting, lerobot-rollout strategies
- LeRobot asynchronous inference: policy_server, robot_client, actions_per_chunk 50, chunk_size_threshold 0.7
- Zhao et al., 2023: Learning Fine-Grained Bimanual Manipulation with Low-Cost Hardware (ACT)
- Zeng et al., 2017: Robotic Pick-and-Place of Novel Objects in Clutter, 1st in ARC 2017 stowing
- Hernandez et al., 2016: Team Delft's Robot, winner of the Amazon Picking Challenge 2016
- Automation Distribution UR5e listing: 39,083 to 43,544 USD by configuration
Ready for high-quality robotics data?
AY-Robots connects your robots to skilled operators worldwide.
Get Started