Category: Crazyflie

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 while ago we posted a tutorial on how to modify the firmware to add logging/parameters and to plot/modify them from the client. We have done a continuation on this tutorial to show how to modify the client to integrate logging and parameters directly into the UI (like we have done on the flight tab). For the tutorial we use our virtual machine to do the development and running the code. Since we continue on the concepts and design made in the first video, it might be a good idea to see that one first.

 

A while ago I started working on a brushless motor control driver for the Crazyflie. I implemented most of it but did not really have time to test it. Recently we have gotten some request and questions about it so we took some time to do some further testing.

Implementing a brushless motor control driver can be done in many ways. If you have brushlesss motor controllers that can be controlled over I2C that could have been one way but usually the brushless motor controller (BLMC) take a PWM input. This is most commonly a square wave with a period of 20ms and a pulse width of 1-2 ms high, were 1 ms is 0%, and 2 ms is 100%. A period of 20 ms means a frequency of 50Hz. This is most often a high enough update rate for R/C electronics like servos etc. but when it comes to BLMC that is not the case. Therefore many new BLMC can read a much higher update rate of up to 400 Hz were the pulse still is 1-2 ms high. That way you can match the BLMC input to the update rate of the stabilization control loop and increase stability. In the code we added a define BLMC_PERIOD where this can be set.

To test this we wanted a frame which was quick to setup and found this. It is based of a PCB just like the Crazyflie and has the four motor controllers with it, perfect! The built in BLMC are based on an the Atmel MCU Atmega8 which is very commonly used in the R/C BLMC which means it is possible to re-flash them with the SimonK firmware. This is know to be a great firmware and enables fast PWM update rate etc. So we built and flashed the firmware configured for the tgy6a which is compatible and it worked right away, yay!

Now we only had to connect the Crazyflie to the BLMC:s on the frame. The BLMC electrical interface for the PWM signal is often a 5V interface but the Crazyflie runs on 2.8V. 2.8V would in most cases be treated as an high input and can probably be used directly but there is no simple way to connect this signal on the Crazyflie. Instead one way is to use the existing motor connectors and the pull-down capability that is already there. Then it is also possible to pull this signal to 5V with a resistor to get a 5V interface so this is what we did. To power the Crazyflie we took the connector of an old battery and soldered it the 5V output of the frame.CF to BL Frame connections

Now it was just a matter of testing it! However as size increases so does the potential damage it can make. We therefore took some precaution and tied it down. First we tested the stability on each axis using the stock values and it worked really well so we decided to not tune it further. The only issue was that suddenly one of the BLMC mosfets burnt. We replaced it and it worked again but don’t know why it burnt. Later when we flew it something was still strange so we have to investigate this.

We will upload the code as soon as it has been cleaned up. Please enjoy a short video of the journey :)

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 :-).

A couple of weeks ago we moved into the Malmö based business incubator Minc. It’s a great chance to get some extra help developing Bitcraze and also to get a chance to meet people from other start-ups. Below is a picture of a bunch of Crazyflies in our lab (i.e the table designated lab).

Bitcraze Lab

On a more technical note, here’s a video of a blimp that was hacked together with some left over party-balloons and a broken Crazyflie that we had lying around. It’s the day after the party, so there wasn’t that much lift left in the balloons (that’s why we have a bunch of them). After a few hacks to the firmware it actually works pretty well! The motors power has been redistributed and only the Yaw regulation is active, which explains that the yaw is still pretty stable, we are thinking about pushing the ‘blimp-mode’ at some point (first we will need more balloons and Helium though :) ).

We have released version 0.5 of the Bitcraze Virtual Machine and version 0.3 of the Raspberry Pi image.

Here are some of the changes for Bitcraze VM 0.5:

  • Upgraded all Ubuntu Packages
  • Installed custom build of KDE Marble with Python bindings
  • Installed PyQtGraph
  • Installed Oracle Java JRE (needed for PyCharm)
  • Installed PyCharm Community Edition 3.1
  • Installed KiCad from repo (using build script, but excluding documentation) to add support for all of our projects in their new format
  • Installed EmbSys RegViewer plugin for Eclipse
  • Replace old BitBucket repos with new GitHub repos and updated the “Update all repos” script
  • Decreased image size (Even with all the new stuff this new version is smaller than the previous)

The full Bitcraze VM 0.5 changelog is available here and the files are available as direct download or as torrent.

Here are some of the changes for the Raspberry Pi image 0.3:

  • Moved configuration files in the fat partition: It is now possible to configure radio link and inputdevice mapping easily from windows/linux/mac. See crazyflie folder.
  • Upgraded all packages
  • Replace old BitBucket repos with new GitHub repos and updated to the latest versions
  • Updated the README.txt with information on how to flash the Crazyflie/Crazyradio from the Raspberry Pi
  • Image size increased from 2GB to 4GB

The full Raspberry Pi image 0.3 changelog is available here and the files is available as direct download or as torrent.

 

