Category: Software

In the first years that I started at Bitcraze I’ve been focused mostly on embedded development and algorithmic design like the app layer, controllers and estimators and such, however recently I started to be quite interested in the robotic integration between the Crazyflie and other (open-source) projects and users. This means that I’ll be dwelling more often in the space between Bitcraze and the community, which is something that I do really enjoy I noticed during the Grand Tour. It also initiated my work with simulators which I think would be very useful for the community too. The summer fun project that I’ve been now working on is to integrate the Crazyflie with ROS2 to integrate standard navigational packages, which will be the topic of this blogpost!

ROS2 Crazyflie Node

So first I worked on the ROS2 node that actually communicates with the Crazyflie directly. I think many of you are familiar with the USC’s CrazySwarm project, of which the ROS2 variant, CrazySwarm2, is already available for most functionalities. Even though the name says CrazySwarm, this can be very easily used for only one Crazyflie too. The CrazySwam2 is currently under more development by the IMRClab of TU Berlin, but please take a look if you want to give it a go!

For now while Crazyswarm2 is still under development, I used the Bitcraze Crazyflie python library to make a more hackish node that just publishes exactly the information I want. I am focusing on the scenario with the STEM ranging bundle, aka the Crazyflie + Flowdeck (optical flow + distance sensor) + Multi-ranger (5 x distance sensors) combo, where the node logs the multi-ranger data and the odometry from the Flowdeck with the Crazyradio and outputs that into necessary /scan and /odom topics. Moreover, it also outputs several tf2 transforms that makes it possible to either visualize it in RVIZ and/or connect it to any other packages and it should react to incoming twist messages as well.

Development with a Simulator

And of course… I went in head first and connected it directly with the SLAM toolbox. I have worked with ROS1 in the past, but I had my first experience working with that package in the course: Build Mobile Robots with ROS2 (by Weekly Robotic Newsletter’s Mat Sadowski), so I couldn’t wait to try it on a real platform like the Crazyflie. However, tuning this was of course more work than I thought, as the map that I got out of it first was mostly a sparse collection of dots. Of course the SLAM toolbox is meant for lidars and not something that provided sparse range distances like the Multiranger. Then I decided to take one or two steps back, and first connect a simulator to make tuning a bit easier.

Luckily, I’ve already started to look at simulators, and was quite far in the Webots integration of the Crazyflie. Actually… Webots’ next release (2022b) will contain a Crazyflie as standard! Once it is out, I’ll write a blogpost about that separately :). As luck has it, Webots also has good ROS2 integration as well, and even won the ‘Best ROS Software’ award by The Construct’s ROS awards! Another reason is that I wanted to try out a different simulator for ROS2 this time to complement what I’ve learned in the ROS2 course I mentioned earlier.

So I used the webots driver node to write a simulated Crazyflie that should output the same information as the real Crazyflie node, so that I can easily hack around and try out different things without constantly disturbing my cats from their slumber :). Anyway, I won’t go into to the simulator too much and save that for another blogpost!

Simple Mapping

I decided to also take another additional step before going full SLAM, which is to make a simple mapper node first! This takes the estimated state estimate of the Crazyflie and the Multiranger’s range values and it creates an occupancy grid type map of it. I do have to give kudos to the Marcus’ cflib Pointcloud script and Webot’s simple mapper example, as I did look at them for some reference. But still with the examples, integration and connecting the dots together is quite some work. Luckily I had the simulator to try things out with!

So first I put the Crazyflie in an apartment simulator, flew around and see if any decent maps comes out of it and it seemed it did! Of course, the simulated Crazyflie’s ‘odometry’ comes from near perfect position estimate, so I didn’t expect any problems there (and in such a situation you would actually not really need the localization part of SLAM). This still needs some improvements to be done, like now range measurements that don’t see anything are excluded from drawing, but still it was pretty cool to map the virtual environment.

