Legs - #190
Merged
Merged
Conversation
Cite REF-CAD-006, retiring the self-intersecting hand-typed table (WING-01: thickness went negative from x/c ~0.742, outline crossed into a bowtie). wing_airfoil_integrity.py checks 1/2 now PASS.
…KTD4) hull() convexified the corrected S1223 section by 1.612x (real reflexed lower surface aft of ~65% chord), over the integrity gate's 1.10x tolerance. Replace with a manual polyhedron() built from s1223_scaled_pts() at root/tip -- same point list/order the 2D outline check already validates, so the built cross-section matches the tabulated airfoil exactly instead of its convex hull. Side walls are explicitly triangulated (not left as quads): root/tip outlines differ enough that the quad isn't planar, and OpenSCAD's own nonplanar-quad fallback produced a non-watertight mesh (Volumes: 3, trimesh is_watertight=False). Explicit diagonal split fixes it (Volumes: 2, watertight, 1 body). wing_airfoil_integrity.py check 3 read wing_solid()'s own source instead of assuming hull(), so it verifies whichever loft method is actually in use rather than going stale the next time this changes.
…-01/02) Replace the full-span Ø12.3mm clearance bore (retired 12mm CF tube era) with a per-side bearing seat sized to F688ZZ (REF-SENSOR-019) that terminates at the fuselage wall, matching SPAR-01's overhung-shaft architecture. WING_SPAR_BOSS_OD re-derived from the bearing's actual flange OD (27.7mm); WING_SPAR_BORE_D corrected 12.3 -> 8.3mm. cargo_bay_envelope.py's payload gate is rewritten: the old model measured clearance around a spar crossing the bay, which is no longer physically true, so it now measures the real interior envelope off the published mesh. PASSes: 101.6x76.2x76.2mm payload fits (CARGO-01). CF-TUBE-12MM marked SUPERSEDED in the BOM (qty 0, retained for traceability); SPAR-TILT-4130 is the single active spar BOM row.
…onflict.py Port and stbd rows both printed the placeholder (-270.0, -70.0), matching neither side's actual sweep. The xcyl() calls beneath them already used the real per-side bounds; only the human-readable label was wrong.
…U5/KTD1) CARGO-03c found the tenon under-strength as a structural joint (10.14 MPa bearing vs. the repo's only CF-PETG figure, 5 MPa bond-limited, FOS 0.49). A single fallback rod (matching the main spar's convention) doesn't work either: an aft rod at the forward rod's Ø8.2mm doesn't fit anywhere aft of the main spar bore (aft edge 49.30mm) before the Hall conduit's fixed 52.25-55.75mm span, and every station past that breaks the repo's 1.16mm minimum-wall floor by x=60mm. Settle on an asymmetric two-rod couple instead: Ø8.2mm forward (14mm from LE, unchanged) + Ø6.2mm aft (62mm from LE, root-only embed -- the tip section can't take it). Pure two-pin statics gives equal-magnitude forces independent of rod position (the main spar rides in a clearance bore here and reacts no moment about this axis) -- 304.3 N ultimate at each rod, clearing the cited 5 MPa bond-limited CF-PETG allowable at FOS 5.26 (fwd) and 4.14 (aft, embed bumped 40->42mm to clear). No new coupon data needed. The tenon is traded out of the load path entirely -- fuselage_root_tab() reverts to its original locating/index-only role (smaller W/L, same H to keep reaching real material), gated behind TENON_LOAD_PATH="two_rod" (default) vs "enlarged_tenon" (coupon-gated alternative, kept but unbuilt). Mass: CF-ROD-8MM + CF-ROD-6MM pairs add ~22g total vs. the ~48g the original steel-rod estimate carried. Fuselage-side wall bosses mirror the main spar boss's embed pattern (merge_cargo_interior.py); the forward boss's embed is bumped 40->41mm to avoid a non-manifold seam from an exact end-cap coincidence with the main spar boss. Re-merged shell verified watertight, 1 body.
ce-compound-refresh discoverability check: nothing in the root instructions told an agent the solutions store exists. One-line pointer in §10 Workflow, alongside the existing REFERENCES.md/TODO.md guidance.
… drift (U6) Re-render/re-bake wing_port_s1223_revo.stl and wing_stbd_s1223_revo.stl against the U1-corrected S1223 table, the true-loft wing_solid(), the F688ZZ bearing seat, and the U5 tie-rod bores. Root-caused the carried-forward wing_root_deconflict.py findings (published shell blocking the EDF/Hall/nav-light conduits, stbd spar bore not penetrating the bulkhead): merge_cargo_interior.py's camber- midline constants (WING_SPAR_MIDLINE, WING_EDF_MIDLINE_FWD/AFT, WING_ENC_MIDLINE) were hand-copied snapshots taken against the pre-U1 airfoil table and never refreshed, so the cargo shell cut its harness ports and spar bore up to 1.3mm off the wing's actual conduit centerlines. Replaced with _wing_midline_mm(), which parses the live SCAD table via wing_spar_station_fit -- this class of drift is now structurally impossible. Also fixed: nav-light wire exit was never cut on the stbd side past the spar boss's inboard tip (the wire rides loose in the spar's hollow ID past where the rotating tube itself ends); THICKNESS_SCALE_TIP 1.45->1.56, re-derived against the corrected airfoil (the old figure was calibrated against the broken table and left the tip wall at 0.82mm, below the 1.16mm floor). Two tool tolerances raised to documented, still-conservative floors after real U5 rod-boss/aperture tangencies (0.0033mm^3) and post-rebake float32 round-trip noise (~1e-5mm^3) tripped bare-zero thresholds: wing_root_deconflict.py BOOL_NOISE_TOL=1.0mm^3 (reusing the tool's own existing bulkhead-check tolerance), landing_gear_wing_clearance.py EPS_MM3 1e-3->1e-2mm^3 -- both 2-4 orders of magnitude below the smallest real defect either tool has found. wing_root_deconflict.py: CLEAR. wing_internal_clearance.py: PASS. wing_spar_carrythrough.py: fwd rod FOS 5.26, aft FOS 4.14. validate_stls.py: 62/62 watertight. cargo_bay_envelope.py: PASS.
…2 citation (SPAR-02, U7) The cited >=25 kgf.cm tilt-servo requirement was a spec pick (serenity-rev-r.jsx L383), not a load derivation, and DS3225 only cleared it to 98% (24.5 kgf.cm @ 6.8V). Re-derived from aero+inertia only per TILT_SPAR_ANALYSIS.md SS2's stated pivot-at-CG geometry: - Gravity term nulled by construction (PIVOT_Z set equal to the computed nacelle-assembly CG_Z); transverse offset bounded at <=0.019 kgf.cm from the two known off-axis parts, not claimed exact. - Inertia term ~1.78 kgf.cm from the mass table + the repo's only tilt-timing figure, at the existing 4g/1.5x ultimate convention. - Aero term: no nacelle Cd/frontal-area data exists in the repo -- left as an explicit open item, not assumed zero. Grounded total ~1.80 kgf.cm, 7.3% of DS3225's 24.5 kgf.cm. DS3225 stands; no servo change. Bench verification remains open (TODO SS0.8). Found and fixed a citation error along the way: "RAIL-2" was being conflated with the nacelle-tilt servo rail in WBS.md/REFERENCES.md. RAIL-2 (5V_OBS, POWER_DISTRIBUTION.md SS3.2.1/SS11.1) is actually the Observer-board/cargo-winch-servo rail and is unaffected by the DS3225 swap. The real tilt-servo rail is the 6V servo bus (SS3.3), now resized 1.5A -> 2.3A/servo -- this pushes the all-servo simultaneous-stall total to 8.8A, which exceeds the existing 6V BEC's 7A burst rating, flagged as a new finding for owner attention.
…ation Batista, Lagomazzini, Ramirez-Pena & Vazquez-Martinez, "Mechanical and Tribological Performance of Carbon Fiber-Reinforced PETG for FFF Applications," Appl. Sci. 2023, 13(23), 12701 (DOI 10.3390/app132312701, CC BY 4.0). ASTM D638 tensile / D695 compressive tests on 20% short-CF PETG vs. unreinforced PETG, FFF-printed. Measured: tensile strength 39.23 vs 48.41 MPa (CF REDUCES tensile strength -- short-fiber pull-out/cohesion loss), compressive strength ~47-60 MPa (CF improves compression). No bearing (ASTM D953) or interlaminar-shear/fusion test in this study, so it does not directly supply the bearing/fusion allowable CARGO-03c's enlarged-tenon alternative still needs -- it's the first real bulk-compressive data point this repo has ever cited for CF-PETG, an order of magnitude above the previous ~5 MPa bond-limited placeholder, without silently substituting bulk compression for the bearing mode that actually governs a tenon in a slot. Cross-referenced from docs/structural_analysis.md SS7.3 (the placeholder's first use) and the CARGO-03c "requires verification" row in REFERENCES.md and airframe/fuselage-mid/WBS.md -- the built two_rod default path already clears FOS 4.0 against the existing placeholder and needs nothing from this citation to stay closed; it only bears on whether the coupon-gated enlarged_tenon alternative is worth revisiting.
…G-01/CARGO-01/02) Implements U4 of docs/plans/2026-08-24-001-fix-wing-repair-root-joint-plan.md, the one unit left unbuilt from the plan: two CF-PLATE-2MM locating-groove pockets (fore Y-40, aft Y+118) replace the retired cargo Y=+30 ring as the SPAR-01 couple closure -- that ring's own bottom chord was cut away by the clamshell aperture and never actually closed anything. Gated off via RING_Y30_ENABLED=False (kept documented, not deleted) in merge_cargo_interior.py; grooves added to add_structural_features.py RING_POCKETS following the existing ring-frame pattern exactly. Extends wing_root_deconflict.py with an explicit probe for the U5 two-rod tie-rod bores (previously unmodeled), using each rod's own fuselage-side embed span rather than the wider main-spar span. Closes out U8: WING-01, SPAR-01, CARGO-01, CARGO-02 all verified against final re-merged geometry and checked off in WBS.md (root + wings-nacelles + fuselage-mid); corresponding TODO.md lines removed. Updates docs/structural_analysis.md SS5 and docs/TILT_SPAR_ANALYSIS.md SS1/SS3.2 to describe the two-independent-spar/two-servo/wall-bearing mechanism instead of the superseded single-spar/cargo-bay-servo one. bom_revS.csv CF-PLATE-2MM row updated to the 3-station config. Full R9 gate sweep passes clean on final geometry: wing_airfoil_integrity, wing_internal_clearance, wing_root_deconflict, wing_spar_carrythrough, cargo_bay_envelope, landing_gear_wing_clearance --proud (4/4; LG-25 proud- material finding tracked separately, not blocking), validate_stls (62/62). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Owner-selected option 1 for LG-25: the U5 fwd wing-root tie-rod boss (ROD_FWD_BOSS_OD 17.9mm) stood up to 12.0mm proud of the fore landing-gear bay's flange-rebate pocket (5mm deep) at both fore corners, since lg_bay_features() protects wing keep-outs from the bay's own cuts. Adds a stepped boss (two booleaned cylinders, no new taper primitive needed): full 17.9mm OD along most of the embed, stepped down to a reduced OD for the last 25mm nearest each side's *_INB end -- the actual overlap station, found by direct measurement, not the *_OUTB/wall-facing end a first read of the canted bay plate frame would suggest. The needed OD was tuned empirically against tools/landing_gear_wing_clearance.py --proud: a partial reduction (12.0mm) cut interference volume by >50% but left the same 12.0mm depth reading (the rod's own bore must run continuously through the station, so any nonzero boss radius reaching that deep keeps reporting it); 10.6mm -- radial margin 1.2mm over the 8.2mm bore, at this repo's own 1.16mm minimum-wall figure plus a hair -- clears it fully: "none -- the rebate shaves the whole footprint". Full R9 gate sweep re-verified clean: wing_root_deconflict (incl. the new tie-rod bore probe), wing_spar_carrythrough (fwd rod FOS unaffected -- the bearing check uses the rod's own diameter/embed, not the boss OD), cargo_bay_envelope, landing_gear_wing_clearance --proud (0mm proud, 4/4 CLEAR), validate_stls (62/62 watertight). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…tput serenity_assembly.py now owns airframe/freecad/assembly/SerenityAssembly.FCStd directly (OUTPUT retargeted from the separate Serenity-Assembled.FCStd). That file was a hand-built, manually-placed reference with 17 objects, several stale/duplicated across revisions (both the current nacelle_port_revs and the superseded nacelle_port_revq were present, at overlapping positions). This script already imports every current canonical STL with validated or explicitly-marked-VERIFY hull-frame placements; running it now regenerates that file cleanly (34 objects, zero missing STLs). Old content is preserved in the pre-existing .FCBak/.FCStd.bak2 files alongside it (the FCStd itself is gitignored, never tracked). Adds a NACELLE TILT CONFIGURATION block: NACELLE_TILT_PORT_DEG / NACELLE_TILT_STBD_DEG (0 = forward/cruise, 90 = vertical/hover) drive a rigid per-side rotation about that nacelle's own pivot (hull +X axis, through the CG/pivot station already used elsewhere in this script). The nacelle body, EDF stator sleeve, EDF aft spider sleeve, and nozzle iris all move together as one group, since they're rigidly attached to the nacelle. The rotation sign was reverse-engineered from the pre-existing hand-built file's own Nacelle_Stbd placement (axis (-1,0,0), angle 90 deg) rather than assumed, so the script's default (port 0 deg / stbd 90 deg) reproduces that file's port-forward/stbd-vertical configuration. Verified via bounding-box comparison: the stbd nacelle body, stator sleeve, and nozzle iris all show their long/short axes swapped between hull Y and Z relative to the untilted port side -- confirming the rotation is a true 90 deg tilt, not a no-op or double-application. PIVOT_Z and the other nacelle Z-station constants are hoisted from assemble() to module level so the new tilt helpers can use them. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Answers a direct question: no, petal state was not reflected in the assembly -- every nacelle always imported the single, no-suffix nacelle_nozzle_iris.stl (petals closed), regardless of that side's configured tilt. Investigating turned up that this file itself is stale: it's a 2026-07-19 render, three weeks before the Rev T3 flap-shingle fix (2026-08-09, airframe/wings-nacelles/WBS.md SS1.1.3.1) that split the combined asm preview into two committed, name-suffixed endpoint renders and exposed FLAP_PHI so each is reproducible from source. serenity_assembly.py: added nozzle_iris_stl(side), which picks nacelle_nozzle_iris-closed.stl (FLAP_PHI=PHI_CLOSED) below a 45 deg threshold and nacelle_nozzle_iris-open.stl (FLAP_PHI=PHI_OPEN) above it, keyed off each side's NACELLE_TILT_*_DEG. This is a binary endpoint selection, not a continuous interpolation -- documented in the docstring, since an arbitrary intermediate tilt would need a fresh openscad render at a computed FLAP_PHI, which this script does not invoke. Makefile: NACELLE_STLS and its build rules were also still targeting the stale bare filename, and never built nacelle_nozzle_flap_seal.stl (the Rev T3 seal flap) at all. Replaced with rules for -closed.stl/-open.stl (via FLAP_PHI) and flap_seal.stl (via RENDER_PART); also fixed OUTPUT to match the script's R1.3 retarget (SerenityAssembly.FCStd, not the old Serenity-Assembled.FCStd). Verified both committed STLs are still exactly reproducible from the current SCAD (identical face count and volume to float precision) before relying on them, and confirmed the regenerated assembly picks the correct mesh per side (port/0deg -> 25,308-facet closed mesh, stbd/90deg -> 27,396-facet open mesh). Logged, not fixed (out of scope for this task): serenity_render_views.py (a separate Blender preview-render pipeline) still references the stale bare filename. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… open Investigates a report that airframe/freecad/assembly/SerenityAssembly.FCStd "doesn't open" with "the mesh data structure has some defects" (x10 in the GUI). Confirmed the document does open underneath the warnings (headless via freecadcmd, and with Gui active under xvfb-run: all 34 view providers created, no exception) -- but traced the warnings to 5 real, pre-existing mesh defects (2 objects x 2 files + 1 fin), not a false alarm. edf_stator_sleeve.stl / edf_aft_spider_sleeve.stl: each carries a main sleeve body plus 3-4 small keying-tab bodies that touch it at exactly coincident vertices (measured min distance 0.0) but were never welded into one shell on STL export, leaving locally overlapping/non-manifold facets at the seams -- already logged as "not 2-manifold" in airframe/wings-nacelles/WBS.md but not previously root-caused or fixed. Fixed via a manifold3d boolean union of the mesh's own split bodies (the same Manifold.__add__ primitive merge_cargo_interior.py already uses): removed 12/12 duplicate seam facets per file and both are now trimesh-watertight as a whole file (each body already was individually). The tabs stay separate solids by design -- this fixes the seam overlap, not the (intentional) multi-body structure. dorsal_antenna_fin.stl: a different, worse defect -- 4 completely degenerate zero-area single-triangle fragments plus 2 of its 3 real bodies with inverted (negative-volume) winding. Fixed: dropped the degenerate fragments, corrected winding, unioned the 3 real bodies. Result is 1 body, 22 faces (was 56 across 7), fully watertight, volume matching the largest real body exactly -- the other two bodies were fully contained within its footprint (duplicate/leftover geometry, not distinct features). Flagged in WBS.md for a visual re-check before next print, since collapsing three bodies into one is a bigger change than the sleeve fix. Re-verified: freecadcmd reload of a freshly regenerated assembly reports zero "mesh data structure has some defects" warnings (was 5); all 5 previously-flagged objects now report Mesh.isSolid() == True; tools/validate_stls.py passes 61/61. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…g bug Owner-directed re-derivation of the rear CF skid-rod reinforcement (docs/structural_analysis.md SS6) against a nose-high/single-skid landing case, using the Phase 11 AUW (4,273 g) so it survives to final configuration without re-deriving again. Corrected two things SS6.2 got wrong: it computed from a stale, doubled AUW (SS2's own 2026-08-22 note already flagged this and was never acted on for SS6), and its "approx 76x23mm2" skid cross-section was never actually measured -- direct cross-sectioning of the published rear_shell24_2mm_ repaired.stl at 8mm intervals (Y=204 to 384) finds the real tube is ~24x23mm, about 3x narrower. With both corrected: the existing symmetric flat-landing case now shows FOS 5.85 (better than SS6.2 believed), but the nose-high single-skid case comes in at FOS 2.93 -- real margin, but below this repo's own 4.0 target. More consequential than the FOS number: tracking the skid tube's actual centerline continuously found the CF rod's bore is cut through the main horseshoe ring's own wall, not the discrete skid tube it's meant to reinforce -- confirmed by direct distance probe at Y=210 (inside the bore's own 173-233mm span): ring wall 2.1mm away, actual skid tube 13.2mm away, outside the bore's clearance. The rod isn't mechanically coupled to the structure it's supposed to stiffen, independent of which load case applies. Tracked as LG-26 (airframe/landing-gear/WBS.md); LG-03 closed as superseded (it assumed the channel was missing -- it exists, just in the wrong place). Checked the tensile-allowable source (REF-MAT-001) against the 3d-print- design skill's anisotropy caveat by re-reading the full paper: it has no flexural test of its own (D638 tensile / D695 compression only) and no print-orientation data for this geometry -- the FOS figures use bulk tensile strength as a bending proxy, now flagged in both REFERENCES.md and structural_analysis.md as an approximation pending a real flexural coupon. Findings only -- no rod resize or reposition applied. The fix order per LG-26 is to re-site the bore to the tube's real (curving) centerline first; a correctly-coupled rod may close most of the 2.93->4.0 gap on its own, since the current FOS assumes zero rod contribution. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…l data REF-MAT-002 (Ramachandran et al. 2026, Mechanics of Advanced Composite Structures) reports a genuine ASTM D790 three-point flexural strength for unreinforced PETG (54 MPa) -- the correct test type for the rear skid-arm bending check in docs/structural_analysis.md SS6.4, which had been using REF-MAT-001's bulk tensile strength (48.41 MPa) as a proxy pending exactly this kind of data. Updates both FOS figures accordingly (allowable moved from 48.41 to 54 MPa): symmetric flat-landing case 5.85 -> 6.53 (still PASS); nose-high single-skid case 2.93 -> 3.27 (still below the repo's 4.0 target, closer than the proxy estimate but not closing the gap). The print-orientation caveat from the original derivation is unchanged -- this source doesn't provide interlayer/ Z-axis data either, so the FOS figures remain upper bounds pending a coupon of the actual tube geometry. Propagated to REFERENCES.md (new REF-MAT-002 entry), structural_analysis.md SS6.4, the LG-26 tracking item, and the finish-airframe-components plan's U5 summary. PDF committed to avionics/datasheets/ alongside this repo's other tracked datasheets so the citation is reproducible. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…4.75 The rear skid's CF rod bore was cut through the horseshoe ring's own wall (2.1-3.5mm clearance) instead of the discrete skid tube it was meant to reinforce (13+mm away) over the entire high-moment span. Re-measured the tube's real hollow-cavity centerline continuously (middle+rear shells) and re-sited SKID_ROD_BORES; both shells regenerated and validate_stls.py 61/61 PASS, rod now sits 2.09-7.03mm from the tube wall everywhere checked. Re-running the nose-high derivation with the rod now geometrically coupled (parallel-EI split) shows the fix alone isn't enough — a solid 4mm CF rod only carries ~2-6% of the moment, so plain-PETG FOS only moves 3.27->3.47. Closing the remaining gap to the 4.0 target requires the 20% CF-PETG skin material change (FOS 4.75), whose flexural allowable now has a full 10/20/30% fiber-fraction table in REF-MAT-002 (extracted from the source paper's Table 4) — notably 10% CF-PETG is *weaker* than plain PETG. LG-03 closed as superseded (it assumed the channel was missing; it exists, just mis-sited).
A generic "CF-PETG" citation could be misread as any fiber fraction, including the weakest commonly-cited 10% blend. Locked the spec at 20% chopped carbon fiber (77 MPa / 6.67 GPa flexural, REF-MAT-002) after verifying a genuine 30%-CF retail filament does not exist — the prior 3DXTech CarbonX PETG+CF citation never published its fiber % at all, and every commercial filament checked tops out around 15-20%. Switched supplier to 3D Maker Engineering's PETG-CF Pro Series, which explicitly states 20% chopped carbon fiber on its own product page. Converted 12 remaining plain-PETG structural printed parts and clarified 27 existing generic "CF-PETG" citations to state the fraction explicitly. Excluded PRINT-GPS-RETENTION, PRINT-CARGO-WINCH-FAIRLEAD, and the nacelle flap master/seal from conversion (RF and functional reasons, documented in each row's Notes). Added a missing BOM row for dorsal_antenna_fin.stl, which had zero cost/mass tracking despite already being a real, repaired, assembly-imported part; kept on plain PETG since carbon fiber is conductive and this is an antenna support structure.
…plan New phased EMI/RF plan spans schematic capture through flight test for every RF system and EMI-sensitive subsystem; defines gate criteria and deliverables without redesigning hardware. Hardware fixes it surfaces still land in avionics/emi-hardening/WBS.md, not this plan.
…king placeholders
flake8 F541: 4 print() calls used f-strings with no {} placeholders
(pre-existing lines in a multi-line print block; the placeholder-bearing
lines around them were correctly f-strings, these weren't).
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.
No description provided.