Introduction
The SystemStructure provides a flexible framework for defining mechanical systems using discrete mass-spring-damper models. It serves as input to the SymbolicAWEModel, which automatically generates symbolic differential algebraic equations from the structural definition.
See Building a system using Julia and Building a system using YAML for tutorials on creating systems.
Public enumerations
SymbolicAWEModels.DynamicsType — Type
DynamicsType `DYNAMIC` `STATIC` `WING` `BODY_STATIC`Enumeration for the dynamic model governing a point's motion, a rigid body's motion, or a twist_surface's twist. The shared idea: DYNAMIC quantities carry differential state and are solved by the dynamics; the others are prescribed — no state, held constant within a step, but mutable between steps.
Elements
DYNAMIC: Solved by the dynamics. A point moves by Newton's second law; a rigid body integrates its 6-DOF state; a twist_surface twist solves its equilibrium.STATIC: Prescribed, no state. A point's position is welded in the world frame; a rigid body is clamped to the world; a twist_surface twist is a prescribed control input read live via the registered getter.WING: A point rides aWing— static in the wing's body frame.BODY_STATIC: A point rides aBody— static in the rigid body's body frame; it feeds its net force (and the moment about the body COM) into the body.
SymbolicAWEModels.WingType — Type
WingType `RIGID_DYNAMICS` `PARTICLE_DYNAMICS`Enumeration for the aerodynamic model type of a wing.
Elements
RIGID_DYNAMICS: Wing uses quaternion-based rigid body dynamics with twist twist_surfaces. Aerodynamic forces/moments are applied to the wing center of mass.PARTICLE_DYNAMICS: Wing uses refined per-panel forces directly applied to structural points. VSM panel forces are lumped to WING-type points with no rigid body constraint.
Aerodynamic models
SymbolicAWEModels.AbstractAeroModel — Type
AbstractAeroModelSupertype for a wing's aerodynamic model. The concrete subtype selects, by dispatch, the aero_component builder that emits the wing's aero equations. Built-in subtypes: AeroNone, AeroDirect, AeroLinearized, AeroPlate. Subtype it and add an aero_component method to plug in custom aerodynamics; see the VSM coupling documentation for a worked example with a live-updating field.
SymbolicAWEModels.AeroNone — Type
AeroNone()No aerodynamic forces (returns zeros). A body with aero = AeroNone() is a plain rigid/kinematic body. Needs no VSM geometry and carries no state.
SymbolicAWEModels.AbstractVSMAero — Type
abstract type AbstractVSMAero <: AbstractAeroModelAero modes backed by a VSMEngine (stored in the engine field). VSM operations dispatch on this supertype; the engine's fields (vsm_wing, aero_x, …) are forwarded from the mode. Built-in subtypes: AeroDirect and AeroLinearized.
SymbolicAWEModels.AeroDirect — Type
AeroDirect()Stored forces from the nonlinear VSM solve, piecewise-constant between updates. Carries a VSMEngine; the no-arg form is the engine-less marker filled in during wing construction.
SymbolicAWEModels.AeroLinearized — Type
AeroLinearized()First-order Taylor expansion using the Jacobian from VSM linearization (RIGID_DYNAMICS only). Carries a VSMEngine; the no-arg form is the engine-less marker filled in during wing construction.
SymbolicAWEModels.AeroPlate — Type
AeroPlate(calc_cl, calc_cd; drag_corr=1.0)Flat-plate CL/CD lookup aerodynamics. Carries the shared polar lookups (calc_cl/calc_cd: α_deg → coefficient) and drag correction used by all of a wing's flat-plate (1-point STATIC) TwistSurfaces. One polar set per wing.
SymbolicAWEModels.ContinuousAero — Type
ContinuousAero()Frozen-circulation VSM aerodynamics with live symbolic force assembly (PARTICLE_DYNAMICS only). The VSM solver runs every vsm_interval steps and solves only the circulation distribution (VortexStepMethod.solve_base!); the resulting per-refined-panel induced velocity is frozen. Each RHS step then evaluates the calc_forces! chain symbolically per refined panel — geometry interpolated from the live strut points with the frozen mesh weights, effective angle of attack, polar lookups, and lift/drag directions all live — capturing aerodynamic damping between refreshes. Carries a VSMEngine; the no-arg form is the engine-less marker filled in during wing construction.
SymbolicAWEModels.aero_component — Function
aero_component(mode::AbstractAeroModel, wing::AbstractWing, sys_struct; name, params) -> SystemBuild the aero subsystem for wing, selected by dispatch on both the wing's aero model and its dynamics type (RigidWing/ParticleWing). Returns a System exposing the connectors fixed by the dynamics type, all in the wing body frame (the wiring layer aero_eqs! drives inputs and reads outputs; connectors a mode ignores still exist for binding):
RIGID_DYNAMICS(num = length(wing.twist_surface_idxs)): inva[1:3],rho,R_b_w[1:3,1:3],omega[1:3],twist[1:num],twist_vel[1:num]; outforce[1:3],moment[1:3],twist_moment[1:num].PARTICLE_DYNAMICS(np = number of WING points): inpoint_pos[1:3,1:np],point_vel[1:3,1:np],va[1:3,1:np],rho[1:np]; outpoint_force[1:3,1:np].
A mode supports a dynamics type by defining the matching method (rigid, particle, or both). Add a method on a custom AbstractAeroModel subtype to plug in your own aerodynamics.
SymbolicAWEModels.is_builtin_aero — Function
is_builtin_aero(mode::AbstractAeroModel) -> Booltrue for the package's built-in aero models. Custom models return false, which forces a model rebuild (the compiled cache cannot be reused for user-supplied equations). Each built-in mode sets this in its aero_modes/ file.
SymbolicAWEModels.aero_hash_id — Function
aero_hash_id(mode::AbstractAeroModel) -> TupleStructural fields of mode that change the generated equations and therefore must enter the model-cache key. Return only fields that alter the equation structure, never runtime-mutable values (those are read live via registered getters). Defaults to an empty tuple.
aero_hash_id(mode::ContinuousAero)The frozen mesh-interpolation weights and billow offsets are baked into the generated equations, so they are structural and enter the model-cache hash.
Winch models
SymbolicAWEModels.AbstractWinchModel — Type
abstract type AbstractWinchModelSelects the winch motor dynamics. Each concrete model carries its own parameter fields and adds a winch_component(model, sys_struct, idx; name, params) method building the MTK subsystem (mirrors AbstractAeroModel). The model lives in Winch.model; common drum parameters (gear_ratio, drum_radius, f_coulomb, c_vf, inertia_total) stay on the Winch struct. New models = new struct + a few methods; see TorqueWinch.
SymbolicAWEModels.TorqueWinch — Type
TorqueWinch(; friction_epsilon=6.0)Torque-controlled winch motor (the default winch model). set_value is the motor torque [N·m]. Coulomb friction is smoothed by friction_epsilon (the smooth_sign transition width). The drum parameters (gear_ratio, drum_radius, f_coulomb, c_vf, inertia_total) live on the Winch struct; friction_epsilon is a numerical property of this model and lives here (mutable, live-tunable).
Equations
ω_motor = vel / ratio, ratio = drum_radius / gear_ratio
friction = smooth_sign(ω_motor, friction_epsilon) * f_coulomb * ratio +
c_vf * ω_motor * ratio^2
tau_total = set_value + ratio * force - friction
acc = ifelse(brake > 0.5, 0, ratio * tau_total / inertia_total)SymbolicAWEModels.CascadedLengthWinch — Type
CascadedLengthWinch(; v_max, position_gain, velocity_gain, friction_epsilon=6.0)Length-controlled winch motor. set_value is the target tether length [m]. An outer proportional law turns the length error into a velocity reference, hard- clamped at ±v_max; an inner proportional law with load feedforward tracks it. The feedforward (+friction − ratio·force) cancels the load disturbance so tether spring-mass bouncing does not perturb the reel speed. No integrator, so there is no windup at the v_max clamp and no overshoot; the closed-loop speed response is first-order.
Drum parameters (gear_ratio, drum_radius, f_coulomb, c_vf, inertia_total) live on the Winch; the gains and friction_epsilon are this model's own fields (mutable, live-tunable). A low v_max gives a slow quasi-static reel-in, useful for displacement-controlled load sweeps.
Equations
ω_motor = vel / ratio, ratio = drum_radius / gear_ratio
friction = smooth_sign(ω_motor, friction_epsilon) * f_coulomb * ratio +
c_vf * ω_motor * ratio^2
vel_unclamped = position_gain * (set_value − len)
vel_ref = clamp(vel_unclamped, −v_max, v_max)
tau_cmd = velocity_gain * (vel_ref − vel) + friction − ratio * force
tau_net = tau_cmd + ratio * force − friction
acc = ifelse(brake > 0.5, 0, ratio * tau_net / inertia_total)Core model type
SymbolicAWEModels.SymbolicAWEModel — Type
mutable struct SymbolicAWEModel <: AbstractKiteModelThe main state container for a kite power system model, built using ModelingToolkit.jl.
This struct holds the complete state of the simulation, including the physical structure (SystemStructure), the compiled model (SerializedModel), the atmospheric model, and the ODE integrator.
Users typically interact with this model through high-level functions like init! and next_step! rather than accessing its fields directly.
Type Parameters
S: Scalar type, typicallySimFloat.V: Vector type, typicallyKVec3.P: Number of tether points in the system.
sys_struct::SystemStructure: Reference to the point mass system with points, segments, pulleys and tethersserialized_model::SymbolicAWEModels.SerializedModel: Container for the compiled and serialized model componentsintegrator::Union{Nothing, OrdinaryDiffEqCore.ODEIntegrator}: The ODE integrator for the full nonlinear model Default: nothingt_0::Float64: Relative start time of the current time interval Default: 0.0iter::Int64: Number of next_step! calls Default: 0t_vsm::Float64: Time spent in the VSM linearization step Default: zero(SimFloat)t_step::Float64: Time spent in the ODE integration step Default: zero(SimFloat)param_registry::Any: Build-time flattened-parameter registry (transient, never serialized). Default: nothinginitial_registry::Any: Build-time initial-condition registry (transient, never serialized). Default: nothing
SymbolicAWEModels.SymbolicAWEModel — Method
SymbolicAWEModel(set::Settings, sys_struct::SystemStructure; kwargs...)Constructs a SymbolicAWEModel from an existing SystemStructure.
This is the primary inner constructor. It takes a SystemStructure that defines the physical layout of the kite system and prepares it for symbolic model generation.
Arguments
set::Settings: Configuration parameters.sys_struct::SystemStructure: The physical system definition.kwargs...: Further keyword arguments passed to theSymbolicAWEModelconstructor.
Returns
SymbolicAWEModel: A model ready for symbolic equation generation viainit!.
System structure and components
SymbolicAWEModels.SystemStructure — Type
struct SystemStructureA discrete mass-spring-damper representation of a kite system.
This struct holds all components of the physical model, including points, segments, winches, and wings, forming a complete description of the kite system's structure.
Components
Point: Point masses.TwistSurface: Collections of points for wing deformation.Segment: Spring-damper elements.Pulley: Elements that redistribute line lengths.Tether: TwistSurfaces of segments controlled by a winch.Winch: Ground-based winches.Wing: Rigid wing bodies.Transform: Spatial transformations for initial positioning.
SymbolicAWEModels.SystemStructure — Method
SystemStructure(name, set; points, twist_surfaces, segments, pulleys, tethers, winches, wings, transforms)Constructs a SystemStructure object representing a complete kite system.
Physical Models
- "ram": A model with 4 deformable wing twist_surfaces and a complex pulley bridle system.
- "simple_ram": A model with 4 deformable wing twist_surfaces and direct bridle connections.
Arguments
name::String: Model identifier ("ram", "simple_ram", or a custom name).set::Settings: Configuration parameters fromKiteUtils.jl.
Keyword Arguments
points,twist_surfaces,segments, etc.: Vectors of the system components.prn::Bool=true: If true, print info messages about auto-generated components.
Returns
SystemStructure: A complete system ready for building aSymbolicAWEModel.
SymbolicAWEModels.Point — Type
mutable struct PointA point mass, representing a node in the mass-spring system.
idx::Int64: Index in the points vector (assigned by SystemStructure).name::Union{Nothing, Int64, Symbol}transform_idx::Int64: Resolved transform index (filled by SystemStructure).wing_idx::Int64: Resolved wing index (filled by SystemStructure).body_idx::Int64: Resolved rigid-body index for a body-anchored point (filled by SystemStructure). 0 = not anchored.transform_ref::Union{Int64, Symbol}wing_ref::Union{Int64, Symbol}body_ref::Union{Int64, Symbol}pos_cad::StaticArraysCore.MVector{3, Float64}pos_b::StaticArraysCore.MVector{3, Float64}anchor_b::StaticArraysCore.MVector{3, Float64}pos_w::StaticArraysCore.MVector{3, Float64}vel_w::StaticArraysCore.MVector{3, Float64}ext_force_w::StaticArraysCore.MVector{3, Float64}force::StaticArraysCore.MVector{3, Float64}aero_force_b::StaticArraysCore.MVector{3, Float64}drag_force::StaticArraysCore.MVector{3, Float64}va_b::StaticArraysCore.MVector{3, Float64}type::DynamicsTypeextra_mass::Float64: User-provided mass [kg].total_mass::Float64: Total mass [kg]: extra_mass + segment contributions (computed during simulation).body_frame_damping::StaticArraysCore.MVector{3, Float64}: Per-axis damping in body frame [N·s/m].world_frame_damping::StaticArraysCore.MVector{3, Float64}: Per-axis damping in world frame [N·s/m].area::Float64: Cross-sectional area for drag [m²].drag_coeff::Float64: Drag coefficient [-].fix_sphere::Bool: If true, constrain point to a sphere.fix_static::Bool: If true, dynamically freeze point position.
SymbolicAWEModels.Point — Method
Point(name, pos_cad, type; wing=1, transform=1, ...)Constructs a Point object, which can be of four different DynamicsTypes:
STATIC: The point does not move. $\ddot{\mathbf{r}} = \mathbf{0}$DYNAMIC: The point moves according to Newton's second law. $\ddot{\mathbf{r}} = \mathbf{F}/m$WING: The point has a static position in the rigid body wing frame. $\mathbf{r}_w = \mathbf{r}_{wing} + \mathbf{R}_{b\rightarrow w} \mathbf{r}_b$BODY_STATIC: The point is static in aBody's body frame (passbody); it rides the body and feeds its net force and moment into it.
A WING point of a PARTICLE_DYNAMICS wing may also pass body: it then rides that Body instead of integrating Newton's law, keeping its wing membership (per-point aero, wing-frame fitting) while feeding its net force and COM moment into the body — the coupling used when the wing structure is a chain of bodies joined by TimoshenkoJoints instead of spring segments.
Arguments
name::Union{Int, Symbol}: Name/identifier for the point (e.g.,:kcu,:le_1, or1for legacy).pos_cad::KVec3: Position of the point in the CAD frame.type::DynamicsType: Dynamics type of the point (STATIC,DYNAMIC, etc.). PassBODY_STATICtogether withbodyto anchor the point to a rigid body.
Keyword Arguments
wing::Union{Int, Symbol}=1: Reference to the wing (name or index).transform::Union{Int, Symbol}=1: Reference to the transform (name or index).body::Union{Int, Symbol}: Reference to aBodyto anchor the point to (requirestype = BODY_STATICortype = WING). The point then rides the body kinematically and feeds its net force (and the moment about the body COM) into the body. Defaults to no anchor.anchor_b::KVec3: Anchor offset in the body frame [m] (used withbody).vel_w::KVec3=zeros(KVec3): Initial velocity of the point in world frame.extra_mass::Float64=0.0: User-provided mass of the point [kg].body_frame_damping::Union{Float64,KVec3}=zeros(KVec3): Per-axis damping for body frame.world_frame_damping::Union{Float64,KVec3}=zeros(KVec3): Per-axis damping for world frame.fix_sphere::Bool=false: If true, constrains the point to a sphere.fix_static::Bool=false: If true, dynamically freezes the point.
Returns
Point: A newPointobject. Theidxfield is assigned later by SystemStructure.
SymbolicAWEModels.TwistSurface — Type
mutable struct TwistSurfaceA set of bridle lines that share the same twist angle and trailing edge angle.
idx::Int64: Index in the twist_surfaces vector (assigned by SystemStructure).name::Union{Nothing, Int64, Symbol}point_idxs::Vector{Int64}: Resolved point indices (filled by SystemStructure).point_refs::Vector{Union{Int64, Symbol}}le_pos::StaticArraysCore.MVector{3, Float64}: Leading edge position in body frame [m] (from closest VSM panel).chord::StaticArraysCore.MVector{3, Float64}: Chord vector in body frame [m] (from closest VSM panel).y_airf::StaticArraysCore.MVector{3, Float64}: Spanwise vector in local panel frame (from closest VSM panel).type::DynamicsTypemoment_frac::Float64: Chordwise rotation point fraction (0=LE, 1=TE).damping::Float64: Damping coefficient for twist dynamics [N·m·s/rad].stiffness::Float64: Torsional restoring stiffness for twist dynamics [N·m/rad]. The resulting moment (stiffness * twist_angle) is divided by the twist_surface's inertia, same as the aero/tether moments, before being applied to the twist angular acceleration. Models the panel's own structural resistance to twisting, independent of any restoring moment from bridle tension geometry. Defaults to 0.0 (no effect, matching prior behaviour) when not set.twist::Float64: Current twist angle [rad].twist_ω::Float64: Current twist angular velocity [rad/s].tether_force::Float64: Tether force contribution [N].tether_moment::Float64: Tether moment contribution [N·m].aero_moment::Float64: Aerodynamic moment [N·m].unrefined_section_idxs::Vector{Int64}: Indices of VSM unrefined sections in this twist_surface.area::Float64: Surface area [m²] (flat-plate sections;NaNwhen unused).
SymbolicAWEModels.TwistSurface — Method
TwistSurface(name, points, type, moment_frac; damping=50.0)Constructs a TwistSurface object representing a collection of points on a kite body that share a common twist deformation.
TwistSurface geometry (lepos, chord, yairf) is computed later by SystemStructure using the closest VSM panel to the twist_surface's mean point position.
Arguments
name::Union{Int, Symbol}: Name/identifier for the twist_surface.points::Vector: References to points (names or indices).type::DynamicsType: DYNAMIC or STATIC.moment_frac::SimFloat: Chordwise rotation point (0=LE, 1=TE).
Keyword Arguments
damping::SimFloat=50.0: Damping coefficient for twist dynamics.stiffness::SimFloat=0.0: Torsional restoring stiffness [N·m/rad]. Adds a-stiffness * twist_angle / inertiaterm to the twist angular acceleration, independent of the bridle-tension restoring moment.0.0reproduces prior behaviour exactly.x_airf=nothing: Chord-direction reference (body frame). When given, stored as thechordfield — twist is measured relative to it. Defaults to auto-derived from the closest VSM panel during SystemStructure construction.y_airf=nothing: Spanwise reference (body frame). Auto-derived when omitted.area=NaN: Surface area [m²] for flat-plate (AeroPlate) sections.twist=0.0: Initial twist angle [rad] (prescribed input forSTATICsections).
Returns
TwistSurface: A newTwistSurfaceobject. Theidxandpoint_idxsare resolved by SystemStructure. Whenx_airf/y_airfare omitted the geometry fields (lepos, chord, yairf) are computed during SystemStructure construction from the closest VSM panel.
SymbolicAWEModels.Segment — Type
mutable struct SegmentA segment representing a spring-damper connection from one point to another.
The spring-damper model uses per-unit-length stiffness and damping:
- Effective stiffness:
k = unit_stiffness / length[N/m] - Effective damping:
c = unit_damping / length[N·s/m]
unit_stiffness is either a Real (linear) or a callable F(ε) of the axial strain ε = (len − l0)/l0 returning the spring force [N] (nonlinear); the callable owns the full law, including any slack/compression behaviour, so compression_frac is ignored for it.
unit_stiffness is typed Any (not a type parameter) so the segment stays a concrete type — SystemStructure.segments is written every step, and a parametric element type would make that collection abstract and allocate.
idx::Int64: Index in the segments vector (assigned by SystemStructure).name::Union{Nothing, Int64, Symbol}point_idxs::Tuple{Int64, Int64}: Resolved endpoint indices (filled by SystemStructure).point_refs::Tuple{Union{Int64, Symbol}, Union{Int64, Symbol}}unit_stiffness::Any: Stiffness per unit length:Real[N] (k = unit_stiffness/length), or callable F(ε) → force [N].unit_damping::Float64: Damping per unit length [N·s]. Effective c = unit_damping/length [N·s/m].l0::Float64: Rest (unstretched) length [m].compression_frac::Float64: Compressive/tensile stiffness ratio (0-1). 0 = no compression stiffness.diameter::Float64: Segment diameter [m].density::Float64: Material density [kg/m³].len::Float64: Current length [m] (updated during simulation).force::Float64: Current force [N] (updated during simulation).
SymbolicAWEModels.Segment — Method
Segment(name, set, point_i, point_j; l0, compression_frac,
diameter_mm, unit_stiffness, unit_damping)Constructs a Segment using settings for material properties.
Arguments
name::Union{Int, Symbol}: Name/identifier for the segment.set::Settings: The settings object containing material properties.point_i,point_j: References to the two endpoint points (names or indices).
Keyword Arguments
l0::SimFloat=zero(SimFloat): Unstretched length [m]. Calculated from point positions if zero.compression_frac::SimFloat=0.0: Compressive/tensile stiffness ratio (0-1). 0 = no compression stiffness.diameter_mm::Float64=NaN: Tether diameter [mm]. IfNaN, usesset.d_tether.unit_stiffness::Float64=NaN: Stiffness per unit length [N]. Effective k = unit_stiffness/length.unit_damping::Float64=NaN: Damping per unit length [N·s]. Effective c = unit_damping/length.density::Float64=NaN: Material density [kg/m³]. IfNaN, usesset.rho_tether.
SymbolicAWEModels.Segment — Method
Segment(name, point_i, point_j, unit_stiffness, unit_damping, diameter; l0, compression_frac)Basic constructor for a Segment object.
Arguments
name::Union{Int, Symbol}: Name/identifier for the segment.point_i,point_j: References to the two endpoint points (names or indices).unit_stiffness: Stiffness per unit length [N]. Effective k = unit_stiffness/length [N/m].unit_damping: Damping per unit length [N·s]. Effective c = unit_damping/length [N·s/m].diameter: Segment diameter [m].
Keyword Arguments
density::SimFloat=NaN: Material density [kg/m³] used for mass.
SymbolicAWEModels.Pulley — Type
mutable struct PulleyA pulley described by two segments with the common point of the segments being the pulley.
idx::Int64: Index in the pulleys vector (assigned by SystemStructure).name::Union{Nothing, Int64, Symbol}segment_idxs::Tuple{Int64, Int64}: Resolved segment indices (filled by SystemStructure).segment_refs::Tuple{Union{Int64, Symbol}, Union{Int64, Symbol}}type::DynamicsTypesum_len::Float64: Sum of connected segment lengths [m].len::Float64: Current pulley length [m] (updated during simulation).vel::Float64: Current pulley velocity [m/s] (updated during simulation).
SymbolicAWEModels.Pulley — Method
Pulley(name, segment_i, segment_j, type)Constructs a Pulley object that enforces length redistribution between two segments.
Arguments
name::Union{Int, Symbol}: Name/identifier for the pulley.segment_i,segment_j: References to the two segments (names or indices).type::DynamicsType: Dynamics type (DYNAMIC).
SymbolicAWEModels.Tether — Type
mutable struct TetherA collection of segments forming a flexible line.
Can be constructed two ways:
- Route 1 (explicit segments): Provide segment references directly.
- Route 2 (auto-generation): Provide start/end points and
n_segments; intermediate points and segments are created byexpand_auto_tethers!.
unit_stiffness is either a Real (linear) or a callable F(ε) of the axial strain returning force [N]; a callable propagates to every auto-generated segment (Route 2), making the whole line nonlinear.
unit_stiffness is typed Any (not a type parameter) to keep Tether concrete, since SystemStructure.tethers is read every step.
idx::Int64: Index in the tethers vector (assigned by SystemStructure).name::Union{Nothing, Int64, Symbol}segment_idxs::Vector{Int64}: Resolved segment indices (filled by SystemStructure).segment_refs::Vector{Union{Int64, Symbol}}start_point_idx::Int64: Resolved start point index (filled by SystemStructure).start_point_ref::Union{Nothing, Int64, Symbol}end_point_idx::Int64: Resolved end point index (filled by SystemStructure).end_point_ref::Union{Nothing, Int64, Symbol}n_segments::Int64unit_stiffness::Anyunit_damping::Float64diameter::Float64density::Float64stretched_len::Float64: Current stretched length [m] (updated during simulation).len::Float64: Unstretched tether length [m] (sum of segment l0). ODE state variable. Segment l0 = len / n_segments.init_stretched_len::Union{Nothing, Float64}: Initial stretched standoff [m] — the placed point geometry (Σ segment norms). Drives placement of root tethers.nothing= use the geometric (CAD) length, i.e. no scaling.init_tether_force::Union{Nothing, Float64}: Target initial spring force [N], default 0.reinit!solves the unstretchedlenfrom the placed stretched length:len = stretched · (1 − force/unit_stiffness). Mutually exclusive withinit_stretch_frac.init_stretch_frac::Union{Nothing, Float64}: Initial unstretched/stretched length fraction.reinit!setslen = init_stretch_frac · stretched; 0.9 gives 10% pre-stretch, 1.0 no tension, >1.0 slack. Must be positive. Mutually exclusive withinit_tether_force.
SymbolicAWEModels.Tether — Method
Tether(name, segments, stretched_length=nothing;
start_point=nothing, end_point=nothing,
tether_force=nothing, stretch_frac=nothing)Route 1: Construct a Tether from explicit segment references.
Arguments
name::Union{Int, Symbol}: Name/identifier for the tether.segments::Vector: References to segments (names or indices).stretched_length=nothing: Stretched standoff [m] (placed point geometry). Drives placement of root tethers.nothing= use the geometric length.
Keyword Arguments
start_point=nothing: Optional start point ref.end_point=nothing: Optional end point ref.tether_force=nothing: Target initial spring force [N], default 0.stretch_frac=nothing: Initiallen/stretchedfraction. Mutually exclusive withtether_force.
SymbolicAWEModels.Tether — Method
Tether(name, stretched_length=nothing;
start_point, end_point, n_segments,
unit_stiffness=NaN, unit_damping=NaN,
diameter=NaN, tether_force=nothing, stretch_frac=nothing)Route 2: Construct a Tether for auto-generation of intermediate points and segments by expand_auto_tethers!.
Arguments
name::Union{Int, Symbol}: Name/identifier for the tether.stretched_length=nothing: Stretched standoff [m] (placed point geometry). Drives placement of root tethers.nothing= use the geometric length.
Keyword Arguments
start_point: Reference to the start point (required).end_point: Reference to the end point (required).n_segments::Int: Number of segments to generate (required).unit_stiffness::Float64=NaN: Per-unit-length stiffness [N]. NaN = derive from Settings during auto-expansion.unit_damping::Float64=NaN: Per-unit-length damping [N·s]. NaN = derive from Settings during auto-expansion.diameter::Float64=NaN: Tether diameter [m]. NaN = derive from Settings during auto-expansion.density::Float64=NaN: Material density [kg/m³]. NaN = derive from Settings during auto-expansion.tether_force=nothing: Target initial spring force [N], default 0.stretch_frac=nothing: Initiallen/stretchedfraction. Mutually exclusive withtether_force.
SymbolicAWEModels.Winch — Type
mutable struct WinchA set of tethers (or a single tether) connected to a winch mechanism.
idx::Int64: Index in the winches vector (assigned by SystemStructure).name::Union{Nothing, Int64, Symbol}tether_idxs::Vector{Int64}: Resolved tether indices (filled by SystemStructure).tether_refs::Vector{Union{Int64, Symbol}}winch_point_idx::Int64: Resolved winch point index (filled by SystemStructure).winch_point_ref::Union{Int64, Symbol}init_vel::Float64: Initial reel-out velocity [m/s]. Applied on reinit!.vel::Float64: Current reel-out velocity [m/s]. ODE state variable.acc::Float64: Current winch acceleration [m/s²] from motor dynamics.set_value::Float64: Abstract setpoint passed to the winch component as theset_valueconnector. Interpretation is the component's choice (e.g. motor torque, current, set velocity, set length). The default component treats it as motor torque [N·m].brake::Float64: Brake input in [0, 1]. The outer integrator freezeswinch_velandtether_lenwhen> 0.5; custom components may interpret intermediate values as a continuous brake.speed_controlled::Bool: If true, reel-out velocity is prescribed externally rather than integrated from motor dynamics: winch acceleration is forced to 0 (ignoringmodel). Set the velocity viawinch.vel.force::StaticArraysCore.MVector{3, Float64}gear_ratio::Float64: Gear ratio [-].drum_radius::Float64: Drum radius [m].f_coulomb::Float64: Coulomb friction force [N].c_vf::Float64: Viscous friction coefficient [N·s/m].inertia_total::Float64: Total rotational inertia [kg·m²].friction::Float64: Current friction force [N] (updated during simulation).model::AbstractWinchModel: Winch motor dynamics model carrying its own parameters. Defaults toTorqueWinch. SeeAbstractWinchModel.
SymbolicAWEModels.Winch — Method
Winch(name, set, tethers; winch_point, ...)Constructs a Winch object that controls tether length through torque or speed regulation.
Arguments
name::Union{Int, Symbol}: Name/identifier for the winch.set::Settings: Settings object for winch parameters.tethers::Vector: References to tethers connected to this winch (names or indices).
Keyword Arguments
winch_point: Reference to the ground attachment point (name or index). Required.init_vel::SimFloat=0.0: Initial reel-out rate [m/s].brake=0.0: Brake input in [0, 1].> 0.5engages a hard freeze onwinch_velandtether_lenat the outer integrator.speed_controlled::Bool=false: If true, prescribe reel-out velocity viawinch.velinstead of integrating motor dynamics; winch acceleration is forced to 0, ignoringmodel.friction_epsilon::SimFloat=6.0: Coulomb-friction smoothing width; forwarded into the defaultTorqueWinch(ignored when an explicit non-defaultmodelis passed).model::AbstractWinchModel=TorqueWinch(): Winch motor dynamics model. SeeAbstractWinchModelfor plugging in your own.
SymbolicAWEModels.Winch — Method
Winch(name, tethers, gear_ratio, drum_radius, f_coulomb,
c_vf, inertia_total; winch_point, ...)Constructs a Winch by directly providing physical parameters.
Arguments
name::Union{Int, Symbol}: Name/identifier for the winch.tethers::Vector: References to tethers (names or indices).gear_ratio,drum_radius,f_coulomb,c_vf,inertia_total: Physical parameters.
Keyword Arguments
winch_point: Reference to ground attachment point. Required.init_vel::SimFloat=0.0: Initial reel-out rate [m/s].
SymbolicAWEModels.AbstractWing — Type
abstract type AbstractWingAbstract base type for all wing implementations.
Concrete subtypes must implement rigid body dynamics and provide a reference frame for attached points and twist_surfaces.
SymbolicAWEModels.RigidWing — Type
Body with rigid (DYNAMIC/STATIC) 6-DOF dynamics.
SymbolicAWEModels.ParticleWing — Type
Body whose pose is fitted from structural points (particle/KINEMATIC).
SymbolicAWEModels.Wing — Function
Declare Wing as a generic function (not an extension of VortexStepMethod.Wing).
SymbolicAWEModels.VSMEngine — Type
mutable struct VSMEngine{BA, W, SL}Vortex Step Method aerodynamic engine carried by a VSM aero mode (AbstractVSMAero engine field). Holds the VortexStepMethod objects, the linearization state, and the structural↔panel mapping.
Fields
vsm_aero,vsm_wing,vsm_solver: VortexStepMethod objects.aero_y: operating-point inputs[alpha, beta, ω1, ω2, ω3, twist...].aero_x: baseline wind-axis coefficients[CL, CD, CS, CM1, CM2, CM3, cm...].aero_jac: dense Jacobiand(aero_x)/d(aero_y).point_to_vsm_point,wing_segments: PARTICLE_DYNAMICS structural↔panel maps.aero_scale_chord: force scale compensating chord-length error (PARTICLE).aero_z_offset: body-frame z-shift of VSM panels (RIGID).
SymbolicAWEModels.VSMWing — Function
VSMWing(name, set, twist_surfaces, vsm_set; transform=nothing, y_damping=150.0, ...)Construct a Wing with Vortex Step Method aerodynamics. Builds the VSMEngine (vsm_wing/vsm_aero/vsm_solver) internally and attaches it to the wing.
Arguments
name::Union{Int, Symbol}: Name/identifier for the wing.set::Settings: Settings object for VSM configuration.twist_surfaces::Vector: References to twist_surfaces (names or indices).vsm_set: VSM settings for engine creation. Required for VSM-backed aero modes (AbstractVSMAero); may benothingfor engine-less modes likeAeroNone.
Keyword Arguments
transform=nothing: Reference to the transform. Defaults to 1.R_b_to_c,pos_cad,inertia_diag: Geometry placeholders (resolved later).y_damping,angular_damping: Damping coefficients.dynamics_type::WingType=RIGID_DYNAMICS: Aerodynamic model type.aero::AbstractAeroModel: Aerodynamic model (defaults bydynamics_type).group_points_moment::Bool=true: Whenfalse, in-group (twist_surface) points add no moment to the wing body; their force still contributes. Runtime-switchable.point_to_vsm_point,wing_segments: VSM structural↔panel maps.z_ref_points,y_ref_points,origin: Body-frame references.aero_scale_chord,aero_z_offset: VSM force/panel adjustments.n_unrefined_sections=nothing: Number of coarse (unrefined) spanwise sections used for twist/deformation control, before mesh refinement into the full VSM panel mesh; also sizes the linearized aero I/O inbuild_vsm_engine(twistsurface-count proxy). Only used for.obj/.dat-based wings ([`createvsmwing](@ref)); ignored when loading fromaerogeometry.yaml, where it is inferred from the geometry file's sections instead. Whennothing,ObjWing` picks its own default (one unrefined section per panel boundary).
VSMWing(name, vsm_aero, vsm_wing, vsm_solver, twist_surfaces, R_b_to_c, pos_cad; transform=nothing)Construct a RIGID_DYNAMICS Wing from pre-created VSM objects. Kept for backward compatibility with predefined structures.
SymbolicAWEModels.PlateWing — Function
PlateWing(name, twist_surfaces, calc_cl, calc_cd;
dynamics_type=PARTICLE_DYNAMICS, transform=nothing,
y_damping=150.0, angular_damping=0.0, drag_corr=0.93,
z_ref_points=nothing, y_ref_points=nothing, origin=nothing)Construct a flat-plate Wing (no VSM engine; vsm === nothing). Each flat-plate section is a 1-point STATIC TwistSurface carrying the section's body-frame reference frame, area, and prescribed twist; the shared polar lookups live on the wing's AeroPlate aero model. Supports both RIGID_DYNAMICS and PARTICLE_DYNAMICS.
Arguments
name: Wing name/identifier.twist_surfaces: References (names or indices) to the wing's flat-plate sections — each a 1-pointSTATICTwistSurface.calc_cl: CL lookup callable(alpha_deg) → CL.calc_cd: CD lookup callable(alpha_deg) → CD.
Keyword Arguments
dynamics_type:RIGID_DYNAMICSorPARTICLE_DYNAMICS(default).transform: Reference to transform (name or index).y_damping,angular_damping: Damping coefficients.drag_corr: Drag correction factor (stored on theAeroPlatemodel).z_ref_points,y_ref_points,origin: Body-frame references.
SymbolicAWEModels.create_plate_interpolations — Function
create_plate_interpolations(alpha_deg, cl_data, cd_data;
alpha_cd=nothing, spline=:cubic)Create CL and CD interpolation objects from polar data vectors.
Arguments
alpha_deg: angle of attack values [deg]cl_data: lift coefficient valuescd_data: drag coefficient valuesalpha_cd: separate alpha values for CD (default: same as CL)spline::cubicfor cubic spline,:linearfor piecewise linear
Returns
(cl_interp, cd_interp)tuple of interpolation objects
SymbolicAWEModels.Body — Type
Body{A<:AbstractAeroModel, D<:WingDynamics}A 6-DOF body integrated (or fitted) in the principal frame, optionally carrying aerodynamics. A plain body has aero = AeroNone(); a "wing" carries a real aero mode (see [sys_struct.wings]). type is DYNAMIC (free 6-DOF), KINEMATIC (pose fitted from structural points — particle wings) or STATIC (clamped). D mirrors the rigid/particle distinction into the type domain for aero dispatch. All bodies share the 6-DOF generator rigid_body_eqs!.
The rigid-body core (mass, inertia_principal, frames, 6-DOF state) is set directly or derived from the body's points; aero/wing fields are inert when aero is AeroNone. Loads are gravity (-g·mass for DYNAMIC bodies), the settable external wrench, joint wrenches, and aerodynamics.
idx::Int64: Index in the bodies vector (assigned by SystemStructure).name::Union{Nothing, Int64, Symbol}transform_idx::Int64: Resolved transform index (filled by SystemStructure). 0 = no transform.transform_ref::Union{Int64, Symbol}mass::Float64: Total mass [kg].inertia_principal::StaticArraysCore.MVector{3, Float64}R_b_to_p::Matrix{Float64}R_p_to_c::Matrix{Float64}com_offset_b::StaticArraysCore.MVector{3, Float64}principal_frame_method::PrincipalFrameMethod: Method used to compute the principal frame (seePrincipalFrameMethod).ext_force_w::StaticArraysCore.MVector{3, Float64}ext_force_b::StaticArraysCore.MVector{3, Float64}ext_moment_b::StaticArraysCore.MVector{3, Float64}damping::StaticArraysCore.MVector{3, Float64}: Angular damping[d_x, d_y, d_z][N·m·s] along the body-frame axes.fix_sphere::Bool: If true, COM motion is confined to a sphere about the world origin.type::DynamicsType: Dynamics type: DYNAMIC (free 6-DOF), KINEMATIC (fitted) or STATIC (frozen).pos_cad::StaticArraysCore.MVector{3, Float64}R_b_to_c::Matrix{Float64}Q_b_to_w::Vector{Float64}ω_b::StaticArraysCore.MVector{3, Float64}pos_w::StaticArraysCore.MVector{3, Float64}vel_w::StaticArraysCore.MVector{3, Float64}acc_w::StaticArraysCore.MVector{3, Float64}com_w::StaticArraysCore.MVector{3, Float64}com_vel::StaticArraysCore.MVector{3, Float64}Q_p_to_w::Vector{Float64}ω_p::StaticArraysCore.MVector{3, Float64}aero::AbstractAeroModel: Initial body→world orientation;Q_b_to_wis reset from this eachreinit!.twist_surface_idxs::Vector{Int64}: Resolved twist_surface indices (filled by SystemStructure).twist_surface_refs::Vector{Union{Int64, Symbol}}wind_disturb::StaticArraysCore.MVector{3, Float64}drag_frac::Float64: Raw twist_surface references.va_b::StaticArraysCore.MVector{3, Float64}v_wind::StaticArraysCore.MVector{3, Float64}aero_force_b::StaticArraysCore.MVector{3, Float64}aero_moment_b::StaticArraysCore.MVector{3, Float64}tether_moment::StaticArraysCore.MVector{3, Float64}tether_force::StaticArraysCore.MVector{3, Float64}elevation::Float64elevation_vel::Float64elevation_acc::Float64azimuth::Float64azimuth_vel::Float64azimuth_acc::Float64heading::Float64turn_rate::StaticArraysCore.MVector{3, Float64}turn_acc::StaticArraysCore.MVector{3, Float64}course::Float64aoa::Float64group_points_moment::Bool: Whether in-group (twist_surface) points contribute their moment to the body.z_ref_points::Union{Nothing, Tuple{WeightedRefPoints, WeightedRefPoints}}y_ref_points::Union{Nothing, Tuple{WeightedRefPoints, WeightedRefPoints}}origin::Union{Nothing, WeightedRefPoints}
SymbolicAWEModels.Body — Method
Body(name; mass, inertia_principal | inertia, pos, vel=zeros,
Q_b_to_w=[1,0,0,0], ω_b=zeros, com_offset_b=zeros, R_b_to_p=I,
angular_damping=0, fix_sphere=false, type=DYNAMIC, transform=nothing,
ext_force_w=zeros, ext_moment_b=zeros)Construct a standalone rigid body. pos/vel are the body origin's initial world-frame position/velocity; Q_b_to_w/ω_b its initial orientation/spin. The principal-frame ODE state is derived from these by init_rigid_body!.
type is DYNAMIC (free 6-DOF, default) or STATIC (clamped to its initial pose — e.g. a cantilever root). transform optionally references a Transform that repositions/rotates the body's initial pose (azimuth, elevation, heading), like a wing.
angular_damping is a scalar (isotropic) or length-3 per-axis principal-frame damping. fix_sphere=true confines COM motion to a sphere about the world origin (radial DOF frozen), like a RIGID_DYNAMICS wing's fix_sphere.
Supply the inertia in one of two ways: inertia_principal (a length-3 diagonal principal inertia, with R_b_to_p giving the body→principal rotation), or inertia (a full 3×3 body-frame tensor), in which case both inertia_principal and R_b_to_p are derived via the chosen principal_frame_method. Give one, not both.
SymbolicAWEModels.ElasticJoint — Type
ElasticJointA 6-DOF elastic connection between two Bodys. Anchored at a body-frame offset on each body, it applies a restoring wrench from the relative pose of the anchors, decomposed in body A's frame into axial (EA), shear (GA, both transverse axes), torsion (GJ), and bending (EI, both transverse axes), with optional translational/rotational damping. The equal-and-opposite wrench is added to both bodies' load accumulators.
Each stiffness is either a Real (linear law, force = k·Δ) or a callable interpolation f (nonlinear law, force = f(Δ), e.g. a wrinkling/saturating inflatable beam). They may be mixed per DOF; the type parameter S keeps the fields concrete (Reals share one type, interpolations share one type) so the ODE right-hand side stays allocation-free. The symbolic equations are identical for Real or interpolation stiffnesses (the choice is resolved at runtime in the registered force function), but the stiffness types are part of the SystemStructure type parameter, so a float vs an interpolation is a distinct compiled model with its own cache entry.
idx::Int64: Index in the elastic_joints vector (assigned by SystemStructure).name::Union{Nothing, Int64, Symbol}body_a_idx::Int64: Resolved index of body A (filled by SystemStructure).body_b_idx::Int64: Resolved index of body B (filled by SystemStructure).body_a_ref::Union{Int64, Symbol}body_b_ref::Union{Int64, Symbol}anchor_a_b::StaticArraysCore.MVector{3, Float64}anchor_b_b::StaticArraysCore.MVector{3, Float64}stiffness_axial::Any: Axial stiffness:RealEA [N/m], or interpolation force(Δx) (body A x-axis).stiffness_shear::Any: Shear stiffness:RealGA [N/m], or interpolation force(Δ) (both transverse).stiffness_torsion::Any: Torsional stiffness:RealGJ [N·m/rad], or interpolation moment(Δθ) (x-axis).stiffness_bending::Any: Bending stiffness:RealEI [N·m/rad], or interpolation moment(Δθ) (transverse).damping_trans::Float64: Translational damping [N·s/m].damping_rot::Float64: Rotational damping [N·m·s/rad].rest_offset_a::StaticArraysCore.MVector{3, Float64}R_rel0::Matrix{Float64}
SymbolicAWEModels.ElasticJoint — Method
ElasticJoint(name, body_a, body_b; anchor_a=zeros, anchor_b=zeros,
stiffness_axial, stiffness_shear, stiffness_torsion,
stiffness_bending, damping_trans=0, damping_rot=0)Connect body_a to body_b (names or indices) with a 6-DOF elastic joint. anchor_a/anchor_b are the connection points in each body's frame. Each stiffness is a Real (linear) or a callable interpolation of the relative DOF (nonlinear); interpolations must all be the same type.
SymbolicAWEModels.TimoshenkoJoint — Type
TimoshenkoJointA consistent-stiffness Timoshenko connection between two Bodys — the distributed-compliance counterpart of the lumped ElasticJoint. Like that joint it connects two bodies and applies a restoring wrench; a chain of bodies joined by TimoshenkoJoints forms a beam. The "element" of the underlying 2-node beam finite element is exactly this body-A–to–body-B connection.
Unlike the hinge, the stiffness couples each node's transverse displacement to its rotation, so transverse shear (cross-sections rotating while the centerline stays straight) is represented — the defining Timoshenko ingredient. Fewer segments match a given beam fidelity than a hinge chain.
The element wraps the linear stiffness corotationally: an element frame follows the chord and node A's orientation, small deformations are measured relative to it, and the restoring wrench is accumulated equal-and-opposite into both bodies' load accumulators (the same body_force/body_moment that ElasticJoint and body_eqs! use). Damping resists the relative node velocity/spin.
Each rigidity (EA axial, GA shear with shear_coeff correction factor k, Φ = 12·EI/(k·GA·L²), GJ torsion, EIy/EIz bending about the two transverse axes) is either a Real (linear) or a callable of that mode's strain/curvature returning the effective rigidity at the current deformation — the distributed-beam analogue of ElasticJoint's nonlinear stiffness. Unlike the hinge, whose callable returns a force, here it returns a rigidity, because the consistent element couples bending to shear and no single force suffices; a curvature-softening EIy(κ) is how inflated-tube wrinkling enters (Breukels). All callables must share one type. rest_length (0 ⇒ taken from the initial geometry) and the per-node rest orientations R_a_rel0/R_b_rel0 (set at reinit!) define the unstrained configuration.
idx::Int64: Index in the timoshenko_joints vector (assigned by SystemStructure).name::Union{Nothing, Int64, Symbol}body_a_idx::Int64: Resolved index of body A (filled by SystemStructure).body_b_idx::Int64: Resolved index of body B (filled by SystemStructure).body_a_ref::Union{Int64, Symbol}body_b_ref::Union{Int64, Symbol}anchor_a_b::StaticArraysCore.MVector{3, Float64}anchor_b_b::StaticArraysCore.MVector{3, Float64}EA::Any: Axial rigidity:RealEA [N], or callable EA(ε) of axial strain ε=δ/L₀.GA::Any: Shear rigidity (beforeshear_coeff):RealGA [N], or callable GA(γ) of shear angle.GJ::Any: Torsional rigidity:RealGJ [N·m²], or callable GJ(κ) of twist rate κ=Δθ/L₀.EIy::Any: Bending rigidity about y:RealEIy [N·m²], or callable EIy(κ) of curvature κ=Δθ/L₀.EIz::Any: Bending rigidity about z:RealEIz [N·m²], or callable EIz(κ) of curvature κ=Δθ/L₀.shear_coeff::Float64: Shear correction factor k (e.g. 5/6 solid, 8/9 inflated tube).damping_trans::Float64: Translational damping [N·s/m] on relative node velocity.damping_rot::Float64: Rotational damping [N·m·s/rad] on relative node spin.rest_length::Float64: Rest (unstrained) chord length [m]; 0 ⇒ taken from initial geometry.R_a_rel0::Matrix{Float64}R_b_rel0::Matrix{Float64}
SymbolicAWEModels.TimoshenkoJoint — Method
TimoshenkoJoint(name, body_a, body_b; anchor_a=zeros, anchor_b=zeros,
EA, GA, GJ, EIy, EIz, shear_coeff=5/6,
damping_trans=0, damping_rot=0, rest_length=0)Connect body_a to body_b (names or indices) with a Timoshenko beam element. anchor_a/anchor_b are the node points in each body's frame. Each rigidity is a Real (linear) or a callable of its strain/curvature returning the effective rigidity (nonlinear); callables must all be the same type. rest_length=0 takes the unstrained length from the initial geometry.
SymbolicAWEModels.Transform — Type
mutable struct TransformDescribes the spatial transformation (position and orientation) of system components relative to a base reference point.
idx::Int64: Index in the transforms vector (assigned by SystemStructure).name::Union{Nothing, Int64, Symbol}wing_idx::Union{Nothing, Int64}: Resolved wing index (filled by SystemStructure).wing_ref::Union{Nothing, Int64, Symbol}rot_point_idx::Union{Nothing, Int64}: Resolved rotation point index (filled by SystemStructure).rot_point_ref::Union{Nothing, Int64, Symbol}base_point_idx::Union{Nothing, Int64}: Resolved base point index (filled by SystemStructure).base_point_ref::Union{Nothing, Int64, Symbol}base_transform_idx::Union{Nothing, Int64}: Resolved base transform index (filled by SystemStructure).base_transform_ref::Union{Nothing, Int64, Symbol}elevation::Float64: Elevation angle [rad].azimuth::Float64: Azimuth angle [rad].heading::Float64: Heading angle [rad].elevation_vel::Float64: Angular velocity in elevation direction [rad/s].azimuth_vel::Float64: Angular velocity in azimuth direction [rad/s].turn_rate::Float64: Angular velocity around radial axis [rad/s].base_pos::Union{Nothing, StaticArraysCore.MVector{3, Float64}}: Base position [m]. Nothing = derived from base_transform.
SymbolicAWEModels.Transform — Method
Transform(name, elevation, azimuth, heading; base_point, base_pos, base_transform, wing, rot_point)Constructs a Transform object that orients system components using spherical coordinates.
Arguments
name::Union{Int, Symbol}: Name/identifier for the transform.elevation,azimuth,heading: Spherical coordinates [rad].
Keyword Arguments
Base Reference (choose one method):
base_pos&base_point: Use a fixed position and a reference point.base_transform: Chain to another transform's position.
Target Object (choose one):
wing: Reference to the wing to position at (elevation, azimuth).rot_point: Reference to the point to position at (elevation, azimuth).
Indexing
SymbolicAWEModels.NamedCollection — Type
NamedCollection{T} <: AbstractVector{T}A wrapper around a vector that enables both numeric and symbolic indexing.
By subtyping AbstractVector, this type works transparently with all existing code that expects vectors, including @unpack macros and iteration.
Names are extracted from items that have a name field. Items without names (or with name=nothing) are only accessible by numeric index.
items::Vector: The underlying vector of itemsname_to_idx::Dict{Symbol, Int64}: Mapping from symbolic names to indices
SymbolicAWEModels.NameRef — Type
NameRef = Union{Int, Symbol}A reference to another component, either by symbolic name (:ground) or integer index (1).
Name resolution
Components reference each other by name or index at construction time. These are stored in _ref fields (e.g. point_refs, wing_ref). During SystemStructure construction, assign_indices_and_resolve! maps every ref to a numeric index via build_name_dict (name → vector position) and stores the result in the corresponding _idx fields (e.g. point_idxs, wing_idx).
Each component has a name field (const, set once at construction) that identifies it for lookup. The type includes Nothing for forward-compatibility but no public constructor produces name=nothing; a nothing-named component would simply be unreferenceable by name (only by vector index).
System state
KiteUtils.SysState — Type
SysState(s::SymbolicAWEModel, zoom=1.0)Constructs a SysState object from a SymbolicAWEModel.
This is a convenience constructor that creates a new SysState object and populates it with the current state of the provided model.
Arguments
s::SymbolicAWEModel: The source model.zoom::SimFloat=1.0: A scaling factor for the position coordinates.
Returns
SysState: A new state struct representing the current model state.
KiteUtils.update_sys_state! — Function
update_sys_state!(ss::SysState, s::SymbolicAWEModel, zoom=1.0)Updates a SysState object with the current state values from the SymbolicAWEModel.
This function takes the raw data from the model's internal integrator and populates the fields of the user-friendly SysState struct, converting units (e.g., radians to degrees) and calculating derived values like AoA and roll/pitch/yaw angles.
Arguments
ss::SysState: The state struct to be updated.s::SymbolicAWEModel: The source model.zoom::SimFloat=1.0: A scaling factor for the position coordinates.
update_sys_state!(sys_state, y::AbstractVector, sam::SymbolicAWEModel, t::Real)Update a SysState for a linear state-space simulation, using output y and model sam.
SymbolicAWEModels.update_from_sysstate! — Function
update_from_sysstate!(sys::SystemStructure, sys_state::SysState)Update the dynamic state of a SystemStructure from a SysState snapshot.
This function copies the state variables that are present in SysState (such as point positions, wing orientations, winch lengths, and twist angles) into an existing SystemStructure. Fields that cannot be populated from SysState (such as aerodynamic forces, moments, and segment forces) are set to NaN to prevent them from being plotted.
This is useful for visualizing a SysLog by extracting individual SysState snapshots and applying them to a SystemStructure for plotting with the Makie extension.
Arguments
sys::SystemStructure: The system structure to update (must already exist with correct topology).sys_state::SysState: The state snapshot to copy from.
Example
# Load a system log
sim_log = load_log(...)
# Create a SystemStructure with the same topology
sys = SystemStructure(se(), "ram")
# Update from a specific time step
update_from_sysstate!(sys, sim_log.syslog[100])
# Plot the system at that time step
plot(sys)Notes
- The
SystemStructuremust have been created with the same model configuration as the simulation that generated theSysLog. - Aerodynamic and force fields are set to
NaNand will not be plotted. - The number of points in
sysmust match the parametric typePofSysState{P}.