Experiment code for Crazyflow. It covers simulator speed benchmarks, sim-to-real validation, system identification, learned controllers, sampling-based obstacle avoidance, drone racing, and vision policies from Gaussian splats.
We use pixi for the environments. Install pixi with
curl -fsSL https://pixi.sh/install.sh | bashand restart your shell, then fetch the submodules with
git submodule update --init --recursiveOne of the simulators we compare against relies on IsaacGym, which is not available from PyPI. It has to be fetched before installing anything.
pixi run --frozen setup-isaacgym
pixi installEnvironments build their native dependencies through activation scripts in tools/, so the first
entry into one takes a while.
Each experiment has its own environment to avoid dependency conflicts between different simulations and deployment tools.
| Environment | Experiments |
|---|---|
crazyflow |
benchmarks/ |
sim2real |
sim2real/ |
sysid |
sysid/ |
racing |
racing/ |
mppi |
mppi_obstacles/ |
figure8, learn2fly, throw |
figure8/, learn2fly/, throw/ |
vision |
vision/ |
pybullet, flightning, l2f, flightmare, diff-aero, aerial-gym |
Baselines for benchmarks/ and sim2real/ |
Enter an environment with pixi shell -e <env>, or run a single command in it with
pixi run -e <env> <command>.
Every script that flies the real drone takes its state from motion capture and talks to the drone over the radio. Launch the tracker and the estimator in separate terminals first.
pixi run -e sim2real ros2 launch motion_capture_tracking launch.py
pixi run -e sim2real python submodules/drone-estimators/drone_estimators/ros_nodes/ros2_node.py \
--drone_name cf<your_drone_id> --legacyAny environment with ROS works. The drone id, radio channel and model come from the config file of the experiments.
A PX4 vehicle is flown from its companion computer through MAVROS instead. Install the repository
there with pixi as well: the sim2real and sysid environments also resolve for linux-aarch64,
so pixi install -e sysid works on a Jetson. The ROS environments build mavros_msgs into
ros_ws/ on activation (tools/setup_mavros_msgs.sh, pin MAVROS_MSGS_REF to the MAVROS version
of the companion computer) and motion_capture_tracking (tools/setup_mocap.sh). On aarch64 acados
is not built, cfclient is not installed, and JAX runs on the CPU. Set the drone model in the config
to anything but a Crazyflie, e.g. hb_x500, and describe the vehicle in its table of
sysid/config_drones.toml, thrust curve and limits included, and MAVROS in [drone.px4]. Start the
script, then arm and flip the RC mode switch to OFFBOARD: it flies to the start of the experiment,
through the trajectory, and holds position at the end until you take over with the RC, which works
at any time. localization in [drone.px4] picks where the estimate comes
from, "gps" outdoors on an RTK fix or "mocap" indoors, and the flight aborts into PX4's landing
mode when that measurement goes stale. The scripts see the vehicle in a global frame with x north, y
west and z up, anchored at the takeoff position with "gps" and at the motion capture origin with
"mocap", while MAVROS reports in ENU relative to the estimator origin.
Indoors the vehicle needs the motion capture pose on /mavros/vision_pose/pose. The Holybro launch
option of motion_capture_tracking publishes it there directly, without a relay node and without
the tf tree:
pixi run -e sim2real ros2 launch motion_capture_tracking holybro_launch.pyThe motion capture type, the hostname and the hb1 rigid body it tracks are in
config/holybro_cfg.yaml of the package. The launch file pins ROS_AUTOMATIC_DISCOVERY_RANGE to
LOCALHOST, so run it on the companion computer next to MAVROS, where the node reaches the motion
capture system over its own connection to hostname, or run it on the ground station and set the
range to SUBNET so MAVROS on the vehicle sees the topic.
pixi run -e sysid python crazyflow_experiments/sysid/collect_data.py
pixi run -e sim2real python crazyflow_experiments/sim2real/deploy.pyTo check a trajectory before flying it, plot the config:
pixi run -e sim2real python crazyflow_experiments/control/trajectory_visualizer.py crazyflow_experiments/sysid/config.tomlEach experiment lives in its own folder and has its own readme with the setup and the commands.
| Experiment | Readme |
|---|---|
| System identification | crazyflow_experiments/sysid/ |
| Sim2real | crazyflow_experiments/sim2real/ |
| Benchmarking | crazyflow_experiments/benchmarks/ |
| Racing | crazyflow_experiments/racing/ |
| Figure-8 tracking | crazyflow_experiments/figure8/ |
| Reach position | crazyflow_experiments/learn2fly/ |
| Throw and stabilize | crazyflow_experiments/throw/ |
| MPPI obstacle avoidance | crazyflow_experiments/mppi_obstacles/ |
| Vision | crazyflow_experiments/vision/ |
For the learned controllers (figure-8 tracking, reach position, throw and stabilize), environments and agents are implemented in core/. Checkpoints and recordings go under saves/ and results/.
Since our experiments cover multiple environments, the tests also need to run in multiple environments. Each test module therefore declares the environment it needs and skips itself elsewhere. This allows us to run a single test-all command that checks everything
pixi run test # runs the suite in the active environment
pixi run test-all # runs all tests in their respective environmentsResults go to results/ and checkpoints to saves/, both resolved through utils/paths.py.