Author: Stefan

We are happy to have been invited to the IEEE CSS Days 2026 on Wednesday the 21st of October at 19:30 UTC to talk about the Crazyflie in a controls context. The talk is 15 minutes long, including questions. We hope to see you there! Read on for more information about what the talk will contain…

Every now and then we get to interact with the community; our users, customers, ex-colleagues and others. You keep on inspiring us every time, and the discussions help us understand what you are doing in your work and where you are heading next, so that we can prioritise our work and efforts. We also enjoy sharing what is in our pipeline, what we are thinking about and how we imagine our products can be used to do awesome things. This talk will be such a session, with a focus on what improvements have been made lately to the Crazyflie ecosystem that can be interesting from a controls perspective.

IEEE CSS Days – what is it?

IEEE Control Systems Society (CSS) is the IEEE society dedicated to control systems engineering. Their flagship online showcase event, IEEE CSS Days, held 19-23 October, is virtual and free, and will highlight the society’s people, research, industry activities, community activities and more. All information can be found in the link. One of the sessions is “Technical Committee on System Identification and Adaptive Control Session”, and it is during this sessions that we have been invited to talk about the Crazyflie.

An overview of the talk

The title is “Advancements in the Crazyflie as a Testbed for Drone Control Research” – let’s break that down a little bit. We envision the Crazyflie to be a platform for trying new things; a canvas with just enough things premade for you to test your concepts with as little effort as possible. This is also true for the controls field. All the ideas floating around in the research community, and everything that has already been done, combined, intend to solve control problems at different levels and in different ways. We want to support as many ways of working as possible, and we believe we have lately done some advancements that can help you in your work. We want to share them with you, and are excited to see what cool things you can come up with using them.

Some examples of improvements

We are aware of that all of you will not be able to catch the CSS session. For that reason, here are some of the things that will be mentioned. If you have been reading the blog, you will probably recognise them:

Onboard, decentralised positioning – not really new, but something we keep coming back to when talking to the community. Lighthouse, which is laser-based, is still our highest performing positioning system. However, as we move into larger swarms, UWB has the advantage of not requiring line-of-sight between satellites and robot – this keeps Loco Positioning System interesting.

Bidirectional DSHOT and RPM telemetry – The Crazyflie Brushless now carries the possibility to get measurements of the rotor speeds. motorsGetRPM()in motors.c gives you what you need to get started.

cflib2 – The new, rust-powered cflib. It is already released (still on version 0, so expect API changes), and gives you performance and reliability boosts compared to the old cflib, and with more to come. Together with radio improvements, the radio performance has increased immensely: we have flown 49 drones on one Crazyradio in our flight lab. If you use Python for scripting, we highly recommend you try the new lib out.

As we move into bigger swarms, swarm management becomes a topic: Communication, monitoring, flashing and configuration. This is something that we are working on.

Let us know what you think of these improvements, when you start using them!

Event details

Here are the details for the talk:

Event: IEEE CSS Days
Time: 21st of October, 19:30 UTC
Speaker: Stefan Thorstenson
Title: “Advancements in the Crazyflie as a Testbed for Drone Control Research”

We hope to see you there!

And, if not, we will hopefully catch you some other time. In the meantime, keep on letting us know what you are working on – we are always interested to hear about it and discuss.

Most of us who work on Crazyflie firmware live in one corner of it at a time — a driver here, a control loop there — and rarely step back to see the whole tree at once. We built a treemap of the firmware to do exactly that: one picture, every source file, sized by how much code it actually is and grouped by the directory it lives in. It makes you realize how much is going on in the firmware to make your part work.

How the map was built

The map straight out of a real build: for the cf2 target, we let Kbuild run to completion and then read its own .cmd files, the bookkeeping Kbuild already writes for every compiled object, recording exactly which source file produced it. Group those files by their top-level directory under src/ — deck, drivers, hal, init, lib, modules, platform, utils — plus vendor and scripts alongside, size each tile by lines of code, and the tree draws itself.

The treemap

Below is the top-level view of the crazyflie-firmware. Quite beautiful, right? We think so, at least. It contains years of work from the Bitcraze team and all of you out there who have directly contributed or indirectly by finding bugs and asking for new features.

