Ethan Sheehan
All work REGULATOR — 2026

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.

RoleSimulation and flight-code pipeline
Bench telemetry for the 7 bar test: supply pressure decaying from 15.9 to 10.4 bar, regulated pressure rising to about 6.5 bar against the 7 bar setpoint, and the servo transient
Bench, 7 bar setpoint: P1 decays 15.9 to 10.4 bar, P2 holds 6.5 against the 7 bar setpoint, servo transient below.
Best hold
3.96 / 4.0 bar
Replay
5001/5001 bit-exact
Tank held
55 bar
01

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.

Feed-system schematic: nitrogen bottle into the E-Reg servo ball valve, into the propellant tank and engine, with the STM32 closing the loop on the bottle and tank pressures
Feed system: N₂ bottle → E-Reg (servo ball valve) → tank → engine, STM32 closing the loop over P₁/P₂.
The bench rig in the workshop: a pressure vessel and pipework on a wooden stand, STM32 boards and wiring on the table, a team member at the bench
The bench rig: pressure vessel, STM32 boards, wiring. Frame grab, June 2026.
02

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.

Block diagram of the cascade controller: state machine, gain-scheduled outer pressure PID, inner valve-angle PI, servo, gear train and backlash, with the feedback paths drawn
Cascade controller: state machine, gain-scheduled outer PID, inner valve-angle PI, servo/gear/backlash, feedback paths.
Simulink export of the controller subsystem: five inputs (mode command, pressure setpoint, tank, bottle and valve-angle measurements) into one MATLAB Function block, four outputs (servo speed, servo demand, state, active setpoint)
The v2 controller as one MATLAB Function block in Simulink, autolayout as exported.
Simulink export of the top-level EReg v2 model: controller, servo-actuated valve and tank plant subsystems with pressure-transducer blocks and scopes
EReg_v2 top model: controller, servo-actuated valve, tank plant. Autolayout as exported.
03

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.

Simulated flight-scale two-phase nitrous oxide tank drain: tank pressure held at the 55 bar setpoint while the saturation pressure floor falls and the tank temperature drops 3.8 K
Two-phase N₂O at flight scale: 55 bar hold while the vapour-pressure floor collapses and the tank self-cools 3.8 K.
04

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.

Simulated dual-branch run: fuel branch held at 50 bar and oxidiser branch at 55 bar from one shared bottle whose pressure falls from 300 to 220 bar
Two regulators, one bottle: both branches hold (50/55 bar), HP 300→220 bar.
Water and IPA mass-flow plateaus from the simulation, with the ratio 0.885 annotated against the injector-theory value of 0.887
Water vs IPA flow plateau; ratio 0.885 vs √(786/1000) = 0.887.
Simulated v2 clean-mode water mission: controller state bands over time, tank pressure rising to setpoint during dead-head pressurise with no overshoot, then holding through the run
v2 clean-mode mission: state bands, dead-head pressurise with zero overshoot.
05

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.

Scatter of held pressure against commanded setpoint for all eight bench tests with a y equals x reference line; the 4 bar test sits on the line, the supply-limited tests fall below it
Commanded vs held pressure, all 8 tests, y = x reference.
Bench telemetry for the 8.5 bar test: the servo angle hunting between 47 and 107 degrees for two seconds before settling while regulated pressure climbs to 7.36 bar
Bench, 8.5 bar setpoint: the hunting-then-settle test.
Bench telemetry for the supply-limited 5 bar test: supply pressure barely above the setpoint and the valve angle saturating near 100 degrees
Bench, 5 bar setpoint, supply-limited: P1 barely above setpoint, valve saturates.
Bench telemetry for the full 190 second bottle blowdown at a 3 bar setpoint: supply falling from 14.7 to 2.1 bar and regulated pressure dropping away from setpoint as supply dies
Bench, full blowdown: P2 vs setpoint as supply dies, 14.7→2.1 bar over 190 s.
06

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.