BackActive development
Active development2026Author

Wren

A small, fast visuomotor policy for low-cost robot arms

The recipe behind billion-parameter robot policies, scaled down about 30× to a $200 arm and a Jetson, and measured on real hardware.

61M

Trainable parameters

Trains in about 6 h on one 8 GB laptop GPU.

108 ms

Round trip on a Jetson Orin Nano

After capturing the prediction as one CUDA graph; 314 ms before.

7/10

Real-arm successes

Against ACT's 5/9. Small n, not yet significant.

Problem

The policies that work on real arms are large: hundreds of millions to billions of parameters, trained on clusters, run on desktop GPUs. A $200 arm with an edge computer cannot use them, and the ones small enough to fit tend to jitter at every chunk boundary.

The question was whether the evidence-backed recipe, pretrained patch tokens, flow matching and trained-in chunk continuity, survives being scaled down to hardware a student can buy.

What I built

The policy and everything around it, from recording demonstrations to running on the Jetson.

  • The model: DINOv2 ViT-S/14 shared by both cameras, 80 patch tokens per view so spatial layout survives, a 6-layer transformer trunk and a 6-block flow-matching DiT action expert
  • Training-time real-time chunking: a random clean prefix is excluded from the loss, so the model learns to continue a plan already under way
  • Edge inference: sampling is shape-static, so the whole prediction is one CUDA graph, cutting Jetson model time from 288 ms to 83 ms
  • A real-time runner with async inference, timestamped chunks, a 50 Hz servo executor and per-query logs
  • A ZMQ inference server on the Jetson Orin Nano
  • Episode Studio, a web app for 100 Hz teleoperation, LeRobot recording and live policy tests
  • A literature review behind every design choice: 7,162 abstracts screened, about 480 papers read in full

Architecture

Scene and wrist cameras go through one shared DINOv2 encoder, fine-tuned at a tenth of the trunk's learning rate. Their 160 patch tokens, a joint-state token and a task token form a 162-token memory for a 6-layer transformer trunk.

A flow-matching DiT action expert cross-attends to that memory and turns Gaussian noise into 16 absolute joint targets, 1.6 s at 10 fps, in 8 Euler steps. The first steps can be pinned to the plan the arm is already executing, which is what makes consecutive chunks join without blending.

Chunk continuity is trained in, not blended

During training, a random prefix of 0 to 4 steps is given clean and excluded from the loss. On the robot, each new chunk is pinned to what the arm will be doing when it lands, so consecutive chunks meet without a blending step.

On the real arm the median switch jump is 0.2°, against several degrees for ACT. Offline, chunk-switch disagreement at 60k steps drops from 1.7° to 0.7° with it.

Never blind at the gripper

30% of scene tokens are masked, and occasionally the whole scene view, but the wrist camera is never dropped. Joint angles get about 1° of noise and are hidden 30% of the time, so the model cannot just copy them.

Augmentation jitters brightness, contrast, saturation and sharpness but never hue, because the colour of the object is signal.

One query, end to end

What happens every time the runner asks for the next chunk. The pinned prefix is the step that removes the jitter.

  1. Capture

    Scene camera streamed from the Jetson, wrist camera over USB, six joint angles.

  2. Encode

    Shared DINOv2, 80 patch tokens per camera, into a 162-token memory.

  3. Pin the prefix

    The steps the arm will already be executing are fixed, not sampled.

  4. Sample

    8 Euler steps of flow matching, captured as one CUDA graph.

  5. Execute about 0.6 s, then switch

    50 Hz servo executor; the next chunk lands on top of this one.

Real arm, pick up a pumpkin and place it in a tray

Scored from saved frames on 2026-09-27. Small n and not interleaved, so the difference is not statistically significant yet. Both policies share the same failure: hovering at the grasp without committing.

PolicySuccessSwitch-jump p90
Wren 60k (61M)7/100.7–4.2°
ACT 80k (baseline)5/91.6–1.8°
SmolVLA (450M, fine-tuned)Completed the task in earlier informal runs~350 ms per query; needed RTC and smoothing to stop jitter

Experiments

Real-arm trials against ACT

Question
Does the scaled-down recipe beat a standard baseline on the real arm?
Method
100 teleoperated episodes (19,832 frames) over two camera positions and several lighting setups; Wren 60k and ACT 80k run on the same task and scored from saved frames.
Result
7/10 for Wren against 5/9 for ACT. Not statistically significant yet; the next step is an interleaved 10-spot round, then targeted demos at the failing spots.

Jetson latency

Question
Can it run fast enough on edge hardware to react?
Method
Per-stage latency benchmark on a Jetson Orin Nano in 25 W mode with clocks pinned.
Result
Eager PyTorch was limited by the ARM CPU issuing kernels, not by the GPU. One CUDA graph took model time from 288 ms to 83 ms and the round trip to 108 ms.

Limitations and failure modes

  • The real-arm result is small n and not interleaved; the difference from ACT is not statistically significant yet.
  • Offline errors are measured on frames that were also in training, so they are optimistic.
  • One task so far: pick up a pumpkin and place it in a tray.
  • Every component has close prior work. The contribution is empirical, this combination at this scale on real hardware, not a new mechanism.

Gallery

Wren on the real SO-101, reaching for the pumpkin
Real-arm trials: pick up the pumpkin and place it in the tray, including a run where the pumpkin is moved by hand mid-episode
What the policy sees: the scene camera and the wrist camera on the SO-101 workspace
What the policy sees: the scene camera and the wrist camera on the SO-101 workspace
The SO-101 arm running a policy rollout
Front and wrist views at the start and end of an episode, checked against what the policy was actually fed
Front and wrist views at the start and end of an episode, checked against what the policy was actually fed

Attribution

Built by me
The policy, training recipe, real-time runner, Jetson inference server, Episode Studio and the literature review are mine.
Based on external research
DINOv2 (Meta), LeRobot and the SO-101 arm are upstream. The design follows published work on flow matching, DiT action experts and training-time real-time chunking (Black et al.), with CT-VAM, ABC-DiT, FlowDPG and MINERVA as the closest prior art.
Experiment performed by me
The real-arm trials against ACT and the Jetson latency work.

Related

  • Ripple

    An always-on site engineer for Nav2 robots

  • Kurat

    Autonomous conversational robot