Skip to content

Give an ObjWing back its mesh geometry, its crease and its panelling - #323

Closed
1-Bort-1 wants to merge 5 commits into
mainfrom
agent/RamAirKites.jl-43
Closed

1-Bort-1 wants to merge 5 commits into
mainfrom
agent/RamAirKites.jl-43

Conversation

@1-Bort-1

@1-Bort-1 1-Bort-1 commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

TL;DR

ObjWing returns a Wing with gamma_tip, radius, le_interp, te_interp, area_interp, inertia_tensor and T_cad_body left at their empty defaults, flying the default crease_frac rather than the one its polars were deflected about, and keeping whatever sections the geometry file holds however many panels the caller asked for. All three are v4.0.0 rebuilding it as ObjAdapter.obj_to_yaml + Wing(yaml): the YAML loader has no mesh to fill the seven fields from, and two keywords stop at the polar generation.

The seven empty fields

v3's ObjWing filled all seven itself. Since v4.0.0 a caller reading the spanwise geometry off an OBJ wing — wing.le_interp[i](gamma) is how a bridle is placed on one — hits nothing, and the wing's inertia silently falls back to point masses. ObjAdapter.seed_mesh_geometry! fills them from the mesh, reusing read_faces, center_to_com!, find_circle_center_and_radius, create_interpolations and calculate_inertia_tensor in the order v3 called them. No new geometry code.

The frame is the risk worth reading. The interpolations are built on the mesh's own coordinates, not centred on the centre of mass the way v3 built them, because that is the frame obj_to_yaml cuts its sections in. A wing whose interpolations and sections disagreed by the centre of mass would place a bridle 0.7 m off the panels it loads. The new testset asserts the two agree at the centre. center_to_com! is called on a copy of the vertices: it centres what it is given, and here only the value is wanted.

The crease and the panelling

crease_frac reached obj_to_yaml, so the polars are deflected about it, but not the Wing, which flew the 0.75 default — the YAML route (Wing(settings::VSMSettings)) already forwards it. And spanwise_distribution defaulted to UNCHANGED, which keeps the sections the geometry file carries: asking for more panels than it holds sections throws BoundsError: attempt to access 4-element Vector{Section{Float64}} at index [5] out of compute_refined_panel_mapping!. It now defaults to LINEAR, which is identical when the counts match and panels the cut when they do not.

Surprise

ObjWing accepted a path without the .obj suffix and only obj_to_yaml appended it, so the mesh was read under a different name than the one the caller passed. The suffix is now normalised in ObjWing itself.

Verification

  • Reproduced first: the new crease/panelling testset errors on unchanged code with the BoundsError above; wing.le_interp is nothing
  • test/ram_geometry/test_kite_geometry.jl red before, green after: 34/34, of which 13 are the two new testsets (juliaserver)
  • Documentation red on 1fb4224 with [:missing_docs, :cross_references]makedocs checks every docstring in the modules it is given, and seed_mesh_geometry! was in no @docs block — and green on cbfc328, which puts it on the private-functions page; docs/make.jl also runs clean locally
  • Local full suite: not run · GitHub CI on cbfc328: every check green
  • Benchmark: n/a — the added work is one read_faces and one circle fit per ObjWing call, against the NeuralFoil sweep that dominates it.
  • Risk: the LINEAR default. It changes nothing for a caller whose geometry already has n_panels + 1 sections, which is what ObjWing generates unless n_sections is passed.

Scope

+101 / −8 across 5 files. The @test_skip in test/ram_geometry/test_kite_geometry.jl said these ObjWing internals "were dropped when ObjWing was replaced by convert-then-load" and asked for the test to be rebuilt; it is, against the cached ram_air_matrix_dir() geometry, so neither new testset costs a NeuralFoil sweep.

Found by upgrading OpenSourceAWE/RamAirKites.jl to SymbolicAWEModels 0.17 (OpenSourceAWE/RamAirKites.jl#43), where SymbolicAWEModels.calc_pos — the function that places a ram-air kite's bridle along the span — throws MethodError: no method matching getindex(::Nothing, ::Int64) on wing.le_interp. That upgrade also needs OpenSourceAWE/SymbolicAWEModels.jl branch agent/RamAirKites.jl-43, which is independent of this one and green on the registered 5.1.1.

From OpenSourceAWE/RamAirKites.jl#43 · task RamAirKites.jl-43

1-Bort-1 and others added 4 commits September 14, 2026 17:55
gamma_tip, radius, le_interp, te_interp, area_interp, inertia_tensor and
T_cad_body were left at their empty defaults when ObjWing became
obj_to_yaml + Wing(yaml), so reading the spanwise geometry off an OBJ wing
hit nothing and the wing's inertia fell back to point masses.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KPJmueyiyGSNpN73BATMuH
Four unrefined sections span the kite in 1.1 m steps, which is looser than the
centre-of-mass offset the assertion is there to catch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KPJmueyiyGSNpN73BATMuH
UNCHANGED keeps the sections the geometry file carries, so asking it for 20
panels indexes past the fourth.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KPJmueyiyGSNpN73BATMuH
ObjWing kept spanwise_distribution=UNCHANGED, which keeps whatever sections the
geometry file carries, so asking for more panels than it has sections threw a
BoundsError out of compute_refined_panel_mapping!. crease_frac reached the polar
generation but not the Wing, which flew the 0.75 default instead.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012tnxXN2aT3F7zwCbsXd6Sb
@codecov

codecov Bot commented Sep 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

makedocs checks every docstring in the modules it is given, so the new one
failed the build twice over: missing from any canonical @docs block, and the
@ref to it in the Wing(yaml) docstring had nothing to point at. Its own @ref to
Wing is qualified because ObjAdapter imports the module, not the type.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@1-Bart-1 1-Bart-1 closed this Sep 15, 2026
@1-Bart-1
1-Bart-1 deleted the agent/RamAirKites.jl-43 branch September 15, 2026 06:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants