Category: Documentation

The Bitcraze organization page on github contains some 60+ repositories and if you are looking for a specific piece of code it might be hard to know where to find it. In this blog post we will try to describe how the repositories are organized and hopefully make it easier to understand where to start your search.

The Bitcraze repositories contain code and information related to a wide range of applications and products, some might be of interest to many users, while others have a smaller audience. Examples are software for the Crazyflie and decks, but also things like simulation, tests, hardware and our web site. As we try to be as open as possible most of the content we produce will end up in a repository, which obviously increases the number of available repos over time. For most users there is usually only a handful of repositories that are of interest though so let’s create some order.

The main repositories

There are three repositories that are the hot spots of most functionality, these are usually the first place to look and the only repositories most users will ever use. You can find quick links to these repos in the “Pinned” section on the Bitcraze github start page.

The repositories are:

  • crazyflie-firmware – the source code for the STM processor firmware on the Crazyflie. This is where most of the important Crazyflie functionality is implemented, such as controllers, estimators, motor control and communication with decks. If you want to change a behavior in the Crazyflie itself, look here.
  • crazyflie-lib-python – the python library used to communicate with the Crazyflie. This is used to control a Crazyflie remotely. Use it if you want to use a script to control a Crazyflie, also contains lots of examples of how to do common tasks.
  • crazyflie-clients-python – a the python client that is used to connect to the Crazyflie. The client is simply a GUI that uses the python lib to communicate with the Crazyflie. Everything that is done in the Client can also be done by a script using the python library.

Another source of quick links to common and important repositories can be found on our web, on the Repository overview page. This page also contains short descriptions of the repositories.

Related repositories

Many of our products are implemented as multiple sub-systems, perhaps using different languages or technologies and running in separate hardware, in most cases we separate these sub-systems into their own repositories. The rule of thumb is that these repositories are named in a similar way to indicate that they are related, for instance lighthouse-bootloader and lighthouse-fpga that contain code for the lighthouse-deck. However note that in most cases there will also be related functionality implemented in the main repos as well, in the Lighthouse deck case for instance, most of the actual positioning functionality is in the crazyflie-firmware repo while Lighthouse system management is implemented in the lib and client.

Bootloaders

When powering up a CPU there must be a small piece of code available that sets up the basic configuration of the device to enable it to communicate with other parts of the system, like memories and such. This code is usually called a bootloader. Bootloaders are rarely changed and in most cases written to the device as a part of the factory production process. They have their own repositories and you can find a bunch of them, named XXXXXX-bootloader. Bootloaders are not that interesting and can be ignored by most users.

History

Some repositories might have names that do not make sense in the current context, this is most likely due to historical reasons. We might have given a repository a name that seemed to be descriptive at that time, but as time goes by it might not be as good any more. An example is the range of “LPS-XXXXX” repositories that contains code for the Loco Positioning System. Originally LPS meant “Local Positioning System” as this was the only positioning system we had, but when we also created the Lighthouse system we changed the meaning of LPS to “Loco Positioning System”. A better naming of the repositories would perhaps be “Loco-XXXX”?

A similar transition also exists for the Crazyflie that has evolved from Crazyflie 1 to Crazyflie 2.0 and 2.1. Some repositories (named “crazyflie-XXX”) were created when Crazyflie 1 was released and have evolved to be compatible with Crazyflie 2.X, while some other repositories (named “crazyflie2-XXX”) were created when Crazyflie 2.0 was released. Even though crazyflie-firmware is not compatible with Crazyflie 1 anymore, it still has the old name.

Retired code

Some repositories are obsolete, maybe they contain experimental code that is no longer of interest or perhaps the functionality has been implemented elsewhere. We try to archive these repos and if you are looking for current functionality you can safely ignore any repository that is marked with the “Public archive” flag in github.

Still unclear

There is a short description in each repository that is intended to describe the contents. It is possible (likely) that the description was written a long time ago, with a different context and that it might not be as helpful as intended. If this is the case, just ask us. Drop a question in our discussions forum or send us an email, we try to help as much as we can!

A big part of our work is to provide examples, getting-started guides and other documentation to get users started quickly. Documentation should be up-to-date, be understandable and detailed but, at the same time, not overwhelming. Examples should cover common applications and, most importantly, teach how to create your own projects. This is a never-ending task as our eco-system constantly evolves.

In recent weeks we have updated many parts of the AI-deck documentation and examples – this process is not finished (and will never be), but we thought giving you an overview about what we think most struggle with as well as what we updated would be interesting – especially as we see many AI-deck related questions in the discussions.
We saw that many struggle with understanding the whole communication chain and the importance to update all microcontrollers in it – so we will first give an overview on how everything is connected and then dive into where to find documentation, which examples already exist and how to get started with an own project on GAP8. Note that this post is centered around the GAP8; we do not go into detail about the NINA WiFi.

