soft-arm-reach-robust
Soft continuum arm · solvedexploration 9 of 9 agent attempts pass
Exploration task. Built after the paper's sweep to test whether a task can force a mechanism outside the catalogue (docs/exploration_new_mechanisms.md, docs/soft_arm_spec.md). Not part of the benchmark tiers or of the paper's main counts; the soft arm is reported in the paper as a plant outside the sweep, the other tasks are not; all sessions ran under the paper's protocol.
more
Each sibling moves the equilibrium under a given command in a different way; the hooked payload does so in one step mid-hold. Gate fine on 0.9 of the seeds on every scenario.
Gate. per-seed success is the `fine` rung of this benchmark's ladder ['safe', 'coarse', 'fine', 'fast'] (`--success-mode fine`), not the evaluator's default flag; the task is solved when the success rate over the grader's held-out seeds is `>= 0.9`; the same gate must also hold on the sibling scenario(s) `payload_v1`, `hook_v1`, `warmup_v1`, `weak_chamber_v1` (`--scenarios`)
Axes: plant:soft_arm, scenario:nominal_v0, gate:fine_10mm, exploration:soft-arm, material:unknown-per-seed, robust:siblings
Each video re-runs the attempt's final controller through the task's own evaluator on a public seed (never the grader's held-out ones). The table under each video is the official grade on the held-out seeds.
nominal_v0| criterion | graded | needed |
|---|---|---|
| base:fine | 1.000 | ≥ 0.900 |
| scenario:payload_v1 | 1.000 | ≥ 0.900 |
| scenario:hook_v1 | 1.000 | ≥ 0.900 |
| scenario:warmup_v1 | 1.000 | ≥ 0.900 |
| scenario:weak_chamber_v1 | 1.000 | ≥ 0.900 |
The agent's final message
The controller is done and passes the gate on every seed I tested: 360 of 360 runs (72 seeds × the five graded scenarios) reach the `fine` rung. On the visible seeds 0–4 the official evaluator reports `solved=True` at the 0.9 gate, with all four rungs met, including `fast`. The grader's own seeds are different, so that part is still untested. About 38 minutes of the 60 were used (01:29 → 02:07). **How it works** (`/app/work/controller.py`, with a docstring explaining the law and each gain): - **Feedforward:** for each new target, it searches the nominal static map for the pair of segment commands (dp) that puts the tip there. The search is limited to |dp| ≤ 0.6, the unfolded branch, which avoids the S/C ambiguity. That command is then multiplied by per-segment, per-side gains learnt at the end of each target that was held well. These gains soak up the seed's stiffness, the chamber gains, the weak chamber and the payload. - **Feedback:** on every new camera frame, an integral term is updated by a damped least-squares step through the map's Jacobian. It tracks hysteresis, creep, the warm-up drift and the hooked payload. - **Command shaping:** the command is slew-limited to 1.5 per second so it doesn't excite the 1.25 Hz bending mode. It is sent through `chamber_commands` with a 0.1 co-contraction bias, the same bias the map was built with. **Fixes that turned out to matter:** - **No carry-over between targets.** Carrying the integral offset into the next target pushed it into…
On each new target it inverts a nominal static tip map by grid search to get a feedforward differential chamber command scaled by a learned ratio, then adds a damped-least-squares Jacobian integral correction from filtered camera tip error, rate-limited and converted to chamber commands.
Shown: public seed 0 (nominal_v0); this episode passes the fine rung. This episode: hold_error_max 0.00246, targets_held_fine 6, targets_held_coarse 6, settle_time_max 4.92, final_error_max 0.00232, track_rms 0.0216, saturation_ratio 0, max_speed 0.556, stiffness_scale 1.08, payload_mass 0, total_reward -24.9.
controller.py · agent transcript · trial soft-arm-reach-robust__8uq6v2r
payload_v1| criterion | graded | needed |
|---|---|---|
| base:fine | 1.000 | ≥ 0.900 |
| scenario:payload_v1 | 1.000 | ≥ 0.900 |
| scenario:hook_v1 | 1.000 | ≥ 0.900 |
| scenario:warmup_v1 | 1.000 | ≥ 0.900 |
| scenario:weak_chamber_v1 | 1.000 | ≥ 0.900 |
The agent's final message
The controller is done and passes the gate on every seed I tested: 360 of 360 runs (72 seeds × the five graded scenarios) reach the `fine` rung. On the visible seeds 0–4 the official evaluator reports `solved=True` at the 0.9 gate, with all four rungs met, including `fast`. The grader's own seeds are different, so that part is still untested. About 38 minutes of the 60 were used (01:29 → 02:07). **How it works** (`/app/work/controller.py`, with a docstring explaining the law and each gain): - **Feedforward:** for each new target, it searches the nominal static map for the pair of segment commands (dp) that puts the tip there. The search is limited to |dp| ≤ 0.6, the unfolded branch, which avoids the S/C ambiguity. That command is then multiplied by per-segment, per-side gains learnt at the end of each target that was held well. These gains soak up the seed's stiffness, the chamber gains, the weak chamber and the payload. - **Feedback:** on every new camera frame, an integral term is updated by a damped least-squares step through the map's Jacobian. It tracks hysteresis, creep, the warm-up drift and the hooked payload. - **Command shaping:** the command is slew-limited to 1.5 per second so it doesn't excite the 1.25 Hz bending mode. It is sent through `chamber_commands` with a 0.1 co-contraction bias, the same bias the map was built with. **Fixes that turned out to matter:** - **No carry-over between targets.** Carrying the integral offset into the next target pushed it into…
On each new target it inverts a nominal static tip map by grid search to get a feedforward differential chamber command scaled by a learned ratio, then adds a damped-least-squares Jacobian integral correction from filtered camera tip error, rate-limited and converted to chamber commands.
Shown: public seed 0 (payload_v1); this episode passes the fine rung. This episode: hold_error_max 0.00231, targets_held_fine 6, targets_held_coarse 6, settle_time_max 5.88, final_error_max 0.00219, track_rms 0.0229, saturation_ratio 0, max_speed 0.577, stiffness_scale 1.08, payload_mass 0.005, total_reward -28.5.
controller.py · agent transcript · trial soft-arm-reach-robust__8uq6v2r
hook_v1| criterion | graded | needed |
|---|---|---|
| base:fine | 1.000 | ≥ 0.900 |
| scenario:payload_v1 | 1.000 | ≥ 0.900 |
| scenario:hook_v1 | 1.000 | ≥ 0.900 |
| scenario:warmup_v1 | 1.000 | ≥ 0.900 |
| scenario:weak_chamber_v1 | 1.000 | ≥ 0.900 |
The agent's final message
The controller is done and passes the gate on every seed I tested: 360 of 360 runs (72 seeds × the five graded scenarios) reach the `fine` rung. On the visible seeds 0–4 the official evaluator reports `solved=True` at the 0.9 gate, with all four rungs met, including `fast`. The grader's own seeds are different, so that part is still untested. About 38 minutes of the 60 were used (01:29 → 02:07). **How it works** (`/app/work/controller.py`, with a docstring explaining the law and each gain): - **Feedforward:** for each new target, it searches the nominal static map for the pair of segment commands (dp) that puts the tip there. The search is limited to |dp| ≤ 0.6, the unfolded branch, which avoids the S/C ambiguity. That command is then multiplied by per-segment, per-side gains learnt at the end of each target that was held well. These gains soak up the seed's stiffness, the chamber gains, the weak chamber and the payload. - **Feedback:** on every new camera frame, an integral term is updated by a damped least-squares step through the map's Jacobian. It tracks hysteresis, creep, the warm-up drift and the hooked payload. - **Command shaping:** the command is slew-limited to 1.5 per second so it doesn't excite the 1.25 Hz bending mode. It is sent through `chamber_commands` with a 0.1 co-contraction bias, the same bias the map was built with. **Fixes that turned out to matter:** - **No carry-over between targets.** Carrying the integral offset into the next target pushed it into…
On each new target it inverts a nominal static tip map by grid search to get a feedforward differential chamber command scaled by a learned ratio, then adds a damped-least-squares Jacobian integral correction from filtered camera tip error, rate-limited and converted to chamber commands.
Shown: public seed 0 (hook_v1); this episode passes the fine rung. This episode: hold_error_max 0.00215, targets_held_fine 6, targets_held_coarse 6, settle_time_max 6, final_error_max 0.00227, track_rms 0.0229, saturation_ratio 0, max_speed 0.524, stiffness_scale 1.08, payload_mass 0.01, total_reward -28.
controller.py · agent transcript · trial soft-arm-reach-robust__8uq6v2r
warmup_v1| criterion | graded | needed |
|---|---|---|
| base:fine | 1.000 | ≥ 0.900 |
| scenario:payload_v1 | 1.000 | ≥ 0.900 |
| scenario:hook_v1 | 1.000 | ≥ 0.900 |
| scenario:warmup_v1 | 1.000 | ≥ 0.900 |
| scenario:weak_chamber_v1 | 1.000 | ≥ 0.900 |
The agent's final message
The controller is done and passes the gate on every seed I tested: 360 of 360 runs (72 seeds × the five graded scenarios) reach the `fine` rung. On the visible seeds 0–4 the official evaluator reports `solved=True` at the 0.9 gate, with all four rungs met, including `fast`. The grader's own seeds are different, so that part is still untested. About 38 minutes of the 60 were used (01:29 → 02:07). **How it works** (`/app/work/controller.py`, with a docstring explaining the law and each gain): - **Feedforward:** for each new target, it searches the nominal static map for the pair of segment commands (dp) that puts the tip there. The search is limited to |dp| ≤ 0.6, the unfolded branch, which avoids the S/C ambiguity. That command is then multiplied by per-segment, per-side gains learnt at the end of each target that was held well. These gains soak up the seed's stiffness, the chamber gains, the weak chamber and the payload. - **Feedback:** on every new camera frame, an integral term is updated by a damped least-squares step through the map's Jacobian. It tracks hysteresis, creep, the warm-up drift and the hooked payload. - **Command shaping:** the command is slew-limited to 1.5 per second so it doesn't excite the 1.25 Hz bending mode. It is sent through `chamber_commands` with a 0.1 co-contraction bias, the same bias the map was built with. **Fixes that turned out to matter:** - **No carry-over between targets.** Carrying the integral offset into the next target pushed it into…
On each new target it inverts a nominal static tip map by grid search to get a feedforward differential chamber command scaled by a learned ratio, then adds a damped-least-squares Jacobian integral correction from filtered camera tip error, rate-limited and converted to chamber commands.
Shown: public seed 0 (warmup_v1); this episode passes the fine rung. This episode: hold_error_max 0.00235, targets_held_fine 6, targets_held_coarse 6, settle_time_max 4.88, final_error_max 0.00218, track_rms 0.0216, saturation_ratio 0, max_speed 0.561, stiffness_scale 1.08, payload_mass 0, total_reward -24.8.
controller.py · agent transcript · trial soft-arm-reach-robust__8uq6v2r
weak_chamber_v1| criterion | graded | needed |
|---|---|---|
| base:fine | 1.000 | ≥ 0.900 |
| scenario:payload_v1 | 1.000 | ≥ 0.900 |
| scenario:hook_v1 | 1.000 | ≥ 0.900 |
| scenario:warmup_v1 | 1.000 | ≥ 0.900 |
| scenario:weak_chamber_v1 | 1.000 | ≥ 0.900 |
The agent's final message
The controller is done and passes the gate on every seed I tested: 360 of 360 runs (72 seeds × the five graded scenarios) reach the `fine` rung. On the visible seeds 0–4 the official evaluator reports `solved=True` at the 0.9 gate, with all four rungs met, including `fast`. The grader's own seeds are different, so that part is still untested. About 38 minutes of the 60 were used (01:29 → 02:07). **How it works** (`/app/work/controller.py`, with a docstring explaining the law and each gain): - **Feedforward:** for each new target, it searches the nominal static map for the pair of segment commands (dp) that puts the tip there. The search is limited to |dp| ≤ 0.6, the unfolded branch, which avoids the S/C ambiguity. That command is then multiplied by per-segment, per-side gains learnt at the end of each target that was held well. These gains soak up the seed's stiffness, the chamber gains, the weak chamber and the payload. - **Feedback:** on every new camera frame, an integral term is updated by a damped least-squares step through the map's Jacobian. It tracks hysteresis, creep, the warm-up drift and the hooked payload. - **Command shaping:** the command is slew-limited to 1.5 per second so it doesn't excite the 1.25 Hz bending mode. It is sent through `chamber_commands` with a 0.1 co-contraction bias, the same bias the map was built with. **Fixes that turned out to matter:** - **No carry-over between targets.** Carrying the integral offset into the next target pushed it into…
On each new target it inverts a nominal static tip map by grid search to get a feedforward differential chamber command scaled by a learned ratio, then adds a damped-least-squares Jacobian integral correction from filtered camera tip error, rate-limited and converted to chamber commands.
Shown: public seed 0 (weak_chamber_v1); this episode passes the fine rung. This episode: hold_error_max 0.00256, targets_held_fine 6, targets_held_coarse 6, settle_time_max 5.7, final_error_max 0.00247, track_rms 0.0222, saturation_ratio 0, max_speed 0.558, stiffness_scale 1.08, payload_mass 0, total_reward -26.3.
controller.py · agent transcript · trial soft-arm-reach-robust__8uq6v2r
nominal_v0| criterion | graded | needed |
|---|---|---|
| base:fine | 1.000 | ≥ 0.900 |
| scenario:payload_v1 | 1.000 | ≥ 0.900 |
| scenario:hook_v1 | 0.975 | ≥ 0.900 |
| scenario:warmup_v1 | 1.000 | ≥ 0.900 |
| scenario:weak_chamber_v1 | 0.950 | ≥ 0.900 |
The agent's final message
The final controller is in `/app/work/controller.py`. It passes on the visible seeds 0–19 in all five scenarios, but not every seed in every scenario; weak-chamber is the closest to the 0.9 gate. Failures per scenario over 80 seeds, using my own checker (it counts a target as held at 10 mm for 2 s, like the evaluator's `fine` rung): | Scenario | Failures (of 80 seeds) | |---|---| | `nominal_v0` | 0 | | `payload_v1` | 0 | | `warmup_v1` | 0 | | `hook_v1` | 2 | | `weak_chamber_v1` | 3 | Every seed that fails does so on one or two of its six targets. The official verify command on seeds 0–19 shows `fine` at 1.00 on the task's own scenario. It shows 1.00 on payload, hook and warm-up, and 0.95 (1 of 20) on weak-chamber. It prints `solved=False` because it compares against a gate of 1.0, not the task's 0.9. The `fast` rung is 0.85, which isn't graded here. **How it works:** - **Feed-forward:** The nominal static tip map is embedded in the file. Each new target is inverted to a pair of segment commands, starting from the previous solution. - **Feedback:** On each camera frame, an integrator corrects those commands using the map's Jacobian, with Tikhonov damping. It runs faster (`KI_FAST`) once the tip is nearly still. This absorbs the per-seed stiffness and chamber gains, payload, warm-up, creep and hysteresis. - **Learned gain:** After a target settles within 8 mm, the controller records how far the final command was from the feed-forward, per segment and per sign. It uses that…
The controller inverts a precomputed nominal static map from segment differential pressure commands to tip position to produce a feedforward command for each target, then adds a damped-Jacobian integrator driven by camera tip error (with faster gain when quasi-static) and learns per-chamber gain corrections from well-settled targets to reject material offsets and drift.
Shown: public seed 0 (nominal_v0); this episode passes the fine rung. This episode: hold_error_max 0.00103, targets_held_fine 6, targets_held_coarse 6, settle_time_max 4.96, final_error_max 0.000731, track_rms 0.0191, saturation_ratio 0, max_speed 0.722, stiffness_scale 1.08, payload_mass 0, total_reward -21.9.
controller.py · agent transcript · trial soft-arm-reach-robust__UhabYLx