After completing Installation, a significant amount of configuration is needed before the Crazyswarm is ready to fly. Follow the steps below.

Set up radio communication

Since the Crazyflies share radios and communication channels, they need to have a unique identifier/address. The convention in the Crazyswarm is to use the following address:


where <X> is the number of the Crazyflie in the hexadecimal system. For example cf1 will use address 0xE7E7E7E701 and cf10 uses address 0xE7E7E7E70A. The easiest way to assign addresses is to use the official Crazyflie Python Client.

  1. Physically label your Crazyflies with numbers.

  2. Assign addresses using the Crazyflie Python Client (use a USB cable for easiest handling).

  3. Each radio can control about 15 Crazyflies. If you have more than 15 CFs you will need to assign different channels to the Crazyflies. For example, if you have 49 Crazyflies you’ll need three unique channels. It is up to you which channels you assign to which CF, but a good way is to use the Crazyflie number modulo the number of channels. For example, cf1 is assigned to channel 80, cf2 is assigned to channel 90, cf3 is assigned to channel 100, cf4 is assigned to channel 80 and so on.

Note: Crazyflies must be rebooted after any change of the channel/address for the changes to take effect.

Finally, add the user permissions to use the USB Radio without being root.

Update firmware

Crazyswarm is tested with the official Bitcraze firmwares for the Crazyflie and Crazyradio. We supply the binary image of the Crazyradio firmware in the /prebuilt directory.

  1. Upgrade the firmwares of your Crazyflies with the latest official release using cfclient. This will update STM32, NRF51, and attached decks (e.g., LightHouse deck). We tested version 2021.6.


    If you use a custom-built firmware, you can also use, see below. To flash on the command line, check out the official Bitcraze documentation: STM32, NRF51.

  2. Upgrade the firmware of your Crazyradios with the latest official firmware. Note that this is even required for newly bought Crazyradios.

    1. git clone

    2. python crazyradio-firmware/usbtools/

    3. sudo python crazyradio-firmware/usbtools/ flash prebuilt/cradio.bin

    4. Now unplug and re-plug the radio. You can check the version using rosrun crazyflie_tools scan -v, which should report Found Crazyradio with version 99.55.

Adjust configuration files

Several configuration files may require editing. You can edit those files in place, or follow Crazyswarm Integration with Git if you want to use your custom package.

Configure external tracking system

The first configuration file is the ROS launch file, ros_ws/src/crazyswarm/launch/hover_swarm.launch. It contains settings on which external tracking system to use, among others.

Select hardware make

First, select your tracking system in the appropriate tab below.

Vicon is fully supported and tested with Tracker 3.4. Set the host name of the Vicon machine:

# ros_ws/src/crazyswarm/launch/hover_swarm.launch
motion_capture_type: "vicon"
motion_capture_host_name: "viconPC" # hostname or IP address

If using libobjecttracker as object_tracking_type disable all objects.

Select object tracking mode (motion capture only)

The most significant configuration choice is whether or not to use unique arrangements of motion capture markers for each Crazyflie in your fleet. Select one of the tabs below for a description of each choice. Later steps in the documentation will change depending on your selection.

With a unique marker arrangement for each Crazyflie, you rely on the motion capture vendor to differentiate between objects. This is generally preferred. However, if you have lots of Crazyflies, it can be hard to design enough unique configurations – there are not many places to put a marker on the Crazyflie.

If your arrangements are too similar, motion capture software may not fail gracefully. For example, it may rapidly switch back and forth between recognizing two different objects at a single physical location.

# ros_ws/src/crazyswarm/launch/hover_swarm.launch
object_tracking_type: "motionCapture"

Enumerate Crazyflies

Second we have crazyflies.yaml, a file that lists all active Crazyflies. The Crazyswarm server reads this configuration file at startup. If it cannot communicate with all the Crazyflies defined in crazyflies.yaml, it will halt and report an error.

# ros_ws/src/crazyswarm/launch/crazyflies.yaml
  - id: 1
    channel: 100
    initialPosition: [1.5, 1.5, 0.0]
    type: default
  - id: 2
    channel: 110
    initialPosition: [1.5, 1.0, 0.0]
    type: medium

The file assumes that the address of each CF is set as discussed earlier. The channel can be freely configured. The initialPosition field is required for the simulation and for some motion capture configurations, see below.

If you use unique marker arrangements, the initialPosition field of the crazyflies.yaml entries will be ignored, but it should still be set because the parser will expect it.

