There is a new release of the firmware, version 2024.2. The main change, and almost only change, in this release, is the Bluetooth stack that was updated from the Nordic’s semiconductor S110 to S130, which affects the firmware on the NRF51 on the Crazyflie. This was mainly done to be able to pass the listing requirement on Bluetooth SIG, but it will also have beneficial technical effects on the Crazyflie radio communication state of affairs.

The new stack and bootloader are distributed in the normal release .zip, which means that it can be updated from the client as normal. Please note that the latest lib and clients are required as we have had to implement new procedures to flash the bootloader and stack.

First of all, let’s define what is a soft device. Nordic semiconductor radio chips are awesome in the way that the radio hardware is fully documented, this means that we can implement our own radio protocols but we would also be able to implement our own Bluetooth stack (I have attempted that a long time ago with some success, the nRF5 radio hardware is really powerful and can be set up to do much of the work!). However, backing your own Bluetooth stack would require passing a full suite of validation at the Bluetooth SIG to prove the stack conform to specification. In order to avoid that, the usual strategy is to buy a Bluetooth device and to talk to it over UART. What Nordic did is to implement a “Softdevice”, a binary blob that runs in the same CPU as the user application and that talks to the application using software interrupt. This keeps the application completely separated from the Bluetooth stack and so means that we get the benefits of a pre-qualified Bluetooth stack that has already been tested and approved.

Currently, we have ported the bootloader and the nrf firmware to the new S130 stack. This opens a lot of potential benefits for the future:

  • The new stack should be at least 6 times faster than the old one. This makes implementing BLE communication for the Crazyflie to a PC/Chromebook much more appealing and should allow to make the existing mobile client more full features.
  • We are now able to update the bootloader, so we can make a new improved version of it in the future (ie. with safe link, swarm optimization, much faster Bluetooth boot loading….)
  • The new stack supports device and host mode. So things like pairing a gamepad with the Crazyflie becomes a technical possibility! (actual implementation is left as an exercise for the contributor ;-).

One very important thing to note is that working on the bootloader requires a debugger: if you flash a bugged radio bootloader you need a SWD debug probe to be able to fix your Crazyflie. The bootloader+softdevice flashing procedure is very safe, as long as you flash a working firmware.

This change should open quite new exciting possibilities. It will be interesting to see what we can achieve with BLE and updated bootloaders in the future. Please note that we had to make a change to both the Crazyflie python library and the CFclient in order to flash this new firmware so make sure that you update those as well to try out this new release.

Developer meeting

The next developer meeting will be on the 6th of March 2024, we will talk about the Crazyflie Supervisor subsystem… We have made some changes to the supervisor recently, and we will continue working more on it in the next couple of weeks mostly preparing for the arrival of the Brushless Crazyflie. We will talk about the current state and what we are working on. Follow the thread on Bitcraze Discussions to be up to date on how to join!

You may have noticed that the HQ propellers, which are a part of the thrust upgrade bundle, have been out of stock for quite some time now. I know that many of you are relying on those propellers for the additional 20 grams of thrust they allow, so I have some news – some good, some bad.

Let’s start with the bad news: our partner and manufacturer, unfortunately, faced some problems with the mold they were using for these propellers- we prepared to face the fact that having our thrust propellers as they were before was not possible anymore. With the mold in this state, we could never go back to the same version of those propellers. To be a little dramatic, the high-quality propellers have taken their final spin. We knew it could take some time to find a good solution, and were prepared to communicate about a long-time shortage of the item.

But now for the good news! Thankfully, the replacement mold our partner used proved to be as good as the previous one – and faster than scheduled. Now back in stock, the HQ propeller can fly as well as its predecessor. We tested it and it showed the same characteristics that we’ve come to expect from the thrust upgrade.

Picture of 4 new HQ ultralight propellers -from a 45 degrees angle

So, what’s the real difference? Well, since it maintains the same level of performance, agility, and stability, not much. They have an updated design and have an added “ultralight” in the name (which sounds cooler, doesn’t it?). Those of you with a keen sense of observation will also notice that they have a new SKU – as well as the thrust upgrade bundle.

All in all, this change will have minimal impact on your flying if you’re used to the thrust upgrade bundle. Don’t hesitate to try out this new version and give us some feedback if you have any!

Hi everyone,

