Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AUTHORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Bart van de Lint joined the project in 2024. His major contribution is the first

## Developers
- Uwe Fechner, Delft/ Den Haag, The Netherlands - original author of the `KPS3` and `KPS4` kite models
- Bart van de Lint, Trondheim, Norway - author of the `RamAirKite` model
- Bart van de Lint, Trondheim, Norway - author of the `SymbolicAWEModel` model

## Contributors
- Daan van Wolffelaar, Delft, The Netherlands - contributed the scripts
Expand Down
20 changes: 10 additions & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ SPDX-License-Identifier: MIT
- added licenses to each file, the command `pipx run reuse lint` succeeds now
- add the command above to the CI scripts
- the script `create_xz_file`
- the option to linearize the RamAirKite system using ModelingToolkit
- the option to linearize the SymbolicAWEModel system using ModelingToolkit
- a simplified ram air kite model for faster development and testing
- the example `lin_ram_model.jl` to show how to linearize a model
- add the page `Examples RamAirKite` do the documentation
- add the page `Examples SymbolicAWEModel` do the documentation
#### Changed
- the example `ram_air_kite.jl` can now be run like this `SIMPLE=true; include("examples/ram_air_kite.jl")`
- the package `Rotations` is no longer re-exported
- improved documentation
#### Fixed
- small fixes of the RamAirKite model
- small fixes of the SymbolicAWEModel model

### KiteModels v0.7.3 2025-05-05
#### Fixed
Expand All @@ -32,7 +32,7 @@ SPDX-License-Identifier: MIT
- fixed or documented issues found by `Aqua.jl`
- made `DSP` a test dependency
- remove package `OrdinaryDiffEqSDIRK`
- improve documentation for `RamAirKite`
- improve documentation for `SymbolicAWEModel`
#### Added
- the examples `calc_spectrum.jl` and `plot_spectrum.jl` to the menu
- the quality insurance package `Aqua.jl`
Expand All @@ -45,10 +45,10 @@ SPDX-License-Identifier: MIT
#### Added
- added `mwe_26.jl` for debugging the initial state solver
- the example `ram_air_kite.jl`
- the struct `PointMassSystem` for easy definition of the kite power system
- the struct `SystemStructure` for easy definition of the kite power system
#### Changed
- BREAKING: the model KPS_3L was renamed to RamAirKite
- the RamAirKite model is using the **VortexStepMethod** with a deforming wing now
- BREAKING: the model KPS_3L was renamed to SymbolicAWEModel
- the SymbolicAWEModel model is using the **VortexStepMethod** with a deforming wing now
- bump KiteUtils to `v0.10`
- bump ModellingToolkit to `9.72`
- bump VortexStepMethod to `1.2.5`
Expand Down Expand Up @@ -128,7 +128,7 @@ SPDX-License-Identifier: MIT
- added tests for calc_azimuth(s::AKM), the azimuth in wind reference frame
- re-enable logging of the angles of attack of the three plates
- `steering_test_4p.jl` now calculates both `c1` and `c2` of the turn-rate law
- the environment variable `NO_MTK` disables the pre-compilation of the `RamAirKite` model
- the environment variable `NO_MTK` disables the pre-compilation of the `SymbolicAWEModel` model
to save time during development
- the script `menu2.jl` for model verification was added

Expand Down Expand Up @@ -168,7 +168,7 @@ SPDX-License-Identifier: MIT
- always specify the `system.yaml` file to use in the examples, always use `load_settings` instead of `se`.
This ensures that the settings are always freshly loaded from the file when the script is launched, so any changes
to the settings become immediately effective.
- the RamAirKite model was replaced by the pure ModelingToolkit (MTK) based version. This allows not only a much faster simulation, but the results are also much more accurate.
- the SymbolicAWEModel model was replaced by the pure ModelingToolkit (MTK) based version. This allows not only a much faster simulation, but the results are also much more accurate.

### KiteModels v0.6.5 - 2024-08-12
#### Changed
Expand Down Expand Up @@ -247,7 +247,7 @@ to the settings become immediately effective.
- update Documenter to v1.0

#### Added
- add type `RamAirKite`, which is now only a copy of `KPS4`, but shall implement a kite with the steering
- add type `SymbolicAWEModel`, which is now only a copy of `KPS4`, but shall implement a kite with the steering
lines going to the ground

