Blog

Last Saturday it was Arduino day 2015 and it happens that the Arduino office in Sweden is in the same building as ours. So we where invited and presented Crazyflie. It was a really fun event with a lot of interesting people passing  by and we had a lot of fun.

Arduino day 2015

There was also Helium balloon, which gave us a perfect occasion to use the blimp hack we did more than a year ago. We attached a brunch of ‘Arduino colored’ balloon to it and flew it around using the Deviation TX. It is definitly something we have to port to Crazyflie 2.o.

blimp_scaled

Finally as the event was hosted by Arduino, and we do not have Arduino compatibility (yet … ; ), we thought we would make something with Arduino and present it. We ended up making a Crazyflie Controller using an Arduino and using a thumb stick and ultrasonic distance sensor that was lying around the office. We attached everything to a glove to make it a ‘wearable’ controller.

arduino_glove

 

 

glove_action glove_closeup

The glove is working as follow: you place your hand over a hard surface (concrete floor or table), click the thumb-stick button to set the zero and from now-on rising the hand higher will increase the Crazyflie thrust. Then the thumb-stick can be used to steer the Crazyflie. The program is quite simple and implemented in a single loop.

Technically the most work has been put in enabling the serial port of the Crazyradio so that the Arduino can send commands to the Crazyflie using the Crazyradio directly without a computer. As there is a lot of pins available on Crazyradio and a voltage regulator capable of accepting up to ~16V, the aim has always been to be able to use it as a radio module for other system. Our first thought was PPM input, but now serial control will also be possible. We are still cleaning up the code and working on other new functionality on the Crazyradio. We plan to release a new firmware soon that will support PPM, UART and a more efficient USB protocol to communicate with many Crazyflies using one radio dongle.

As many out there think is is more fun to fly the Crazyflie rather then develop upon it (like we do :-)) we have quickly looked at ways to pilot it with a RC transmitter. This forum thread is a good starting point for a developer discussion. To summarize it a bit there are many ways of implementing it which all require more or less development and has different pros/cons

  • Attach the Crazyradio PA to the expansion module/port of an RC transmitter.
  • Implement the E-Sky transmitter protocol or other nRF24L01+ protocols in the nRF51.
  • Using the DeviationTx code and a nRF24L01+ module.
  • Attaching a RC receiver to the deck (expansion port) interface.

Today I will write a bit more about the DeviationTx as it is a great open source project and that it has support for the Crazyflie. It was over a year ago we got contacted by Victor who wanted to implement the Crazyflie protocol in the DeviationTx code base, which he did pretty quickly. We feel ashamed for taking so long to try it out. So during the weekend I freed up some time and gave it a shot. The DeviationTx project replaces the firmware in Walkera transmitters with a better one which has the possibility to support a great amount of RC models. However many of them use different transceivers modules so this must be added to the hardware. Well a bit of hardware hacking is always fun and we had a nRF24L01+PA module laying around. They have a module installation document but I found it easier follow this guide as I had the same type of module and transmitter (Devo7e).

devo7e nRF24L01 module

The module installation was done pretty quickly but what took time was to update the firmware. The instructions tells one to download the walkera update tool but I just couldn’t find it on their website, nor the original walkera devo7e firmware (which they recommend to test with first). Thankfully I could find one using google and ended up using this link. Next thing was to fire up a windows 7 virtual machine to install it in which it worked without problems. So did the flashing of the DeviationTx firmware, I flashed the nightly build 4.0.1 and copying the file system according to the instructions. What I forgot though was to edit the hardware.ini file to enable the module which I understood when the protocol selection had a star in front of the name <*CFlie> (OK, I admit, I thought the hardware wasn’t working at first…). Then I setup a new model using the <CFlie> and I used the Fixed ID to setup the address, The data rate and channel are combined in the fixed id using channel as lowest two decimal digits and the rate the first were 0, 1, and 2 for 250kbit/s, 1Mbit/s, and 2Mbit/s respectively. So channel 80 on 2Mbit/s is encoded as 280 and channel 80 on 250kbit/s as 80.

