VOLLEY deployer, closed, on its ESPA interface

VOLLEY: an electromagnetic orbital CubeSat deployer

A magazine-fed electromagnetic deployer that ejects unmodified CubeSats from a rideshare host at programmable velocity, the unserved regime between spring deployers (~2 m/s) and propulsive transfer vehicles (hundreds of m/s).

MIT TRL 2-3 Model outputs only, unvalidated No FEA No hardware

The idea

CubeSats flown as rideshare secondaries inherit the primary customer's orbit. The spring that ejects them adds 1-2 m/s, enough to drift clear, not enough to change an orbit. A satellite with no propulsion of its own is stuck there for life. VOLLEY replaces the spring with an ironless double-sided Halbach linear synchronous motor driving a reusable magnetic sled along a 1.5 m track. Twelve 3U CubeSats feed from two transverse cassettes and fire one at a time. The satellite is never modified, the magnets ride the sled, not the payload.

Interior
Interior. Track, stator belts, sled, and both cassettes with the enclosure open.
Exploded view
Exploded. Nine documents: track, stator, sled, cassettes, brake, ESPA interface, enclosure, payload.

A shot, end to end

Feed, retention gate, 1.3 m of acceleration at 10.7 g, coast and trim, release at 1500 mm, regenerative braking over the next 240 mm, eddy brake, sled recovered for the next shot. Regeneration returns 296 J of the sled's 1291 J to the bank and the brake absorbs the remaining 952 J, so efficiency is quoted electrical-to-payload net of a 23 % sled-energy credit.

Mid-stroke
Mid-stroke. Under thrust, payload cradled.
Release
Release. Payload departs at 1500 mm.
Braking
Braking. Sled runs on into the eddy brake.
Animated shot: position, velocity, commanded force and bank current against time
The stroke, drawn as it happens. 157.3 ms from breech to release. Position, velocity, commanded force and bank current, all four from the same integrator that produces the paper's numbers (paper/make_animation.py imports motor_model.py rather than reimplementing it).

Headline results

Every figure here is a script output, not a measurement. Two of them carry a genuine independent cross-check; everything else is single-sourced.

QuantityValueSource
Thrust constant11.22 N per kA/m, ±1.26 % ripplemotor_model.py
Exit velocity, 3U16.54 m/s at 10.7 gmotor_model.py
Electrical to payload efficiency21.2 %motor_model.py
Closed-loop dispersion0.027 m/s (3σ) to ±0.10 km apogeemotor_model.py
Orbital lifetime multiplierx1.62 at mean activity, not invariant, P16astro.py
Constellation seeding, 30°1.4-6.9 days vs 25 by differential dragastro.py
Dry / loaded mass76.9 kg / 124.9 kgmass_properties.py
Recoil per shot66.1 N·sastro.py
Track first mode109 Hz fixed-fixed (target >70)sizing.py

These numbers moved down on 2026-07-29. The headline was 20.37 m/s at 16.3 g against a 4.86 kg parametric sled; exact solid volumes from the Gen3 CAD give 9.445 kg (P15). The consequence of each mass band was declared in validation/A4_sled_structural.md before the structural analysis ran, and the measurement landed in the ≥ 6.80 kg branch, "the headline changes and the paper changes materially". A4 has since run and the drawn plate passes all three bands, so nothing forces a lighter chassis. The scripts moved first, then the paper. Exit velocity is down 19 % and efficiency from 32 % to 19 %, since taken back to 21.2 % by regeneration (A11), but the lifetime multiplier fell only x1.80 to x1.62, lifetime is a weak function of Δv, so the mission case survives better than the machine spec. 9.445 kg is the as-drawn, unpocketed geometry and A4 reports a 17x stress margin, so a rib-stiffened redesign would recover mass; nobody has designed one.
Shot simulation
The shot. Force, velocity and current through the 157.3 ms stroke.
Orbital lifetime
Lifetime. Boosted vs unboosted decay. The x1.62 ratio is the claim, not the absolute years.

Where the energy goes

2881 J leaves the capacitor bank per shot, 296 J comes back through the regenerative section, and 547 J of the net 2585 J reaches the payload — the 21.2 %. Source sizing.py energy_closure; 100.0 % accounted. This chart said "no regeneration credit" and put the sled's whole 1291 J in the brake until 2026-07-31. The 2025 decision behind that argued the motor cannot arrest the sled, which it cannot — the brake still takes 952 J of every shot. It never argued that none of the energy could be recovered, and A11 found 23 % of it available. The 86 J ESR bar has its own history: no script modelled the bank's series resistance until 2026-07-30, so the loss was real in hardware and absent from the accounting until a circuit simulation found it.

Sled KE (brake)952 J
Copper, shot + regen843 J
Payload KE547 J
Recovered to the bank297 J
Converter loss113 J
Bank ESR loss94 J
Auxiliary35 J

Seeding, against the alternative

Days to spread a constellation 30° apart. The differential-drag comparator is itself a model output, not a measurement, replacing it with published flown results is an open task.

VOLLEY, 10 m/s1.4 d
VOLLEY, 5 m/s2.8 d
VOLLEY, 2 m/s6.9 d
Differential drag25.0 d

GMAT cross-check, the first external result, and it found something

GMAT R2022a, run headless with MSISE90 / 20x20 gravity / RK89, propagated to the 120 km floor at three solar-activity levels. The x1.80 lifetime multiplier of the day reproduces at mean and high activity. At low activity it does not, and the invariance the paper nominated as its defensible result is falsified. These runs were propagated at 20.37 m/s, before the measured sled mass moved the rated point to 16.54 m/s, the falsification survives, since a uniform density scale cannot move a ratio at any Δv, but the absolute numbers are historical (P19).

High, F10.7 250x1.7302
Mean, F10.7 150x1.7750
Low, F10.7 70x2.0739
astro.py claimx1.80

Spread 18.48 % against a ≤5 % band declared before the run, A5's verdict is FAIL. The mechanism was tested, not guessed: astro.py models solar activity as a uniform multiplicative scale on density, and sweeping that scale over a 40x range moves the multiplier only 1.7992 to 1.7968. A uniform density factor divides both lifetimes by the same number, so the ratio is invariant by construction of the model. MSIS instead changes the shape of the density, altitude profile with F10.7, the boosted orbit's apogee sits ~37 km higher, and the ratio then moves. Written up as P16.

Separately, over a bounded 30-day window the fitted decay rates are −0.1618 km/day (GMAT) against −0.1216 km/day (astro.py), GMAT decays 1.33x faster. Reported SMA is osculating and its short-period variation runs 12.2 km peak to peak, several times the decay across the window, so the comparison is a least-squares rate over 31 daily samples rather than a difference of endpoints.

What has actually been verified

Two results have a genuine independent cross-check: the Halbach airgap field (analytic wave model vs magpylib, agreeing to three digits) and orbital decay (orbit-averaged Gauss vs an independent Cowell RK4, 99.4 %). Nothing has been validated by hardware, FEA, or third-party review. Each cross-check below carries an acceptance band declared before its run. Three have now been run, and one of the three failed , which is the point of declaring the band first.

AnalysisToolClosesStatus
A1 airgap fieldFEMME1, E2specified
A4 sled chassisCalculiX ccx 2.21P5, P8run, all 3 bands pass
A5 lifetime & seedingGMAT R2022aE6, P16run, FAIL, invariance falsified
A6 conjunction PcNASA CARAP1specified
A7 separation & tip-offProject ChronoE7specified
A8 pulse-power chainngspiceE17run, bands met, 2 findings

The paper once carried four numbers its own scripts did not reproduce. All four were found by rebuilding the analysis from scratch and corrected against the scripts; the conjunction claim was reframed rather than patched, because that minimum turned out to be a near-resonant beat sample that swings an order of magnitude with a ±2.5 % velocity change. The defects stay documented as P1, P4 for the audit trail.

Reproducing it

Five scripts, two dependencies, roughly twelve minutes end to end. Results land in analysis/results/*.json.

ScriptWhat it computesRuntime
verify_field.pymagpylib cross-check of the airgap field~10 s
mass_properties.pyparametric mass rollupinstant
motor_model.pyKt, shot sim, closed-loop dispersion~2 min
sizing.pymechanical, thermal, electrical marginsinstant
astro.pylifetime, seeding, conjunction~10 min