Digital twins & sim-to-real
What does a 1:N model of a cargo UAV tell you about the 1:1 aircraft?
research/aerolog-scaling
Research programme (proposal stage): per-quantity error budget for a Froude-scaled cargo aircraft model, with a stdlib scaling calculator; first-order result: at 1:10 the model needs 17 to 35% more power than Froude scaling predicts
8 tests
What it found
An open research programme on sub-scale flight testing of cargo and delivery aircraft. Dynamic (Froude) scaling keeps trim, mode frequencies and gust response, but Reynolds number falls as n1.5, so skin friction rises, and cell, motor and propeller performance do not scale with the airframe. The programme asks how large each error is for 1:2 to 1:20 models of an electric cargo aircraft, and whether a corrected model can recover it. Milestone 1 is a stdlib calculator (9 tests; exponent table dimensionally checked, ISA and Sutherland values checked) and a first-order flat-plate result for a 1,000 kg, aspect-ratio-10 airframe: at 1:10 the model needs 1.27× the Froude-scaled power (1.17 to 1.35 across form-factor, wetted-area and aspect-ratio sweeps) and L/D falls from 22.8 to 18.0. An untripped laminar-flow variant makes small models look better than full size, which is a modelling artefact and the reason the next milestones use XFOIL polars measured against UIUC data. The airframe constants are design choices, not a specific aircraft; the Froude exponents and the NASA TP-1435 and other citations are from memory and were not machine-checked (registries returned 403). Preliminary. Milestone 6a: on 134 measured cruise flights of a DJI Matrice 100 (Rodrigues et al. 2022 data, CC BY 4.0), electrical power scales with takeoff mass to the power 1.54 (95% bootstrap interval 1.41 to 1.67 over flights), consistent with the m1.5 behind Froude power n3.5, within one airframe and a 13.6% mass range; electrical cruise power is 1.85× the ideal induced power at every payload, and falls 10% from 4 to 12 m/s. Payload is partly confounded with flight day (density not logged). Milestone 7a: at n = 0.2 the uncorrected model needs 1.157× the Froude power; a search of 178 section and boundary-layer cases (NACA 4-digit and low-Reynolds sections, CL within 6%, lift-curve slope within 5%) reaches at best 1.086, so no section restores it to within 5% (H5 refuted in this space; NeuralFoil polars, similarity kept).
Research log
Ongoing: each run adds a batch and an entry, newest first. Source: LOG.md.
2026-10-31 · Milestone 9o: can the output-error fit estimate the noise correlation itself and still recover 9n's gain? (planned before running)
- Why: 9n's "Next". Whitening recovered 14 of 9m's 17 points of gust share, but with rho = 0.9 given exactly, so 83% was an upper bound.
- Plan (
experiments/estimated_rho/run.py): 9n's script and seed (20261103: the white and coloured-unweighted rows should reproduce 9m and 9n). Third column: from the unweighted coloured fit, estimate rho as the lag-1 autocorrelation of the pooled residuals (clipped to 0 to 0.99), refit with AR(1)-whitened residuals, re-estimate, refit once more (iterated GLS). Reports the distribution of estimated rho (truth 0.9). - Predictions (before running): (1) the median estimated rho is within 0.1 of 0.9 (prior 70%; residuals of a misspecified-by-noise fit are slightly under-correlated). (2) Share of draws within 10% gust is within 3 points of 9n's known-rho 83% (prior 55%). (3) Fit failures at most twice white's (prior 65%). Refuted: (1) median outside 0.8 to 1.0; (2) gap over 3 points; (3) more than twice.
- Limits known in advance: one true rho, AR(1) assumed in the estimator as in the generator (the model is correct, which flatters it); 10 draws on a third of the designs; one seed.
### Outcome of 9o (experiments/estimated_rho/: run.py, results.txt; about 25 min wall)
- 26 designs, 260 draws, 2 periods, 10% noise. White and coloured-unweighted rows reproduce 9m and 9n exactly. Coloured with rho estimated by two GLS iterations: fit failures 0; median |error| in phugoid, short-period frequency and damping ratio 0.25, 1.21, 1.63% (known rho 0.26, 1.19, 1.60; unweighted 0.26, 1.51, 2.55); share of draws within 10% gust 83% (known rho 83%, unweighted 69%, white 86%); designs with 90% of draws within 10% gust 18 of 26 (17 known rho); median worst gust error 5.9%; median worst mode error 3.2%. Estimated rho: median 0.878, 5th to 95th percentile 0.840 to 0.906 (truth 0.9).
- (1) held (0.878). (2) held (83% against 83%). (3) held (0 failures).
- Reading: estimating the correlation from the residuals costs nothing measurable against being given it, so 9n's recovery (69% to 83% gust share) is not an artefact of knowing rho. The estimate is biased low by about 0.02. The 1.5x gust margin from 9m can drop to about 1.2x if the fit is iterated GLS.
- Limits: the estimator's AR(1) form matches the generator, which flatters it (real IMU noise is not exactly AR(1)); one true rho; 10 draws on a third of the designs; one seed; paper draft not updated for 9m to 9o.
- Next: misspecified noise (AR(2) or 1/f generator, AR(1) estimator); real IMU noise density; NACA 0012/0015 data; thrust law; AIAA template.
2026-10-31 · Milestone 9n: does fitting 9m's coloured-noise record with AR(1)-whitened residuals recover the loss? (planned before running)
- Why: 9m's "Next". 9m's output-error fit weights residuals as independent; with AR(1) noise (rho 0.9) a generalised least-squares residual, e_t - rho e_(t-1), is the efficient weighting.
- Plan (
experiments/whitened_noise/run.py): 9m's script and seed (20261103, same standard normals, so the white and coloured-unweighted columns should reproduce 9m), plus a third column: the same coloured record fitted with whitened residuals, in both continuation stages. rho = 0.9 is given to the fit (known), which flatters it; estimating rho is not tried. - Predictions (before running): (1) whitening brings the median short-period frequency error on coloured noise back to within 0.5 points of white's (prior 55%). (2) Share of draws within 10% gust recovers at least half of 9m's 17-point loss (prior 60%). (3) Fit failures stay at most twice white's (prior 65%). Refuted: (1) gap over 0.5 points; (2) recovers under 8.5 points; (3) more than twice.
- Limits known in advance: rho known exactly, one value; 10 draws on a third of the designs; one seed.
### Outcome of 9n (experiments/whitened_noise/: run.py, results.txt; about 17 min wall)
- 26 designs, 260 draws each, 2 periods, 10% noise. The white and coloured-unweighted rows reproduce 9m exactly (same seed). Coloured with whitened residuals (rho = 0.9 known): fit failures 0; median |error| in phugoid, short-period frequency and damping ratio 0.26, 1.19, 1.60% (unweighted: 0.26, 1.51, 2.55; white: 0.07, 0.67, 1.51); share of draws within 10% gust 83% (69% unweighted, 86% white); designs with 90% of draws within 10% gust 17 of 26 (9, 19); median worst gust error 5.9% (7.2, 5.6); median worst mode error 3.2% (4.0, 3.1).
- (1) refuted, narrowly: the short-period frequency gap to white is 0.52 points, against a bar of 0.5; the phugoid error is unchanged (0.26). (2) held: whitening recovers 14 of 9m's 17 points of gust share. (3) held (0 failures).
- Reading: whitening brings gust-prediction reliability back to within 3 points of the white-noise case and the damping error nearly to white's, but not the frequency errors. It needs the correlation coefficient, here given exactly; a real fit would estimate rho, which is not tested, so 83% is an upper bound for a whitened fit. The 1.5x margin advice from 9m stands unless rho can be estimated from the record.
- Limits: as planned (rho known, one value, 10 draws, a third of the designs, one seed); the paper draft has not been updated for 9m or 9n.
- Next: estimate rho from the residuals (iterated GLS); real IMU noise density; NACA 0012/0015 data; thrust law; AIAA template.
2026-10-31 · Milestone 9m: does coloured (AR(1)) sensor noise break the output-error fit that white noise did not? (planned before running)
- Why: 9l's "Next". Every noisy-identification result so far used white noise; real IMU and air-data errors are correlated in time, and a fit that treats residuals as independent can be biased by slow noise that looks like a mode.
- Plan (
experiments/coloured_noise/run.py): 9l's script (continuation start, estimated initial state, 2 phugoid periods, 10% noise, tail-slope scale 0.75, every third of the 78 designs, 10 paired draws, seed 20261103). Both columns see the same standard normals: white, or AR(1) with rho = 0.9 per sample (sample step is one twentieth of a short-period period, so the correlation time is about half a short-period cycle) scaled to the same marginal rms. - Predictions (before running): (1) coloured noise raises the median short-period frequency error over white, but it stays under 3% (prior 60%). (2) Fit failures with coloured noise are no more than twice white's (prior 55%). (3) The share of draws within 10% gust falls by under 10 points (prior 45%). Refuted: (1) coloured at or above 3%, or not higher than white; (2) more than twice; (3) 10 points or more.
- Limits known in advance: a single correlation coefficient, equal on all four states and in-band with the short-period mode; 10 draws on a third of the designs; one seed.
### Outcome of 9m (experiments/coloured_noise/: run.py, results.txt; about 15 min wall)
- 26 designs, 260 draws each, 2 periods, 10% noise, estimated initial state, same standard normals for both. White against AR(1) rho = 0.9: fit failures 0 and 0; median |error| in phugoid, short-period frequency and damping ratio 0.07, 0.67, 1.51% against 0.26, 1.51, 2.55%; share of draws within 10% gust 86% against 69%; designs with 90% of draws within 10% gust 19 against 9 of 26; median worst gust error 5.6% against 7.2%; median worst mode error 3.1% against 4.0%.
- (1) held (1.51%, higher than white's 0.67 and under 3%). (2) held (0 and 0). (3) refuted: the gust share fell 17 points, not under 10.
- Reading: coloured noise at the same rms doubles the short-period frequency error and cost 17 points of gust-prediction reliability, with no outright fit failures, so the failure is silent: the fit converges, to slightly wrong modes. The earlier white-noise results (9h to 9l) are optimistic for a real record; the 2-period test card advice stands, but a margin on the gust error of roughly 1.5x is prudent where the noise is correlated.
- Limits: as planned (one rho, equal on all states, 10 draws, one seed). The residual weighting is the unweighted white-noise one; a whitened (generalised) least-squares residual was not tried and may recover much of the loss.
- Next: whitened residuals for the coloured case; real IMU noise density; NACA 0012/0015 data; thrust law; AIAA template.
2026-10-31 · Milestone 8f: paper draft catches up with milestones 2a to 2c and 9j to 9l (no new simulation)
- Section 4.10 gains the 10% noise, continuation-start and estimated-initial-state results; new Section 4.11 holds the measured-flight energy results with their limits;
check_numbers.py ties the new figures to this log (all ok). Next: turbulence; thrust law; lift-plus-cruise sizing; AIAA template.
2026-10-31 · Milestone 9l: what does estimating the initial state cost the output-error fit at 10% noise? (planned before running)
- Why: 9k's "Next". Every output-error fit so far was simulated from the true initial state, which a real doublet does not give; 9i and 9j flagged it as flattering.
- Plan (
experiments/estimated_x0/run.py): 9k's continuation fit on records of 2 phugoid periods, 10% noise, tail-slope scale 0.75, every third of the 78 mode-matched designs, 10 paired draws, seed 20261102 (reduced for session CPU). Both fits see the same record: (a) initial state known; (b) the four initial states are free parameters started at the first noisy sample, in both stages of the continuation. - Predictions (before running): (1) median short-period frequency error with estimated x0 is under 3% (prior 70%). (2) Estimated x0 has no more than twice the fit failures of known x0 (prior 60%). (3) The share of draws within 10% gust drops by under 10 points (prior 55%). Refuted: (1) at or above 3%; (2) more than twice; (3) 10 points or more.
- Limits known in advance: white noise on all four states; 10 draws on a third of the designs, so shares have coarse resolution; 2 periods only; one seed.
### Outcome of 9l (experiments/estimated_x0/: run.py, results.txt; 8.5 min wall, 34 min CPU)
- 26 designs (every third of 78), 260 draws, 2 periods, 10% noise. Known x0 against estimated x0: fit failures 0 and 0; median |error| in phugoid, short-period frequency and damping ratio 0.07, 0.65, 1.38% against 0.07, 0.71, 1.46%; share of draws within 10% gust 88% against 89%; designs with 90% of draws within 10% gust 23 against 21 of 26; median worst gust error 5.6% for both.
- (1) held (0.71%, under 3%). (2) held (0 and 0). (3) held (the share did not drop; it rose one point, within the 10-draw resolution).
- Reading: for a 2-period record at 10% noise, estimating the four initial states costs about 0.06 points of short-period frequency error and nothing measurable in gust outcome, so 9i to 9k's known-x0 assumption did not flatter the output-error fit at this record length. The 2-period test card advice stands.
- Limits: as planned (a third of the designs, 10 draws, white noise, one seed); a real doublet's initial state also depends on input shape and actuator lag, not modelled; 4-period records were not rerun with free x0.
- Next: turbulence (coloured, not white, noise); real IMU noise density; NACA 0012/0015 data; thrust law; AIAA template.
2026-10-31 · Milestone 9k: does starting the output-error fit by continuation from a 1-period fit fix 9j's 4-period failures at 10% noise? (planned before running)
- Why: 9j's "Next". At 10% noise and 4 phugoid periods the output-error fit failed or landed in the wrong basin in 170 of 1560 draws (62% of draws within 10% gust, 5 of 78 designs at 90%), and its start was the least-squares transition matrix, which is badly biased at that noise.
- Plan (
experiments/output_error_start/run.py): 9j's script with records of 4 periods only, noise 0.10, tail-slope scale 0.75, 78 designs, 20 paired draws, seed 20261101. Both fits see the same noisy record: (a) output error started from the LS matrix (the 9j start, rerun on new draws); (b) continuation: fit the first phugoid period alone, then refit the full record from that solution. - Predictions (before running): (1) continuation has fewer fit failures than the LS start (prior 85%) and under 60 of 1560 (prior 65%). (2) At least 40 of 78 designs reach 90% of draws within 10% gust under continuation (prior 55%). (3) Median short-period frequency error stays under 3% for both starts (prior 80%). Refuted: (1) failures not lower, or 60 or more; (2) fewer than 40; (3) either at or above 3%.
- Limits known in advance: those of 9j (known initial state, white noise on all four states, 20 draws, one scale); one seed.
### Outcome of 9k (experiments/output_error_start/: run.py, results.txt; about 3 h of CPU)
- 4 phugoid periods, 10% noise, 1560 draws. Fit failures: 144 (LS start) against 9 (continuation). Median |error| in phugoid, short-period frequency and damping ratio: 0.03, 1.34, 2.59% (LS start) against 0.03, 1.14, 2.34% (continuation). Share of draws within 10% gust: 63% against 77%. Designs with 90% of draws within 10% gust: 8 against 36 of 78. Median worst gust error 7.7% against 6.2%; median worst mode error 4.3% against 3.7%.
- (1) held (9 failures, under 60). (2) refuted: 36 of 78 designs, not 40. (3) held (1.34 and 1.14%).
- Reading: most of 9j's 4-period failures came from the starting point, not from the information in the record: fitting one period first and extending removes 94% of them and lifts the gust share from 63 to 77%. It does not reach the 85-87% of the 1 to 2 period records, so at 10% noise a long record still is not better than a short one; the extra samples are mostly decayed and add noise-dominated residual. Test card advice stays: one to two phugoid periods.
- Limits: as 9j; the 144 LS-start failures (9 vs 170 in 9j: different draws) were counted, not diagnosed further; continuation uses the known initial state in both stages.
- Next: estimated initial state; turbulence; real IMU noise density; NACA 0012/0015 data; thrust law; AIAA template.
2026-10-31 · Milestone 2c: how much of the Matrice 100's fixed flight energy is set by cruise altitude (25 vs 50 m), and what does that do to range? (predictions fixed before the run)
- Why: 2b's "Next". Its E0 (64 kJ at 8 m/s) is nearly all climb and hover, and the study flew two altitudes that 2b pooled.
- Plan (
experiments/altitude_energy/run.py): refit whole-flight energy = E0 + a50 x [altitude 50 m] + j x cruise distance by least squares per commanded speed (4, 6, 8, 10 m/s), with bootstrap intervals (flights resampled, 5000 draws); one-way range with one TB48D pack at 80% usable for each altitude, as in 2b. - Predictions (before running): (1) the 50 m altitude adds 15 to 60% to E0 at 8 m/s (prior 60%); (2) the per-metre slope j differs between altitudes by under 15% (prior 65%; tested by an interaction term); (3) one-way range with one pack at 8 m/s is at least 20% longer at 25 m than at 50 m (prior 55%). Refuted: (1) outside 15 to 60%; (2) 15% or more; (3) under 20%.
- Limits known in advance: altitude is confounded with route and order only as far as the study design allowed (not checked beyond the design table); 8 m/s has 34 flights split in two; extrapolation from short legs as in 2b.
### Outcome of 2c (experiments/altitude_energy/: run.py, results.txt)
- The plan's premise was wrong. The study flew four altitudes (25, 50, 75, 100 m) and four payload codes (0 to 750), not two altitudes;
parameters.csv also stores altitude as text, which made my first fit (a 50 m dummy) silently zero. Predictions (1) to (3) were therefore ill-posed; the first run was discarded and the analysis redone as a pooled fit (speeds 4 to 10 m/s with a fixed effect each, altitude and payload as linear terms, cruise distance), labelled post hoc. - Result (132 flights, R2 0.93, residual sd 4.9 kJ): each extra 25 m of altitude costs 9.6 kJ [8.9, 10.3] per flight (about 384 J per metre climbed, against 38 J/m of potential energy for 3.9 kg, so climb and descent time at hover-like power dominate), each payload step of 250 costs 8.0 kJ [7.0, 8.9]. E0 at 25 m with no payload falls with speed (56, 49, 46, 42 kJ at 4, 6, 8, 10 m/s). The 2b E0 (64 kJ at 8 m/s) was an average over all four altitudes and payloads.
- Predictions as written, at 8 m/s: (1) 50 m adds 21% to E0 (inside 15 to 60%, but by accident of a wrong premise); (2) untested; (3) failed, 25 m range is only 1.07 times the 50 m range, because the cruise slope, not E0, dominates range.
- Range, one pack, 80% usable, no payload: 2.7 km at 25 m falling to 2.2 km at 100 m (8 m/s). The bootstrap interval is huge (1.4 to over 40 km): the cruise slope is not identified (51.7 J/m, interval -13 to 103) because cruise windows are under 150 m. The lower end, about 1.1 to 1.4 km, agrees with 2b; the point estimates should not be quoted as range. A usable range needs flights with cruise legs of kilometres, which this dataset does not have.
- Limits: altitude may be confounded with route and time of day (not checked); payload codes taken from the table without confirming units; one airframe.
- Next: separate climb, hover and descent power from the 5 Hz series to get a physical E0 (m g h / efficiency); a lift-plus-cruise sizing model for the cargo class (milestone 2 proper), where cruise slope comes from the Froude table, not from these short legs.
2026-10-31 · Milestone 2b: how much of a measured Matrice 100 flight is not cruise, and what one-way range does a battery buy? (predictions fixed before the run)
- Why: 2a's "Next". Its cruise-only J/m flatters the drone and says nothing about battery range, the binding limit.
- Plan (
experiments/mission_energy/run.py): integrate V x I over each of the 134 route flights; split energy into the cruise window (as 2a) and the rest; regress whole-flight energy on cruise distance per speed (intercept = fixed energy, slope = J/m); range from one TB48D pack (129.96 Wh, retailer listing, not a DJI page) at 80% usable. - Predictions (before running): (1) non-cruise energy is 10 to 30% of a flight; (2) whole-flight J/m at 8 m/s is at least 20% above cruise-only; (3) one pack gives under 10 km one way, loaded round trip at 8 m/s.
### Outcome of 2b (experiments/mission_energy/results.txt)
- (1) failed: non-cruise share is 77.4% [73.8, 80.8] (49% at 4 m/s, 95% at 8 m/s, 97% at 10 m/s). The legs are short (mean path 467 m, 199 s; cruise window 30 to 149 m at 8 m/s), so these flights are mostly climb, hover and acceleration. Mean non-cruise power 381 W.
- (2) held, by far: 153.8 against 60.1 J/m at 8 m/s (2.56x).
- (3) held, trivially: one-way range with one pack at 80% usable is 0.94 to 1.08 km from the regression (E0 64 kJ, slope 113 J/m at 8 m/s) and 2.0 to 2.9 km if the cruise-only slope (60, 44 J/m) is combined with the same fixed energy. Two packs: 2.3 to 2.7 km (regression).
- Reading: the 2a break-even distances (63 to 83 km) are an energy-per-metre result for a drone with unlimited battery; for this airframe the pack allows about 1 to 3 km one way, so the Matrice 100 cannot make the comparison the 2a numbers suggest. The binding constraint is battery energy, as 2a guessed.
- Limits: the regression slope absorbs acceleration and braking and extrapolates from cruise distances under 150 m to kilometres (uncertain by about a factor of 2, hence the bracket); E0 is nearly all the data's fixed climb and hover, set by the experiment's altitude (25 or 50 m, not separated here); pack capacity from a retailer and the number of packs the study flew is not checked; 80% usable is an assumption; one 3.7 kg airframe, not a 500 kg cargo aircraft.
- Next: separate altitude (25 vs 50 m) in E0; a lift-plus-cruise and fixed-wing sizing model with the Froude table for the cargo-class question in milestone 2 proper; check the pack count in Rodrigues et al.
2026-10-31 · Milestone 2a: energy per package from measured flights against a diesel truck (predictions fixed before the run)
- Why: milestone 2 of track 22 asks where in payload and distance each mode wins. Rodrigues et al.'s measured flights (already used in 6a) give J/m; Stolaroff et al. (2018, Nat. Commun. 9:409, read on nature.com) give a sourced truck figure (7.8 MJ/package) and a modelled quadcopter (32 J/m).
- Predictions: (1) pooled cruise energy 50 to 80 J/m; (2) energy break-even one-way distance above 20 km at the base stop density; (3) per payload-kg-km comparison with a truck, dropped before the run (no truck payload mass in the source).
- Outcome (
experiments/energy_per_package/results.txt): (1) failed: pooled 86.4 J/m [81.2, 91.5], inflated by 41 flights at 4 m/s (127 J/m); at 8 and 10 m/s it is 63 and 48. (2) held: break-even 63 km (8 m/s) and 83 km (10 m/s) at base density; 21 km at 10 m/s with four times the density. - Limits: cruise only; no climb, hover or landing energy; the truck figure is a US national-average style estimate for one vehicle class; 12 m/s has two flights; one airframe (3.7 kg), so payload fractions of 7 to 14% say nothing about a 500 kg cargo VTOL. Battery range not modelled (the binding constraint).
- Next: add takeoff and hover energy (route H flights) and the M100 battery capacity from a datasheet to get feasible range; then a lift-plus-cruise and fixed-wing model for milestone 2 proper.
2026-10-31 · Milestone 9j: does the output-error fit survive 10% sensor noise, where 9h's least squares was unusable? (planned before running)
- Why: 9i's "Next". 9h found equation-error least squares unusable at 10% noise (5177 of 7800 fits failed at 4 periods); 9i only tested 3%.
- Plan (
experiments/output_error_10pct/run.py): 9i's script unchanged except noise 0.10 and seed 20261031; 78 designs, tail-slope scale 0.75, records of 1, 2, 4 phugoid periods, 20 paired draws, LS and OE on the same noisy record. - Predictions (before running): (1) OE short-period frequency error at 10% noise is under 3% at every record length (prior 70%). (2) OE has no more fit failures than LS and fewer at 4 periods (prior 85%). (3) At 4 periods at least 40 of 78 designs reach 90% of draws within 10% gust under OE (prior 50%). Refuted: (1) any record length at or above 3%; (2) OE failing more than LS; (3) fewer than 40.
- Limits known in advance: those of 9i (known initial state, white noise on all four states, 20 draws, one scale); one seed.
### Outcome of 9j (experiments/output_error_10pct/: run.py, results.txt; about 1 h of CPU)
- Median short-period frequency error, LS then OE: 19.1% then 0.74% (1 period), 52.7% then 0.71% (2), 164% then 1.25% (4). Damping ratio: 15.4, 34.9, 72.2% (LS) against 1.39, 1.48, 2.57% (OE). Designs with 90% of draws within 10% gust: LS 0, 0, 0 of 78; OE 58, 57, 5 of 78. Share of draws within 10%: LS 63, 36, 0%; OE 85, 85, 62%. Fit failures: LS 0, 0, 1059 of 1560; OE 0, 5, 170 of 1560.
- (1) held (OE under 1.3% at every length). (2) refuted: OE had 5 failures at 2 periods where LS had none (at 4 periods OE 170 against LS 1059). (3) refuted: 5 of 78 designs, not 40; at 4 periods the output-error fit also degrades (62% of draws within 10%).
- Reading: at 10% noise the output-error fit still recovers the modes to about 1% at 1 to 2 phugoid periods and keeps the 85% gust share seen at 3%, where least squares fails every design. A 4-period record at 10% noise is the one case it does not survive: the long record has more decayed-out samples and the optimiser fails or lands in the wrong basin 11% of the time. So the 9i relaxation (any record of at least one phugoid period) holds to 10% noise only for records of 1 to 2 periods.
- Limits: as 9i (known initial state flatters OE; white noise on all four states; 20 draws; one scale; one seed 20261031). The 4-period failures were not diagnosed (starting point from the LS transition matrix is poor at 10% noise).
- Next: start OE from a damped guess rather than the LS matrix; estimated initial state; turbulence; real IMU noise density; AIAA template.
2026-10-30 · Milestone 9i: does an output-error fit beat 9h's equation-error least squares on the same noisy free response? (planned before running)
- Why: 9h's "Next". Its least-squares floor got worse with longer records because noise in the regressors biases the transition matrix.
- Plan (
experiments/output_error_fit/run.py): 9h's 78 designs, true tail-slope scale 0.75, 3% channel noise, records of 1, 2, 4 phugoid periods, 20 paired draws per design. Both estimators see the same noisy record: LS as in 9h, and an output-error fit (Levenberg-Marquardt on the 16 entries of the continuous A, simulated from the known initial state, started at the log of the LS transition matrix). f is picked and scored as in 9f and 9h. - Predictions (before running): (1) OE short-period frequency error at 3% noise is under half of LS at every record length (prior 85%). (2) OE does not get worse from 1 to 4 periods by more than a factor of 2 (prior 70%). (3) At 4 periods at least 50 of 78 designs reach 90% of draws within 10% gust under OE (prior 60%). Refuted: (1) a record length where OE is at least half of LS; (2) a worsening above 2; (3) fewer than 50.
- Limits known in advance: known initial state (a real doublet's is estimated); white noise on all four states; 20 draws, so shares have about 2-point resolution per cell; one scale; one seed (20261030).
### Outcome of 9i (experiments/output_error_fit/: run.py, results.txt; about 58 min of CPU)
- Median short-period frequency error, LS then OE: 1.87% then 0.21% (1 period), 6.06% then 0.21% (2), 33.5% then 0.33% (4). Damping ratio: 1.99, 4.46, 23.1% (LS) against 0.44, 0.44, 0.64% (OE). Designs with 90% of draws within 10% gust: LS 52, 51, 13 of 78; OE 67, 67, 66 of 78. Share of draws within 10%: LS 83, 84, 64%; OE 86, 87, 87%. OE matches or slightly beats the noiseless 9f value on gust (86 to 87%). No fit failures in either.
- (1) held (ratio 0.11, 0.03, 0.01). (2) held (0.21% to 0.33%, factor 1.6). (3) held (66 of 78).
- Reading: 9h's "longer record is worse" was an artefact of the equation-error estimator, not of the information in the record. With an output-error fit 3% sensor noise costs almost nothing and a longer record helps slightly. The demonstrator test card constraint from 9h (one short-period record at high rate) relaxes to any record of at least one phugoid period, provided the identification is output-error.
- Limits: as planned. The known initial state flatters OE, and the 10% noise case, where 9h's LS was unusable, was not rerun.
- Next: estimated initial state and turbulence; 10% noise; windowed fit; real IMU noise density; NACA 0012/0015 data; thrust law; AIAA template.
2026-10-29 · Milestone 9h: what mode errors does a real time-domain fit of a noisy free response give, and what do they do to the adjustable tail? (planned before running)
- Why: 9f and 9g assumed Gaussian mode errors; their "Next" asked for an estimator on a simulated record. Here the 4-state model (u, alpha, q, theta) at f = 1 is released from an initial disturbance, sampled with sensor noise, and its discrete transition matrix fitted by least squares (equation-error); the eigenvalues give the observed modes.
- Plan (
experiments/doublet_fit/run.py): the 78 mode-matched designs at true tail-slope scales 0.75 and 1.0; initial state u = 0.1 v, alpha = 0.05 rad; sampling 20 points per short-period period; record 1, 2 and 4 phugoid periods; white noise at 1%, 3% and 10% of each channel's rms; 100 draws. Relative error of the fitted phugoid frequency, short-period frequency and damping ratio at f = 1 is carried to every f on the grid (as 9f does with its assumed noise), f is picked as in 9f, and the true model is scored on modes and the three gust peaks. Failed fits (no two complex pairs) keep f = 1. - Predictions (before running): (1) at 1% noise and 4 phugoid periods the median short-period damping-ratio error is above the median short-period frequency error (prior 80%): damping is the hard one. (2) At 3% noise and 2 phugoid periods the share of draws with worst gust error within 10% is below the 9f noiseless value of 86% by at least 10 points (prior 65%). (3) Lengthening the record from 1 to 4 phugoid periods does not improve the short-period estimate by more than a factor of 2 (prior 60%), since the short period decays within the first period. Refuted: (1) frequency error not smaller; (2) share within 10 points of 86%; (3) improvement above a factor of 2.
- Limits known in advance: all four states observed with white noise (a real unit measures rates and accelerations with different noise, and there is turbulence); free response from an initial condition, not a flown elevator doublet; equation-error least squares is biased by noise in the regressors (that bias is part of the result); the error measured at f = 1 is carried to other f; one seed.
### Outcome of 9h (experiments/doublet_fit/: run.py, results.txt; about 25 min)
- A least-squares fit of the free response gives, at 1% channel noise and a record of 1 phugoid period, median errors of 0.13% (phugoid frequency), 0.33% (short-period frequency) and 0.54% (damping ratio) at scale 0.75, and 87% of draws within 10% on gust (noiseless 9f: 86 to 87%). At 3% noise the share is 83 to 85% for 1 to 2 periods and the short-period frequency error is 1.5 to 6%. At 10% noise the share falls to 61 to 63% (1 period) and the short-period error is 15 to 19%.
- Longer records are worse, not better. Short-period frequency error at 1% noise is 0.33%, 0.70%, 4.45% for 1, 2, 4 phugoid periods (scale 0.75); at 3% noise with 4 periods it is 34% and only 7 of 78 designs reach 90% of draws within 10% gust (scale 0.75). The short period has decayed after the first period, so extra samples add noise but no information on it, and the equation-error least squares is biased by noise in the regressors. At 10% noise and 4 periods 5177 of 7800 fits at scale 0.75 fail to give two complex pairs.
- (1) refuted: damping-ratio error is below the short-period frequency error at 1% noise and 4 periods (3.22 against 4.45% at 0.75; 1.98 against 1.94% at 1.0, a tie); it is above it at 1 and 2 periods. (2) refuted: at 3% noise and 2 periods the share is 83 to 84%, 2 to 3 points under noiseless, not 10. (3) held, trivially: the estimate does not improve from 1 to 4 periods, it worsens by more than a factor of 10.
- Reading: 9f's assumed 2 to 3% mode noise is reached by a plain least-squares fit when the sensor noise is about 1% of each channel's rms and the record is about one phugoid period; the demonstrator's test card should record the short period's first few cycles at high rate, not a long record. With 3% sensor noise a naive fit already loses 14 to 20 designs in the per-design reliability count, and with 10% it is unusable. A better estimator (windowed fit, output-error method) is the obvious next step; this one is the floor.
- Limits: as planned (white noise on all four states, free response from an initial condition, error at f = 1 carried to other f, equation-error bias included, one seed, 100 draws); no turbulence; the sensor noise levels are fractions of rms, not a unit's datasheet.
- Next: output-error (nonlinear least squares) fit and a windowed fit against this floor; a real IMU noise density; NACA 0012/0015 data; thrust law; AIAA template.
2026-10-29 · Milestone 9f: how much noise in the identified modes can the adjustable tail (9d, 9e) tolerate? (planned before running)
- Why: 9e's "Next". It set f from the exact short-period and phugoid; a real pitch doublet and phugoid trace give frequencies and damping with error. The 10% gust bar only holds in flight if it survives that.
- Plan (
experiments/noisy_identification/run.py): the 78 mode-matched designs; true tail-slope scales 0.75, 0.9, 1.0; the pilot observes phugoid frequency, short-period frequency and short-period damping ratio with independent multiplicative Gaussian error sigma = 0, 2, 5, 10%, and picks f on the 0.05 grid minimising the worst observed-mode error against the n = 1 reference; 200 draws per design and scale; the true model at the chosen f is scored on modes and the three gust peaks. - Predictions (before running): (1) at sigma 2% the share of draws with worst gust error within 10% stays at least 85% of its noiseless value (prior 70%). (2) At sigma 5% the share falls below half of the noiseless value (prior 55%), because the damping ratio is the quantity most sensitive to f and the hardest to measure. (3) At sigma 10% fewer than 20 of 78 designs have 90% of draws within 10% gust (prior 80%). Refuted: (1) below 85%; (2) at least half; (3) 20 or more.
- Limits known in advance: errors are independent per mode (real doublet errors in frequency and damping are correlated); the noise is applied to the mode summary, not to a time-domain fit; as 9d and 9e otherwise.
### Outcome of 9f (experiments/noisy_identification/: run.py, results.txt; about 20 min)
- Share of (design, draw) pairs with worst gust error within 10%, noiseless 86 to 87% (67 to 68 of 78 designs as in 9e): 84 to 86% at sigma 2%, 58 to 61% at 5%, 33 to 35% at 10% (scales 0.75, 0.9, 1.0). Median worst gust error 4.6 to 4.7% noiseless, 5.6% at 2%, 8.6 to 8.8% at 5%, 14.3 to 14.7% at 10%. Median worst mode error 2.3 to 2.4%, 3.2 to 3.3%, 4.9 to 5.1%, 8.1 to 8.2%. The median chosen f is 0.05 off the noiseless f at 2%, 0.05 to 0.10 at 5%, 0.15 to 0.20 at 10%.
- (1) held: at 2% the share is 84 to 86% against 86 to 87%, i.e. 97 to 100% of noiseless. (2) refuted: at 5% the share is 58 to 61%, about 68% of noiseless, not under half. (3) held, trivially: 0 of 78 designs have 90% of draws within 10% at 5% or 10% noise (54 to 61 of 78 at 2%), so on a strict per-design reliability bar the tolerance is between 2% and 5%.
- Reading: the adjustable tail of 9d and 9e needs the in-flight mode estimate good to about 2 to 3% (frequencies and damping ratio each) to keep the 10% gust bar for most designs; at 5% roughly 6 draws in 10 still pass, but no design is reliable. Gust error rises about linearly with the mode noise (4.7, 5.6, 8.7, 14.5% at 0, 2, 5, 10%), roughly 1.4 times the observed-mode noise at the upper end. Damping ratio is the quantity a short doublet measures worst, so the requirement is a demonstrator test-card requirement, not a given.
- Limits: independent errors per mode (real errors are correlated, and could be better or worse); noise on the mode summary, not a time-domain fit of a simulated doublet; 200 draws per cell, one seed (20261029); other limits as 9d and 9e.
- Next: a time-domain doublet with sensor noise and a fit of the 4-state model, to get actual mode errors for a given record length; NACA 0012/0015 data; thrust law; AIAA template.
2026-10-29 · Milestone 9g: the same question as 9f (PR #11443) when only the short-period frequency is identified (planned before running)
- Why: a parallel run landed 9f (all three modes observed) while this one ran; this is the narrower frequency-only variant, kept as a complement. 9d and 9e set the tail-area multiplier f from the model's own exact short-period error. In flight f would come from a pitch doublet whose frequency estimate has error.
- Plan (
experiments/identification_noise/run.py): the 78 mode-matched designs; at true tail-slope scale 0.75 and 1.0, f is the grid value (0.6 to 1.8, step 0.05) whose short-period frequency times (1 + noise) is closest to the n = 1 value; noise normal with relative sd 0, 1, 2, 5, 10%, 400 draws per design. Report worst gust error and mode error at the chosen f, and the number of designs with 90% of draws within 10% (gust) and 10% (modes). - Predictions (before running): (1) at sd 2% the median-over-designs median worst gust error is within 1.5 points of the sd 0 value (prior 70%). (2) At sd 5% at least 40 of 78 designs have 90% of draws within 10% gust at scale 0.75 (prior 50%). (3) At sd 10% fewer than 20 of 78 do (prior 65%). Refuted: (1) gap above 1.5; (2) fewer than 40; (3) 20 or more.
- Limits known in advance: only the short-period frequency is identified (not damping); noise is independent of f and Gaussian; no estimator model (a real doublet gives biased, correlated estimates); the reference is the same surrogate.
### Outcome of 9g (experiments/identification_noise/: run.py, results.txt; about 20 min)
- Choosing f from the short-period frequency alone, with no noise, 72 of 78 designs have every draw within 10% on gust (both slope scales) and all 78 are within 10% on every mode; the median worst gust error is 5.6%. With relative noise sd 1%, 2%, 5%, 10% the number of designs with at least 90% of draws within 10% gust falls to 63, 51, 0, 0 of 78 (scale 0.75; scale 1.0: 61, 53, 0, 0). The 90th-percentile worst gust error is 6.6%, 8.2%, 17.1%, 32.8% (scale 0.75). Modes are more tolerant: all 78 stay within 10% at sd 2%, 55 of 78 at sd 5%, none at 10%.
- (1) held on the median (5.6% at sd 0 and sd 2%, gap 0.0), though the 90th percentile already rises 2.6 points. (2) refuted: at sd 5% no design reaches 40 of 78 (it is 0). (3) held (0 of 78 at sd 10%, bar under 20).
- Reading: the adjustable tail of 9d and 9e is only as good as the frequency estimate. A gust match within 10% needs the short-period frequency identified to about 2% (1 sigma); a mode match within 10% needs about 5%. The grid step of 0.05 in f is itself coarse at this scale, which is why the 5% gust bar is lost at sd 2%.
- Limits: as planned (Gaussian noise independent of f, frequency only, grid f); sd 0 here (frequency rule, 72) differs from 9e's mode rule (67) because the rules differ.
- Next (as 9f): estimator model (a simulated doublet with turbulence and sensor noise, giving the actual frequency error); a finer f grid; NACA 0012/0015 data; thrust law; AIAA template.
2026-10-29 · Milestone 9e: does the tail-area multiplier that recovers the modes also recover the gust peaks? (planned before running)
- Why: 9d's "Next". 9c found the gust peaks more slope-sensitive than the modes (none of 78 within 10% at scale 0.75); 9d recovered the modes with an adjustable area f. The demonstrator specification only holds if the same f, set from the modes alone (what an in-flight pitch doublet identifies), also brings the gust peaks back.
- Plan (
experiments/adjustable_gust/run.py): the 78 mode-matched designs; for each true slope scale 0.75, 0.8, 0.9, 1.0 choose f in 0.6 to 1.8 (step 0.05) minimising the worst mode error, then compute the worst gust error over H = 5, 12.5, 25 chords against the unchanged n = 1 reference. Nothing is tuned on gust. - Predictions (before running): (1) at scale 0.75 at least 40 of 78 designs have worst gust error within 10% with f applied (prior 60%; against 0 of 78 without f). (2) At scale 0.75 the median worst gust error with f is above the median worst mode error with f (prior 80%): the area change fixes the area-slope product but not the tail lift distribution, arm-dependent damping or the pitch-rate peak. (3) Some design is within 10% on gust at all four scales (prior 65%). Refuted: (1) fewer than 40; (2) gust median not above mode median; (3) none.
- Limits known in advance: as 9d (area multiplier at fixed arm and aspect ratio, tail mass and inertia unchanged, slope as one factor, no actuator) and 9a (no penetration lag, no alpha-dot, rigid).
### Outcome of 9e (experiments/adjustable_gust/: run.py, results.txt; about 4 min)
- With f set by the mode criterion alone, 67 of the 78 designs keep every gust peak within 10% at every true slope scale 0.75, 0.8, 0.9 and 1.0, and 43 within 5% (9c, no f: 0 of 78 at either bar). At scale 0.75 the median worst gust error is 4.7% (90th percentile 10.2%) against 21.5% without f; the median worst mode error is 2.4%. The best designs (e.g. NACA 4412 wing, k 1.0, AR 12; NACA 0015 tail, area 0.20, AR_t 3.5, arm 3.0) are within 1.5% on gust at all four scales with f = 1.45, 1.35, 1.20, 1.10.
- (1) held (67 of 78 at scale 0.75, bar 40). (2) held (gust median 4.7% above mode median 2.4%). (3) held (67 designs within 10% at all four scales).
- Reading: the adjustable tail the demonstrator needs (9d) restores the gust response as well as the modes, to within a factor of about two of the mode error. The 11 designs still outside 10% are the ones whose gust sensitivity is carried by the wing (k above 1), which a tail change cannot reach. Together 9c and 9e say the gust match is not a property of a fixed tail but of a tail whose effective area is set in flight from the identified short-period.
- Limits: as planned; f is chosen on a 0.05 grid by the model's own mode error, i.e. assumes the short-period is identified exactly (noise in the identification is not modelled); the reference is the same surrogate.
- Next: noisy in-flight identification of f (how much doublet noise the 10% bar tolerates); NACA 0012/0015 data when the UIUC host answers; thrust law; AIAA template.
2026-10-29 · Milestone 9d: can an adjustable tail area recover the modes if the true tail slope is 0.75 to 1.0 of NeuralFoil's? (planned before running)
- Why: 9c's "Next". 8e and 9c show no fixed tail survives a 20 to 25% lower tail slope; the demonstrator then needs the tail to be adjustable. The mode model depends on the tail through the area-slope product (and a small drag term), so a multiplier f = 1/s on tail area should compensate to first order; the question is whether it does in the full model, over what f range, and for how many of the 78 mode-matched designs.
- Plan (
experiments/adjustable_tail/run.py): the 78 designs of tail_search (within 5% on all three modes at slope scale 1.0); for each true slope scale s in 0.75, 0.8, 0.9, 1.0, scan a tail-area multiplier f in 0.6 to 1.8 (step 0.05) and record the f band that brings the worst mode error within 5%. - Predictions (before running): (1) at least 70 of the 78 designs are recoverable at every scale with some f in the grid (prior 75%). (2) The median f_min at s = 0.75 lies between 1.2 and 1.4 (prior 70%); f = 1/s is not exactly right because tail drag, downwash and the l_t-dependent q-damping scale differently. (3) A range f in [1.0, 1.35] is enough for at least half of the designs at s = 0.75 (prior 65%). Refuted: (1) fewer than 70; (2) median outside 1.2 to 1.4; (3) fewer than half.
- Limits known in advance: area multiplier at constant arm and aspect ratio (tail mass and inertia are unchanged, though the tail mass was studied in
tail_mass); the surrogate scale is one factor; the wing slope is unscaled; no actuator.
### Outcome of 9d (experiments/adjustable_tail/: run.py, results.txt; about 2 min)
- Of the 78 mode-matched designs, an adjustable tail-area multiplier f recovers all three modes within 5% for 76 at every true slope scale 0.75, 0.8, 0.9 and 1.0 (individually 76, 78, 77 and 78 of 78 at 0.75, 0.8, 0.9, 1.0). Median f_min is 1.27, 1.20, 1.05, 0.95 at scales 0.75, 0.8, 0.9, 1.0, so the needed area tracks 1/s (1.33, 1.25, 1.11) to within about 0.06 and a little below it. At scale 0.75, 54 of 78 designs need f at most 1.33; the largest f_min is 1.35. The tightest-range design (NACA 5406 wing, k 1.0, AR 12; NACA 0009 tail, area 0.15, AR_t 5, arm 3.5) is within 5% for f in [1.10, 1.30] at 0.75 and [0.85, 1.00] at 1.0, so a tail that varies about 0.85 to 1.30 times its nominal area covers the whole slope range.
- (1) held (76 of 78, prediction at least 70). (2) held (median f_min 1.27 at 0.75). (3) held (54 of 78, over half).
- Reading: 8e and 9c show that no fixed tail survives a lower tail slope. This shows a flight-adjustable tail area does: the failure is a calibration problem, not a design-space dead end, provided the slope can be identified in flight (e.g. from the short-period frequency the pitch-doublet gives) and the tail resized or its effective lift area changed by 15% to 35%. The demonstrator specification should include an adjustable tail, which is the correction the paper was missing.
- Limits: area multiplier at fixed arm and aspect ratio; the 5% band is on mode errors only (the gust metrics of 9c were more sensitive and were not re-evaluated with f); tail mass and inertia unchanged; slope scaled as one factor; no actuator or elevator dynamics; a 0.05 grid on f.
- Next: gust metrics with f applied (does the same f recover 9c's gust peaks?); in-flight slope identification from the short-period; NACA 0012/0015 data; thrust law; AIAA template.
2026-10-28 · Milestone 9c: do the gust peaks of the 24 gust-matched tails survive a tail slope 0.75 to 1.0 of NeuralFoil's? (planned before running)
- Why: 9b's "Next". 8e showed the mode match does not survive a lower tail slope (none of 78 robust); 9b's 24 designs that also match gust at all three H rest on the same unvalidated slope. The question is whether the gust metrics are more tolerant than the modes, which would make the gust match the more defensible part of the claim.
- Plan (
experiments/tail_gust_robust/run.py): the 78 mode-matched designs of 9b (reproduced), each re-evaluated with the tail slope times 0.75, 0.8, 0.9, 1.0 (as 8e); modes and the three gust peaks (H = 5, 12.5, 25 chords) as percent difference from the unchanged n = 1 reference. Count designs within 10% (and 5%) on all gust metrics at every scale, and compare the worst gust error with the worst mode error at scale 0.75. - Predictions (before running): (1) at least one of the 78 keeps all three gust peaks within 10% at all H and all four scales (prior 35%). (2) For most designs the worst gust error at scale 0.75 is smaller than the worst mode error at scale 0.75 (prior 65%), since the load-factor peak depends on the wing slope, not the tail. (3) None keeps all gust peaks within 5% at every scale (prior 85%). Refuted: (1) none; (2) half or fewer; (3) some design does.
- Limits known in advance: as 9b and 8e (slope scaled as one factor; wing slope unscaled; no penetration lag, no alpha-dot, rigid, no elevator).
### Outcome of 9c (experiments/tail_gust_robust/: run.py, results.txt; about 3 min)
- Of the 78 mode-matched designs, none keeps all gust peaks within 10% at every tail-slope scale 0.75, 0.8, 0.9, 1.0 (and none within 5%); none is within 10% at scale 0.75 alone. The most robust (NACA 4412 wing, k 1.0, AR 12; NACA 0015 tail, area 0.40, AR_t 7, arm 1.5) has worst gust error 14.0, 8.5, 9.3, 13.4% at the four scales. Median worst gust error over the 78: 21.5, 16.5, 8.2, 6.0% at scales 0.75, 0.8, 0.9, 1.0 (modes: 13.4, 10.9, 6.5, 3.7%).
- (1) refuted (0 of 78). (2) refuted: the gust error at scale 0.75 is below the mode error for 0 of 78 designs; the gust metrics are more sensitive to the tail slope than the modes, not less, because the pitch rate and attitude peaks follow the short-period damping and frequency directly. (3) held.
- Reading: 9b's 24 gust-matched designs are as fragile as 8e's mode-matched ones. The sentence "the tail that restores the modes restores the gust response" is a statement about the NeuralFoil slope; with the slope 20 to 25% lower (what 8c/8d suggest at the tail's Re) the worst gust error is typically above 15%. A demonstrator needs the tail slope measured or an adjustable tail (incidence/area) to recover the match in flight.
- Limits: as planned; the 1.0-scale errors here are the maximum over all three gust lengths, so they are larger than 9b's per-count statistics.
- Next: tail slope identification (wind tunnel or flight) as the milestone that gates the claim; NACA 0012/0015 data; thrust law; AIAA template.
2026-10-28 · Milestone 9b: do the tails that restore the modes also restore the gust response? (planned before running)
- Why: 9a's "Next". 9a tested only wings with the 7b tail; the tail redesign of
tail_search (78 designs within 5% on all three modes) is the part of H5 that survived, so the question is whether it survives the gust metrics too. The UIUC host is still refused (HTTP 000), so NACA 0012/0015 data stay open. - Plan (
experiments/tail_gust/run.py): the 17 power-matched wings and 270-tail grid of tail_search; keep the designs within 5% on all three modes; for each, the three gust peaks (dn, q, theta) at H = 5, 12.5, 25 chords as percent difference from n = 1 (same gust model as 9a, tail slope and drag as in tail_search). - Predictions (before running): (1) fewer than half of the 78 mode-matched designs have all three gust peaks within 10% at H = 12.5 (prior 70%). (2) The peak load-factor increment is the worst-matched metric for most of the 78 (prior 55%), since the modes are matched by tail changes but dn depends on the wing slope and k. (3) Some design is within 5% on all three modes and all three gust peaks at all three H (prior 25%). Refuted: (1) half or more are within 10%; (2) another metric is worst for most; (3) none is, or (prior-low) the best is looser than 10%.
- Limits known in advance: same as 9a (no penetration lag, no alpha-dot, rigid, no elevator); tail slope unvalidated (8c to 8e), so a pass is a statement about the surrogate.
### Outcome of 9b (experiments/tail_gust/: run.py, results.txt; about 3 min)
- Of the 78 mode-matched designs (the
tail_search count, reproduced), 72 have all three gust peaks within 10% of n = 1 at H = 12.5 chords, and 24 have all three within 5% at all three gust lengths. The best (NACA 5406 wing, k 1.0, AR 12; NACA 0012 tail, area 0.15, AR_t 3.5, arm 3.5) is within 1.2% on every gust metric at every H while its modes are within 1.1%. The tail that restores the modes restores the gust response with it, because the rotational response is what the tail controls. - (1) refuted (72 of 78 within 10%, prediction: fewer than half). (2) refuted (worst metric at H 12.5: peak q for 36 designs, peak dn for 35, theta for 7; neither is most). (3) held (24 designs; the prior was 25%).
- Reading: the mode-matched non-similar demonstrator also matches a scaled gust, contrary to 9a's result for the 7b tail where nothing came within 10%. Combined with 9a, the earlier "no design restores power, modes and gust response together" holds only for the fixed 7b tail; with the tail in the design space it is refuted. All of it rests on the unvalidated NeuralFoil tail slope (8c to 8e): a tail slope 20% lower would break the modes first (8e), so the gust match inherits that.
- Limits: as 9a (no penetration lag between wing and tail, no alpha-dot term, rigid, no elevator); the slope scale of 8e was not applied here; 78 designs on a grid, not an optimum.
- Next: apply the 8e slope scales to the gust metrics; NACA 0012/0015 data when the UIUC host answers; thrust law; AIAA template.
2026-10-28 · Milestone 9a: does the Froude model keep the gust response (H1 proper)? (planned before running)
- Why: the draft's "Next" and the last untested half of H1 ("response to a scaled gust"). The UIUC host (m-selig.ae.illinois.edu) is refused by the egress proxy in this session (HTTP 000,
connect_rejected), so 8e's NACA 0012/0015 data step cannot run; the gust response needs no external data. - Plan (
experiments/gust_response/run.py): the four-state model and power-matched grid of nonsimilar_modes; a 1-cos vertical gust with gradient H = 5, 12.5, 25 full-size chords (H scaled by n and w_g by sqrt(n) so alpha_g(t sqrt(g/L)) is identical at every scale); exact zero-order-hold simulation; metrics peak load-factor increment, peak q sqrt(L/g), peak pitch attitude, as percent difference from n = 1. - Predictions (before running): (1) the uncorrected similar n = 0.2 model differs from n = 1 by more than 5% in at least one metric at H = 12.5 (prior 80%; its short period is 15% high and its damping 10% low). (2) The best power-matched non-similar case is within 5% on all three metrics for none of the three gust lengths (prior 75%), since the 17 cases already miss the modes by 15% or more. (3) The peak pitch rate is the worst-matched metric (prior 60%). Refuted: (1) all three within 5%; (2) some case within 5% at some H; (3) another metric is worst.
- Limits known in advance: no gust penetration lag between wing and tail, no alpha-dot derivative, no elevator or autopilot, rigid body, one reference aircraft; the 4-state model's short-period error (16 to 25% from the free-model table) is inherited.
### Outcome of 9a (experiments/gust_response/: run.py, results.txt; about 2 min)
- The uncorrected similar n = 0.2 model matches the n = 1 peak load-factor increment within 2.0% at all three gust lengths (-0.3, -0.8, -2.0%) but its peak pitch rate is 26.8 to 32.6% high and its peak pitch attitude 19.8 to 21.6% high. So the load a gust puts on the wing transfers, the rotational response does not.
- Of the 17 power-matched non-similar cases, none is within 5% or even 10% on all three metrics at any gust length. The best have peak pitch rate 18.3 to 30.5% high and peak load factor 8.8 to 22.3% high (the power match inflates the wing area, k above 1, which raises the load-factor increment).
- (1) held (pitch rate 30.5% at H 12.5). (2) held (0 of 17 at all three H). (3) held (pitch rate is the worst metric for the similar model and for the three best cases at H 5 and 25; at H 12.5 for the k 1.30 4412 case it is also the worst, 24.7%).
- Reading: H1's gust half is refuted for the rotational response, consistent with the 16 to 25% short-period error, and the power-matching correction (H5) trades a drag match for a worse load-factor match. A design that restores power, modes and gust response together is not in this grid.
- Limits: as planned (no penetration lag, no alpha-dot, rigid, no elevator); the tail slope uncertainty of 8c to 8e applies here too, and the pitch-rate error is the part most sensitive to it.
- Next: NACA 0012/0015 data when the UIUC host answers; include the gust metrics in the correction search objective; thrust law; AIAA template.
2026-10-28 · Milestone 8e: does any tail restore the modes if the true tail slope is 0.75 to 1.0 of NeuralFoil's? (planned before running)
- Why: 8d's "Next". 8c and 8d put NeuralFoil's section slope at 1.2 to 1.7 times the UIUC measurement at Re 1e5 to 2e5, so the 1% mode match of the headline tail may not survive. A design that passes with the slope uncertain is the robust answer.
- Plan (
experiments/robust_tail/run.py): the 17 power-matched wings and the 270-tail grid of tail_search, each tail evaluated with its lift slope times 0.75, 0.8, 0.9 and 1.0; robust = worst mode error within 5% (or 3%) at all four scales. Same mode model; only the tail slope is scaled. The wing slope is not scaled (the 8d data were for sections like the tail's; the wing is not tested here). - Predictions (before running): (1) fewer than half of the 78 designs that pass within 5% at scale 1.0 pass at all four scales (prior 85%). (2) The headline tail (NACA 0015, area 0.15, AR 5, arm 3.5, k 1.0) is not robust within 3% (prior 90%) but some design in the grid is robust within 5% for the k = 1.0 wings (prior 60%). Refuted: (1) half or more stay; (2) the headline passes within 3%, or no k = 1.0 wing has a design robust within 5%.
- Limits known in advance: scaling the slope is a one-parameter stand-in for the surrogate error (it ignores the drag and the zero-lift shift); the measured ratio was for cambered sections; scale 0.75 is the low end of the 8d reading, not a measurement at the tail.
### Outcome of 8e (experiments/robust_tail/: run.py, results.txt; about 2 min)
- Of the 78 tail designs that pass within 5% at slope scale 1.0 (the count of
tail_search reproduced), none passes at all of 0.75, 0.8, 0.9 and 1.0, and none passes within 3%. No wing of the 17 has a robust design. The best worst-case error over the four scales is 7.1% (k 1.0, NACA 5406 wing, NACA 0012 tail, area 0.30, AR_t 5, arm 2.0) and 7.2% (k 1.0, NACA 4412 wing). - (1) held (0 of 78 stay, against a bar of fewer than half). (2) the first half held and the second half is refuted: the headline tail is not robust within 3%, and no k = 1.0 wing has a design robust within 5% (prediction said some would).
- Reading: a tail redesign recovers the modes only if the tail slope is known to about 8% (8c's table: -5.2% short-period error at x 0.9). The 8c/8d data say NeuralFoil's slope may be 20 to 35% high, so the tail-redesign result stands as a statement about the surrogate, and the paper cannot claim a demonstrator that matches the modes until the real tail slope is measured (the tail needs a wind-tunnel or flight identification step, or a section with published data at Re 1.5e5). Mode error at x 0.75 is 7 to 13% for the best k = 1.0 tails, so the shortfall is a robustness limit, not a total failure.
- Limits: slope scaled as a single factor; the design is chosen on the NeuralFoil slope and judged on the scaled one, so a design centred on a mid-range slope was not searched for separately (its worst case is bounded below by the 7.1% above, since the table already minimises the worst case over the four scales); the cambered 8d sections stand in for the tail's NACA 0015; 4,353 rather than 4,474 designs because tails whose modes are not complex at some scale are skipped.
- Next: NACA 0012/0015 data (Vols. 4 and 5 formats, Sheldahl and Klimas); demonstrator tail-incidence/area adjustability as a design response; gust response and thrust law.
2026-10-28 · Milestone 8d: does NeuralFoil's lift slope for the 14 to 15% thick UIUC sections match measurement at Re 1e5 to 2e5, the range of the tail? (planned before running)
- Why: 8c's "Next". Vol. 1 holds only NACA 0009 up to Re 1e5, below the tail's 1.5e5 and thinner than the headline NACA 0015. Vol. 2 (
LIFT02.TXT) holds NACA 2414 and 2415 (D. Imes) at Re about 6e4, 1e5, 2e5 and 3e5, which bracket the tail. Both are cambered, so the slope is fitted in a window centred on the measured zero-lift angle (same window for NeuralFoil). NACA 0012/0015 were searched for in Vols. 1 to 3 and are not there; Vols. 4 and 5 are not in the LIFT file format (not parsed here). - Plan (
experiments/uiuc_naca241x/run.py): same NeuralFoil call as 8c, windows of +-2, 3, 4 deg about the zero-lift angle. - Predictions (before running): (1) NeuralFoil / UIUC slope is within 10% at Re 2e5 for both sections in the +-3 deg window (prior 55%). (2) The spread of the ratio over the three windows at Re 1e5 is larger than at 2e5 (prior 70%). (3) At Re 1e5 NeuralFoil overestimates the slope as it did for the 0009 (ratio above 1.05; prior 50%). Refuted: (1) either section outside 10%; (2) spread no larger at 1e5; (3) ratio at or below 1.05.
- Limits known in advance: cambered, not the symmetric NACA 0015 of the design; one tunnel; the Re 1.5e5 tail is bracketed, not measured.
### Outcome of 8d (experiments/uiuc_naca241x/: run.py, results.txt; about 1 min; data fetched at run time, not committed)
- NeuralFoil / UIUC section slope, windows +-2 / 3 / 4 deg about the zero-lift angle. NACA 2415: 1.67 / 1.62 / 1.42 at Re 1.0e5 and 1.22 / 1.29 / 1.35 at 2.0e5. NACA 2414: 1.40 / 1.23 / 1.22 at 1.0e5 and 1.23 / 1.32 / 1.29 at 2.0e5. At 3e5 the ratio falls to 1.12 to 1.24. Over the four runs bracketing the tail (Re about 1e5 and 2e5, all windows) the ratio is 1.22 to 1.67, mean 1.36.
- (1) refuted: at Re 2e5 both sections are 22% to 35% above measurement in every window (2415 in the +-3 deg window: 1.29). (2) held: the ratio's spread over windows is 0.25 (2415) and 0.19 (2414) at 1e5 against 0.13 and 0.09 at 2e5. (3) held: NeuralFoil is above the measured slope at 1e5 (1.2 to 1.7), as it was for the 0009 at 1e5 (1.18, 8c).
- Reading: for the cambered 14 to 15% sections the surrogate's slope is too high at Re 1e5 to 2e5, with 22% to 67% excess. NeuralFoil returns slopes above the thin-airfoil 2 pi (up to 11.9 per rad at Re 6e4), which a real section does not show in these data. If the NACA 0015 tail behaves alike, its true slope at Re 1.5e5 is about 0.75 to 0.8 of NeuralFoil's, which 8c's sensitivity table puts at a short-period error of roughly -10% or worse (the table stops at x 0.8; not extended here). So the headline "within 1% to 3%" mode match is not supported at the surrogate's accuracy; the finding that a tail redesign recovers the modes depends on the tail model, and the paper's claim stays about the surrogate. Zero-lift angles agree within 0.5 deg at Re >= 6e4 (2415: -0.9 to -2.2 measured against -0.7 to -2.3).
- Limits: cambered sections, not the symmetric NACA 0015; 2D tunnel data (Imes, one model each); the tail's 1.5e5 is bracketed not measured; the NACA 0012/0015 are not in Vols. 1 to 3 (Vols. 4 and 5 are in other formats, not parsed).
- Next: re-run the tail search with the slope scaled by 0.75 to 0.8 to see whether a passing tail still exists (a tail that passes with the slope uncertain by 25% is the robust answer); Vols. 4 and 5 file formats; Sheldahl and Klimas 0012 data.
2026-10-28 · Milestone 8c: does NeuralFoil's NACA 0009 lift slope match measured UIUC data at Re 4e4 to 1e5? (planned before running)
- Why: the paper's first "Before submission" item and its main stated limit. The UIUC host (m-selig.ae.illinois.edu) answers now (HTTP 200); Volume 1 of the Low-Speed Airfoil Tests (Selig et al., 1995) holds a measured NACA 0009 (M. Nankivil, smooth) at Re 40,600 / 60,900 / 79,900 / 100,700 in
LIFT01.TXT. NACA 0009 is the thinnest of the three tail sections in tail_search; 0012 and 0015 are not in Volume 1 (not checked here, and the check is stated as such). - Plan (
experiments/uiuc_tail_slope/run.py): fetch LIFT01.TXT, fit the section lift slope a0 by least squares over alpha in [-3, 3] deg at each Re, and take NeuralFoil xxxlarge (n_crit 9, same call as nonsimilar_modes) at the same Re and alphas; compare a0 and the zero-lift alpha. Then propagate the ratio measured/NeuralFoil a0 into the 4-state short-period frequency of the headline non-similar design (short period scales roughly with sqrt of the tail slope) to say whether the 1% mode match survives. - Predictions (before running): (1) NeuralFoil a0 is within 10% of measured at all four Re (prior 60%; low-Re wind-tunnel slopes on thin sections are often below 2 pi and XFOIL-class codes are known to be off in the laminar-separation regime). (2) The error is largest at the lowest Re (40.6k) (prior 75%). (3) The measured slope is below NeuralFoil's at Re near 1e5 (prior 55%). Refuted: (1) any Re outside 10%; (2) the largest error at another Re; (3) measured above.
- Limits known in advance: one section of three; 2D tunnel data with its own blockage and wall corrections (the data reduction is Selig's); the tail runs at CL near 0.05, a region where laminar bubbles on a symmetric section can change the slope; the 3D tail is the 2D slope with the lifting-line correction, as in the model.
### Outcome of 8c (experiments/uiuc_tail_slope/: run.py, results.txt; 3 s; data fetched at run time from the UIUC host and not committed, since they are GPL-licensed)
- Section slope a0 over |alpha| <= 3 deg, per rad: UIUC 4.36 / 5.07 / 5.57 / 6.12 against NeuralFoil 3.14 / 5.01 / 6.40 / 7.20 at Re 40.6k / 60.9k / 79.9k / 100.7k (thin-airfoil 2 pi = 6.28). NeuralFoil / UIUC = 0.72 / 0.99 / 1.15 / 1.18. The measured zero-lift angle is -0.15 to -0.47 deg for a symmetric section (tunnel and model asymmetry); NeuralFoil gives 0.
- (1) refuted: three of four Re are outside 10% (28%, 15%, 18%). (2) held: the largest error is at 40.6k (28% low). (3) held: at Re near 1e5 measured is below NeuralFoil (ratio 1.18).
- The ratio is not stable under the fit window: over |alpha| <= 2 / 3 / 4 deg it runs 0.82 / 0.72 / 0.98 at 40.6k, 0.76 / 0.99 / 1.12 at 60.9k, 0.87 / 1.15 / 1.18 at 79.9k, 0.99 / 1.18 / 1.17 at 100.7k. The lift curve near zero is not a line at these Re (laminar-bubble kinks), so "the tail slope" has an uncertainty of order 15 to 30% from the data alone, wider than the 2% the 1% mode match can tolerate.
- Propagated into the headline design (k 1.0, AR 12, tail area 0.15, AR_t 5, arm 3.5, NACA 0015, tail Re 150,045): short-period error is -10.5, -5.2, -0.3, +4.5, +9.1% at tail slope x 0.8, 0.9, 1.0, 1.1, 1.2. So the "within 1%" match holds only if the tail slope is within about 2% of NeuralFoil's. The paper's claim is therefore about the surrogate, as the draft already says; this check shows the surrogate's slope is not confirmed to that accuracy, and it does not tell the sign of the real error at Re 1.5e5.
- Limits: only NACA 0009 (0012 and 0015, the sections the best tails use, are not in Vol. 1); the tail Re 1.5e5 is above the highest measured Re (1.0e5), so this is an extrapolation of the comparison; one tunnel and one model; 23 points per Re in the window.
- Next: find measured NACA 0012/0015 data at Re 1e5 to 2e5 (Vol. 2 to 5 of the same series, Sheldahl and Klimas SAND80-2114 for 0012); a design whose short period depends less on the tail slope (a larger tail, shorter arm) as a robustness criterion; gust response and thrust law; AIAA template.
2026-10-28 · Milestone 8b: figures for the paper (no new simulation)
- Why: 8a's pre-submission list.
paper/make_figures.py redraws three figures from the committed results.txt files only (power ratio against n; worst mode error against wing area factor; tails passing against CG offset), embedded in paper/draft.md. - Checked by eye: fig 2 shows worst-case error under 5% only for k = 0.9 to 1.1 (3.1% to 3.7% away from k = 1.0) and under 3% only at k = 1.0. Fig 3 is the re-searched count of 7f, not the fixed-tail tolerance of 7g, and is captioned so.
- Still open: UIUC tail-slope check (host unreachable), gust response and thrust law, AIAA template.
2026-10-28 · Milestone 8a: first draft of the paper (no new simulation)
- Why: milestone 7 is complete; milestone 8 is the paper. The UIUC host was probed again (no HTTP response), so the tail-slope check stays open and is the first item under "Before submission".
- Done:
paper/draft.md (abstract, hypotheses table, results 4.1 to 4.8, limitations, pre-submission list) and paper/check_numbers.py, which asserts that each headline number in the draft appears in the results file or LOG outcome it came from (all pass). - Headline as written: H5 is refuted for sections and for the wing alone but not once the tail is redesigned, and the resulting non-similar demonstrator needs its CG within about 3% of a chord. The draft states that this rests on one unvalidated polar surrogate.
- Next: UIUC polar check when reachable; gust response; AIAA template, figures and bibliography check.
2026-10-28 · Milestone 7h: what does the sub-scale demonstrator look like in millimetres, and how tight is its CG? (arithmetic on 7d to 7g, no new simulation)
- Why: 7g's "Next" and the last item of milestone 7. The demonstrator specification for
aerolog-sitl needs dimensions a builder can cut, not chord fractions. - Plan (
experiments/demonstrator_spec/run.py, stdlib only): apply the formulas of tail_search and fixed_tail to the n = 0.2 model of the 1,000 kg, AR 10 reference for the two k = 1.0, AR 12 wings with 7g's best fixed tail (NACA 0015, area 0.15, AR_t 5, arm 3.5). - UIUC airfoil host (m-selig.ae.illinois.edu) still unreachable through the proxy (probed this session, no HTTP response), so the NeuralFoil tail-slope check stays open.
### Outcome (experiments/demonstrator_spec/results.txt)
- Model: 8.00 kg, wing span 2,078 mm, chord 173.2 mm, area 0.360 m^2, CL 0.80, trim speed 21.1 m/s (full size 47.2 m/s), Re 2.5e5 (wing) and 1.5e5 (tail). Tail: span 520 mm, chord 103.9 mm, area 0.054 m^2, arm 664 mm from the wing AC.
- CG must be placed within +/-6.1 mm (NACA 4412 wing) or +/-5.2 mm (5406) of the design position to keep all three longitudinal modes within 5% of the full-size aircraft, from 7g's +/-0.035 and +/-0.030 chords. That is the binding build tolerance of the design, and it is tight for an 8 kg model.
- Limits: inherits 7d to 7g (four-state model, point-mass inertia, reference CG at the wing AC by choice, unchecked tail slope); no mass or inertia tolerance is derived.
- Next: UIUC polar check when the host is reachable; mass and inertia tolerance of a built model; milestone 8 paper draft.
2026-10-27 · Milestone 7g: does a tail fixed at its 7d (h = 0) design keep the modes within 5% when the built CG is off? (hypothesis written before the run)
- Why: 7f's "Next". 7f re-chose the tail at every CG offset h, so it showed a compensating tail exists, not what a builder with a fixed tail and an imprecise CG faces.
- Plan (
experiments/fixed_tail/run.py, 7f's model by path): for the k = 1.0, AR 12 wings (NACA 4412, 5406), take every tail within 5% on all three modes at h = 0 (23 per wing in 7f), keep it fixed, and sweep h from -0.10 to +0.10 chords. Report per tail the contiguous h interval around 0 where it stays within 5%, and the best tail's interval. Hypothesis: the best fixed tail tolerates |h| of at most 0.02 chords (about 1 to 2% of mean chord) because short-period frequency scales with sqrt of static margin; refuted if the best fixed tail stays within 5% out to |h| = 0.05 on both sides. - Limits known in advance: same as 7f (point-mass inertia at Froude value, NeuralFoil tail slope unchecked, four-state model, reference CG at h = 0 by choice).
### Outcome (experiments/fixed_tail/results.txt, about 1 min)
- Each of the 23 tails per wing that pass at h = 0 stays within 5% on all three modes over an h interval about 0.065 chords wide (median; 0.030 to 0.075 across tails, 4412; 0.025 to 0.070, 5406), and the interval is not centred: it extends further on the unstable side for most tails (e.g. 4412 with NACA 0009, area 0.15, arm 3.5: h from -0.055 to +0.020).
- The best symmetric tolerance is +/-0.035 chords (NACA 0015, area 0.15, tail AR 5, arm 3.5, on the 4412 wing; +/-0.030 on the 5406). Only 8 and 9 of 23 tails tolerate |h| = 0.02 on both sides and none tolerate 0.05.
- Hypothesis judged: its point estimate (best tail tolerates at most 0.02) was wrong, since the best tolerates 0.03 to 0.035; its stated refutation (best within 5% out to 0.05 both sides) did not occur either. So it is partly refuted: the tolerance is about +/-0.03 chords, between the two numbers I wrote down.
- Reading: a builder must place the model CG within about +/-3% of a chord of the reference position (a few millimetres on the 0.2-scale model's chord, not computed here), and for the reference tail the 7f finding that a compensating tail always exists does not relax that.
- Limits: as 7f; the reference CG at h = 0 is a modelling choice, so the tolerance is relative to that choice; grid step 0.005 chords.
- Next: UIUC polar check of the tail slope (host was unreachable in earlier sessions; probe first); sub-scale demonstrator specification for
aerolog-sitl.
2026-10-27 · Milestone 7f: how far can the model's CG sit from the full-size CG before 7d's tail search stops finding a match? (hypothesis written before the run, no numeric predictions)
- Why: 7e's "Next". 7d and 7e held the CG at the wing aerodynamic centre in both aircraft, so static margin was never varied.
- Plan (
experiments/cg_margin/run.py, 7d's tail grid and mode model by path): model CG h wing chords ahead of the wing AC (wing Cm_alpha = -a_w h; tail arm from the CG grows by h chords), n = 1 reference at h = 0, the two k = 1.0, AR 12 wings (NACA 4412, 5406), h from -0.10 to +0.10, tail re-searched at each h. Hypothesis: a match persists for |h| up to about 0.05 and is lost by 0.10; refuted if passing tails vanish at |h| <= 0.05.
### Outcome (experiments/cg_margin/results.txt, about 1 min)
- h = 0 reproduces 7d (23 passing tails for both wings; best tail NACA 0015, area 0.15, AR_t 5, arm 3.5).
- Held: passing tails stay between 18 and 28 for h from -0.05 to +0.05 (NACA 4412 and 5406), and fall to 13 and 7 to 15 at |h| = 0.10 but do not vanish; the best worst-deviation stays under 3.6% everywhere. The best tail moves with h (arm 2.0 to 3.5 chords), so the sweep shows a compensating tail exists, not that the 7d tail tolerates a CG error.
- Limits: the tail is re-chosen per h, so a fixed tail built for h = 0 was not tested (that is the tolerance a builder faces if the CG is placed after the tail); point-mass inertia held at the Froude value as in 7d; reference at h = 0 is a modelling choice, not a sourced CG; NeuralFoil tail slope at Re near 1e5 still unchecked.
- Next: fixed-tail CG tolerance; UIUC polar check; sub-scale demonstrator specification for
aerolog-sitl.
2026-10-27 · Milestone 7e: do 7d's passing tails survive the pitch inertia a tail of that size and arm adds? (planned before running)
- Why: 7d's "Next". It held pitch inertia at the Froude value for every tail, but its best tails (area 0.15, arm 3.5 chords) are not the full-size tail (0.2, 3.0), and tail mass at its arm sets part of I_yy.
- Plan (
experiments/tail_mass/run.py, 7d's wings, tail grid and mode model imported unchanged): tail as a point mass m_t = mu m (area / 0.2 sim-wing area) at its arm; I_yy changes by m_t l_t^2 - mu m l_ref^2 (l_ref = the full-size 3.0-chord arm), CG held (nose ballast). mu for this airframe is not sourced, so it is swept over 0, 0.02, 0.04, 0.06 of total mass; mu = 0 must reproduce 7d (6 wings, 78 tails). - Predictions (before running): (1) at mu = 0.04 at least 4 of 17 wings still have a tail within 5% on all three (prior 60%): area x arm^2 is 0.15 x 3.5^2 = 1.84 against 0.2 x 3^2 = 1.80, so the inertia change of the 7d best tails is small. (2) The number of passing tails falls monotonically with mu from the 7d count of 78 (prior 85%: stiffer-than-modelled inertia shifts the short period away from the matched value), but the k = 1.0, AR 12 wings keep a passing tail at every mu (prior 65%, since the grid can re-select the arm). Refuted: (1) fewer than 4 wings; (2) the count is not monotone, or a k = 1.0 wing loses all tails.
- Limits known in advance: point-mass tail, mass proportional to area (no boom or structure scaling with arm); CG held, though a heavier longer tail moves it and so the static margin; mu swept, not sourced; same NeuralFoil slope caveat as 7d.
### Outcome (experiments/tail_mass/results.txt; 17 wings x 270 tails x 4 values of mu, about 12 min with /usr/bin/python3.13)
- Check: mu = 0 reproduces 7d exactly (6 of 17 wings, 78 of 4,474 tails within 5%).
- (1) held: at mu = 0.04, 6 of 17 wings still have a tail within 5% on all three modes (79 tails). The count of wings is 6 at every mu (0, 0.02, 0.04, 0.06).
- (2) refuted in its first half, held in its second: the number of passing tails is not monotone and does not fall: 78, 81, 79, 80 (the grid of stable designs also changes a little, 4,474 to 4,487). The k = 1.0, AR 12 wings (NACA 4412 and 5406) keep 23 to 26 passing tails at every mu, with the same best tail (NACA 0015, area 0.15, tail AR 5, arm 3.5) at worst deviation 0.8% and 0.5%, unchanged to the digit shown.
- Reading: for this tail geometry the 7d result is insensitive to tail mass, as the area x arm^2 comparison (1.84 against 1.80) suggested: the redesigned tail has almost the inertia of the full-size one, so the point-mass correction is small. This closes the inertia objection to H5 only for a point-mass tail with CG held; it says nothing about CG shift.
- Limits: point-mass tail with mass proportional to area; CG held at the Froude value by assumption (a longer, lighter tail moves the CG and the static margin, which sets the short period directly); mu swept, not sourced; NeuralFoil tail slope at Re near 1e5 still unchecked against UIUC data (host unreachable in this session); four-state model.
- Next: a CG and static-margin sweep for the k = 1, AR 12 design (the remaining untested assumption); UIUC polar check; then the sub-scale demonstrator specification for
aerolog-sitl.
2026-10-27 · Milestone 7d: can a tail redesign at n = 0.2 bring the power-matched wings' short period and damping within 5% of the n = 1 aircraft? (planned before running)
- Why: 7c found the short-period error (+13% to +25%) is set by the tail, whose Re at n = 0.2 is 1.7e5 against 1.9e6, so a wing correction cannot fix it. The tail is the lever not yet searched.
- Plan (
experiments/tail_search/run.py): the 17 power-matched wings of 7b/7c (same code path), each with the tail varied over section (NACA 0009, 0012, 0015), area 0.15 / 0.2 / 0.3 / 0.4 / 0.6 of the Froude-scaled similar wing area, tail aspect ratio 3.5 / 5 / 7 and arm 1.5 / 2 / 2.5 / 3 / 3.5 / 4.5 similar-wing chords (the full-size and 7c value is 3). Everything else as 7c (tail trimmed at CL 0.05, Froude inertia, same reference modes). A case passes when phugoid frequency, short-period frequency and short-period damping are all within 5% (and 3%) of the reference. The tail grid is searched per wing, so the count is of wings with at least one passing tail, and I also report how many tail designs pass. - Predictions (before running): (1) at least one wing has a tail that gets all three within 5% (prior 55%): a smaller or shorter-arm tail lowers pitch stiffness and the short period can be pulled down; damping is the harder constraint because it moves with CL and the tail's own Re. (2) None of the wings with CL more than 15% off 0.8 passes (prior 75%), since damping there is off by 35% to 50% and the tail does not change CL. Refuted: (1) no wing has a passing tail; (2) a low-CL wing passes.
- Limits known in advance: tail slope still from NeuralFoil at Re near 1e5 (not checked against UIUC data); a larger or longer tail changes weight and CG in reality, here inertia is held at the Froude value; four-state model without elevator.
### Outcome (experiments/tail_search/results.txt; 17 wings x 270 tails, 4,474 stable designs, about 3 min)
- (1) held: 6 of the 17 wings have a tail that puts phugoid frequency, short-period frequency and short-period damping all within 5% of the n = 1 reference, and 2 within 3% (78 of 4,474 tail designs within 5%, 22 within 3%). Best: NACA 5406 and 4412 at k = 1.0, AR 12 (the 7b wings that met the CL and slope proxies) with a NACA 0015 tail of 0.15 of the similar wing area, tail AR 5, arm 3.5 chords: worst deviation 0.5% (5406) and 0.8% (4412), with power ratios 0.967 and 1.031.
- (2) held: no wing with CL below 0.68 passes (k >= 1.2; best worst-case 6.5% to 41%); the passing wings have CL 0.73 to 0.89. Their power matches are those of 7b.
- So H5 is not refuted once the tail is redesigned: a wing at the full-size CL (k = 1, AR 12) with a smaller, longer-armed, thicker tail matches power to within 4% and all three modes to within 1%. This reverses 7c's "refuted in the wing-only space". The cost is a tail 25% smaller (0.15 against 0.2) on a 17% longer arm, i.e. a non-similar model whose tail is sized to the lower Reynolds number.
- Limits: still one NeuralFoil surrogate for wing and tail (UIUC polar check outstanding; the short-period shift is only as good as the tail slope at Re about 1e5); a 0.8% to 3% match is inside that error, so "within 5%" means the surrogate model, not the airframe; inertia and CG held at the Froude value although a different tail changes both; four-state model with no elevator or thrust dynamics; strip theory with fixed e = 0.8; a grid of 270 tails, not an optimiser; one reference airframe.
- Next: milestone 7e, put the k = 1, AR 12 design through the 3a model with tail mass and CG shifted; UIUC polar check of the NACA 0012/0015 slope at Re near 1e5; then the sub-scale demonstrator specification for
aerolog-sitl.
2026-10-27 · Milestone 7c: do the 7b matches keep the longitudinal modes (H1 proper) at n = 0.2? (planned before running)
- Why: 7b found power matches only through proxies for H1 (CL, finite-wing slope). H5 needs the matched model to keep trim speed, phugoid and short-period frequency and damping within the H1 bar of 3% (refuted at 5%) of the n = 1 aircraft. The 3a four-state model already gives these for geometric-similar models.
- Plan (
experiments/nonsimilar_modes/run.py): recompute the 7b grid (same code path, NACA 4412 and 5406, 9 area factors x 8 aspect ratios, n = 0.2), keep the cases with |power ratio - 1| <= 0.05, and give each the 3a model with its own S = k S_sim, AR and chord. Tail kept as the Froude-scaled full-size tail (area 0.2 S_sim, AR 5, arm 3.0 full-size mac x n), NACA 0012 at its own Re; inertia = Froude-scaled full-size (radius of gyration 0.3 of the full-size span x n); wing at the section alpha giving CL = 0.8/k (trim speed is Froude by construction, so "trim speed" is tested through CL). Frequencies nondimensional, omega sqrt(L/g) with L the Froude length. Reference: the 3a n = 1 values (phugoid 0.270, short period 1.654, zeta_sp 0.516, free transition). - Predictions (before running): (1) no matched case has phugoid frequency, short-period frequency and short-period damping all within 5% of the reference (prior 65%): the tail's lift slope at Re of about 1e5 and the shorter relative arm when the chord grows move the short period. (2) The two 7b cases that passed both proxies do not pass the 3% bar on all three (prior 60%). Refuted: (1) one case has all three within 5%; (2) both are within 3% on all three.
### Outcome (experiments/nonsimilar_modes/results.txt; 17 power-matched cases, about 4 min)
- (1) held: 0 of 17 have phugoid frequency, short-period frequency and short-period damping all within 5% of the n = 1 reference (phugoid 0.270, short period 1.656, zeta 0.514), and 0 within 3%. The best worst-case deviation is 15.5% (NACA 5406, k = 1.1, AR 10).
- (2) held: the two 7b cases that met both proxies fail H1 proper: NACA 5406 at k = 1, AR 12 has short period +18.2% and damping -9.2%; NACA 4412 k = 1, AR 12 +18.4% and -10.1%. The 7b proxies (CL, finite-wing slope) did not capture this.
- The cause is the tail, not the wing. The short-period frequency is +13% to +25% in every case, including the uncorrected similar model (1.905, +15%): the tail's chord is a quarter of the wing's, its Re at n = 0.2 is 1.7e5 against 1.9e6 at full size, and NeuralFoil's NACA 0012 slope and the resulting pitch stiffness change with it. Phugoid frequency stays within 6% in every case. Damping moves with CL (low CL cases are over-damped, +39 to +53%).
- So H5 as worded (power within 5% *without breaking H1) is refuted in the wing-only design space of 7a and 7b: a wing correction that fixes power does not touch the short-period error, which the tail sets. The remaining lever is the tail (section, area, arm), so the search has to be extended there before the claim is closed.
- Limits: the tail slope comes from the NeuralFoil surrogate at Re near 1e5 (unchecked against UIUC polars; the short-period shift is only as good as that slope); tail trimmed at CL 0.05 with strip theory; inertia, tail geometry and CG fixed at the scaled full-size values; four-state model with no elevator or thrust dynamics; one full-size reference airframe.
- Next: milestone 7d, a tail search at n = 0.2 (area 0.2 to 0.6 of the wing, section, arm) for the matched wing cases; UIUC polar check of the tail slope when the host is reachable.
2026-10-27 · Milestone 7b: do non-similar corrections (wing area, aspect ratio) restore H2 to within 5% at n = 0.2? (planned before running)
- Why: 7a searched only sections at geometric similarity and left a gap of 8.6% (1.157 to 1.086). The levers it left out change Reynolds number directly: a larger wing area at fixed weight and speed raises the chord (Re up) and lowers CL (induced drag down), and aspect ratio trades induced drag against chord.
- Plan (
experiments/nonsimilar_search/run.py): model at n = 0.2 with weight 0.2^3 W and Froude speed fixed; wing area factor k = S/S_similar in 0.8 to 2.0 (CL = 0.8/k), aspect ratio 5 to 16, e = 0.8; NeuralFoil xxxlarge polars for NACA 4412 and the 7a winner NACA 5406 (free transition), Re from chord = S/b. Power ratio = (CD/CL) / (CD/CL)_ref with the same n = 1 reference as 7a. H1 proxy, reported not enforced: CL/CL_ref and finite-wing lift-curve slope ratio a0/(1 + a0/(pi e AR)), against the 6% / 5% bounds of 7a. - Predictions (before running): (1) some (k, AR) reaches a ratio of 1.05 or less (prior 60%), at k above 1.3. (2) None of those keeps CL within 6% of 0.8 (prior 75%), since CL moves 1/k. (3) A design that reaches 1.05 and keeps the finite-wing slope within 5% of the reference's (AR 10) does not exist (prior 70%). Refuted: (1) best over 1.05; (2) a design with k within 6% of 1 reaches 1.05; (3) one exists.
### Outcome (experiments/nonsimilar_search/results.txt; 144 cases of 2 sections x 9 area factors x 8 aspect ratios, about 4 min)
- My criterion was wrong, and I found it only after the first run. "Ratio at most 1.05" is met by 63 of 144 cases, but the best reach 0.735: a high-aspect-ratio model draws 25% less power than the full-size aircraft, which is a different mismatch, not a correction. H5 asks for a match, so the run was redone with a two-sided band (|ratio - 1| <= 0.05). The predictions below are judged on that band; the first-run count is kept in the file only as the one-sided figure.
- A match exists: 17 of 144 cases. At the similar aspect ratio (AR 10) it takes more wing area: NACA 4412 at k = 1.3 gives 0.996, NACA 5406 at k = 1.2 gives 0.974 (similar designs: 1.157 and 1.094). So H5 is not refuted once non-similar changes are allowed (reverses 7a, which searched only sections at similarity).
- But the cost is the H1 proxy. Of the 17, only 2 keep CL within 6% of 0.8; the AR 10 matches have CL 0.53 to 0.67 (17% to 33% low), i.e. a different trim angle and a lower wing loading than the Froude scale model. The two that meet both proxies include NACA 5406 at k = 1, AR 12 (ratio 0.967, CL 0.800, 3D slope 1.034 of reference): the profile-drag penalty is offset by cutting induced drag, so the power matches at this one point while its split between induced and profile drag, and so its speed dependence, does not. That is a power match at the trim point, not a correction of the physics.
- Predictions: (1) held in its two-sided form: a match exists, at k of 1.2 to 1.3 for AR 10. (2) refuted: 2 matches keep CL within 6% (both with AR changed rather than area). (3) refuted: a match with finite-wing slope within 5% exists (14 of 17; 2 with both bounds).
- Limits: NeuralFoil is still unchecked against UIUC polars (selig host refused through the proxy this session, so the check was not done); the lift-slope and CL bounds are proxies, no flight-dynamics run; strip theory with fixed e = 0.8 at every AR (e varies with taper and AR); the match at AR 12 is within the surrogate's likely error of 3 to 5%, so 0.967 is not distinguishable from 1.
- Next: put the AR 12 and k = 1.3 candidates through the 3a longitudinal-mode model (H1 proper); UIUC polar check when the host is reachable.
2026-10-27 · Milestone 6b: does the m^1.5 exponent survive a day-clustered bootstrap and date fixed effects? (planned before running)
- Why: the 6a limit says payload and flight day are partly confounded (3 of 16 days have one payload; air density is not logged) and the bootstrap resampled flights, so its interval is optimistic if days differ.
- Plan (
experiments/rodrigues_energy/run_days.py): (a) the 6a regression with a bootstrap that resamples whole days (10,000); (b) a dummy per day, so the exponent comes only from within-day payload contrasts, on all flights and on days with more than one payload, with flight and day-cluster bootstraps. - Predictions (before running): (1) the day-clustered interval is wider than the flight bootstrap's 0.254 and still contains 1.5 (prior 60%). (2) The date-fixed-effect exponent is within 0.15 of 1.539 (prior 60%), since payload was mostly varied within day. Refuted: (1) width at or under 0.254, or 1.5 outside; (2) shift of more than 0.15.
### Outcome (experiments/rodrigues_energy/results_days.txt, run_days.py 71 s; 134 flights, 16 days, 13 days with more than one payload)
- (1) held: resampling whole days gives 1.539 [1.394, 1.704], width 0.310 against 0.254 for the flight bootstrap; 1.5 is inside.
- (2) held: with a dummy per day the exponent is 1.529 (all flights) and 1.531 on the 13 multi-payload days (116 flights), flight-bootstrap [1.390, 1.676], day-cluster [1.384, 1.693]. So day and weather confounding does not move the estimate by more than 0.01.
- So the 6a result stands with an honest, wider interval: the m^1.5 power law holds inside the M100 data. Still one airframe and a 13.6% mass span; density and temperature remain unlogged, and a day dummy absorbs only what is constant within a day.
- Next: a second airframe or the hover rows against the same law; sourced full-size propeller for 5a; non-similar corrections for H5.
2026-10-27 · Milestone 7a: can a different airfoil or trip restore H2 to within 5% at n = 0.2? (planned before running; the search ran once, with the low-Reynolds list added before I looked at the first result's ranking)
- Why: H5 says a corrected model brings the power ratio at n = 0.2 within 5% of Froude without breaking H1. Under Froude similitude the usable levers are few: weight, speed and CL are fixed, and trim speed goes as CL^-0.5, so the H1 3% bar leaves CL +/-6%. What remains is the section and the boundary-layer state.
- Plan (
experiments/correction_search/run.py): reference = full-size NACA 4412, free transition, CL 0.8, Re_mac 3.06e6. Model at n = 0.2 (Re_mac 2.74e5): 158 NACA 4-digit sections (camber 0 to 6%, position 0.2/0.4/0.6, thickness 6 to 15%) plus 10 low-Re sections (SD7037, E387, S1223, E214, MH32, FX 63-137, Clark Y, AG35, SD7062, E61), each free or tripped at 5% chord; NeuralFoil xxxlarge polars. Ratio = (cd + CDi) / (cd_ref + CDi); then the best ratio over CL 0.752 to 0.848 using power ~ CD/CL^1.5. H1 proxy: section lift-curve slope within 5% of the reference (not a flight-dynamics run). - Prediction (before running): no section reaches 1.05 (prior 70%): induced drag is 83% of the reference drag, so only the section term can move, and the model section's cd is 1.5x or more higher at Re 2.7e5. Refuted if any case reaches 1.05 with slope within 5%.
### Outcome (experiments/correction_search/results.txt)
- The uncorrected model (same 4412) has ratio 1.157 free and 1.383 tripped at n = 0.2.
- Prediction held; H5 refuted in this design space: 0 of 178 cases reach 1.05, best 1.086 (NACA 5406, free, at CL 0.752, slope 0.98 of reference) and 1.090 at CL 0.8 (NACA 3608, free). The best sections are thin, cambered and untripped (cd 0.0081 against the reference 0.0053). Low-Re sections do no better (E214 1.123, SD7037 1.132). Tripping hurts every section.
- So a better section closes about half the gap (1.157 to 1.09), and the rest is not reachable by section choice: at n = 0.2 expect at least 8% extra power. This is a statement about the section and CL levers only.
- Limits: NeuralFoil is a surrogate, still unchecked against UIUC polars, so differences of a few percent between sections are within its likely error; the 5% slope bound is a proxy for H1 (pitch moment, tail and phugoid untested); 2D strip with a fixed AR 10 / e 0.8 wing; geometric similarity kept, so non-similar models (different aspect ratio, a larger chord, vortex generators, a lighter-than-scaled model) are outside the search and are the next candidates; the power ratio is aerodynamic, with no propulsion efficiency.
- Next: non-similar corrections (aspect ratio, chord) with the longitudinal model; UIUC polar check of the surrogate; day-clustered bootstrap for 6a.
2026-10-27 · Milestone 6a: does measured electrical power on a real multirotor scale as mass^1.5, the exponent behind Froude power n^3.5? (planned before running)
- Why: milestone 6 and the "Next" of milestone 2. Froude scaling gives power proportional to n^3.5, which for a rotor in hover is momentum theory's P_i = (m g)^1.5 / sqrt(2 rho A) (m ~ n^3, A ~ n^2). Rodrigues et al. (Patterns 2022) assume the 1.5 in their energy model (their Eq. 3); the exponent was not fitted. Their data (Figshare 10.1184/R1/12683453, CC BY 4.0: 209 flights of a DJI Matrice 100, 3.68 / 3.93 / 4.18 kg takeoff mass at 0 / 250 / 500 g payload, speeds 4 to 12 m/s, 5 Hz battery V and I) lets us fit it. The mass range is only 13.6%, so this tests the exponent inside one airframe, not across scales.
- Plan (
experiments/rodrigues_energy/run.py): mean battery power V*|I| over the cruise samples of each R1 to R7 flight (horizontal ground speed within 20% of the commanded speed, |vz| < 0.5 m/s); OLS of ln P on ln m (takeoff mass from payload) with commanded speed, speed squared and wind-speed mean as covariates; 95% bootstrap interval over flights (10,000 resamples). Also hover: the 4 route-H ground-hover flights are only used for the absolute level, with P_i from ISA density at 300 m and disc area from the DJI 1345 propeller (13 in), 4 rotors. - Predictions (before running): (1) the fitted mass exponent has a 95% interval containing 1.5 (prior 55%; a non-zero constant avionics and profile power pulls it below 1.5, wind and air-density noise widen it). (2) The interval is wider than +/-0.4 (prior 50%): 13.6% mass span against flight-to-flight scatter. (3) Cruise power rises with speed between 4 and 12 m/s by less than 25% (Rodrigues et al. report little speed effect). (4) Electrical cruise power exceeds the ideal induced power P_i by a factor of 1.5 to 3 (figure of merit, motor and ESC losses, profile and parasite power).
- Refuted: (1) 1.5 outside the interval; (2) width under 0.8; (3) a rise of 25% or more; (4) factor outside 1.5 to 3.
- Limits known in advance: one airframe, one battery, 13.6% mass span; density and temperature are not logged per flight (ISA at the site is used), and payload was not randomised against day or hour, so the exponent can be confounded by weather; battery sag at low state of charge is not modelled; the 5 Hz power is the sensor's.
### Outcome (experiments/rodrigues_energy/: run.py 21 s, results.txt; 134 of 209 flights kept: R-routes with at least 5 s of cruise samples; 46 / 42 / 45 flights at 0 / 250 / 500 g and one at 750 g)
- (1) held: the fitted mass exponent is 1.539, 95% bootstrap interval [1.413, 1.667] over flights (10,000 resamples), with speed, speed squared and mean wind as covariates; 1.5 is inside. Without covariates 1.524 [1.303, 1.747]; R1 flights only 1.509 [1.376, 1.643]; altitude-25 flights only (n = 37) 1.410 [1.211, 1.630]. So inside one airframe over a 13.6% mass range the measured electrical power follows the m^1.5 of momentum theory, and the exponent that Froude scaling turns into n^3.5 is not contradicted. It does not test the exponent across a factor of 10 in size.
- (2) refuted: the interval is 0.25 wide (prediction: wider than 0.8 in total). The mass signal is cleaner than expected (cruise power rises from 440 W to 534 W between 0 and 500 g).
- (3) held, but the sign is the other way: cruise power falls with speed instead of rising, by 10.1% from 4 to 12 m/s in the fitted model (507 W at 4 m/s, 414 W at 12 m/s as raw means; 4 to 8 m/s: -0.4%), the translational-lift effect that Rodrigues et al. mention as small up to 8 m/s. Mean wind is a covariate, so this is not the wind.
- (4) held: electrical cruise power over the ideal induced power (P_i = (m g)^1.5 / sqrt(2 rho A), rho 1.20, A from four 13 in propellers) is 1.84, 1.86, 1.85 at 0, 250, 500 g. The ratio does not move with mass, which is the same statement as (1). Ground hover (route H, 4 flights at 3 m, 0 g) draws 431 W against 440 W cruise.
- Not shown: any scaling across size. The M100 is one airframe; the energy side of H4 (efficiency of motor and propeller at model size) is still the 5a propeller result alone. Dates: 16 flight days, 3 with a single payload, so day and payload are partly confounded (density not logged); the bootstrap resamples flights, not days, so the interval is optimistic if days differ.
- Next: a day-clustered bootstrap or a fixed-effect for date to test that confound; hover power from route H against the same model for a second airframe (the dataset is one vehicle); sourced full-size propeller for 5a.
2026-10-27 · Milestone 2: open TP-1435 and check every reference (a check, not an experiment)
- Why: the proposal and the code quoted TP-1435 and 13 other references from memory because the registries returned 403 on the first session. They answer now.
- Method:
cite_check.py on PROPOSAL.md; NTRS search API for the four NASA records; Crossref for the two DOIs it skipped or could not match; TP-1435's PDF downloaded and Table 4 read. - Result: the memory version was wrong in four places: TP-1435's middle author is Brown, not Bowman; its NTRS id was 19790022005 not 19790015227; Chambers (SP-2009-575) is 20110012492 not 20100005350; Johnson, Silva and Solis is 20180003381 not 20180002029 (the old id is an unrelated record). "Jordan et al., AirSTAR papers (2005 to 2006)" is now a specific record (NTRS 20040085988, 2004). Four DOIs confirmed by
cite_check.py, Rodrigues et al. and Brandt and Selig by Crossref. - TP-1435 Table 4: velocity, time, angular rate, linear acceleration, oscillatory frequency, mass and mass moment of inertia match
EXPONENTS; a new test pins them. No change to any milestone 1, 3a, 4a or 5a number. Force, moment, power, energy and Reynolds rows are not in the table as separate Froude rows and stay derived. - Limits: the PDF is an OCR scan, so the rows were read by eye from garbled text; the Jordan et al. venue, Drela, Raymer and the BlueSky paper are not re-opened.
- Next: milestone 6 (energy against Rodrigues et al. flights; the dataset is public on Carnegie Mellon's Kilthub, probe it) and a sourced full-size propeller for 5a.
2026-10-27 · Milestone 5a: how much peak propeller efficiency does a Froude model lose to Reynolds number? (predictions fixed before the final numbers)
- Why: H4 says motor-plus-propeller efficiency at n = 0.1 is at least 10 points below full size (refuted under 5). Only the propeller part can be measured here; the UIUC Propeller Database (wind-tunnel data, 91 MB zip, reachable through the proxy) gives eta(J) at many RPMs for APC propellers.
- Plan (
experiments/propeller_efficiency/run.py): peak eta and Re at 0.75 R (from RPM, diameter, c/R at 0.75) for every APC curve with a bracketed peak; within-propeller slope against log10 Re, bootstrap over propellers; saturating fits eta_inf - a Re^-b (b = 0.5, 0.2). Predictions: (1) peak efficiency rises with Re in nearly every propeller; (2) the fall from Re 1e5 to 3.2e4, inside the data, is 5 to 10 points; (3) the data cannot reach a full-size Re of about 1e6, so the n = 0.1 gap is an extrapolation.
### Outcome (experiments/propeller_efficiency/results.txt)
- 151 curves, 34 propellers, Re75 1.5e4 to 1.2e5. (1) held: 97% of per-propeller slopes are positive, mean 0.21 per decade [0.18, 0.23].
- (2) partly: the saturating fits give 9.9 and 10.3 points for 1e5 to 3.2e4, at the top of the predicted range; the cross-propeller bin means differ by 6.6 points (0.669 vs 0.603) over a smaller Re span. So H4's 10-point bar is about met by the propeller alone for a model near Re 1e5.
- (3) held: extrapolation to Re 1e6 gives 19 to 25 points from the saturating fits, 31 from a straight line; not used as a result. The full-size Re 1e6 is itself an assumed figure (1.5 m, 200 m/s tip, 0.1 m chord).
- Limits: RPM and Re move together inside a propeller (J at peak, tip Mach), so the slope mixes effects; APC thin-electric and slow-flyer props only; motor efficiency not modelled; the 1.2 kg/m3 and 1.8e-5 Pa s are lab air.
- Next: a sourced full-size propeller (diameter, RPM, chord) for the Re; motor efficiency vs size.
2026-10-27 · Milestone 3a: do trim speed and the longitudinal modes survive Reynolds-dependent aerodynamics? (predictions written after a first exploratory run, so not blind)
- Why: H1 says trim speed and mode frequencies agree within 3% (refuted over 5%) at n = 0.1. Froude scaling makes them agree exactly for fixed coefficients, so any gap comes from Re-dependent CL(alpha), CD and tail effectiveness.
- Plan (
experiments/longitudinal_modes/run.py): wing NACA 4412 plus tail NACA 0012, NeuralFoil polars at each surface's Re, 4-state Etkin model; model flown at full-size trim angle, or at full-size CL. Predictions (stated after seeing a first run that crashed on the mode extraction, before the final numbers): trim speed moves under 3% at n = 0.1 (tripped); frequencies within 3%; short-period damping moves more than frequency.
### Outcome (experiments/longitudinal_modes/results.txt)
- Tripped, n = 0.1 vs 1: same-alpha rule gives dV +6.5%, phugoid frequency -5.2%, short-period frequency +5.1%, damping -6.7%: H1 refuted on this rule (prediction 1 and 2 wrong). Same-CL rule: frequencies +0.8% and -1.3% (held), short-period damping -6.3% (prediction 3 held).
- Free transition at n = 0.1 and 0.05: the short period becomes overdamped (two real roots) and trim CL drops; this is the NeuralFoil bubble regime from 4a, not used as a result.
- Phugoid damping is positive in the textbook estimate but negative here even at n = 1 (induced-drag slope CD_alpha with no speed-dependent thrust); the sign is a modelling artefact, so it is not reported.
- Limits: no gust response (H1 names it); the surrogate is unvalidated against UIUC data; geometry and CG are design choices; the tail is trimmed by the elevator at zero lift; no thrust-line or propeller terms.
- Next: gust response; thrust law; UIUC polar check.
2026-10-27 · Milestone 4a: do airfoil polars keep H2 (power) and H3 (CLmax)? (predictions fixed before the run)
- Why: milestone 1's flat-plate drag could not say whether H2 survives a real section. XFOIL itself is not installable here; NeuralFoil 0.3.3 (a neural surrogate trained on XFOIL, MIT) is, via AeroSandbox 4.2.10.
- Plan (
experiments/airfoil_polars/run.py): NACA 4412 section, Re_mac from the milestone-1 calculator at n = 1 to 0.05, three boundary-layer states (n_crit 9, n_crit 5, trip at 5% chord). Section cd at cl = 0.8 plus induced drag (AR 10, e 0.8) gives the power ratio against n = 1; CLmax from the alpha sweep. - Predictions: (1) the n = 0.1 power ratio is at least 1.20 in all three states (H2 refuted if under 1.10). (2) CLmax falls by at least 0.2 at n = 0.1 in all three states (H3 refuted if under 0.1). (3) the surrogate is not trustworthy at n = 0.05 (Re 3.4e4).
### Outcome (experiments/airfoil_polars/results.txt)
- Power ratio vs Froude at n = 0.1 (Re_mac 9.7e4): 1.445 (n_crit 9), 1.291 (n_crit 5), 1.361 (tripped). (1) held; milestone 1's flat-plate 1.27 sits at the bottom of this range. At n = 0.2 the ratio is 1.11 to 1.19, so the 20% bar is not met there.
- CLmax change at n = 0.1: -0.37, -0.52, -0.48. (2) held (H3 supported for a 2D clean section).
- (3) held: free-transition n_crit 9 at n = 0.05 gives cd 0.137 (ratio 5.3), a separated-bubble regime the other two states do not show (1.8 to 2.0); not used as a result.
- Not done: no check against UIUC measured polars (hosts 403 or not tried), so the surrogate error is unquantified; NeuralFoil CLmax at Re 3e6 is 1.84, which looks high against the 4412's textbook value (from memory, unchecked). 2D section only: no finite-wing, flap or Reynolds-dependent induced effects; cl = CL strip approximation.
- Next: UIUC polar check of the surrogate; vortex-lattice model for H1.
2026-10-27 · Milestone 1: how much power does a Froude model need beyond the Froude prediction? (planned before running)
- Hypothesis: with a flat-plate skin-friction drag model, a Froude-scaled model at n = 0.1 needs more than 20% extra power over
n^3.5 x P_full (H2), because Re falls as n^1.5 and Cf rises as Re falls, while all other Froude-scaled quantities match by construction. - Plan:
experiments/run.py scales one 1,000 kg, AR 10 airframe to n = 1 to 0.05 and reports Re, CD0, L/D, the power ratio and the battery fraction for a range scaled with length; sweeps form factor, wetted area and aspect ratio; compares a tripped (turbulent) with an untripped (laminar below Re 5e5) boundary layer. Unit tests check the ISA, Sutherland viscosity, the exponent table's dimensional consistency and the skin-friction formulas.
### Outcome
- Tripped base case: power ratio 1.06 (n = 0.5), 1.16 (0.2), 1.27 (0.1), 1.42 (0.05); L/D falls from 22.8 to 18.0 at n = 0.1. Across the CD0 and aspect-ratio sweeps the n = 0.1 ratio is 1.17 to 1.35, so the >20% bar holds in every case except aspect ratio 6 (1.17); the low-drag case is 1.21.
- The untripped case is not monotone: attached laminar flow gives lower Cf at Re near 3e5, so the model beats full scale (ratio 0.96 at n = 0.2) until Re falls to 1e5. This is an artefact of the model, since real wings at that Re separate. It is why H2 must be tested with XFOIL polars, not a flat plate.
- Battery fraction for a range scaled with length falls with n (0.13x at n = 0.1) so a model at fixed cell specific energy has far more battery margin than the full-size aircraft per body length: endurance in scaled time does not test the full-size energy budget. This follows from range, not from drag.
- So H2 is supported at the base case by a flat-plate estimate, not yet by an airfoil-based one. Preliminary; first-order model only.
- Limits: flat-plate Cf with a form factor, not an airfoil; no induced-drag Re effect; no CLmax; powertrain efficiency held fixed (it falls with scale, so the ratio here is optimistic); constants for the airframe are design choices, swept but not sourced to a specific aircraft; citations not machine-checked.
- Next: milestone 2 and 3 (open the NASA table; vortex-lattice and flight-dynamics model).
Paper, code and results
More in Digital twins & sim-to-real
- Does a physics-shaped twin of a real buck converter beat plain ARX? Only partly: all models sit at 0.5 to 0.9 V free-run error against a 0.06 V quantisation floor, and the winner flips with which half of the 20 ms record is fittedDoes a physics-shaped twin of a real buck converter beat plain ARX? Only partly: all models sit at 0.5 to 0.9 V free-run error against a 0.06 V quantisation floor, and the winner flips with which half of the 20 ms record is fitted. One 20 ms record; natural frequency fitted, no component values.
- How much feedback delay can a digital twin's controller tolerate, and does a fixed-step simulator get that margin right?Exact: a fixed-step twin under-reports a PD loop's delay margin by 18.6% at dt = 0.1 s and 1.0% at 5 ms, because the largest stable delay is the largest n with (n + 1/2) dt below the true margin (25 of 25 cases)
- How wrong is a simulator's pendulum period at its default timestep?How wrong is a simulator's pendulum period at its default timestep? Exact elliptic-integral period against Euler, semi-implicit Euler, Verlet and RK4: Euler fails (14% period error at 2 ms), the symplectic pair is 0.75 ppm, and releasing from rest hides the symplectic error.
- Which 95% upper bound on a failure rate actually covers 95% at simulator-rollout sample sizes?Which 95% upper bound on a failure rate really covers 95% at rollout sample sizes: exact coverage shows only Clopper-Pearson never undercovers (min 0.950), Wilson dips to 0.93, Jeffreys to 0.85 and Wald to 0.06–0.75; zero-failure certification of p ≤ 1% takes 299 rollouts (CP), 268 (Wilson) or 191 (Jeffreys).
- How many fixed steps per orbit does a twin need before an eccentric orbit stops drifting?How many fixed steps per orbit does a twin need before an eccentric orbit stops drifting? Against the exact Kepler solution RK4 needs 64 to 4096 steps per orbit (e = 0 to 0.9), the symplectic pair 8 to 16 times more, and at e = 0.9 every fixed step fails.
- How long does a digital twin of a chaotic system stay accurate? Each e-fold of smaller state error buys 1.12 time units on Lorenz-63 (1/lambda = 1.11)How long does a digital twin of a chaotic system stay accurate? On Lorenz-63 each e-fold of smaller state error buys 1.12 time units (1/lambda = 1.11); a parameter error buys 0.85. Mean over 40 starts, one tolerance.
All 164 Digital twins & sim-to-real projects →
Other research topics
Proper scoring & elicitation28Effort & peer prediction9Verification games & slashing19Detection & tolerances14Markets as routers13Prediction-market design9Paying contributors8Decentralised training systems23Digital twins & sim-to-real164LLM chip design loops40Robot manufacturing loops53Ambient AI assistant46Self-replicating manufacturing34Simulation-first design64Engineered clothing45Task-specific AI accelerators40Algorithmic chip-design loops42Open-source purpose-built robots44The software-engineering loop43Adversarial human imitation41Open-source residential construction41Autonomous multi-angle capture34Sensing, imaging and 3D31Energy supply and dense energy storage39Robot societies among people31Agentic co-design of low-cost robots27Laundry-hanging robots25Machine learning on qualitative data23Robots on the building site27Civilizations & group psychology1History & human sciences1
Produced with AI assistance (Claude). Results are from the code in this repository and are simulated or stylised unless the abstract says otherwise; nothing here implies affiliation with or endorsement by any lab, researcher or company cited. MIT licensed.