Latest code on GitHub

Up to now, I’ve deferred adding code to GitHub until a particular development phase is over.  However, so much has changed in the past few months, I ought to share.  Features:

  • X8 optional configuration
  • more precise and efficient scheduling using select() allowing for extra sensors…
  • LEDDAR – fully tested
  • PX4FLOW – tested to the extent the quality of the PX4FLOW allows
  • ViDAR – testing in progress
  • Garmin LIDAR-Lite V3 – arrival imminent
  • Compass – tested but unused except for logging
  • Fusion – tested, but each sensors source requires different fusion paramters

The compass function is unused except for logging.  The ViDAR and Fusion features require at least a height sensor and further calibration.  Therefore, I strongly recommend setting

self.camera_installed = False

unless you want to see how well it isn’t working yet.

Your can enable logging for the ViDAR stats without including them in the Fusion by setting the above to True and also setting these two variables to False:

 #-------------------------------------------------------------------------------
 # Set the flags for horizontal distance and velocity fusion
 #-------------------------------------------------------------------------------
 hdf = True
 hvf = True

This code comes with absolutely no warranty whatsoever – even less than it normally does.  Caveat utilitor.

Left (a)drift

I flew Phoebe earlier with LEDDAR working well.  She repeatedly drifted left, and self-corrected as can be seen in the graph below.  You can see her repeatedly drifting and stopping.  This is the expected behaviour due to the top level PID controlling velocity not distance: drift is stopped, but not reversed.  On that basis, I’ve updated the code on GitHub.

Left (a)drift

Left (a)drift

To get her back to where she took off from, I need another set of ‘pseudo-PIDs’ to recognise and correct the distance drifted.  I’m going to keep this as simple as possible:

  • I’ll continue to use my velocity flight plan – integrating this over time will provide the ‘target’ for the distance PIDs in the earth reference frame
  •  I’ll integrate the velocity (rotated back to earth frame) over time to get the distance PID ‘input’ – although this is double integration of the accelerometer, it should be good enough short-term based upon the close match between the graph and the flight I watched.
  • critically, I’ll be using fixed velocity output from the distance ‘pseudo PID’, rotated back to the quad-frame as the inputs to the existing velocity PIDs – the input and target of the distance ‘pseudo PID’ only provide the direction, but not speed of the correction.

This should be a relatively simple change which will have a visible effect on killing hover drift, or allowing intentional horizontal movement in the flight plan.

After that, I’ll add the compass for yaw control so Phoebe is always facing the way she’s going, but that’s for another day.

Code update

I’ve updated the code on GitHub.  The only significant change is the Raspberry Pi camera works correctly with the restructured code.

As far as flight quality is concerned, it’s better than earlier versions prior to when I added the class code and switched to the IMU FIFO, but it’s a long way to go before it’s good enough.

I don’t think there’s much else I can do without adding the laser sensors, and that means it’s going to continue to be quiet here for a while.

Buffering

I’ve finally got the FIFO buffer code working with lots of protection against overflow, and also using a guaranteed way to ensure the code and FIFO are always synchronised.  It works perfectly, so I’ve updated the code on GitHub

Then I took Zoe and Phoebe about; with the floppy props Zoe flew OK but not as well as usual and, as usual, neither would fly at all with the CF props.  Some stats revealed unsurprisingly that it’s Z-axis noise from the props;  Zoe’s floppy props aren’t so floppy at freezing temperatures but when I brought her indoors, she was fine again.

The problem is the motors / props can’t react fast enough to sharp spikes in acceleration, so drift ensues – in this case downwards vertical drift keeping them both pinned to the ground when the sensors felt the spikes.  I need to find a way to soften those acceleration spikes such that the net integrated velocity is the same, and the motors can react to it.

There’s a couple of approaches I can take here, and as usual, I’ll be trying both.

The first is to add additional foam buffering between the HoG and the frame to soften the blows just like Zoe’s floppy props do.  The second is to tweak the vertical velocity PID gains to be dominated by the I-gain and reduce the P-gain significantly.

A box it is then!

I’ve tried various ways to acclimatise Zoe’s sensors prior to flight.  The best so far is to set the props spinning at minimum speed, and after 5 seconds, grab a FIFO full of data (42 batches of samples in the 512 byte FIFO and 12 byte batch size), and use these to calculated start-of-flight gravity.  The props then continue to run at this base speed up to the point the flight kicks off.

The net result is a stable flight with no vertical drift during hover, but with horizontal drift of about a meter.  Without this code, horizontal drift is half this but she continues to climb during hover.

I’m not sure how I can improve this, so I’ll leave it alone for now and instead have a look at making a DIY cardboard box to keep Zoe out of the wind.

In passing, I did a quick analysis of the code size: 1021 lines of python code, 756 lines of comments and 301 blank lines giving a total of 2078 lines in Quadcopter.py.  Here’s the script I knocked together quickly FYI:

code = 0
comments = 0
spaces = 0

with open("Quadcopter.py", "rb") as f:
    for line in f.readlines():
        line = line.strip()
        if len(line) == 0:
            spaces += 1
        elif line[0] == '#':
            comments += 1
        else:
            code += 1
 
    print "Code %d, Comments %d, Blank Lines %d, Total %d" % (code, comments, spaces, code + comments + spaces)

