Private API

This page documents the internal functions and types of SymbolicAWEModels.jl. These are not part of the public API and may change without notice. They are listed here for developers and for those interested in the model's internal workings.

Core types and constructors

SymbolicAWEModels.SerializedModelType
@with_kw mutable struct SerializedModel{...}

A type-stable container for the compiled and serialized components of a SymbolicAWEModel.

This struct holds the products of the ModelingToolkit.jl compilation process, now organized into nested attribute structs (ProbWithAttributes, etc.). This simplifies the structure and improves serialization robustness.

  • set_hash::Vector{UInt8}

  • sys_struct_hash::Vector{UInt8}

  • full_sys::Union{Nothing, ModelingToolkitBase.System}: Unsimplified system of the mtk model Default: nothing

  • defaults::Vector{Pair}: Default: Pair[]

  • guesses::Vector{Pair}: Default: Pair[]

  • inputs::Union{Symbolics.Arr, Vector{Symbolics.Num}}: Symbolic representation of the control inputs. Default: Num[]

  • outputs::Union{Symbolics.Arr, Vector{Symbolics.Num}}: Outputs of the linearization and control function. Default: Num[]

  • prob::Union{Nothing, SymbolicAWEModels.ProbWithAttributes}: Container for the ODE problem and its getters/setters. Default: nothing

  • simple_lin_model::Union{Nothing, SymbolicAWEModels.SimpleLinModelWithAttributes}: Container for the simplified linear model and its state getters. Default: nothing

  • lin_prob::Union{Nothing, SymbolicAWEModels.LinProbWithAttributes}: Container for the linearization problem and its components. Default: nothing

  • control_funcs::Union{Nothing, SymbolicAWEModels.ControlFuncWithAttributes}: Container for the control functions. Default: nothing

source
SymbolicAWEModels.SimFloatType
const SimFloat = Float64

This type is used for all real variables, used in the Simulation. Possible alternatives: Float32, Double64, Dual Other types than Float64 or Float32 do require support of Julia types by the solver.

source
VortexStepMethod.WingType
Wing(name, vsm_aero, vsm_wing, vsm_solver, groups, R_b_to_c, pos_cad; transform=1)

Constructs a VSMWing object (backward compatibility constructor).

This is a convenience constructor that creates a VSMWing for backward compatibility with existing code. New code should use VSMWing(...) directly.

Arguments

  • name::Union{Int, Symbol}: Name/identifier for the wing.
  • vsm_aero, vsm_wing, vsm_solver: Vortex Step Method components.
  • groups::Vector: References to groups attached to this wing (names or indices).
  • R_b_to_c::Matrix{SimFloat}: Rotation matrix from body frame to CAD frame.
  • pos_cad::KVec3: Position of wing center of mass in CAD frame.

Keyword Arguments

  • transform::Union{Int, Symbol}=1: Reference to the transform.
  • y_damping::SimFloat=150.0: Damping coefficient for lateral motion.

Returns

  • VSMWing: A new VSM wing object.
source
VortexStepMethod.Wing(set::Settings; prn=true, kwargs...)

Create a Wing geometry object from the settings provided.

This constructor checks for .obj and .dat files in the model directory. If found, it uses VortexStepMethod.ObjWing(obj_path, dat_path) to load the wing. Otherwise, it falls back to loading from aero_geometry.yaml.

This is a constructor helper that reads geometry from the Settings object and initializes the Wing object from VortexStepMethod.jl.

source
SymbolicAWEModels.create_tetherFunction
create_tether(tether_idx, set, points, segments, tethers, attach_point, type, dynamics_type; z, unit_stiffness, unit_damping)

Procedurally create a multi-segment tether.

This function builds a tether from a specified number of segments, connecting a given attach_point on the kite to a new anchor point on the ground.

source

State management and model simplification

SymbolicAWEModels.getstateFunction
getstate(sys_struct::SystemStructure) -> Tuple

Capture and return a snapshot of the key dynamic states of the system.

source
SymbolicAWEModels.set_measured!Function
set_measured!(sys_struct, heading, turn_rate, tether_len, tether_vel)

Adjust the model's state to match a set of "measured" or target values.

This function is typically used in state estimation or stabilization loops. It takes a set of target values (e.g., from a sensor or a reference trajectory) and forces the corresponding states in the SystemStructure to match, calculating kinematically consistent values for other related states.

source
SymbolicAWEModels.copy!Function
copy!(sys1::SystemStructure, sys2::SystemStructure)

Copy the dynamic state from one SystemStructure (sys1) to another (sys2).

This function is designed to transfer the state (positions, velocities, etc.) between two system models, which can have different levels of fidelity. For example, it can copy the state from a detailed multi-segment tether model (sys1) to a simplified single-segment model (sys2).

The function handles several cases:

  • If sys1 and sys2 have the same structure, it performs a direct copy of all point states.
  • If sys2 is a simplified (1-segment per tether) version of sys1, it copies the positions and velocities of the tether endpoints.
  • It also copies the state of wings, groups, winches, and pulleys where applicable.
source
SymbolicAWEModels.reinit!Function
reinit!(transforms::AbstractVector{Transform}, sys_struct::SystemStructure)

Apply the initial spatial transformations to all components in a SystemStructure.

This function iterates through all transforms and applies the specified translation and rotation to position and orient the kite system components correctly in the world frame at the beginning of a simulation.

If transforms is empty, simply initializes posw = poscad for all components.

source
reinit!(sys_struct::SystemStructure, set::Settings; ignore_l0=false, remake_vsm=false)

Re-initialize a SystemStructure from a Settings object.

This function resets various component states (e.g., winch lengths, group twists, pulley positions) to their initial values as defined in the Settings object. It is typically called before starting a new simulation run.

Pulley lengths are initialized proportionally based on current segment lengths: pulley.len = segment1.len / (segment1.len+segment2.len) * pulley.sum_len

Keyword Arguments

  • ignore_l0::Bool=false: If true, recalculate segment rest lengths from current positions
  • remake_vsm::Bool=false: If true, recreate VSM wing, aerodynamics, and solver from settings. This is useful after modifying aerogeometry.yaml or other VSM-related configuration files. For REFINE wings, also rebuilds the pointtovsmpoint mapping.
source
reinit!(sam::SymbolicAWEModel, lin_prob::ModelingToolkit.LinearizationProblem)

Reinitializes a LinearizationProblem with the current system and settings parameters.

This function updates the internal parameter vectors of the linearization problem with the latest values from the SymbolicAWEModel's sys_struct and set fields.

source
reinit!(s::SymbolicAWEModel, prob::ODEProblem, solver; prn, precompile, reload, outputs) -> (ODEIntegrator, Bool)

