Skip to content
Open
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 REUSE.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ SPDX-FileCopyrightText = "2025 Uwe Fechner, Bart van de Lint"
SPDX-License-Identifier = "MIT"

[[annotations]]
path = ["docs/src/*.png", "docs/src/*.svg", "docs/src/*.md", "data/.gitignore"]
path = ["docs/src/*.png", "docs/src/*.svg", "docs/src/*.md", "data/.gitignore", "docs/src/assets/group_slice.svg"]
SPDX-FileCopyrightText = "2025 Uwe Fechner, Bart van de Lint"
SPDX-License-Identifier = "CC-BY-4.0"

Expand Down
5 changes: 5 additions & 0 deletions bin/reuse_lint
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Copyright (c) 2025 Uwe Fechner
# SPDX-License-Identifier: MIT

cd ..
pipx run reuse lint
3 changes: 3 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[deps]
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
KiteUtils = "90980105-b163-44e5-ba9f-8b1c83bb0533"

[sources]
KiteUtils = {path = ".."}
1 change: 1 addition & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ makedocs(;
"Reference frames" => "reference_frames.md",
"Exported Functions" => "functions.md",
"Exported Types" => "types.md",
"System Structure" => "system_structure.md",
"Examples" => "examples.md",
],
)
Expand Down
2,811 changes: 2,811 additions & 0 deletions docs/src/assets/group_slice.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions docs/src/reference_frames.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,30 @@ CurrentModule = KiteUtils
## Position and velocity
For position and velocity vectors of the model the **ENU** (East North Up) reference frame is used.

## World Frame and CAD Frame

### World Frame
The **world frame** is the general inertial reference frame used for all simulation dynamics in the system structure. By default, the **ENU** (East-North-Up) frame is used as the world frame in [`SystemStructure`](@ref), with the following properties:
- **Origin**: Located at the winch position (0, 0, 0)
- **x-axis**: Points East
- **y-axis**: Points North
- **z-axis**: Points Up (vertical, opposite to gravity)

All dynamic quantities (positions, velocities, forces) are expressed in this world frame during simulation.

### CAD Frame
The **CAD frame** is the coordinate system in which the system geometry is initially defined (e.g., in CAD software). The CAD frame can have an arbitrary origin and orientation - it does not need to match the world frame.

When constructing a [`SystemStructure`](@ref):
- All points are initially specified with `pos_cad` positions in the CAD frame
- [`Transform`](@ref) objects convert these CAD frame coordinates to world frame coordinates
- The `base_pos` argument in a Transform specifies where the CAD frame origin should be placed in the world frame
- After transformation, all simulation proceeds in the world frame

This separation allows system geometry to be defined in whatever coordinate system is most convenient for design, then automatically converted to the simulation frame.

## Wind and Controller Frames

The controller is using the **W** (Wind) reference frame as shown in the figure below, y-axis downwind and z-axis up.

The orientation of the kite is expressed with respect to the **EX** (Earth XSense = North East Down) reference frame.
Expand Down
100 changes: 100 additions & 0 deletions docs/src/system_structure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
```@meta
CurrentModule = KiteUtils
```

## Introduction

The [`SystemStructure`](@ref) provides a flexible framework for defining the physical
structure of airborne wind energy (AWE) systems using discrete mass-spring-damper models.
This structure can represent many different AWE system configurations, from simple
single-line kites to complex multi-wing systems with intricate bridle networks.

## Workflow

