Reel-out runs
The building blocks of examples/simple_opt_reelout.jl, in the order a run uses them.
Running an example script
SimpleKiteControllers.run_example — Function
run_example(file; inputs...)include the example script file (relative to the package's examples/, or absolute) into Main with the keyword inputs, which the script reads with script_inputs; a plain include of the same script runs with its defaults. Returns what the include returns. A script started this way may itself run_example another one before it reads its own inputs: they are restored afterwards.
run_example("simple_opt_reelout.jl"; show_plots = false,
tos_overrides = Dict{Symbol, Any}(:max_reopt => 0))SimpleKiteControllers.script_inputs — Function
script_inputs(file, defaults::NamedTuple) -> NamedTupleThe inputs run_example passed to the script file (call it with @__FILE__), merged over defaults, which name every input the script takes. Only the script run_example was called on gets them, once: another script it includes gets its own defaults. A keyword the script does not take is an error.
SimpleKiteControllers.run_input_defaults — Function
run_input_defaults() -> NamedTupleEvery input a caller of simple_opt_reelout.jl may pass with run_example("simple_opt_reelout.jl"; ...) (see src/script_inputs.jl), at its default:
show_plots: draw the figures.run_archive: copy the log and its inputs tooutput/archives/<stamp>/.path_tr_project: a system project whose turn-rate table sizes the path,nothingfor the run's own.fcs_overrides,tos_overrides,wc_overrides,set_overrides: sweep and test overrides of the controller, optimizer, winch and plant settings.steer_disturbance,xtrack_offset,xtrack_phase,hold_compliance: test inputs of the stability and cross-track analyses.steer_gain_factor,steer_gain_feedback_only,extra_steer_delay,hook_settle: the V1 stability hook.replay_paths: a scenario folder whose optimizer results are replayed.output_path: where the log goes instead ofoutput/,nothingforoutput/.
SimpleKiteControllers.muted — Function
muted(f)Call f() with stdout and logging silenced, e.g. a run_example inside a sweep. Rebinds Base.stdout instead of redirect_stdout, which can only restore a file-backed stream and so fails, with stdout left on devnull, in a REPL whose stdout is a custom IO (e.g. Kaimon's).
SimpleKiteControllers.latest_global — Function
latest_global(name::Symbol)The global name of Main, read at the latest world age: after a run_example the script's globals were (re)defined in a newer world than the caller's code runs in.
SimpleKiteControllers.first_error_line — Function
The first line of the message err would print: a one-line reason for a progress log
Simulated-time budget
SimpleKiteControllers.reelout_budget — Function
reelout_budget(wind_speed, default_v_wind, sim_time; l_reel, kv, v_cap, wind_factor)
-> (; time, below_knot, v_nominal)Simulated time [s] to fly at the overriding wind_speed [m/s] (ground wind at h_ref).
At and above BUDGET_KNOT (the wind at BUDGET_HEIGHT, i.e. wind_speed * wind_factor) it is the reel-out budget: BUDGET_ENTRY, plus l_reel [m] of tether reeled out at BUDGET_REEL_MARGIN of the nominal speed v_nominal, plus BUDGET_TAIL. v_nominal is the winch's own law kv * sqrt(force) at the conservative force estimate BUDGET_F_COEF * (wind_speed * wind_factor)², capped by the drum's speed limit v_cap [m/s].
Below the knot, which the sqrt-law does not cover, it is sim_time [s] (the project's) scaled by the ratio of the project's default_v_wind to wind_speed, raised to BUDGET_BELOW_KNOT_EXPONENT when that ratio exceeds 1.
kv is the winch's kv and wind_factor the ratio of the wind at BUDGET_HEIGHT to the one at h_ref, from the project's profile law.
SimpleKiteControllers.sim_budget — Function
sim_budget(project, project_set, fcs, sim_time, wind_speed, default_v_wind) -> Union{Float64, Nothing}Simulated time [s] to ask init for, and the message that says how it was chosen.
With no wind-speed override (wind_speed nothing) it is sim_time (nothing: the project's own). With one, it is reelout_budget, fed with the drum's v_sat from the project's winch file, the winch's kv from the same file and the wind factor at BUDGET_HEIGHT of the project's own profile law. project_set is the project's Settings, fcs its FC_Settings (for reelout_l_max) and default_v_wind the project's wind before the override.
SimpleKiteControllers.BUDGET_HEIGHT — Constant
Height the budget's wind is taken at [m].
Feasibility gates
SimpleKiteControllers.ReeloutFeasibility — Type
ReeloutFeasibilityThe turn-rate coefficients and curvature margins a reel-out run's reference path is gated against, as returned by check_reelout_feasibility. c1, c2 and delay are NaN when the table could not serve the (body_damping, depower_setpoint) cell.
check_startup_path applies the abort policy on top of these verdicts: which check refuses the run and which only warns.
Fields
c1::Float64: Turn-rate gain of the pattern depower [1/m]c2::Float64: Turn-rate coefficientc2of the pattern depower [-]delay::Float64: Steering delay of the pattern depower's turn-rate law [s]feas_start::Union{Nothing, NamedTuple}:check_pattern_feasibleat the starting tether length,nothingwhenc1isNaNfeas_end::Union{Nothing, NamedTuple}:check_pattern_feasibleat the maximum tether length,nothingwhenc1isNaNc1_final::Float64: Turn-rate gain atdepower_final[1/m],NaNwhen unavailable or equal to the pattern'sfeas_final::Union{Nothing, NamedTuple}: What phase 5 flies: the starting path lifted byel_offset_final, scored atreelout_l_maxwithc1_final;nothingwhen unavailable
SimpleKiteControllers.Phase5MarginState — Type
Phase5MarginStateMutable state for the in-air phase-5 margin tracking during a run.
Fields
margin::Float64: Phase-5 margin of the installed path;NaNif not in the tablewarned::Bool: Whether the one warning per run has been spent
SimpleKiteControllers.c1_at — Function
c1_at(f, phase) -> Float64The turn-rate gain to score a path against at flight phase phase: from phase 5 that is f.c1_final (the depower flown then, ~22 % less authority than the pattern's), before that f.c1. Falls back to the pattern's c1 whenever the table could not serve depower_final.
c1_at(f, phase, c1) -> Float64The turn-rate gain to check a path against at flight phase phase, given c1, the table's gain at the depower asked about: the depower a reply carries (a candidate's own, when scoring it) or the one currently flown (when sizing a request). From phase 5 that is depower_final's, c1_at(f, phase); before that c1, falling back to the startup law f.c1 when c1 is NaN, a depower the table cannot serve.
SimpleKiteControllers.phase5_margin — Function
phase5_margin(f, az, el) -> Float64What phase 5 will fly a candidate path (az, el) with: its curvature margin at depower_final's c1 and at reelout_l_max, the length the final laps happen at. Evaluated at install time, because the path installed during the LAST reel-out lap is the one phase 5 inherits. NaN when the table could not serve depower_final.
NOT comparable to an install's own margin, which is read at the current length: early in the reel-out the two differ by length more than by depower, converging as the length approaches reelout_l_max. The number worth watching is the last one, where only the depower is left.
SimpleKiteControllers.check_reelout_feasibility — Function
check_reelout_feasibility(fec, fcs, tos; l_tether) -> ReeloutFeasibilityScore an optimized reference path against the three static gates a reel-out run needs, WITHOUT applying any policy: no error, no abort decision. Returns the verdicts; the caller decides what refuses the run and what only warns.
Checks performed (all reported via @info/@warn here):
- elevation floor — the path's lowest elevation against
fcs.run.min_elevation + tos.gates.candidate_elevation_margin; - ground clearance —
check_pattern_heightatl_tether, whentos.gates.min_height > 0; - turn-rate coefficients for
(fcs.run.body_damping, depower)—depoweris the one the pattern is FLOWN at,fcs.course.depower_setpointunless the caller flies the optimizer's own, where a reply judged at the setpoint's c1 is off byc1(flown)/c1(setpoint), ~22 % at 0.33 against 0.274 (Cabauw 8 m/s, 2026-09-18); a cell the table cannot serve costs the diagnosis, not the run (warned, coefficients becomeNaN); - curvature at the STARTING length (the worst case for one fixed path) and at
fcs.reelout.reelout_l_max, plus the dead-time context forfcs.pattern.attractor_dist; - phase 5 — the same path lifted by
fcs.reelout.el_offset_final, scored atdepower_final's ownc1(looked up separately; warned, not refused).
SimpleKiteControllers.check_startup_path — Function
check_startup_path(fec, fcs, tos; l_tether, depower = fcs.course.depower_setpoint)
-> ReeloutFeasibilityThe abort policy on the startup path installed in fec: the gates of check_reelout_feasibility that REFUSE a reel-out run rather than only warn, each an error that says why. Returns the verdicts when the path passes.
- The ELEVATION floor,
fcs.run.min_elevation + tos.gates.candidate_elevation_margin: this repo's own criterion is an angle andfig8_metricsfails a run that breaks it. AWETrim constrains height and not elevation, so this is not something the solve avoids on its own. - The clearance floor
tos.gates.min_heightatl_tether, when set: the optimizer earns part of itsmin_heightby reeling out within the lap, which an installed (azimuth, elevation) curve does not, so it must be told here rather than flown past. - The curvature margin at the STARTING length against
tos.gates.min_feasibility_margin, at the depower the pattern is FLOWN at (depower): the optimizer knows nothing of the V3's turn-rate law, so a path the kite cannot turn along is a plausible thing for it to return, and flying it measures the steering clamp instead of the path. Skipped when the table cannot servedepower(feas_startisnothing).
Run state and loop
SimpleKiteControllers.RunSetup — Type
RunSetupEverything one reel-out run of examples/simple_opt_reelout.jl READS, built once by setup_run: the settings, the plant s, the winch and its controllers, the optimizer's conditions and session, and the laws the gates and the loop read. Every function of the run takes it as setup and reads setup.<field> or destructures it. The script never rebinds it; mutable members (fcs, wc, s, fec, the opt_*_log vectors, ...) are changed in place.
The last block of fields is filled later, by the startup solve (solve_startup_path!) and the startup gates (startup_feasibility), through merge_into!; until then they hold their defaults. The type parameters are the plant's type S, which the package does not know, and the two turn-rate laws, read every step, so that the loop compiles against their concrete types.
The block functions of the run read their fields by name only, so a NamedTuple with the fields a function reads serves as well (the unit tests build them that way).
Fields
inputs::NamedTuple: The caller's inputs, merged over the defaultsshow_plots::Bool: Whether the run shows its plots at the endsteer_disturbance::Union{Nothing, Function}: Test input: t -> Δu added to the steeringxtrack_offset::Union{Nothing, Function}: Test input: τ -> δ [deg], the attractor moved along the path normalxtrack_phase::Int64: The phasextrack_offsetstarts inhold_compliance::Union{Nothing, NamedTuple}: Test input: (; gain, τF, τpos) of a compliant hold in phase 5steer_gain_factor::Float64: V1 hook: factor on the steeringsteer_gain_feedback_only::Bool: The factor on the feedback part onlyextra_steer_delay::Int64: V1 hook: extra steering delay [samples]hook_settle::Float64: [s] after phase 4 began, when the V1 hooks startreplay_paths::Union{Nothing, String}: Scenario folder whose optimizer answers are replayedproject_name::String: Systemreelout*.yamlturbulence::Union{Float64, String}: Level in [0, 1], or "default"project::String: Its filefcs::FC_Settings: The controller's settings, overrides appliedtos::TrajOptSettings: The optimizer's settings, overrides appliedproject_set::KiteUtils.Settings: The kite's settings, the wind override appliedl_tether::Float64: [m] the starting tether length of the settingseffective_sim_time::Float64: [s] asked ofinit, seesim_budgetoutput_path::String: Where the log, the summary and the marker gorun_done_file::String: The finished-run marker, seewrite_run_donelog_name::String: The log's name,<log_file>_optwc::WinchControllers.WCSettings: The ONE winch settings of both winch loopswpc::WinchControllers.WinchPosController: The length loop of the plant's winchdt0::Float64: [s] 1 / sample_freqrcs::WinchControllers.WCSettings: The same object aswc, as the reel-out controller reads its::Any: The plant, built by the caller'sinit_modelrc::WinchControllers.WinchController: The reel-out winch controllerf_high_nominal::Float64: [N] the force ceiling before the first-lap reductionguard_lfc::WinchControllers.LowerForceController: The force floor before the reel-outl_set::Real: [m] the settled length, as the plant reports it (Float32 for V3Kite); the startup request sends it unconvertedfec::FigureEightController: The path in the air and the guidance on itinflow::SimpleKiteControllers.InflowConditions: The wind sent with every requestcap_wind::Float64: [m/s] the wind the pattern box is sized atwinch::SimpleKiteControllers.WinchParams: The winch sent with the startup solvewinch_first_lap::SimpleKiteControllers.WinchParams: The same under the first-lap force limitwinch_reopt::SimpleKiteControllers.WinchParams: The winch sent with the re-optimizationsel_center_seed_base::Float64: [deg] centre elevation of the shipped guessel_center_seed::Float64: [deg] the seed's centre, aftersolve_startup_path!the one it converged fromopt_chain::SimpleKiteControllers.OptChain: The session with the optimizer, and its cachesopt_r_scale::Float64: [-] anchor ratio and headroom of the turn-radius requestopt_r_min::Union{Nothing, Float64}: [m] the startup turn-radius request; nothing when offopt_r_on::Bool: Whether a turn radius is requestedopt_r_sent::Union{Nothing, Float64}: [m] the radius the startup solve was sentopt_box::Union{Nothing, SimpleKiteControllers.PatternLimits}: The pattern box sent; nothing when offopt_depower_log::Vector{NamedTuple}: Every reply's depowerpower_gate_off::Function: Pred -> whether the power gates are bypassed for a prediction [W]wing_lift::Function: (az, el) -> the lobe lift [deg] of an installed pathc1_at_depower::Any: Depower -> turn-rate gain c1 [1/m] of the path side; NaN off the tablec1_ctrl_at::Any: Depower -> c1 [1/m] of the controller's table; NaN off itc1_setpoint::Float64: [1/m] c1 at the depower setpoint, the loop's tuning pointc1_depower_max::Float64: [-] the highest depower of the controller's tablepattern_depower::Function: Reply -> the depower its path is flown atel_floor::Float64: [deg] the elevation floor of every candidate pathstartup_seed_offset::Float64: [deg] offset of the seed the startup solve converged fromguess_az::Vector{Float64}: That seed's guess, azimuth [deg]guess_el::Vector{Float64}: That seed's guess, elevation [deg]opt_startup_solve_s::Float64: [s] wall time of the startup solvefeas::Union{Nothing, ReeloutFeasibility}: The startup gates' verdictmargin5::Union{Nothing, Phase5MarginState}: The in-air phase-5 checkc1_at_phase::Union{Nothing, Function}: (phase, depower | st) -> c1 [1/m] to check a path againstphase5_margin_at::Union{Nothing, Function}: (az, el) -> the margin phase 5 flies a path with
SimpleKiteControllers.RunState — Type
RunStateEverything the startup functions and the simulation loop of examples/simple_opt_reelout.jl WRITE, in one place, so they take it as an argument (st) instead of rebinding script globals. The loop-only bookkeeping is grouped as in the loop. startup_feasibility and reelout_results.jl read the fields as st.<field>, and so does DelayedInjection in validate_margins.jl, during the loop: st is the one global of the run's state. Plain data: no model type, so the package can define it without depending on the model.
Fields
opt_result::Union{Nothing, SimpleKiteControllers.StepReply}: The reply the run flies (startup, or the retry that took over)opt_table::Union{Nothing, Dict{String, Any}}: Its /trajectory tableopt_downloops::Union{Nothing, Bool}: Whether the flown path turns downwards in the loops, from its /trajectory tableopt_power_pred::Float64: [W] predicted mean reel-out power of the installed pathopt_paths_raw::Vector{Tuple{Vector{Float64}, Vector{Float64}}}: Every optimizer answer as it arrived, before any liftopt_paths_at::Vector{Tuple{Float64, Int64}}: (sim time [s], phase) each of those was installed atopt_r_scale::Union{Nothing, Float64}: Anchor ratio x headroom of the turn-radius requestopt_r_min::Union{Nothing, Float64}: [m] turn-radius request, or nothingopt_box_now::Union{Nothing, SimpleKiteControllers.PatternLimits}: Pattern limits sent with the last re-optimization requestincumbent_score::Union{Nothing, @NamedTuple{margin::Float64, el_ok::Bool, clr_ok::Bool, height::Float64, ok::Bool}}: Score of the best startup path so farinc_result::Union{Nothing, SimpleKiteControllers.StepReply}: The reply of the best startup path so far (the incumbent)inc_table::Union{Nothing, Dict{String, Any}}: The incumbent's /trajectory tableinc_raw::Union{Nothing, Tuple{Vector{Float64}, Vector{Float64}}}: The incumbent's path as the optimizer sent itstartup_wing_frac::Float64: Share of the lobe lift the startup path could carryc1_startup::Float64: [-] turn-rate gain the startup path is checked againstdepower_flown_opt::Float64: [-] rel_depower the optimizer asked forn_path_initial::Int64: Number of points of the path installed before the runpath_min_h_start::Float64: Lowest height of the startup path at the starting tether length [m]az_c_path::Float64: Azimuth centre of the startup path [deg]el_c_path::Float64: Elevation centre of the startup path [deg]az_amp_path::Float64: Azimuth half-width of the startup path [deg]el_height_path::Float64: Elevation span (peak to peak) of the startup path [deg]pred_timeline::Vector{@NamedTuple{t::Float64, power::Float64}}: (; t, power): which path was flown whenp5_history::Vector{@NamedTuple{t::Float64, az::Vector{Float64}, el::Vector{Float64}, raw::Tuple{Vector{Float64}, Vector{Float64}}, margin::Float64, el_applied::Float64}}: Every path flown, for the phase-5 fallbackp5_fallback_done::Bool: Checked once, from the stop latch on, at the next crossingp5_q_az_prev::Float64: [deg] Q's azimuth from the path centre, last stepp5_fallback::Union{Nothing, @NamedTuple{t::Float64, from_margin::Float64, to_margin::Float64, to_t::Float64}}: (; t, frommargin, tomargin, to_t) when a fallback was blended inccs::Union{Nothing, CourseControllerSettings}: Course controller settingscc::Union{Nothing, CourseController}: Course controllerl_set::Float64: [m] tether length setpointtransition_start::Float64: [s] time phase 3 began;reelout_delaycounts from itstop_start::Float64: [s] time the soft-stop deceleration latched; NaN = not yetstop_v_entry::Float64: [m/s] v_set at the moment it latchedstop_dp_entry::Float64: [-] rel_depower at the moment it latchedstop_T::Float64: [s] duration of the linear decel to reach 0 at reeloutlmaxreelout_started::Bool: True once the gate has opened; LATCHED, never re-closesreelout_start_t::Float64: [s] time it opened; the soft-start ramp counts from herereelout_trigger_fired::Bool: True if the FORCE trigger opened it, not the timerreelout_done::Bool: True once either stop criterion has ended reel-outstop_reason::String: "length", "laps", or "" if reel-out never stoppedfinal_start::Float64: [s] time phase 5 began; the run endsfcs.reelout.final_timeafter ite_mech::Float64: [Wh] running mechanical energy, logged for the viewerfirst_lap_f_high_applied::Bool: Whether the first-lap reduction of the upper force limit is in forceff_log::Vector{Float64}: [-] feed-forward steering per stepff_chi_log::Vector{Float64}: [rad] chord correction per stepff_u_filt::Float64: [-] low-passed feed-forward steeringff_chi_filt::Float64: [rad] low-passed chord correctiondp_final_extra::Float64: [-] phase-5 force limiter's depower above depower_finaldp_final_extra_peak::Float64: [-] the most it asked for, for the summaryrel_depower_prev::Float64: [-] depower commanded last step; the gain reads c1 theredepower_flown::Float64: [-] current blended outputdepower_blend_from::Float64: Depower the current blend started from [-]depower_blend_to::Union{Nothing, Float64}: Depower the current blend goes to [-];nothingwhen none is in progressdepower_blend_t0::Float64: Time the current depower blend started [s]fig8_n::Int64: Live lap count: 0 before phase 4, 1 at first entry, +1 per traversalfig8_idx_prev::Int64: Index of Q on the path at the previous stepfig8_idx_progress::Float64: Path points Q has advanced since phase 4 began, for the lap countn_path::Int64: Number of points of the installed pathraw_az::Union{Nothing, Vector{Float64}}: Azimuth of the reference TRACKING is scored against [deg]raw_el::Union{Nothing, Vector{Float64}}: Elevation of the reference TRACKING is scored against [deg]chk_points::Int64: Resolution the path in the air is checked atel_applied::Float64: [deg] lift the path in the air actually carrieslift_on::Bool:el_offset_finallatched in; never cleared once setel_shift_events::Vector{NamedTuple}: In-air shift attempts, one per outcome CHANGElift_t::Float64: [s] when it latched; NaN = neverlift_remaining::Float64: [m] of reel-out left at that momentel_shift_warned::Bool: A held-back shift warns onceel_shift_lap::Int64: Lap of the last in-air shift attemptel_shift_target::Float64: Elevation target of the last in-air shift attempt [deg]geom_t::Vector{Float64}: Time of each logged step [s]geom_az_c::Vector{Float64}: Azimuth centre of the pattern asked for at each step [deg]geom_az_amp::Vector{Float64}: Azimuth half-width of the pattern asked for at each step [deg]geom_el_h::Vector{Float64}: Elevation span of the pattern asked for at each step [deg]geom_d_raw::Vector{Float64}: Cross-track error to the scored referencen_droop_bins::Int64: Number of |azimuth| bins of the droop statistics: where in the pattern the kite ends up lowdroop_n::Vector{Int64}: Number of samples in each |azimuth| bindroop_flown::Vector{Float64}: [deg] kite below the path's elevation centredroop_ref::Vector{Float64}: [-] depth of the path at Q, in half-spansdroop_sag::Vector{Float64}: [deg] kite below the path at Qreopt_pending::Bool: A solve is queued on the serverreopt_n::Int64: Solves completed, accepted or rejectedreopt_lap::Float64: Lap count at which the last request went outreopt_next_poll::Float64: [s] next /status pollreopt_t_request::Float64: [s] when the pending request went outreopt_blocked_s::Float64: [s] wall time spent frozen waiting for a replyreopt_last_solve_s::Float64: [s] wall time the last blocking wait tookreopt_events::Vector{NamedTuple}: One row per solve, for the run summaryreopt_t_wall_request::Float64: [s] time() when the cycle's first request went outreopt_cycles::Vector{NamedTuple}: (; t, l, status, wall_s) per completed cycleblend_retries_total::Int64: Cold-restart attempts spent on a rejected replychallenges_total::Int64: Cold challenger solves run against an accepted reply (challenge_growth)challenges_won::Int64: Challenger solves that were installed instead of the reply they challengedel_min_extra::Float64: [deg] shortfall of the last reply gated out; carried across cyclesblend_from::Union{Nothing, Tuple{Vector{Float64}, Vector{Float64}}}: The path the blend in progress starts from; fold-free across w in [0, 1]blend_to::Union{Nothing, Tuple{Vector{Float64}, Vector{Float64}}}: The path the blend in progress goes toblend_t0::Float64: Time the blend in progress started [s]raw_from::Union{Nothing, Tuple{Vector{Float64}, Vector{Float64}}}: The scored reference's endpoint the SAME blend starts fromraw_to::Union{Nothing, Tuple{Vector{Float64}, Vector{Float64}}}: The scored reference's endpoint the blend goes tot_phase4::Float64: [s] time phase 4 was first reached this run; NaN before thatxt_start::Float64: [s] first step of phasextrack_phase; τ counts from herehold_f_lp::Float64: [N] low-passed force of the compliant holdhold_l0::Float64: [m] length the compliant hold began atdist_t::Vector{Float64}: [s] time of each disturbed stepdist_d::Vector{Float64}: [-] disturbance addeddist_u::Vector{Float64}: [-] steering sent to the model, controller plus disturbancesteer_delay_buf::Vector{Float64}: FIFO of the raw steering commands, kept full of the lastextra_steer_delayof them from the start of the run, so it is already primed with real history by the time the hook switches on. The feed-forward goes through a FIFO of its own, so the two stay aligned.
ff_delay_buf::Vector{Float64}: FIFO of the feed-forward steering, delayed likesteer_delay_bufxt_t::Vector{Float64}: [s] time of each phase-5 stepxt_delta::Vector{Float64}: [deg] offset commandedxt_d::Vector{Float64}: [deg] signed cross-track error to the unshifted path, right of travel > 0xt_q::Vector{Int64}: [-] index of the closest path point Qxt_phase::Vector{Int64}: [-] flight phase, and the operating point for the model:xt_L::Vector{Float64}: [m] tether lengthxt_va::Vector{Float64}: [m/s] apparent wind speedxt_vk::Vector{Float64}: [m/s] kite speed normal to the tetherxt_dp::Vector{Float64}: [-] depowerfig8m::Union{Nothing, NamedTuple}: The scored verdict, oncereelout_resultshas itopt_power_meas::Union{Nothing, Float64}: [W] measured mean reel-out power, or nothingarchive_dir::String: The run's archive folder, "none" until (or unless) it exists
SimpleKiteControllers.step_commands! — Function
step_commands!(st, setup, plant, t) -> (; rel_depower, rel_steering, v_set, phase, guide, cmd)Everything of one step of the reel-out loop before the model is stepped: the attractor guidance (guide, from navigate_fig8, with the cross-track test input), the steering and depower (cmd, see steering_command!), the lift target, the lap count, the re-optimization, the path blends, the phase-5 fallback, the winch setpoint v_set and the steering hooks. plant is the model as read at the start of the step, see the top of this file.
SimpleKiteControllers.record_step! — Function
record_step!(st, setup, plant, t, commands)After step!, which overwrites parts of sys_state: the controller's view of the step in the log's slots (commands from step_commands!), the path geometry logs and the running e_mech.
SimpleKiteControllers.check_overspeed — Function
check_overspeed(setup, plant) -> Boolv_app above v_app_abort, reported: the run stops rather than wait for the opaque solver abort it causes later.
Run log and startup retries
SimpleKiteControllers.with_run_log — Function
with_run_log(f, path; min_level = Info)Run f() with its log messages shown as usual and also written to path, message by message, so the file is complete up to a crash. A throw is written as a last [ Error: the run threw: … line and rethrown. The parent folder is created. Returns what f returns.
SimpleKiteControllers.startup_ladder_report — Function
startup_ladder_report(log) -> NamedTupleWhat a run log of simple_opt_reelout.jl (log is the file written by with_run_log, or its text) says about the two retry paths of the startup:
seed_retries: startup solves sent again from another seed after a 422 (startup_retry_el_offsets), andseed_offset, the offset the solve converged from (nothingfor the shipped guess);ladder: whetherretry_startup!ran, atmargin_inagainst the gategate, and per attemptattempts,lever => outcomewith the outcome"422","took over","took over, cleared","no better"or"below a floor"(each with its margin), andstoppedwhen the levers ran out;margin_start: the startup margin the run went on with, andthrew, the first line of the error a run that stopped there threw (nothingotherwise).
ladder_line(report) is the one-line form.
SimpleKiteControllers.ladder_line — Function
ladder_line(report) -> Stringstartup_ladder_report in one line, e.g. startup: ladder at margin 0.979 < 1.30, 4 retries [radius correction: 422, ceiling step: 422, …], levers spent; flew margin 1.04; threw ….
SimpleKiteControllers.startup_log_lines — Function
startup_log_lines(log) -> Vector{String}The startup section of a run log (see with_run_log), as two runs of the same code with the same optimizer answers write it: the messages up to the first progress line of the loop (step …), without their continuation lines, without the optimizer client's transport messages (RE_TRANSPORT, which differ between a server run and a cached one), and with wall times (… s), file time stamps, the folder of saved trajectories (…/trajectories/, which differs between checkouts) and the SimpleKiteControllers. prefix of printed types (shown only when Main does not import the type) masked.