Click into modules/src and it’s 91 files, 27,680 lines — the flight logic. hal/src is leaner: 21 files, 7,036 lines, sitting right above the raw drivers.

Walking the tree

Ordered the way the map itself reads, biggest tile first:

  • vendor — a second, separate pile of third-party code (FreeRTOS itself, libdw1000, test frameworks), distinct from lib.
  • lib — vendored third-party libraries the firmware builds on (the STM32 standard peripheral library, CMSIS, FatFS, Segger RTT).
  • drivers — low-level code talking directly to individual chips: sensors, radio, motors.
  • modules — the flight logic: commander, controller, state estimator, Kalman filter, CRTP handling.
  • deck — drivers for the decks (flow deck, lighthouse, LED ring, and the rest), detected and brought up at runtime.
  • hal — the hardware abstraction layer sitting above the raw drivers (sensor fusion input, power management, storage) that the rest of the firmware calls into.
  • utils — small shared helpers used across the rest of the tree: CRC, PID, filters, assertions.
  • scripts — build tooling (Kconfig, Makefiles, dependency-checking scripts). Sized like everything else, but none of it is actually compiled into the firmware.

platform and init are in there too, but at this scale they barely register as pixels — more on why that’s fitting below.

Some observations

Diff two builds instead of looking at just one, and a couple of things pop out that are easy to state but satisfying to actually go and check.

CF2 vs. CF2.1 Brushless. These are two different physical boards, but walk the diff and the only directories where a single file differs are hal/src and platform/src. Everything else in the tree — all of modules, all of drivers, all of lib — is the same source code, regardless of whether it ends up on a brushed or a brushless frame. The resulting code differs mainly due to the configuration found in e.g. platform_defaults_cf2.h.

sensors_mpy9250_lps25h.c in the bottom left corner is not compiled into the Brushless – it does not have those sensors. The same is true for Crazyflie 2.1. However, the Crazyflie 2.0 has these sensors. The sensor setting is selected at runtime, which is why you can flash your CF2.0 and CF2.1 with the same firmware.

Every controller ships in every build. modules/src has a whole cluster of controllers sitting side by side — PID, Mellinger, INDI, Brescianini, Lee — and all of them get compiled in. Which controller actually flies the drone is a parameter you can flip at runtime.

Closing thoughts

Line them all up and the codebase is huge, but the part of it that’s actually specific to one physical board is tiny. platform and init — the directories that differ per board and handle bringing the system up — barely show up next to vendor and modules. That’s easy to feel intuitively after enough time in the codebase, and much easier to actually see laid out flat like this.

It would take a long time to work your way through every corner of this tree, if you ever fully do. The tool that generates this map can be found here, and it works on one or two (compare) Kbuild targets. It already has compiled examples.

Is this an interesting way to look at a codebase you already partly know? And now that it’s laid out flat in front of you — is there anything in here that looks like it could use some tidying up? We’d like to hear about it.

We are constantly amazed about what awesome things you, our users, do with our products, and how well you do it. Time and time again you push the limits of what the Crazyflie can do, and what is possible within the field of robotics. We do what we can to provide the best possible foundation for all your visions, both in terms of improvements to existing features and also adding new, awesome features. Once in a while, though, you find something that you think can be improved, that we have not thought about, and you know how it can be solved. This is what this blog post is about – how to take an idea that you have and make it available to all of our users…

First, let’s just clarify that we are talking about software today. There is hardware and mechanics as well, but let’s save that for another time. Our software is open source. Being open source is one of the foundational pillars that we at Bitcraze build upon. We believe that this a great way for you to understand our products; everyone has the possibility to understand and troubleshoot the Bitcraze products. It also makes it easier for us to collaborate with all of you and in the end makes for better products for all of you. A positive spiral of enabling awesomeness.

Three is a swarm.

Benefits of contributing – doing things together

Now why would you contribute? You have made an improvement, and maybe you think: Well, I have what I need, there is no direct value for me to make this change available to everyone. Or maybe you think it is an issue that only you have encountered, or that the change is not big enough to merge to the main repository. Or too much work to do it… Here is the good thing: as soon as you let us know what you are working on, we can help you understand the value and the effort of that change request – we know the community, what it is doing and what it needs. We also know how to take an idea and turn it into a product. Once you have said “I have an idea”, we will take the torch that you lit and push the idea forward. You will be accredited for the contribution (e.g. your name will show in our repository), but we will take the responsibility for it: We will test it, support it and maintain it, so that you don’t have to. We will make sure it follows the evolution of the software.

