Author: Arnaud

It seems that many have received their Crazyflie 2.0 now. It is a very exciting time for us, tell us what you think about your Crazylie 2.0 and if you have any problems. We wish you Merry Christmas, a Happy New Year, and a lot of fun with your new Crazyflie 2.0!

Getting started

The instructions and documentation are not really as finished as we would like them to be but we hope it is good enough for everyone to get started. For convenience we have put together a sets of links to find the information easier.

Crazyflie 2.0 – Getting started
Crazyflie 2.0 – Wiki
Crazyflie 2.0 – FAQ
Crazyradio/Crazyradio PA – Wiki
Crazyradio/Crazyradio PA – Windows driver installation
Android App
iOS App

Expansion port

The expansion port is a core functionality and it is important that it is easy to work with. The hardware part of the expansion port allows to easily attach custom electronic to the Crazyflie 2.0, making it a very versatile platform. We want to bring this convenience to the firmware and software development as well. We are not really there yet but would like to share our ideas of how we think, but also as an inspiration and to get valuable feedback.

As you might know we have added One-Wire memories on all our expansion board so that CF2 is able to detect which expansion board is connected. The intent is to automatically initialize the expansion board driver when a board is detected so that the firmware can contain all the expansion board drivers. Other benefits are that the resources easier can be shared but also blocked if there are conflicts between boards.

Currently we are in a state where we have made a prototype of how we want the driver to look like and work. The example/mock-up driver we have put together is for the traffic light hack we have written about earlier. The driver would just declare which expansion board it is supporting and it would be loaded automatically. Also some enhancement to the parameter API would allow for more declarative and short code.

Things will be a little bit slow here at Bitcraze during Christmas period as we are focusing on support and on our families. This is however definitely one or our focus when we start 2015. We will create issues to track this work in the Crazyflie firmware bug tracker, contributions are welcome :).

Bluetooth support

We have also published the rest of the Crazyflie firmware, the nRF51 has firmware, bootloader and a ‘Master Boot Switch’. The STM32F4 has bootloader and firmware. The nRF51 bootloader and firmware supports bluetooth low energy using a proprietary stack from Nordic Semiconductor. This stack architecture should play well with open source software as it is completly isolated from the firmware, it runs on the background and is interfaced with syscall (ie. the same way a program communicates with an OS in computers), Nordic call that a Softdevice. The problem is that the supporting libs that allows to access the softdevice is currently proprietary and we do not have the right to publish it.

Currently you can compile the nRF51 firmware in ESB (Enhanced Shock Burst) mode (ie. to communicate with Crazyradio) out of the box. To compile with BLE support you should download the S110 Softdevice and nrf51_sdk from Nordic Semiconductor and this requires you to have one of the Nordic kit. We are in communication with Nordic to fix this situation and will keep you updated. One nice thing about the nRF51 is that the radio is well documented so one way or another this is going to be solved: either we can distribute supporting files for the Nordic stack, or we make our own stack ;-).

Virtual machine

The virtual machine for the Crazyflie 2.0 is on its way, but as we have run into some problems, it has been delayed a bit. Now most of the problems has been fixed and we hope to release it any day now.

The workload is still huge and now it is starting to take its toll, we are really looking forward to a short vacation around Christmas! But even though we will be off, we will still be checking the support forum. Meanwhile we are doing our best to continue to march on and we managed to write some new documentation and also pushed some new releases. Please have a look at last week post which we have updated and will continue to update as we push them out.

Unbalanced CCW propellers

After receiving the final production version we have found that many of the CCW propellers (not marked with an A) shipped with Crazyflie 2.0 are a bit too unbalanced. This might cause vibration that will affects the flight performance. To get the best flight performance the propellers, especially CCW, might need to be balanced. Balancing the propellers is pretty easy, all you need is a needle and some office tape. We have put together a step by step guide on how to balance them and also updated the general assembly instructions to include balancing. We are currently investigating this with the propeller manufacturer and we will keep updating about it. If you have any questions or concerns drop by our support forum.

Firmware update

Yesterday we released a new version of the Crazyflie 2.0 firmware. This version fixes an issue that was triggered by the motor PWM frequency interfering with the one of the voltage regulators causing the Crazyflie 2.0 to shut-off if the thrust increased too fast. Doubling the PWM frequency fixed this issue completely. We also adjusted the gyro and accelerometer low pass filters a bit to handle vibrations from unbalanced propellers a bit better.