And boy I was happy when I saw the green led (radio com led) blink on the Crazyflie 2.0, but nothing happened when I pushed the trust… Then I remembered, we recently implemented a lock so that a zero thrust must be sent at least once for it to unlock (to prevent Crazyflie to fly away if the gamepad is not setup correctly and constantly sends 100% thrust :). Looking into the source code one could see the trust was at minimum 5535 which was never unlocking the thrust. Removing this lock in the Crayflie 2.0 firmware and it was flying! but in plus mode… The Deviation cflie module code seem to rotate the pitch/roll setpoints.

Next step will be to do some modifications to the Deviation cflie module for Crazyflie 2.0, adding code to unlock the thrust and disabling the axis rotation, then make a pull request to the DeviationTx project for everyone to enjoy.

A big thanks to the DeviationTx project and to Victor for the cflie module implementation! Ohh, and by the way, they are making a universialTx module that will support almost any RC model out there, including Crazyflie, can’t wait to see that.

While digging around in our office looking for a board we found a piezo buzzer we bought a while back. The reason for buying it was to test some buzzer functionality to the Crazyflie 2.0, but we forgot about it. But now that we found it again we got to work :-) We documented the build in our hacks section on the wiki, but here’s a quick run down.

  • Get a piezo buzzer and a Crazyflie 2.0 prototype deck
  • Solder it to the RX2/TX2 pins (pinout)
  • Clone and build custom firmware (dev-buzzer branch)
  • Play around with the parameters in the buzzer group
    • Set buzzer.effect for different effects
    • Set buzzer.melody for different melodies (with buzzer.effect = 2)

If you want to add new melodies or effects, have a look in the modules/src/buzzer.c file :-)

Here’s a Vine with the result (enabling sound is a good idea :-) )

On a side note Seeedstudio will start shipping out the CCW propeller replacements this week. If you still haven’t filled in the replacement form it’s not too late, here’s the form.

Lately we have merged a new input subsystem to the Crazyflie python client, it allows for more flexible input configuration like connecting more than one gamepad in training mode, or having external input like the LeapMotion appear as standard input. To test the flexibility of the new input system, on Friday, we implemented a ØMQ input driverØMQ is a library that permits to easily transmit messages between program. It is high speed, low latency and extremely easy to use. It has binding and implementation for a lot of programming language, which opens Crazyflie control to a lot more people and application.

The way it currently work is: You connect the graphical Crazyflie client and select ZMQ as input device. You connect the ØMQ socket and send json to it containing pitch/roll/yaw/thrust. And voila, you are controlling Crazyflie from your own program.

We just got a Kinect 2 and started playing around with it, suddenly the new ØMQ control became very useful. We already worked with the kinect long time ago so we had control code from back then. Also we wanted to quickly do a proof of concept so we started working with the Microsoft SDK to see what is possible, we are going to use libfreenect2 on Linux later. Finally we know how hard it was to control the thrust so we wanted a way to test pitch/roll first as a proof of concept. At the end of the day we ended up with this architecture in the office:

zmq_kinekt

The C++ implementation in visual studio detects the Crazyflie and sends coordinate to the Controller python script. The controller script is a stripped down version of or previous kinect experiment and only runs PID control loops to control pitch and roll, trying to keep Crazyflie at a fixed coordinate in space. Finally the Crazyflie client is setup in training mode with ZMQ handling pitch and roll and the gamepad handling thust and yaw. The gamepad can take-over completely in case of problem.

Thanks to ZMQ resiliance we can stop any part of the system and start it again, the connections automagically reappears. So we ended up with the following workflow:

  • Fly in the Kinect detection area
  • hand-over pitch/roll to the controller loop
  • When the Crazyflie starts oscillating or going away, take over control and land
  • Stop controller, modify things, restart

This was quite painless and nice. We ended-up connecting together very different systems and they just worked. We got so interested by the experiment that we now have a full ZMQ Crazyflie server on the work that would allow other program to do what is possible with the standard Crazyflie API: scan for Crazyflie, connect, read and write log and params.

 

Some time ago we decided that it would be nice to have a name for the Crazyflie expansion boards, a bit like the Arduino shields or the Beagle bone capes. We organized a poll on our website, that ended with cheating so we organized a local vote and flykit won. In second place was the deck. Over time we started liking deck more and more since it fits better with the actual look of the boards. Finally we pushed ourselves to decide on one and we went with deck. This comes from the naming of floor in ships, planes and (more importantly) space ships. We also though we could write a bit about the Crazyflie 2.0 expantion capabilities and the deck architecture. In this post we are forcing ourselves to say deck instead of expansion port, lets see how it goes :-).

