Internals

Non-exported names that the docstrings of the other API pages refer to.

SimpleKiteControllers.RETIRED_YAML_KEYS — Constant

Keys that were removed from the settings structs, each with the one value the code now always behaves as: the shape parameters C and D of figure_eight_path, the TrajOptSettings fields that no run switched on, and the switches every run had on; traj_opt_settings.jl adds the fixed parameters of the optimizer client. Archived settings files still carry them.

source
SimpleKiteControllers.attractor_floor — Function
attractor_floor(fcs::FC_Settings, l_tether) -> Float64

The floor [deg] of the attractor lead at tether length l_tether [m]: fcs.pattern.attractor_dist, scaled by attractor_dist_ref_length / l_tether when fcs.pattern.attractor_dist_ref_length > 0. Scaled, the floor is a fixed arc LENGTH, attractor_dist in rad times the reference length, so the guidance rate it sets no longer falls as the tether grows.

source
SimpleKiteControllers.gate_candidate — Function
gate_candidate(tos, c) -> (; verdict, reason, detail, raise, low)

Judge the candidate c, a NamedTuple of what was measured on the reply as it will be flown:

  • margin: curvature margin at the current length l_now; opt_r_reply, r_span and opt_r_min describe the optimizer's own measure of the same curve, for the message.
  • clearance [m] and chk_el_min [deg]: lowest height and elevation of the path, against tos.gates.min_height and el_floor.
  • folds: whether the blend from the path in the air folds over itself.
  • new_pred, opt_power_pred, prev_install_pred [W]: predicted power of the candidate, of the startup path and of the previous install, and power_gate_off, whether the power gates are bypassed for this candidate.
  • size: the candidate's growth against the previous install (growth, az_ratio, el_ratio).
  • blend_attempt: how many cold restarts this cycle has spent already.

verdict is :accept; :retry, to ask for a fresh reply (reason says why, low whether it is about height and raise, for a height shortfall, how many degrees to add to the elevation floor of the next request, else nothing); or :reject, to give up on this cycle with detail as the event text. The checks run in the order of the gates of data/traj_opt.yaml: turn margin (never retried), clearance, elevation floor, blend fold or power, size growth.

source
SimpleKiteControllers.wants_challenge — Function
wants_challenge(tos, c) -> Bool

Whether an ACCEPTED reply looks like a step into a worse basin and is cross-checked by a cold solve (challenge_growth): it GREW the pattern by more than tos.reopt.challenge_growth against the previous install and predicts LESS power than that install. c holds size, new_pred and prev_install_pred as in gate_candidate; a NaN prev_install_pred (before the first re-optimization has installed a path) never asks.

source
SimpleKiteControllers.depower_command! — Function
depower_command!(st, setup, plant, t, phase_before, phase, rel_depower) -> (rel_depower, phase)

The depower actually flown: the optimizer's, ramped over path_blend_time in phases 3 and 4; phase 5 once the reel-out is done; the soft-stop ramp toward depower_final; and the phase-5 force limiter.

source
SimpleKiteControllers.elevation_min_request — Function
elevation_min_request(fcs, tos, l_tether; extra = 0.0) -> Union{Float64, Nothing}

The elevation floor [deg] to send with a request made for tether length l_tether: the highest of what the gates will demand there — asind(tos.gates.min_height/l_tether) for the clearance one and fcs.run.min_elevation + tos.gates.candidate_elevation_margin for the elevation one — plus extra. nothing asks for nothing and leaves the optimizer's own 0.6°.

Inverting path_min_height at the length being asked for is what makes the request and the gate the same question: AWETrim constrains HEIGHT and reaches its floor at the END of the lap's reel-out, while the reply is installed as angles at the anchor and judged there. The floor FALLS as the tether grows, so it belongs with every request and not in the session — see the analogous argument for min_turn_radius at the request site.

extra is what a retry raises the floor by after a reply was gated out, measured off that reply and carried forward: the shortfall is structural and the next length has it too.

source
SimpleKiteControllers.setup_run — Function
setup_run(inputs; init_model) -> RunSetup

Everything the run READS and never rebinds, built in order: the settings and their overrides, the plant s (built by the caller's init_model(project, project_set, fcs, wpc, sim_time; turbulence, set_overrides), since the package does not depend on the model), the winch and its controllers, the optimizer's conditions and session, the turn-rate laws (c1_at_depower, c1_ctrl_at) and the lobe lift. The script keeps the result in the one global setup and hands it to every function of the run; the loop destructures it (see run_loop!). The fields are documented at RunSetup.

source
SimpleKiteControllers.solve_startup_path! — Function
solve_startup_path!(setup, st) -> NamedTuple

The startup solve (solve_startup, a 422 retried from startup_retry_el_offsets in order); its reply goes to st.opt_result. Returns what setup gains from it: the seed it converged from (el_center_seed, startup_seed_offset, guess_az, guess_el) and its wall time, opt_startup_solve_s. The startup solve holds the script; blocking re-optimizations hold the loop (reopt_blocked_s).

source
SimpleKiteControllers.startup_feasibility — Function
startup_feasibility(setup, st) -> (; feas, margin5, c1_at_phase, phase5_margin_at)

The gates that refuse the run (check_startup_path) on the installed startup path, at the depower the pattern is FLOWN at (pattern_depower): the kite flies the optimizer's u_d from phase 3 on. Returns the verdicts feas, margin5, the Phase5MarginState of the in-air phase-5 check, and the two laws the loop reads off feas: c1_at_phase(phase, depower | st), the c1 to check a path against at time t, and phase5_margin_at(az, el), what phase 5 will fly a candidate path with.

source
SimpleKiteControllers.steering_command! — Function
steering_command!(st, setup, plant, t, chi_set, dmin)
    -> (; rel_steering, rel_depower, phase, u_ff, chi_cmd, w_lim, w_course, err)

Entry state machine, descent limiter, feedback fusion, PID and rel_depower (see CourseController), with the gain scale and the curvature feed-forward, then the depower of depower_command!. The phase is the one after the switch to phase 5 when the reel-out is done.

source
SimpleKiteControllers._dist — Function
_dist(az1, el1, az2, el2)

Small-area spherical distance [deg] in the (azimuth, elevation) plane; azimuth differences are compressed by cos(elevation).

source
SimpleKiteControllers._path_geometry — Function
_path_geometry(az, el, up_loops)

Turn a closed curve in (azimuth, elevation) [deg] into what the controller holds: (az, el, seg_len, tangent), the cyclic path points [deg], the arc length of each segment [deg] and the path direction at each point [rad]. A duplicated closing point is dropped and the traversal direction is reversed if it does not match up_loops.

source