Another benefit of contributing is that when you contribute, another person somewhere else, working on similar things, is also contributing. We truly believe that the more our users contribute, the more our users contribute – the positive spiral mentioned earlier. There is a community out there, and it is filled with talented and knowledgeable people; it is welcoming and it is simply great to be a part of. This seems like a fitting place to say: Thank you for being awesome, community! We are so happy to have you.

Lending each other a helping hand when needed.

Some recent examples

Over the years a number of external contributions have been made, all of which have been appreciated around the globe. Here are a few recent ones:

Solution of buffer overflow in syslink

A change doesn’t have to be big to be valuable. This is a great example of finding a bug, and fixing it. Deep in the firmware things become quite niche, and therefore difficult to understand if you don’t have that specific competence.

https://github.com/bitcraze/crazyflie-firmware/issues/1585

Mellinger controller angle limitation fix

This was contributed by a user who found that there was a limitation to what angle could be commanded when flying the Crazyflie in manual mode using the Mellinger controller.

https://github.com/bitcraze/crazyflie-firmware/pull/1596

Thrust battery compensation documentation

Thrust battery compensation is an external contribution to begin with. Here is a pull request to improve the documentation of it, in order to increase usability. Good for everyone!

https://github.com/bitcraze/crazyflie-firmware/pull/1606

Building Out Of Tree controllers on macOS

We do our best to make all our software work on as many operating systems as possible. This can be difficult though, and yet very appreciated by a lot of people when it works. Here is an example of a change that makes it easier to build Out Of Tree controller on macOS.

https://github.com/bitcraze/crazyflie-firmware/pull/1595

Account for drag in EKF for flapper

The Flapper Nimble has completely different aerodynamic properties than a Crazyflie. This work adds the possibility to account for that in the Extended Kalman Filter (EKF) of the onboard firmware.

https://github.com/bitcraze/crazyflie-firmware/pull/1584

How to become a contributor

For software contributions, the current procedure is to fork the repository for which you want to do a change, and then create a pull request to the original repository from your fork. If you feel that you are not ready to do that, or have questions, then please reach out via email or Github discussions in the corresponding repository. We are happy to discuss ideas before turning them into pull requests. During the process of merging the change into the main branch, we might ask you to provide additional information. This is because we want to make sure we fully understand what problem you are trying to solve and how. Doing so, we can take over the responsibility, and you can let go of it (if you want to). Smaller changes usually means less effort, and vice versa. However, you can contribute with as much time and effort as you see fit.

Ready for takeoff.

Worth noting also is that not all ideas or pull requests will end up in changes in the software. There could be a number of reasons for an idea being discarded, where effort compared to value is the main justification. Whatever happens we promise to have an open dialogue about your idea, and that we are transparent with the decisions that we make, so that future contributions will be even better! Just remember, no idea is too big or too small to pitch.

Pushing forward, together

Making it easier to do contributions, and increase the quality of the contributions, is something that we are dedicated to and prepared to make efforts for. So if you have any thoughts on how we can improve, or think about reasons that keep you from contributing that we can solve, we would very much like to hear it!

We are looking forward to collaborating on all amazing, crazy, improving and mind-blowing ideas out there!

Hello!

My name is Stefan, and on Wednesday the 7th of January I had the honor of joining the Bitcraze team as a software developer. I have thirteen years of experience working with robotics software in product development industry; as a developer, product owner and group manager, mainly within the areas controls, planning and sensor fusion. My vision is to bring as much of my experience into Bitcraze as possible, and have fun while doing it!

My heart has always belonged in the software development, connecting real life with control software, understanding the full chain from decisions in software to product behavior. This is especially present at Bitcraze, with small yet capable products. Understanding the entire system also lets you optimize the system as a whole, which is a complex but stimulating task. I am really looking forward to dig into this!

Going forward, I’m hoping for great collaboration, of course within the team but also with users of our products. Reach out if you have ideas, improvement suggestions or interesting projects! We are here to make your ideas fly!