So it was off to try it out on a real crazyflie. In one of our meeting rooms, I had one Crazyflie take off, let it turn around with a twist message in a /cmd_vel topic and made a map of the room I was currently in. The effect of the 4 range sensors rotating around and creating a map in one go, makes me think of these retro video transitions. And the odometry drift does not seem as bad for it to be possible, but I haven’t mapped our entire office yet so that might be different!

What’s next?

So I’m not stopping here for sure, I want to extend this functionality further and for sure get it to work with the SLAM_toolbox properly! But if the simple mapper already can produce such quality, I’m pretty sure that this can be done in one way or the other. What I could also do, is first generate a simple map and already have a go at the NAV2 package with that one… there are many roads to Rome here!

Currently I’m doing my work on my personal Github account in the crazyflie_ros2_experimental repository. Everything is still very much in development, hackish and quite specific for one use case but that is expected to change once things are working better, so please check the planning in the project’s readme. In the mean time, you can indicate to us in this vote if this is an interesting direction for us to go towards. Not that it will stop me from continuing this project since it is too much fun, but it is always good to know if certain efforts are appreciated!

Last week we had the first ever Bitcraze DEV meeting! With about 10 participants, we covered a range of topics. The meeting was mostly focused around how to handle support and what the DEV meetings should be about. We also had a chance to get some feedback, and one of the points was sharing a bit more what we’re currently working on and what we might work on in the future. So in the light of that, this blogpost is about CPX (the Crazyflie Packet eXchange) protocol. We’ve mentioned CPX before (1, 2), but with this blogpost I want to share the current status and some thoughts on why we need something new.

As summer is approaching and things are winding down, I’m talking the opportunity to get back to the AI deck and CPX. The AI deck was officially released out of early access last month, but there’s still more work to be done with porting examples, adding some more functionality and increasing stability and performance.

For the AI deck we’re only supplying examples, there’s no functionality that will be used with the platform (except for the WiFi connection maybe). This is in contrast to for instance the Flow deck, where there’s a specified functionality the user can use and that should work. So in order to move forward I came up with a little demo that I want to get working during the summer. The goal is to make an application where I can fly around the Crazyflie with the keyboard and get a video stream back. To achieve this I’m using the Flow deck together with the AI deck and using WiFi for both CPX and CRTP (to send command and to get images and logging).

Why we need something new

I’ve written a post about CPX in the past (link) where I detailed the issues we are trying to solve. But in short we needed was a protocol that …

  • … could be routed though intermediaries to reach it’s destination
  • … could handle high transfer rates with large amounts of data as well as small messages
  • … could handle different memory budgets
  • … doesn’t drop data along the way if some parts of the system is loaded

As the Crazyflie echo system grows and becomes more complex we need new tools to work with it. When CRTP was implemented many years ago, the complexity we have today wasn’t something we could imagine. The Crazyflie had the only MCU and the hardware on the decks were used directly from it. Now we have multiple decks with more complex systems on them: AI deck (2 MCUs), Active marker deck (1 MCU) and the Lighthouse deck (1 FPGA). Looking forward these more complex decks might increase in the future. With more and more functionality in the Crazyflie and resources occupied, like DMA channels and pins, some functionality might need to move further out onto the decks.

For each deck new protocols are implemented and specific code is needed in the Crazyflie to handle it. Some things also become complex, like getting printouts from the different MCUs on the decks. So for the AI deck we wanted to test something new and more generic to see if it would be something we could use more in the future to talk directly to different MCUs in the system.

Will CPX replace CRTP? Probably not. We’re not sure what solution we will land in, but I think CPX is a good step in the right direction.

Current status

Back to my little demo. To reach the goal there’s a few things which needs to be fixed:

  • crazyflie-firmware/#1065: When starting to run CRTP over CPX (via WiFi) I’ve noticed that the UART2 driver was too slow, loading the system too heavily and creating problems down the line. So this is being worked on, and at the same time the old SYS-link over UART2 implementation is being moved to CPX instead.
  • aideck-esp-firmware/#12: We’ve had reports of intermittent performance issues for WiFi, which is also effecting.

