Add multi-frame orientations to SysState (Qw/Qx/Qy/Qz)#123
Conversation
Replace the single `orient` quaternion with component-major arrays Qw/Qx/Qy/Qz
(one entry per oriented frame), mirroring the X/Y/Z position layout. SysState
gains a second type parameter O (number of oriented frames); SysLog and Logger
follow.
Backwards compatibility is preserved via property views:
- `ss.orient` aliases frame 1 (mutable, so `.= ` and `= ` both work)
- `ss.orients[i]` / `ss.pos[i]` are mutable per-entity views
- `SysState{P}()`/`SysState{P}` keep working (O defaults to 1; the 1-arg form
is the `SysState{P,O} where O` UnionAll, so existing dispatch still matches)
- the StructArray/SysLog `.orient` accessor returns a per-timestep column
- `load_log` reads both new (Qw/...) and old (`orient`) Arrow logs
- `show` still displays a single `orient` line
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Round out the SysState property views on the log side: `StructArray{<:SysState}`
and `SysLog` now expose `.orients[frame][t]` and `.pos[point][t]` (lazy
per-entity time series) alongside the existing `.orient`. Fixes
`syslog.syslog.orients` erroring through the StructArray getproperty shim.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Keeping version at 0.12.0 made the workspace unresolvable: examples depends on KiteViewers, whose latest release caps KiteUtils at 0.11, so no KiteViewers version is installable against 0.12.0 — breaking both the docs and test environments (shared workspace manifest). Revert version to 0.11.8 (within KiteViewers' compat range) and mark the changelog section as unreleased; the breaking bump lands when tagging, once KiteViewers supports it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Question: Why is this a breaking release, if you added backward compatible wrappers?
JETLS gives the following warnings:
ufechner@framework:~/repos/KiteUtils/bin$ ./jetls
# Analyzed 15 files in 23.57s
# Found 2 diagnostics in 1 file (2 warnings)
# @ src/sysstate_views.jl:28,1
@inline function Base.setindex!(q::FrameQuat, v, i::Int)
field = (:Qw, :Qx, :Qy, :Qz)[i]
@inbounds getfield(q.ss, field)[q.k] = v
└──────────────────────────────────────────┘ ── no matching method found `setindex!(::Float32, ::Bool, ::Int64)`, `setindex!(::Float64, ::Bool, ::Int64)`, `setindex!(::Int16, ::Bool, ::Int64)` (3/4 union split) [warn:inference/method-error]
end
# @ src/sysstate_views.jl:28,1
@inline function Base.setindex!(q::FrameQuat, v, i::Int)
field = (:Qw, :Qx, :Qy, :Qz)[i]
@inbounds getfield(q.ss, field)[q.k] = v
└──────────────────────────────────────────┘ ── no matching method found `setindex!(::Float32, ::Any, ::Int64)`, `setindex!(::Float64, ::Any, ::Int64)`, `setindex!(::Int16, ::Any, ::Int64)` (3/4 union split) [warn:inference/method-error]
end
This section of the documentation might need an update: https://opensourceawe.github.io/KiteUtils.jl/stable/examples/#The-system-state,-type-SysState
There was a problem hiding this comment.
Pull request overview
This PR updates SysState to support multiple orientation frames by replacing the single orient quaternion field with component-major Qw/Qx/Qy/Qz arrays (one value per oriented frame), and threads the new O type parameter through logging (Logger/SysLog) and log I/O. It also introduces view types so existing .orient access remains usable (frame 1).
Changes:
- Replace
SysState’s single quaternion storage with multi-frame quaternion component arrays (Qw/Qx/Qy/Qz) and addOas a second type parameter. - Add ergonomic views for per-point positions (
.pos[i]) and per-frame orientations (.orients[k]), while keeping legacy.orient(frame 1) working. - Update log save/load paths and tests to reflect the new schema and type parameters, including back-compat loading of legacy
orientArrow logs.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| test/test-logfiles.jl | Updates schema-coupled type assertions to SysState{P,1}. |
| src/sysstate.yaml | Replaces orient with Qw/Qx/Qy/Qz component arrays parameterized by O. |
| src/sysstate_views.jl | Adds view types for .orient, .orients, and .pos, plus StructArray column views. |
| src/logger.jl | Updates Logger constructors to include O (defaulting to 1). |
| src/load_log.jl | Adds back-compat logic to load either new Qw... or legacy orient columns. |
| src/KiteUtils.jl | Wires in new view-based getproperty/setproperty! and updates SysLog typing/constructors. |
| src/build.jl | Updates generator templates for the new SysState{P,O} / Logger{P,O,Q} structure. |
| src/_sysstate.jl | Generated: updates SysState definition to SysState{P,O} and adds Qw/Qx/Qy/Qz fields. |
| src/_syslog.jl | Generated: updates syslog(logger) to build StructArray{SysState{P,O}} with quaternion components. |
| src/_show.jl | Generated: keeps a single displayed orient line via the legacy view. |
| src/_save_log.jl | Generated: resizes quaternion component vectors instead of orient_vec. |
| src/_logger.jl | Generated: updates Logger{P,O,Q} fields and preallocation vectors for quaternion components. |
| src/_log.jl | Generated: logs quaternion components (Qw..Qz) instead of orient. |
| src/_load_log.jl | Generated: updated to read Qw..Qz columns (but currently still builds StructArray{SysState{P}}). |
| src/_demo_syslog.jl | Generated: updates demo syslog creation to store Qw..Qz and accept O. |
| CHANGELOG.md | Documents the breaking change and the provided compatibility accessors. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…iteUtils.jl into sysstate-orients
|
It is breaking, things can become abstract type which is performance regression. But updating is easy, and the code will probably not error. Still, I will release it as breaking. |
* Separate out aero to component * Fix for tests * Restore speed_controlled winch flag The winch-interface refactor (#210) dropped the `speed_controlled` field, which broke the V3Kite flight-replay path that prescribes reel-out velocity from recorded CSV data. Add it back as a runtime-switchable flag: when `winch.speed_controlled` is true, `winch_acc` is forced to 0 (ignoring the winch component's `acc` output), so `D(winch_vel) = 0` and velocity is prescribed via `winch.vel`. Implemented with the registered `get_speed_controlled` accessor so it takes effect without recompiling, matching the pre-refactor behavior. Caveat: the model cache key (set_hash + sys_struct_hash) does not capture this equation change, so existing cached binaries must be rebuilt (remake=true) for the restored branch to take effect. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Update psys * Add cache test * Fix docs * Dont use useless abbreviations * Improved check * Use dispatch field instead of func * Update default manifests * Merge plate into group and rename to twistsurface * Merge wing types into one Wing; route plate aero through aero_component Collapse BaseWing/VSMWing/PlateWing into a single `Wing` type. VSM state moves into a `VSMEngine` sub-struct on `wing.vsm`. The engine is wing infrastructure shared by all aero modes — an AeroNone wing still carries it for section matching and twist-surface geometry — so it lives on the wing, not in the aero mode. VSMWing/PlateWing become constructor functions that return a Wing; `wing isa VSMWing/PlateWing` become `is_vsm`/`is_plate`. Flat-plate aero now goes through `aero_component(::AeroPlate, ...)` on the same PARTICLE connector contract as the other per-point modes, extended with per-point `va`/`rho` (the only inputs plate needs; VSM particle modes ignore them). Deletes plate_eqs.jl and its bespoke wiring branch. RHS aero getters are function-barriered on the concrete VSMEngine for type-stable, allocation-free reads. Full suite green (1174/1174), zero alloc. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Refactor aero updates to be dispatch-based * Improve code quility * Restructure files * Remove _ prefixes * Use dispatches instead of is vsm * Refactor plotting * Use normalized inertia * Dont display z offset * Improve plotting * Fix docs * Update default manifests * Add continuous aero mode * Add continuous billowing aero mode * Read yaml density * Sync densities and tighten tols * Add reusable RigidBody component, 6-DOF elastic joint, and rigid-body replay Extract the QUATERNION wing's 6-DOF dynamics into a shared generator and build a standalone multi-rigid-body capability on top of it. - rigid_body_eqs!: generic 6-DOF generator (quaternion kinematics + Euler + Newton + body-frame output) driven by a total force/moment at the COM, with optional integration overrides for pinning/damping. wing_eqs! now delegates to it (behaviour-equivalent; wing tests green). - RigidBody: standalone component (own collection, accessors, state serialization, getter, update, cache hash, init) reusing rigid_body_eqs!. Specified by mass/inertia/ICs + gravity + a settable external wrench; a `fixed` flag freezes all DOF. - ElasticJoint: 6-DOF elastic connection between two rigid bodies (EA/GA/GJ/EI + damping), equal-and-opposite wrench into both bodies' load accumulators. - Logging/replay: SysState/Logger now carry rigid-body positions (X/Y/Z) and per-wing/per-body orientation frames (KiteUtils orients); update_from_sysstate! reconstructs them; the Makie ext draws bodies (and wings) as RGB body-frame triads from the orientation quaternion. New position_slots(sys_struct) is the single source of truth for the X/Y/Z slot layout. Tests: test_rigid_body (free-fall, spin-up, COM-offset), test_joint (axial & torsional frequency, momentum conservation), test_beam_replay (SysLog round-trip + reconstruction). Example: beam_6dof_joints.jl (10-segment cantilever). Depends on KiteUtils orients (OpenSourceAWE/KiteUtils.jl#123). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Add option to use interp * Flatten RHS struct reads into MTK params; concrete-type wing/engine (2.76x RHS) Replace the hottest @register_symbolic struct reads in the ODE RHS with flat MTK parameters synced once per step, and concretely type the wing's aero/engine so the abstract-field tax disappears. - Wing{A<:AbstractAeroModel} (aero::A) + parametric AeroLinearized/AeroDirect/ ContinuousAero{E}; engine built and attached (attach_engine\!) before the wing is constructed. Removes the datatype.c offset lookup + the per-coefficient dispatch on the abstract VSMEngine. - flat_params.jl: path-based `params` view mirroring sys_struct, scalar/array/ callable parameters, and a sync (build_param_sync/sync_params\!) with subsystem name-matching across the aero_1+... namespace boundary. - Flatten aero coeffs (aero_y/x/jac, drag_frac), segment fields, and joint stiffness/damping; joint interpolation stiffness via callable params (no @register_symbolic). rotation_matrix_to_quaternion rewritten with ifelse so it is symbolic (-4 registers), computed once and CSE-shared. RHS 3.79 -> 1.375 us (2.76x), 0 allocations; full test suite 1739/1739. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Flatten top-level data getters into MTK params (3.17x RHS) Convert the remaining equation-level data reads (points, segments, wings, twist surfaces, pulleys, rigid bodies, settings, winch top-level) from @register_symbolic getters to flat params via the path-based `params` view. Rules established: - Equations -> flat params; defaults/guesses (initial conditions) keep registered getters, since a param referenced only in a default is pruned by mtkcompile. - psys must stay anchored in an equation (calc_wind_factor for point models; get_body_R_b_to_p for point-less rigid-body/joint/beam models). - Genuine functions (calc_wind_factor, joint interpolation, polars) stay registered; only data is flattened. Reverted the callable-param mechanism. - Custom winch components keep registered getters (params kwarg would break the user-defined winch.model interface). RHS 3.79 -> 1.197 us (3.17x), 0 allocations; full test suite 1739/1739. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Flatten aero-mode subsystem data getters (direct/continuous/plate) Convert the per-subsystem data reads to flat params, added to each component's System parameter list (synced via the namespace-matching path): - AeroDirect: frozen force/moment/per-twist-moment overrides (provides_aero_override and stores_point_force are constant-true for AeroDirect, so the conditions bake away) -> params.{wings,points}.aero_force_b / aero_moment_b / aero_moment. - ContinuousAero: frozen induced velocity -> params.wings[w].aero.v_ind. - AeroPlate: section chord/y_airf/twist/area + drag_corr -> flat params. The alpha-dependent polars (get_plate_cl/cd, get_continuous_cl/cd/cm) stay @register_symbolic (genuine functions), which also keeps psys anchored in those subsystems. test_aero_modes 500/500, test_continuous_aero 19/19, test_match_aero_sections 144/144. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Update plan: data flattening complete (3.17x, 1739/1739) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Remove dead @register_symbolic getters (data now flat params) Delete the ~65 now-unused registered getters from accessors.jl (537 -> 148 lines) plus the engine_aero_* barriers and the dead plate/continuous data getters (get_plate_drag_corr, get_twist_surface_area, get_continuous_v_ind, induced_velocity_component); their struct reads are flat MTK params now. Kept (still used): initial-condition getters (defaults/guesses can't be flat params), genuine functions (joint interpolation, polars), the psys anchor get_body_R_b_to_p, and the winch-component getters. get_wind_vec stays as a plain computed reader for the wind_vec flat param (no longer @register_symbolic). test_bench.jl: drop the per-getter allocation tests (getters gone; the RHS 0-allocation test is the guard). Full suite 1727/1727. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Update plan: dead-code deletion done (1727/1727); note Initial() IC option Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Initialize ODE state via MTK Initial() params Replace parameter-dependent IC defaults (which became initialization equations reading the live `psys`) with build-time constant defaults, so MTK exposes settable `Initial(state)` parameters. A new `initial` view (initial_conditions.jl) mirrors the flat `params` view: `bind_initial\!` records each struct-field -> state-variable binding and bakes the constant default. After compilation `build_initial_sync` builds a setter over the `Initial` params (kept when `is_parameter(sys, Initial(var))`, which holds for surviving unknowns and observed vars solved at init), and `sync_initial\!` pushes the live `SystemStructure` state onto them before each fresh `init`. reinit\! now syncs params and ICs onto the problem and runs a single init on the fresh path, dropping the trailing `reinit\!(...; reinit_dae)` there: that re-solve does not re-read `Initial` and discarded the synced state for PARTICLE wings. The reinit_dae path is kept only when reusing an existing integrator. Removes the reset_vel ODEProblem-rebuild hack. Full suite green (1727/1727); RHS still 0 allocations. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Remove quasi static because it is not used * Remove dead getters * Remove almost all register symbolic * Add example to fit beam stiffness * Remove all register symbolic * Fix docs * Don't run refresh twice * Monolith inplace getter * Remove tether props func * Useless bench * Fix aqua failure * Remove plan --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Separate out aero to component * Fix for tests * Restore speed_controlled winch flag The winch-interface refactor (#210) dropped the `speed_controlled` field, which broke the V3Kite flight-replay path that prescribes reel-out velocity from recorded CSV data. Add it back as a runtime-switchable flag: when `winch.speed_controlled` is true, `winch_acc` is forced to 0 (ignoring the winch component's `acc` output), so `D(winch_vel) = 0` and velocity is prescribed via `winch.vel`. Implemented with the registered `get_speed_controlled` accessor so it takes effect without recompiling, matching the pre-refactor behavior. Caveat: the model cache key (set_hash + sys_struct_hash) does not capture this equation change, so existing cached binaries must be rebuilt (remake=true) for the restored branch to take effect. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Update psys * Add cache test * Fix docs * Dont use useless abbreviations * Improved check * Use dispatch field instead of func * Update default manifests * Merge plate into group and rename to twistsurface * Merge wing types into one Wing; route plate aero through aero_component Collapse BaseWing/VSMWing/PlateWing into a single `Wing` type. VSM state moves into a `VSMEngine` sub-struct on `wing.vsm`. The engine is wing infrastructure shared by all aero modes — an AeroNone wing still carries it for section matching and twist-surface geometry — so it lives on the wing, not in the aero mode. VSMWing/PlateWing become constructor functions that return a Wing; `wing isa VSMWing/PlateWing` become `is_vsm`/`is_plate`. Flat-plate aero now goes through `aero_component(::AeroPlate, ...)` on the same PARTICLE connector contract as the other per-point modes, extended with per-point `va`/`rho` (the only inputs plate needs; VSM particle modes ignore them). Deletes plate_eqs.jl and its bespoke wiring branch. RHS aero getters are function-barriered on the concrete VSMEngine for type-stable, allocation-free reads. Full suite green (1174/1174), zero alloc. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Refactor aero updates to be dispatch-based * Improve code quility * Restructure files * Remove _ prefixes * Use dispatches instead of is vsm * Refactor plotting * Use normalized inertia * Dont display z offset * Improve plotting * Fix docs * Update default manifests * Add continuous aero mode * Add continuous billowing aero mode * Read yaml density * Sync densities and tighten tols * Add reusable RigidBody component, 6-DOF elastic joint, and rigid-body replay Extract the QUATERNION wing's 6-DOF dynamics into a shared generator and build a standalone multi-rigid-body capability on top of it. - rigid_body_eqs!: generic 6-DOF generator (quaternion kinematics + Euler + Newton + body-frame output) driven by a total force/moment at the COM, with optional integration overrides for pinning/damping. wing_eqs! now delegates to it (behaviour-equivalent; wing tests green). - RigidBody: standalone component (own collection, accessors, state serialization, getter, update, cache hash, init) reusing rigid_body_eqs!. Specified by mass/inertia/ICs + gravity + a settable external wrench; a `fixed` flag freezes all DOF. - ElasticJoint: 6-DOF elastic connection between two rigid bodies (EA/GA/GJ/EI + damping), equal-and-opposite wrench into both bodies' load accumulators. - Logging/replay: SysState/Logger now carry rigid-body positions (X/Y/Z) and per-wing/per-body orientation frames (KiteUtils orients); update_from_sysstate! reconstructs them; the Makie ext draws bodies (and wings) as RGB body-frame triads from the orientation quaternion. New position_slots(sys_struct) is the single source of truth for the X/Y/Z slot layout. Tests: test_rigid_body (free-fall, spin-up, COM-offset), test_joint (axial & torsional frequency, momentum conservation), test_beam_replay (SysLog round-trip + reconstruction). Example: beam_6dof_joints.jl (10-segment cantilever). Depends on KiteUtils orients (OpenSourceAWE/KiteUtils.jl#123). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Add option to use interp * Flatten RHS struct reads into MTK params; concrete-type wing/engine (2.76x RHS) Replace the hottest @register_symbolic struct reads in the ODE RHS with flat MTK parameters synced once per step, and concretely type the wing's aero/engine so the abstract-field tax disappears. - Wing{A<:AbstractAeroModel} (aero::A) + parametric AeroLinearized/AeroDirect/ ContinuousAero{E}; engine built and attached (attach_engine\!) before the wing is constructed. Removes the datatype.c offset lookup + the per-coefficient dispatch on the abstract VSMEngine. - flat_params.jl: path-based `params` view mirroring sys_struct, scalar/array/ callable parameters, and a sync (build_param_sync/sync_params\!) with subsystem name-matching across the aero_1+... namespace boundary. - Flatten aero coeffs (aero_y/x/jac, drag_frac), segment fields, and joint stiffness/damping; joint interpolation stiffness via callable params (no @register_symbolic). rotation_matrix_to_quaternion rewritten with ifelse so it is symbolic (-4 registers), computed once and CSE-shared. RHS 3.79 -> 1.375 us (2.76x), 0 allocations; full test suite 1739/1739. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Flatten top-level data getters into MTK params (3.17x RHS) Convert the remaining equation-level data reads (points, segments, wings, twist surfaces, pulleys, rigid bodies, settings, winch top-level) from @register_symbolic getters to flat params via the path-based `params` view. Rules established: - Equations -> flat params; defaults/guesses (initial conditions) keep registered getters, since a param referenced only in a default is pruned by mtkcompile. - psys must stay anchored in an equation (calc_wind_factor for point models; get_body_R_b_to_p for point-less rigid-body/joint/beam models). - Genuine functions (calc_wind_factor, joint interpolation, polars) stay registered; only data is flattened. Reverted the callable-param mechanism. - Custom winch components keep registered getters (params kwarg would break the user-defined winch.model interface). RHS 3.79 -> 1.197 us (3.17x), 0 allocations; full test suite 1739/1739. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Flatten aero-mode subsystem data getters (direct/continuous/plate) Convert the per-subsystem data reads to flat params, added to each component's System parameter list (synced via the namespace-matching path): - AeroDirect: frozen force/moment/per-twist-moment overrides (provides_aero_override and stores_point_force are constant-true for AeroDirect, so the conditions bake away) -> params.{wings,points}.aero_force_b / aero_moment_b / aero_moment. - ContinuousAero: frozen induced velocity -> params.wings[w].aero.v_ind. - AeroPlate: section chord/y_airf/twist/area + drag_corr -> flat params. The alpha-dependent polars (get_plate_cl/cd, get_continuous_cl/cd/cm) stay @register_symbolic (genuine functions), which also keeps psys anchored in those subsystems. test_aero_modes 500/500, test_continuous_aero 19/19, test_match_aero_sections 144/144. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Update plan: data flattening complete (3.17x, 1739/1739) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Remove dead @register_symbolic getters (data now flat params) Delete the ~65 now-unused registered getters from accessors.jl (537 -> 148 lines) plus the engine_aero_* barriers and the dead plate/continuous data getters (get_plate_drag_corr, get_twist_surface_area, get_continuous_v_ind, induced_velocity_component); their struct reads are flat MTK params now. Kept (still used): initial-condition getters (defaults/guesses can't be flat params), genuine functions (joint interpolation, polars), the psys anchor get_body_R_b_to_p, and the winch-component getters. get_wind_vec stays as a plain computed reader for the wind_vec flat param (no longer @register_symbolic). test_bench.jl: drop the per-getter allocation tests (getters gone; the RHS 0-allocation test is the guard). Full suite 1727/1727. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Update plan: dead-code deletion done (1727/1727); note Initial() IC option Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Initialize ODE state via MTK Initial() params Replace parameter-dependent IC defaults (which became initialization equations reading the live `psys`) with build-time constant defaults, so MTK exposes settable `Initial(state)` parameters. A new `initial` view (initial_conditions.jl) mirrors the flat `params` view: `bind_initial\!` records each struct-field -> state-variable binding and bakes the constant default. After compilation `build_initial_sync` builds a setter over the `Initial` params (kept when `is_parameter(sys, Initial(var))`, which holds for surviving unknowns and observed vars solved at init), and `sync_initial\!` pushes the live `SystemStructure` state onto them before each fresh `init`. reinit\! now syncs params and ICs onto the problem and runs a single init on the fresh path, dropping the trailing `reinit\!(...; reinit_dae)` there: that re-solve does not re-read `Initial` and discarded the synced state for PARTICLE wings. The reinit_dae path is kept only when reusing an existing integrator. Removes the reset_vel ODEProblem-rebuild hack. Full suite green (1727/1727); RHS still 0 allocations. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Remove quasi static because it is not used * Remove dead getters * Remove almost all register symbolic * Add example to fit beam stiffness * Remove all register symbolic * Fix docs * Don't run refresh twice * Monolith inplace getter * Remove tether props func * Useless bench * Fix aqua failure * Remove plan * Attach point to rigid body * Merge rigid body and wing * Import Point * Fix CI * No multi-line inline comments. Comments should be in docstring or 1-line max. * Add docstring * Add fallback * Remove useless backup * Try to fix 404 --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Replaces the single
orientquaternion inSysStatewith component-majorarrays
Qw/Qx/Qy/Qz— one entry per oriented frame — mirroring howpositions are stored as
X/Y/Z. This lets a log carry orientations for multiplewings and/or rigid bodies (e.g. a chain of rigid-body beam segments), not just a
single kite.
SysStategains a second type parameterO(number of oriented frames);SysLogandLoggerthread it through.Backwards compatibility
Preserved via property views and UnionAll dispatch:
ss.orientaliases frame 1 as a mutable view, so bothss.orient .= qand
ss.orient = qkeep working.ss.orients[i]andss.pos[i]are mutable per-entity views.SysState{P}()still constructs (O defaults to 1);SysState{P}is theSysState{P,O} where OUnionAll, so existingf(::SysState{P}) where Pdispatch and
isa SysState{P}still match. Same forSysLog{P}.StructArray{<:SysState}/SysLog.orientaccessor returns aper-timestep quaternion column (
syslog.orient[k]unchanged for callers).load_logreads both new (Qw/...) and legacy (orient) Arrow logs.showstill prints a singleorientline.Tests
Pkg.test()passes (Logfiles 29/29). The two schema-coupled assertions intest-logfiles.jlwere updated for the 2-parameter type (SysState{7,1}).🤖 Generated with Claude Code