Author: Marcus

Most of the time we have a few prototypes lying around that we’re working more or less on. Sometimes some of these make it into a product if we feel that they might be useful or fun for the community, like for instance the SD-card. Now it’s time for another prototype to be moved to manufacturing, a deck with VL53L0x laser ToF distance sensor.

On the Crazyflie 2.0 (and Crazyflie 1.0 10-DOF) we have a pressure sensor mounted to help control the altitude of the platform. Since air pressure is moving around a lot and the measurement is noisy it’s been very hard to get a rock-solid altitude hold working (although it’s getting closer). Already back when ST released the VL6180X we were looking at it, but the range was too short (10cm max). So when ST released the VL53L0x which has longer range (200cm max) we though this might be a good deck for the Crazyflie 2.0.

So we have a working prototype and thanks to stephanbro and Marcus Grieff we also have the firmware to use it with the Kalman filter. We are currently working at making it work together with the pressure sensor with the current altitude-hold mode.

Currently we’re working on verifying the hardware to make sure the power supply is good enough for it, but then the next step is production. Hopefully it will be available in a couple of months :-) Below is a picture of the current prototype.

VL53

Up until now, we’ve made our products available to customers through Seeedstudio and a number of distributors around the world. This has been a great solution since we’ve been able to focus on development of products instead of shipping packages and maintaining our own e-shop. When customers contact us and want to buy, we’ve been directing them towards local distributors where they can buy in local currency and with faster delivery times. But the last year more and more customers wanted to buy products directly from us and this has been taking up more and more of our time. The main reason has been complex purchasing procedures or local distributors not carrying the hardware the customer wants. Also if a customer starts discussing with us about what to buy, they tend to want to buy directly from us instead. Since we haven’t had a good set-up for this, we’ve been shipping packets on a case-to-case basis from our office basement (yes, the same basement where we fly with the Loco positioning). This has been very time consuming.

So, in order to optimize the sales and shipping, we’ve decided to launch our own e-shop. Our idea is that it is a complement to other distributors and the Seeedstudio Bazaar. Buying from local distributors will result in lower shipping costs and faster delivery. So we’re not aiming at replacing this, instead our goals are:

  • Have one place where we offer a full assortment of our products
  • Take responsibility for the end-to-end experience (both the purchasing and product support)

In order to service the e-shop, we’ve set up warehousing in Hong Kong, close to Shenzhen were the Seeedstudio manufacture is located. Aside from servicing the e-shop, this solution will also be used for drop-shipping custom orders, so replacing our basement packaging system.

As with most things, the more you know about something, the more you understand how complex it is. When we first started thinking about setting up our own e-shop/warehouse solution, we thought that this would probably take about a week: we evaluate a couple of solutions, select one and then just start selling/shipping. Turns out that things are more complex and this has caused a few weeks delay for the Loco positioning products since they will only be available through our shop. Now we’re hoping everything is on track, but we’re very new at this so please bare with us if there’s any hickups along the way when starting this up.

We’re opening up the store today, so you can have a look. Any feedback and comments are welcome! But as you might quickly notice, all the products are out of stock. The Loco positioning hardware as well as the other products are on their way to the warehouse, but they got a bit delayed along the way. Our best estimate is that the products are stocked at the end of the week or beginning of next week. The link to the e-shop is store.bitcraze.io.

store-launch

Here’s a photo of some of the boxes. Looks a lot like normal boxes, but these contain the Loco positioning hardware :-)

 

After a hectic week we’re finally ready to put some new decks into production! A couple of months ago we selected 4 deck prototypes to try to bring to production before Christmas: WiFi, GPS, BigQuad and the Buzzer. After working hard on them during the last months, we’re now ready to release the Buzzer and BigQuad decks. Last week we ordered the first batches and the product pages and descriptions are being written this week. We’ll push out more information about the boards as it gets available, so stay tuned!

Below is a few quick shots of the latest prototypes:

So what happened to the GPS and the WiFi decks? The latest prototypes are working, but there’s still some minor issues. So instead of moving to production with the current design, we’re doing one last prototype iteration and launching the boards early next year.

On a related note we’ve been working hard together with Seeedstudio to get some more Crazyflie 2.0s into stock before Christmas. Not so surprisingly we’re not the only ones rushing to produce. But thanks to lots of efforts from Seeedstudios side the Crazyflie 2.0 will be back in stock in a couple of days!

cf2 front rosetteIt’s that time of year again, time for Christmas shopping. This year we thought that we would plan ahead and produce more units before Christmas to meet the demand. It was a great plan, but there were some hick-ups on the way. Originally the plan was that a fresh batch of Crazyflie 2.0’s would be rolling out of production right around now and being available in the Seeedstudio bazaar. But unfortunately we’ve only managed to get a small part of the batch out. And since demand is high before Christmas they were all sold out immediately. But we’re working hard to get the remaining part of the batch ready. The new time-plan is for the units to be finished around Christmas, which means they might not have time to ship to customers and be ready to get unwrapped by happy geeks around the world. But there’s still a chance to get a great present for your fellow geek (or maybe your own inner geek), check out our list of local distributors.

On another note we’re having some issues with shipment of spare batteries from China. New shipping and customs regulations have made it very expensive to ship spare batteries that are not included in products. Normally several orders of products are bundled together when doing the shipping/customs from Seeedstudio, but each battery now has to be handled separately with it’s own declaration and paperwork .We’re trying to find a way around this issue, but until then the spare battery at Seeedstudio will be listed as out of stock. If anyone has any tips on how to solve the issue, please let us know.

Last week and this week is busy with preparations for the New York and Berlin maker faires. Since we will be in the Seeedstudio booth we don’t have the same space as at the Bay Area Maker Faire, so we had to rebuild our “fly-cage”. The new specs are 1.7 x 0.7 x 0.7 meters. This is the area the Crazyflie 2.0 should be able to fly in for a full charge without touching the sides on the net.

We don’t have any special plans during the faire, except for flying during the day. So if you feel like meeting up, having a beer and getting lost in various technology discussions then leave a comment or drop us a mail.

The autonomous flying rig we used in bay-area was using the Kinect 2 sensor. This new rig is only using a standard webcam which is cheaper and easier to manage (ie. we do not need a Windows computer anymore). We are attaching an augmented reality marker on the top of Crazyflie and the image processing is mostly done by the ArUco library. ArUco is detecting the position of the Marker in 3D and the position is sent via zeromq to the controller. We used the same controller code as for the Kinect, we just had to tune it a bit better to keep in the smaller space. Then the controller is sending pitch/roll/yaw to the Crazyflie client setup to have a ZMQ as input device.

CPBrmPrUAAAKkEj

If you want to build the same cage then here’s a list of the parts:

  • Some kind of net (we used normal fishing net)
  • Fishing line (to tighten the cage)
  • Aluminium beam (for tents)
  • These 3D printed parts
  • Webcam with standard camera attachment (we use Logitech C920)
  • Camera attachment screw

We are in the process of cleaning up the code for the webcam. It will be pushed on Github and we will document the build on the Wiki.

During the last week we’ve taken a big step, moving to Python 3! The reason for the move is that Python 3 is becoming broadly adopted and it has more features that we want to make use of. Also 3 > 2. This post will explain a bit of what we did, some of the problems we encounters and the current status. The numbers 2 and 3 will be thrown around a lot in the text, but to precise we’re talking about versions 2.7+ and 3.4+ (even more precise it’s been tested on 2.7.9 and 3.4.3). The next release of the client will run on Python 3, but if you want to test it now just clone the development branch on GitHub.

Status

If you have developed applications using the API and Python 2 then you might be getting a bit worried right about now. The compatibility for both Python 2 and 3 will be kept for most things, except for the client:

This will be compatible with both 2 and 3:

  • The Crazyflie Python API (everything in lib/cflib)
  • The examples for the Crazyflie Python API (everything in examples)
  • The ZMQ server using the Crazyflie Python API (bin/cfzmq)
  • The Crazyflie command-line bootloader (bin/cfloader)

But the main clients will only have Python 3 compatibility:

  • The Crazyflie Python client (bin/cfclient)
  • The Crazyflie Python headless client (bin/cfheadless)

API Examples

While doing the porting we’ve also added more examples to cover more of the Crazyflie Python API. In order to keep 2/3 compatibility for the API it’s important to be able to test it easily with the different versions. We are having unit-tests on the TODO-list, but until then we’ve been using the API examples to test. All the examples should run with both Python 2 and 3. It’s also a good thing with more examples showing how to use the API…

Porting and compatibility

The approach we used was to first run the 2to3 utility to automatically to as much as possible of the porting. After that we had to fix the rest of the errors manually and also maintain the dual 2/3 compatibility of the API.

In our previous implementation we made use of strings to store binary data that we were sending/receiving. But because of incompatibilities between Python 2 and 3 this didn’t fit very well. To make things neat for the API we found a container where we could store bytes that works with both Python 2 and 3, the bytearray. Even though we use the same type, there’s still some subtle differences in usage between the versions. After doing some testing we found ways where the syntax was the same for Python 2/3.

First of all bytearrays can be created from a string, tuple or list. When indexed by the [] operator it will give you the value of each byte.

>>> d = bytearray([i for i in range(10)])
>>> d
bytearray(b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t')
>>> d[5]
5

The main point is getting something meaningful out of the bytearray when doing the communication, here’s a few examples:

Unpacking a byte, an integer and a word from the first 7 bytes (little endian)

>>> struct.unpack("<BIH", a[:7])
(0, 67305985, 1541)

Getting a string from a subset of the data can be done by using decode and the char-set to use for decoding. We use ISO-8859-1 since the Crazyflie does not support Unicode (yet?).

>>> d = bytearray([i for i in range(97,100)])
>>> d
bytearray(b'abc')
>>> d.decode("ISO-8859-1")
'abc'

You can also easily get a tuple or a list:

>>> list(d)
[97, 98, 99]
>>> tuple(d)
(97, 98, 99)

And you can also concatenate:

>>> d + d
bytearray(b'abcabc')

And find a byte:

>>> d.find(bytearray((98, )))
1

But there’s also a few things we couldn’t get to work in a good way and have to check which version we’re running and execute different code, like the queue import that has changed name.

if sys.version_info < (3,):
    import Queue as queue
else:
    import queue

Another problem we haven’t solved is creating a bytearray from a string, so it’s also

if sys.version_info < (3,):
    self._data = bytearray(data)
else:
    self._data = bytearray(data.encode('ISO-8859-1'))

As for the client code that was ported to Python 3 without keeping the backwards compatibility there wasn’t any big issues. The biggest change was the PyQT4 API where there’s a few things that have improved when placing custom Python data in GUI objects. Before QVariant was used for this. You would create a QVariant object that wrapped the Python object. To get data out from the QVariant again you would have to explicitly say what type it had by calling the correct function (like toInt()). Now this is a lot smoother. QVariant has been skipped and you just use the Python type directly.

For more information have a look here where we found a lot of useful tips. Don’t hesitate to leave a comment if you think we could have done things differently or if you have any tips!

What’s not working

There’s still a few things we’re not sure how to fix and we have to look into it a bit more. These are:

  • There doesn’t seem to be any Python 3 bindings for the Leap Motion. According to this it’s possible to build the bindings yourself.
  • The Python 3 bindings to Marble for the GPS tab hasn’t been investigated yet

PEP-8

On a side note we’ve started using Travis CI (more on this next week) and will start creating unit-tests for the Crazyflie Python  API. As a first step we’re running PEP-8 on all the code. This will be checked automatically for all commits and pull-requests.

 

This weekend we went to the maker weekend at Hx in Helsingborg and showed off the Crazyflie 2.0 flying with the Kinect. It’s an awesome demo for fairs since it flies by itself and looks pretty good. Below is a few photos from the event.

But this time we ran into some issues with the set-up. When we first developed this we were running the image acquisition and processing on Linux using libfreenect2, but we later switched to Windows. The reason is these three lines. These lines map the depth measurement to the camera measurements and gives a set of “world-coordinates”. This is needed, since the distances left/right wouldn’t be correct without taking the distance away from the camera into consideration. Without it a left/right movement close to the camera would give a much larger response than one further away from the camera.

So to solve the issue above we moved everything to Windows, which would kind of solve the issue. But we started experiencing lag in the regulation, which originated from lag in the image processing. After doing some more digging we drew the conclusion that there was a USB issue when using the Crazyradio at the same time as the Kinect v2. Once every couple of minutes the FPS for the video will drop really low (which results in CPU usage going down as well). But disconnecting the Crazyflie (i.e not using the Crazyradio) seems to solve this issue. To work around this problem we currently have a set-up where we use two laptops. Since we’re running ZMQ to communicate between the applications it’s a quick operation to split it up on multiple hosts. So the Windows laptop runs image acquisition and processing and the Linux laptop runs the control-loop and Crazyflie client for sending the commands to the Crazyflie.

When we were first developing this there was lost of things happening in the libfrenect2 repo, so this might be implemented now. Does anyone have any tips for this? We would love to be able to run the system fully on Linux with only one laptop :-)

During the upcoming months we will be attending both the New York Maker Faire and the Berlin Maker Faire, hanging around the Seeedstudio booth. So if you want to see the Crazyflie/Kinect demo live or just to hang out and talk to us then drop by!

MF15NY_Badge1 icon_Berlin