Reinitializes an existing kite power system model's ODE integrator.

This function resets the integrator's state with new values from s.set, allowing for the simulation to be restarted from a new initial condition without needing to rebuild the entire symbolic model.

Arguments

  • s::SymbolicAWEModel: The kite power system state object.
  • prob::ODEProblem: The ODE problem to be solved.
  • solver: The solver to be used.

Keyword Arguments

  • adaptive::Bool=true: Whether to use adaptive time-stepping.
  • reload::Bool=true: Force reloading the model from disk.
  • lin_vsm::Bool=true: If true, linearizes the VSM model after reinitialization.

Returns

  • (ODEIntegrator, Bool): A tuple containing the reinitialized integrator and a success flag.
source
SymbolicAWEModels.reposition!Function
reposition!(transforms::AbstractVector{Transform},
            sys_struct::SystemStructure)

Update the system's spatial orientation based on its current position, preserving velocities.

Unlike reinit!, uses current world positions (pos_w) as the starting point rather than resetting from CAD coordinates. Heading is wind-relative (absolute), consistent with reinit!: the same analytical solve_heading_rotation is used.

Preserves existing velocities (vel_w, ω_b) of all points and wings.

Arguments

  • sys_struct::SystemStructure: The system model to update.
source
SymbolicAWEModels.update_sys_struct!Function
update_sys_struct!(s::SymbolicAWEModel, sys_struct::SystemStructure, integ=s.integrator)

Updates the high-level SystemStructure from the low-level integrator state vector.

This function reads the raw state vector from the ODE integrator and uses the generated getter functions to populate the human-readable fields in the SystemStructure. This synchronization step is crucial for making the simulation results accessible.

source
SymbolicAWEModels.get_set_hashFunction
get_set_hash(set::Settings; fields)

Calculates a SHA1 hash for structural fields in the Settings object. This is used to check if a cached compiled model is still valid.

Structural Fields (affect symbolic equations):

  • :segments: Number of tether segments (affects state vector size)
  • :model: Kite model name (affects geometry)
  • :foil_file: Airfoil data file (affects VSM setup)
  • :physical_model: Model type (ram, simpleram, 4attach_ram)
  • :quasi_static: Whether points are quasi-static (affects equations)
  • :winch_model: Winch dynamics model (affects winch equations)

