Category: Random stuff

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.

Future

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!

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.

Project

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.

sim_cf2:

https://github.com/CrazyflieTHI/sim_cf2

Multi-Agent Client:

https://github.com/CrazyflieTHI/crazyflie-client-multi-agent-thi

Show-and-tell post of CrazySim:

https://github.com/orgs/bitcraze/discussions/995

For the original sim_cf Flight Simulator for the Crazyflie visit:

https://github.com/wuwushrek/sim_cf

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.

//Björn

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:

forward(distance)

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:

take_off(height)

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 discussions.bitcraze.io 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:

Products:

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!

Community

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!

Bitcraze

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!

We’re getting close to the end of the year and as usual we look back at what has been going on at Bitcraze.

Community

This year we had a booth at ICRA in London. We were also involved in starting the “Aerial Robotics Community Working Group” for ROS and the ROScon keynote in New Orleans together with Dronecode foundation.

We have been hosting developer meetings this year in an attempt to spread information, get feedback and have live discussions:

They are all available on YouTube if you missed them.

Guest blog posts

We have had lots of interesting blog posts from our users this year!

New hardware

A number of new exciting products are available in our store

We have also been working on some new products that are not ready for the store yet, these include the Crazyflie 2.1 brushless, an improved lighthouse deck and some other things we will write about in coming blog posts – stay tuned for exciting news!

Software

There have been 3 releases during 2023

The big picture when it comes to the software is that there has been some work done on estimators and controllers, including “out-of-tree support” to make it easy to add to your own. We have worked on support for brushless motors, including safety features like the supervisor and arming functionality. The client has been upgraded to use PyQt6 instead of PyQt5.

There has been a bit of a focus on stability, partly by us in the infinite flight project, but also at TU Delft in their 24/7 swarm.

Bitcraze

Exciting things have been happening in the office as well! Hanna did an internship in the beginning of the year and Sofia has joined us to help with packing while Kristoffer unfortunately is leaving for new adventures. We have also expanded our flight lab, and right now it feels gigantic, it will take some time to get used to the new large size!

As always when writing the yearly looking back blog post, we are amazed at all the things that have been going on during the year. Thanks for joining us on our journey!

I joined Bitcraze back in 2015 and I have had a fantastic time during my 8 years in the company, but I have decided to move on to new adventures and I will leave Bitcraze after Christmas.

Clinker boat
Clinker boat. From wikipedia, this file is licensed under the Creative Commons Attribution-Share Alike 4.0 International license.

This summer I visited Karlskrona, an old naval city in Sweden, and happened to pass by a school that teaches traditional wooden boat building. I have done various types of wood work in my spare time before and the idea of learning more about boat building full time got stuck in my head and refused to go away. In January I will start to learn about how to build boats in the Nordic clinker tradition that dates back to before the viking age, this style of boat building is also on the UNESCO intangible heritage list!

Building boats might seem very different from developing small quads, but there is a similarity in learning, evolving skills and explore new areas, even though in a different field. Exploration and learning is very much what I like and have been doing at Bitcraze, in so many fields ranging from the obvious ones related to robotics such as control theory, positioning systems, embedded programming and so on, but also in the many areas related to running a company. After all we are only 6 persons and I have had the opportunity to be involved in everything from sales, marketing, IT, organization, the office, flight lab, production and much more. One field that I have a strong interest in is how to organize a company and I’m especially happy that I have had the possibility to try all sorts of ideas related to self organization at Bitcraze.

I’d like to thank everyone at Bitcraze for an awesome time, we’re almost always moving close to the speed of light, in a relaxed way! I would also like to thank all the interesting people I have met through the years, it is very inspiring to see what you are doing with the Crazyflie and other products, I hope you all continue to do funky stuff!

Happy hacking!

Before we start settling down and preparing for Christmas, it’s time for another release! The last one was before the summer in July, and we’ve had quite a few changes on the development master branch that we’d like to share. You can now download the latest Cfclient through pip and install the newest firmware on the Crazyflie to 2023.11 via the CFclient.

Latest changes in CFclient and Cflib

The most significant change in the CFclient is that we have finally transitioned from QT5 to QT6 for the GUI graphics. Additionally, we have addressed some issues with the toolboxes. Finally, we have added an information box to indicate the state of the supervisor, such as whether the Crazyflie is considered tumbled, flying, or if a restart is required because it is locked.

Cfclient when the crazyflie is tumbled with supervisor info

For the backend, namely the Crazyflie Python library, some important changes have been implemented. Along with fixes to the parameter and logging framework, full-state setpoints have been introduced. This feature has existed in firmware for a while due to the Crazyswarm1 project (now Crazyswarm2), but it wasn’t implemented in the cflib until now. Additionally, it’s now necessary to use `notify_setpoint_stop` in cases of switching between high-level setpoints and regular position setpoints. There is also a generic motion capture example now based on the libmotioncapture library.

Note that even though the CFclient has been converted to QT6, there are several examples in the Cflib folder that have not been updated yet. This will be fixed soon, and a ticket has been created for it. Additionally, in the Bitcraze-VM, there have been some reported issues with QT6 (see this ticket).

Latest changes in the firmware

