Three caveats surfaced during walkthrough lived only in the conversation transcript before this commit. Now they live where future agents and future-me will actually see them: - reach_operation.m and reachability/README.md state prominently that the current reach tube is an over-approximation of the LINEAR model, not a sound tube for the nonlinear plant. Thesis-blocking for a real safety claim. Upgrade paths documented. - ctrl_heatup.m header and plant-model/CLAUDE.md note that the feedback-linearization u_ff assumes exact alpha_f, alpha_c. Real plants drift (burnup ~20%, boron ~10x, xenon). Robust treatment = parametric reach with alpha as an interval. - ctrl_heatup.m header and plant-model/CLAUDE.md note that sat() is formally a 3-mode piecewise-affine sub-system. Operation-mode LQR is dormant (trivially); heatup will need either a dormancy proof or explicit hybrid modeling. README.md top-level now has a run-commands table for the reach artifacts and a pointer to the soundness status. Hacker-Split: raise caveats from transcript to artifact so the work is actually reviewable by people who weren't in the room. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.7 KiB
Session 2026-04-17 — controllers, linearization, first per-mode reach, barrier attempt
Context
Pre-lunch discussion: reachability thrust is empty, controllers missing for three of four DRC modes, tool choice (CORA vs JuliaReach) open. Dane stepped away for lunch with instructions to "let me rip" on the whole pipeline. Auto-mode on.
What landed
- Three new controllers in
plant-model/controllers/:ctrl_shutdown.m— constantu = -5*beta(passive hot standby).ctrl_scram.m— constantu = -8*beta(max rod worth).ctrl_heatup.m— feedback-linearizing P on a rampedT_avgreference, with saturatedu. No integrator state on purpose (see below).
pke_linearize.m— numerical Jacobians via central finite differences. At the operating point the linear model agrees with the nonlinear simulation to ~4e-4 relative error for a 5%Q_sgstep over 60 s. Eigenvalues span[-65.93, -0.0124]— stiff by a factor of ~5000.ctrl_operation_lqr.m— full-state LQR aroundx_op. Closed-loop T_avg tracking is essentially perfect under the sameQ_sgstep that makes the plain P controller overshoot by ~5 F. Cost: requireslyap/icare(base MATLAB, no Control Toolbox).main_mode_sweep.m— drives all five modes back-to-back from plausible ICs, saves 6 figures todocs/figures/mode_sweep_*.png.- Hand-rolled zonotope reach in
reachability/reach_linear.mplusreach_operation.mend-to-end. Over-approximates with axis-aligned box hull + elementwise-abs matrix propagation. Result for operation mode underQ_sg ∈ [85%, 100%]·P0and an initial ±0.1 K box on T_avg: max|T_c - T_c0| = 0.1 Kover 600 s. Safety band is ±5 K. Operation-mode obligation discharged. - Lyapunov-ellipsoid barrier in
reachability/barrier_lyapunov.m. Does NOT certify safety — the tightest quadratic bound we can get (over a sweep ofQbar(9,9)from 10 to 1e6) yields max|dT_c| ≈ 33 K, far outside the 5 K band. This is a fundamental limitation of quadratic Lyapunov for highly anisotropic problems: the ellipsoidal invariant is fat in the precursor/thermal directions and can't be made tight only along T_c. For an analytic barrier cert here we'd need SOS polynomial barriers or a polytopic invariant. Numerical zonotope reach still proves safety; the analytic cert is a "nice to have". - Julia port in
julia-port/. Plant parameters, RHS, linearize, all five controllers, LQR factory.scripts/sim_sanity.jlmatches MATLAB to 3 decimals on the standard operation test.scripts/reach_operation.jlis a stub — ReachabilityAnalysis.jl's LGG09, GLGM06, BFFPSV18 all numerically explode on the unscaled stiff system (envelopes of 1e14 K or worse). Fix is diagonal state-scaling; didn't get to it this session.
Key findings worth carrying forward
The model doesn't support true cold shutdown
alpha_f, alpha_c are linearized at (T_f0, T_c0) = (328 C, 308 C).
Extrapolating to T = 50 C gives intrinsic feedback of ~5 $ which is
unphysical — real temperature coefficients saturate/flip at low temp.
Trust range: ±50 C from operating point. "Shutdown" in this demo
means hot standby (290 C, n≈0), not cold shutdown. Documented in
plant-model/CLAUDE.md. To properly support cold shutdown we'd need
piecewise-linear or table-lookup coefficients — separate modeling task.
Heatup overshoot is a controller-design signal, not a physics bug
First heatup pass started from n=1e-6 and produced a ~20-minute lag
(reactor rebuilds power from decay-heat level) followed by a ~7 K
overshoot (thermal inertia + no derivative term). Fixed by:
(a) saturating |u| at 0.5·beta so rho stays subcritical-prompt,
(b) starting heatup from n=0.001 (0.1% power, already critical),
which matches real plant practice — criticality is achieved in
shutdown before DRC transitions to heatup.
PID not a good idea here
The plant has intrinsic integrators (thermal mass). Adding PI:
- Increments state dim 10→11 (cheap for CORA, ok for JuliaReach).
- Anti-windup saturation turns each "continuous mode" into a hybrid mode inside itself — more transitions, more reach-set bookkeeping.
- Integrator drift under persistent disturbance inflates the reach set over long horizons.
Stuck with P + feedforward; if needed we can promote to PI with eyes open about the hybrid-mode cost.
LQR is dramatically better than P for operation mode
Same operating point, same Q_sg step: LQR holds T_avg essentially at setpoint; plain P has 5 F overshoot and ~0.8 F steady-state lag. LQR adds zero state. The only downside: K is tuned around one operating point — off-point robustness would need gain scheduling or MPC.
Hand-rolled reach beats ReachabilityAnalysis.jl out of the box
The stiff, poorly-scaled nature of this system (eig span 5000x, state magnitudes spanning 10 orders) breaks ReachabilityAnalysis.jl with default settings. Hand-rolled MATLAB reach with augmented-matrix integration trick + elementwise-abs box propagation was ~50 lines and produced a tight, trustworthy result immediately. Lesson: for well-structured linear reach, don't reach for a toolbox.
The analytic barrier problem is anisotropy-limited
Safety set is a thin slab |T_c - T_c0| <= 5 K in a 10D state space.
Lyapunov ellipsoids that contain an initial box + robust invariant
are necessarily fat in the uncontrolled directions (slow
precursors), and no rescaling of the Lyapunov weight can pull them
tight only along T_c without blowing out the other directions.
Logical next step for a thesis-strength barrier: SOS polynomial
barriers or polytopic (halfspace-intersection) invariants.
Soundness, α-drift, saturation — the three "this isn't actually rigorous yet" flags
Dane caught these during walkthrough. All three now documented in the relevant file headers so they don't live only in the transcript:
- Soundness:
reachability/reach_operation.mandreachability/README.mdnow prominently state the current reach tube is over-approximation of the LINEAR model, not the nonlinear plant. Upgrade paths: nonlinear reach (CORA/JuliaReach nonlinearSys) or linear reach + Taylor-remainder inflation. Either is thesis-blocking for a real safety claim. - α-drift:
ctrl_heatup.mheader andplant-model/CLAUDE.mdnow note that the feedback-linearization cancellation assumes exact α_f, α_c. Real reactors have α drifting (burnup ~20%, boron ~10x, xenon). Robust treatment = α as interval, parametric reach. - Saturation semantics:
ctrl_heatup.mheader now notes the sat() is piecewise affine and must be either proven dormant or modeled as a hybrid sub-mode in reach. Operation-mode LQR is dormant (trivially); heatup will need explicit treatment.
Documented in README.md top-level under the reach commands too.
Loose ends for the next session
- Julia reach needs state rescaling.
S = diag(...)chosen so all states have O(1) magnitude, then run reach in scaled coords. - Heatup reach: the ramped reference makes
x*(t)time-varying, so LQR-around-x_op isn't directly applicable. Options: trajectory-LQR (time-varying K), or tube MPC. - Predicate thresholds still not pinned in the FRET spec.
t_avg_in_rangecurrently = ±5 K in the reach code but not reflected in the spec JSON. Need to sync. - Shutdown and scram modes don't have reach analysis yet. They're trivial (constant u) but the safety claim for scram — "reactor reaches subcritical decay in bounded time from any operating IC" — is actually a nice bounded-time reachability problem.
Commit
Committed as two or three logical chunks. See git log.