Tuesday, May 7, 2013

Flying on OS X!

Finally got my new MacBook Pro set up (by following what I had done previously), and can now fly on OS X!  The one thing I was missing was libusb, which I installed with 'brew install libusb'.

The radio found the Crazyflie, and flying is very similar to how it works under Linux.  The UI has quite a bit more lag, but most of my attention is on the Crazyflie anyway.... ;)

Monday, May 6, 2013

Flying!

After assembling the hardware (took maybe an hour between soldering, putting on the propellers, motor mount, etc) setting up the controller in PC Client (under Linux), and updating the Crazyflie and Crazyradio firmware - it's alive!

Really fun to fly, although it's a lot more difficult than I thought.  It takes some practice to keep the thrust just right to keep it level, and at the same time tweak the roll/pitch/yaw to make it head where I want.  I let my kids take a stab at it but they kept on slamming it into the ceiling/walls/furniture - fortunately it can take a hit :)

I think an auto-level feature making use of the altimeter would make it so much easier to fly.  e.g., pushing a button to set the altitude, then simply focusing on roll/pitch/yaw to change the horizontal direction.  It's still fun though to play with the current firmware and get more skilled at controlling the craft, next I'd like to tweak the PID contants and see the effect.  If I can get some help filming I'll post some videos...

Crazyradio firmware with USB3.0 fix

In my last post, Arnaud (one of the Bitcraze guys) replied, informing me that they have fixed an issue with the Crazyradio on USB3.0 hosts!

I cloned the Crazyradio repository with 'hg clone', then fired up an Ubuntu 12.10 VM and installed the 'Small Device C Compiler':


sudo apt-get install sdcc

Performing a 'make' in crazyradio-firmware/firmware resulted in a binary: bin/cradio.bin .

I could have burned this image via SPI, but I have another Linux machine handy (a neat little Olimex OLinuXino with Python already installed), so I cloned the repository on that machine as well, copied over cradio.bin, and followed the instructions on the Crazyradio Wiki.

This flashed the latest Crazyradio code onto my device - and testing out on my MacBook Pro, it did indeed solve the "IOUSBFamily was not able to enumerate a device" issue!

Saturday, May 4, 2013

Issue with Crazyradio on MacBook Pro

Plugging the Crazyradio into USB, I don't get anything on my 13" MacBook Pro (Retina).  I did install VMWare Fusion with an Ubuntu instance so was hoping to start out with Linux; but, the virtual machine can't see the Crazyradio either.

For some reason, it can't enumerate under OS X; I see this in an OS X console:

$sudo dmesg | tail

USBF: 294. 40 [0xffffff801f876000] The IOUSBFamily is having trouble enumerating a USB device that has been plugged in.  It will keep retrying.  (Port 1 of Hub at 0x14000000)
USBF: 298.517 [0xffffff801f876000] The IOUSBFamily was not able to enumerate a device.
USBF: 299.836 [0xffffff801f876000] The IOUSBFamily is having trouble enumerating a USB device that has been plugged in.  It will keep retrying.  (Port 1 of Hub at 0x14000000)
USBF: 304.718 [0xffffff801f876000] The IOUSBFamily was not able to enumerate a device.
USBF: 306. 40 [0xffffff801f876000] The IOUSBFamily is having trouble enumerating a USB device that has been plugged in.  It will keep retrying.  (Port 1 of Hub at 0x14000000)
USBF: 307.358 [0xffffff801f876000] The IOUSBFamily gave up enumerating a USB device after 10 retries.  (Port 1 of Hub at 0x14000000)
USBF: 307.358 [0xffffff801f876000] The IOUSBFamily was not able to enumerate a device.

So I assume since it can't enumerate under OS X, it can't be handed off to the VM either.  I suspect it could be a hardware issue with the Crazyradio, perhaps some marginal electrical issue that manifests itself on specific types of machines.  Next I will try using an externally powered USB hub; if that doesn't work, I will also try another machine running Linux...

Got it!

This arrived in the mail today, a tiny and nicely designed box:



Here's what was inside - the board, battery, 2 sets of props (with an extra prop in each set), 5 motors (an extra one), the radio, antenna, and motor mounts:


I'm looking forward to getting it built and hope to try it out within the next couple of days!

Thursday, February 28, 2013

gamepad issues on OS X

The PC client currently supports the use of a 4-axis gamepad (e.g., PS3 controller) for flying.  I ordered a $10 USB controller from eBay, plugged it in, and tried some of the default settings.

The gamepad was recognized, and values showed up in the client for pitch/roll/yaw/thrust as the axis were moved; however, one of the axis always changed 2 of the controls, and the range wasn't correct for 1 of the axis.

I found a tool called HID_n_Seek to look at the output from all of the USB endpoints, and discovered that there are actually 5 endpoints that change value as the axis are moved.  4 of them behaved as expected, and 1 of them seemed to combine the output from a few different axis.

Likewise, a test using pygame (which is currently used by the Crazyflie PC client for the joystick input) showed the same thing.  I found this test script:


#!/usr/bin/env python

import pygame, time
#from pygame import joystick, event

pygame.init()
#joystick.init()
j = pygame.joystick.Joystick(0)
j.init()
print 'Initialized Joystick : %s' % j.get_name()
try:
    while True:
        time.sleep(1)
        pygame.event.pump()
        for i in range(0, j.get_numaxes()):
            if j.get_axis(i) != 0.00:
                print 'Axis %i reads %.2f' % (i, j.get_axis(i))
        for i in range(0, j.get_numbuttons()):
            if j.get_button(i) != 0:
                print 'Button %i reads %i' % (i, j.get_button(i))
except KeyboardInterrupt:
    j.quit()
    

Which produced output like this:

Axis 0 reads 0.00
Axis 1 reads 0.00
Axis 2 reads 0.05
Axis 3 reads 0.00
Axis 4 reads 0.00
...

After moving each axis, it appears that we we want to ignore axis 2.  i.e., the mapping looks like this:

Axis 0 - Left stick (L = -1.0, R = 1.0)
Axis 1 - Left stick (U = -1.0, D = 1.0)
Axis 3 - Right stick (L = -1.0, R = 1.0)
Axis 4 - Right stick (U = -1.0, D = 1.0)
IGNORE AXIS 2 (affect by all sticks)


So now it's simply a matter of figuring out the best way to modify the Crazyflie PC client to use axis 0, 1, 3, and 4 for input, and skip axis 2.  Remapping the configs/input/*.json fixes the axis; for example:


     "axis": [
          {"name":"Roll", "type":"Input.AXIS", "id":4, "scale":1.0, "key":"roll"},
          {"name":"Pitch", "type":"Input.AXIS", "id":3, "scale":-1.0, "key":"pitch"},
          {"name":"Yaw", "type":"Input.AXIS", "id":0, "scale":1.0, "key":"yaw"},
          {"name":"Thrust", "type":"Input.AXIS", "id":1, "scale":-1.0, "key":"thrust"},
          {"name":"Pitch Cal+", "type":"Input.BUTTON", "id":7, "scale":-1.0, "key":"pitchcal"},
          {"name":"Pitch Cal-", "type":"Input.BUTTON", "id":5, "scale":1.0, "key":"pitchcal"},
          {"name":"Roll Cal +", "type":"Input.BUTTON", "id":6, "scale":1.0, "key":"rollcal"},
          {"name":"Roll Cal -", "type":"Input.BUTTON", "id":8, "scale":-1.0, "key":"rollcal"},
          {"name":"Killswtich", "type":"Input.BUTTON", "id":14, "scale":1.0, "key":"estop"},
          {"name":"Exit", "type":"Input.BUTTON", "id":12, "scale":1.0, "key":"exit"}
     ]}

However, that breaks one of the buttons (because the buttons should be 4-7, not 5-8, and the inputs are stored as an array indexed by the id, so we can't have both a button and axis at id 4).  So perhaps need to make a code change such that we can have an axis/button with the same id...

Update:
I created a patch back on 3/1 that got merged in; this controller should work under OS X now.

Wednesday, February 27, 2013

Qt menu and OS X

One strange issue I noticed with crazyflie-pc-client is that it appeared to be missing some menubar items.  Specifically, "Configure Input device", "Exit", "Options", and "Help".  It took some digging but I finally found this:

QMenuBar on Mac OS X

QMenuBar on Mac OS X is a wrapper for using the system-wide menu bar. If you have multiple menu bars in one dialog the outermost menu bar (normally inside a widget with widget flag Qt::Window) will be used for the system-wide menu bar.
Qt for Mac OS X also provides a menu bar merging feature to make QMenuBar conform more closely to accepted Mac OS X menu bar layout. The merging functionality is based on string matching the title of a QMenu entry. These strings are translated (using QObject::tr()) in the "QMenuBar" context. If an entry is moved its slots will still fire as if it was in the original place. The table below outlines the strings looked for and where the entry is placed if matched:
String matchesPlacementNotes
about.*Application Menu | About <application name>The application name is fetched from the Info.plist file (see note below). If this entry is not found no About item will appear in the Application Menu.
config, options, setup, settings or preferencesApplication Menu | PreferencesIf this entry is not found the Settings item will be disabled
quit or exitApplication Menu | Quit <application name>If this entry is not found a default Quit item will be created to call QApplication::quit()
You can override this behavior by using the QAction::menuRole() property.


So, Qt parses the name of the menu bar items, and if they even partially match certain string (e.g., "configure"), it will move the item into what it thinks is a Mac native menu bar!!

Since this is probably not what we want here, adding the following to an action disables this feature:


   <property name="menuRole">
    <enum>QAction::NoRole</enum>
   </property>   


For example:

  <action name="menuItemConfInputDevice">
   <property name="text">
    <string>Configure Input device</string>
   </property>
   <property name="menuRole">
    <enum>QAction::NoRole</enum>
   </property>   
  </action>