Skip to content

Commit 52fae47

Browse files
committed
Add initial docs
1 parent 9274f67 commit 52fae47

13 files changed

Lines changed: 1844 additions & 14 deletions

File tree

.github/workflows/docs.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: Deploy Documentation
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
permissions:
10+
contents: read
11+
pages: write
12+
id-token: write
13+
14+
concurrency:
15+
group: "pages"
16+
cancel-in-progress: false
17+
18+
jobs:
19+
build:
20+
runs-on: ubuntu-latest
21+
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@v4
25+
26+
- name: Setup pixi
27+
uses: prefix-dev/setup-pixi@v0.8.1
28+
with:
29+
pixi-version: v0.49.0
30+
cache: true
31+
32+
- name: Build documentation
33+
run: pixi run -e docs mkdocs build
34+
35+
- name: Setup Pages
36+
uses: actions/configure-pages@v3
37+
38+
- name: Upload artifact
39+
uses: actions/upload-pages-artifact@v4
40+
with:
41+
path: ./site
42+
43+
deploy:
44+
environment:
45+
name: github-pages
46+
url: ${{ steps.deployment.outputs.page_url }}
47+
runs-on: ubuntu-latest
48+
needs: build
49+
if: github.ref == 'refs/heads/main'
50+
51+
steps:
52+
- name: Deploy to GitHub Pages
53+
id: deployment
54+
uses: actions/deploy-pages@v4

docs/api/core.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Core
2+
3+
::: drone_controllers.core
4+
5+
The core module provides the foundational functionality for controller parametrization and registration.
6+
7+
## Key Concepts
8+
9+
### Controller Parametrization
10+
11+
The `parametrize` function allows you to automatically configure controllers with parameters for specific drone models:
12+
13+
```python
14+
from drone_controllers import parametrize
15+
from drone_controllers.mellinger import state2attitude
16+
17+
# Get a controller configured for the Crazyflie 2.x
18+
controller = parametrize(state2attitude, "cf2x_L250")
19+
20+
# Use the controller (all parameters are automatically filled in)
21+
rpyt, pos_err = controller(pos, quat, vel, ang_vel, cmd)
22+
```
23+
24+
### Parameter Registry
25+
26+
Controllers register their parameter types using the `@register_controller_parameters` decorator:
27+
28+
```python
29+
@register_controller_parameters(MyControllerParams)
30+
def my_controller(pos, vel, *, param1, param2, param3):
31+
# Controller implementation
32+
pass
33+
```
34+
35+
### ControllerParams Protocol
36+
37+
All controller parameter classes must implement the `ControllerParams` protocol:
38+
39+
- `load(drone_model: str)` - Load parameters for a specific drone model
40+
- `_asdict()` - Convert parameters to a dictionary
41+
42+
## Example Usage
43+
44+
```python
45+
from functools import partial
46+
from drone_controllers.mellinger.params import StateParams
47+
48+
# Manual parameter loading
49+
params = StateParams.load("cf2x_L250")
50+
controller = partial(state2attitude, **params._asdict())
51+
52+
# Equivalent to using parametrize
53+
from drone_controllers import parametrize
54+
controller = parametrize(state2attitude, "cf2x_L250")
55+
```