On Crazyflie 2.0 decks can be installed both on top and bottom. Each deck we make has a symbol indicating its correct orientation:

deck_conf  Expansion board orientation

 

Lots of signals and functionality has been routed from the Crazyflie 2.0 to the deck port:

Connector_multiplexing

 

The OW pin is used to connect a One Wire memory with a specific data format, this allows Crazyflie 2.0 to know which board is connected and to activate automatically the right driver, so this is kind of plug-and-play. This is currently used to enable the LED ring deck driver. The aim is to develop an API that will allow anyone to easily create decks that would be automatically detected by Crazyflie.

The deck architecture opens lots of possibility. We’ve already made the LED ring that faces down, but it would be possible to make one that faces up as well. In the future we hope to have have ground facing camera, GPS boards, Camera boards. And more than one can be installed at the same time. We also investigate doing bigger expansion board for example to have Crazyflie acting as the brain for a bigger quad.

On the firmware front, we are finishing the merge of Crazyflie 1 and Crazyflie 2 firmware. Currently the source code for Crazyflie 1 and Crazyflie 2 is on two different branches which makes it harder to maintain both of them. We have come so far that we have a working merge that can compile and fly either for CF1 or for CF2. There are loots of cleaning up to be done before it can be pushed though but we are giving a heads up as the changes will affect forks that are doing rebase as well as pull requests.

When the schools closed for vacation last week Minc (the company accelerator where we have our office) hosted a “bring-your-children-to-work” day. The original idea came from Fredrik who works at the Swedish Arduino office (in the same building as us). One of the goals whas to let children see cool technology and to get a chance to try it out. We quickly jumped on this since we thought it would be fun for the children to fly. But we realized there was a bit of a safety problem letting Crazyflies go wild all around the place. So we dug up an old idea we had been discussing (yes, there’s lots of those..), the input-device MUX.

The idea is to allow combinations of input-devices to work together at the same time. There’s a couple of use-cases for this that we have been discussing in the past, like combining Kinect with a controller so you can take control if you loose tracking. But the most obvious one is a “learning” mode, where you could control roll/pitch from one device and thrust/yaw from another. Or having the possibility to take over control “on-the-fly” (no pun intended…) from one device to another. For us it makes it a lot easier to give a controller to people and say “Try it out!” if we can take over control just in case things start going bad.

So we started hacking around a bit and got it working, but there’s still lots of work to be done. We revised the architecture a bit for the input-device layer in the Crazyflie Python client from what we posted before. The main change is the multiplexer, which enables the user to open multiple input-devices at the same time and combine them. The other change is to connect other devices “higher-up” in the architecture, like the Leapmotion. Instead of connecting it as an input-device with a mapping, it is connected directly to the MUX and will give well scaled values for controlling. The same goes for other devices such as the Kinect and network connections (which would allow to control Crazyflie throw the client from any other software).

input-arch-mux

 

The hardest part will not be to code this, it will be to design the UI and configuration of this functionality. We have some sketches, but any ideas are welcome! In its current state you just select a MUX, then the devices that you want to use (master first, then slave). But there’s no way of configuring what values are taken from what device.

Check out this album to see a few photos from the “bring-your-children-to-work” day!

We have finally managed together with Seeedstudio to improve the CCW propellers and to setup a process to acquire a free set of CCW replacement props. As continuing from this post we have discovered that many of the CCW propellers from the first batch of Crazyflie 2.0 where a bit too unbalanced. Too be a bit more technical the tolerance distribution for the CCW propellers was a bit offset, so instead of the majority being decently balanced, many where unbalanced and needed balancing. This is not really a big issue and can pretty easily be corrected by balancing them with some tape according to this guide and we still recommend them to be balanced to get the best flight performance. We however think there where to many unbalanced propellers so we offer every one that bought a Crazyflie 2.0 kit from the first batch a free set of CCW propellers including shipping from China. To acquire a free set of CCW propellers please fill in this form.

Propeller guy