It is often useful to select a subset of all available Crazyflies. The graphical “Chooser” and the additional configuration file allCrazyflies.yaml help make this easy. See Manage fleet with the Chooser for details.

Define Crazyflie types

The third configuration file crazyflieTypes.yaml defines the possible types. Each type specifies the physical attributes of the quadrotor. The type field in the crazyflies.yaml entries must refer to a type listed in this file.


Many users will not need to modify this file.

# ros_ws/src/crazyswarm/launch/crazyflieTypes.yaml
    bigQuad: False
    batteryVoltageWarning: 3.8  # V
    batteryVoltateCritical: 3.7 # V
    markerConfiguration: 0
    dynamicsConfiguration: 0
    bigQuad: True
    batteryVoltageWarning: 7.6  # V
    batteryVoltateCritical: 7.4 # V
    markerConfiguration: 1
    dynamicsConfiguration: 0
numMarkerConfigurations: 2
  "0":  # for standard Crazyflie
    numPoints: 4
    offset: [0.0, -0.01, -0.04]
      "0": [0.0177184,0.0139654,0.0557585]
      "1": [-0.0262914,0.0509139,0.0402475]
      "2": [-0.0328889,-0.02757,0.0390601]
      "3": [0.0431307,-0.0331216,0.0388839]
  "1": # medium frame
    numPoints: 4
    offset: [0.0, 0.0, -0.03]
      "0": [-0.00896228,-0.000716753,0.0716129]
      "1": [-0.0156318,0.0997402,0.0508162]
      "2": [0.0461693,-0.0881012,0.0380672]
      "3": [-0.0789959,-0.0269793,0.0461144]
numDynamicsConfigurations: 1
    maxXVelocity: 2.0
    maxYVelocity: 2.0
    maxZVelocity: 3.0
    maxPitchRate: 20.0
    maxRollRate: 20.0
    maxYawRate: 10.0
    maxRoll: 1.4
    maxPitch: 1.4
    maxFitnessScore: 0.001

The dynamics and marker configurations are only relevant when using a motion capture system for tracking, see below for details.

The markerConfiguration fields are not needed with unique marker arrangements. All marker setup should be done in your motion capture system. Create one object in your motion capture software for each marker arrangement and give them names like cf1, cf2, cf3, etc., corresponding to the IDs listed in your crazyflies.yaml.

Manage fleet with the Chooser

The graphical Chooser tool is used to enable/disable subsets of the available Crazyflies and perform other practical tasks. Chooser relies on the additional configuration file allCrazyflies.yaml, which has the same format as crazyflies.yaml (see Enumerate Crazyflies). Edit this file to contain all the Crazyflies you have available. Then, start the Chooser:

cd ros_ws/src/crazyswarm/scripts

You should see something like the screenshot below.


Each checkbox corresponds to an entry in allCrazyflies.yaml. The checkbox positions should match the initialPosition fields in the file. You can drag a box to select many checkboxes at once.

Whenever the selection is changed, the allCrazyflies.yaml entries for the selected boxes are immediately copied and written to crazyflies.yaml.


If you are using the allCrazyflies.yaml and the Chooser, you should never need to edit crazyflies.yaml manually.

The buttons perform various functions that can be tedious to do for many CFs:


Deselects all CFs.


Selects all CFs.


Retrieves battery voltage for enabled CFs. Only works if crazyflie_server is not running at the same time. Can be used while the CF is in power-safe mode.


Retrieves STM32 firmware version of enabled CFs. Only works if crazyflie_server is not running at the same time. Can only be used if CF is fully powered on.


Puts enabled CFs in power-safe mode (NRF51 powered, but STM32 turned off). Only works if crazyflie_server is not running at the same time.


Reboot enabled CFs (such that NRF51 and STM32 will be powered). Only works if crazyflie_server is not running at the same time.

flash (STM)

Flashes STM32 firmware to enabled CFs. Only works if crazyflie_server is not running at the same time. Assumes that firmware is built in crazyflie-firmware/cf2.bin. Use --stm32Fw to specify a custom path.

flash (NRF)

Flashes NRF51 firmware to enabled CFs. Only works if crazyflie_server is not running at the same time. Assumes that firmware is built in crazyflie2-nrf-firmware/cf2_nrf.bin. Use --nrf51Fw to specify a custom path.

Testing configuration

Once you have finished configuration, move on to the Hovering (hello, world) tutorial for your first test flight!