1. Define system components ([`Point`](@ref), [`Segment`](@ref), [`Group`](@ref), [`BaseWing`](@ref), etc.)
2. Assemble into a [`SystemStructure`](@ref)
3. Initialize component positions using [`Transform`](@ref)s
4. Simulate using [`SymbolicAWEModels.jl`](https://github.com/OpenSourceAWE/SymbolicAWEModels.jl)

## Core Types and Constants

### Simulation Types

```@docs
SimFloat
KVec3
KVec4
SVec3
```

### Public Enumerations

```@docs
SegmentType
DynamicsType
```

## System Components

### Points and Point Dynamics

```@docs
Point
Point(idx, pos_cad, type; wing_idx, vel_w, transform_idx, mass, bridle_damping, fix_sphere)
```

### Wing Deformation Groups

```@docs
Group
Group(idx, point_idxs, le_pos, chord, y_airf, type, moment_frac)
```

### Segments and Connections

```@docs
Segment
Segment(idx, set, point_idxs, type; l0, compression_frac, axial_stiffness, axial_damping)
Segment(idx, point_idxs, axial_stiffness, axial_damping, diameter; l0, compression_frac)
```

### Pulleys and Length Redistribution

```@docs
Pulley
Pulley(idx, segment_idxs, type)
```

### Tethers and Winch Control

```@docs
Tether
Tether(idx, segment_idxs, winch_idx)
Winch
Winch(idx, set::Settings, tether_idxs; tether_len, tether_vel, brake)
Winch(idx, tether_idxs, gear_ratio, drum_radius, f_coulomb, c_vf, inertia_total; tether_len, tether_vel, brake)
```

## Wing Components

### Wing Abstractions and Implementations

```@docs
AbstractWing
BaseWing
```

### Spatial Transformations

```@docs
Transform
Transform(idx, elevation, azimuth, heading; base_point_idx, base_pos, base_transform_idx, wing_idx, rot_point_idx)
Transform(idx, set; wing_idx, rot_point_idx, base_point_idx, base_pos, base_transform_idx)
```

## Complete System Structure

```@docs
SystemStructure
SystemStructure(name, set; points, groups, segments, pulleys, tethers, winches, wings, transforms)
```
3 changes: 2 additions & 1 deletion examples/bridle_info.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# SPDX-FileCopyrightText: 2022 Uwe Fechner
# SPDX-License-Identifier: MIT

using KiteUtils, LinearAlgebra
using KiteUtils
using LinearAlgebra

if basename(pwd()) == "examples"
set_data_path("../data")
Expand Down
29 changes: 16 additions & 13 deletions scripts/build_docu.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,25 @@

using Pkg

function globaldependencies()
projectpath = Pkg.project().path
basepath, _ = splitdir(projectpath)
Pkg.activate()
globaldependencies = keys(Pkg.project().dependencies)
Pkg.activate(basepath)
globaldependencies
end
# Check if LiveServer is installed globally
current_project = Pkg.project().path
Pkg.activate()
has_liveserver = "LiveServer" in keys(Pkg.project().dependencies)
Pkg.activate(current_project)

if !("LiveServer" in globaldependencies())
if !has_liveserver
println("Installing LiveServer globally!")
run(`julia -e 'using Pkg; Pkg.add("LiveServer")'`)
end

# if !("Documenter" ∈ keys(Pkg.project().dependencies))
# using TestEnv
# TestEnv.activate()
# end
# Activate the docs environment
basepath = dirname(current_project)
docs_path = joinpath(basepath, "docs")
Pkg.activate(docs_path)

# Instantiate to ensure all dependencies are installed
if !isfile(joinpath(docs_path, "Manifest.toml"))
Pkg.instantiate()
end

using LiveServer; servedocs(launch_browser=true)
19 changes: 13 additions & 6 deletions src/KiteUtils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,16 @@ SOFTWARE. =#
# the parameter P is the number of points of the tether, equal to segments+1
# in addition helper functions for working with rotations

using PrecompileTools: @setup_workload, @compile_workload
using PrecompileTools: @setup_workload, @compile_workload
using Rotations, StaticArrays, StructArrays, RecursiveArrayTools, Arrow, YAML, LinearAlgebra, DocStringExtensions
using Parameters, StructTypes, CSV, Parsers, Pkg
export Settings, SysState, SysLog, Logger, MyFloat
export SimFloat, KVec3, KVec4, SVec3
export SegmentType, POWER_LINE, STEERING_LINE, BRIDLE
export DynamicsType, DYNAMIC, QUASI_STATIC, WING, STATIC
export Point, Group, Segment, Pulley, Tether, Winch
export AbstractWing, BaseWing
export Transform, SystemStructure

import Base.length
import ReferenceFrameRotations as RFR
Expand Down Expand Up @@ -88,6 +94,7 @@ include("settings.jl")
include("yaml_utils.jl")
include("transformations.jl")
include("trafo.jl")
include("system_structure.jl")

include("_sysstate.jl")

Expand Down Expand Up @@ -200,7 +207,7 @@ the apparent wind speed.

Parameters:
- `vec_c`: (`pos_n`-2) - (`pos_n`-1) n: number of particles without the three kite particles
that do not belong to the main thether (P1, P2 and P3).
that do not belong to the main tether (P1, P2 and P3).
- `v_app`: vector of the apparent wind speed

Returns:
Expand All @@ -217,7 +224,7 @@ end
get_particles(height_k, height_b, width, m_k, pos_pod= [ 75., 0., 129.90381057], vec_c=[-15., 0., -25.98076211],
v_app=[10.4855, 0, -3.08324])

Calculate the initial positions of the particels representing
Calculate the initial positions of the particles representing
a 4-point kite, connected to a kite control unit (KCU).

Parameters:
Expand All @@ -238,7 +245,7 @@ function get_particles(height_k, height_b, width, m_k, pos_pod= [ 75., 0., 129.9
h_kz = height_k * sin(beta); # print 'h_kz: ', h_kz
h_bx = height_b * cos(beta)
h_bz = height_b * sin(beta)
pos_kite = pos_pod - (h_kz + h_bz) * z + (h_kx + h_bx) * x # top, poing B in diagram
pos_kite = pos_pod - (h_kz + h_bz) * z + (h_kx + h_bx) * x # top, point B in diagram
pos_C = pos_kite + h_kz * z + 0.5 * width * y + h_kx * x # side point, point C in diagram
pos_A = pos_kite + h_kz * z + (h_kx + width * m_k) * x # nose, point A in diagram
pos_D = pos_kite + h_kz * z - 0.5 * width * y + h_kx * x # side point, point D in diagram
Expand Down Expand Up @@ -337,7 +344,7 @@ end
"""
save_log(flight_log::SysLog, compress=true; path="")

Save a fligh log of type SysLog as .arrow file. By default lz4 compression is used,
Save a flight log of type SysLog as .arrow file. By default lz4 compression is used,
if you use **false** as second parameter no compression is used.
"""
function save_log(flight_log::SysLog, compress=true; path="")
Expand All @@ -355,7 +362,7 @@ end
"""
export_log(flight_log; path="")

Save a fligh log of type SysLog as .csv file.
Save a flight log of type SysLog as .csv file.
"""
function export_log(flight_log; path="")
if path == ""
Expand Down
Loading
Loading