Finally here is the last, and probably most interesting part of the “Measuring propeller RPM” series, see part 1 and part 2 to catch up. Now it is time to gather some data and display what we get.

As described in part 2 we are now able to measure each propeller RPM with the expansion board we made and with the code we added. This can, as been described in part 2, be logged to a csv file using the cfclient. Next thing would be to do something useful with it. To do that we use Octave (very similar to Matlab but open source). The first thing that could be interesting to know is the step response for a  motor and propeller. This was acquired by altering the Crazyflie 2.0 firmware a bit to do a step from zero to max trust and then to zero again. It was done on M1 with a fully charged battery.

M1 step response

 

The motor goes from zero to 25k rpm in about 180ms, quite impressive. What is also interesting is that the falling slope in the range 15k to 20k rpm is quite similar to the rising slope in the same region. The inertia of the turning parts of the motor and the propeller is quite low so this energy will quickly be consumed when the motor and propeller starts to coast. This is good as it will lead to better maneuverability.

 

 

 

cf2 thrust fixtureKnowing the RPM is great but it is the thrust that is most interesting. So to get this we need a rig where we can measure it. We made one out of a bottle to which we glued a prototype board on that we put on a scale, not a perfect rig but simple and probably good enough. Then we made a program that ramped up the PWM from 0% to 93.75% in 16 steps with stabilization disabled. We also connected the Crazyflie 2.0 to a power box where we could measure the current. The program would increase the thrust in 16 steps and during each step we took a reading of the thrust and current. The RPM, voltage and PWM was logged over the cfclient at the same time. Some manual work was needed afterwards to correlate the data and get it into a table. While in the table a lot of interesting plots could be graphed.

rpm and thrustThe first one would be the rpm and thrust as this transfer function is interesting. By using the Octave polyfit function the second order fit could be found. It is a pretty accurate fit and with this fit it is easier to get the thrust, as the rpm is the only variable needed, which is easier to measure. The fitting function returned by polyfit is:

Thrust (in gram) = 1.0942e-07*rpm² – 2.1059e-04*rpm + 0.15417.

 

 

 

Here is a combined plot of some other interesting parameters. Notice that the voltage graph is ~quadratic, the current ~square-root and the power linear. From the power graph one can find out that the thrust efficiency is about 3.8 gram/W. Not super good but pretty good for a quad of the Crazyflie 2.0 size.

thrust_v_a_w_rpm_tight

Another interesting graph is the graph of the flight time. Since we know the power consumption and the battery characteristics we can plot a graph of an estimated flight time depending on the battery size. This graph makes the assumption the battery capacity per weight is 32mAh/g.

flighttime_capacity

And finally the transfer function we set out to find, the PWM to thrust. The problem with this is that motors are controlled by voltage (PWM) and the voltage comes from the battery, which varies with the power taken from the battery due to internal resistance. Therefor we made two fitting functions, one based on measured battery voltage while applying PWM, and one based on the PWM. Looking at the graph one interesting thing is that the polyfit is making a better fit (red curve) for the PWM. I would have expected the opposite. Something that we will have to investigate further. Or maybe one of our readers have the answer?

pwm_to_thrust

On the wiki we will update this analysis with some more details and the raw data so if you are interested please have a look! Hopefully using this information we can make the Crazyflie 2.0 fly even better.

On the news side there is a new version of the Android client available on Google play, thanks Fred! Also Fred has uploaded the slides of his Crazyflie lightning talk at Fosdem 2015.

We finally got some time to follow up on the previous blog post Measuring propeller RPM: Part 1. In this post we will continue where we left of and describe a little about the software we have implemented.

The sensor output, as showed in the scope picture, can be connected directly to a digital input. We connected them to the expansion port signals TX2, RX2, IO2 and IO3 as they are all internally connected to a timer with capture capability, TIM5_CH3, TIM5_CH4, TIM3_CH2, TIM3_CH1 respectively. With the capture functionality it is possible to trigger a timer read on events like a pin change. Thus it is not that difficult to calculate the period time of the input signal which can be used to calculate the rpm. Setting up the timer to run at 1us tick was a bit tricky but manageable. With 1us tick it will wrap around, it’s a 16 bit timer, so after 1us * 65536 = 65.5ms. This means the slowest rpm that can be measured is about 458 rpm (1/(2*65.5ms)*60). The division by 2 is because there are 2 blades on the prop. Since hovering happens way over 458 rpm it doesn’t matter much that we can’t measure any slower speed.