Crazyflie 2.0 can be updated with Crazyradio using the latest version of the Crazyflie client, with the update zip. Documentation of the update process is on the wiki. We also made a USB dfu update zip for people that do not have the Crazyradio. Instruction for the DFU is in the README.txt file in the zip file. In the future it will be possible to update Crazyflie 2.0 with the Android and iPhone client as well. This time around the update is for Crazyflie 2.0 only but the plan is to merge both Crazyflie firmware together in order to release everything at the same time.

New Android release

The Android client is also going forward thanks to Fred. This evening we are releasing an update that enhance the GUI and allow the app to run full screen on Android 4.4+. The update is going to be released on the play store.

android client 0.2

 

Feedback

We are really eager to hear what you think about the new Crazyflie 2.0, the instructions and everything else around it. So please drop by our feedback topic in the forum, or post your feedback here, to let us know what you think.

We kicked off the Crazyflie 2.0 production about one week ago and we are still working hard on ensuring the best possible quality of the production. To do so we have a test specification/plan that is executed on all the produced units. Making test protocols is something we have had some experience of in our former day-jobs, but it is always a challenging and time consuming task. However the reward is great, good tests ensure good quality to the end user. The higher the production quality is, the happier everyone is, and the more time we have to do other things like developing new features :-).

The tests runs on an assembled PCB and first thing to verify is an electric test checking that voltages and current consumption are normal. Then the board gets programmed.

For the original Crazyflie, the testing was heavily based on the power on self-test. This is still the case with the Crazyflie 2.0 which allows to make sure that everything is working in factory as well as every time a Crazyflie gets powered (this power-on-self-test is the first thing to run before assembling the Crazyflie).

For Crazyflie 2.0 we also needed to create new tests for the expansion port. First of all we needed to check that the connector is mounted properly and that the pins for the expansion port are able to pass though the PCB. Secondly we also have to test the electrical connectivity. For this we have created a special expansion test board which, allows the Crazyflie to self test all expansion connections. This board is detected by the 1-wire memory which is mounted on the test board. When it is inserted it will automatically trigger the test code which checks all connections.

To do tests on a limited budget you will have to get creative. E.g. to do output power and frequency test for the radio communication on the Crazyflie and Crazyradio we are using the rfExplorer. It is a neat cheap 2.4GHz spectrum analyzer that we control from Python which can measure the radio frequency and output power. ICT or bed of nail tests are also very expensive and instead we use test fixtures with pogo-pins to test the electronics. It doesn’t get as extensive as a net checking ICT but with some clever testing using the software most components can be tested anyway. We have added some photos of the original Crazyflie test rig to this post. We will soon travel to the Seeedstudio office in Shenzhen in China and we will take photos of the new production and test equipment.

One of the nice new functionality of Crazyflie 2.0 is the Bluetooth 4.0 low energy (BLE) connectivity. In Crazyflie 2.0 we are using a radio microcontroller chip from Nordic semiconductor, the nRF51822. This radio chip allows us to keep compatibility with the existing Crayradio (and future Crazyradio PA), and to support BLE connectivity as well. The radio chip is a bit bigger that the one we used so far, and with the Power amplifier, we end up having the radio taking more space on the PCB:

The extra footprint is offset by the fact that we are now using smaller sensors and that the nRF51 is also handling the power management thus freeing pins on the main CPU.

The main usage of BLE will be to fly Crazyflie from a compatible mobile device like an Android phone or an Iphone. This could be used both to ‘just fly’ or to develop crazyflie control apps using the mobile phones capabilities. For example the phone camera could be used to detect and control Crazyflie autonomously. We have prototyped the BLE communication both on the existing Android client and for IPhone. The plan is to provide basic apps for the Crazyflie 2.0 release so that the copter can be flown from a mobile device out of the box. So far we have got the copter to fly from both Android and IOS:

We are not planning on implementing any BLE support for the PC client, so Crazyradio is still the main way to communicate with Crazyfle. It is possible to have BLE on PC but it would require a major effort to get it to work for Linux, Windows and Mac (there is no cross-platorm Python BLE lib as far as I know. If there is some please tell me in the comments!). Also Crazyradio is lower latency and has an higher datarate which makes it better for flying and communicating with one or many Crazyflie 2.0 from a PC.

We are also implementing BLE in the bootloader. This means that it will be possible update the Crazyflie 2.0 firmware from both a PC or a mobile device.