A new version of the Crazyflie PC Python client has been released, version 2015.08. It’s been a while since the last release of the client so there’s a long list of changes, including lots of fixed bugs. The main new features are:

  • Student/Teacher mode:  It’s possible to use two input devices, where one can take over control from the other. This can be used for teaching or for working with a computer auto-pilot (doc)
  • Control the LED-ring from the Flight Tab:  Now it’s possible to turn on/off the headlights directly with a click and to select the LED-ring effect from a drop-down (doc)
  • New LED-tab to set custom patterns and intensity: Enables the user to individually set the color of each LED as well as the intensity of the LED-ring
  • ZMQ access to LED-ring memory and parameters: Write patterns for the LED-ring or set/get parameter values from an external application using JSON and ZMQ (doc)
  • ZMQ input device: Simulate a joystick by sending axis values in JSON via ZMQ. This can be used to implement a computer auto-pilot using for instance the Kinect (doc)
  • Switched from PyGame to PySDL2 on Mac OSX/Windows and native input device on Linux
  • WiiMote support

The next step after the release is to shape up the code a bit, so we’ve started using Travis for building and continuous integration. The long term goal is to run Flake8 and unit-tests on the code, but we still have a bit to go. The way we’re working towards this is by slowly enabling more and more checking in Travis, fixing one type of errors at a time.

 

A while ago we implemented something we called mux-mode for controllers, where the Crazyflie can be controlled from multiple controllers at once. Initially it was implemented the day before a “bring-your-kids-to-work” day at Minc (where our office is). The idea was that the kids would control roll/pitch from one controller and we would control thrust/yaw from another controller. But we would also have the possibility to take over roll/pitch by holding a button on our controller. It was a big hit and let’s just say the “take-over” functionality came in handy :-)

A couple of months later we started working with the Kinect v2 with the goal of automatically piloting the Crazyflie using it. Again the input-mux feature came in handy. Instead of having the kids controlling the roll and pitch, the autopilot was now doing it. This enabled us to work on one problem at a time, first roll/pitch then yaw and finally thrust. When we were finished the autopilot was controlling all of the axes and we just used the “take-over” functionality when things got out of control.

So far this functionality has been disabled by default, but last week we fixed it up and enabled the code. With this change we’ve renamed the feature to teacher/student and also changed the way mappings are selected for the client. Below is a screenshot of the new menu, but have a look at the wiki for more details. If you want to try it out, pull the latest version on the development branch. It’s a great feature if you know someone that want’s to try flying for the first time!

On a side-note we tried some other ways to mix the controllers, like one we called “mix-mux”. This would take the input from two devices and add them together, so if both give 25% thrust the total would be 50%. It was really fun to try, but impossible to fly (maybe we need to work on our communication skills…).

During the design-phase of the Crazyflie 2.0 products last year, we sat down and had a long discussion about testing. In order to make sure things runs smoothly, it’s best to make sure that the hardware you’re designing can be tested properly in manufacturing. It could be as simple as adding a few test-points or a bit more complicated like making sure the product can run self-tests to cover some of the testing. There’s also other factors that count, such as the time it takes to test one unit. The better the tests are the less hassle you will get down the line and the happier your customers will be. The cost of finding a faulty board during production is very low, while finding faulty units in the field can be a costly process.

When it comes to the Crazyflie 2.0 we tried to think all of this though during the design-phase, walking though the schematic and making sure that everything could be tested properly in manufacturing. Since the new design is more complex then the old one, we also ended up with a test procedure with more steps and more things that could potentially go wrong. So we felt we needed some way to keep track of the products all the way from the production, to faulty units we might get from customers. Figuring out how faulty units might get passed the testing is crucial for improving it. But in order to acheieve this you need some way to track each board, thankfully for us this was already solved.

Both the Crazyflie 2.0 and all the decks fitted with a 1-wire memory have a unique identifier, a serial number. So these can easily be used for tractability. But without any information to trace it not very useful. So we built a simple framework for reporting as all of the test data back to our servers where we could easily look up what was happening. Here’s a screenshot of what it looks like for a tested Crazyflie 2.0 (1-wire memory products look similar):

cf2_testing

So what’s all the information? Well, here’s a quick rundown:

  • Run list: Each test that involves the serial is listed, so it’s easy to select which one you want information about
  • golden_sample: Serial of the golden sample unit
  • power and power_d: The measured power and power deviation from the golden sample
  • freq and freq_d: The measured frequency and frequency deviation from the golden sample
  • Tests: The framework allows for a number of tests to be defined, the result of each test is reported and if the test fails it’s possible to see in which step this happened
  • Console output: For the Crazyflie 2.0 there’s a special case of being able to see the console output when the unit is started

There’s of course a lot of other nifty features with having this setup, like getting production updates in real-time and being able to look at lots of statistics. All in all we’re pretty happy with the system, but there’s still lots of things to be added. Oh, and if anyone is wondering what happens if the internet connection is lost: It’s all saved locally as well (and uploaded when the connection is recovered). Plan for the worst and hope for the best :-)

If you’re interested in seeing what some of the rigs looks like, then have a look at this old post with some pictures from when we started up the Crazyflie 2.0 manufacturing.