Downloads · 30 days
12
26% of all-time downloads
Bigenlight/act_banana_in_pot
act_banana_in_pot is a robotics model from Bigenlight. Use it for the robotics task on the model card, and read the license before you ship it in a product. It is set up for lerobot. The card lists the license as apache-2.0.
An Action Chunking Transformer (ACT) policy trained by imitation learning to perform the manipulation task "put the right banana in the pot" on a Universal Robots UR7e arm with two RGB cameras.
Downloads · 30 days
12
26% of all-time downloads
All-time downloads
46
Public
Parameters
51.7M
207 MB on disk
Likes
0
Public
Click a slice to open those files.
.safetensors207 MB · 100%
From the Hugging Face model README
An Action Chunking Transformer (ACT) policy trained by imitation learning to perform the manipulation task "put the right banana in the pot" on a Universal Robots UR7e arm with two RGB cameras.
chunk_size = 100, n_action_steps = 100.Bigenlight/banana_in_pot_lerobot_v3
(51 teleoperated episodes / 21,524 frames, UR7e follower + GELLO leader, 2 cameras).lr = 1e-5 (constant).| I/O | Spec |
|---|---|
observation.state | (7,) — UR joints q1..q6 (radians) + gripper position |
observation.images.cam1 / cam2 | RGB, trained at 360×640 |
action | (7,) — [cmd1..cmd6, grip_cmd], absolute joint targets (radians) + ~binary gripper |
Images were captured at 720p and resized on-the-fly to 360×640 during training (aspect-preserving half-resolution; no dataset re-encode). You must resize every live camera frame to 360×640 at inference — a different aspect ratio or interpolation degrades the policy.
| Component | Detail |
|---|---|
| Robot | Universal Robots UR7e — 6-DOF collaborative arm, joints in radians. Inference uses the UR7e follower only. |
| Teleoperation (data collection) | GELLO low-cost 3D-printed leader arm. Leader signals are recorded but are not policy inputs at inference. |
| Camera 1 | Intel RealSense D435 — RGB only |
| Camera 2 | Intel RealSense D435if — RGB only |
| Camera streams | 1280×720 (720p) @ 30 fps, color only (no depth / IR recorded). ACT is trained on the two RGB views resized to 360×640. |
| Task | "put the right banana in the pot" — table with distractor objects (2 bananas, apple, carrots/peppers, watermelon slice) and a silver pot; success = the correct banana placed in the pot. |
| Dataset scale | 51 episodes / 21,524 frames / ~12 min @ 30 fps. |
| Item | Value |
|---|---|
| Policy | ACT (ResNet18 backbone, CVAE, chunk_size=100, n_action_steps=100) |
dim_model / heads | 512 / 8 |
| Encoder / decoder layers | 4 / 1 |
| Normalization | MEAN_STD for state, action, and visual |
| Batch / steps | 8 / 50,000 |
| Optimizer | AdamW, lr = 1e-5 (constant), backbone lr = 1e-5 |
| Backbone | ResNet18_Weights.IMAGENET1K_V1 (ImageNet-pretrained) |
| GPU | RTX 3060 12GB (~4.7 GB used, ~3.9 step/s) |

Final training loss ≈ 0.065.
Evaluated on held-out episodes (train vs. held-out gap is negligible → generalizes, no overfitting). The step 50,000 checkpoint (this model) is the best by held-out L1.
| step | joints MAE (rad) | overall L1 | gripper acc | train L1 | held-out L1 |
|---|---|---|---|---|---|
| 10000 | 0.0392 | 0.0395 | 98.0% | 0.0392 | 0.0406 |
| 20000 | 0.0354 | 0.0345 | 98.8% | 0.0324 | 0.0356 |
| 30000 | 0.0267 | 0.0265 | 98.8% | 0.0258 | 0.0269 |
| 40000 | 0.0256 | 0.0245 | 99.2% | 0.0222 | 0.0256 |
| 50000 ⭐ | 0.0237 | 0.0225 | 99.2% | 0.0205 | 0.0235 |

Best checkpoint (step 50,000):

The wrist joint (cmd6) carries the largest error — it is the axis with the most natural
variation. The gripper channel is close to binary.
from lerobot.policies.act import ACTPolicy
from lerobot.policies import make_pre_post_processors
policy = ACTPolicy.from_pretrained("Bigenlight/act_banana_in_pot")
policy.eval()
# Normalization is NOT baked into forward() in lerobot 0.6.1 — it lives in the
# processor pipeline saved alongside the checkpoint. select_action returns a
# NORMALIZED action; the post-processor converts it back to radians.
preprocessor, postprocessor = make_pre_post_processors(
policy_cfg=policy.config,
pretrained_path="Bigenlight/act_banana_in_pot",
)
Per control tick:
policy.reset() # once at the start of each rollout
obs = preprocessor(obs) # normalize + batch + move to device
action = policy.select_action(obs) # normalized
action = postprocessor(action) # radians, numpy (7,)
select_action returns one action per call from an internal queue; on an empty queue it
predicts a full 100-step chunk and replans after 100 executed actions (temporal ensembling
is off by default in this config).
LeRobot ships no UR robot class — you build the observation dict yourself and stream
joint targets with ur_rtde at 30 Hz
(33.3 ms control period). Loop: read getActualQ() + gripper → grab both cameras, BGR→RGB,
resize to 360×640 → build observation.state / observation.images.cam1 / cam2 →
preprocess → select_action → postprocess → servoJ(q_target[:6]) + drive gripper from
grip_cmd.
⚠️ Safety — actions are ABSOLUTE joint positions (the single biggest safety driver):
q1..q6 ≈ [2.84, -1.41, 1.78, -2.01, -1.66, -3.42]
rad before enabling the policy, or the first absolute command is a large jump.max(|q_target − getActualQ()|) > ~0.15 rad, abort.cam1/cam2 → physical-viewpoint
mapping. Swap them and it fails silently. Verify wiring every session.grip_cmd is ~binary — threshold (e.g. >0.5 → close) and map to your driver.A full deployment guide (with a reference ur_rtde skeleton and all the citations to the
lerobot inference/normalization code paths) is in the project's DEPLOY_UR.md.
Bigenlight/banana_in_pot_lerobot_v3Bigenlight/banana_in_pot_hilserl