Technically we are using the Nordic Semiconductor soft device BLE stack. The stack runs a little bit like an operating system, behind and independently of the firmware: the firmware is not linked to the stack. This will make things a little bit easier to have an open-source firmware even though the nordic bluetooth stack is closed. Another nice thing about the nordic chip is that the radio peripheral is well documented so implementing open source stacks in the future is potentially possible.

Practically we where originally planning to have two modes for the firmware: one Crazyradio and one bluetooth mode. However the new release of the Nordic BLE stack allow to mix BLE and Crazyradio at the same time. So we are working on having a seamless connection procedure between Crazyradio and BLE: when starting Crazyflie 2.0 it will be accessible both via BLE and with the Crazyradio. When connected the unused mode will be disabled until disconnection. Also the name of the copter will be communicated both in BLE and Crazyradio mode and can be changed by the user. This will help a lot people having more than one Crazyflie (us first!) to differentiate them.

As we said in previous post, with Crazyflie 2.0 one of the focus has been on enhancing the current Crazyflie platform. The radio range and power is one of these things that is good enough on the current Crazyflie but that could be made much better. So on Crazyflie 2.0 we added a +20dB power amplifier that increase the output power up to +20dBm.

The logical move was to add a similar amplifier on the Crazyradio dongle and that is what we did. We made Crazyradio PA (power amplifier) and we intend to release it with Crazyflie 2.0

The output power is now of 20dBm for Crazyradio PA, which will dramatically increase the control range. Even though Crazyflie was originally intended for indoor use, Crazyflie 2.0 is pretty capable outside, mostly with the expansion capability that could allow to add things like GPS, so the extra range could be put to use. But maybe the biggest advantage is indoor where Crazyradio is now playing equal with Wifi in term of TX power. This increases the link robustness and allows for flying in other rooms (could be useful with a powerful FPV for example).

Preliminary tests show much better performance compared to the first Crazyradio and Crazyflie both indoor and outdoor. So far, we mesured a stable link two floors down about 20m away indoor and about 150m outside range (the uplink has been tested up to 450m). Of course we are continuing to work on it and final specs will come later.

As for the radio dongle mechanic we have changed nothing: the connectors and LEDs are still at the same place. This was made possible by using smaller SMD components and so existing 3D-printed cases for Crazyradio still work for Crazyradio PA.

While designing the Crazyflie 2.0 one of our focuses has been enhancing the current Crazyflie functionality. As a flying development kit the current Crazyflie already has a JTAG debug port that allows to flash and debug the STM32F1 microcontroller. The design uses a standard ARM 10-pins cortex debug connector. The connector is shipped with the Crazyflie control board, but it is not soldered. So before doing any advanced debugging with the Crazyflie the user will have to solder the debug connector (it is always possible to flash new firmware using the radio bootloader).

With Crazyflie 2.0 we wanted to make it easier to debug it out-of-the-box, without needing to solder. But the issue is that standard debug-connectors tend to be fairly large, so to fit the connector on the board we used a different connector that connects to an adapter board.

Aside from having a reset button, the adapter board will have 3 JTAG/SWD connectors:

  • 20-Pins HE10 ARM JTAG with 2.54mm spacing: The most commonly used connector
  • 10-Pins ARM Cortex with 1.27mm spacing: Used in some modern ARM board, the same as the current Crazyflie
  • 6-Pins SWV with 2.54mm spacing: Compatible with the connector present on ST Discovery boards

The smaller 6-pin connector connects to the Crazyflie 2.0 for flashing and debugging of its 2 MCUs: The STM32F405 and nRF51822. The connector for debugging the STM32F4 is mounted on the Crazyflie 2.0. For the nRF51 we are still working to get a solder-free solution using the same cable/connector on the debug-adapter. Why not just put two connectors, or one big with all the signals on the Crazyflie? There’s just no more space on the board. The connector looks very small, but when you bring the footprint into KiCad it’s like parking a minivan in your bedroom :-)

Since all the connectors are wired together the board can also be used in a number of other combinations, like using it as a 20-pin to 10-pin Cortex JTAG adapter or any other combination of its connectors.