Finally after some issues and lots of interruptions we made the move to GitHub. We will keep the BitBucket repos (but as read-only) since there’s lots of inbound links for code and issues.

If you are interested in doing the same move here’s what we did.

Create the reposiory on GitHub, then pull in Mercurial project from BitBucket into a local git repos using git-remote-hg:

git clone hg::https://bitbucket.org/bitcraze/crazyflie-firmware

The new github repos can then be added to the local git. Tags and branches can then be pushed to github. As Mercurial and Git have very different way to handle branches you will have to chose which branch to push and push them manually (we did not find any way to push all at once and we did not want to push all the branches anyway…):

cd crazyflie-firmware
git remote add github git@github.com:bitcraze/crazyflie-firmware.git
git push github master
#Pushing tags
git push --tags github
# Tracking and pushing all interesting branches
git branch --track 2014.01 origin/branches/2014.01
git push github 2014.01
git branch --track gps_ublox_dev origin/branches/gps_ublox_dev
git push github gps_ublox_dev

 

Copying the issues from BitBucket to GitHub can be done using this script. It takes the source user/repo and destination user/repo as arguments. Keep in mind that GitHub doesn’t have the same metadata as BitBucket does. So there’s a JSON file where you set up the mapping between BitBucket kind/status/priority/component and GitHub labels. In this you can set up zero to multiple labels. If a mapping for components is missing then a label with the same name is used. Milestones on BitBucket is mapped 1:1 to GitHub. The needed labels and milestones will be created as they are used while copying the issues.

If you are copying issues to an organization repository you will have to use a GitHub API token for identification, since you cannot log in using the organization username. Here’s an example for what we did for the Crazyflie python clients:

#Migrating tickets from Bitbucket to Github
python migrate.py -g bitcraze -d crazyflie-clients-python -u bitcraze -s crazyflie-pc-client -k your_api_token_here

Two tips: Create a new user that does the migration (like bitcraze-issue-importer) and make sure that you haven’t created any issues in the target repositories before the migration. If you don’t have any issues before then the number will match and all the references will work out of the box (from commit messages and other issues).

To show the functionality in the logging and parameter frameworks we did a video. It shows how to use the Bitcraze virtual machine to add variables and parameters to the firmware and to flash it using the radio bootloader. It also shows how to visualize the log-data using the plotter and to modify parameters from the client.

While cutting the video we noticed that the temperature goes down when we touch the pressure sensor. Either we are more cold-blooded than we should be or there’s a bug in there somewhere…

Edit: Turns out it not a bug. After some discussions this morning (and testing) we arrived at the conclusion that the measurement was correct. The PCB get’s a bit warm when running/charging and a fingertip isn’t necessarily 37C.

After a week of fixing things for the Crazyflie firmware/software RC (release candidate) we have now tagged and built the final release 2014.01 of the crazyflie PC client and firmware. Last week we listed the changes, but for the final version we also made improvements for the logging and communication. This mostly effects the connection and downloading of TOCs and parameters, which improves the connection reliability.

Screenshoot_2014.01.0

With this release there are some updates to the Python API for the Crazyflie. In order to more easily keep the examples in sync with the API we have added some basic examples in the example folder in the repository. We will also update the wiki with these changes.

To download the new version the links are:

A while back we had a poll about when and how we should release new firmware and software. Since this we are aiming at at least doing a release every 7- 8 weeks of firmware/software that has been updated. So last week we branched and build release candidates of the firmware and the pc client. We will keep the RC until the end of the week or until we think it’s stable enough. During that time we will fix any serious bugs that come up. So if you are up for it download/flash it and give it a try. If you find any issues, don’t hesitate to let us know on the issue tracker (client / Crazyflie firmware).

Here are the files:

Some of the new features include:

  • Client: Playstation 4 controller configuration
  • Client: Improved plotting functionality (using PyQtGraph)
  • Client: Improved logging functionality (UI and logging to file)
  • Client: Added credits tab for Crazyflie PC client
  • Client: Updated API for logging and crazyflie
  • Client: Application icon added
  • Client: Fixed bug that prevented using Crazyradio/pyusb if the software “gopro studio” was installed
  • Client: Various bugfixes
  • Firmware: A couple of new default log variables (acceleration, magnetometer)
  • Firmware: Fix of the pitch/roll/yaw calculation: it is now correct all around roll.

We are also working on a Mac OSX release of the client using py2app. It’s not something that we have done before, but hopefully it will be ready by the next planned release (before 2014.03).

Last week we had a poll about moving to GitHub. For once there was a clear message from a poll, Move to GitHub! So after this release we will make the move. We will move things over gradually and in the move we will most likely make some structural changes as well, like splitting up the PC client and API into different repositories.

The last couple of weeks we have tried to become a bit more active on twitter (@bitcraze_se) and we will keep writing about smaller and bigger things that’s happening at Bitcraze. So if you are interested in keeping up to date this is a good source of info.