The firmware has undergone some important changes too. On the STM side of things, the hybrid TDOA mode has been merged (check out this recent blog post). This feature is still considered experimental, so please refer to the documentation for the right settings. Additionally, support for the supervisor information box in the CFclient has been added. To utilize it, both the firmware and CFclient need to be updated. There is also a new example demonstrating communication between gap8 and cpx. Last but not least, it is now possible to create Python bindings for portions of the Kalman filter, mainly for the Loco positioning system. On the other hand, the NRF firmware has no added functionalities except for some build changes and fixes.

Crazyradio2 + LPS tools

We’ve also made some improvements in other firmware or tools. Starting with the Crazyradio2, which includes fixes for broadcasting (important for you Crazyswarm2 folks!). We also aimed to make a new release of LPS tools since we heard that people were experiencing issues with USB devices. Unfortunately, there are some problems with the GitHub release actions, so that will likely be delayed. For anyone facing USB issues, you can install the LPS tools from source with Python following the ReadMe’s instructions.

Release details and Remaining issues

So here are the details of all that is released:

Some things still require attention that are a bit affected by this release, but we haven’t had the time to fix it yet:

  • Fix issues with LPS tools and release (see this ticket)
  • CFclient seems to be broken on the bitcraze-VM (see this ticket)
  • CFlib examples with QT-based GUI are still on QT5 (see this ticket)
  • The newest CFclient seems to need additional packages in some cases ( see this and this ticket)

Please let us know at https://discussions.bitcraze.io if you are having more problems.

Developer meeting this Wednesday

As we already announced last week in the Monday blog post, we will be having a developer meeting this Wednesday (6th Dec, 3 pm CET) regarding the Flow deck (refer to this discussion thread for joining information). Since we usually don’t fill up the entire hour, the last part of the developer meeting is available for some generic support questions face-to-face (online), including questions about the release!

The Flow deck has been around for some time already, officially released in 2017 (see this blog post), and the Flow deck v2 was released in 2018 with an improved range sensor. Compared to MoCap positioning and the Loco Positioning System (based on Ultrawideband) that were already possible before, optical flow-based positioning for the Crazyflie opened up many more possibilities. Flight was no longer confined to lab environments with set-up external systems; people could bring the Crazyflie home and do their hacking there. Moreover, doing research for exploration techniques that cannot rely on external positioning systems was possible with it as well. For example, back in my day as a PhD student, I relied heavily on the Flow deck for multi-Crazyflie autonomous exploration. This would have been very difficult without it.

However, despite the numerous benefits that the Flow deck provides, there are also several limitations. These limitations may not be immediately familiar to many before purchasing a Crazyflie with a Flow deck. A while ago, we wrote a blog post about positioning systems in general and even delved into the Loco Positioning System in detail. In this blog post, we will explore the theory of how the Flow deck enables the Crazyflie to fly, share general tips and tricks for ensuring stable flight, and highlight what to avoid. Moreover, we aim to make the Flow deck the focus of next week’s Developer meeting, with the goal of improving or clarifying its performance further.

Theory of the Flow deck

I won’t delve into too much detail but will provide a generic indication of how the Flow deck works. As previously explained in the positioning system blog post, the Flow deck is a relative positioning system with onboard estimation. “Relative” means that wherever you start is the (0, 0, 0) position. The extended Kalman filter processes flow and height information to determine velocity, which is then integrated to estimate the position—essentially dead reckoning. The onboard Kalman filter manages this process, enabling the Crazyflie to use the information for stable hovering.

Image from Positioning System Overview blogpost

The optical flow sensor (PMW3901) calculates pixel flow per frame (this old blog post explains it well), and the IR range sensor (VL53L1x) measures height up to 4 meters (under ideal conditions). The Kalman filter incorporates a measurement model that describes the relationship between these two values and the velocity of the Crazyflie. More detailed information can be found in the state estimation documentation. This capability allows the Crazyflie to hover, as explained in the getting started tutorial.

Image from state estimation repo documentation

Tips & Tricks and Limitations

If you want to fly with the Crazyflie and the Flow deck, there are a couple of things to take in mind:

  • Take off from a floor with texture. Natural texture like wood flooring is probably the best.
  • The floor shouldn’t be too shiny, and be aware of infrared scattering for the height sensor
  • The room should be well-lit, as the sensor needs to see the texture.

There are certain situations that the Flow deck has some issues with:

  • Low or no texture. Flying above something that is only one plain color
  • Black areas. Similar reason to flying above no texture, but it’s more difficult than usual. Especially with startup, the position estimate diverges
  • Low light conditions
  • Flying over its own shadow

We made a video that shows these types of behaviors, starting of course with the most ideal flying conditions:

Moreover, it is also important to note that you shouldn’t fly too high or yaw too often. The latter will make the Crazyflie drift, as the optical flow cannot be distinguished as being caused by the yaw movement.

Developer meeting about Flow deck

We believe that many of the issues people experience are primarily due to the invisibility of the positioning quality. In many of our examples, the Crazyflie will not take off if the position is stable. However, we don’t have a corresponding functionality in our CFclient, as it is more up to the user to recognize when the positioning is diverging. There is a lot of room for improvement in this regard.

This is the reason why the next developer meeting will specifically focus on the Flow deck, which will be on Wednesday the 6th of December, 3 pm central European time. During the meeting, we will explain more about the Flow deck, discuss the issues we are facing, and explore ways to enhance the visibility of positioning quality. Check out this discussion thread for information on how to join.