docs/api/mellinger.md

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# Mellinger Controller
2+
3+
The Mellinger controller is a geometric tracking controller originally developed for aggressive quadrotor maneuvers [[1]](#references). This implementation is based on the Crazyflie firmware version.
4+
5+
## Controller Functions
6+
7+
### state2attitude
8+
9+
::: drone_controllers.mellinger.control.state2attitude
10+
11+
The position control component of the Mellinger controller. Converts desired position, velocity, and acceleration into attitude commands.
12+
13+
**Example:**
14+
```python
15+
from drone_controllers import parametrize
16+
from drone_controllers.mellinger import state2attitude
17+
18+
controller = parametrize(state2attitude, "cf2x_L250")
19+
20+
rpyt, pos_err_i = controller(pos, quat, vel, ang_vel, cmd)
21+
```
22+
23+
### attitude2force_torque
24+
25+
::: drone_controllers.mellinger.control.attitude2force_torque
26+
27+
The attitude control component that converts attitude commands into desired forces and torques.
28+
29+
**Example:**
30+
```python
31+
from drone_controllers import parametrize
32+
from drone_controllers.mellinger import attitude2force_torque
33+
34+
controller = parametrize(attitude2force_torque, "cf2x_L250")
35+
36+
force, torque, att_err_i = controller(pos, quat, vel, ang_vel, rpyt_cmd)
37+
```
38+
39+
### force_torque2rotor_vel
40+
41+
::: drone_controllers.mellinger.control.force_torque2rotor_vel
42+
43+
Converts desired forces and torques into individual rotor velocities using the quadrotor mixing matrix.
44+
45+
**Example:**
46+
```python
47+
from drone_controllers import parametrize
48+
from drone_controllers.mellinger import force_torque2rotor_vel
49+
50+
controller = parametrize(force_torque2rotor_vel, "cf2x_L250")
51+
52+
rotor_speeds = controller(force, torque)
53+
```
54+
55+
## Parameter Classes
56+
57+
### StateParams
58+
59+
::: drone_controllers.mellinger.params.StateParams
60+
61+
Parameters for the position control loop.
62+
63+
### AttitudeParams
64+
65+
::: drone_controllers.mellinger.params.AttitudeParams
66+
67+
Parameters for the attitude control loop.
68+
69+
### ForceTorqueParams
70+
71+
::: drone_controllers.mellinger.params.ForceTorqueParams
72+
73+
Parameters for the force/torque to rotor speed conversion.
74+
75+
## Complete Controller Pipeline
76+
77+
Here's how to use all three components together:
78+
79+
```python
80+
import numpy as np
81+
from drone_controllers import parametrize
82+
from drone_controllers.mellinger import (
83+
state2attitude,
84+
attitude2force_torque,
85+
force_torque2rotor_vel
86+
)
87+
88+
# Parametrize all three controller components
89+
state_ctrl = parametrize(state2attitude, "cf2x_L250")
90+
attitude_ctrl = parametrize(attitude2force_torque, "cf2x_L250")
91+
rotor_ctrl = parametrize(force_torque2rotor_vel, "cf2x_L250")
92+
93+
# Define state
94+
pos = np.array([0.0, 0.0, 1.0])
95+
quat = np.array([0.0, 0.0, 0.0, 1.0]) # [x, y, z, w]
96+
vel = np.array([0.0, 0.0, 0.0])
97+
ang_vel = np.array([0.0, 0.0, 0.0])
98+
99+
# Define command: [x, y, z, vx, vy, vz, ax, ay, az, yaw, r_rate, p_rate, y_rate]
100+
cmd = np.array([1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])
101+
102+
# Run the complete pipeline
103+
rpyt, pos_err_i = state_ctrl(pos, quat, vel, ang_vel, cmd)
104+
force, torque, att_err_i = attitude_ctrl(pos, quat, vel, ang_vel, rpyt)
105+
rotor_speeds = rotor_ctrl(force, torque)
106+
107+
print(f"Final rotor speeds: {rotor_speeds} rad/s")
108+
```
109+
110+
## Integral Error Handling
111+
112+
The Mellinger controller uses integral terms for robustness. You must pass integral errors between calls:
113+
114+
```python
115+
# Initialize
116+
pos_err_i = None
117+
att_err_i = None
118+
119+
for step in range(100):
120+
# Update state and command...
121+
122+
# Pass previous integral errors
123+
ctrl_errors = (pos_err_i,) if pos_err_i is not None else None
124+
rpyt, pos_err_i = state_ctrl(pos, quat, vel, ang_vel, cmd, ctrl_errors=ctrl_errors)
125+
126+
ctrl_errors = (att_err_i,) if att_err_i is not None else None
127+
force, torque, att_err_i = attitude_ctrl(pos, quat, vel, ang_vel, rpyt, ctrl_errors=ctrl_errors)
128+
129+
rotor_speeds = rotor_ctrl(force, torque)
130+
```
131+
132+
## Array API Compatibility
133+
134+
All Mellinger functions support the Python Array API and can be used with JAX, PyTorch, etc.:
135+
136+
```python
137+
import jax.numpy as jnp
138+
from jax import jit
139+
140+
# Convert to JAX arrays
141+
pos_jax = jnp.array([0.0, 0.0, 1.0])
142+
quat_jax = jnp.array([0.0, 0.0, 0.0, 1.0])
143+
# ... other arrays
144+
145+
# JIT compile the controller
146+
jit_controller = jit(parametrize(state2attitude, "cf2x_L250"))
147+
148+
rpyt, pos_err_i = jit_controller(pos_jax, quat_jax, vel_jax, ang_vel_jax, cmd_jax)
149+
```
150+
151+
# References
152+
153+
[1] D. Mellinger and V. Kumar, "Minimum snap trajectory generation and control for quadrotors," 2011 IEEE International Conference on Robotics and Automation, Shanghai, China, 2011, pp. 2520-2525, doi: 10.1109/ICRA.2011.5980409.

0 commit comments

Comments
 (0)