Runtime Fields (don't affect compilation, excluded from hash):

  • :profile_law: Wind profile law (evaluated at runtime via symbolic function)
  • :v_wind, :elevation: Initial conditions
  • Other runtime parameters
source
SymbolicAWEModels.get_sys_struct_hashFunction
get_sys_struct_hash(sys_struct::SystemStructure)

Calculates a SHA1 hash for the topology and structure of a SystemStructure. This is used to check if a cached compiled model is still valid.

Includes all structural properties that affect the symbolic equations:

  • Point connectivity and types (STATIC, DYNAMIC, QUASI_STATIC, WING)
  • Segment connectivity
  • Group structure and types (FIXED, TWIST)
  • Pulley constraints and types
  • Tether topology
  • Winch configuration
  • Wing topology, connectivity, aerodynamic model type (QUATERNION vs REFINE), and aero mode
  • Transform hierarchy

Excludes runtime-configurable properties like masses, lengths, stiffnesses.

source

Physics and geometry helpers

SymbolicAWEModels.calc_headingFunction
calc_heading(sys::SystemStructure)

Calculate heading angles for all wings in the system structure. Returns a vector of heading angles, one per wing.

source
calc_heading(R_b_to_w, wind_norm)

Calculate heading angle from body-to-world rotation matrix and wind direction. Heading is the angle of the body x-axis projected onto a wind-perpendicular plane.

source
SymbolicAWEModels.calc_R_t_to_wFunction
calc_R_t_to_w(wing_pos)

Calculate the rotation matrix from the local tether frame (_t) to the world frame (_w).

The tether frame is a local spherical coordinate system:

  • z-axis: Aligned with the tether (radial direction).
  • y-axis: Azimuthal direction, parallel to the XY plane.
  • x-axis: Elevation direction, tangent to the sphere (y × z).
source
SymbolicAWEModels.calc_R_v_to_wFunction
calc_R_v_to_w(wing_pos, e_x)

Calculate the rotation matrix from the view frame (_v) to the world frame (_w).

The view frame is defined with its z-axis pointing from the origin to the wing, and its x-axis aligned with the wing's x-axis projected onto the view plane.

Note: Uses explicit element access to avoid slice notation that doesn't scalarize properly when nested inside norm/division operations.

source
SymbolicAWEModels.calc_posFunction
calc_pos(wing::Wing, gamma, frac)

Calculate a position on the kite based on spanwise (gamma) and chordwise (frac) parameters.

source
SymbolicAWEModels.calc_winch_forceFunction
calc_winch_force(tether_vel, tether_acc, motor_torque, set)

Calculate the tensile force on the winch tether based on its motion and motor torque.

This function uses a settings object to define the physical parameters of the winch.

Arguments

  • tether_vel: The velocity of the tether [m/s].
  • tether_acc: The acceleration of the tether [m/s²].
  • motor_torque: The torque applied by the motor [Nm].
  • set: A settings struct.

Returns

  • The calculated force on the winch tether [N].
source
SymbolicAWEModels.find_axis_pointFunction
find_axis_point(P, l, v=[0,0,1])

Calculate the coordinates of a point Q that lies on a line defined by vector v and is at a distance l from a given point P.

source
SymbolicAWEModels.get_base_posFunction
get_base_pos(transform::Transform, transforms, wings, points)

Get the base position for a given transform, resolving chained transforms if necessary.

source

Equations and system management

SymbolicAWEModels.create_sys!Function
create_sys!(s::SymbolicAWEModel, system::SystemStructure; prn=true)

Create the full ModelingToolkit.ODESystem for the AWE model.

This is the main top-level function that orchestrates the generation of the entire set of differential-algebraic equations (DAEs). It calls specialized sub-functions to build the equations for each part of the system (forces, wing dynamics, scalar kinematics, linearized aerodynamics) and assembles them into a single System.

Arguments

  • s::SymbolicAWEModel: The main model object to be populated with the system.
  • system::SystemStructure: The physical structure definition.
  • prn::Bool=true: If true, print progress information during system creation.

Returns

  • set_values: The symbolic variable representing the control inputs (winch torques).
source
SymbolicAWEModels.scalar_eqs!Function
scalar_eqs!(s, eqs, psys, pset; kwargs...)

Generate equations for derived scalar kinematic quantities useful for control and analysis.

This includes elevation, azimuth, heading, course, angle of attack, and their time derivatives, as well as apparent wind calculations.

Arguments

  • s::SymbolicAWEModel: The main model object.
  • eqs, psys, pset: Accumulating vectors and symbolic parameters.
  • kwargs...: Symbolic variables for the system's state.

Returns

  • eqs: The updated list of system equations.
source
SymbolicAWEModels.wing_eqs!Function
wing_eqs!(s, eqs, psys, pset, defaults; kwargs...)

Generate the differential equations for the wing's rigid body dynamics.

For QUATERNION wings:

  • ODE state: comw, comvel, Qptow, ωp (principal frame)
  • Euler rotation equations in principal frame (diagonal I)
  • Newton's 2nd law for COM translation
  • Body frame output (Rbtow, wingpos, ωb) computed algebraically via Rbtow = Rptow * Rbtop (constant)

For REFINE wings:

  • No rigid body dynamics (handled by DYNAMIC points)
  • Rbto_w from structural ref points
  • Principal frame variables set to zero/aliases
source
SymbolicAWEModels.vsm_eqs!Function
vsm_eqs!(s, eqs, guesses, psys; kwargs...)

Generate aerodynamic equations for all wings.

Aero mode is resolved at build time — each wing's aero_mode determines which equations are generated:

  • AERO_LINEARIZED: symbolic linearization equations (q∞·A·(x₀ + J·Δ)) that the solver can differentiate through
  • AERO_DIRECT: registered functions returning stored forces
  • AERO_NONE: zeros

For REFINE wings, per-point forces come from get_point_aero_force (which also respects AERO_NONE).

source
SymbolicAWEModels.point_eqs!Function
point_eqs!(s, eqs, defaults, guesses, points, segments, groups, wings, psys, pset;
           R_b_to_w, wing_pos, wing_vel, wind_vec_gnd, fix_wing, twist_angle,
           pos, vel, acc, point_force, point_mass, spring_force_vec, drag_force, l0,
           spring_sum_force, point_drag_force, disturb_force, tether_r, chord_b, fixed_pos, normal, pos_b,
           fix_point_sphere, fix_static, body_frame_damping, world_frame_damping,
           va_point_b, va_point_w, wind_at_point, height,
           aero_force_point_b, has_refine_wings,
           group_y_airf, tether_wing_force, tether_wing_moment)

Generate equations for all point types (STATIC, DYNAMIC, QUASI_STATIC, WING).

Arguments

  • s::SymbolicAWEModel: The main model object (for atmospheric model).
  • eqs, defaults, guesses: Accumulating vectors for the MTK system.
  • points, segments, groups, wings: System components.
  • psys, pset: Symbolic parameters representing system and settings.
  • R_b_to_w: Symbolic rotation matrix (body to world).
  • wing_pos, wing_vel: Symbolic wing center of mass position/velocity.
  • wind_vec_gnd: Symbolic ground-level wind vector.
  • fix_wing: Symbolic boolean for fixing wing dynamics.
  • twist_angle: Symbolic group twist angle.
  • pos, vel, acc: Pre-declared point state variables.
  • point_force, point_mass: Pre-declared point force and mass variables.
  • spring_force_vec, drag_force, l0: Pre-declared segment force variables.
  • spring_sum_force: Pre-declared accumulated spring/drag forces variable.
  • Other variables: Various point-specific symbolic variables.
  • tether_wing_force, tether_wing_moment: Mutable arrays to accumulate forces/moments.

Returns

  • Tuple (eqs, defaults, guesses) with updated equation vectors. Note: tether_wing_force and tether_wing_moment are modified in-place.
source
SymbolicAWEModels.segment_eqs!Function
segment_eqs!(s, eqs, guesses, points, segments, pulleys, tethers, winches, wings, psys, pset;
             pos, vel, wind_vec_gnd, spring_force_vec, drag_force, l0,
             pulley_len, tether_len)

Generate equations for segment spring-damper forces and aerodynamic drag.

Arguments

  • s::SymbolicAWEModel: The main model object (for atmospheric model).
  • eqs, guesses: Accumulating vectors for the MTK system.
  • points, segments, pulleys, tethers, winches, wings: System components.
  • psys, pset: Symbolic parameters representing system and settings.
  • pos, vel: Symbolic point state variables.
  • wind_vec_gnd: Symbolic ground-level wind vector.
  • spring_force_vec, drag_force, l0: Pre-declared segment force variables.
  • pulley_len, tether_len: Symbolic state variables for pulley and tether lengths.

Returns

  • Tuple (eqs, guesses, len, spring_force) with updated equation vectors and the segment length and spring force variables for use by other components.
source
SymbolicAWEModels.update_vsm!Function
update_vsm!(s::SymbolicAWEModel, integ=s.integrator)

Update the aerodynamic model from the Vortex Step Method (VSM).

This function updates the VSM aerodynamics for all wings, with wing-type-specific behavior:

For QUATERNION wings:

  • Takes the current kinematic state (apparent wind, angular velocity, twist angles)
  • Linearizes the VSM aerodynamics around this operating point
  • Updates the Jacobian (vsm_jac) and steady-state forces (vsm_x)

For REFINE wings:

  • Updates VSM panel positions from current structural deformation
  • Solves the full nonlinear VSM system
  • Distributes panel forces to structural points via point.aero_force_b

This is typically called periodically during simulation based on the vsm_interval parameter.

source
SymbolicAWEModels.jacobianFunction
jacobian(f::Function, x::AbstractVector, ϵ::AbstractVector) -> Matrix

Numerically compute the Jacobian of a vector-valued function f at point x.

This function uses a simple forward finite difference method to approximate the partial derivatives of f with respect to each component of x.

Arguments

  • f::Function: The function to differentiate (y = f(x)).
  • x::AbstractVector: The point at which to evaluate the Jacobian.
  • ϵ::AbstractVector: A vector of perturbation sizes for each component of x.

Returns

  • Matrix: The Jacobian matrix J, where J[i, j] = ∂f[i] / ∂x[j].
source
SymbolicAWEModels.load_serialized_model!Function
load_serialized_model!(sam, model_path; remake=false, reload=false)

Load a serialized model from disk if it is valid.

A model is considered valid if its settings and system structure hashes match the current ones in the SymbolicAWEModel object (sam).

Arguments

  • sam::SymbolicAWEModel: The main model object.
  • model_path::String: The path to the serialized model file.
  • remake::Bool: If true, forces the model to be considered invalid, triggering a rebuild.
  • reload::Bool: If true, forces reloading from disk even if the model is already in memory.

Returns

  • true if a valid model was successfully loaded into sam.serialized_model, false otherwise.
source
SymbolicAWEModels.maybe_create_lin_prob!Function
maybe_create_lin_prob!(sam, outputs; ...)

Create and cache the LinearizationProblem if it does not exist or if the outputs have changed.

Arguments

  • sam::SymbolicAWEModel: The main model object.
  • outputs: A vector of output variables for the linearization.
  • create_lin_prob::Bool: Flag to enable/disable creation.
  • outputs_changed::Bool: Flag indicating if the output vector has changed.
  • prn::Bool: Flag to enable/disable printing of progress messages.

Returns

  • true if a new problem was created, false otherwise.
source
SymbolicAWEModels.maybe_create_control_functions!Function
maybe_create_control_functions!(sam, outputs; ...)

Create and cache the control functions if they do not exist or if the outputs have changed.

Arguments

  • sam::SymbolicAWEModel: The main model object.
  • outputs: A vector of output variables for the control functions.
  • create_control_func::Bool: Flag to enable/disable creation.
  • outputs_changed::Bool: Flag indicating if the output vector has changed.
  • prn::Bool: Flag to enable/disable printing of progress messages.

Returns

  • true if new functions were created, false otherwise.
source
SymbolicAWEModels.maybe_create_prob!Function
maybe_create_prob!(sam; create_prob=true, prn=true)

Create and cache the ODEProblem if it does not already exist.

This function compiles the full system, creates the ODEProblem, and generates the necessary getter/setter functions.

Arguments

  • sam::SymbolicAWEModel: The main model object.
  • create_prob::Bool: A flag to enable or disable the creation of the problem.
  • prn::Bool: A flag to enable or disable printing of progress messages.

Returns

  • true if a new problem was created, false otherwise.
source
SymbolicAWEModels.maybe_create_simple_lin_model!Function
maybe_create_simple_lin_model!(sam, outputs; ...)

Create and cache a simplified linear model if it does not exist or if the outputs have changed.

Arguments

  • sam::SymbolicAWEModel: The main model object.
  • outputs: A vector of output variables for the linear model.
  • create_simple_lin_model::Bool: Flag to enable/disable creation.
  • outputs_changed::Bool: Flag indicating if the output vector has changed.
  • prn::Bool: Flag to enable/disable printing of progress messages.

Returns

  • true if a new model was created, false otherwise.
source
SymbolicAWEModels.generate_control_funcsFunction
generate_control_funcs(model, inputs, outputs)

Generate in-place and out-of-place control functions from a ModelingToolkit system.

This function wraps ModelingToolkit.generate_control_function and ModelingToolkit.build_explicit_observed_function to create the necessary functions for simulation and analysis.

Arguments

  • model: The full ODESystem.
  • inputs: A vector of input variables.
  • outputs: A vector of output variables.

Returns

  • A NamedTuple containing the generated functions (f_oop, f_ip, h_oop, h_ip), system dimensions (nu, nx, ny), and symbolic variables (dvs, psym, io_sys).
source
SymbolicAWEModels.generate_simple_lin_modelFunction
generate_simple_lin_model(sys_struct, sys, y_vec)

Generate a simplified linear state-space model for a single-wing system.

This model is a minimal representation suitable for simple controllers, focusing on heading, turn rate, and tether dynamics.

Arguments

  • sys_struct::SystemStructure: The structure defining the system topology.
  • sys::ODESystem: The compiled ModelingToolkit system.
  • y_vec: A vector of output variables for the linear model.

Returns

  • A NamedTuple containing the state-space matrices (model), and getters for the state (get_x), state derivatives (get_dx), and outputs (get_y). Returns nothing for all fields if the system does not have exactly one wing.
source
SymbolicAWEModels.generate_lin_gettersFunction
generate_lin_getters(sys)

Generate setter functions for the parameters of a linearized system.

Arguments

  • sys: The linearized ModelingToolkit system.

Returns

  • A NamedTuple containing setter functions for the winch set-points (set_set_values), the system structure parameters (set_sys), and the settings parameters (set_set).
source
SymbolicAWEModels.generate_prob_gettersFunction
generate_prob_getters(sys_struct, sys)

Generate getter and setter functions for the state variables of the full system model.

These functions provide a convenient way to access and modify the state and parameters of the compiled ODESystem (sys).

Arguments

  • sys_struct::SystemStructure: The structure defining the system topology.
  • sys::ODESystem: The compiled ModelingToolkit system.

Returns

  • A NamedTuple containing various getter and setter functions for different parts of the system state.
source
SymbolicAWEModels.LinProbWithAttributesType
@with_kw struct LinProbWithAttributes{SetLinSetValues, SetLinSys, SetLinSet, LinOut}

A container for the general-purpose linearization problem and the resulting full linearized model (A,B,C,D matrices).

  • prob::ModelingToolkit.LinearizationProblem: Linearization problem of the mtk model.

  • set_set_values::Any

  • set_sys::Any

  • set_set::Any

source
SymbolicAWEModels.ProbWithAttributesType
@with_kw struct ProbWithAttributes{...}

A container for the main Ordinary Differential Equation (ODE) problem and its associated getter and setter functions for the full, nonlinear physical state.

source
SymbolicAWEModels.ControlFuncWithAttributesType
@with_kw struct ControlFuncWithAttributes{FIP, FOOP, HIP, HOOP, DVS, PSYM}

A container for callable control functions and their symbolic representations, generated from the full system model.

  • f_ip::Any: In-place dynamics function f(dx, x, u, p, t).

  • f_oop::Any: Out-of-place dynamics function dx = f(x, u, p, t).

  • h_ip::Any: In-place observation function h(y, x, u, p, t).

  • h_oop::Any: Out-of-place observation function y = h(x, u, p, t).

  • nu::Int64: Number of inputs (u).

  • nx::Int64: Number of states (x).

  • ny::Int64: Number of outputs (y).

  • dvs::Any: The symbolic state vector.

  • psym::Any: The symbolic parameter vector.

  • io_sys::ModelingToolkitBase.System: The generated input-output system.

source

Utility and internal functions

SymbolicAWEModels.get_model_nameFunction
get_model_name(set::Settings, sys_struct::SystemStructure; precompile=false)

Constructs a unique filename for the serialized model based on its configuration. The filename includes the Julia version, physical model, wing type, dynamics type, and component counts to ensure that the correct cached model is loaded.

source
SymbolicAWEModels.posFunction
pos(s::SymbolicAWEModel)

Returns a vector of the position vectors [m] for each point in the system.

source
SymbolicAWEModels.calc_spring_propsFunction
calc_spring_props(sam, tether_sam; prn=false) -> (Vector, Vector, Matrix, Float64)

Calculate the equivalent stiffness and damping, and return the step response data.

This function orchestrates the process by performing a step response test on the tether_sam model and then analyzing the resulting tether length data.

Arguments

  • sam::SymbolicAWEModel: The reference model, used for its physical properties.
  • tether_sam::SymbolicAWEModel: A copy of the model to perform the step test on.

Keywords

  • prn::Bool=false: If true, enables printing of intermediate results.

Returns

  • Tuple{Vector{Float64}, Vector{Float64}, Matrix{Float64}, Float64}: A tuple containing:
    1. unit_stiffness [N]
    2. unit_damping [Ns]
    3. tether_lens (the step response data)
    4. dt (the simulation time step)
source
calc_spring_props(sam, tether_lens, F_step; p=5, prn=false) -> (Vector, Vector)

Calculate spring constant k and damping coefficient c from a step response.

This function analyzes the time series of tether lengths (tether_lens) resulting from a step force (F_step) to estimate the parameters of an equivalent second-order mass-spring-damper system.

Arguments

  • sam::SymbolicAWEModel: The model from which to take physical parameters (mass).
  • tether_lens::Matrix{Float64}: A matrix of tether length time series data.
  • F_step::Float64: The magnitude of the applied step force.

Keywords

  • p::Int=5: The percentage band used to determine the settling time.
  • prn::Bool=false: If true, enables printing of detailed calculations.

Returns

  • Tuple{Vector{Float64}, Vector{Float64}}: A tuple containing two vectors:
    1. k_values (spring constants [N/m])
    2. c_values (damping coefficients [Ns/m])
source
SymbolicAWEModels.set_v_wind_ground!Function
set_v_wind_ground!(s::SymbolicAWEModel, v_wind_gnd=s.set.v_wind, upwind_dir=-π/2)

Sets the ground wind speed [m/s] and upwind direction [rad] in the model.

source
SymbolicAWEModels.in_percent_bandFunction
in_percent_band(x, steady, delta_x, i, p) -> Bool

Helper function to check if a time series has settled within a percentage band.

It checks if all values of the time series x from index i to the end are within a tolerance band defined by p percent of the total change delta_x.

source
SymbolicAWEModels.stepFunction
step(sam, steps, F_step, F_0; abs_tol, consecutive_steps_needed, prn) -> Matrix

Apply a step force to a model and simulate its dynamic response.

This function records the length of each tether over a specified number of simulation steps. It includes an early exit condition if the system's state settles.

Arguments

  • sam::SymbolicAWEModel: The model to be simulated.
  • steps::Int: The total number of simulation steps.
  • F_step::Float64: The magnitude of the step force to apply.
  • F_0::Vector{KVec3}: The initial force vector for each tether attachment point.

Keywords

  • abs_tol::Float64=1e-6: Absolute tolerance for the settling check.
  • consecutive_steps_needed::Int=10: Number of consecutive steps required to be within tolerance to be considered settled.
  • prn::Bool=false: If true, enables printing of status messages.

Returns

  • Matrix{Float64}: A matrix where each row corresponds to a tether and each column to a time step, containing the tether lengths.
source
SymbolicAWEModels.create_model_archiveFunction
create_model_archive(source_dir, archive_path)

Finds all model*.bin files in the source_dir, copies them to a temporary directory, and compresses that directory into a .tar.gz archive at the specified archive_path.

source
SymbolicAWEModels.filecmpFunction
filecmp(path1::AbstractString, path2::AbstractString) -> Bool

Compare two files byte-by-byte to check if they are identical.

source
SymbolicAWEModels.extract_model_archiveFunction
extract_model_archive(archive_path, dest_dir)

Safely decompress a .tar.gz file by first extracting to a temporary directory and then copying the contents to the final destination.

Arguments

  • archive_path::String: The path to the .tar.gz file to be extracted.
  • dest_dir::String: The path to the target directory.
source
SymbolicAWEModels.copy_dirFunction
copy_dir(src_dir, dst_dir)

Copies all files from src_dir to dst_dir. Overwrites existing files if force=true. Creates dst_dir if it does not exist.

source
SymbolicAWEModels.get_example_packagesFunction
get_example_packages()

Get the list of packages from examples/Project.toml, excluding SymbolicAWEModels itself. This ensures init_module installs the correct dependencies for running examples.

source

Base overloads (internal use)

Base.getindexFunction

Access item by numeric index.

source

Access item by symbolic name.

source
Base.getindex(x::ModelingToolkit.Symbolics.Arr, idxs::Vector{Int64})

Extend Base.getindex to allow indexing a symbolic array with a vector of integer indices, which is not natively supported by ModelingToolkit.

source
Base.getpropertyFunction
Base.getproperty(pa::ProbWithAttributes, sym::Symbol)

Overloads getproperty to provide convenient access to the simplified system (sys) contained within the ODE problem's function definition.

source
Base.getproperty(sam::SymbolicAWEModel, sym::Symbol)

Overloads getproperty to allow direct access to fields within the nested serialized_model. This provides a convenient way to access compiled functions and other model components without explicitly referencing sam.serialized_model.

source
Base.setproperty!Function
Base.setproperty!(sam::SymbolicAWEModel, sym::Symbol, val)

Overloads setproperty! to allow direct setting of fields within the nested serialized_model. This allows you to change properties of the compiled model as if they were fields of the SymbolicAWEModel itself.

source

YAML loader internals

SymbolicAWEModels.get_field_or_nothingFunction
get_field_or_nothing(::Type{T}, row::NamedTuple,
                     field::Symbol) where T

Convert field to type T if present, otherwise return nothing.

Examples

get_field_or_nothing(Int64, row, :idx)  # -> Int64 or nothing
get_field_or_nothing(Tuple{Int64,Int64}, row, :pair)
    # -> (Int64, Int64) or nothing
source
SymbolicAWEModels.resolve_referencesFunction
resolve_references(row::NamedTuple, property_tables::Dict{String, Dict{String, NamedTuple}})

Resolve string references in a row by looking them up in property tables. If a field value is a String, check if it exists as a key in any property table. If found, merge those properties into the current row (current row takes precedence).

source
SymbolicAWEModels.call_yaml_constructorFunction
call_yaml_constructor(Constructor, row::NamedTuple,
    args_spec, kwargs_spec; mappings=Dict())

Generic YAML-to-constructor caller. Extracts positional args and kwargs from YAML row and calls constructor.

Arguments

  • Constructor: Constructor function to call
  • row::NamedTuple: Parsed YAML row
  • args_spec::Vector{Symbol}: Names for positional args
  • kwargs_spec::Vector{Symbol}: Names for kwargs

Keyword Arguments

  • mappings::Dict{Symbol, Function}: Mapping functions that take the row and return the arg value

Example

row = (idx=1, x=0.0, y=0.0, z=0.0, type="STATIC")
point = call_yaml_constructor(Point, row,
    [:idx, :pos_cad, :type],  # positional args
    [:extra_mass, :wing_idx];       # kwargs
    mappings=Dict(
        :pos_cad => r -> [Float64(r.x),
            Float64(r.y), Float64(r.z)],
        :type => r -> parse_dynamics_type(
            String(r.type))
    ))
source
SymbolicAWEModels.update_yaml_from_sys_struct!Function
update_yaml_from_sys_struct!(sys_struct::SystemStructure,
                              source_struc_yaml::AbstractString,
                              dest_struc_yaml::AbstractString,
                              source_aero_yaml::AbstractString,
                              dest_aero_yaml::AbstractString)

Update point positions in structural and aerodynamic YAML files from the current state of a SystemStructure.

Arguments

  • sys_struct: SystemStructure with current point positions
  • source_struc_yaml: Path to source structural geometry YAML file
  • dest_struc_yaml: Path to destination structural YAML file
  • source_aero_yaml: Path to source aero geometry YAML file
  • dest_aero_yaml: Path to destination aero YAML file

Source and destination paths must be different for each pair.

Example

sys = load_sys_struct_from_yaml("struc_geometry.yaml"; ...)
sam = SymbolicAWEModel(set, sys)
# ... run simulation ...
update_yaml_from_sys_struct!(sys,
    "struc_geometry.yaml",
    "struc_geometry_stable.yaml",
    "aero_geometry.yaml",
    "aero_geometry_stable.yaml")
source
SymbolicAWEModels.update_aero_yaml_from_struc_yaml!Function
update_aero_yaml_from_struc_yaml!(source_struc_yaml, source_aero_yaml,
                                   dest_aero_yaml=source_aero_yaml)

Update aero geometry YAML positions directly from structural geometry YAML, without requiring a full SystemStructure object. This is a simpler alternative to update_yaml_from_sys_struct!() when you just need to sync positions between YAML files.

Arguments

  • source_struc_yaml: Path to the structural geometry YAML file
  • source_aero_yaml: Path to the aerodynamic geometry YAML file
  • dest_aero_yaml: Destination path for updated aero YAML (defaults to source_aero_yaml for in-place updates)

Assumptions

  • LE/TE pairs are derived from the groups: section (point_idxs first=LE, last=TE)
  • Number of aero sections equals number of groups
  • Uses pos_cad coordinates from struc YAML (body-frame positions)

Example

update_aero_yaml_from_struc_yaml!(
    "data/2plate_kite/struc_geometry.yaml",
    "data/2plate_kite/aero_geometry.yaml",
    "/tmp/claude/aero_geometry_updated.yaml")
source

SystemStructure internals

SymbolicAWEModels.autocalc_tether_lenFunction
autocalc_tether_len(winch::Winch, tethers, segments)

Average unstretched tether length across all tethers connected to this winch (sum of segment l0 per tether, then average).

source
SymbolicAWEModels.resolve_refFunction
resolve_ref(ref::NameRef, name_dict::Dict{Symbol, Int64}, component_type::String) -> Int64

Resolve a reference (name or index) to an index using the name dictionary. If ref is an integer, returns it directly. If ref is a symbol, looks up in dictionary.

source
SymbolicAWEModels.resolve_ref_specFunction
resolve_ref_spec(spec, name_dict, component_type) -> Union{Int64, Vector{Int64}, Nothing}

Resolve a reference point specification (single ref or vector of refs) to indices.

source
SymbolicAWEModels.validate_sys_structFunction
validate_sys_struct(sys_struct::SystemStructure)

Validate a SystemStructure for common configuration errors.

This function checks for issues that can cause initialization failures or numerical problems during simulation. It emits warnings for suspicious configurations and throws assertions for definite errors.

Validations Performed

Point Validations

  • NaN extra_mass (error)
  • Negative extra_mass (warning)
  • Non-positive total_mass for DYNAMIC points (error) - checked before NaN position
  • NaN position (error) - often caused by zero mass

Wing Validations

  • Non-positive mass (error) - checked before NaN position
  • Zero or near-zero principal inertia components on QUATERNION wings (error/warning)
  • NaN inertia values (error)
  • Empty group list for QUATERNION wings (warning)
  • NaN position (error) - often caused by zero mass/inertia

Winch Validations

  • Zero or negative inertia_total (error)
  • Very small inertia_total (warning)
  • NaN inertia_total (error)
  • Non-positive drum_radius (error)
  • Non-positive gear_ratio (error)

Segment Validations

  • Unusual diameter outside (0, 1) m range (warning)
  • Non-positive rest length l0 (error)
  • Zero or negative stiffness (warning)
  • Negative damping (warning)

Pulley Validations

  • Zero total length constraint (error)

Group Validations

  • Inconsistent moment_frac across groups (error)
source
SymbolicAWEModels.build_name_dictFunction
build_name_dict(items::Vector) -> Dict{Symbol, Int64}

Build a name→index dictionary from a vector of items with optional name fields. Items with name=nothing are skipped. Integer names are converted to Symbols.

source
SymbolicAWEModels.identify_wing_segmentsFunction
identify_wing_segments(wing_points; groups=nothing, wing_group_idxs=nothing)

Identify wing segments (LE/TE pairs) from WING-type points.

When groups and wing_group_idxs are provided, uses group point_idxs to determine LE (point_idxs[1]) and TE (point_idxs[end]) for each section. Falls back to a consecutive-pair heuristic (sorted by point index) when groups are unavailable.

In both paths an x-coordinate check swaps LE/TE if needed (LE has smaller pos_cad[1]).

Arguments

  • wing_points::AbstractVector{Point}: WING-type points for a wing.

Keyword Arguments

  • groups::Union{Nothing, AbstractVector{Group}}: All groups in the system (indexed by wing_group_idxs).
  • wing_group_idxs::Union{Nothing, AbstractVector{<:Integer}}: Indices into groups belonging to this wing.

Returns

  • Vector{Tuple{Int64, Int64}}: (lepointidx, tepointidx) pairs.
source
SymbolicAWEModels.match_aero_sections_to_structure!Function
match_aero_sections_to_structure!(wing, points; groups)

Rebuild unrefined sections to match structural LE/TE positions, preserving refined panel polars via use_prior_polar.

Works for all VSMWing types (QUATERNION and REFINE). When the structural and aerodynamic section counts match the rebuild is a 1:1 copy (source_idx == i) that ensures positions exactly match structural points. When they differ, use_prior_polar and non-empty refined_sections are required.

For non-REFINE wings whose section count changed, the linearization vectors (vsm_y, vsm_x, vsm_jac) are resized to match the new n_unrefined_sections.

Keyword Arguments

  • groups::AbstractVector{Group}: Groups in the system (used for group-based LE/TE identification via identify_wing_segments).
source
SymbolicAWEModels.compute_spatial_group_mapping!Function
compute_spatial_group_mapping!(the_wing, groups, points)

Map groups to unrefined sections using spatial proximity. Each group is assigned to the closest unrefined section based on distance between centers.

source
SymbolicAWEModels.init_untransformed_components!Function
init_untransformed_components!(points, wings, update_vel;
                               filter=true)

Initialize pos_w = pos_cad for untransformed components. When filter=true (default), only components with transform_idx == 0 are initialized. When filter=false, all components are initialized (used when no transforms exist).

source
SymbolicAWEModels.adjust_vsm_panels_to_origin!Function
adjust_vsm_panels_to_origin!(vsm_wing, origin_offset)

Adjust VSM panel positions when body frame origin changes.

When QUATERNION wings are loaded from YAML, the panel positions in aero_geometry.yaml are specified in an absolute body frame. However, the body frame origin is adjusted to the mean position of all WING points. This function updates all panel positions to be relative to the new origin by subtracting the offset.

Arguments

  • vsm_wing: VortexStepMethod.Wing with sections to adjust
  • origin_offset: Vector [x, y, z] to subtract from panel positions
source
SymbolicAWEModels.apply_aero_z_offset!Function
apply_aero_z_offset!(vsm_wing, aero_z_offset)

Apply z-axis offset to VSM panel positions in body frame.

For QUATERNION wings, this shifts the aerodynamic center of pressure in the positive z-direction (body frame) to adjust the moment arm. This is applied AFTER the COM adjustment.

Arguments

  • vsm_wing: VortexStepMethod.Wing with sections to adjust
  • aero_z_offset: Distance to shift panels in +z direction [m]
source
SymbolicAWEModels.calc_refine_wing_frameFunction
calc_refine_wing_frame(points::Vector{Point}, z_ref_points, y_ref_points, origin_idx)

Calculate Rbto_w rotation matrix and origin position for a REFINE wing from structural point positions.

This function implements the same Rbtow calculation logic as used in `generatesystem.jlfor REFINE wings, ensuring consistency between initialization (reinit!`) and simulation (symbolic equations).