Aside from the issues there’s also a few other features that are being added:

  • CRTP over CPX: Since I already have a connection for the images I also want to use this for controlling the Crazyflie. The latency is too high for controlling roll/pitch/yaw in real-time, but in my case I have the Flow deck for position control
  • CPX over CRTP: Although not part of the demo, this is interesting to look at for the future. One example is that right now we have an implementation where the Crazyflie firmware has a special implementation for the WiFi credentials. If we would like to set it from the ground we would first have to do CRTP to the Crazyflie, re-package it and then send it via CPX to the ESP32 on the AI deck. Instead I would like to send it via CPX directly from the ground, saving us extra work and complexity in the Crazyflie
  • Using Zeroconf/mDNS for finding AI decks: With this changes it will be possible to connect to the Crazyflie via the client, so we need a way to find the AI decks. For this Zeroconf/mDNS has been added, so AI decks will be automatically discovered on the local network.

The current status can be seen in the following draft PRs: crazyflie-firmware/#1068 and crazyflie-lib-python/#342. Note that until these are real PRs (not draft) they are not useful, so don’t try to use them yet.

CPX documentation

For more information on CPX and how it’s implemented, check out the documentation on our website we well as the specific documentation on using it from the GAP8.

Our Ultra Wide Band (UWB) based positioning system, the Loco Positioning System, has been around for a long time and is still going strong! In this post we will tell you a bit about how it works (for those that don’t know about it yet), what research that is on-going in the field and new developments.

Crazyflie with Loco deck

Basics

UWB is using high frequency, low power, wide band radio where one of the most important properties is that it is possible to detect when a packet is received with very high accuracy. Combining this with very high frequency clocks, opens up the possibility to measure the time it takes for a radio packet to travel from a transmitter to a receiver. Since radio waves propagates with the speed of light in air we can convert the time into distance, and this is the basic idea in UWB positioning.

Not only is it possible to measure the timing of transmissions, the packets can also contain data, like in other radio standards. This property is extensively used to include time stamps of when a packet is sent, and also for instance the time stamp of when the transmitter received other packets or the position of an anchor.

This sounds pretty straight forward, but there are (of course) some complications. We will mention some of them but not go into the details.

  • Reflections – radio waves bounce around on walls and objects. Luckily, the nature of UWB actually uses this to its advantage and works better indoors than out side.
  • The clocks in the transmitter and receiver are not synchronized – the Time Of Flight can unfortunately not simply be measured by subtracting reception time from transmission time as the time stamps originate from two different clocks. The problem can be solved by sending some more packets back and forth though.
  • Packet collisions – two transmitters can not send at the same time, one or both packets will be lost. Transmissions must be scheduled or packet loss must be handled.
  • Obstacles – obstacles between the transmitter and receiver changes the transmission time.
  • Antennas – the propagation time through the antenna is substantial and changes depending on the angle to the transmitter/receiver.
  • Radio interference – other radio sources may interfere with the UWB radio signals and add noise or packet loss.

Modes

The Loco Positioning System can run in two fundamentally different modes: Two Way Ranging (TWR) and Time Difference of Arrival (TDoA).

Two Way Ranging (TWR)

In TWR the Crazyflie measures the distance to one anchor at a time, over and over again. Each measurement in initiated by the Crazyflie and requires 4 messages to be sent between the Crazyflie and the anchor, two request-response pairs. The position is estimated by pushing the measured distances into the kalman estimator.

This mode only supports one Crazyflie, but has the advantage of being very robust and also works pretty well some distance outside the system.

Time Difference of Arrival (TDoA)