I’m Rik, and today marks my return to Bitcraze. Some of you might remember me from a couple of years back when I spent a few months here as an intern. Perhaps you’ve even stumbled upon my guest blog post discussing the paper that concluded my master’s degree. I’m thrilled to be back in the fold!

Picture of Rik smiling against the Bitcraze logo

It’s exciting to be back in Sweden. I love to cook, and although traditional Swedish and Dutch cuisine share quite some similarities (a lot of potatoes and gravy), it’s nice to try out new ingredients and foods. Additionally, being close to the great outdoors is a major draw for me. I already went on my first hike and I heard there are some nice bouldering areas not so far from Malmö.

One of the things that initially attracted me to Bitcraze are its close ties with the research community. In fact, it was through my own research as a master’s student that I first encountered the company. I’m eager to deepen these connections further and collaborate with researchers across various disciplines. Combining this with a team of talented colleagues and a vibrant enthusiast community makes it a great opportunity to learn!

I’m particularly drawn to Bitcraze’s unique organizational ethos. The emphasis on self-organization and collective success resonates with me. The idea of continuously shaping our workplace to reflect our values truly excites me.

See you around!

If you haven’t seen it yet then check out our latest Christmas video! In it, we show off a bunch of new stuff, with the main ones being the new Crazyflie brushless and the Lighthouse V2 (which supports up to 16 base stations). But there were also a few other things featured in the video! One of them is the charging pad the Crazyflie brushless takes off from and lands on in the video. This weeks blog post is about the charger, how it came to be, how it works and what lies ahead.

Picture of the Crazyflie brushless on the charging pad

Some history

A while back I worked a bit on a contact charger for the Crazyflie 2.1. The idea was to try and make a design where small pogo-pins could be added to various decks which would allow the Crazyflie 2.1 to charge when lading on a charging pad. Some of the issues with the design was that the area was small (it had to fit on a deck), it put requirements on each deck and that some decks (like the Flow V2 deck) has components which are taller than the pogo-pins. So after the blog post back in 2021 this has been on the shelf, until recently when the Crazyflie brushless work has been moving forward.

With the new prototype design for the Crazyflie brushless being made, there was a chance to address some of the issues I’ve seen before and do another try. All we needed was to add some pads for soldering pogo-pins on the wings (which actually wasn’t as easy as one would think due to layout constraints). So now the charging points didn’t have to be on each deck, they are built into the Crazyflie BL base. The distance between the points is also larger, allowing for a bigger hole in the charging PCB and allowing for a higher variety of decks, like the LED ring with the diffuser shown in the video.

The last missing part of the puzzle was when we needed to do more flight testing with the Crazyflie brushless. We wanted to reproduce the infinite flight demo we previously had for the Crazyflie 2.1, but the current Qi charger pad didn’t work with the new Crazyflie brushless. Time for the next iteration of the charger prototype!

Under the hood

So how complex can you make a charger? Lots! When making a prototype I like to add as much ideas possible to the design. Missing something you wanted to test and doing a new version takes a lot of time but adding some extra crazy ideas might be pretty quick in the design phase. A lot of the time ideas are scrapped along the way, most of the time because of space- or price constraints. Sometimes they are just bad or too complex. Luckily in this case the charger has a large PCB with lots of space and it’s just an early prototype so there’s (almost) no bad ideas!

Under the hood (or 3D printed plastic in this case) there’s a bunch of stuff:

  • An WiFi/BLE module, the ESP32-C6-MINI
  • USB-C connector
  • USB-PD controller
  • 6 DC-jack connectors and 5 terminals for connecting power
  • Measurement of charging current and supply voltage
  • 12 WS2812B RGB LEDs for the outer ring and 12 for the inner one
  • 20-to-5V DC/DC and 5-to-3V3 DC/DC
  • Some debugging LEDs and UART

Intended use

The idea with the contact charger has been to easily charge your Crazyflie without disconnecting the battery, plugging in the micro-USB connector or blocking the use of decks facing downwards like the Qi charger does. In addition to this I also wanted to try out some other ideas.

Chaining chargers: When we go to fairs we normally show a demo of 9 x Crazyflie 2.1 flying with decentralized decision making and the lighthouse positioning system. As you can see there’s a lot of power cords and charging pads laying around. The idea here was to chain the power supplies together and also attach the chargers to each other (hence the hexagonal shape).

