feat(airframe): Rev T1 — the tilt spar becomes a structural member of the wing (both halves) - #195
Merged
Stab-Rabbit-coding merged 15 commits intoAug 31, 2026
Conversation
U1 of docs/plans/2026-08-29-003-feat-unified-20mm-spar-trunnion-belt-drive-plan.md. tools/spar_bundle_fit.py (new) — sizes a hollow spar bore against the conductor bundle it must swallow, using the EXACT tabulated optimal circle-packing ratios K(n) for n <= 7 (Melissen 1997) and refusing to interpolate outside that table. Reproduces the plan's finding: 4 x D5.5 circumscribe D13.28, so SPAR_BORE_D = 11.0 (proposed independently by both docs/plans/2026-08-27-nacelle-wiring-plan.md and the external source conversation) does not fit at all, and of the 16 mm tubes only 16x14 fits — with 0.36 mm radial, no room to twist. 20x16.3 PASSes at 1.51 mm radial. The 5.5 mm wire OD is an ASSUMPTION — bom_revS.csv records no OD for WIRE-10AWG — and the tool prints that caveat on every run rather than letting the figure harden by repetition (plan 003 DEP-2 / OQ4). tools/wing_spar_station_fit.py — solve_tip_scale() generalised to solve_scale() and now run for the ROOT as well. Through Rev S1b the root was never at risk (15.60 mm of section against a D8.3 bore), so a tip-only solver was sufficient; a D20.4 bore breaks the root out by 2.40 mm, and the old tool would have reported the tip figure and said nothing about it. Also adds --t-root/--t-tip overrides, reports solved scales as actual t/c (a bare multiplier hides that the tip stops being an S1223 — plan RISK-1), and reports the UNSCALED camber midline, which is what spar_bore() centres on and what the fuselage side must derive SPAR_Z from. solve_tip_scale() is kept as an alias — the Rev S1b/U6 notes cite it by name. Verified: --bore 20.4 --station 28 gives root 1.456 / tip 2.190 (KTD2's frozen figures) and midline +8.84 (SPAR_Z = 58.01 + 8.84 = 66.85); regression --bore 8.3 --station 45.15 still reproduces the as-built 1.550. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Plan 003 U2/U3/U5 + plan 004 U3, wing side only. The spar stops being a rotating drive shaft riding bearings and becomes a BONDED STRUCTURAL MEMBER OF THE WING, which is what re-routes everything else here. Airfoil (KTD2, tool-solved, not hand-tuned): SPAR_BORE_STATION 45.15 -> 28.00 mm SPAR_BORE_OD 8.3 -> 20.4 mm THICKNESS_SCALE 1.00 -> 1.46 root t/c 12.14 -> 17.72 % THICKNESS_SCALE_TIP 1.56 -> 2.20 tip t/c 18.93 -> 26.70 % THE ROOT OML MOVES FOR THE FIRST TIME in this design's history — at 1.00 a D20.4 bore breaks out of the root skin by 2.40 mm. tools/wing_spar_station_fit.py solved the tip only until this revision and would have said nothing about it. Root load path — the substantive change. A bearing transmits shear, not moment, so the Rev R2 rotating spar was structurally incapable of reacting the root moment; the enlarged tenon (FOS 0.49) and then the two-rod couple (FOS 4.14) both existed to work around that. A fixed bonded spar carries moment directly: nacelle -> trunnion -> spar -> fuselage socket, with the couple arm going from 48 mm (chordwise rod spacing) to the full 86.7 mm span. spar bending, cantilever bound 33.28 MPa, FOS 9.0 vs the 300 MPa stand-in TENON_LOAD_PATH default -> "spar_carrythrough"; tenon locates only tie rods RETIRED — the fwd rod (9.9..18.1) now intersects the spar bore (17.80..38.20) outright, and the aft rod's only remaining job would be wing torsion, which is 0.41 N.m ultimate -> bond shear 0.016 MPa, FOS 306 PUBLISHED TO THE FUSELAGE: >= 55 mm socket reach for FOS 4.0 at the repo's standing 5 MPa figure (17 mm if the LG-11 coupon lands REF-MAT-001's 47 MPa) Bore inventory, all constant-mm so taper cannot erode the webs: 8.0 D3.2 nav 3-core (new; the light rotates, the spar does not) 28.0 D20.4 bonded CF spar — now carries the 4x 10 AWG feeds on the tilt axis 44.5 D6.5 AK7455 SPI quad + power pair (was D3.5 @ 54.0, sized for 4-wire I2C) 54.0 D4.4 tilt drive shaft (new) The 2x D7 EDF double-D is RETIRED: it could not carry two 10 AWG conductors at any realistic wire OD, and its 27.5 mm station now falls inside the spar bore. Two errors found and corrected rather than propagated: * wing_tip_spar_through_bore() carried rotate([0,90,0]), cutting a CHORDWISE hole. Harmless at D8.3 (the module's real job was simply never done); at D20.4 it would gash the tip. Its sibling had the right convention all along. * plan 004 KTD4's shaft station 43 implies a 15 mm gear centre distance. The tilt ring gear is concentric with the spar, so at C=15 the algebra returns a ring PD of 10.5 mm — smaller than the spar it encircles. Real minimum C is 23.1; 26.0 is used, putting the shaft at station 54. Also closes the long-open WBS 1.1.3.6 item: the encoder pocket was still 7x7 mm, dimensioned around the MT6701 3x3 QFN rejected on 2026-07-19, with a D3.5 conduit labelled 4-wire I2C. Now AK7455 QFN24 4x4 on a 10x8 board, ring magnet grown ID 27/OD 41 (ID 10 could not pass over a D20 spar), HALL_SENS_R 11 -> 17 so the IC still reads mid-annulus. Wingtip: bearing seat retired (a bearing here would let the spar spin under the pinion's reaction). Plan 003's wingtip pinch collar and garage are moved with cause, both recorded in-file: a D30 collar cannot exist in a 22.83 mm section and has nothing to do against a 5,492 mm^2 bond, and the tip has no volume for 10 AWG disconnects (section falls 17.50 -> 3.43 mm aft of the spar). Mass: printed wing shell 101.9 -> 110.0 g/side; spar 96.2 -> 58.2 g/pair. Gates: validate_stls 61/61, wing_internal_clearance PASS, wing_airfoil_integrity PASS (now validating the sections at their ACTUAL scales, closing RISK-2), cargo_bay_envelope PASS, landing_gear_wing_clearance --proud CLEAR. wing_root_deconflict FAILS with 3 findings, all fuselage-side staleness against the new station — the fuselage is deliberately untouched this pass and the deltas are published to its plan. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…m figures
Adds docs/WING_ATTACH_INTERFACE.md as the single specification for both wing
joints, because the Rev T1 load path now crosses two joints owned by three
different WBS files and the numbers were about to be stated three times. The
wing side is BUILT; the fuselage and nacelle sides build to this.
Root -> fuselage. A bonded spar socket carries the whole joint; the tenon
locates and there are no tie rods. Hull Y +21.00 / Z +66.85 / D20.4, both
stations DERIVED (LE root bakes to Y -7.0 + station 28.0; chord line Z +58.01 +
the UNSCALED camber midline 8.84 -- applying THICKNESS_SCALE to the midline
would lift the socket 4.07 mm above the spar it receives). Socket reach >= 55 mm
for FOS 4.02: bearing stress goes as 1/L^2, so length is the only real lever.
Tip -> nacelle. Spar stub 32 mm proud, bearings on the nacelle trunnion, ring
gear PD 33.8 at C 26.0, ring magnet ID 27 / OD 41.
Four upstream figures corrected, each with its derivation rather than a swap:
* plan 004 KTD4's shaft station 43 implies a 15 mm gear centre distance. The
ring gear is concentric with the spar, so the algebra returns a ring PD of
10.5 mm -- smaller than the spar it encircles. Built at C 26.0 / station 54.
This escalates OQ1 (servo range) to BLOCKING: 180 deg needs station 58.5,
which collides with the root tenon at 58.5 mm.
* TILT_ENCODER_WIRING_EMI_SPEC.md 6.1's premise ("the tilt spar is 4130 steel,
ferromagnetic") is now false -- the spar is CF. Corrected in place; the
mitigations are retained with a changed target (the drive shaft and pinion
ARE steel and ARE nearby), so the zero-calibration stays mandatory.
* wings-nacelles WBS 1.1.4 still read "PIVOT_Z STAYS 111.5" and quoted the
withdrawn station-22 pick, both contradicting the FROZEN block six lines
above them. Reconciled to 116.1 / 28.0, and OQ5 closed as RESOLVED (the
trunnion is concentric with the spar; no tip-rib bracket is needed).
* plan 005 OQ5 asked whether the station move should be re-sequenced; it is
done, so the question is void -- but its +9.8 mm clearance margin is
owner-accepted and that plan is the last thing that can silently spend it.
TILT_SPAR_ANALYSIS.md 3.6 re-derives the section for a FIXED spar and marks
3.2/3.5's torsion, keyability and bearing-journal discriminators VOID -- all
three were consequences of the spar rotating, not of its loads. CF was rejected
there on the functional gate, explicitly not on strength; with no keyway and no
journal the gate is gone, and the larger spar is 38.0 g/pair LIGHTER than the
small steel one at 10.3x the section modulus.
REFERENCES.md REF-MATH-001 (Melissen 1997) catalogues the circle-packing ratios,
because the n=4 case decided a load-bearing geometry change and the wrong
constant (11.0 mm) had already propagated through two independent documents by
being carried in prose instead of computed.
TODO 0.8/0.8.1 carries the open gates: CF spar certificate, measured wire OD,
servo range, the LG-11 coupon, aero revalidation, WA-R1..R13, and the owner
decision on the 36 mm cargo-bay intrusion.
Gates: 8 of 9 green; wing_root_deconflict RED by design until WA-R1/R6 land.
flake8 clean. precommit_index --check clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…itability Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…airfoil Three owner directives, each of which invalidated something I had built. 1. THE SPAR MUST NOT PENETRATE THE THRUST DUCT. The stub was 32.0 mm, budgeted outward from the bearing stack and never checked against the duct. The duct is a cylinder r=25 about the nacelle's local Z; the spar runs along local X at Y=0, so every point of it sits |X| from the duct axis and it clears only if it TERMINATES at |X| >= 26. With the tip face at |X| = 41.7 the maximum stub is 15.7 mm. The 32 mm stub reached |X| = 9.7 -- fifteen millimetres inside the duct wall, through the thrust column between the EDFs. Same class of error as the Rev R2 through-duct spar this revision exists to remove. Now 15.0 mm, and the nacelle's bearing pair must fit inside it (2x 6804 = 14.0 mm does). 2. THE CENTRE OF THE CARGO BAY MUST STAY CLEAR. That kills the 55 mm socket: the bay's clear span starts at hull X -100 and the wall skin is at -81.33, so only 18.67 mm of socket depth exists. At that depth the socket gives FOS 0.51 on the moment, and since stress goes as 1/L^2 no socket can recover it. THE JOINT SPLITS: the socket keeps the SHEAR (0.31 MPa, FOS 16 -- shear never needed depth), and the moment moves to a bonded ROOT FLANGE on the inner sidewall, 80 x 60 mm, FOS 29.2. A flange trades an unfavourable 1/L^2 depth term for a linear area term, so this is better than the socket it replaces, not a compromise -- and it protrudes only its own ~5 mm to X ~ -86 against a bay edge at -100. It also demotes the LG-11 coupon from a gate to a packaging convenience here. 3. THE SERVO DRIVES THE SHAFT MORE THAN ONE REVOLUTION. This inverts the tip stage from a step-UP to a REDUCTION and dissolves the impossibility I flagged last pass: as a reduction the ring is the LARGER member, so it clears the spar easily. Module 0.8, 14T pinion / 50T ring, i = 3.571, shaft turns 1.389 rev per 140 deg of nacelle, C = 25.6 -> shaft station 54.0 -> 53.6. 36T turns exactly one revolution (not "more than"); 54T pushes the bore to 55.2 and leaves 1.1 mm to the root tenon, under the 1.16 mm floor. CONSEQUENCE: the actuator is no longer a limited-rotation servo but a continuous-rotation gearmotor or stepper closed on the AK7455's absolute angle. That retires the 180-vs-270 question, which was BLOCKING an hour ago. Encoder follows: HALL_SENS_R 17.0 -> 16.8, ring ID 26 / OD 41.2, board 9 x 8. AIRFOIL RE-DERIVED FROM THE TABULATED UIUC COORDINATES (REF-CAD-006), not quoted. The header claimed max thickness "at 22.6% chord" and max camber "at 39.4% chord"; both LOCATIONS were wrong and neither was traceable to the table this file actually builds from. Sampling at 1/20000 chord returns 19.8% and 49.0% -- exactly the published S1223 characterisation. The built sections are now named for what they are: S1223/t17.7 (root) and S1223/t26.7 (tip) -- S1223's camber line with the thickness envelope scaled x1.46 and x2.20. Camber is identical in all three (8.67% at 49.0%) because s1223_section() scales thickness about an unscaled camber line. LE radius goes as t_scale^2, verified numerically: 0.02502c -> 0.05333c -> 0.12110c, so the tip's nose is 12% of its own chord. What survives, what does not, stated per-claim in the header: the camber figures are exact; zero-lift angle and lift-curve slope partially survive at the root on thin-airfoil grounds (they depend on the camber line alone) and not at all at the tip, which is far outside that theory's range; every performance number (CL 1.55, CL_max 2.0, L/D 30-35, the 7.6 N cruise lift) does NOT survive and is marked history-only at each use. Re is unchanged at 1.3e5-1.8e5 -- all low-Reynolds, where polars do not transfer between Re let alone between sections. Also fixes a stale comment: HALL_CABLE_STATION read 44.5 while its own comment still said 44.0 and quoted the 44.0 webs, from an edit that silently missed. Gates: 7 of 8 green; wing_root_deconflict RED by design until the fuselage moves. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sweeps the three owner directives through every place the repo describes this
wing, and corrects two citation defects found on the way.
AIRFOIL, DESCRIBED ACCURATELY THROUGHOUT. The built sections are named for what
they are -- S1223/t17.7 (root) and S1223/t26.7 (tip): S1223's CAMBER LINE with
the thickness envelope scaled x1.46 / x2.20. Updated in wings_s1223_revo.scad
(new "SECTION DESIGNATION AND DATA" block), docs/flight_envelope.md,
docs/WING_ATTACH_INTERFACE.md S4A, wings-nacelles/WBS.md, bom_revS.csv/.json,
and TODO S0.8. Every figure is re-derived from the tabulated UIUC coordinates
(REF-CAD-006) at 1/20000 chord, not quoted.
Per-claim, rather than a blanket disclaimer:
camber 8.67% at 49.0% chord EXACT for the built sections (camber is unscaled)
zero-lift angle, dCl/dalpha PARTIALLY survives at the ROOT only -- thin-airfoil
theory makes both depend on the camber line alone,
which is why preserving it matters; but 17.7% is
already outside "thin" and 26.7% emphatically is
CL 1.55 / CL_max 2.0 / L/D DOES NOT survive; marked history-only at each use
7.6 N cruise lift, "22% AUW" DOES NOT survive (derived from the above)
printed surface finish NEVER characterised -- FDM layer lines are a
de-facto trip strip at these Re
Re is unchanged at 1.3-1.8e5, all below 5e5, where polars do not transfer between
Reynolds numbers let alone between sections. flight_envelope.md carries a banner
saying plainly that every aerodynamic result in it now rests on an input that no
longer describes the aircraft.
CITATION DEFECT 1 -- structural_analysis.md cited "14 CFR Part 23.303" twice.
That section belonged to the PRE-2017 Part 23 and does not exist in the current
rule; the Amdt. 23-64 restructure moved limit/ultimate to S23.2230. Same class
of defect REFERENCES.md already recorded for S23.1401. Corrected, and Part 23
added as REF-FAA-004 with S23.2230 and S23.2265 quoted verbatim from GovInfo's
CFR XML (eCFR's HTML endpoint bot-blocks automated retrieval; GovInfo is the
same authority).
CITATION DEFECT 2, in the other direction -- the FOS 4.0 joint target was
described as "a design-team judgment value" with no basis. It has one:
S23.2265 requires a SPECIAL factor beyond the basic 1.5 for parts "subject to
appreciable variability because of uncertainties in manufacturing processes or
inspection methods", which is exactly FDM-printed CF-PETG. The requirement is
now cited; the numeric value stays the project's own choice. Also recorded, to
prevent a future fabrication: +3.8/-1.52 appear NOWHERE in current Part 23 and
must not be cited to it.
Geometry figures swept to the Rev T1b values: stub 32 -> 15.0 mm (duct-bounded),
shaft station 54.0 -> 53.6, ring/pinion 50T/14T module 0.8 at C 25.6,
HALL_SENS_R 17.0 -> 16.8, ring magnet ID 26 / OD 41.2, root socket 55 mm ->
18.5 mm socket + 80x60 bonded flange. BOM: PRINT-WINGS-S1223 mass 118 -> 124
g/side and re-noted; BRG-MF128ZZ to QTY 0 (no wingtip bearing exists any more --
one there would let the spar spin under the pinion's gear reaction).
Closed: the cargo-bay intrusion owner decision (the bay stays clear and the joint
got better, 4.02 -> 29.2), the 180-vs-270 servo question (void under a multi-turn
drive), and WA-R5. Opened: actuator re-select, and trunnion packaging -- the
bearing pair, ring gear and ring magnet must now all fit inside 15 mm.
Aerodynamic content produced with the aeronautical-engineering skill; it carries
a standing ENGINEERING REVIEW REQUIRED notice -- these are computed geometric
properties and a statement of what is NOT known, not a performance substantiation.
Gates: 7 of 8 green, flake8 clean, index clean; wing_root_deconflict RED by
design until the fuselage side moves.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… last pass ID 27 / OD 41 -> ID 26 / OD 41.2 and HALL_SENS_R 17 -> 16.8 in the EMI spec, the attach interface, plan 004, plan 005 and the wings-nacelles WBS. The encoder geometry moved with the drive-shaft station in e887b66 and these five citations of it did not follow -- exactly the stale-figure class this revision has been correcting elsewhere, so leaving them would have been self-defeating. Also corrects a derived figure that was wrong in both revisions: an IC left at R = 11 sits 2.0 mm inboard of the ring's inner edge (r 13.0), not 2.5 mm. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…s://github.com/Stab-Rabbit-coding/Serenity-UAV into claude/serenity-wing-nacelle-validation-kvux9w
…t drive The wing side of Rev T1 has been built since 2026-08-29; the fuselage side still carried WING_SPAR_Y = +38.15 and WING_SPAR_BORE_D = 8.3, so tools/wing_root_deconflict.py failed on three findings that were all that one fact. This lands the fuselage half and the actuator that goes with it. Fuselage joint (WA-R1/R1b/R2/R4/R6, airframe/blender-scripts/merge_cargo_interior.py) - Spar socket moved to chord station 28.0 -> hull Y +21.00, Z +66.85 (unscaled camber midline), bore 8.3 -> 20.4, boss 27.7 -> 30.1. Shear only, FOS 16. - F688ZZ root bearing DELETED. Not a tidy-up: a bearing here would let the fixed spar spin under the tilt pinion's gear reaction. - Both wing-root tie rods retired -- the wing already gates them off, and the forward one now intersects the O20.4 spar bore. - Mortise 30.8 -> 12.8 for the 12 mm locating tenon (fit +0.40 mm/side). - Conduits re-cut: nav O4.2 @ Y +1.0, AK7455 O7.5 @ Y +37.5, drive shaft O4.4 @ Y +46.6. The two O7 EDF ports are gone; the four 10 AWG feeds now enter through the spar's own bore. The root flange is a bonded PART, not printed hull, and measurement decided it: ray-casting the envelope on a 13x17 grid (221/221 hits) shows the sidewall skin moving 34.3 mm (port) / 37.0 mm (stbd) across the 80x60 footprint. Filling to a plane makes it 34 mm thick; bounding it with a plane leaves that plane tangent to the skin (measured: a 0.46 mm non-manifold edge, 4 incident faces, plus a sliver body). Cut locally instead, in its own generator. Tilt actuator (WA-R15) -- multi-turn, per owner direction - DS3225 body + LibreServo_v4, rotation-limit pin removed, run continuous rotation and closed on the AK7455. Same body, so the Rev S1d pad footprint, bolt pattern and 60 g mass carry over; the mode, position and stage are new. - Coaxial direct drive does NOT fit: the body overlaps the O30.1 socket boss by 13.5 mm in Y at either output-shaft orientation. Fuselage spur pair instead, m 0.8, 38T/38T, C 30.40, 1:1 -- both axes are along hull X so no right-angle stage is needed. C is set by the landing-gear bay tops, not chosen. - 1:1 deliberately: a step-up would trade the 48x torque surplus for slew rate but pull the actuator back to 260 deg, re-opening the question Rev T1 closed. - The gear plane is forced 11 mm inboard of X -100/-240 by the root tenon -- no gear that can transmit at C = 30.40 clears it in Y -- which costs the actuator an 18 mm standoff and 18 mm/side of cargo-bay roof reach. Control (docs/TILT_DRIVE_CONTROL_SPEC.md, new) Cascade: LibreServo_v4 closes the actuator on its own absolute encoder; Pilot closes the nacelle on the AK7455. Sensors, sign conventions, spans, fail states, and the bench programme that would produce a plant model. No gains: the plant is not identified, and dead time is unmeasured. Two findings worth naming -- the train is NOT self-locking and has no holding provision (TILT-CTL-01), and differential tilt needs a trip that is architecturally separate from both position loops (TILT-CTL-02). Tool defects found while the geometry was being fixed (they were masked by it) - wing_root_deconflict.py tenon_params() matched only "two_rod", so the Rev T1 default path fell through to the enlarged 30 mm tenon and reported an 8.60 mm/side mortise foul against a correctly-sized mortise. - The spar corridor is stepped (O20.4 outboard, O16.3 inboard) and was swept at one diameter, reading the intended annulus as "wall not cut". - Every route was probed 12 mm past the wall bracket, correct for a shaft and wrong for a wire. - cargo_bay_envelope.py derived spar OD with the retired 0.15 mm/side rotating clearance and called it a "rotating tilt-spar". - merge_cargo_interior.py finalize_watertight() dropped sliver bodies before closing slits, so a fresh 2-face zero-area body reached the published STL. Mass: +77.0 g (+0.170 lbm), +1.97 % of AUW. Hover T/W was ~1.19 against a 1.2 minimum, so this is tracked as a blocker (WA-R18), not absorbed. Gates: wing_root_deconflict, wing_internal_clearance, wing_airfoil_integrity, wing_spar_carrythrough, spar_bundle_fit, cargo_bay_envelope, landing_gear_wing_clearance --proud, validate_stls, precommit_index --check -- all green. Cargo shell regenerated: watertight, 1 body, 0 boundary and 0 non-manifold edges, CI_valid. Analysis and implementation by Claude (Claude Opus 5, Anthropic) under the author's direction, per AGENTS.md §3 "Attribution and Licensing". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…d auditability Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ass errors The audit was asked for as a lightening exercise. The lightening is real but small; the bookkeeping error is large, so it leads. BOM vs mesh -- 23 PRINT-* rows measured against the STL they name The BOM understates printed mass by +521.6 g, 13.3 % of the 3,911 g AUW. Worst rows: PRINT-CARGO-SECT +207.2, PRINT-BATT-TRAY +118.2, PRINT-HEAD-SHELL +94.6, PRINT-CARGO-CRADLE +62.6, PRINT-MIDDLE-CANONICAL +55.9. Three are corrected here; the rest are measured and reported for their owning branches rather than edited across a governance boundary. Corrected - PRINT-CARGO-SECT 165 -> 372 g. NOT a Rev T1c regression: the pre-Rev-T1c shell already measured 316 g against the same row. It predates the Rev R6 landing-gear bay features, the actuator pads, the O30.1 sockets and the CF thwart pockets. - FOAM-PU-2LB 900 -> 22 g. 900 g was the KIT mass, not installed foam. The row's own note says ~0.7 L mixed fill, which at 2 lb/ft^3 is 22.4 g. Independently bounded: the cargo section's enclosed cavity is 3.183 L, less the 2.135 L cargo bay (explicitly not foamed) = 1.048 L foamable = 33.6 g before the EPS void formers displace any of it. - PRINT-WING-ROOT-FLANGE 12.7 -> 25.6 g/ea. Our own error at Rev T1c: costed as RHO_SOLID x 40 % infill. At 5 mm thick with 4 perimeters at 0.6 mm the plate is 4.8 mm of wall and 0.2 mm of infill -- essentially solid. RHO_PRINT is a BULK figure and must not be re-derived as RHO_SOLID x infill. That last correction revises Rev T1c from +77.0 g to +102.8 g (+2.63 % AUW). Where the cargo-section mass is Base shell 389.0 g before features; 372.2 g as built (the duct, aperture and mating-face cuts take out more than the bosses add). The two actuator pads are 109.5 g -- 29 % of the shell and the heaviest discretionary feature on it. Lightening - Actuator standoffs: 109.5 g of solid block reacting a 5.0 N worst-case combined load (3.47 N gear separation + 3.53 N actuator inertia at 4g x 1.5). The governing mode is mesh opening, not strength: cantilever deflection is 1.4e-5 mm solid, 2.5e-5 mm hollow, 9.5e-5 mm on four posts, against a 0.05 mm centre-distance budget. Hollowing to a 2.5 mm wall saves 32.9 g with no structural question. Rejected: shrinking NSVMT_STANDOFF (11 + 6 + 1, all accounted) and thinning the 6 mm gear face (already 7.5 x module). - Wing roots: nothing to take. The spanwise distribution is a clean taper with no local pile-up, WALL_T 2.5 is four perimeters at 0.6 (the floor), and THICKNESS_SCALE 1.46 is the solved figure leaving 1.19 mm of skin over the O20.4 bore against a 1.16 mm floor. The 33.7 g the retired tie rods gave back is the whole of what this structure had. Also noted: summing the BOM mass column returns 12.7 kg, which is the mass of nothing -- it mixes installed hardware, consumable stock and ground equipment. An Installed flag is needed before it can back a weight statement. Analysis by Claude (Claude Opus 5, Anthropic) under the author's direction, per AGENTS.md SS3 "Attribution and Licensing". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… carried mass Follows docs/MASS_AUDIT_CARGO_WING_ROOT.md. Eight units, ranked by measured mass, each with the check that gates it. The ranking has an uncomfortable shape and the plan says so up front: the single largest lever is not structural. BATT-6S-4000 is 750 g -- 19 % of AUW and the heaviest item on the aircraft -- and BATT-6S-2800 is 225 g lighter, more than every printed-part optimisation in the plan combined. That is a mission trade, not an engineering one, so the plan sizes it and leaves the call to the owner. W2 (BOM reconciliation) gates everything else, because the BOM understates printed mass by +521.6 g and shaving 30 g off a part whose row is 118 g wrong is decoration, not weight reduction. Targets, measured: - W3 battery-tray floor pocket, -23.1 g. FLOOR = 8.5 mm is NOT a strength figure -- the SCAD says it is set by RAIL_D = 6.5 so the slot does not breach the cavity. That constraint exists only at the rails. At 3.0 mm the floor is FOS 55 at limit and FOS 25 at 9 g x 1.5 against 77 MPa flexural (REF-MAT-002), deflecting 0.045 mm on a 56 mm span under a 750 g pack. - W4 hollow the actuator standoffs, -32.9 g. Governing mode is gear-mesh deflection, not strength: 2.5e-5 mm against a 0.05 mm centre-distance budget. - W5 cargo cradle windowed frame, ~-25 g. The cradle is NOT over-thick -- it is already 2.5 mm walls; it is a fully-closed 110 x 80 x 60 box for a 250 g payload. Medium confidence, because the auto-latch works by flex-tab compliance and that snap force is uncharacterised, so the tabs and the rim within 10 mm of them are exclusion zones. - W6 nacelle pod STL identity. PRINT-NACELLE-PORT/STBD name an STL that no longer exists (the s_ prefix was dropped); the two candidates measure 278 g and 658 g against a 132 g row. Listed as a target because the answer could make it the largest one and invert the ranking (RISK-3). - W7 landing-gear bay bosses, 126 g raw, unquantified -- assume nothing is free until the bolt bearing check is redone. - W8 wing root CLOSED, recorded so it is not re-litigated: clean taper with no local pile-up, WALL_T 2.5 is the 4-perimeter floor, and THICKNESS_SCALE 1.46 is the solved value leaving 1.19 mm of skin over the bore against 1.16. Also states three rules the audit learned the hard way: RHO_PRINT is a bulk figure and must not be re-derived as RHO_SOLID x infill; consumable stock is not installed mass; and bounding-box fill fraction is a signal, not an answer -- the wing and the tray look alike in that column and are entirely different findings. Analysis by Claude (Claude Opus 5, Anthropic) under the author's direction, per AGENTS.md SS3 "Attribution and Licensing". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
| mode 5 MPa was written to bound -- so this socket is very likely far more | ||
| conservative than it looks. It is NOT re-based here: overturning a | ||
| standing repo allowable is an owner decision gated on the LG-11 coupon | ||
| (root TODO SS1.1.4), not a side effect of a geometry change. The sweep |
The local .venv is 351 MB of third-party packages and has never been tracked, so this is a guard rather than a cleanup — but the guard matters more than it looks. .github/workflows/ci.yml runs flake8 with an explicit --exclude list that does NOT name .venv. Lint passes today only because CI checks out a fresh tree with no virtualenv in it; a single `git add -A` from a working copy would commit one and the lint job would fail immediately on thousands of findings in vendored code. Cheaper to ignore the directory than to grow the exclude list. Also records, where someone will actually see it, that this .venv SHADOWS system Python packages several tools depend on (manifold3d, sympy, matplotlib are installed system-wide) -- hence the /usr/bin/python3 invocation used throughout the tooling docs. venv/, env/ and ENV/ are covered too. Verified no tracked path at any depth matches them (0 files), and the tracked-but-ignored count is unchanged at 9 -- all of those come from the pre-existing *.pre-g351x and named-file rules, none from this change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Stab-Rabbit-coding
deleted the
claude/serenity-wing-nacelle-validation-kvux9w
branch
August 31, 2026 00:48
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This branch carries both halves of Rev T1, in the order they happened.
shaft and becomes a fixed 20 × 16.3 mm CF tube bonded into the wing over its
full span — the wing's primary bending member. Everything below is a
consequence of that. (8 commits, §0.)
WING_SPAR_Y = +38.15andWING_SPAR_BORE_D = 8.3, sotools/wing_root_deconflict.pyfailed on three findings that were all that one fact.0 — The wing half (Rev T1 / T1b)
The four 10 AWG ESC feeds had no viable path to the nacelles: they do not fit the
wing's Ø7 conduits, and those conduits sit 17.65 mm forward of the tilt axis, so
every transition dragged the harness through a ~45 mm arc.
A bearing transmits shear, not moment, so the Rev R2 rotating spar was
structurally incapable of reacting the wing-root moment — which is why both
previous root designs (enlarged tenon FOS 0.49, two-rod couple FOS 4.14) existed
only to work around it. A fixed bonded spar carries it directly, and the couple
arm goes from 48 mm of chordwise rod spacing to the full 86.7 mm span.
THICKNESS_SCALETHICKNESS_SCALE_TIPTENON_LOAD_PATH = "spar_carrythrough"; tie rods retiredBore inventory, all constant-mm so taper cannot erode the webs: 8.0 Ø3.2 nav ·
28.0 Ø20.4 spar (now carrying the 4 × 10 AWG on the tilt axis) · 44.5 Ø6.5
AK7455 · 53.6 Ø4.4 drive shaft. The 2 × Ø7 double-D is retired — it could not
carry two 10 AWG conductors at any realistic wire OD, and its 27.5 mm station now
falls inside the spar bore.
Three owner directives that invalidated built geometry
reached 15 mm inside the duct wall. The spar runs along local X at Y = 0,
so it clears only if it terminates at |X| ≥ 26 → max 15.7, built 15.0.
It had been budgeted outward from the bearing stack and never checked against
the duct — the same class of error as the Rev R2 through-duct spar this
revision exists to remove. The nacelle's bearing pair, ring gear and ring
magnet must now all fit inside 15 mm.
only 18.67 mm exists before the bay, where it gives FOS 0.51 on moment,
and capacity goes as 1/L². Splitting the joint by load type instead — socket
for shear, bonded 80 × 60 flange for moment — lands FOS 29.2 against the
4.02 the long socket gave. The constraint produced a better joint, and the
bay is untouched.
reduction and dissolves an "impossible ring gear" finding that was only
true under the step-up reading a limited-rotation servo forces. Built 14T/50T
module 0.8, i = 3.571, C = 25.6 → station 53.6. It voids the 180°/270°
question and makes the encoder load-bearing for control, not telemetry.
The airfoil is no longer an S1223 — and is now described as such
Re-derived from the tabulated UIUC coordinates (REF-CAD-006) at 1/20000 chord,
not quoted. The built sections are designated S1223/t17.7 (root) and
S1223/t26.7 (tip): S1223's camber line with the thickness envelope scaled
×1.46 / ×2.20.
The previous header's chordwise locations were wrong — "22.6 %" and "39.4 %"
against a true 19.8 % and 49.0 %, which match the published S1223
characterisation exactly and were never traceable to the coordinate table the
file actually builds from.
Stated per claim rather than as a blanket disclaimer: camber (8.67 % at 49.0 %)
is exact; zero-lift angle and lift-curve slope partially survive at the
root only, on thin-airfoil grounds — that theory depends on the camber line
alone, which is why preserving it matters, but 26.71 % t/c is far outside
"thin"; CL_max, L/D and the 7.6 N cruise-lift figure do not survive.
docs/flight_envelope.mdnow carries a banner saying every aerodynamic result init rests on an input that no longer describes the aircraft. LE radius goes as
t_scale²— the tip's nose is 12 % of its own chord.Errors found and corrected rather than propagated
wing_tip_spar_through_bore()carriedrotate([0,90,0])and was cutting achordwise hole. Harmless at Ø8.3 — the module's real job was simply never
done — but a 20 mm gash at Ø20.4.
returns a ring gear smaller than the spar it encircles.
wing_airfoil_integrity.pyvalidated only thet_scale = 1.0table and neverread either thickness scale — it would have passed identically at 2.20, so it
was not covering the risk it was cited for. Now validates the sections
wing_solid()actually lofts.restructure → §23.2230 (new
REF-FAA-004, verified verbatim from GovInfoCFR XML; eCFR bot-blocks automated retrieval).
§23.2265 requires a special factor for parts with manufacturing-process
variability — exactly FDM-printed CF-PETG. The requirement is now cited; the
numeric value stays the project's own choice.
current Part 23 and must not be cited to it.
New:
docs/WING_ATTACH_INTERFACE.md— the single spec for both joints, with aWA-R1…R15 requirement register;
tools/spar_bundle_fit.py;REF-MATH-001(Melissen 1997) for the exact circle-packing ratios, because the n = 4 case
decided a load-bearing geometry change and the wrong constant (11.0 mm) had
already propagated through two independent documents by being carried in prose
instead of computed.
Unverified, and the FOS numbers should not be read as cleared: the 10 AWG
wire OD is assumed at 5.5 mm (
bom_revS.csvrecords none, and the wholeØ20.4 bore chain derives from it), and no ASTM D3039/D695 certificate exists for
any CF stock — the 300 MPa spar allowable is a conservative stand-in.
Aerodynamic content produced with the
aeronautical-engineeringskill, whichcarries a standing ENGINEERING REVIEW REQUIRED notice: these are computed
geometric properties and an explicit statement of what is not known, not a
performance substantiation.
1 — Fuselage wing-root joint (WA-R1/R1b/R2/R4/R6)
airframe/blender-scripts/merge_cargo_interior.pynow matches the Rev T1 wing:The root flange turned out not to be printable hull material, and measurement is what decided it. Ray-casting the envelope on a 13 × 17 grid (221/221 hits) shows the sidewall skin moving 34.3 mm (port) / 37.0 mm (stbd) of hull X across the 80 × 60 footprint. Filling to a plane gives a 34 mm slab; bounding with a plane leaves that plane tangent to the skin (measured: a 0.46 mm non-manifold edge with 4 incident faces, plus a sliver body). Subtracting a translated envelope from the full 900k-face shell was worse still. Cut locally, in its own generator, it is clean.
New:
airframe/stls/fuselage/generate_wing_root_flange.py→ 24.3 / 24.4 cm³, both watertight single bodies.2 — Multi-turn tilt actuator (WA-R15)
DS3225 body + LibreServo_v4, rotation-limit pin removed, run continuous-rotation and closed on the AK7455 — the architecture the cargo winch already uses. Same body, so the Rev S1d pad footprint, bolt pattern and 60 g mass all carry over.
Three things were forced, not chosen:
The stage is 1:1 deliberately: a step-up would trade the 48× torque surplus for slew rate but pull the actuator back to 260°, re-opening the 180-vs-270 question Rev T1 exists to close.
Control spec —
docs/TILT_DRIVE_CONTROL_SPEC.md(new)Cascade: LibreServo_v4 closes the actuator on its own absolute encoder; Pilot closes the nacelle on the AK7455. Sensors, sign conventions, spans, fail states, and the bench programme that would produce a plant model.
No gains, and the document says why — the plant is not identified and dead time is unmeasured. Two findings worth naming:
TILT-CTL-01/WA-R16— flight-release blocker.TILT-CTL-02.3 — Weight audit —
docs/MASS_AUDIT_CARGO_WING_ROOT.md(new)All 23
PRINT-*rows whose description names an existing STL were measured. The BOM understates by +521.6 g.PRINT-CARGO-SECTPRINT-BATT-TRAYPRINT-HEAD-SHELLPRINT-CARGO-CRADLEPRINT-MIDDLE-CANONICALThe cargo-section row is not a Rev T1c regression — the pre-T1c shell already measured 316 g against that same 165 g row. Three rows corrected here; the rest measured and reported for their owning branches rather than edited across a governance boundary.
Foam and voids: cargo-section enclosed cavity 3.183 L, less the 2.135 L cargo bay (which the BOM itself says is not foamed) = 1.048 L foamable → 33.6 g, an upper bound before EPS void formers displace any of it.
FOAM-PU-2LBcarried 900 g — the A+B kit mass. Its own note says "~0.7 L mixed fill", which at 2 lb/ft³ is 22.4 g. Corrected; procurement quantity unchanged.Correction to our own Rev T1c figure
Rev T1c is +102.8 g (+2.63 % AUW), not the +77.0 g first recorded. The root flange was costed as
RHO_SOLID × 40 % infill. That is the wrong model: at 5 mm thick with 4 perimeters at 0.6 mm the plate is 4.8 mm of wall and 0.2 mm of infill — essentially solid.RHO_PRINTis a bulk figure and must not be re-derived that way.4 — Weight-reduction plan —
docs/plans/2026-08-30-001-...(new)Eight ranked units. The largest lever is not structural:
BATT-6S-4000is 750 g — 19 % of AUW — and the 2800 mAh pack is 225 g lighter, more than every printed-part optimisation combined. Sized here; the call is the owner's.RAIL_D = 6.5so the slot does not breach the cavity. At 3.0 mm it is FOS 55 at limit and FOS 25 at 9 g × 1.5 against 77 MPa flexural, deflecting 0.045 mm under a 750 g pack.PRINT-NACELLE-PORT/STBDname an STL that no longer exists; the two candidates measure 278 g and 658 g against a 132 g row.Tool defects found while the geometry was being fixed
The gate had been red "by design" for one known cause, which meant its other checks were unexercised. Four real defects surfaced:
tenon_params()matched only"two_rod", so the Rev T1 default path fell through to the enlarged 30 mm tenon and reported an 8.60 mm/side mortise foul against a correctly-sized mortise.cargo_bay_envelope.pyderived spar OD with the retired 0.15 mm/side rotating clearance and called a fixed bonded tube a "rotating tilt-spar".merge_cargo_interior.pyfinalize_watertight()dropped sliver bodies before closing slits, so a fresh 2-face zero-area body reached the published STL.Verification
Cargo shell regenerated: watertight, 1 body, 0 boundary and 0 non-manifold edges, CI-valid.
Known blockers carried out of this PR
WA-R16/TILT-CTL-01WA-R18MA-1WA-R17WA-R15aTILT-CTL-02..06Nacelle side (WA-R7…R12) is unchanged and still specification-only.
Analysis and implementation by Claude (Claude Opus 5, Anthropic) under the author's direction, per
AGENTS.md§3 "Attribution and Licensing".🤖 Generated with Claude Code