In TDoA the setup is different, the anchors are transmitting packets while the Crazyflie is passively listening to the traffic. From the received information it is unfortunately not possible to measure the distance to the anchors, but what we can get is the difference in distance to two anchors. For example, we might know that we are 0.54 meters closer to anchor 3 than anchor 6, or similar. It is possible to calculate the position from this information and similarly to TWR the measurements are pushed to the kalman estimator for further processing.

This mode supports unlimited numbers of Crazyflies (swarms) but is less robust compared to TWR, especially outside the system. TDoA is similar to how GPS works.

Research

There are many researchers that use the Loco System, some use it as a positioning system and investigate topics like path planning or similar, while some others are looking at different questions related to the UWB positioning itself. We will not try to mention everyone, we probably only know of a small fraction of what is going on (please tell us!), but would like to point out two areas of research.

The first is related to improving the estimated position by handling measurement errors and the environment in a better way. Examples of this is to compensate for differences in reception angle or handling of obstacles in the space. We would like to mention Wenda Zhao’s work at the Dynamic Systems Lab, University of Toronto. He has contributed the robust TDoA implementation in the kalman estimator (blog post) as well as a public TDoA data set.

The second is inter drone ranging, that is measuring the distance between drones as an addition to, or instead of drone-to-anchor measurements. Examples in this are are the work by Dr Feng Shan at School of Computer Science and Engineering Southeast University, China (blog post) and professor Klaus Kefferpütz, Hochschule Augsburg, work on “Crazyflie quadcopter in decentralized swarming” as presented on the BAM days last year.

Experimental functionality

Even though there has not been a lot of code committed lately in our repositories related to the Loco Positioning System, it has been simmering in the background. We would like to mention what is cooking in the pots and some of the stuff that has been discussed or tested.

System size

An 8 anchor Loco Positioning System can cover a flight space of around 8×8 meters, but from time to time we get the question of larger systems. TDoA3 was designed with this in mind and supports up to 255 anchors, which in theory would make it possible to build larger systems. This functionality was implemented 4 years ago but we never really tested it(!). Finally we collected all anchors in the lab an set up 20 anchors in the same system, and it worked! This should make it possible to extend systems to at least 15×15 meters, but maybe even more with some clever radio cell planing.

Another possibility to enlarge a system is to tweak the radio settings to make them reach longer. There is a “Longer range” mode in TDoA3 that lowers the bit rate, but again it has not really been verified. This was also tested in the latest Loco frenzy and with some minor modifications it worked the way we hoped, with 20 anchors! The tests mainly verified that the anchors play nicely together, and we are not sure about the maximum range (to be tested) but we believe distances of up to 40 meters between anchors is possible. To use this feature you should make sure to use the latest firmware for the Loco Nodes as well as the Crazyflie.

The two features mentioned above should hopefully make it possible to go big and we hope it could be used for shows for instance.

TDoA3 hybrid mode

If one looks at the messages sent in a TDoA system, the anchors are actually doing TWR with each other, while the Crazyflie(s) are just listening to the traffic and that the possibility to extract the position is a nice “side effect”. Now imagine if the Crazyflies were to send some messages from time to time, then they could act as “dynamic” anchors, or do inter-drone ranging with each other. This is something we call TDoA3 hybrid mode.

Currently there is no official implementation of the Hybrid mode, only some experimental hacks. Some researchers have done their own implementations, but we hope, at some point, to generalize the functionality and integrate it into the firmware.

Read more

If you are interested to read more about positioning and the Loco system, you can take a look at the following link list.

Summer time!

Summer is coming and with that vacations, yeay! There will always be someone at the office to help you if you need help, and we will handle shipping through out the summer, but it might take a bit longer than usual.

We hope you all have some great summer months!

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.

We recently added improved support for assert information in the client and wanted to take this opportunity to describe some of the features in the console tab of the client that are useful for debugging and profiling.

Example of the console tab

