Skip to content

Commit 64da868

Browse files
committed
Refactor the simulation. Add the attitude controller interface. Add docker support. Add docs. Improve tests and tooling.
1 parent fdf780e commit 64da868

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+2102
-3077
lines changed

.dockerignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.git
2+
.github
3+
.vscode
4+
.pytest_cache
5+
**/*.pyc

.github/workflows/test_solution.yml

+2-8
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,11 @@ jobs:
2828
post-cleanup: 'all'
2929
- name: Install cffirmware
3030
run: |
31-
git clone https://github.com/utiasDSL/pycffirmware.git
31+
git clone -b drone_racing https://github.com/utiasDSL/pycffirmware.git
3232
cd pycffirmware
3333
git submodule update --init --recursive
3434
./wrapper/build_linux.sh
35-
- name: Install stable baselines
36-
run: pip install stable-baselines3
37-
shell: bash -el {0}
38-
- name: Install stable baselines
39-
run: pip install stable-baselines3
40-
shell: bash -el {0}
41-
- run: pip install .
35+
- run: pip install .[rl, test]
4236
shell: bash -el {0}
4337
- name: Run simulation tests
4438
run: python scripts/kaggle.py

.readthedocs.yaml

+3-1
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,6 @@ sphinx:
1515

1616
python:
1717
install:
18-
- requirements: docs/requirements.txt
18+
- requirements: docs/requirements.txt
19+
- method: pip
20+
path: .

README.md

+20-9
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
## Installation
2929

3030
To run the LSY Autonomous Drone Racing project, you will need 2 repositories:
31-
- [pycffirmware](https://github.com/utiasDSL/pycffirmware) - `main` branch: A simulator for the on-board controller response of the drones we are using to accurately model their behavior
31+
- [pycffirmware](https://github.com/utiasDSL/pycffirmware/tree/drone_racing) - `drone_racing` branch: A simulator for the on-board controller response of the drones we are using to accurately model their behavior.
3232
- [lsy_drone_racing](https://github.com/utiasDSL/lsy_drone_racing) - `main` branch: This repository contains the drone simulation, environments, and scripts to simulate and deploy the drones in the racing challenge
3333

3434
### Fork lsy_drone_racing
@@ -62,7 +62,7 @@ In addition, you also need to install the pycffirmware package from source with
6262

6363
```bash
6464
cd ~/repos
65-
git clone https://github.com/utiasDSL/pycffirmware.git
65+
git clone -b drone_racing https://github.com/utiasDSL/pycffirmware.git
6666
cd pycffirmware
6767
git submodule update --init --recursive
6868
sudo apt update
@@ -80,17 +80,20 @@ python scripts/sim.py
8080

8181
If everything is installed correctly, this opens the simulator and simulates a drone flying through four gates.
8282

83+
### Using Docker
84+
TODO: Add docker instructions
85+
8386
## Difficulty levels
84-
The complete problem is specified by a YAML file, e.g. [`getting_started.yaml`](config/getting_started.yaml)
87+
The complete problem is specified by a TOML file, e.g. [`level0.toml`](config/level0.toml)
8588

8689
The config folder contains settings for progressively harder scenarios:
8790

8891
| Evaluation Scenario | Constraints | Rand. Inertial Properties | Randomized Obstacles, Gates | Rand. Between Episodes | Notes |
8992
| :---------------------------------: | :---------: | :-----------------------: | :-------------------------: | :--------------------: | :-------------------: |
90-
| [`level0.yaml`](config/level0.yaml) | **Yes** | *No* | *No* | *No* | Perfect knowledge |
91-
| [`level1.yaml`](config/level1.yaml) | **Yes** | **Yes** | *No* | *No* | Adaptive |
92-
| [`level2.yaml`](config/level2.yaml) | **Yes** | **Yes** | **Yes** | *No* | Learning, re-planning |
93-
| [`level3.yaml`](config/level3.yaml) | **Yes** | **Yes** | **Yes** | **Yes** | Robustness |
93+
| [`level0.toml`](config/level0.toml) | **Yes** | *No* | *No* | *No* | Perfect knowledge |
94+
| [`level1.toml`](config/level1.toml) | **Yes** | **Yes** | *No* | *No* | Adaptive |
95+
| [`level2.toml`](config/level2.toml) | **Yes** | **Yes** | **Yes** | *No* | Learning, re-planning |
96+
| [`level3.toml`](config/level3.toml) | **Yes** | **Yes** | **Yes** | **Yes** | Robustness |
9497
| | | | | | |
9598
| sim2real | **Yes** | Real-life hardware | **Yes** | *No* | Sim2real transfer |
9699

@@ -100,7 +103,7 @@ The config folder contains settings for progressively harder scenarios:
100103
You can choose which configuration to use by changing the `--config` command line option. To e.g. run the example controller on the hardest scenario, you can use the following command
101104

102105
```bash
103-
python scripts/sim.py --config config/level3.yaml
106+
python scripts/sim.py --config config/level3.toml
104107
```
105108

106109
## The online competition
@@ -240,11 +243,19 @@ pip install cfclient
240243
conda deactivate
241244
```
242245

246+
### Vicon bridge
247+
TODO: Expand
248+
243249
### Common errors
244250

245251
#### libNatNet
246252
If libNatNet is missing either during compiling crazyswarm or launching hover_swarm.launch, one option is to manually install it. Download the library from its [github repo](https://github.com/whoenig/NatNetSDKCrossplatform), follow the build instructions, and then add the library to your `LIBRARY_PATH` and `LD_LIBRARY_PATH` variables.
247253

254+
#### LIBUSB_ERROR_ACCESS
255+
Change the USB access permissions with
256+
257+
```sudo chmod -R 777 /dev/bus/usb/```
258+
248259
### Fly with the drones
249260

250261
#### Settings
@@ -274,7 +285,7 @@ roslaunch crazyswarm cf_sim2real.launch
274285
In a second terminal:
275286

276287
```bash
277-
python scripts/deploy.py --controller <path/to/your/controller.py> --config config/level3.yaml
288+
python scripts/deploy.py --controller <path/to/your/controller.py> --config config/level3.toml
278289
```
279290

280291
where `<path/to/your/controller.py>` implements a controller that inherits from `lsy_drone_racing.controller.BaseController`

benchmarks/config/test.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[sim]
2-
physics = "pyb" # pyb: PyBullet, dyn: Mathematical dynamics model, TODO: Complete the list
2+
physics = "pyb"
33
camera_view = [5.0, -40.0, -40.0, 0.5, -1.0, 0.5]
44
sim_freq = 500 # Simulation frequency, in Hz
55
ctrl_freq = 500 # Controller frequency, in Hz. This frequency is used to simulate the onboard controller, NOT for the environment's step function

benchmarks/sim.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import numpy as np
88

99
if TYPE_CHECKING:
10-
import numpy.typing as npt
10+
from numpy.typing import NDArray
1111

1212
load_config_code = f"""
1313
from pathlib import Path
@@ -27,15 +27,15 @@
2727
"""
2828

2929

30-
def time_sim_reset(n_tests: int = 10) -> npt.NDArray[np.floating]:
30+
def time_sim_reset(n_tests: int = 10) -> NDArray[np.floating]:
3131
setup = load_config_code + env_setup_code
3232
stmt = """env.reset()"""
3333
return np.array(timeit.repeat(stmt=stmt, setup=setup, number=1, repeat=n_tests))
3434

3535

3636
def time_sim_step(
3737
n_tests: int = 10, sim_steps: int = 100, physics_mode: str = "pyb"
38-
) -> npt.NDArray[np.floating]:
38+
) -> NDArray[np.floating]:
3939
modify_config_code = f"""config.sim.physics = '{physics_mode}'\n"""
4040
setup = load_config_code + modify_config_code + env_setup_code + "\nenv.reset()"
4141
stmt = f"""

config/getting_started.yaml

-177
This file was deleted.

config/level0.toml

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Level 0
2+
3+
# | Evaluation Scenario | Rand. Inertial Properties | Randomized Obstacles, Gates | Rand. Between Episodes | Notes |
4+
# | :-----------------: | :-----------------------: | :-------------------------: | :--------------------: | :---------------: |
5+
# | `level0.toml` | *No* | *No* | *No* | Perfect knowledge |
6+
7+
[sim]
8+
# Physics options:
9+
# "pyb": PyBullet
10+
# "dyn": Mathematical dynamics model
11+
# "pyb_gnd" PyBullet with ground effect
12+
# "pyb_drag": PyBullet with drag
13+
# "pyb_dw": PyBullet with downwash
14+
# "pyb_gnd_drag_dw": PyBullet with ground effect, drag, and downwash.
15+
physics = "pyb"
16+
17+
camera_view = [5.0, -40.0, -40.0, 0.5, -1.0, 0.5]
18+
sim_freq = 500 # Simulation frequency, in Hz
19+
ctrl_freq = 500 # Controller frequency, in Hz. This frequency is used to simulate the onboard controller, NOT for the environment's step function
20+
gui = false # Enable/disable PyBullet's GUI
21+
22+
[sim.disturbances.action]
23+
type = "GaussianNoise"
24+
std = 0.001
25+
26+
[sim.disturbances.dynamics]
27+
type = "UniformNoise"
28+
low = [-0.1, -0.1, -0.1]
29+
high = [0.1, 0.1, 0.1]
30+
31+
[env]
32+
id = "DroneRacing-v0" # Either "DroneRacing-v0" or "DroneRacingThrust-v0". If using "DroneRacingThrust-v0", the drone will use the thrust controller instead of the position controller.
33+
reseed = true # Whether to re-seed the random number generator between episodes
34+
seed = 1337 # Random seed
35+
freq = 30 # Frequency of the environment's step function, in Hz
36+
symbolic = false # Whether to include symbolic expressions in the info dict. Note: This can interfere with multiprocessing! If you want to parallelize your training, set this to false.
37+
sensor_range = 0.45 # Range at which the exact location of gates and obstacles become visible to the drone. Objects that are not in the drone's sensor range report their nominal position.
38+
39+
[env.track]
40+
# Tall gates: 1.0m height. Short gates: 0.525m height. Height is measured from the ground to the
41+
# center of the gate.
42+
[[env.track.gates]]
43+
pos = [0.45, -1.0, 0.525]
44+
rpy = [0.0, 0.0, 2.35]
45+
[[env.track.gates]]
46+
pos = [1.0, -1.55, 1.0]
47+
rpy = [0.0, 0.0, -0.78]
48+
[[env.track.gates]]
49+
pos = [0.0, 0.5, 0.525]
50+
rpy = [0.0, 0.0, 0.0]
51+
[[env.track.gates]]
52+
pos = [-0.5, -0.5, 1.0]
53+
rpy = [0.0, 0.0, 3.14]
54+
55+
# Obstacle height: 1.05m. Height is measured from the ground to the top of the obstacle.
56+
[[env.track.obstacles]]
57+
pos = [1.0, -0.5, 0.95]
58+
[[env.track.obstacles]]
59+
pos = [0.5, -1.5, 0.95]
60+
[[env.track.obstacles]]
61+
pos = [-0.5, 0.0, 0.95]
62+
[[env.track.obstacles]]
63+
pos = [0.0, 1.0, 0.95]
64+
65+
[env.track.drone]
66+
pos = [1.0, 1.0, 0.05]
67+
rpy = [0, 0, 0]
68+
vel = [0, 0, 0]
69+
ang_vel = [0, 0, 0]

0 commit comments

Comments
 (0)