### KiteModels v0.5.11 - 2024-04-04
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ This package is part of Julia Kite Power Tools, which consists of the following
- a new 5-point model based on ModelingToolkit (MTK) is in development;
this will allow to create linearized models around any operation point and to do analysis in the frequency domain.
#### April 2025
- a new model `RamAirKite` was contributed, based on the package [VortexStepMethod](https://github.com/Albatross-Kite-Transport/VortexStepMethod.jl)
- a new model `SymbolicAWEModel` was contributed, based on the package [VortexStepMethod](https://github.com/Albatross-Kite-Transport/VortexStepMethod.jl)
#### November 2024
- the four point kite model KPS4 was extended to include aerodynamic damping of pitch oscillations;
for this purpose, the parameters `cmq` and `cord_length` must be defined in `settings.yaml`
Expand Down
Binary file removed data/prob_1.10_ram_dynamic_3_seg.bin.default.xz
Binary file not shown.
Binary file removed data/prob_1.11_ram_dynamic_3_seg.bin.default.xz
Binary file not shown.
2 changes: 1 addition & 1 deletion data/settings_ram.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ solver:
kite:
model: "data/ram_air_kite_body.obj" # 3D model of the kite
foil_file: "data/ram_air_kite_foil.dat" # filename for the foil shape
physical_model: "ram" # name of the kite model to use (KPS3, KPS4 or RamAirKite)
physical_model: "ram" # name of the kite model to use (KPS3, KPS4 or SymbolicAWEModel)
top_bridle_points: # top bridle points that are not on the kite body in CAD frame
- [0.290199, 0.784697, -2.61305]
- [0.392683, 0.785271, -2.61201]
Expand Down
3 changes: 2 additions & 1 deletion docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ KiteModels = "b94af626-7959-4878-9336-2adc27959007"
KitePodModels = "9de5dc81-f971-414a-927b-652b2f41c539"
KiteUtils = "90980105-b163-44e5-ba9f-8b1c83bb0533"
OpenSSL_jll = "458c3c95-2e84-50aa-8efc-19380b2a3a95"
VortexStepMethod = "ed3cd733-9f0f-46a9-93e0-89b8d4998dd9"

[compat]
OpenSSL_jll = "~3.0.0"
ControlPlots = "0.2.7"
Documenter = "1.11"
KitePodModels = "0.3"
KiteUtils = "0.7, 0.8, 0.9, 0.10"
OpenSSL_jll = "~3.0.0"
julia = "1.10, 1.11"
12 changes: 5 additions & 7 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,14 @@ if ("TestEnv" ∈ keys(Pkg.project().dependencies))
using TestEnv; TestEnv.activate()
end
end
using ControlPlots
using ControlPlots, VortexStepMethod
using KiteModels
using Documenter

DocMeta.setdocmeta!(KiteModels, :DocTestSetup, :(using KitePodSimulator); recursive=true)

makedocs(;
modules=[KiteModels,
isdefined(Base, :get_extension) ?
Base.get_extension(KiteModels, :KiteModelsControlPlotsExt) :
KiteModels.KiteModelsControlPlotsExt],
modules=[KiteModels],
authors="Uwe Fechner <[email protected]>, Bart van de Lint <[email protected]> and contributors",
repo="https://github.com/ufechner7/KiteModels.jl/blob/{commit}{path}#{line}",
sitename="KiteModels.jl",
Expand All @@ -32,11 +29,12 @@ makedocs(;
"Home" => "index.md",
"Types" => "types.md",
"Functions" => "functions.md",
"RamAirKite" => "ram_air_kite.md",
"SymbolicAWEModel" => "ram_air_kite.md",
"Parameters" => "parameters.md",
"Examples 1p" => "examples.md",
"Examples 4p" => "examples_4p.md",
"Examples RamAirKite" => "examples_ram_air.md",
"Examples SymbolicAWEModel" => "examples_ram_air.md",
"SystemStructure for custom models" => "tutorial_system_structure.md",
"Quickstart" => "quickstart.md",
"Advanced usage" => "advanced.md",
],
Expand Down
8 changes: 4 additions & 4 deletions docs/src/examples_ram_air.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Expected output for first run:
```
[ Info: Loading packages
Time elapsed: 7.483472342 s
[ Info: Creating wing, aero, vsm_solver, point_system and s:
[ Info: Creating wing, aero, vsm_solver, system_structure and s:
Time elapsed: 15.341197455 s
[ Info: Creating ODESystem
4.316010 seconds (8.72 M allocations: 222.606 MiB, 1.42% gc time, 25.46% compilation time: 14% of which was recompilation)
Expand All @@ -48,7 +48,7 @@ file in the `data` folder:
```
[ Info: Loading packages
Time elapsed: 7.396961284 s
[ Info: Creating wing, aero, vsm_solver, point_system and s:
[ Info: Creating wing, aero, vsm_solver, system_structure and s:
Time elapsed: 15.387790726 s
[ Info: Initialized integrator in 29.545349428 seconds
[ Info: System initialized at:
Expand Down Expand Up @@ -83,13 +83,13 @@ include("examples/lin_ram_model.jl")
```
See: [`lin_ram_model.jl`](https://github.com/ufechner7/KiteModels.jl/blob/main/examples/lin_ram_model.jl)

## How to create a RamAirKite
## How to create a SymbolicAWEModel
The following code is a minimal example that shows how to create a ram air kite struct:
```julia
using KiteModels

# Initialize model
set = load_settings("system_ram.yaml")

rak = RamAirKite(set)
sam = SymbolicAWEModel(set)
```
2 changes: 1 addition & 1 deletion docs/src/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ s = KPS4(KCU(set))
Or, if you want to use the ram-air kite model:
```julia
set = load_settings("system_ram.yaml")
s = RamAirKite(set)
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.
Expand Down
4 changes: 2 additions & 2 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ include("examples/menu.jl")
- a new 5-point model based on ModelingToolkit (MTK) is in development;
this will allow to create linearized models around any operation point and to do analysis in the frequency domain.
#### April 2025
- a new model `RamAirKite` was contributed, based on the package [VortexStepMethod](https://github.com/Albatross-Kite-Transport/VortexStepMethod.jl)
- a new model `SymbolicAWEModel` was contributed, based on the package [VortexStepMethod](https://github.com/Albatross-Kite-Transport/VortexStepMethod.jl)
#### November 2024
- the four point kite model KPS4 was extended to include aerodynamic damping of pitch oscillations;
for this purpose, the parameters `cmq` and `cord_length` must be defined in `settings.yaml`
Expand All @@ -69,7 +69,7 @@ include("examples/menu.jl")
- the documentation was improved

## Provides
The type [`AbstractKiteModel`](@ref) with the implementation [`KPS3`](@ref), [`KPS4`](@ref) and [`RamAirKite`](@ref), representing the one point, the four point kite model and the ram air kite model, together with the high level simulation interface consisting of the functions [`init_sim!`](@ref) and [`next_step!`](@ref). Other kite models can be added inside or outside of this package by implementing the non-generic methods required for an AbstractKiteModel.
The type [`AbstractKiteModel`](@ref) with the implementation [`KPS3`](@ref), [`KPS4`](@ref) and [`SymbolicAWEModel`](@ref), representing the one point, the four point kite model and the ram air kite model, together with the high level simulation interface consisting of the functions [`init_sim!`](@ref) and [`next_step!`](@ref). Other kite models can be added inside or outside of this package by implementing the non-generic methods required for an AbstractKiteModel.

Additional functions to provide inputs and outputs of the model on each time step. In particular the constructor [`SysState`](@ref) can be called once per time step to create a SysState struct for
logging or for displaying the state in a viewer. For the KPS3 and KPS4 model, once per time step the [`residual!`](@ref) function is called as many times as needed to find the solution at the end
Expand Down
8 changes: 4 additions & 4 deletions docs/src/ram_air_kite.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
CurrentModule = KiteModels
```
## Introduction
The [`RamAirKite`](@ref) is based on ModelingToolkit, which allows to define the differential algebraic equations in symbolic form. It does not use a KCU. Instead, the kite is controlled from the ground (e.g. a ship) using three winches and four tethers.
The [`SymbolicAWEModel`](@ref) is based on ModelingToolkit, which allows to define the differential algebraic equations in symbolic form. It does not use a KCU. Instead, the kite is controlled from the ground (e.g. a ship) using three winches and four tethers.

## Private enumerations
```@docs
Expand All @@ -17,13 +17,13 @@ Pulley
Segment
Tether
Winch
KitePointGroup
PointMassSystem
Group
SystemStructure
```

## Private functions
```@docs
diff_eqs!
wing_eqs!
reinit!
scalar_eqs!
linear_vsm_eqs!
Expand Down
2 changes: 1 addition & 1 deletion docs/src/test_plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Expected output:
julia> include("examples/ram_air_kite.jl")
[ Info: Loading packages
Time elapsed: 2.863292943 s
[ Info: Creating wing, aero, vsm_solver, point_system and s:
[ Info: Creating wing, aero, vsm_solver, system_structure and s:
Time elapsed: 4.51880941 s
[ Info: Initialized integrator in 6.000656365 seconds
[ Info: System initialized at:
Expand Down
62 changes: 62 additions & 0 deletions docs/src/tutorial_system_structure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
```@meta
CurrentModule = KiteModels
```
# Custom SystemStructure and SymbolicAWESystem

A custom `SystemStructure` can be used to create models of kite power systems of almost any configuration.
- custom amount of tethers
- custom bridle configurations
- quasi-static or dynamic point masses
- different amounts of stiffness, damping and diameter on different tether segments

## Creating a simple tether

We start by loading the necessary packages and defining settings and parameters.

```@example 1
using KiteModels, VortexStepMethod, ControlPlots

set = se("system_ram.yaml")
set.segments = 20
dynamics_type = DYNAMIC
```
Then, we define vectors of the system structure types we are going to use. For this simple example we only need points and segments.
```@example 1
points = Point[]
segments = Segment[]

points = push!(points, Point(1, [0.0, 0.0, set.l_tether], STATIC; wing_idx=0))
```
The first point we add is a static point. There are four different [`DynamicsType`](@ref)s to choose from: `STATIC`, `QUASI_STATIC`, `DYNAMIC` and `WING`. `STATIC` just means that the point doesn't move. `DYNAMIC` is a point modeled with acceleration, while `QUASI_STATIC` constrains this acceleration to be zero at all times. A `WING` point is connected to a rigid wing body.

Now we can add `DYNAMIC` points and connect them to eachother with segments. `BRIDLE` segments don't need to have a tether, because they have a constant unstretched length.
```@example 1
segment_idxs = Int[]
for i in 1:set.segments
global points, segments
point_idx = i+1
pos = [0.0, 0.0, set.l_tether] - set.l_tether / set.segments * [0.0, 0.0, i]
push!(points, Point(point_idx, pos, dynamics_type; wing_idx=0))
segment_idx = i
push!(segments, Segment(segment_idx, (point_idx-1, point_idx), BRIDLE))
push!(segment_idxs, segment_idx)
end
```
From these arrays of points and segments we can create a [`SystemStructure`](@ref), which can be plotted in 2d to quickly investigate if the model is correct.
```@example 1
system_structure = SystemStructure("tether"; points, segments)
plot(system_structure, 0.0)
plt.gcf()
```

If the system looks good, we can easily model it, by first creating a [`SymbolicAWEModel`](@ref), initializing it and stepping through time.
```@example 1
model = SymbolicAWEModel(set, system_structure)

init_sim!(model; remake=false)
for i in 1:100
plot(model, i/set.sample_freq)
next_step!(model; dt=1/set.sample_freq)
end
plt.gcf()
```
4 changes: 2 additions & 2 deletions docs/src/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ AbstractKiteModel
AKM
```

## Struct KPS3 and KPS4 and RamAirKite
## Struct KPS3 and KPS4 and SymbolicAWEModel
```@docs
KPS3
KPS4
RamAirKite
SymbolicAWEModel
```
These structs store the state of the one point model and four point model. Only in unit tests
it is allowed to access the members directly, otherwise use the input and output functions.
14 changes: 7 additions & 7 deletions examples/lin_ram_model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#=
This example demonstrates linearized model accuracy by comparing:
1. Nonlinear RamAirKite model simulation
1. Nonlinear SymbolicAWEModel model simulation
2. Linearized state-space model simulation

Both models start from the same operating point and are subjected
Expand Down Expand Up @@ -49,26 +49,26 @@ set_values = [-50.0, 0.0, 0.0] # Set values of the torques of the three winches
set.quasi_static = false
set.physical_model = "simple_ram"

@info "Creating RamAirKite model..."
s = RamAirKite(set)
@info "Creating SymbolicAWEModel model..."
s = SymbolicAWEModel(set)
s.set.abs_tol = 1e-2
s.set.rel_tol = 1e-2
toc()

# Define outputs for linearization - heading
lin_outputs = @variables heading(t)
lin_outputs = @variables heading(t)[1]

# Initialize at elevation with linearization outputs
s.point_system.winches[2].tether_length += 0.2
s.point_system.winches[3].tether_length += 0.2
s.system_structure.winches[2].tether_length += 0.2
s.system_structure.winches[3].tether_length += 0.2
KiteModels.init_sim!(s;
remake=false,
reload=true,
lin_outputs # Specify which outputs to track in linear model
)
sys = s.sys

@show rad2deg(s.integrator[sys.elevation])
@show rad2deg(s.integrator[sys.elevation[1]])


@info "System initialized at:"
Expand Down
32 changes: 0 additions & 32 deletions examples/plotting.jl

This file was deleted.

Loading
Loading