I’ve put Zoe’s code up on GitHub as the best yet, although the either / or of vertical / horizontal drift is seriously starting to pᴉss me off.

Note that since I’ve moved the IMU FIFO into the Quadcopter.py code, QCIMUFIFO.py is not longer on GitHub; Quadcopter.py is the latest best working version and QCDRI.py is the best version that uses the data ready interrupt in case you are seeing the I2C errors like I used to.

Classified

For a while, I’ve wanted to be able to run multiple flights without dropping back to the command line first to type this every time:

sudo python ./qc.py -f fp.csv

This means separating the one-off initialization from the per-flight initialization, putting a keyboard input  in between while allowing all three functions to reference the same shared variables.  I could have done it by adding more global variables, but that would make it harder to understand and maintain the code and if done wrongly, it could cause very hard to diagnose bugs; it was definitely time to make the flight controller code a class allowing class instance variables to be accessed by all functions in the class.

So now you can still run from the command line as above, or not supply parameters thus:

 sudo python ./qc.py

Before each flight, you can add additional parameters, or just rerun the command-line defined flight by just hitting enter:

Wassup?
Wassup? -g
Wassup? -f fp.csv
Wassup? --tc 1 -h 200

Because I’ve removed the Butterworth IIR filter, flights happen almost immediately after hitting enter to any of the above commands.

You can still stop any flight by hitting ctrl-C; mid-flight, that will kill the flight and return to “Wassup?”. Ctrl-C at “Wassup?” will end the program, as will typing “exit” or “quit”.

There is a change to qc.py – because the code is now a class instead of a function, qc.py now has to instantiate the class first:

from QCIMUFIFO import Quadcopter
Quadcopter().go()

instead of

import QCIMUFIFO as Quadcopter
Quadcopter.go()

All code changes are on GitHub.

Zoe the Zero – 2 – Initial Installation

First step is to flash your (at least) 8GB micro SD card with the latest Jessie.  Currently that’s the 2015-11-21 version.

To setup a PiZero, because it only has one USB port, you need a powered (at least) 4 port USB hub, a mini HDMI to HDMI adapter, and a micro USB to USB A adapter.  With that you can set up a PiZero with keyboard, mouse, WiFi dongle and screen, and so get it connected to the internet.

Once connected the next step is to change the various bits of system configuration:

  • expand file system
  • set minimal GPU memory as she’ll be headless
  • christen her – zoe in my case
  • enable I2C
  • boot to console login prompt
  • overclocking – mine seems happy in Turbo mode @ 1GHz! – CPU temperature showing 38.4 degrees
/opt/vc/bin/vcgencmd measure_temp

I’ve found the only way I can guarantee each of these steps works is to reboot between each.

Next step is to update the code to the latest

sudo apt-get update
sudo apt-get dist-upgrade

Next install the various tools required

sudo apt-get install i2c-tools python-smbus python-dev

Next install the RPIO library – ignore the build warnings

git clone https://github.com/metachris/RPIO.git
cd RPIO
sudo python setup.py install
cd ..

If you are installing onto a RPi B2 (the 4 core), then you need to replace the RPIO/source/c_gpio/cpuinfo.c with this one before building:

cpuinfo.c

Next install my performance enhanced GPIO library from GitHub

git clone https://github.com/PiStuffing/Quadcopter
cd Quadcopter
tar xvf GPIO.tgz
cd GPIO
cd source
touch *
cd ..
sudo python setup.py install
cd ..

I think that’s everything.  Next step is to get and populate the pHat – it’ll be a couple of weeks before I get hold of this, so don’t hold your breath for the next update.

Status update

I’ve just managed to squeeze in a couple of test flights before the rain came in, and something is messing up the germs fusion code; noise from the props caught by the accelerometer is my best guess.  I’ll keep tinkering so see whether I can improve this; I’m fairly sure the theory is good, but the reality is swamped by noise.

Just in case the theory is flawed, I’ve uploaded the code to GitHub – just search for germs – it’s commented out so this code is still flyable.  Feedback welcome via comments to this post.

In passing, this update includes a minor fix to the RTF timing, and some tweaks to the diagnotics to keeps the separation between screen and logs clearer.

Finally, I can confirm the 4S cell battery works much better, though I do wonder whether the extra power from the motors has actually increased the noise due to the extra torque making the prop motion more jittery as it steps between motor coils – the motors are able to curtail angular momentum of the props better, pulling them back from overshoot?

 

Wrapping up warm

To overcome the reduced battery power in cold temperatures, I bought some 3mm thick adhesive neoprene foam mat.  I wrapped one of my batteries in it, and took Phoebe out to fly.  She behaved beautifully over several flights so I’ve popped the latest code up to GitHub.  Note there are no significant changes here, just temperature diagnostics and some tidying.

Neoprene wrap

Neoprene wrap

The battery is now held down by just a single silicone rubber band.  The tension in the band compresses the foam cover a little which keeps the battery locked in place, and the neoprene protects the battery from the frame on the underside – a couple of unexpected benefits.