ODE Policy — R1 Lite "insert flower"

Checkpoints of the ODE policy trained on real-robot demonstrations of the Galaxea R1 Lite right arm inserting a flower. The policy learns a velocity field ȧ = f(c, s, a) over the arm's joint targets and produces each 8-step action chunk by integrating that field (RK4) from the current target, instead of denoising a chunk from noise.

Files

Path Content
checkpoints/{50,100,150,200,250,300}.ckpt Full training checkpoints (485 MB each): model, ema_model, optimizer state dicts + the pickled Hydra config. Serve the EMA weights (the loader does this by default).
config/config.yaml, config/overrides.yaml Resolved training config and the command-line overrides of this run
logs/logs.json.txt Per-step / per-epoch training log (loss, lr, epoch time, val_loss every 5 epochs)
SHA256SUMS Checksums of every uploaded file

Checkpoints are torch.save(..., pickle_module=dill) payloads written by the ODE_Policy training runner. Loading them needs that codebase (roboverse_learn.il.policies.ode.ode_image_policy.ODEImagePolicy) and torch.load(..., pickle_module=dill, weights_only=False) — only load checkpoints you trust.

Data

at237299966/r1lite_insert_flower_single: LeRobot v2.1, 95 episodes / 23,034 frames at 15 Hz, single task "insert flower".

Input / output Definition
Cameras head_rgb (720×1280) and right_wrist_rgb (360×640), padded to square then resized to 256×256 (same geometry as the robot client)
agent_pos right-arm joint positions (6, rad) + right gripper opening (1, mm)
ODE state a right-arm absolute joint targets (6, rad). Row convention: a[t] = commanded target at t−1 (episode start: measured joints)
Gripper head binary, +1 close / −1 open; the label flips where the operator's gripper ramp starts
Window 8 observation frames, 8-step action chunk

Training

Model ResNet18 (GroupNorm, random crop) per camera, 8 frames → condition c (512); vector field = 4-layer FiLM-MLP, width 512; proprioception enters the field only (cond_use_s=false); separate gripper head
Integration RK4, 8 control steps per chunk, vel_scale=0.05; observation fixed over the chunk (obs_update=fixed)
Start perturbation 50% of samples, per-joint std [0.005, 0.0316, 0.0138, 0.005, 0.005, 0.005] rad, decay 0.7 per step
Optimisation AdamW, lr 1.5e-4, cosine schedule over 300 epochs, warm-up 500 steps, EMA
Batch 2 × A100-40GB (DDP), 48 per GPU = 96 global; 236 steps/epoch, 70,800 steps in total
Wall clock 9 h 45 min (116 s/epoch)
epoch 0 10 50 100 150 200 250 300
train loss 1.16 0.30 0.070 0.039 0.023 0.017 0.012 0.011
val loss 0.84 0.61 0.68 0.71 0.75 0.81 0.81 0.80 (ep 290)

The validation loss is a weak signal: one held-out episode, raw (non-EMA) weights, with the training start perturbation still active. Its minimum is at epoch 15 (0.54) and it drifts up afterwards, so compare the early and late checkpoints on the robot before picking one.

Deployment

The robot side is the unmodified openpi-r1lite closed-loop client (main_r1lite_closedloop.py, 15 Hz, executes row 0 of every (8, 14) reply). The server re-integrates a chunk every 8 ticks from the last target it sent and walks the client through it, matching how the policy was trained:

python -m roboverse_learn.il.deploy.serve_policy \
    --checkpoint checkpoints/100.ckpt --host 0.0.0.0 --port 8000 --device cuda:0 \
    --gripper_close 1 --gripper_open 100 --gripper_ramp_ticks 27
python -m roboverse_learn.il.deploy.test_client --host 127.0.0.1 --port 8000 -n 40 --gripper_range 1 100   # pre-flight

Measured on an A100: ~19 ms on re-planning ticks, < 0.1 ms on the others; loopback round trip p95 29 ms (budget 66.7 ms). Code: ODE_Policy repository, neural_ode/real/ (data + training) and roboverse_learn/il/deploy/ (server).

Downloads last month

-

Downloads are not tracked for this model. How to track
Video Preview
loading

Dataset used to train at237299966/ODE_policy_insert_flowers