The console tab in the python client is where you can get real time logs from the Crazyflie when connected. Any DEBUG_PRINT() statements in the Crazyflie firmware will popup here and is obviously a simple way of adding debug information to your firmware. The console logs are buffered in the Crazyflie and dumped to the client when you connect, this is why you will see the start up information when connecting to a Crazyflie. If too much information is logged and the buffer is full, you will unfortunately loose some of it but you will be notified by a “<F>” marker in the console window.

On the right side of the console tab window you will find some useful buttons, the first being the “Clear” button that simply clears the console window.

Task dump

The “Task dump” button will print a list with information about the FreeRTOS tasks running in the system, for instance something like this.

SYSLOAD: Task dump
SYSLOAD: Load	Stack left	Name
SYSLOAD: 0.19 	205 		Tmr Svc
SYSLOAD: 83.70 	127 		IDLE
SYSLOAD: 0.01 	213 		CRTP-RX
SYSLOAD: 0.0 	54 		PWRMGNT
SYSLOAD: 0.70 	131 		LH
SYSLOAD: 0.0 	117 		CRTP-SRV
...Code language: CSS (css)

The “load” column contains how much of the total time that was spent in each task, since the previous measurement (or boot). To get useful values when performing some task, you probably want to make a dump at the start of your measurement and a second one at the end to get the average during this specific time.

The “Stack left” shows how many bytes of stack that is left for each task, this is the worst recorded number in the period. Stack size is recorded at task switch time which means it is possible that more stack actually was used at some point, but it should give a good indication if a task is running out of stack.

Assert info

Next up is the new “Assert info” button, it will dump assert or crash info to the console. When the STM CPU encounters a hard fault or some other condition that resets the CPU, it will record some basic crash information in a specific part of the RAM. This special RAM is not reset when the STM re-boots and it will automatically be dumped to the console log for investigation during the start up sequence. The “Assert info” button simply dumps the same information again, which may not sound very useful. But in some cases a client may auto-reconnect to a crashed Crazyflie, consume the console log and dispose of it before a human had the opportunity to look at it. In this case you can simply connect the client to the Crazyflie and click the “Assert info” button to get the information again.

Propeller test

The “Propeller test” button runs a automated test of the propellers and measures vibrations in the platform to determine if they are well balanced or not. The result is printed in the console window, like this: (looks like it is time to change one of my propellers!)

HEALTH: Acc noise floor variance X+Y:0.004469, (Z:0.002136)
HEALTH: Motor M1 variance X+Y: 4.17 (Z:0.55), voltage sag:0.35
HEALTH: Motor M2 variance X+Y: 0.22 (Z:0.42), voltage sag:0.37
HEALTH: Motor M3 variance X+Y: 1.23 (Z:0.21), voltage sag:0.35
HEALTH: Motor M4 variance X+Y: 1.09 (Z:0.17), voltage sag:0.31
HEALTH: Propeller test on M1 [FAIL]. low: 0.0, high: 2.50, measured: 4.17
ESTKALMAN: WARNING: Kalman prediction rate low (82)Code language: CSS (css)

Battery test

The final button is the “Battery test”. It tests if the battery is worn out by spinning the motors and measuring the drop in voltage. A drop in the voltage indicates that the battery probably is bad, but it can also be caused by other sources of extra resistance in the power path, for instance oxide on the battery connector. Use it as an indication only!

Note: Only use this test for the Crazyflie 2.x, not the Bolt or BigQuad.

The result of this test is printed in the console log:

HEALTH: Idle:4.15V sag: 0.67V (< 0.95V) [OK]Code language: CSS (css)

The console side-by-side other tabs

It is possible to add the console log as a tool box at the bottom or one of the sides of the client. In the “View” menu, choose “toolboxes” and click “Console”. A toolbox window with the console log will appear at the bottom of the screen which can be handy as it will be visible even if you switch to another tab.

The Plotter tab with the console as a toolbox

Other debug tools

This post has been focused on the console tab, but there are of course other functionality that is useful when debugging your system. We will end by quickly mention some of them:

There is a new fresh release of both the firmware and the python library and client! The last release (2022.01) was from 2 months ago but we already added quite some extra functionality so we wanted to make a snapshot of this before continuing on other priorities.

Kbuild on CF firmware

One of the biggest changes that you will notice, is that there is now a new way to configure your Crazyflie firmware before building it. The old config.mk is gone and you will now need to either automatically generate a config file or generate one with the menuconfig, of which kbuild is most known for. For more information, please read the blogpost about this latest change, for the exception that we do prefer the users to use ‘make cf2_config’ as instructed in the 2022.03 version of the repo documentation.

Platform support for Bolt

We now defined the Bolt as a different platform. That means that for each release, there should now also be a bolt flavor zip file, next to the cf2 and tag zips, as you can see in the release page. Moreover, if you want to build the firmware to be Bolt compatible, you would first need to do ‘make bolt_defconfig’ to generate the needed configs with kbuild. For more information of how to add your own custom platform, please check out these instructions.

2+ Lighthouse base stations (experimental)

For those that feel constrained by the max 2 lighthouse base station support in the firmware and client, this functionality is now part of the release. This blogpost will explain more about this, and it is still experimental in nature, as you would need to reconfigure the firmware with… you guessed it: Kbuild! Also the geometry estimation needs to be done as a separate python script as well all from the Crazyflie python library. No worries, if you still prefer using the cfclient, it still uses the old way of estimating if you click the button, but just remember that you would need to do something extra in order to get 2+ base station support.

New VM release

We were also made aware of a pretty big error in the bitcraze VM, namely that we still used the old git:// type url for github repositories. IN the new release of the bitcraze VM this should be fixed, so please download the new one, or fix it yourself in your current VM by changing the remote URLs of the github repos you are working on to https://.

There has been some background work going on related to the Lighthouse system, as mentioned in a previous blogpost. The solution has been improved since that blog post and we believe the functionality is now on a level where it works pretty well and can add value to most Lighthouse users.

How to use it?

We have added a brief documentation to get you started. Though the solution has been stabilized, it is still a bit experimental and it has not been fully integrated into the client yet. The base station geometry estimator still has to be run as a python script from the command line, and a reconfigured version of the Crazyflie firmware has to be built and flashed.

We have added some improvements to the client thought to enable it to display base station status for 2+ base stations. This was the final part of the client UI that did not support 2+ base stations, and now remains only the possibility to run the new geometry estimation from the client.

Benefits

What kind of improvements does it bring?

First of all, the functionality to use more than 2 base stations and the possibility to cover a larger flight space. It also makes it possible to set up multi-room systems to support flight from one room to another.

Secondly an improved estimation of the base station geometry (also when using 2 base stations) that generally reduces the errors and improves the position estimation of the Crazyflie when flying. “Jumping” of the estimated position when one base station is occluded should be reduced. When following a trajectory that is straight line through space, the Crazyflie should now actually fly on a fairly straight line, previously the flown path might be a bit curved.

The new solution has a better match to the physical world and hopefully the estimated Z will be closer to zero when the Crazyflie is on the floor, with the “old” method, the solution sometimes is slightly tilted with a Z != 0 in some areas.

Problems

Most of the Lighthouse system works just like before, the new functionality is related to base station geometry estimation. The “standard” geometry estimation is still available in the client and if you continue to use this nothing is changed, the following list is for the new estimation method.

  • The new geometry estimation is a bit clunky to use and the user still has to rebuild the firmware and run a python script.
  • Lighthouse 1 is not fully supported
  • The new geometry estimation does not work with one base station.

We hope to address the above problems in future releases.

Release

Talking about releases, we are working on a new official release. If no unforeseen obstacles are found, we plan to make a new release within a week or two.

The functionality discussed in this blog post is still only in source code, on master or possibly in some pull requests. If you wait for the release all repositories should be syncronized and make it a bit easier to try out.

Feedback