Algorithm

  1. Extract reference point positions (with averaging if vectors provided)
  2. Calculate Z-axis (normal to wing): normalized vector from zp1 to zp2
  3. Calculate X-axis (chord direction): Ytemp × Z, where Ytemp is from yp1 to yp2
  4. Calculate Y-axis (spanwise): Z × X (ensures orthogonality and right-handed system)
  5. Extract origin position from origin_idx point

Arguments

  • points::AbstractVector{Point}: All structural points (must have pos_w initialized)
  • z_ref_points::Tuple{Union{Int64, Vector{Int64}}, Union{Int64, Vector{Int64}}}: Reference points defining Z-axis (normal direction)
  • y_ref_points::Tuple{Union{Int64, Vector{Int64}}, Union{Int64, Vector{Int64}}}: Reference points defining Y-axis (spanwise direction)
  • origin_idx::Int64: Point index defining wing origin (KCU position)

Returns

  • R_b_to_w::Matrix{SimFloat}: 3x3 rotation matrix from body frame to world frame
  • origin::KVec3: Origin position in world frame
source
SymbolicAWEModels.calc_inertia_y_rotationFunction
calc_inertia_y_rotation(I_tensor)

Find the Y-axis rotation that diagonalizes the XZ block of the inertia tensor (zeros out I[1,3] and I[3,1]).

