BSEP E-Reg
A software-defined pressure regulator for HyPower's pressure-fed rockets: a servo ball valve and a gain-scheduled cascade PID on an STM32, simulated, verified bit-exact into flight C, then bench-tested.
What an E-Reg is
HyPower's rockets are pressure-fed: a 300 bar nitrogen bottle pushes the propellant out, and something has to drop that to a steady 30-55 bar at the tank. A mechanical regulator does it with a spring and a diaphragm. The E-Reg does it with a COTS ball valve, a 70 kg·cm servo through a 1:1.7 gear train, and a gain-scheduled cascade PID on an STM32 reading bottle and tank pressure. The team's requirements: 120-300 bar in, 30-55 bar out, under 3 bar transient and 1 bar steady-state error, 80 percent throttle, robust to an in-flight relight. The architecture and hardware came out of a 2024-25 team design study. My part is the simulation and flight-code pipeline behind it.

Controller architecture
The controller is a state machine, OFF to ARMED to PRESSURIZE to RUN, wrapped around two loops: an outer pressure PID with gains scheduled on operating point, and an inner PI on valve angle that hides the servo, gear train and backlash from the outer loop. In v1 this lived as Simulink blocks, tuned against the June 2026 bench data. In v2 I rebuilt it as one C-compilable MATLAB function with every tunable in a single params file, and the plant models are rebuilt from source by script rather than saved by hand. The Simulink exports below are shown as the tool lays them out.


Simulation: the N₂O flight tank
Water on the bench is easy; a flight tank of nitrous oxide is not. The v2 plant carries a two-phase N₂O tank with an equilibrium energy balance, a CoolProp saturation lookup and Dyer/NHNE injector flow. As the tank drains the liquid boils to fill the ullage, the vapour-pressure floor collapses and the tank self-cools 3.8 K. Through that the controller holds 55.0 bar off a 300 bar bottle. The N₂O gains come from the team design study, not from bench data, so this is a model result rather than a test result.
Simulation: two branches, one bottle
Waxwing feeds IPA and N₂O from the same bottle, so the model does too: one shared 6 L, 300 bar N₂ bottle driving two regulators, the IPA branch at 50 bar and the oxidiser at 55 bar. Both branches hold and the bottle falls from 300 to 220 bar over the mission, with N₂ mass conserved across the split to 1e-14 kg. Adding IPA as a fluid gave a cheap sanity check: the flow plateau ratio against water comes out at 0.885, and injector theory says √(786/1000) = 0.887. The clean-mode water mission shows the dead-head pressurise phase with zero overshoot.
Bench, June 2026
Eight recorded regulation tests of the real hardware: an STM32 running the controller, an ADS131 pressure ADC, phone video of the rig with live telemetry on screen. There was no logger, so the numbers were read off the Live Expressions panel frame by frame at 30 fps. Best hold: 3.96 bar on a 4.0 bar setpoint. At 7 bar the supply decayed from 15.9 to 10.4 bar and the hold recovered; at 8.5 bar the servo hunted between 47 and 107 degrees for two seconds, then settled. The 10.5 and 5 bar tests were supply-limited, valve pinned near 100 degrees. The controller holds when there is margin and sits below setpoint when there is not.
Flight code
The flight logic is one pure MATLAB function, ereg_controller_step.m, with its expression grouping kept deliberately close to the v1 block diagram. That made the rebuild testable: replaying v1's recorded inputs through the extracted function reproduces v1's outputs bit-exact, 5001 of 5001 samples, and the full closed-loop replication agrees to a relative 1.5e-11 on every signal against an acceptance of 1e-6. Two C-code paths are proven, Simulink Coder with ert.tlc and a MATLAB Coder library. ereg_controller_hw_step.c is what runs on the STM32 every 2 ms; the board does the same arithmetic as the sim.