WiFi: For a long time I’ve had a prototype of a server for connecting various hardware to (like a charger) so I wanted to try to connect it to this for monitoring.

BLE: The idea was that the Crazyflie could talk to the charger via BLE to for instance change the light effect.

LEDs (and lots of them): The idea was to give some feedback from the charging of the Crazyflie but also to give the charger the ability to act as something more, like lighting up when a Crazyflie decides to land on it.

USB-PD: This is connected to the chaining of power. The ideas was to connect a USB-C charger and distribute the power from it to other chargers via the DC-jack.

Rust: Like we’ve written about before, we’ve been trying out more and more Rust here at Bitcraze. This is yet another experiment, the firmware for the charger is written in Rust using Embassy.


Currently the charger is an internal project, since we use it in our lab for the infinite flight. But it’s of course something that would be exciting to offer our users if there any interest. So let us know what you think!

Also, don’t forget to join us for this Wednesday’s dev meeting. the main topic will be about the Kalman filters however we can answer questions about the wireless as well!

A while ago, we wrote a generic blog post about state estimation in the Crazyflie, mostly discussing different ways the Crazyflie can determine its attitude and/or position. At that time, we only had the Complementary filter and Extended Kalman filter (EKF). Over the years, we’ve made some great additions like the M-estimation-based robust Kalman filter (an enhancement of the EKF, see this blog post) and the Unscented Kalman filter.

However, we have noticed that some of our beginning users struggle with understanding the concept of Kalman filtering, depending on whether this has been covered in their curriculum. And for some more experienced users, it might be nice to have a recap of the basics as well, since this is a very important part of the Crazyflie’s capabilities of flight (and also for robotics in general). So, in this blog post, we will explain the principles of Kalman filtering and how it is applied within the Crazyflie firmware, which hopefully will provide a good base for anyone starting to delve into state estimation within the Crazyflie.

We will also have a developer meeting about Kalman filtering on the Crazyflie, so we hope you can join that as well if you have any questions about how it all works. Also we are planning to got to FOSdem this weekend so we hope to see you there too.

Main Principles of the Kalman Filter

Anybody remotely working with autonomous systems must, at one point, have heard of the Kalman filter, as it has existed since the 60s and even played a role in the Apollo program. Understanding its main principles is also important for anyone working with drones or robotics. There are plenty of resources available, and its Wikipedia page is filled with examples, so here we will focus mostly on the concept and principles and leave the bulk of the mathematics as an exercise for those who like to delve into that :).

So basically, there are several principles that apply to a Kalman filter:

  • It estimates a linear system that is driven by stochastic processes. The probability function that drives these stochastic processes should ideally be Gaussian.
  • It makes use of the Bayes’ rule, which is a general term in statistics that describes the probability of an event happening based on previous knowledge related to that event.
  • It assumes that the ‘to be estimated state’ can be described with a Markov model, which assumes that a sequence of the next possible event (or scenario) can be predicted by the current event. In other words, it does not need a full history of events to predict the next step(s), only the information from the event of one previous step.
  • A Kalman filter is described as a recursive filter, which means that it reuses (part of) its output as input for the next filtering step.

So the state estimate is usually a vector of different variables that the developer or user of the system likes to observe, for either control or prediction, something like position and velocity, for instance: [x, y, , ẏ, …]. One can describe a dynamics model that can predict the state in the next step using only the current time step’s state, like for instance: xt+1 = xt + t, yt+1 = yt + ẏt. This can also be nicely described in matrix form as well if you like linear algebra. To this model, you can also add predicted noise to make it more realistic, or the effect of the input commands to the system (like voltage to motors). We will not go into the latter in this blogpost.

The Concept of Kalman filters

Simplified block scheme of Kalman filtering

So, we will go through the process of explaining the steps of the Kalman filter now, which hopefully will be clear with the above picture. As mentioned before, we’d like to avoid formulas and are oversimplifying some parts to make it as clear as possible (hopefully…).

First, there is the predict phase, where the current state (estimate) and a dynamics model (also known as the state transition model) result in a predicted state. Also in the same phase, the predicted estimated covariance is calculated, which also uses the dynamics model plus an indication of the process noise model, indicating how much the dynamics model deviates from reality in predicting that state. In an ideal world and with an ideal model, this could be enough; however, no dynamics model is perfect, which is why the next phase is also very important.

Then it’s the update phase, where the filter estimate gets updated by a measurement of the real world through sensors. The measurement needs to go through a measurement model, which transforms the measurement into a measured state (also known as innovation or measurement pre-fit residual). Usually, a measurement is not a 1-1 depiction of one variable of the state, so the measurement model ensures that the measurement can properly be compared to the predicted state. This same measurement model, accompanied by the measurement noise model (which indicates how much the measurement differs from the real world), together with the predicted covariance, is used to calculate the innovation and Kalman gain.

The last part of the update phase is where the predictions are updated with the innovation. The Kalman gain is then used to update the predicted state to a new estimated state with the measured state. The same Kalman gain is also used to update the covariance, which can be used for the next time step.

An 1D example, height estimation

It’s always good to show the filter in some form of example, so let’s show you a simple one in terms of height estimation to demonstrate its implications.

1D example of height estimation

You see here a Crazyflie flying, and currently it has its height estimated at zt and its velocity at żt. It goes to the predict phase and predicts the next height to be at zt+1,predict, which is a simple model of just zt + żt. Then for the innovation and updating phase, a measurement (from a range sensor) rz is used for the filter, which is translated to zt+1, meas. In this case, the measurement model is very simple when flying over a flat surface, as it probably is only a translation addition of the sensor to the middle of the Crazyflie, or perhaps a compensation for a roll or pitch rotation.

In the background, the covariances are updated and the Kalman gain is calculated, and based on zt+1,predict and zt+1, meas, the next state zt+1 is calculated. As you probably noticed, there was a discrepancy between the predicted height and measured height, which could be due to the fact that the dynamics model couldn’t correctly predict the height. Perhaps a PID gain was higher than expected or the Crazyflie had upgraded motors that made it climb faster on takeoff. As you can see here, the filter put the estimated height closer to zt+1 to the measurement than the predicted height. The measurement noise model incorporated into the covariances indicates that the height sensor is more accurate than the height coming from the dynamics model. This would very well be the case for an infrared height sensor like the one on the Flow Deck; however, if it were an ultrasound-based sensor or barometer instead (which are much noisier), then the predicted height would be closer to the one predicted by the dynamics model.

Also, it’s good to note that the dynamics model does not currently include the motor input, but it could have done so as well. In that case, it would have been better able to predict the jump it missed now.

A 2D example, horizontal position

A 2D example in x and y position

Let’s take it up a notch and add an extra dimension. You see here now that there is a 2D solution of the Crazyflie moving horizontally. It is at position xt, yt and has a velocity of t, ẏt at that moment in time. The dynamics model estimates the Crazyflie to end up in the general direction of the velocity factor, so it is a simple addition of the current position and velocity vector. If the Crazyflie has a flow sensor (like on the Flow Deck), flow fx, fy can be detected and translated by the measurement model to a measured velocity (part of the state filter) by combining it with a height measurement and camera characteristics.

However, the measurement in the form of the measured flow fx, fy estimates that there is much more flow detected in the x-direction than in the y-direction. This can be due to a sudden wind gust in the y-direction, which the dynamics model couldn’t accurately predict, or the fact that there weren’t as many features on the surface in the y-direction, making it more difficult for the flow sensor to measure the flow in that direction. Since this is not something that both models can account for, the filter will, based on the Kalman gain and covariances, put the estimate somewhere in between. However, this is of course dependent on the estimated covariances of both the outcome of the measurement and dynamic models.

In case of non-linearity

It would be much simpler if the world’s processes could be described with linear systems and have Gaussian distributions. However, the world is complex, so that is rarely the case. We can make parts of the world more abstract in simulation, and Kalman filters can handle that, but when dealing with real flying vehicles, such as the Crazyflie, which is considered a highly nonlinear system, it needs to be described by a nonlinear dynamics model. Additionally, the measurements of sensors in more complex and 3D situations usually don’t have a one-to-one linear relationship with the variables in the state. Can you still use the Kalman filter then, considering the earlier mentioned principles?

Luckily certain assumptions can be made that can still make Kalman filters useful in the sense of non-linearity.

  • Extended Kalman Filter (EKF): If there is non-linearity in either the dynamics model, measurement models or both, at each prediction and update step, these models are linearized around the current state variables by calculating the Jacobian, which is a collection of first-order partial derivative calculations of the model and the state variables.
  • Unscented Kalman Filter (UKF): An unscented Kalman filter deals with linearities by selecting sigma points selected around the mean of the state estimate, which are backpropagated through the non-linear dynamics model.

However, there is also the case of non-Gaussian processes in both dynamics and measurements, and in that case a complementary filter or particle filter would be best suited. The Crazyflie contains a complementary filter (which does not estimate x and y), an extended Kalman filter and an experimental unscented Kalman filter. Check out the state-estimation documentation for more information.

So…. where is the code?

This is all fine and dandy, however… where can you find all of this in the code of the Crazyflie firmware? Here is an overview of where you can find it exactly in the sense of the most used filter of them all, namely the Extended Kalman Filter.

There are several assumptions made and adjustments made to the regular EKF implementation to make it suitable for flight on the Crazyflie. For those details I’d like to refer to the papers on where this implementation is based on, which can be found in the EKF documentation. Also for a more precise explanation of Kalman filter, please check out the lecture slides of Stanford University on Linear dynamical systems or the Linköping university’s course slides on Sensor Fusion.

Update: From the comments we also got notified of an nice EKF tutorial where you write the filter from scratch (github) from Prof. Simon D. Levy from Washington and Lee university. Practice makes perfect!

Next Developer meeting and FOSdem

As you would have guessed, our next developer meeting will be about the Kalman filters in the Crazyflie. Keep an eye on this Discussion thread for more details on the meeting.

Also Kimberly and Arnaud will be attending FOSdem this weekend in Brussels, Belgium. We are hoping to organize an open-source robotics BOF/meetup there, so please let us know if you are planning to go as well!

Today we have a guest blogpost by Thomas Izycki (Technische Hochschule Augsburg) and Klaus Kefferpütz (Ingolstadt Technical University of Applied Sciences, former Augsburg Technical University of Applied Sciences) talking about implementing Software-in -the-Loop for swarm simulation of the Crazyflie.

When our cooperative control lab at the Technical University of Applied Sciences Augsburg was founded a few years ago, our goal was to develop distributed algorithms for teams of UAVs. We quickly decided to use Crazyflies with the algorithms directly implemented in the firmware, thus having a platform for a truly decentralized system. Our ongoing projects focus on cooperative path planning, navigation, and communication.

Since working with several drones at once, which have to communicate and coordinate with each other, can quickly become confusing and very time-consuming, a simulation was needed. It should preferably offer the possibility to integrate the firmware directly in the simulation environment and ideally also offer an interface to the crazyflie python API. With the relocation of our laboratory from Augsburg to the Technical University of Applied Sciences Ingolstadt, which however does not yet have a permanently established flying space, the need for a simulation environment was further increased in order to be less dependent on hardware accessibility. A look at the community and the available simulations quickly led us to the sim_cf flight simulator for the Crazyflie. A fantastic project supporting the use of the actual Crazyflie firmware in software-in-the-loop (SITL) mode and even in hardware-in-the-loop (HITL) mode on a real Crazyflie using the FreeRTOS Linux Port together with ROS and Gazebo. Unfortunately, the project has not been maintained for several years and also had no integration with the Crazyflie Python API. After a short chat with Franck Djeumou and his agreement to use the code of the original sim_cf simulation, the project was ready for an upgrade.

sim_cf2 Flight Simulator

With support for ROS coming to an end we decided to migrate the project to ROS2 and additionally support the current version of the Crazyflie firmware, which at this time is release version 2023.11. With the addition of a driver to connect the cflib to the SITL process, the same python cflib-based scripts can now be used with real Crazyflies and for use in the simulation environment. Only the corresponding driver needs to be loaded during initialization. Overall, the focus of the sim_cf2 simulation is now on using the Crazyflie python API instead of commanding the Crazyflies via ROS.

As for the Crazyflie firmware the whole build process has been fully integrated into the firmware’s KBuild build system. This also allows the use of the same code base for simulation and execution on the real Crazyflie. Depending on the configuration, the firmware is compiled for the STM32F on the Crazyflie or the host system running the SITL.

Components of the sim_cf2 Flight Simulator

To run the simulation, the three modules must therefore be started separately. Gazebo is started using the main launch file. The number and initial pose of the simulated Crazyflies is also defined in this file. Once the firmware for the host system has been built, the desired number of SITL instances can be started using the attached script. Finally, a cflib-based script, the Crazyflie client or the multi-agent client presented below is started. With no radio dongles attached to the computer, the simulation driver is initialized automatically and a connection to the simulated Crazyflie can be established.

There are still a few open issues, including the absence of implemented decks for positioning, such as LPS and Lighthouse. Currently, the absolute position is sent from Gazebo to the SITL instance and fused in the estimator. Moreover, Gazebo requires quite a lot of computing power. We were able to run a maximum of four Crazyflies simultaneously on a relatively old laptop. However, a modern desktop CPU with multiple cores allows for simulating a significantly larger number of Crazyflies.

Multi-Agent Client

Independent of the simulation we designed a GUI for controlling and monitoring our multi-agent teams. It currently supports up to eight Crazyflies but could be upgraded for bigger teams in the future. So far it has been enough for our requirements.

Multi-Agent Client with six connected Crazyflies

A central feature is the interactive map, which makes up about half of the gui. This is a 2D representation of the flight area with a coordinate system drawn in. Connected Crazyflies are displayed as small circles on the map and a new target position can be assigned by clicking on the map after they have been selected by their corresponding button. If required, obstacles or paths to be flown can also be drawn into the map.

Pseudo-decentralized communication

An important aspect of a truly decentralized system is peer to peer communication. It allows information to be exchanged directly between agents and ideally takes place without a central entity. Currently peer to peer communication is not available in the Crazyflie ecosystem, but is in development.

For this reason, we have implemented a workaround in our client, enabling a pseudo-decentralized communication system. This involves adding an additional layer to the Crazy RealTime Protocol (CRTP), which we named the Multi-Agent Communication Protocol (MACP). It consists of an additional packet header made of the destination ID, source ID and a port as endpoint identifier. Every ID is unique and directly derived from the Crazyflie’s address.

These MACP packets are sent via the unused CRTP port 0x9. The packet routing mechanism implemented in the client forwards the packets to their destination. It is also possible to send packets as a broadcast or to address the client directly.

On the firmware side, we have added a corresponding interface to simplify the sending and receiving of macp packets. It is analogous to the CRTP implementation and allows the registration of callback functions or queues for incoming packets on corresponding ports. It can be activated via KBuild.

At least for use in the laboratory and the development of distributed algorithms, this method has proven its worth for us.


We hope that the sim_cf2 simulation can also be useful to others. The complete source code is available on GitHub. Further information concerning installation and configuration can be found in the readme files in the respective repositories.

We would also like to point out that other simulations have been created that are based on sim_cf and therefore offer similar functionality. One of these projects is CrazySim, also available on GitHub. Moreover, there are ongoing efforts to officially integrate such a software-in-the-loop simulation into the Crazyflie firmware and ecosystem.


Multi-Agent Client:

Show-and-tell post of CrazySim:

For the original sim_cf Flight Simulator for the Crazyflie visit:

Hi everyone!

Starting today, I, Björn, have started my master thesis here at Bitcraze. My thesis topic will revolve around fault detection of erroneous states as well as appropiate system responses whenever a fault has been detected. So far, since it’s my first day, I’ve only familiarized myself with the Crazyflie system and gotten to know the lovely people at Bitcraze.

Starting off with fault detection, my initial approach will be to design several observers, each dedicated to a specific sensor, from this, a faulty sensor reading can hopefully be detected by comparing the expected value with the measured one (i.e residual) when combined with an appropriate filter and/or statistical test.

If the result are promising, the suggested strategy could improve the safety of crazyflie, protecting both its surrounding environment, aswell as itself.

Looking forward, I’m excited to get this thesis going and hope to find some interesting results to share with you all.


A few years ago, we wrote a blogpost about the Commander framework, where we explained how the setpoint structure worked, which drives the controller of the Crazyflie, which is an essential part of the stabilization module. Basically, without these, there would not be any autonomy on the Crazyflie, let alone manual flight.

In the blogpost, we already shed some light on where different setpoints can come from in the commander framework, either from the Crazyflie python library (externally with the Crazyradio), the high level commander (onboard) or the App layer (onboard).

General framework of the stabilization structure of the crazyflie with setpoint handling. * This part is takes place on the computer through the CFlib for python, so there is also communication protocol in between. It is left out of this schematics for easier understanding.

However, we notice that there is sometimes confusion regarding these different functionalities and what exactly sends which setpoints and how. These details might not be crucial when using just one Crazyflie, but become more significant when managing multiple drones. Understanding how often your computer needs to send setpoints or not becomes crucial in such scenarios. Therefore, this blog post aims to provide a clearer explanation of this aspect.

Sending set-points directly from the CFlib

Let’s start at the lower level from the computer. It is possible to send various types of setpoints directly from a Python script using the Crazyflie Python library (cflib for short). This capability extends to tasks such as manual control:

send_setpoint(roll, pitch, yawrate, thrust)

or for hover control (velocity control):

send_hover_setpoint(vx, vy, yawrate, zdistance)

You can check the automatic generated API documentation for more setpoint sending options.

If you use these functions in a script, the principle is quite basic: the Crazyradio sends exactly 1 packet with this setpoint over the air to the Crazyflie, and it will act upon that. There are no secret threads opening in the background, and nothing magical happens on the Crazyflie either. However, the challenge here is that if your script doesn’t send an updated setpoint within a certain amount of time (default of 2 seconds), a timeout will occur, and the Crazyflie will drop out of the sky. Therefore, you need to send a setpoint at regular intervals, like in a for loop, to keep the Crazyflie flying. This is something you need to take care of in the script.

Example scripts in the CFlib that are sending setpoints directly:

Setpoint handling through Motion Commander Class

Another way to handle the regular sending of setpoints automatically in the CFLib is through the Motion Commander class. By initializing a Motion Commander object (usually using a context manager), a thread is started with takeoff that will continuously send (velocity) setpoints at a fixed rate. These setpoints can then be updated by the following functions, for instance, moving forward with blocking:


or a giving body fixed velocity setpoint updates (that returns immediately):

start_linear_motion(vx, vy, vz, rate_yaw)

You can check the Motion Commander’s API-generated documentation for more functions that can be utilized. As there is a background thread consistently sending setpoints to the Crazyflie, no timeout will occur, and you only need to use one of these functions for the ‘behavior update’. This thread will be closed as soon as the Crazyflie lands again.

Here are example scripts in the CFlib that use the motion commander class:

Setpoint handling through the high level commander

Prior to this, all logical and setpoint handling occurred on the PC side. Whether sending setpoints directly or using the Motion Commander class, there was a continuous stream of setpoint packets sent through the air for every movement the Crazyflie made. However, what if the Crazyflie misses one of these packets? Or how does this stream handle communication with many Crazyflies, especially in swarms where bandwidth becomes a critical factor?

This challenge led the developers at the Crazyswarm project (now Crazyswarm2) to implement more planning autonomy directly on the Crazyflie itself, in the form of the high-level commander. With the High-Level Commander, you can simply send one higher-level command to the Crazyflie, and the intermediate substeps (setpoints) are generated on the Crazyflie itself. This can be achieved with a regular takeoff:


or go to a certain position in space:

go_to(x, y)

This can be accomplished using either the PositionHLCommander, which can be used as a context manager similar to the Motion Commander (without the Python threading), or by directly employing the functions of the High-Level Commander. You can refer to the automated API documentation for the available functions of the PositionHLCommander class or the High-Level Commander class.

Here are examples in the CFlib using either of these classes:

Notes on location of autonomy and discrepancies

Considering the various options available in the Crazyflie Python library, it’s essential to realize that these setpoint-setting choices, whether direct or through the High-Level Commander, can also be configured through the app layer onboard the Crazyflie itself. You can find examples of these app layer configurations in the Crazyflie firmware repository.

It’s important to note some discrepancies regarding the Motion Commander class, which was designed with the Flow Deck (relative positioning) in mind. Consequently, it lacks a ‘go to this position’ equivalent. For such tasks, you may need to use the lower-level send_position_setpoint() function of the regular Commander class (see this ticket.) The same applies to the High-Level Commander, which was primarily designed for absolute positioning systems and lacks a ‘go forward with x m/s‘ equivalent. Currently, there isn’t a possibility to achieve these functionalities at a lower level from the Crazyflie Python library as this functionality needs to be implemented in the Crazyflie firmware first (see this ticket). It would be beneficial to align these functionalities on both the CFlib and High-Level Commander sides at some point in the future.