Returns (I_diag, Ry) where I_diag = Ry * I_tensor * Ry' and Ry is a rotation about the Y axis by angle θ = atan(2·I₁₃, I₁₁ − I₃₃) / 2.

source
SymbolicAWEModels.rotate_vsm_sections!Function
rotate_vsm_sections!(vsm_wing, R)

Rotate all VSM section LE/TE points by rotation matrix R.

Used during initialization to transform sections from CAD frame to body frame. After the first step, update_vsm!() updates positions from pos_b (already in body frame).

source

NamedCollection internals

SymbolicAWEModels.namesFunction
names(nc::NamedCollection)

Return a vector of all symbolic names in order of their indices. Names are nothing for unnamed items.

source

Equation builders

SymbolicAWEModels.tether_eqs!Function
tether_eqs!(eqs, tethers; len, spring_force)

Generate equations for tether stretched length and average spring force.

Arguments

  • eqs: Accumulating equation vector.
  • tethers: Collection of Tether objects.
  • len: Symbolic segment length variable.
  • spring_force: Symbolic segment spring force variable.

Returns

  • Updated eqs vector with tether equations.
source
SymbolicAWEModels.pulley_eqs!Function
pulley_eqs!(eqs, defaults, guesses, pulleys, segments, psys, pset;
            spring_force, pulley_len, pulley_vel)

