Cotswold Raspberry Jam

So there I was this morning on the bus heading to Cheltenham to co-host the Cotswold Raspberry Jam, gazing at the beautiful Cotswold countryside, and my mind began to wander – well actually it was unleashed from the constraints of dealing with details it couldn’t fix while on a bus.  And out came a better idea about where to go for the next step to autonomy.

What’s been bugging me is the difference between magnetic and GPS North.  The ‘bus’ solution is to ignore magnetic north completely.  The compass still has a role to play maintaining zero yaw throughout a long flight, but it plays no part in the direction of flight – in fact, this is mandatory for the rest of the plan to work.

Instead, the autopilot translates between GPS north, south, east and west coordinate system and Hermione’s forward, backwards, right and left coordinate.  The autopilot only speaks to Hermione in her own coordinates when telling her where to go.  The autopilot learns Hermione’s coordinate system at the start of each flight by asking her to fly forwards a meter or so, and comparing that to the GPS vector change it gets.  This rough translation is refined continuously throughout the flight.  Hermione can start a flight pointing in any direction compared to the target GPS point, and the autopilot will get her to fly towards the GPS target regardless of the way she’s pointing.

Sadly now, I’m back from today’s Jam, and the details confront me once more, but the bus ride did yield a great view of where to go next.


P.S. As always, the jam was great; over 100 parents and kids, lots of cool things for them to see and do, including a visit this time by 2 members of local BBC micro:bit clubs.  Next one is 30th September.

Lightsaber

Just using spare time to put together a tutorial for the Autumn Cotswold Raspberry Jam.

import RPi.GPIO as GPIO
import time

RED_LED = 35
GREEN_LED = 33
BLUE_LED = 37

GPIO.setmode(GPIO.BOARD)

GPIO.setup(RED_LED, GPIO.OUT)
GPIO.setup(GREEN_LED, GPIO.OUT)
GPIO.setup(BLUE_LED, GPIO.OUT)

GPIO.output(RED_LED, GPIO.LOW)
GPIO.output(GREEN_LED, GPIO.LOW)
GPIO.output(BLUE_LED, GPIO.LOW)

#---------------------------------------------------------------
# All the LEDs are turned on every 1/100 of a second or 0.01s.
#---------------------------------------------------------------
pulse_period = 0.01

#---------------------------------------------------------------
# This is how much of the pulse period each LED stays turned on.
# After that, it gets turned off again.
#---------------------------------------------------------------
red_fraction = 0.002
red_on = red_fraction

blue_fraction = 0.003
blue_on = blue_fraction

green_fraction = 0.005
green_on = green_fraction

#---------------------------------------------------------------
# Remember the time this all started so we can work out how long
# we've been going since we started. 
#---------------------------------------------------------------
start_time = time.time()

try:
    while True:
        time.sleep(0.001)
        clock_time = (time.time() - start_time) % pulse_period


        #========================== RED =======================#

        if clock_time < red_on * pulse_period: GPIO.output(RED_LED, GPIO.HIGH) else: GPIO.output(RED_LED, GPIO.LOW) red_on += red_fraction if red_on > 1 or red_on < 0:
            red_fraction = -red_fraction
            red_on += red_fraction


        #========================= GREEN ======================#

        if clock_time < green_on * pulse_period: GPIO.output(GREEN_LED, GPIO.HIGH) else: GPIO.output(GREEN_LED, GPIO.LOW) green_on += green_fraction if green_on > 1 or green_on < 0:
            green_fraction = -green_fraction
            green_on += green_fraction


        #========================= BLUE =======================#

        if clock_time < blue_on * pulse_period: GPIO.output(BLUE_LED, GPIO.HIGH) else: GPIO.output(BLUE_LED, GPIO.LOW) blue_on += blue_fraction if blue_on > 1 or blue_on < 0:
            blue_fraction = -blue_fraction
            blue_on += blue_fraction

except KeyboardInterrupt as e:
    pass

GPIO.output(RED_LED, GPIO.LOW)
GPIO.output(GREEN_LED, GPIO.LOW)
GPIO.output(BLUE_LED, GPIO.LOW)

GPIO.cleanup()

No-fly drones

Zoe

Zoe is going to the Cotswold Jam next Saturday, and then is definitely being retired.  Her Pi0W is just not fast enough to process 680 x 680 pixel ground facing video frames required to fly on gravel / grass.  On the plus side, she’s going to be asset stripped for bigger things.

Hermione

Hermione broke her arm a while back, and the replacement has just been installed, but the weather is still too blustery.  She broke her arm in a free-fall landing; one of her CF legs took the bulk of the force, but punched a hole in her CF armpit.  As a result, in addition to the new arm, I’ve also got a new pelvis from quadframe.com for her legs which is thinner, lighter and prevents the legs from damaging the arms.  Also, because they are thinner, there’s space for larger props; When the need arises, I may well upgrade from the current T-motor 1240 CF props with the larger T-motor 1344s which are still within scope of her T-motor U3 motors.

Chloe

Chloe is back, and is Zoe’s asset stripper, primarily her Garmin LiDAR-Lite V3.  C’s only using an A+ and I don’t expect her to be any better than Zoe as a result; however, very speculatively, the only missing gap in the RPi clan is an A3.  That’s what she’s waiting for.  She’s build only from left-overs / spares / shelved pieces except for her new CF arms, again from quadframe.com – isn’t she pretty?

Chloe reborn

Chloe reborn

A3 speculation

Here’s my best guess / hope of an A3 spec, based realistically on the middle ground between a B3 and Pi0W:

  • single USB A port as per A+ to avoid power drain of ethernet / USB port chipset
  • built in WiFi as per B3* and Pi0W, freeing up the USB port for GPS
  • 4 core processor – ideally, the B2 version rather than B3, again for power consumption reasons.

No-fly Zones

The few times I’ve flown my Mavic, it’s always warned me I live in a class C ICAO airspace designation zone.  It doesn’t surprise me really with RAFs Fairford, Brize Norton, and Royal Wooten Basset all within easy cycling distance.  The Fairford Royal International Air Tattoo normally has squadrons of classic Spitfires, Hurricanes and Lancaster Bombers plus the Red Arrows flying over our back garden on my daughter’s Birthday weekend.  A couple of years back, Air Force One flew within a stone’s throw / spitting distance of our house.  I’m sure I saw ex-POTUS Barack Obama through the window eating his breakfast!  Should the POTUS Trump ever fly by, I’ll be sure to test the metaphorical distance literally.


* Ideally, the new A3 should also include a U.FL connector for a WiFi antenna allowing extended range, ideally switched between the inbuilt and external based upon the presence of an external antenna.  Worst case, I’ll add this myself.

Vanity is…

me trying to convince the audience (there were more than it looks like) how video macro-blocks could be used for lateral motion tracking (and more speculatively, vertical and rotational too).

Me and my Vanity

Me and my Vanity

There are lots more photos of yesterday’s Cotswold Raspberry Jam that aren’t soiled by my presence on facebook – check ’em out at (or even better, join) the Cotswold Jam group or follow us on Twitter.

The next Cotswold Jam with be on 26th November from 1 – 4 at the University of Gloucestershire, Park Campus, Cheltenham.

Hermione development calendar

July

Purchase:

  • New legs (awaiting arrival)
  • New PX4FLOW 1.3.1 (awaiting arrival of a slow boat from China)
  • New PCBs – X8 compatible but testing first in quad mode

August

Implement:

  • URF (and perhaps LEDDAR) height fused with double integrated accelerometer Z axis for qdz_input distance PID
  • PX4FLOW x and y velocities fused with single integrated accelerometer X, Z axes for qvx_input, qvy_input velocity PIDs
  • ignore the PX4FLOW gyro – stick with the MPU9250
  • ignore the PX4FLOW timings – stick to the MPU9250 sampling clock for integration etc
  • working compass
  • look after the kids during their summer holidays

Purchase:

  • get X8 motors and ESC but hold off installation depending on progress of above.

September

Implement:

  • GPS via USB (or 2 port hub if A3 wire built in WiFi has not been announced by then)
  • external antenna for A3 if arrived
  • test flight to GPS defined target at fixed speed / height
  • Cotswold Jam 24th September 1pm – 4pm

October

Purchase:

  • A3 (speculative arrival)

December

Implement:

  • Remove LEDDAR and instead use UART for Scanse Sweep
  • test obstacle avoidance on a GPS target flight

Cotswold Jam – date change – now 2nd July

Due to a double booking at the University of Gloucestershire, we’ve had to move the Cotswold Jam out by a week to Saturday 2nd July.  Current tickets remain valid, but if you can’t attend, please e-mail admin at cotswoldjam.org so that we can free your tickets up for others and return any voluntary donation you gave.

Thanks, and hope to see you there.

Cotswold Raspberry Jam

Cotswold Raspberry Jam

 

Feeding frenzy

My hunger to shop has just been sated: 2 new Pi Zeros + the new 8 mega pixel camera module + the Zero camera cable + Unicorm HAT and diffuser plate.

Yes, you heard me right, the latest Pi Zeros now have a camera slot.

One Zero is for showing off at the next Cotswold Jam, along with the new higher-resolution 8 megapixel camera module.  Perhaps set up as a tiny onesie cam?

The other is for Zoe – and maybe another camera too, once I’ve overcome the problem with WAPping the latest jessie, the use of which is mandatory if I want to use the new higher-res camera with her purely for FPV videos.  The new camera slot points horizontally which is great for retaining the low profile of the Pi Zero.

The unicorn and diffuser are mostly just for playing with on my main Pi.

Next frenzy will start when they launch the A3 which I’ll be transferring Phoebe to for the extra CPU cores and processor speed needed for the two LiDAR units I’ll eventually be installing.

Until then, I’ll be working on repaying my overdraft!

3 point laser tracking

This is a long detailed post – grab a cuppa if you intend to plough through.

Here’s the plan for Phoebe.

There are 3 downward facing red lasers. Two are attached to the underside of her rear arms both pointing in parallel along Phoebe’s Z axis i.e. if Phoebe is horizontal then the laser beams are pointing vertically downwards.  The third laser is handheld by a human. All are probably 5mW / Class 2 – although the power rating may need to be reduced to conform with legislation which is unclear.  5mW is safe due to the human blink reaction; 1mW is safe as long as it’s not viewed through a focusing device such as a lens.

The RaspiCam with NoIR filter is fitted in the center of Phoebe’s lower plate, also facing along her Z axis.  A red camera-style gel filter is fitted over it in the expectation that this will increase the contrast between the laser dots and the rest of the background.  The camera is set to ISO 800 – its maximum sensitivity.  The photos are low resolution to reduce the processing required.  Each shot is taken in YUV mode, meaning the first half of the photo data is luminance / brightness / contrast information.  Photos are taken as fast as possible, which may actually be only a few per second due to the lighting conditions.  The camera code runs on a separate thread from Phoebe’s main flight control code.

A typical flight takes places as follows:

Immediately prior to each flight, the camera is turned on and feeds its output into an OS FIFO.

Quadcopter take-off code is unchanged using the standard flight plan configuration to attain an approximation of the desired hover height (e.g. 3s at 0.3m/s gives roughly 90cm hover height).

Once at hover each motion processing loop, the motion processing code checks whether the FIFO is not empty, and if not empty, it is emptied and the last batch of camera data (i.e. the last shot taken) is processed.

It is scanned for bright dots and their position in the frame stored.  By using the red filter and the Y channel (brightness / contract / luminance of YUV)  from the camera, and because the lasers are fixed in Phoebe’s frame with respect to the camera, the dots should stand out in the photo, and lie between the center and the bottom corners of the photo.  If bright spots are detected in this area, there is a very high level of confidence that these are the red dots from the frame lasers.  The distance between the dots in pixels is proportional to the actual height in meters based upon the camera lens focal length.

This pixel-separation height is saved at the first pass in the hover phase and used thereafter as the target height; deviation in the separation of the dots compared to the target dot separation means a height error which is fed as target change to the vertical velocity PID.

Once the height is processed as above, any third similarly bright dot is assumed to be from the human laser.  If such a dot is not found in 5 seconds, the code moved irreversibly to descent mode.

However if a 3rd dot is found in that 5s period then it’s position relative to the frame laser dots provides targets to

  • the yaw PID so that the 3 dots form an isosceles triangle with the quad laser dots at the base and the human dot is at the peak
  • the horizontal velocity PID so that the 3 dots form an equilateral triangle.

Loss of the human dot returns to frame laser dot mode for 5 seconds to reacquire the lost human dot which if not found, triggers the irreversible standard descent mode based upon the flight plan alone.

Similarly, loss of either of the frame laser dots triggers irreversible standard descent mode but without any wait for reacquisition of the missing frame dot.

This should provide stable hover flight for as long as the battery lasts, with the option of following the human dot to take the Quad for a “walk” on a “laser leash”.

Sounds like a plan, doesn’t is?  Some details and concerns, primarily so I don’t forget:

  • -l per-flight command line control of laser tracking mode
  • mosfets to switch on lasers based on the above?  Depends on whether GPIO pins can drive 2 10mA lasers
  • Is a new PCB needed to expose GPIO switch pin for lasers? If so, don’t forget the pull down resistor!
  • Prototype can be done in complete isolation from Phoebe, using one of my many spare RPi’s along with some LEGO and my as yet unused PaPiRus e-paper screen to show dot location.  This could could then be easily battery powered for testing.

Constraints:

  • Merging a successful prototype into Phoebe requires an ‘A3’ and a rework of the PSU – currently direct feeding 5V into the RPi backfeeds the regulator (which would normally be taking input from the LiPo) causing to heat up significantly
  • None of this can take place before I’ve finished and bagged up the GPIO tutorial for the next Cotswold Jam on 30th April.