Early on in the Crazyflie 2.0 design we decided on using a double-MCU architecture. The main reason for this was to add Bluetooth low energy (BLE) to the platform to permit new use-cases like controlling the Crazyflie 2.0 directly from a mobile device. It just so happens that Nordic semiconductor some time ago released a chip that perfectly matched our requirement: the nRF51822 can run a BLE stack and is still compatible with the nRF24Lx1 that we are using in the current Crazyflie and Crazyradio. This nRF51 chip contains an ARM Cortex-M0 microcontroller, powerful enough to implement the radio functionality and power management, but not powerful enough to run a fully featured Crazyflie. The resulting system architecture can be seen here:

Crazyflie 2.0 system architecture


The nRF51822

The two main tasks for the nRF51 is to handle the radio communication and the power management. We use the radio for both CRTP and BLE, but the hardware also supports other protocols like ANT. The CRTP mode is compatible with the Crazyradio USB dongle and it provides a 2Mbit/seconds data link with low latency. Our initial tests of the Crazyflie 2.0 implementation shows that the latency of the radio link is between 360us and 1.26ms, at 2Mbps without retry and a packet size of respectively 1 and 32 bytes. The main benefit of the CRTP link with the Crazyradio is that it’s easily implemented on any system that supports USB host which, makes it the first choice to hack and experiment with the Crazyflie. To that we have added BLE, mostly with the use case of controlling the Crazyflie 2.0 from a mobile device. The idea is of course to be able to fly easily and on the go with BLE, but we also see lots of opportunities for fun hacks and experimentation with mobile devices. One idea we came up with is to be able to place the mobile device up-side-down on a table and to autonomously hover the Crazyflie above it using the camera on the back.

One of the other particularities of the nRF51 chip is that it was designed to run from a coin battery, which means that it is pretty well suited for low energy operation. So we decided to give the nRF51 the responsibility for power management as well. In the current version of the Crazyflie we have a small chip handling the ON/OFF button and cutting power to the complete board. On Crazyflie 2.0 the button is connected to one GPIO pin on the nRF51 and power to it will never be cut, it just goes in “power down” mode. This permits to reproduce the current ON/OFF functionality and the button can be used for more function like long press and double click. We have also added the possibility to wake up the system from one of the pins in the expansion connector, which allows wake-up by an external source. It also adds more possibilities like waking up the system at regular time-intervals to perform some function.

The STM32F405

We also updated the main MCU to a fast Cortex-M4 with a lot of memory. The CPU power is not a big limitation in the current Crazyflie, but the memory could become a limitation if users would like to implement new functionality that needs a lot more memory. We ran into this problem when we were trying to implement SD-card support for logging, as this required too big buffers. The new MCU has 196kB of RAM which should be enough for anyone (famous last words…). The MCU power will also allow for more computationally intensive algorithms, the first that comes in mind is sensor fusion between inertial sensors and the GPS data.

This amount of memory and computational power also open the doors for new things: the STM32F4 has a Memory Protection Unit, which allow to run tasks in a protected environment and intercept bugs before they can crash the full Crazyflie control firmware (like what  happens on PC operating system). One use of this could be to to allow for “user code” that runs in a protected environment to allow easier development of advanced behavior. As always this kind of functionality spawns lots of crazy ideas :-) The leading one is to run a Lua interpreter in such a protected task. If there was a good API that could be used from Lua you could imagine lots of fun stuff to do. Like adding a new board with sensors, reading them and then controlling the Crazyflie from that, without having to go into the actual control algorithms or risking to crash the firmware. This is of course still a dream but at some point in the future we will definitely give it a try (when we have the time for it that is :-) ).

Inter-MCU communication

Working with a system with multiple MPU is hard. As embedded system developer we know that, so we designed the Crazyflie 2.0 with at least some idea of how to limit the problems related to debugging two inter-dependent MCUs. We have defined as precisely as possible the responsibility of each MCU, which permits to develop and test things independently:

  • The nRF51 is responsible for
    • ON/OFF logic
    • Enabling power to the rest of the system (STM32, sensors and expansion board)
    • Battery charging management and voltage measurement
    • Master radio bootloader
    • Radio and BLE communication
    • Detect and check installed expansion boards
  • The STM32 is responsible for all the rest, among other things:
    • Sensor reading and motor control
    • Flight control
    • Telemetry (including the battery voltage)
    • Additional user development

The nRF51 will act as slave and the STM32 as master. Using a radio bootloader it will be possible to wirelessly update the firmware for both MCUs.

We will write more details and post photos in the following weeks. Do not hesitate to tell us what you think about it, we appreciate all the feedback we get and we already have a couple of verification that we made after previous feedback (ie. radio latency and magnetometer usability).