Next thing was to setup the capture compare. The ST library already provides the basic API, TIM_ICInitStructure, so it was more or less just a matter of finding how to configure it. The capture part of the timer can do quite fancy things but in the end we decided it was easiest to just use it the simple way, were it stores the timer value in the corresponding capture compare register on a predefined edge. As the register values will be overwritten when the next pulse comes we setup a interrupt handler to take care of the result. What the interrupt handler ended up to do was to copy the timer value, use that to calculate the rpm and then save the result in a variable. It turned out to be good to do an average of the two latest values as the pulses was not fully symmetrical because of the two blades. This was then done the same way for each propeller input and, voilà, rpm measurements was taken. (Well, there certainly was a bit of hair pulling before it all worked but in the end it worked! Love that feeling)

Getting it down to a cfclient was a piece of cake using the logging framework. We just defined the variables to be logged, setup the logging in the cfclient and it could all be plotted. The variables was defined using the macros below.

LOG_GROUP_START(rpm)
LOG_ADD(LOG_UINT16, m1, &m1rpm)
LOG_ADD(LOG_UINT16, m2, &m2rpm)
LOG_ADD(LOG_UINT16, m3, &m3rpm)
LOG_ADD(LOG_UINT16, m4, &m4rpm)
LOG_GROUP_STOP(rpm)

Then by connecting the the Crazyflie a log configuration could be created called “motor” containing the rpm values as well as voltage and PWM.

log configuration rpm

After that by opening the Log Blocks tab the “motor” log configuration could be enabled a written to files. The data log output folder can be opened from the menu by selecting “Settings -> Open config folder”. In my case in “logdata/20150202T17-29-49/motor-20150202T17-35-09.csv”. This CSV file can then be imported to a program such as Octave, Matlab, Spreadsheet etc for further analysis.

Log write to file

The data can also be plotted in real-time using the plotter as in the picture below. Hmmm, interesting, the Crazyflie 2.0 seems to hover at about 19000 rpm with the RPM measurement board attached.

plotting of rpm

 

The idea was to do the analysis part in this post as well but it turned out to be a little bit to much, therefore stay tuned for the final analyzing part!

During the last week there’s been lots of work, but we don’t have that much to show for it. We’ve spent a lot of time discussing what we should do during 2015. Last year there was a clear focus: develop, release and ship the Crazyflie 2.0. But up until now we haven’t really discussed what the goals for 2015 are. It’s not that we don’t have ideas, there’s always lots of ideas. It’s more about finding a common focus to work towards. It’s still ongoing, but there’s a few points that we know. We will of course continue the development (firmware, software, clients) of the Crazyflie as well as creating more expansions for the Crazyflie 2.0. For the expansion boards we’ve already talked a bit about it before, but for the firmware/software side we haven’t communicated our plan. The reason for this is simple, there’s not really been a plan for this. The main focus has been stabilization and creating clients for iPhone and Android. But now that it’s done we need to move forward with new features. If you have any feedback on this please let us know. Something that we are hoping to work on is ROS integration. (Edit: well, what do you know, this has already been started by Wolfgang Hoenig, the power of open source! Here’s a link) Once we figure out the plan we will let you now :-)

Fred, the main developer of the Crazyflie Android client, is doing a presentation about the Crazyflie at FOSDEM next weekend. Arnaud will be attending as well so if you would like to meet up, let us know!

But a few things happened during last week:

  • There’s a new release of the Android Client (thanks Fred!), so make sure to upgrade your apps!
  • We’ve added LED-ring settings to the FlighTab in the latest version on the develop branch of the client.
  • We released a bug-fix version of the python client. This new version fixes Crazyflie 2.0 configuration.
  • We added a some guideline for contributing to the client. We hope to streamline the contribution process to be more efficient at it. Tell us if you have any comments.

As for the RPM measurements and analysis we’re working on it, but it’s not ready yet… We are however making progress and it’s been very interesting, have a look at the thrust fixture we made :-).

cf2 thrust fixture