Repository navigation
Conversation
find_steady_state! and init! place the kite at set.azimuths[1] in the wind reference frame. The steady state is solved with the tether in the x-z plane and the wind turned by the azimuth; for an azimuth other than zero, the lateral forces on the tether particles are balanced too, while the kite is kept at the prescribed azimuth. The default azimuth of zero keeps the previous behaviour. Also fix init!(s; steady_state=false) for KPS4, which did not turn s.pos into the wind direction. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The steering set.steerings[1] (KPS3 and KPS4) is set in clear!, like the depower. The heading set.headings[1] (KPS4) is applied by init! after the steady state was found, by rotating the kite points A, C and D about the line from the KCU to the kite, which keeps the position of the kite and the lengths of all springs. KPS3 ignores the heading. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
) init! adds the velocities of the initial rates to the initial state: for the elevation and azimuth rates (KPS3 and KPS4), the tether and the kite rotate as a rigid body about the winch; for the heading rate (KPS4), the kite also rotates about the line from the KCU to the kite, scaled so that calc_heading changes with the prescribed rate. The accelerations are not changed, so the simulation starts with a transient. The rotation of the kite is factored out of set_initial_heading! into heading_after_rotation!. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
KPS3 samples turbulent wind at the unrotated position, and the nonzero-azimuth trim path lacks coverage.
2 open findings
What changed in this PR
Adds initial azimuth, heading, steering, and angular-rate handling to KPS3/KPS4 initialization.
Changes:
- Balances tether geometry for nonzero initial azimuths.
- Applies initial steering, KPS4 heading, and configured rates.
- Adds documentation, changelog entries, and regression tests.
| File | Description |
|---|---|
src/KPS3.jl |
Adds azimuth balancing, steering, and lateral offsets. |
src/KPS4.jl |
Adds azimuth balancing and heading rotation. |
src/KiteModels.jl |
Applies initial headings/rates during initialization. |
test/test-azimuth.jl |
Tests initial azimuth behavior. |
test/test-heading-steering.jl |
Tests heading and steering initialization. |
test/test-initial-rates.jl |
Tests configured angular rates. |
CHANGELOG.md |
Documents the new initialization behavior. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+601
to
+603
| turn_dir = upwind_dir - deg2rad(s.set.azimuth) | ||
| res1 = vcat(turn(res1[1:n], turn_dir), res1[n+1:end]) | ||
| res2 = vcat(turn(res2[1:n], turn_dir), res2[n+1:end]) |
| @testset "$(nameof(Model)), azimuth $(azimuth)°, upwind_dir $(round(rad2deg(upwind_dir)))°" for | ||
| Model in (KPS3, KPS4), azimuth in (30.0, -45.0), upwind_dir in (-π/2, π/4) | ||
| s = new_model(Model, azimuth) | ||
| res1, res2 = @test_logs min_level=Base.CoreLogging.Warn find_steady_state!(s; upwind_dir) |
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Addresses all items (1–5) of the scope proposed in #243 (comment). Stacked on #336.
Initial azimuth (KPS3 and KPS4)
find_steady_state!andinit!(with or withouttrim, also withsteady_state=false) place the kite atset.azimuths[1]in the wind reference frame. The default azimuth of zero keeps the previous behaviour: the extra unknowns are only added for an azimuth other than zero.Method: a rotation about the vertical axis leaves gravity, the winch and a height-only wind profile unchanged. So the steady state is solved with the tether in the x-z plane and the wind turned by the azimuth, and the result is turned back.
trim=false. For KPS4, the KCU and kite stay in the tether plane, and the kite is built symmetric to it (heading 0).Behaviour: a kite at an azimuth is not in equilibrium; it has a side slip angle. With
system.yamlat 30°:trim=false, and 536 N instead of 461 N withtrim=true, at a natural elevation of 60°. Without steering, the kite swings back through 0° to −27° within 10 s.Initial heading and steering
clear!sets the KCU steering fromset.steerings[1][%], like the depower, so the steady state is solved with it. Only its symmetric forces are balanced, so with steering ≠ 0 the kite turns: 20 % steering turns KPS4 from heading 0° to 84° in 3 s.init!rotates the kite points A, C and D about the line from the KCU to point B, solving for the angle so thatcalc_headingreturnsset.headings[1]exactly.Initial rates
init!adds the velocities of the initial rates to the initial state:set.elevation_rates[1]andset.azimuth_rates[1](checked by finite differences).set.heading_rates[1]. KPS3 ignores it.The accelerations are not changed, so the simulation starts with a transient:
Also in this PR
init!(s; steady_state=false)(KPS4) did not turns.posinto the wind direction, so getters likecalc_azimuthwere wrong before the first time step ifupwind_dir≠ −90°.init!docstring lists whichinitial:settings are used (tether length, reel-out speed, depower, elevation, azimuth, steering, heading) and which is ignored (the kite distance), and describes the transient caused by the rates.Tests
test/test-azimuth.jl(124 tests):init!with and without the steady state;test/test-heading-steering.jl(67 tests): the heading for several headings and azimuths, with unchanged kite position, tether and spring lengths; sideways flight for ±90°; KPS3 ignoring the heading; the steering values in the KCU and model; turning with 20 % steering.test/test-initial-rates.jl(43 tests): the rates by finite differences for several combinations with azimuth and heading, unchanged positions, KPS3 ignoring the heading rate, the pitch rate, and continued motion with an azimuth rate.🤖 Generated with Claude Code