As the environment of the system has an impact on this type of functionality, we would love to get feedback from you if you try it out. We’d love to hear how it works for you!

In December we had a blogpost where we gave an overview of existing simulation models that were out there. In the mean time, I have done some work during my Fun Fridays to get this to work even further. Currently I moved the efforts from my personal Github repo to the Bitcraze organization github called crazyflie-simulation. It is all still very much work in progress but in this blogpost I will explain the content of the repository and what these elements can already do.

Low Poly CAD model

The first thing that you will need to have for any simulation, is a 3D model of the Crazyflie. There is of course already great models available from the CrazyS project, the sim_cf project and the multi_uav_simulator, which are completely fine to use as well. But since we have direct access to the exact geometries of the real crazyflie itself, I wanted to see if I could abstract the shapes myself. And also I would like to improve my Blender skills, so this seemed to be a nice project to work with! Moreover, it might be handy to have a central place if anybody is looking for a 3D simulation model of the Crazyflie.

For simulations with only one or a few Crazyflie, the higher resolution models from the other repository are absolutely sufficient, especially if you are not using a very complicated physics geometry model (because that is where most of the computation is). But if you would like to simulate very big swarms, then the polygon count will have more influences on the speed of the simulation. So I managed to make it to 1970 vertices with the below Crazyflie model, which is not too bad! I am sure that we can make it even with lesser polygons but this is perhaps a good place to start out with for now.

In the crazyflie-simulation, you can find the Blender, stl files and collada files under the folder ‘meshes’.

Webots model

We implemented the above model in a Webots simulator, which was much easier to implement than I thought! The tutorials they provide are great so I was able to get the model flying within a day or two. By combining the propeller node and rotational motor, and adjusting the thrust and drag coefficient to be a bit more ‘Crazyflie like’, it was able to take off. It would be nice to perhaps base these coefficients on the system identification of the Crazyflie, like what was done for this bachelor thesis, but for now our goal is just to make it fly!

The webots model can found in the same simulation repository under /webots/. You can try out the model by

webots webots/world/crazyfly_world.wbt

It would then be possible to control the pitch and roll with the arrow keys of your keyboard while it is maintaining a current height of 1 meter. This is current state of the code as of commit 79640a.

Ignition Gazebo model

Ignition will be the replacement for Gazebo Classic, which is already a well known simulator for many of you. Writing controllers and plugins is slightly more challenging as it is only in C++ but it is such a landmark in the world of simulation, it only makes sense that we will try to make a Gazebo model of the Crazyflie as well! In the previous blogpost I mentioned that I already experimented a bit with Ignition Gazebo, as it has the nice multicopter motor model plugin standard within the framework now. Then I tried to make it controllable with the intergrated multicopter velocity control plugin but I wasn’t super successful, probably because I didn’t have the right coefficients and gains! I will rekindle these efforts another time, but if anybody would like to try that out, please do so!

First I made my own controller plugin for the gazebo model, which can be found in the repository in a different branch under /gazebo-ignition/. This controller plugin needs to be built first and it’s bin file added to the path IGN_GAZEBO_SYSTEM_PLUGIN_PATH, and the Crazyflie model in IGN_GAZEBO_RESOURCE_PATH , but then if you try to fly the model with the following:

 ign gazebo crazyflie_world.sdfCode language: CSS (css)

It will take off and hover nicely. Unfortunately, if you try out the key publisher widget with the arrow keys, you see that the Crazyflie immediately crashes. So there is still something fishy there! Please check out the issue list of the repo to check the state on that.

Controllers

So the reason why I made my own controller plugins for the above mentioned simulation models, is that I want to experiment with a way that we can separate the crazyflie firmware controllers, make a code wrapper for them, and use those controllers directly in the simulator. So this way it will become a hybrid software in the loop without having to compile the entire firmware that contains all kinds of extra things that the simulation probably does not need. We can’t do this hybrid SITL yet, but at least it would be nice to have the elements in place to make it possible.