Generate equations for pulley dynamics (rope distribution over pulleys).

Arguments

  • eqs, defaults, guesses: Accumulating vectors for the MTK system.
  • pulleys: Collection of Pulley objects.
  • segments: Collection of Segment objects (for mass calculation).
  • psys, pset: Symbolic parameters representing system and settings.
  • spring_force: Symbolic segment spring force variable.
  • pulley_len, pulley_vel: Symbolic pulley state variables.

Returns

  • Tuple (eqs, defaults, guesses) with updated equation vectors.
source
SymbolicAWEModels.winch_eqs!Function
winch_eqs!(eqs, defaults, winches, tethers, points, psys, pset;
           point_force, set_values, tether_len, tether_vel)

Generate equations for winch motor dynamics and tether reeling.

Arguments

  • eqs, defaults: Accumulating vectors for the MTK system.
  • winches: Collection of Winch objects.
  • tethers: Collection of Tether objects.
  • points: Collection of Point objects.
  • psys, pset: Symbolic parameters representing system and settings.
  • point_force: Symbolic point force variable.
  • set_values: Symbolic winch torque setpoint variable.
  • tether_len, tether_vel: Symbolic tether state variables.

Returns

  • Tuple (eqs, defaults) with updated equation vectors.
source
SymbolicAWEModels.group_eqs!Function
group_eqs!(eqs, defaults, guesses, groups, wings, psys, pset;
           R_b_to_w, fix_wing, twist_angle, twist_ω, group_aero_moment,
           point_force, tether_wing_moment, group_y_airf, group_chord, group_le_pos)

