Introduction
Most of the functions work on a KPS3 or KPS4 object. For this, the variable s is used. Such a variable can be created with the lines:
using KiteSimulators
set = load_settings("system.yaml")
s = KPS3(KCU(set))Or, if you want to use the 4 point kite model:
using KiteSimulators
set = load_settings("system.yaml")
s = KPS4(KCU(set))Or, if you want to use the ram-air kite model:
set = load_settings("system_ram.yaml")
s = SymbolicAWEModel(set)Functions with an "!" as last character of the function name modify one of more of their parameters, in this context mostly the variable s.
Input functions
KiteModels.set_depower_steering! — Function
set_depower_steering!(s::SymbolicAWEModel, depower, steering) -> NothingSet kite depower and steering by adjusting tether lengths. Depower controls angle of attack, steering controls left/right differential. Values are scaled by minimum chord length.
set_depower_steering!(s::AKM, depower, steering)Setter for the depower and steering model inputs.
Parameters:
- depower: Relative depower, must be between 0 .. 1.0
- steering: Relative steering, must be between -1.0 .. 1.0.
This function sets the variables s.depower, s.steering and s.alpha_depower.
It takes the depower offset c0 and the dependency of the steering sensitivity from the depower settings into account. The raw steering value is stored in s.kcu_steering.
KiteModels.set_v_wind_ground! — Function
set_v_wind_ground!(s::SymbolicAWEModel, v_wind_gnd=s.set.v_wind, upwind_dir=-π/2) -> NothingSet ground wind speed (m/s) and upwind direction (radians). Direction: 0=north, π/2=east, π=south, -π/2=west (default).
set_v_wind_ground!(s::AKM, height, v_wind_gnd=s.set.v_wind; upwind_dir=-pi/2)Set the vector of the wind-velocity at the height of the kite. As parameter the height, the ground wind speed [m/s] and the upwind direction [radians] are needed. Is called by the function next_step!.
Output functions
KiteModels.unstretched_length — Function
unstretched_length(s::AKM)Getter for the unstretched tether reel-out length (at zero force).
KiteModels.tether_length — Function
tether_length(s::AKM)Calculate and return the real, stretched tether length.
KiteModels.pos_kite — Function
pos_kite(s::KPS4)Return the position of the kite (top particle).
pos_kite(s::KPS3)Return the position of the kite (top particle).
KiteModels.calc_aoa — Function
Calculate and return the angle of attack in rad
KiteModels.calc_height — Function
calc_height(s::KPS4)Determine the height of the topmost kite particle above ground.
calc_height(s::KPS3)Determine the height of the kite particle above ground.
KiteUtils.calc_elevation — Function
calc_elevation(s::AKM)Determine the elevation angle of the kite in radian.
KiteModels.calc_azimuth — Function
calc_azimuth(s::AKM)Determine the azimuth angle of the kite in wind reference frame in radian. Positive anti-clockwise when seen from above.
KiteModels.calc_azimuth_east — Function
calc_azimuth_east(s::AKM)Determine the azimuth_east angle of the kite in radian. Positive clockwise when seen from above.
KiteModels.calc_azimuth_north — Function
calc_azimuth_north(s::AKM)Determine the azimuth_north angle of the kite in radian. Positive anti-clockwise when seen from above.
KiteUtils.calc_heading — Function
calc_heading(s::AKM; upwind_dir_=upwind_dir(s), neg_azimuth=false, one_point=false)Determine the heading angle of the kite in radian.
KiteUtils.calc_course — Function
calc_course(s::AKM)Determine the course angle of the kite in radian. Undefined if the velocity of the kite is near zero.
KiteModels.cl_cd — Function
cl_cd(s::KPS4)Calculate the lift and drag coefficients of the kite, based on the current angles of attack.
cl_cd(s::KPS3)Calculate the lift and drag coefficients of the kite, based on the current angles of attack.
KiteModels.winch_force — Function
winch_force(s::KPS4)Return the absolute value of the force at the winch as calculated during the last timestep.
winch_force(s::KPS3)Return the absolute value of the force at the winch as calculated during the last timestep.
KiteModels.spring_forces — Function
spring_forces(s::AKM)Return an array of the scalar spring forces of all tether segements.
KiteModels.lift_drag — Function
lift_drag(s::AKM)Return a tuple of the scalar lift and drag forces.
Example:
lift, drag = lift_drag(s)KiteModels.lift_over_drag — Function
lift_over_drag(s::AKM)Return the lift-over-drag ratio.
KiteModels.v_wind_kite — Function
v_wind_kite(s::AKM)Return the vector of the wind speed at the height of the kite.
KiteModels.kite_ref_frame — Function
kite_ref_frame(s::KPS4; one_point=false)Returns a tuple of the x, y, and z vectors of the kite reference frame.
kite_ref_frame(s::KPS3)Returns a tuple of the x, y, and z vectors of the kite reference frame.
KiteModels.orient_euler — Function
orient_euler(s::AKM)Calculate and return the orientation of the kite in euler angles (roll, pitch, yaw) as SVector.
KiteUtils.SysState — Type
SysState(s::AKM, zoom=1.0)Constructor for creating a SysState object from a kite model (KPS3 or KPS4). The SysState object can be used either for logging or for displaying the system state in a viewer. Optionally the position arrays can be zoomed according to the requirements of the viewer.
High level simulation interface
KiteUtils.init! — Function
init!(s::SymbolicAWEModel; solver=nothing, adaptive=true, prn=true,
precompile=false, remake=false, reload=false,
lin_outputs=Num[]) -> OrdinaryDiffEqCore.ODEIntegratorInitialize a kite power system model.
If a serialized model exists for the current configuration, it will load that model and only update the state variables. Otherwise, it will create a new model from scratch.
Fast path (serialized model exists):
- Loads existing ODEProblem from disk
- Calls
reinit!to update state variables - Sets up integrator with initial settings
Slow path (no serialized model):
- Creates symbolic MTK system with all equations
- Simplifies system equations
- Creates ODEProblem and serializes to disk
- Proceeds with fast path
Arguments
s::SymbolicAWEModel: The kite system state object
Keyword arguments
solver: Solver algorithm to use. Ifnothing, defaults toFBDF()orQNDF()based ons.set.solver.adaptive::Bool=true: Whether to use adaptive time stepping.stiffness_factor=nothing: ignored, for backwards compatibilitydelta=nothing: ignored, for backwards compatibilityprn::Bool=true: Whether to print progress information.precompile::Bool=false: Whether to build problem for precompilation.remake::Bool=false: If true, forces the system to be rebuilt, even if a serialized model exists.reload::Bool=false: If true, forces the system to reload the serialized model from disk.lin_outputs::Vector{Num}=Num[]: List of symbolic variables for which to generate a linearization function.
Returns
integrator::OrdinaryDiffEqCore.ODEIntegrator: The initialized ODE integrator.
init!(s::AKM; stiffness_factor=0.5, delta=0.0001,
prn=false) -> OrdinaryDiffEqCore.ODEIntegratorInitializes the integrator of the model (KPS3 and KPS4 only).
Parameters:
- s: an instance of an abstract kite model
- stiffness_factor: factor applied to the tether stiffness during initialization
- delta: initial stretch of the tether during the steady state calculation
- prn: if set to true, print the detailed solver results
Returns: An instance of an ODEIntegrator.
KiteUtils.next_step! — Function
next_step!(s::SymbolicAWEModel, integrator::ODEIntegrator; set_values=nothing, upwind_dir=nothing, dt=1/s.set.sample_freq, vsm_interval=1)Take a simulation step, using the internal integrator.
This function performs the following steps:
- Optionally update the set values (control inputs)
- Optionally update the upwind direction
- Optionally linearize the VSM (Vortex Step Method) model
- Step the ODE integrator forward by
dtseconds - Check for a successful return code from the integrator
- Increment the iteration counter
Arguments
s::SymbolicAWEModel: The kite power system state objectintegrator::ODEIntegrator: The ODE integrator to use
Keyword Arguments
set_values=nothing: New values for the set variables (control inputs). Ifnothing, the current values are used.dt=1/s.set.sample_freq: Time step size in seconds. Defaults to the inverse of the sample frequency.vsm_interval=1: Interval (in number of steps) at which to linearize the VSM model. If 0, the VSM model is not linearized.
Returns
Nothing
next_step!(s::AKM, integrator; set_speed = nothing, set_torque=nothing, set_force=nothing, bearing = nothing
attractor=nothing, v_wind_gnd=s.set.v_wind, upwind_dir=-pi/2, dt=1/s.set.sample_freq)Calculates the next simulation step. Either set_speed or set_torque must be provided.
Parameters:
- s: an instance of an abstract kite model
- integrator: an integrator instance as returned by the function
init! - set_speed: set value of reel out speed in m/s or nothing
- set_torque: set value of the torque in Nm or nothing
- set_force: set value of the force in N or nothing (only for logging, not used otherwise)
- bearing: set value of heading/ course in radian or nothing (only for logging, not used otherwise)
- attractor: the attractor coordinates [azimuth, elevation] in radian or nothing (only for logging)
v_wind_gnd: wind speed at reference height in m/supwind_dir: upwind direction in radians, the direction the wind is coming from. Zero is at north; clockwise positive. Default: -pi/2, wind from west.- dt: time step in seconds
Returns: Nothing
Low level simulation interface
KiteModels.clear! — Function
clear!(s::KPS4)Initialize the kite power model.
clear!(s::KPS3)Initialize the kite power model.
KiteModels.find_steady_state! — Function
find_steady_state!(s::KPS4; prn=false, delta = 0.01, stiffness_factor=0.035, upwind_dir=-pi/2))Find an initial equilibrium, based on the initial parameters l_tether, elevation and v_reel_out.
find_steady_state!(s::KPS3; prn=false, delta = 0.0, stiffness_factor=0.035, upwind_dir=-pi/2)Find an initial equilibrium, based on the initial parameters l_tether, elevation and v_reel_out.
KiteModels.residual! — Function
residual!(res, yd, y::MVector{S, SimFloat}, s::KPS4, time) where S
N-point tether model, four points for the kite on top:
Inputs:
State vector y = pos1, pos2, ... , posn, vel1, vel2, . .., veln, length, v_reel_out
Derivative yd = posd1, posd2, ..., posdn, veld1, veld2, ..., veldn, lengthd, v_reel_outd
Output:
Residual res = res1, res2 = vel1-posd1, ..., veld1-acc1, ...,
Additional parameters:
s: Struct with work variables, type KPS4
S: The dimension of the state vectorThe number of the point masses of the model N = S/6, the state of each point is represented by two 3 element vectors.
residual!(res, yd, y::MVector{S, SimFloat}, s::KPS3, time) where S
N-point tether model, one point kite at the top:
Inputs:
State vector y = pos1, pos2, ..., posn, vel1, vel2, ..., veln
Derivative yd = vel1, vel2, ..., veln, acc1, acc2, ..., accn
Output:
Residual res = res1, res2 = pos1, ..., vel1, ...
Additional parameters:
s: Struct with work variables, type KPS3
S: The dimension of the state vectorThe number of the point masses of the model N = S/6, the state of each point is represented by two 3 element vectors.
Helper functions
KiteModels.copy_examples — Function
copy_examples()Copy all example scripts to the folder "examples" (it will be created if it doesn't exist).
KiteModels.copy_bin — Function
copy_bin()Copy the scripts createsysimage and run_julia to the folder "bin" (it will be created if it doesn't exist).
KiteModels.calc_drag — Function
calc_drag(s::KPS3, v_segment, unit_vector, rho, last_tether_drag, v_app_perp)Calculate the drag of one tether segment, result stored in parameter last_tether_drag. Return the norm of the apparent wind velocity.
KiteModels.calculate_rotational_inertia! — Function
calculate_rotational_inertia!(s::AKM, include_kcu::Bool=true, around_kcu::Bool=false)Calculate the rotational inertia (Ixx, Ixy, Ixz, Iyy, Iyz, Izz) for a kite model from settings. Modifies the kite model by initializing the masses.
Parameters:
- X: x-coordinates of the point masses.
- Y: y-coordinates of the point masses.
- Z: z-coordinates of the point masses.
- M: masses of the point masses.
include_kcu: Include the kcu in the rotational inertia calculation?around_kcu: Uses the kcu as the rotation point.
Returns: The tuple Ixx, Ixy, Ixz, Iyy, Iyz, Izz where:
- Ixx: rotational inertia around the x-axis.
- Ixy: rotational inertia around the xy-plane.
- Ixz: rotational inertia around the xz-plane.
- Iyy: rotational inertia around the y-axis.
- Iyz: rotational inertia around the yz-plane.
- Izz: rotational inertia around the z-axis.
KiteModels.calc_set_cl_cd! — Function
calc_set_cl_cd!(s::KPS3, vec_c, v_app)Calculate the lift over drag ratio as a function of the direction vector of the last tether segment, the current depower setting and the apparent wind speed. Set the calculated CL and CD values in the struct s.
KiteModels.calc_aero_forces! — Function
calc_aero_forces!(s::KPS4, pos, vel, rho, alpha_depower, rel_steering)Calculates the aerodynamic forces acting on the kite particles.
Parameters:
- pos: vector of the particle positions
- vel: vector of the particle velocities
- rho: air density [kg/m^3]
- rel_depower: value between 0.0 and 1.0
- alpha_depower: depower angle [degrees]
- rel_steering: value between -1.0 and +1.0
Updates the vector s.forces of the first parameter.
KiteModels.calc_particle_forces! — Function
calc_particle_forces!(s::KPS4, pos1, pos2, vel1, vel2, spring, segments, d_tether, rho, i)Calculate the drag force of the tether segment, defined by the parameters pos1, pos2, vel1 and vel2 and distribute it equally on the two particles, that are attached to the segment. The result is stored in the array s.forces.
KiteModels.inner_loop! — Function
inner_loop!(s::KPS4, pos, vel, v_wind_gnd, segments, d_tether)Calculate the forces, acting on all particles.
Output:
- s.forces
s.v_wind_tether
KiteModels.loop! — Function
loop!(s::KPS4, pos, vel, posd, veld)Calculate the vectors s.res1 and calculate s.res2 using loops that iterate over all tether segments.