Skip to content

Make the wind turbine's oracle a Newton torque law with a slew-capped PI - #59

Merged
YannBerthelot merged 1 commit into
mainfrom
plant/wind
Oct 2, 2026
Merged

YannBerthelot merged 1 commit into
mainfrom
plant/wind

Conversation

@YannBerthelot

Copy link
Copy Markdown
Owner

Fourth per-plant upgrade from the oracle audit. The wind turbine's MPC slot gets a controller with no optimiser that beats the gradient planner by 38%.

Generator torque reaches its command within a step, so the next step's
power is set by this step's torque. The new oracle, WindTurbineNewtonPI,
takes four Newton steps on the torque command through the plant's own
model with the turbulence at its mean, so the predicted power equals the
target and only the one-step wind innovation is left. Pitch is the
shipped PI on rotor speed in velocity form, with the setpoint at 1.05 x
rated and the command slew capped at 0.13 deg per step near it (the
activity the reward leaves free); the cap opens linearly to the
actuator's 2 deg per step toward the edges of a 0.97-1.13 band. There is
no optimiser. It replaces the GradientMPC, whose descent left a mean of
0.9-1.8 kW of power error its own model predicted.

Protocol cost falls from 2.10e-5 to 1.30e-5 $/step (-38%, better on
every seed), the 10-seed episode cost from 3.56e-5 to 1.38e-5 (ahead of
the PID on 10 of 10, from 9), zero trips, about 0.1 ms per step after a
one-off JIT compile of about 0.4 s per instance, where the planner took
about 0.4 s per step. Over seeds 3-199 of the oracle audit's screen it
never trips and the rotor stays within 0.836-1.178 of rated speed; a new
test runs the screen's extremes.

The NEA floor follows the new best hold, 1454 W (seed 0; mean 1749 W):
rho_floor = rho_floor_tracking goes from 1.17e-5 to 1.01e-5, and NEA is
0.821. e_floor (1680 W, an earlier oracle's hold) is within 1.16x of it
and stays, so the reward is unchanged and wind_turbine-v2 is re-stamped
in place. The gradient planner stays importable as
make_wind_turbine_gradient_mpc and is still the oracle for version-1
params; experts/mpc.py is unchanged.

Checks

  • The full fast suite passes locally: 1905 passed. Lint, format, every docs check and mkdocs build --strict pass too.
  • Only the wind turbine's rows changed in the three data files.
  • An adversarial review (two lenses, each finding checked by a skeptic) found no defect in the controller. Its seven confirmed findings were all wording, and all are fixed here. They covered trip-restart semantics, the per-step timing, the count of batched planners, and the "four Newton steps" phrasing.

Follow-up

No v2 oracle uses the shared GradientMPC move penalty any more (only the turbine did). It will be removed in the next shared-machinery change, which re-records every task.

🤖 Generated with Claude Code

Generator torque reaches its command within a step, so the next step's
power is set by this step's torque. The new oracle, WindTurbineNewtonPI,
takes four Newton steps on the torque command through the plant's own
model with the turbulence at its mean, so the predicted power equals the
target and only the one-step wind innovation is left. Pitch is the
shipped PI on rotor speed in velocity form, with the setpoint at 1.05 x
rated and the command slew capped at 0.13 deg per step near it (the
activity the reward leaves free); the cap opens linearly to the
actuator's 2 deg per step toward the edges of a 0.97-1.13 band. There is
no optimiser. It replaces the GradientMPC, whose descent left a mean of
0.9-1.8 kW of power error its own model predicted.

Protocol cost falls from 2.10e-5 to 1.30e-5 $/step (-38%, better on
every seed), the 10-seed episode cost from 3.56e-5 to 1.38e-5 (ahead of
the PID on 10 of 10, from 9), zero trips, about 0.1 ms per step after a
one-off JIT compile of about 0.4 s per instance, where the planner took
about 0.4 s per step. Over seeds 3-199 of the oracle audit's screen it
never trips and the rotor stays within 0.836-1.178 of rated speed; a new
test runs the screen's extremes.

The NEA floor follows the new best hold, 1454 W (seed 0; mean 1749 W):
rho_floor = rho_floor_tracking goes from 1.17e-5 to 1.01e-5, and NEA is
0.821. e_floor (1680 W, an earlier oracle's hold) is within 1.16x of it
and stays, so the reward is unchanged and wind_turbine-v2 is re-stamped
in place. The gradient planner stays importable as
make_wind_turbine_gradient_mpc and is still the oracle for version-1
params; experts/mpc.py is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@YannBerthelot
YannBerthelot merged commit aabd0d3 into main Oct 2, 2026
6 checks passed
@YannBerthelot
YannBerthelot deleted the plant/wind branch October 2, 2026 16:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant