Why did I choose autonomous flight control?

Right at the beginning of this project, 18 months ago, I assumed autonomous control was a necessary precursor to introducing a human into the mix for safeties sake.  18 months later I have just realized it’s the replacement for the human.  As I mentioned in yesterday’s post, none of the PIDs shown in a google image search have an integrated accelerometer velocity PIDs – they use a human with an RC transmitter and eyes to provide the outer most feedback loop.

The replacement for the human needs a motion sensor which can also measure distance travelled.  There are off-the-shelf solutions here and here and projects based on some google phone technology (cheers Jeremy).

What they share if you look hard enough is the fact they are being used as PhD or above papers in some of the best Universities in the world.

I’d looked at motion detection previously and the RaspberryPi forums did offer DIY ideas and commercial solutions, based upon static orf video image processing using image change processing to produce motion detection.  But again it all seemed too tricky based upon the fact off-the-shelf drones don’t do it.

I’d also tried accelerometer calibration using temperature trends to ensure regardless of temperature, the accelerometer offset / gain was known.  But I abandoned these for the same reason: nobody else bothers.

But now I finally understand why nobody else bothers – they have a human included in their feedback loop, still using an optical positioning system but with a much more powerful processor to control drift.

I really don’t want to introduce a human into the control loop – that was never part of my original plan.

So where to next? My short term target is only a 20 – 30s flight with minimal drift.  I would hope that the combination of trend-line accelerometer offsets and gains, combined with a few fixes applied since then may be able to achieve it.

Once more, we shall see.

 

Dodo!

Or in fact “D’oh! D’oh!”.  As you might guess, two bugs / enhancements found while snoozing on the sofa, musing over some of this morning’s flights:

  1. if you have nested PIDs, try to only include the integral gain in the outermost PID to ensure best performance.  Therefore tune from inner to outer (i.e. next outer gains set to 0 when tuning inner), and once tuned, increase the tuned inner P gain by up to 50%, set the I gain to 0, and reenable the next PID gains – i.e. tune angular rate, absolute angle and horizontal speed in that order.
  2. If you’re going to change how you calculate the Euler angles to match the coordinate system of the gyro angles, you really ought to change the Matrix used so that X, Y and Z angles are wholly independent (i.e. no sines).

Not finished yet with the inside-out re-tuning, but the progress so far looks promising.

Chapter 4: PID gain guesswork.

So I now have 2 new PIDs, which means 6 new PID gains to be guessed / tuned.  I can half that as Phoebe is pretty well balanced so left / right PID gains can be used for front / back PIDs too, but that still leaves me to tune 3.

To start off with (and this may be a permanent condition), I’m going to discount the I and D gains across the board, leaving only the P gain to run, so I’m down to 1.

This remaining gain does the translation from horizontal speed “error” to tilt angle speed “target”.

In a 5mph wind (which is about 2.2m/s), lets guess Phoebe needs to tilt 5 degrees. Let’s not rush her to reach that 5 degree angle – lets give her a second; that means a 2.2m/s horizontal speed needs to result in a 5 degrees per second tilt speed.  Her well tested tilt speed P gain is 2.5, which means her horizontal speed gain should be roughly 1 (1 * 2.2 * 2.5 ≈ 5).  That’ll certainly do as a starting position…but each sensor read happens every 0.01s (100Hz), and given that the vertical speed is the summing over time (v = ∑ acceleration δt), the “input” to the PID is reduced by a factor of ~100 by the δt factor, so we need a P gain ≈ 100 times greater – so in fact, I’ll start with 100 as a trial.

Wish me luck!

Chapter 3: Combining the PIDs

Imagine Phoebe is in a wind free stable hover; a headwind picks up; the X axis accelerometer sensor detects the rearwards drift, and as a result of the PID processing, Phoebe’s nose tilts down to compensate for the headwind.  Simples – until you follow the detail through:

Phoebe’s rearward drift is detected by the accelerometer sensors as a negative horizontal acceleration (as seen in the Prologue), which integrates as a negative horizontal speed.  This is the “input” in the horizontal speed PID, where the “target” is set to 0 drift speed.  This results in a positive “output” from the PID which is then fed into the pitch rate PID as its “target”; the pitch rate “input” comes direct from the gyro; this is 0 degrees per second currently due to the hover leading to a positive “output”.  This PID output needs to drop Phoebe’s nose.  This means the “output” is added to the rear blades and subtracted from the front, which luckily is what the code does in her current role as pitch stability control.  As Phoebe’s nose drops, the rearward drift reduces, and this feeds back to the horizontal speed PID, leading to a smaller positive “output” from the horizontal speed PID.  This then reduces the the pitch rate “target”, and thus reduces the difference in output to the front / back blades, until the rearwards drift becomes 0, and the pitch rate becomes 0.  At this point, Phoebe’s has attained a fixed angle stable hover providing exactly the right amount of power to compensate for the wind drift.

Now imagine the equivalent, but the wind is blowing from the left hand side; the Y axis accelerometer sensor detects the rightwards drift, and as a result of the combined PID processing, Phoebe’s left side tilts down to compensate for the sidewind.  Again, let’s follow this through the PID processing:

Phoebe’s rightward drift is detected by the accelerometer sensors as a negative horizontal acceleration (as seen in the Prologue), which integrates as a negative horizontal speed.  This is the “input” in the horizontal speed PID, where the “target” is set to 0 drift speed.  This results in a positive “output” from the PID which is then fed into the roll angle speed PID as its “target”; the roll angle “input” is the roll speed gyro sensor and is currently 0 degrees per second due to the stable hover, leading to a positive “output” from this PID.  This PID output needs to drop Phoebe’s left side.  This means the “output” is added to the right hand blades and subtracted from the left, which is not what the code does in its current role as roll stability control.  The roll rate PID is correct, so it’s the “output” from the horizontal speed PID which needs to be negated before being used as the roll rate PID “target”.  With that done, as Phoebe’s left-side drops, the rightward drift reduces, and this feeds back to the horizontal speed PID, leading to a smaller positive “output” from the horizontal speed PID.  This then reduces the the roll rate “target”, and thus reduces the difference in output to the left / right blades, until the rightward drift becomes 0, and the roll rate becomes 0.  At this point, Phoebe’s has attained a fixed angle stable hover providing exactly the right amount of power to compensate for the wind drift.

Sorted!  Now to put theory into practise but first, Chapter 4…

 

Where next?

Phoebe has pretty much answered the question: she took off from as good an approximation of a horizontal surface as I could come up with, and yet, once airborne, she drifted backwards. This is the polar-opposite of being able to control her flight in a desired direction; if I can stop this drift for a vertical take-off, then I can apply the opposite logic to apply drift for horizontal movement.

First step as always is to have a nosey through Phoebe’s stats from the flight, in particular the x-axis accelerometer output (plus integral for speed), and engage the outer horizontal-speed PIDs to produce the targets for the inner angular PID (which actually drives lateral speed); the unwarranted horizontal movement is stopped by a managed tilt upwards the same direction (i.e. a backwards drift will be stopped by raising Phoebe’s rear blades, and tilting down her forward ones).

But before I get too engrossed, I think Phoebe and I are due some free-play time together!

One last thing – some stats from a separate flight that day showing two things:

First how much effort is required to maintain stable yaw – about 17% more power is applied to the CW blades than to the ACW blades – that surprised me given that in theory at least, the motors and blades are nigh on identical, and the body is well balanced.  I’ll have to have a think:

YAW stats

YAW stats

Secondly, a plot of acceleration, speed, and height, all derived from the accelerometer; I’m particularly impressed with the speed and height results, particularly as they are just integrated from the acceleration, and the fact that as the applied power drops, you can see the controlled drop in height as expected.  Bodes well for a more automated takeoff.  Units on the left at meters per second per second, meters per second or meters for acceleration, speed and height respectively.  Units on the right are the motor power between 0 and 1000 (PWM pulse width in microseconds)

Vertical Height, Speed and Acceleration

Vertical Height, Speed and Acceleration

 

P(PI) + I

As I’ve mentioned previously, I’m using nested PIDs.  The outer one controls absolute speed in a given direction (in meters per second) or absolute angle (in degrees).  Fed with the required speed / angle as the target, these outer PID outputs are used as the targets for the accelerometer / gyroscope PIDs to produce acceleration / angular speed – all well and good.

But there’s another point here – the above only need “P(PI)” nest; that final “+ I” provides a different function: it deals with permanent stable factors that need a stable level of compensation, such as the difference between the output where the blades start to spinning when sitting stably on the ground and the blade spin speeds needed for the drone to sit stably in mid-air.

Other uses included compensating for a drone which is significantly unbalanced for example due to a heavy DSLR camera strapped on the front.

Another would be for a drone whose motors / blades are out of balance somehow such that the drone permanently spins on the z-axis (yaw) – you can see where I’m going now!

So for a drone whose clockwise (CW) motors spin slightly faster than the anticlockwise (ACW) motors, the drone itself would slowly rotate CW – if you then get the “P(PI)” output the wrong way round, it spins increasingly quickly CW, until it’s tethers wrap themselves up in a spiral and the drone crashes violently – sound familiar?

Anyway, if the “P(PI)” output is set up the right way, that can compensate for the constant yaw error produced by the blade / motor differences.  The downside is however, this requires quite a high “P(PI)” gain compared to just fixing minor deviation in desired yaw due to change in the yaw target.

And that’s where the final “+ I” steps in – by feeding the desire yaw “+ I” output directly to the blades, it can integrate up the angular yaw error, and provide constant compensation independent of the P(PI) which, using more subtle gain, can compensate for the subtle dynamic changes.

One final point – although the take-off speed already uses the “+ I” to control take-off speed, once the drone moves into hover mode, a snapshot of the “+ I” factor is recorded, and used instead.  There are several reasons for this approach:

  • the takeoff speed is ultimately driven by the accelerometer, which is very noisy.
  • this noise feeds into the speed integration meaning the speed output / acceleration target would become very inaccurate over time
  • in addition fact that the “+ I” gain is very high could lead to huge bouncing up and down in flight.

In writing that, I’ve just realized my snapshot is taken at the wrong point (end of takeoff rather then start of hover), which also might have contributed to the crash the other day.  Oops!