Currently I’m only experimenting with a simple fixed height and attitude PID controller written in C, and some extra files to make it possible to make a python wrapper for those. The C-controller itself you can try out in Webots as of this commit 79640a, but hopefully we will have the python version of it working too.

What is next?

As you probably noticed, the simulation work are still very much work in process and there is still a lot enhancements to add or fix. Currently this is only done on available Fridays so the progress is not super fast unfortunately, but at least there is one model flying.

Some other elements that we would like to work on:

  • Velocity controller, so that the models are able to react on twist messages.
  • Crazyflie firmware bindings of controllers
  • Better system variables (at least so that the ign gazebo model and the webots model are more similar)
  • CFlib integration
  • Add a multiranger and/or camera.
  • and more!

I might turn a couple of these into topics that would be good for contribution, so that any community members can help out with. Please keep an eye on the issue list, and we are communicating on the Crazyswarm2 Discussion page about simulations if you want to share your thoughts on this as well.

During the last couple of months we’ve been working on getting the AI-deck out of early-access. One of the things needed for this to happen is an improved infrastructure for the AI-deck, like bootloading and how the deck fits into the rest of the eco-system. For this there’s two new repositories:

CPX (Crazyflie Packet eXchange)

With the addition of two new MCUs (ESP32 and GAP8) as well as the possibility to connect via the WiFi, we quickly run into the issue of how to communicate between the targets. Even more so since there’s no direct access between some of these (like the Crazyflie<->WiFi, Crazyflie<->GAP8, GAP8<->WiFi).

What we needed was a protocol that …

  • … could be routed though intermediaries to reach it’s destination
  • … could handle high transfer rates with large amounts of data as well as small messages
  • … could handle different memory budgets
  • … doesn’t drop data along the way if some parts of the system is loaded

We decided to design and implement a new protocol, which we’ve named CPX (Crazyflie Packet eXchange). The protocol solves the issues above by:

  • Each packet has a source and destination ID, so it can be routed to (and from) the target of the packet
  • Each link between targets can have it’s own MTU, which allows each target to optimize memory usage. In order to handle this, intermediaries are allowed to split packages along the way, so data can be transferred in smaller pieces.
  • Instead of dropping packages if targets become overloaded, congestion in created in the system, where the sender will not be able to send more data until the receiver has been able to handle it.

Currently the new protocol is used for the GAP8 bootloader, for setting up the WiFi on the ESP32 and in the WiFi streamer example. But we’re hoping to expand it in the future to include more functionality, like logging and other plumbing that could be used in user applications.

WiFi configuration changes

With CPX it’s now possible to set up the WiFi from either the Crazyflie, the GAP8 or from the ESP32 itself. For doing this from the Crazyflie we’ve added the option of configuring this using KConfig, where we’ve added the following options in the expansion decks menu for the AI-deck:

  • Do not set-up the WiFi: Should be used if another target is setting up the WiFi, like the GAP8
  • Act as an access point: This will make it possible to connect to the AI-deck as an access point
  • Connect to an access point: This will connect the AI-deck to an access point using SSID/PASSWD entered in the menuconfig

GAP 8 bootloader

To make things easier for the user we want to remove the requirement of using a JTAG dongle to program the GAP8. In order to achieve this we’ve implemented a bootloader for the GAP8 which uses CPX, which means it can be used either from the Crazyflie or over the WiFi. We still haven’t had time to implement the Crazyflie part, where this will fit nicely together with the cload and client deck firmware upgrade, but it’s currently working via the WiFi. So until the implementation is done via the Crazyflie Python library, this script can be used to bootload and start your custom GAP8 firmware. Note though, that you will first have to flash the GAP8 bootloader and set-up the WiFi.

What’s next?

We’re continuing working towards getting the AI-deck out of early access. For CPX and the GAP8 bootloader there’s still a few bugs to iron out and examples to be updated as well as improved support for building using our toolbelt.

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!