Here we go:

How does the AI-deck fit into the Crazyflie Eco-System? How does it communicate?

As with all other decks, the AI-deck is connected over expansion headers. It gets power directly from the battery (VCOM), and both microcontrollers (GAP8 and the NINA WiFi module) are connected to the STM32 via UART.

AI-deck expansion header connections.

To send messages between all those microcontrollers, the CPX protocol was introduced. As the NINA and GAP8 are also connected (via SPI), we have redundant information paths – so per definition, we always route over the NINA.

Now how can we send code to the GAP8 for it to run?

GAP8 always executes code from L2 (second-level RAM), as it has no internal flash. However, it can load code into L2 over a HyperBus interface from external flash memory on startup (which it does if a fuse is blown, however this is already done on your AI-deck and out of scope here). As GAP8 has only volatile memory, it must always load code from exactly the same flash address. To make it possible to update applications easily, we implemented a bootloader, a minimal program which is the first thing to run on startup. The bootloader can either update the application code in flash or copy it into L2, and, if the code is valid, run it. Why is this easier? First, you don’t need to connect a programmer, as the bootloader can read data over other peripherals (in our case SPI from the NINA module). Second, it is safer – if the update fails (and you, for some reason, end up with random code where your application should be) the firmware code will not be valid (the hash computation will fail) and GAP8 will not jump to the corrupt application code but instead safely stay in the bootloader.

As the chain for the over-the-air update with the bootloader is rather complex, we illustrate the ways to flash GAP8 in the image below.

  • the blue path illustrates how you can program over JTAG – you can either write code directly into L2 to run it (this is volatile memory, the code will disappear if you power cycle) or you can write it into flash (over GAP8), such that it is loaded on startup (if you overwrite the bootloader, not recommended) or with the bootloader.
  • the red path is using the cfloader. Meaning it sends your code over the Crazyradio to the nRF, then further to the STM32, from there to the ESP32 (the NINA WiFi module) and from there to the GAP8. This path uses CPX messages; you can read more about it in the CPX documentation.
System Architecture of a Crazyflie with an AI-deck connected.

Where is the documentation?

We have tutorials as well as repository documentation. Tutorials guide you through all the steps needed to run a specific example, while the repository documentation aims to document the general infrastructure and examples in more detail (but without all not directly related steps such as flashing a bootloader, updating other firmware, etc.).

So when you use your AI-deck for the first time, you should start with the getting started guide.
Then you are most likely interested in a more detailed explanation about the used infrastructure, such as the GAP8 including the SDK, how to flash, which examples exist and how to run them, etc. So now you should check out the repository documentation.

As we are mostly speaking about GAP8 here, we should also mention that there is of course also documentation for it outside of Bitcraze. GAP8 is produced by Greenwaves, who provides references and has a public SDK on github – meaning one can actually look up the code for all drivers, look at open issues or even contribute with pull-requests.

Which examples exist? What are they there for? What did we update?

This example is there to get you started with your own applications – it provides a minimal implementation of how to send something to the cfclient console from the GAP8 and is explained in detail in the next section of this post.

The camera test is, as it says, to test the camera – however, it sends the image over JTAG, so if you don’t have a debugger and/or don’t want to overwrite the bootloader this is not an example for you.

The most classic example – this example is used in the getting started guide and streams video over WiFi.

This example uses filters to find faces in images – be a bit careful, though, as it is very sensitive to noisy backgrounds and, for example, blonde hair. However, along with nice image processing examples, it now also implements the streaming of the images in configurable resolution, a fun feature we recently added!

The classification demo is our AI demo which recognizes parcels. Here we recently fixed the CPX initialization, so it can again send results to the console in the cfclient!

The send character over UART example was neither updated nor tested with the newest docker (yet).

How do I write my own code on gap8?


Now we’ll walk you through a minimal example of how to send Hello World from GAP9 to the cfclient console.

C Code

We start with the main file (which we called hello_world_gap8.c and is found here) by including some dependencies:

#include "pmsis.h" for the drivers

#include "bsp/bsp.h" for some configuration parameters (pad configurations for connecting to memory, camera, etc.)

#include "cpx.h" for using the CPX functions to send our hello world to the console

Then we have to write our main function:

int main(void)
{
  return pmsis_kickoff((void *)start_example);
}Code language: JavaScript (javascript)

We call pmsis_kickoff() to start the scheduler and an event kernel, giving it a pointer to the function we want to execute.
This function is what we write next (insert it above the main function, such that it is found in the code of the main).

void start_example(void)
{
  pi_bsp_init();
  cpxInit();

  while (1)
  {
      cpxPrintToConsole(LOG_TO_CRTP, "Hello World\n");
      pi_time_wait_us(1000*1000);
  }

}Code language: JavaScript (javascript)

First we need to initialize the pads according to our configuration (the configuration is automatically chosen with sourcing the ai_deck.sh, which is automatically done in the docker) with pi_bsp_init().
Then we need to initialize CPX (which initializes for example the SPI connection to the NINA WiFi), to be able to send CPX packets. You find more information in the CPX documentation.
Now we are ready for our while loop, in which we want to send “Hello World” to the console (called LOG_TO_CRTP). To not keep the busses overly busy we only want to send it every second, so we wait before we repeat.

Makefile

The Makefile is hierarchical – meaning we have hidden files that do most of the work and need to include $(RULES_DIR)/pmsis_rules.mk in the last line of the Makefile.

We start with defining where the io should go – possibly are host or uart (this is actually not used in this example, but if you’d add a printf, this would define where it goes).
Then we define the operating system we want to use – we can use pulpos or freertos. We chose this as freertos is way more advanced (we are paying for this with some overhead, but in most cases, it will be worth it).

io=uart
PMSIS_OS = freertos

In the next step we need to set the name of our application (this defines the file names of the build output), include the sources (meaning our main c file as well as the two c files CPX needs) and include the header files directory (header files in the same directory as the Makefile should automatically found, but our CPX header files are in a library directory). Make sure all the relative paths are correct for your folder structure.

APP = hello_world_gap8
APP_SRCS += hello_world_gap8.c ../../../lib/cpx/src/com.c ../../../lib/cpx/src/cpx.c
APP_INC=../../../lib/cpx/inc

As a last step, we want to set some compiler flags. Firstly, we want to compile optimized, so we add -O3. Then we add -g to embed debug information.
As we use timers for CPX we also need to add two additional defines to ensure all functions we need are included: the configUSE_TIMERS=1 and the INCLUDE_xTimerPendFunctionCall=1 defines.

APP_CFLAGS += -O3 -g
APP_CFLAGS += -DconfigUSE_TIMERS=1 -DINCLUDE_xTimerPendFunctionCall=1

Compile and Flash


For this section we assume you are in the ai-deck-examples directory.

Now we want to compile using docker:

docker run --rm -v ${PWD}:/module --privileged bitcraze/aideck tools/build/make-example SRC_DIR clean allCode language: JavaScript (javascript)

Where SRC_DIR is the location of your code, here it is examples/other/hello_world_gap8.

Note: You don’t always need to “clean” if you don’t modify the Makefile. It should be fine to save some time by skipping this.

And finally we want to flash using the OTA updater:

cfloader flash [binary] deck-bcAI:gap8-fw -w CRAZYFLIE_URICode language: CSS (css)

Where in this example, [binary] has to be replaced with examples/other/hello_world_gap8/BUILD/GAP8_V2/GCC_RISCV_FREERTOS/target.board.devices.flash.img, and the CRAZYFLIE_URI is something like radio://0/80/2M/E7E7E7E7E7.

Now you can connect to your drone with the cfclient and should see a CPX: GAP8: Hello World print every second.

Note: The LED will not blink as in most other examples, as we did not implement a task which does this.

We hope this blog post helps you get started with your own awesome applications faster!

We have worked hard last week to get a new fresh release out before the summer months are on our doorstep. Not only that we would like to make sure that important bugs are fixed before some of us go on our holiday, but also to be able to display our new AI deck features! Here is an overview of what has been changed

AI deck over air flashing

As you can probably see in the release notes of both the python libraries and the firmware, most of our changes are focused on making it possible to develop for the AI deck without using a programmer all the time. If the STM and NRF firmware of the Crazyflie is fully updated, and the ESP firmware on the AI deck, it should now be possible to flash an AI deck example binary with a Crazyradio! For older versions of the AI deck 1.X (Rev A to C) it is unfortunately still necessary to use the JTAG programmer one last time to flash a bootloader on the GAP8, but after that it should not be needed anymore.

Please check out the new update AI deck tutorial for setting up the AI deck for this new functionality.

Crazyflie Packet eXchange (CPX)

In the light of the work we have done for the AI deck, we also have started to implement a new, inter MCU protocol called the Crazyflie Packet Exchange. Since with the AI deck, we are adding 2 additional microprocessors to the Crazyflie architecture, it was crucial to handle the communication between all platforms and communication channels properly. Currently the functionality is mostly enabled to tailor Wifi streaming and console printouts for the AI deck, but it is meant to be a generic protocol which in the future, should be able to handle more combinations like for instance, command messages through wifi?

You can read about CPX in the crazyflie-firmware repository doc and we will be writing a more detailed blogpost about this later.

Controller Python bindings

For the last part of the Grand tour trip, we had a hackathon with the IMRC lab of TU Berlin and our close collaborator Wolfgang Hönig, in which we managed to convert the PID controller, Mellinger controller and the motor mixing into python bindings, which can be used in the experimental simulator of the Crazyflie.

There is no Pypi release of these, you will need to pull the latest crazyflie-firmware repo and build the bindings with ‘make bindings_python’

Additional fixes

We have some additional fixes to both the python libraries and firmware. For the STM we have updated the STD peripheral library and solved several build issues. For the cfclient, we fixed a lot of issues that were caused by either the latest version of python, as it was more stricter with type definitions, and some issues QT. Moreover, the LED ring headlight functionality has been restored, and the cfbridge.py script, used for the PX4 crazyflie 2.1 tutorial, is re-added, since it suddenly disappeared a few releases ago.

Update and Feedback

Make sure to update your cfclient with ‘pip install cfclient –upgrade’ and to reflash the new stable firmware. For AI deck users, try out our our new tutorial to try out both CPX, the over air flashing and the wifi example. The new AI deck functionalities has been subjected to some limited testing so if there is anything wrong or unclear, please let us know in the forum! The feedback will help the AI deck to become a more stable product for development, so we would be very grateful if you would be able to help out with that.

This week we merged a pretty big change in the Crazyflie firmware code repository. The change altered the way we configure and build what goes in to the drone. We now make use of the Kbuild build system.

The Kbuild build system is the build system used, foremost, by the Linux kernel, but is also used in other projects like Busybox, U-Boot and sort of Zephyr. It is mostly known from its terminal based configuration tool, menuconfig.

A view of the Expansion deck configuration in the menuconfig

Kbuild leverages Kconfig files to build up an hierarchy of configuration options to use when building the software. It allows you to setup dependencies between your configuration, allowing us to do things like only enable the Kalman filter when there is a deck driver that needs it enabled.

This new way of building the firmware replaces the old way of using config.mk to set the build defines you need. Our hope is that Kbuild will make it easier to customize the Crazyflie firmware to fit the need of your department or project.

What does this mean for you?

If you are not changing the firmware as part of your Crazyflie development this will not change anything for you. The Python library will continue to work just like before and Bitcraze will release official firmwares, just like before.

If you are in the habit of fetching and building the latest and greatest version of the Bitcraze firmware there will be some minor changes. This can be seen in our updated build documentation on the web. The biggest deal is that the firmware code needs a configuration file before building is possible. To get the default one you can go:

$ make defconfig
make[1]: Entering directory '/home/jonasdn/sandbox/kbuild-firmware/build'
  GEN     ./Makefile
scripts/kconfig/conf  --defconfig Kconfig
#
# configuration written to .config
#
make[1]: Leaving directory '/home/jonasdn/sandbox/kbuild-firmware/build'Code language: PHP (php)

The way to compile app-layer applications has changed a bit and you will need to adapt (sorry!) the new way of building your app-layer application can be seen in the updated documentation.

If you make heavy use of config.mk and frequently change code in the firmware there are many new possibilities for you. Check the documentation and keep reading this blog.

Making the firmware more modular

With the new build systems help we hope to make it easier to enable and disable features and sub systems in the quad copter. In the default firmware all drivers for all expansion decks are included, as well as all estimators. If you are pushing a feature or experiment that need more RAM or flash, that might be inconvenient for you.

As an experiment we can try building the current maximum-, minimum- and default configuration of the Crazyflie. We say current because the work to make the firmware more modular is ongoing.

The default configuration, the official firmware, we can obtain by invoking the special make command defconfig.

$ make defconfig

And building the maximum is done using allyesconfig this gives us configuration file with all options enabled.

$ make allyesconfig

And conversely the minimum configuration can be set using allnoconfig, which will disable all features that can be disabled.

$ make allnoconfig

The resulting firmware sizes can seen in the table below:

BuildFlashRAMCCM
defconfig232 Kb (23%)76 Kb (59%)57 Kb (89%)
allyesconfig428 Kb (42%)80 Kb (62%)57 Kb (90%)
allnoconfig139 Kb (14%)62 Kb (48%)45 Kb (71%)

This shows some of the potential of the modularization of the firmware. We hope it will make it easier for you to get your stuff to fit, without having to hack around in the code too much.

Making it easier for us to merge your contributions

The new system makes it easier include code in the firmware repository without necessary needing to include it in the official firmware. This will make it easier for us to merge controllers, estimators, algorithms, deck drivers and other stuff from you.

We can include them in our Kconfig files, allowing people to select them and build firmware using them and we can make sure they get (at least compile) tested as part of our continuous integration. So you can sleep soundly knowing your code will not suddenly break with new versions of the firmware.

Creating and distributing your own config

If you want to create your own configuration, and spread it around you can do so.

You can use:

$ make menuconfig

To create a base .config file with your special configuration. If you copy the file, or have us merge it, to the configs/ directory.

$ cp build/.config configs/waggle-drone_defconfig

Then it will be possible for other people to build your configuration by going:

$ make waggle-drone_defconfig
make[1]: Entering directory '/home/jonasdn/sandbox/kbuild-firmware/build'
  GEN     ./Makefile
#
# configuration written to .config
#
make[1]: Leaving directory '/home/jonasdn/sandbox/kbuild-firmware/build'Code language: PHP (php)

But it would also be possible to just add the configuration that differ with the default configuration to your config file:

$ echo CONFIG_PLATFORM_BOLT=y > configs/waggle-drone_defconfig

$ make waggle-drone_defconfig

$ grep PLATFORM build/.config
# CONFIG_PLATFORM_CF2 is not set
CONFIG_PLATFORM_BOLT=y
# CONFIG_PLATFORM_TAG is not set
Code language: PHP (php)

Help out and test it please!

This is quite a big change and we are still shaking out bugs. Please give it a test run and report any issues you find!

If you want to help out, there is a GitHub project that contain the issues we know about, feel free to grab one and contribute your solution!

Happy hacking!

You might, or might not have heard about a tool called Wireshark, it is quite popular in the software development world.

The wireshark official logo


Wireshark is a free and open-source packet analyzer. It is used for network troubleshooting, analysis, communications protocol development and education. It makes analyzing what is going on with packet based protocols easier.

Most often Wireshark is used for network based protocols like TCP and UDP, to try to figure out what is happening with your networking code. But! Wireshark also allows you to write your own packet dissector plugin, this means that you can register some code to make Wireshark handle your custom packet based protocol.

For the latest release of the Crazyflie Python Library we added support for generating a log of the Crazy Real Time Protocol (CRTP) packets the library sends and receives. This is the (packet based) protocol that we use to communicate with the Crazyflie via radio and USB.

We generate this log in the special PCAP format that Wireshark expects. And we also created an initial version of a dissector plugin, written in the programming language LUA.

When we put this two things together it turns into a pretty cool way of debugging what goes on between your computer and the Crazyflie!

What does it look like?

Wireshark gives you a graphical interface where you can view all the packets in a PCAP file. You will see the timestamps of when they arrived. Selecting a packet will give you the information that the dissector has managed to deduce as well as how the packet looked on the wire.

On top of that you get powerful filtering tools. In the below image we have set a filter to view only packets that are received or sent on the CRTP port 8, which is the port for the High level commander. This means that from a log file that contain 44393 packets we now only display 9. Which makes following what goes on with high level commands a bit easier.

Wireshark view of filtering out packets on CRTP port 8

The dissector knows about the different types of CRTP ports and channels and knows how to dissect an high level set-point, as seen by the image above.

What can this be used for?

This functionality is, we think, most useful for when developing new functionality in the Crazyflie firmware, or in the library. You can easily inspect what the library receives or sends and make sure it matches what your code indented.

But it can also be useful when doing client type work! We recently located the source of a bug in the Crazyflie client with the use of this Wireshark plugin.

It was when updating the Parameter tab of the client to handle persistent parameters, and to use a sidebar for extra documentation and value control. As I was testing the code I noticed that every time I changed the value of ring.effect to a valid integer and then disconnected and reconnected, the value was set to 0. Regardless of the value I had set.

I recorded a session using the PCAP log functionality:

$ CRTP_PCAP_LOG=ring.pcap cfclient

And the I fired up wireshark:

$ wireshark ring.pcap

It was now possible for me to track what the library and firmware thought was going on with the ring.effect parameter, by tracking the crtp.parameter_varid field using Wireshark. Filtering down from from 3282 packets to 12 packets.

I had earlier figured out that the varid of the ring.effect variable was 183. This is a quasi-internal representation of a parameter that we do not expose in a good way. In the future we will try to make this Wireshark tracking work with the parameter name as well.

Looking at the write parameter packet from USB #3 to the Crazyflie I could see where I set the value of the parameter to 5, so far so good.

Wireshark view of checking my setting of the ring.effect parameter to 5

The surprising part however was seeing a write further down setting the parameter to 0! This mean that something in the client was actually setting this to zero!

Wireshark view of something setting the ring.effect parameter to 0

After seeing this, locating the actual issue was trivial. I noticed that the Flight Control tab was setting the ring.effect parameter to the current index of the combo box in the UI. And when no LED-ring deck was attached, this amounted to always setting the value to zero.

But having confirmation that this was something happening on the client side, and not some kind of bug with the new persistent parameters was very helpful!

How do you use this?

We have added documentation to the repository documentation for the library on how to generate the PCAP log and how install the Wireshark plugin.

But the quick-start guide is this:

  • Copy the tools/crtp-dissector.lua script to the default Wireshark plugin folder
    • Windows: %APPDATA%\Wireshark\plugin or WIRESHARK\plugins
    • Linux: ~/.local/lib/wireshark/plugins
  • Restart Wireshark or hit CTRL+SHIFT+L
  • Set the environmental variable CRTP_PCAP_LOG to the filename of the PCAP log you want to generate
  • Run Wireshark with the filename as an argument

And please report any issues you find!

Happy hacking!

We are thrilled to announce the new 2022.1 release of the Crazyflie firmwares, library and client! There have been a lot of bug fixes, polishing and new features and we are glad we finally get to share it with all of you.

Noteworthy features and fixes

The features and fixes listed here is only a subset of all the bug fixes and other additions we have done in the last six months. For a more complete view, please check the release notes on GitHub.


Crazyflie STM firmware — Main firmware

Release notes on GitHub


Crazyflie NRF firmware — Radio and power management

Release notes on GitHub

  • We now report the version of the NRF firmware on the Crazyflie console

Crazyflie Python library — The official Python API

Release notes on GitHub


Crazyflie Client — The Crazyflie PC client

Release notes on GitHub

  • Rework of the Parameters tab
    • To better show parameter documentation and to include persistent functionality
Image of the Crayzflie PC client with new parameter tab
New Parameters tab with filtering search and sidebar with more information about values

Documentation

Along with all the new features, bug fixes and general polish of our software we have also spent time making sure our documentation is up-to-date and relevant! You can check it out on our website. Do not forget to check out the individual repositories documentation. And the tutorial page has gotten some love this cycle, check it out!

Please go forth and install this new release and please file issues with any problem you find!

Where to get it?

The firmware images for the Crazyflie STM firmware and the Crazyflie NRF firmware should already be available through the cfclient. And if you want to download them yourself you can find them at https://github.com/bitcraze/crazyflie-firmware/releases.

The Crazyflie Client and the Crazyflie Python library are available through Pypi (The Python Package Index), to install them you can use the following commands:

$ python3 -m pip install --upgrade cfclient # to install or upgrade the Crazyflie client

$ python3 -m pip install --upgrade cflib # to install or upgrade the Crazyflie Python libraryCode language: PHP (php)

Happy hacking!

We have recently worked on functionality in our web site to generate documentation from source in a few ways that we hope will improve the quality as well as simplify maintenance. We have already written a bit about the log and param documentation in the crazyflie-firmware repository, but we now also added and API reference in the python library as well as generating a list of publications related to the Crazyflie.

The Log and Param documentation

Earlier this year we worked on generating documentation for Log and Params from doxygen comments. We will not dig deeper into this here, but you can read more about it in this blog post. The latest version is available on our web in the repository documentation for the crazyflie-firmware: logs and params

An API reference for our Python library

The Crazyflie Python library is what you might use to create programs that interact with the Crazyflie, for instance to manage small swarms. For a while we have had introductory documentation, and step-by-step guides to show you how to perform, what we think are, common tasks.

However along the way we have also added comments and examples to our code. And this, combined with the way we have structured the library actually enables us to automagically generate reference API documentation. That is, something that shows you everything that is possible to do with the library, all modules and classes, all methods and constants that the library offers.

After some recent work this is now happening and the documentation will now get generated each time we deploy our website!

The API reference documentation can be found in the repository documentation for the library. Please check it out! And be picky, complain where the documentation is lacking! Or if the formatting seems weird! We are trying to get the hang of this and we need you to push us!

Managing publications

Some years ago we started to add publication that are related to the Crazyflie to our Research page, we hope that it might be inspiring to read about all the awesome things that the Crazyflie is used for.

Until now it has been a simple list in markdown but with an increasing number of publications it has become harder and harder to maintain it, finally we have put the work into generating the list from a BibTeX (.bib) file instead. One advantage of the new solution is that BibTeX is a well known format to the research community with lots of tools around to manage BibTeX files while another improvement is that the list will be formatted in a consistent manner (which was not always the case earlier).

If you want to add a publication to the page, simply update the .bib file with your data and create a pull request with the changes. We will merge when appropriate and the publication will become visible on the web after the next deploy, usually within a few days.

Behind the scenes

The code for generating documentation from source tends to spread out over multiple repositories and creates some complexity with a multitude of tools for different languages. It should not be necessary to understand the details and we hope the system will be easy to use for contributors to the code base.

Any questions or comments are welcome.

Happy coding!

How to handle our documentation has been always a bit of struggle. For almost 2 years (see this blogpost and this one) we have working on improving the documentation structure, with by transferring information from the wiki, putting information closer to the code and setting up automating documentation. A few months ago, we managed to have automated logging and parameter documentation (see this blogpost).

Even though we think there is some improvement already, it can always be better! We have noticed that some of our users are a bit confused of how to go through our documentation. So in this blogpost we are discussing some navigational strategies of how you can maneuver yourself through the documentation as it is presented on bitcraze.io, which can also be found here.

Ecosystem-based navigation

So more than a year ago, we also started with a Ecosystem overview page, which are meant to take first-timers by the hand through the Crazyflie ecosystem.. This type of overview pages are starting from the three main pillars: the Crazyflie Platform, the Clients and Positioning Technology. This is a type of navigation that we mostly advise to take if you are a beginner Crazyflie user who do not know the structure of the eco system fully.

The Crazyflie platform page consist of all the important elements of the Crazyflie itself. It points to which hardware components the Crazyflie has, mainly the STM32 and NRF51 processor. It also points to the the existing expansion decks with their specifications and combination possibilities. Moreover, it refers to the family tree, which currently consist of the Bolt, Roadrunner and, of course, Crazyflie 2.X. Crazyradio and Clients overview page splits up the elements in the Crazyflie Python client & library, documentation about the Crazyradio PA, and the mobile clients development documentation for both Android and IOS. And finally, the positioning technologies overview page links to the information pages of the Lighthouse Positioning System, Loco Positioning System and the Motion capture system (also check out this blogpost).

Ecosystem-based documentation navigation tree

Repository-based navigation

For those that already have experience with the Crazyflie and its Ecosystem, the previous way of navigating through the docs might be a bit convoluted. With the Ecosystem-based navigation, it takes about 3 scrolls and clicks to reach the STM development documentation, which is a bit to much of a round way if you already know what you are looking for. We have made the repository overview page not for this purpose but we actually started using ourselves a lot within the company, as a direct pathway to the development repository per element. So this is a page that would be useful to other advanced developers as well!

So the repository overview page is split up in 4 main categories: Python-based software, C-based firmware, Other languages and bootloaders. See the navigation tree which of those repositories approximately point too. By the way, have you noticed that repository documentation has a gray header (like this one) and all the overview pages on the web have a green header (like this one)? This are meant to make you aware if you are still on a fluffy overview website page or going in the nitty gritty details of the development documentation.

Repository-based navigation tree

Feature-based navigation ?

Still a remaining problem is that the repository documentation might not be enough to get a good overview. Where do you need to look if you are interested in ‘controllers’ or ‘state estimators’, or how to make an app-layer application? Currently all of this is within the stm32 firmware documentation, as that is the exact location of where all of this is implemented. But how to document spanning features like the CRTP, where not only the STM chip but also the NRF, Crazyradio PA and the Crazyflie python library are also involved? Or how about the loco positioning system, where the Crazyflie communicates through the LPS deck with a separate LPS node?

So perhaps a good way how to present all this information, is to do it feature-based, like ‘controllers’, ‘positioning’, ‘high level commander’, where we present a structure that points to parts of the detailed documentation within the repo-docs. With ecosystem-based, or even repository-based, navigation documentation strategy, it will take for instance 4-7 clicks to come to the specific controller page, as you can verify by looking at the bread-crumb of the header. Perhaps splitting it up based on feature instead of Ecosystem elements or programming language might be a more logical structure of the current state of the Crazyflie documentation.

Feedback

One reason why it is so difficult to do this properly, is that we have a lot of repositories based on each microprocessor of all of our products, which makes our opensource projects quite unique. It is therefore difficult to find another opensource project of which we can take inspiration from. So, let us know what you would prefer for navigating through our documentation in this poll, but we are always open to other suggestions! If you know of any example of a similar opensource software project that is doing it the right way, or have any other tips, send us an email (contact_at_bitcraze.io), contact us on social media platforms or post a comment on this blogpost!

Update 2021-12-21:

The poll is closed and this is the result! Thanks all for responding!

Forms response chart. Question title: What type of documentation navigation would you prefer on bitcraze.io. Number of responses: 9 responses.

Background

In the past couple of weeks we have been busy trying to improve the development interface of the Crazyflie. We want to make developing with and for the platform a more pleasant experience.

We have started looking at the logging- and parameter framework and how to improve it for our users. The aim of this framework is to easily be able to log data from the Crazyflie and to set variables during runtime. Your application can use them to control the behavior of the platform or to receive data about what it is currently up to. As of today, in the firmware there are 227 parameters and 467 logging variables defined.

View from the cfclient of the different logging variables one could subscribe to

These logging variables and parameters have been added to the Crazyflie firmware over the course of years. Some are critical infrastructure, needed to be able to write proper applications that interface with the platform. Some are duplicates or were added as debug years ago. Others have in some way outlived their usefulness as the firmware and functionality has moved on. The problem is that we have no way of conveying this information to our users and this is what we are trying to rectify.

An attempt of stability

We are currently reviewing all of our logging variables and parameters in an attempt to make the situation clearer for our users … and ourselves. We are adding documentation to make the purpose of each individual parameters and logging variables more clear. And we are also dividing them up into two categories: core and non-core.

If a parameter or logging variable is marked as core in the firmware that constitutes a promise that we will try very hard to not remove, rename or in any other way change the behavior of it. The idea is that this variable or parameter can be used in applications without any fear or doubt about it going away.

If a variable or parameter is non-core it does not mean that it is marked for removal. But, it could mean that we need more time to make sure that it is the proper interface for the platform. It means that it could change in some way or in some cases be removed in later firmware releases.

The reason for doing this is twofold: we want to make the Crazyflie interface clearer for our users and we want something that we feel we can maintain and keep an up-to-date documentation of.

What is the result?

We have introduced a pair of new macros to the firmware, LOG_ADD_CORE and PARAM_ADD_CORE which can be used to mark a parameter or variable as core. When using these we also mandate that there should be a Doxygen comment attached to the macro.

Below is an example from the barometer log group, showing the style of documentation expected and how to mark a logging variable as core. Parameters gets treated in the same way.

/**
 * Log group for the barometer
 */
LOG_GROUP_START(baro)

/**
 * @brief Altitude above Sea Level [m]
 */
LOG_ADD_CORE(LOG_FLOAT, asl, &sensorData.baro.asl)

/**
 * @brief Temperature [degrees Celsius]
 */
LOG_ADD(LOG_FLOAT, temp, &sensorData.baro.temperature)

/**
 * @brief Air pressure [mbar]
 */
LOG_ADD_CORE(LOG_FLOAT, pressure, &sensorData.baro.pressure)

LOG_GROUP_STOP(baro)

We have also added a script In the firmware repository: elf_sanity.py. The script will return data about parameters and logging variables that it is included in a firmware elf. This can be used to count the number of core parameters. If we point it to a newly built Crazyflie elf, after we’ve done our initial review pass of the parameters and variables, we get the result below.

$ python3 tools/build/elf_sanity.py --core cf2.elf 
101 parameters and 78 log vars in elf

To produce a list of the parameters and variables you can add the --list-params and --list-logs options to the script.

What is the next step?

Once we have finished our review of the parameters and logging variables we will explore different ways of making the documentation of them available in a clear and accessible way. And we will come up with a scheme for making changes to the set of parameters and variables. Once this is all finished you can expect an update from us.

The end goal of our efforts is making developing for the Crazyflie a smoother process, and we would love to hear from you. What is confusing? What are your pain points? Let us know! So we can do better.

A few weeks ago we released version 2021-03 including the python library, Cfclient and the firmware. The biggest feature of that release was that we (finally) got the lighthouse positioning system out of early access and added it as an official product to the Crazyflie eco system! Of course we are very excited about that milestone, but the work does not end there… We also need to communicate how to use it, features and where to find all this new information to you – our favourite users!

New Landing Page

First of all, we made a new landing page for only the lighthouse system (similar to bitcraze.io/start) we now also have bitcraze.io/lighthouse. This landing page is what will be printed on the Lighthouse base station box that will be available soon in our store, but is also directly accessible from the front page under ‘Product News’.

This landing page has all kinds of handy links which directs the user to the getting started tutorial, the shop page or to its place within the different positioning systems we offer/support. It is meant to give a very generic first overview of the system without being overloaded right off the bat and we hope that the information funnel will be more smooth with this landing page.

New tutorial and product pages

For getting started with the lighthouse positioning system, we heavily advise everybody to follow the new getting started tutorial page, even if you have used the lighthouse system since it’s early access days. The thing is is that the procedure of setting the system up has changed drastically. The calibration data and geometry are now stored in persistent memory on-board the Crazyflie and the lighthouse deck itself is now properly flashed. So if you are still using custom config.mk, hardcode geometry in the app layer or use get_bs_geometry.py to get the geometry… stop what you are doing and update the crazyflie firmware, install the newest Cfclient, and follow the tutorial!

We also already made some product page for the Lighthouse Swarm bundle. Currently it is still noted as coming soon but you can already sign up to get a notification when it is out, which we hope to have ready in about 1-2 month(s). The lighthouse deck was of course already available for those that can not wait and want to buy a SteamVR base station somewhere else. Just keep in mind that, even though the v1 is supported, in the future we will mostly focus on the version 2 of the base stations.

Video tutorial

Once again we have ventured into the land of videos and recorded a “Getting started with the Lighthouse positioning system” tutorial for those who prefer video over text.

Feedback

We love feedback and want to improve! Please don’t hesitate to contact us on contact@bitcraze.io if you have comments or suggestions!