A couple of weeks ago we found the NeoPixel ring from Adafruit at a local shop, we had to attach this neat board to our copter and see what cool effect we could make with it. The ring has 16 RGB LEDs that can be driven independently with only one data wire. The LEDs the Neopixel contains are called WS2812.

This post is describing the development of a WS2812 driver for the Crazyflie. A later post will show the usage we did of it (fairly limited in comparison of the seemingly endless possibility, as usual we have more ideas than time to execute them :-).

The WS2812 LED

First of all we needed to see how to control the LEDs. The protocol used by the WS2812 is quite simple but special. All LED on the ring have a data input and a data output pin in a chained manner. Colors of the LED is send over the Data line to the first LED that will save it internally. When sending a second color the first LED will send the saved color to the second LED. And so on, by sending 16 color data we can set the color of all LEDs of the ring independently. Colors are sent as 24 bits (8 bits per component).

Up to there nothing is really peculiar, the system is pretty neat and allows to control a lot of LEDs with just one IO. The problems comes with the Bit encoding:

ws2812_format

Bits are encoded with pulse width: a short pulse means 0 and a long pulse means 1. The bitrate is of about 800KHz and the tolerances on bit timing is pretty tight. As there is no hardware peripheral dedicated for this (on common microcontrollers), this bitstream needs to be implemented either by bit-banging or by being a bit creative with the peripheral we actually have at our disposal.

Driver implementation

Adafruit did implement a driver for the WS2812 for Arduino, this is a software implementation that uses the CPU to implement the signal. However at that bitrate a software/bit-bang implementation have to be timed carefully and the easiest for that is actually to implement it in assembler. Arduino runs on an AVR processor and these processor are very predictable: each instruction runs in a specified number of clock cycle which makes it possible to implement a timed loop like the one of Adafruit. However this becomes impractical on bigger CPU that implements caches and other optimization that makes it really hard to predict how much cycle each instruction will take.

The Crazyflie runs a STM32F103 based on an ARM Cortex-M3. This is just complex enough to make the ASM-timed loop impractical: The CPU core runs at 72MHz but the flash is slower so a simple cache memory is inserted in the middle and depending of the state of this cache it may take from 1 to 3 cycles to execute an instruction. There is an even bigger problem: a CPU timed loop requires to stop all interrupt and to have the CPU running exclusively on updating the WS2812. We cannot allow that on the Crazyflie that require a 250Hz control loop to stay (controllably) airborne.

We asked Google to see if someone already came with a solution and actually someone did. The Elia’s Electronics Blog posted a neat, well documented, solution using the STM32 Pulse Width Modulation (PWM) capabilities of the STM32 to generate signals that the WS2812 understands. All we needed was a timer/pwm output then. It happens that we have one timer1 output on the Crazyflie extension port:

crazyflie_neopixelring

This is only 3 wires: VCOM for the battery voltage, GND and the timer output.

I started porting the Elia’s code to the Crazyfle. The only free timer we could easily use was different and much more complex than the one Elia uses. So part of the frustrating implementation was to figure out WHY the signal was looking weird on the scope! Finally after an hour or so the code was working:

IMG_20140411_202251

Enhancements

Now that was not quite enough. The driver is using the PWM to generate the 1’s and 0’s pulse width and the DMA is used to feed the bit width independently of the CPU (so that it can do something else, like controlling the copter attitude…). It requires all the 16 LEDs data to be written in the memory buffer before starting the DMA. Each LED has 24 bits color data and each bit will be encoded as 16bit pulse length for the timer. It means that the full ring will take 768Bytes in RAM. It sounds small but its a bit too much for us and, most importantly, it does not scale: if we want a second ring the ram requirement will double.

To fix this I implemented two things: An easy one is that the DMA can do some type conversion and one of these is that it can read 8 bit in memory and write 16 bit in the peripheral. This allows to store only 8 bits pulse width in memory and so divides by 2 the memory requirement, but it still doesn’t scale.

The fix to scaling is double buffering. The STM32F103 does not implement DMA double buffering as such but what it has is close enough: circular DMA with half-transfer interrupt. The idea is to load the 2 first LED in a buffer and to start the DMA for 42 bytes in circular mode. When the DMA has transferred the first LED it triggers the half-transfers interrupt which allows the CPU to replace the first LED data by the 3rd. When the 2nd LED is transferred the transfer-complete interrupt is triggered by the DMA and the CPU fills in the 4th LED in place of the 2nd one. The DMA roll-over at the beginning of the buffer and sends what is now the 3rd LED data. This continues until all the LEDs has been  sent. This solution scales: it requires a 42 bytes buffer for as many LED as we want!