Generate equations for deformable wing group twist dynamics.

Arguments

  • eqs, defaults, guesses: Accumulating vectors for the MTK system.
  • groups: Collection of Group objects (deformable wing sections).
  • wings: Collection of Wing objects.
  • psys, pset: Symbolic parameters representing system and settings.
  • R_b_to_w: Symbolic rotation matrix (body to world).
  • fix_wing: Symbolic boolean for fixing wing dynamics.
  • twist_angle, twist_ω: Symbolic twist state variables.
  • group_aero_moment: Symbolic aerodynamic moment on groups.
  • point_force: Symbolic point force variable.
  • tether_wing_moment: Accumulated tether moments on wings (for validation).
  • group_y_airf, group_chord, group_le_pos: Symbolic group geometry variables.

Returns

  • Tuple (eqs, defaults, guesses) with updated equation vectors.
source

VSM and aerodynamics internals

SymbolicAWEModels.build_point_to_vsm_point_mappingFunction
build_point_to_vsm_point_mapping(wing_points::AbstractVector{Point}, vsm_wing::VortexStepMethod.AbstractWing)

Build 1:1 mapping from structural WING points to VSM wing section points (LE/TE) using closest-point distance.

For each VSM section point (LE/TE), finds the closest structural point in CAD frame.

Constraint