Hope this helps a bit to explain the commander frame work in more detail and where the real autonomy lies of the Crazyflie when you use different commander classes. If you have any questions on what the Crazyflie can do with these, we advise you to ask your questions on and we will try to point you in the right direction and give examples!

It’s the first day of the year, and it’s become traditional now at the beginning of a new year to (fore)see what we have in store for 2024.

Here is how we think it will go:


The Christmas video was filled with promising prototypes (it’s here if you missed it!) that we hope to get to your lab in 2024. The Lighthouse deck 2.0 (which allows for positioning from 16 base stations) and the Crazyflie 2.1 Brushless will continue to be in our focus.
We plan also to change a little bit what’s in your Crazyflie 2.1 box. The 47-17 propellers and the longer pin headers will come as standard in the kit, which will be renamed Crazyflie 2.1+ for the occasion.
We have as usual a lot of prototypes that we’re hoping to be able to present to you someday, so keep reading our blogposts to keep you updated!


We are interested in some conferences in 2024. Even though our schedule is not clear, we’re hoping to join at least ICRA in Yokohama and ROScon in Odense.

We will continue the developer meetings – the first in January is actually next Wednesday and should be only a support meeting. You’re welcome to join if you have any questions!

Also we are planning to continue helping to host the Aerial ROS community working group meetings. Moreover, ROScon will be very near us this year as well, so that would be nice to join too.

We’re continuing our collaboration with Flapper Drones, and are also excited to dive into the school education together with Droneblocks!


Even if we’re sad to see Kristoffer pursue new adventures, we’re hoping his gap can be filled soon. We have spent a lot of time in the last months trying to find the next Bitcrazer(s), and hope 2024 will be filled with new faces!

Of course, those are the things we can see coming for us in 2024 – we hope most of them come true!

We wish you a great year, filled with hacking, developping, and flying ideas!

It’s not often a blog post happens on the 25th of December, so this time, you’re having a treat with some new Bitcraze prototypes as a present from us! If you have time to get away from the Christmas table, there’s something we’d love you to watch:

Now let’s try to see if you noticed all the new stuff you see in this video!

Our new flight lab

We teased it, but in the beginning of December, we got our extended flight lab! We added 110 m2 to our flight space. It was a rush to have everything ready for the video – we cleaned everything, painted the walls and the green logo, set up the positioning system without our truss… But now we’re happy to show you how big the space is! Even if it’s hard to convey the real size on camera.

The Crazyflie 2.1 brushless

We already talked about it in this blog post, but the brushless has made significant progress and we feel confident that you will get your hands on it in 2024. Here, we use the extra power for a fast and agile flight. It also was very stable and didn’t crash once during the shooting!

The Lighthouse V2

Yes, you counted right! The Brushless flew with 16 base stations! We’ve worked really hard this past three months to create a new Lighthouse deck – the Lighthouse deck 2.0. It could get its position from 16 base stations. That’s 4 times more than what was previously possible! It behaved consistently well during the different tries, and we are really happy with the result. Right now, it’s just a prototype, but we’re hoping to get it to the next step in the coming months.

The contact charging station

Marcus created a power charger for the Brushless that doesn’t need any extra deck to allow for charging. It connects with the brushless feet. It has also the cool feature of changing LEDs indicating the status (idle, charging or charged). It is also a prototype, and we don’t know if this will end up being a product

The high-power LED

This is trickier to see, but it’s not our usual LED ring that the brushless carries. It’s a new, powerful LED underneath. It is so powerful that it nearly blinded us when we tried it for the first time. We put a diffuser on it, and it allowed the Crazyflie to be visible at such a high pace! This is a prototype too of course and we’re not sure if we will release it, but it’s fun to use for this kind of project.

Other announcements

During this week, our office is closed- we take this week to celebrate and rest a little before 2024. This means that shipping and support will be greatly reduced.

But we’re back the week after- at a somewhat reduced pace though. The developer meeting on the 3rd of January is maintained but without any presentation. We’ll take this time to answer any questions you have and talk a little! The details are here.

Bitcraze got their presents this year: a handful of working prototypes! We hope we got your wishes too, merry Christmas to you!