Conclusion

All that process was not really simple. However the result is simple, now the only thing required to control a Neopixel ring in the Crazyflie is:

 

#define BLACK {0x00, 0x00, 0x00}</span>
static uint8_t color[][3] = {{40, 40, 40}, {32, 32, 32}, {16,16,16}, {8,8,8},
                             {4,4,4}, {2,2,2}, {1,1,1}, BLACK,
                             BLACK, BLACK, BLACK, BLACK,
                             BLACK, BLACK, BLACK, BLACK,
                            };

/* ... */
ws2812Send(color, 16);

And it will run nicely without interrupting other tasks like control and communication. Replace 16 by 32 to control 2 Neopixel rings. The current implementation has been pushed in the crazyflie-firmware neopixel_dev branch (still require some clean-ups!). Actual implementation is in ws2812.c and neopixelring.c.

neopixel_flying

The only problem left is not software: At the end of the battery life, the voltage is not enough to fully lit the blue LED. That make all white look orange-ish. The only way to fix this problem would be to step-up the battery voltage higher then the forward voltage of the blue LED. Though it works well enough without that.

Stay tuned for a following post about actual usage of the ring.

Most of last week was spent at the Devoxx France conference in Paris. Even though we didn’t have our talk until the end of the week, we hung around most of the time just developing and working. And of course we also got the chance to meet lots of interesting people and demo the Crazyflie. We worked on some code for the NeoPixel ring from Adafruit, implementing some different effects. We also did a quick hack to be able to change effects when flying using the Leap Motion. Since we haven’t had any time to prepare videos/photos of it and to clean up the code, we will post more about that next week.

We also got a chance to do some other fun things, like flying the FPV Crazyflie over the crowd at one of the keynotes and also record some video while flying though the conference.

 