Requires: length(wing_points) == 2 * length(vsm_wing.unrefined_sections)

Arguments

  • wing_points::AbstractVector{Point}: Structural WING-type points
  • vsm_wing::VortexStepMethod.AbstractWing: VSM wing with sections

Returns

  • Dict{Int64, Tuple{Int64, Symbol}}: Mapping structuralpointidx -> (section_idx, :LE or :TE)

Algorithm

  1. For each section in vsm_wing.sections:
    • Find closest unused structural point to section.LEpoint → assign to (sectionidx, :LE)
    • Find closest unused structural point to section.TEpoint → assign to (sectionidx, :TE)
  2. Distance measured in CAD/body frame using norm(point.poscad - sectionpoint)
source
SymbolicAWEModels.update_vsm_wing_from_structure!Function
update_vsm_wing_from_structure!(wing::VSMWing, points::AbstractVector{Point})

Update VSM section points (LE/TE) directly from structural point positions using 1:1 mapping.

This creates two-way coupling: structural deformation → VSM sections → aero forces.

Algorithm

Uses direct 1:1 correspondence between structural points and VSM section points:

  1. For each structural WING point:
    • Calculate current position in body frame: posb = Rbtow' * (pos_w - origin)
    • Find corresponding VSM section point (LE or TE) via wing.pointtovsm_point
    • Set VSM section point directly: section.LEpoint = posb (or TE_point)

Notes

  • Section points are stored in body frame coordinates
  • wing.R_b_to_w and wing.pos_w are updated each timestep from structural geometry (symbolic equations)
  • To get world coordinates: world_pos = wing.R_b_to_w * section.LE_point + wing.pos_w

Arguments

  • wing::VSMWing: Wing with REFINE type
  • points::AbstractVector{Point}: All structural points (will filter for WING type)
source
SymbolicAWEModels.distribute_panel_forces_to_points!Function
distribute_panel_forces_to_points!(wing::VSMWing, points::AbstractVector{Point})

Distribute VSM forces to structural points using refined panel forces.

After VSM solve, each refined panel force/moment is split into corner-node forces (moment-preserving about the chosen reference) and then aggregated to the structural LE/TE points of the parent section (1:1 mapping).

Algorithm

  1. Initialize all WING point aero_forces to zero
  2. Build inverse mapping from section → LE/TE structural point indices
  3. For each refined panel of this wing:
    • Get panel force/moment from solver solution (body frame)
    • Map panel to its parent section using refined_panel_mapping
    • Split to LE/TE forces with compute_aerostruc_loads
    • Accumulate forces at the corresponding structural points

Arguments

  • wing::VSMWing: Wing with REFINE type and solved VSM state
  • points::AbstractVector{Point}: All structural points (will filter for WING type)
source

Heading and geometry

SymbolicAWEModels.solve_heading_rotationFunction
solve_heading_rotation(R_b_to_w, target_heading, k, wind_norm)

Analytical solution for heading rotation angle.

The heading components vary with rotation angle θ as: hy(θ) = A1sin(θ) + B1cos(θ) + C1 (same form for hz)

The equation hycos(h) - hzsin(h) = 0 gives: Asin(θ) + Bcos(θ) + C = 0

Solution: θ = atan2(A, B) - acos(-C / √(A² + B²))

source
SymbolicAWEModels.get_ref_position_from_pointsFunction
get_ref_position_from_points(points::AbstractVector{Point}, ref::Int64)
get_ref_position_from_points(points::AbstractVector{Point}, refs::Vector{Int64})

Helper to get position (single point or average of multiple). Used for REFINE wing reference point calculations.

source
SymbolicAWEModels.sym_calc_R_t_to_wFunction
sym_calc_R_t_to_w(wing_pos)

Symbolic version of calcRttow that uses explicit element access to avoid slice scalarization issues when nested inside norm/division operations.

source

Other internals

SymbolicAWEModels.init_principal_frame!Function
init_principal_frame!(wings, points)

Compute principal frame ODE state from body frame. Must be called after body frame (posw, Rbtow, velw, ωb) is fully initialized.

Sets: comw, Qptow, comvel, ωp (derived from body frame), and pos_b for QUATERNION wing points (body frame, relative to COM).

source
SymbolicAWEModels.update_segment_forces!Function
update_segment_forces!(sys_struct::SystemStructure)

Calculate and update spring forces for all segments in-place.

This function computes the spring-damper forces for each segment using the same formulas as in generate_system.jl. It updates the len and force fields of each segment in the SystemStructure.

The spring-damper force follows Hooke's law with damping:

\[F = k(l - l_0) - c\dot{l}\]

where:

  • k = unit_stiffness / l (tension) or k = compression_frac * unit_stiffness / l (compression)
  • l is current length, l_0 is unstretched length
  • c = unit_damping / l is damping coefficient
  • \dot{l} = (v₁ - v₂) ⋅ û is extension rate

Arguments

  • sys_struct::SystemStructure: The system structure containing points and segments.

Returns

  • nothing: Modifies segment.len and segment.force in-place.

Example

update_segment_forces!(sam.sys_struct)
for segment in sam.sys_struct.segments
    println("Segment $(segment.idx): force = $(segment.force) N")
end
source
KiteUtils.LoggerMethod
KiteUtils.Logger(sam::SymbolicAWEModel, steps::Int)

Constructs a Logger from a SymbolicAWEModel with the correct number of points.

This convenience constructor automatically calculates the total number of points including VSM panel corners (4 corners per panel) and creates a Logger with the appropriate size.

Arguments

  • sam::SymbolicAWEModel: The AWE model to create a logger for.
  • steps::Int: The number of time steps to allocate for logging.

Returns

  • Logger: A new logger with size for all points including panel corners.

Example

logger = Logger(sam, 1000)  # Instead of Logger(length(sam.sys_struct.points), 1000)
source