[pe2-gallery album=”http://picasaweb.google.com/data/feed/base/user/115721472821530986219/albumid/6002584693333310545?alt=rss&hl=en_US&kind=photo” ]

A couple of weeks ago we attached a uBlox MAX-7 GPS module to the Crazyflie (blog post). Back then it was mostly a proof of concept, all we did was to re-route the raw GPS data (in text NMEA format) directly to the PC using the Crazyflie text console port. This allowed us to quickly prove that a GPS can work on the Crazyflie but was not that useful and efficient: the copter did not decode the gps position and a lot of radio bandwidth was used. Last Friday we decided to fix it and to make it clean(er).

The ultimate goal was to measure the Crazyflie speed, if it wasn’t for the rain we could have done the measurement! Anyway, this work allowed us to exercise the debug functionality of the Crazyflie platform and so to see the strength of it but also what needs to be enhanced. In this post we will try to document (at high level) the steps taken to implement the GPS in the Crazyflie. The source code is pushed in the crazyflie firmware and python-client git repos. The Python client code is in the master branch and the firmware code in the gpu_ublox_dev branch (dev branch means that the code is far from final/clean, but it works!).

Electronically the GPS is connected using only 4 pins: VCC, GND, serial RX and serial TX. The serial port is connected to pins 3 and 5 of the expansion header. The power is connected to VCC.

crazyflie-ublox

The electronic was already tested and working so we had 2 tasks left:

  • Decoding the GPS information in the firmware and creating log variables to make the data available for the PC software
  • Updating the GPS tab of the PC software to fetch GPS data from the log subsystem instead of parsing it from the text console

It happens that these two tasks could be done mostly independently and Marcus and I started to work in parallel. The only thing we had to agree upon was which log variable and what scaling to use for the variables. We used the format that the GPS chip is already using which made things easier.

Firmware

For the firmware part, the first step was to acquire the GPS data. GPS chips usually can talk two languages: the standard text-based NMEA and some kind of proprietary binary format, UBX for uBlox. I chose the binary format as it is a lot easier use in C: no text parsing has to be done, all data dirrectly fits in a C structure. But first the GPS has to be setup to output data in binary modes and to output the data we were interested in. To quickly setup the GPS I used a tool that uBlox provides and that permits to generate proper UBX messages:

u-center_msg

Two UBX messages where required: One to disable NMEA output and one to enable the NAV-PVP message which contains basically all data you would want from a GPS (position, speed, date and the accuracy). Once this is sent to the GPS chip it starts to send a NAV-PVP UBX packet once a second. Then, the GPS acquisition loop in the Crazyflie (currently implemented in the UART task, so it has to be moved into a proper driver) just has to wait for an UBX packet, read it and if it is a NAV-PVT packet then extract values from it. The GPX code has been tested on PC using another uBlox receiver connected to a USB serial cable. Then after copying the newly added uartReceiveUbx() function  into the Crazyflie firmware, the GPS acquisition loop looks like this:

  while(1)
  {
    uartReceiveUbx(&msg, 100);

    if (msg.class_id == NAV_PVT) {
      gps_fixType = msg.nav_pvt->fixType;
      gps_lat = msg.nav_pvt->lat;
      gps_lon = msg.nav_pvt->lon;
      gps_hMSL = msg.nav_pvt->hMSL;
      gps_hAcc = msg.nav_pvt->hAcc;
      gps_gSpeed = msg.nav_pvt->gSpeed;
      gps_heading = msg.nav_pvt->heading;
    }

    ledseqRun(LED_GREEN, seq_linkup);
  }

The last thing, to make the data available from the PC, is to add a GPS log block and to add variables to it:

LOG_GROUP_START(gps)
LOG_ADD(LOG_UINT8, fixType, &gps_fixType)
LOG_ADD(LOG_INT32, lat, &gps_lat)
LOG_ADD(LOG_INT32, lon, &gps_lon)
LOG_ADD(LOG_INT32, hMSL, &gps_hMSL)
LOG_ADD(LOG_UINT32, hAcc, &gps_hAcc)
LOG_ADD(LOG_INT32, gSpeed, &gps_gSpeed)
LOG_ADD(LOG_INT32, heading, &gps_heading)
LOG_GROUP_STOP(gps)

Debugging the firmware code can be done using the client log plotter tab, not so nice to look at positioning but good enough to see if it is working (when the accuracy, gps.hAcc,  goes down the GPS has a fix!):

gps_graph_fix

Client

Once the log block was decided, Marcus could start the client development by updating the debug driver. The debug link is a module of the Python client that behaves like a CRTP (the Crazyflie protocol) link but is in fact just some software running offline. It allows to easily develop and debug the client without requiring the usage of a Crazyflie. The debug link was modified to include all variable that the Crazyflie would eventually contain and to give them some value that can be logged.

When this was done, the GPS tab has to be updated to display actual values, a max speed and reset button is also added (the idea was to measure the Crazyflie speed). After fighting more than expected with the QT layouts the result is good enough:

vm-gps-debug

Note that the client uses the Python binding of KDE Marble which has to be compiled manually. Only Marcus has had the courage to do that on his computer, but luckily he also compiled it on the latest Bitcraze VM so that we can all easily enjoy the new GPS tab :).

Merge

Now that the client and the firmware are made separately we ‘just’ have to connect the new client to the new firmware. And guess what? it worked the first time :-) (Yes I know you have no reason to believe me but this time it really worked the first time).

Unfortunately for us last Friday was one of these Swedish rainy day, all we could do was to take turns to stand in the middle of the road outside of our office, in the rain, holding the Crazyflie in a plastic bag and waiting for the GPS to get a fix (people passing by were looking quite strangely at us …). It happens that the rain where not helping at all! And the fact that we don’t have assisted-GPS (yet) means that the GPS would get a fix in 40sec best case, it took about 5-10minutes for us. But eventually we got the fix:

gps-test-fix

Conclusion

One thing we have to work on is the modularity of the firmware. Things like having a clear and easy to use HAL for peripherals on the extension port. It is on our ToDo list and it would have been useful here to do a cleaner job with the firmware implementation. A good thing is that while this implementation is uBlox specific for the firmware part, it is completely hardware-independent on the client side. It means that it is possible to implement any kind of positioning, with other GPS chip or other technology, and as long as this positioning declares the right log variable the client will work with it unmodified.

As for the GPS, uploading assistance data to the Crazyflie would permit to drastically reduce the fix time to about 10-15sec. Also this GPS is capable of 10Hz update rate which would be nice to test. The GPS on a Crazyflie is still mostly a proof-of-concept and is of course not useful for indoor flight. Though with light winds the Crazyflie is pretty capable outdoor, so with GPS capability it could be interesting to experiment a bit with trajectory planing. Of course this is even more true for country with a warm and dry weather :-).