Slow Flight with APM - mastering the PID on the edge of stall

One of the features of extreme high altitude flight is the high true airspeeds that are needed to generate the dynamic pressure required for airborne flight.  To minimise these extreme speeds for my high altitude glider project, I wanted to increase the flyable operation envelope closer to the airframe's stall speed, helping the reign-in the stratospheric true airspeeds!

As I was playing about tuning the roll and pitch control PID loops using my airframe model in an X-plane HIL simulation, I discovered that a relatively large amount of derivative could yield some dramatic improvements to roll control when on the edge of the stall condition.  The D term could be wound up at least an order of magnitude higher than could be tolerated at higher speeds.

To make use of this feature, I forensic'd my way through the codebase and the APM libraries to add a non-linearity to the PID speed scalar as it is applied to the derivative term.  I did this by tweaking the PID.css file in the PID Arduino library folder (not the AP_PID, as it took me a while to discover..!)  The mods are:

PID::get_pid(int32_t error, uint16_t dt, float scalar)
 float output  = 0;
  float delta_time = (float)dt / 1000.0;
 float deriv_scalar = (scalar - 0.5);

 // Compute proportional component
 output += error * _kp;

 // Compute derivative component if time has elapsed
 if ((fabs(_kd) > 0) && (dt > 0)) {
  float derivative = (error - _last_error) / delta_time;

  // discrete low pass filter, cuts out the
  // high frequency noise that can drive the controller crazy
  float RC = 1/(2*M_PI*_fCut);
  derivative = _last_derivative +
          (delta_time / (RC + delta_time)) * (derivative - _last_derivative);

  // update state
  _last_error   = error;
  _last_derivative    = derivative;

  // add in derivative component
  deriv_scalar *= deriv_scalar;
  deriv_scalar = max(0,deriv_scalar);
  output     += _kd * derivative * deriv_scalar;

 // scale the P and D components
 output *= scalar;

(Oh, and I corrected the spelling of scalar too!)

I have also expanded the clipping of the speed scalar delivered to the PID controller from the normal 0.5-2.0 in the standard APM codebase, to 0.01-5.0  I also chose to tune the controller with the reference speed to be the stall speed of the aircraft (7m/s) instead of the default cruise speed (25m/s).

The funny (scalar-0.5) term I have used to increase the decay of the term away from the stall speed without getting into complicated and CPU intensive maths.  This allows a higher derivative gain to be used without unduly influencing normal flight. 

So, having got this compiled and working in APM and X-plane, here are the results:

When I glide towards the stall speed in stabilise mode, holding as best I can, a level flight path, but with the roll control derivative term zeroed, which is more or less how I have tuned the controller till now, the airframe slows to approximately 16-17kts before a divergent roll instability develops.  This instability can develop at slightly higher speeds too, but the main characteristic is once it develops, it is properly divergent.  There is no saving it, except for a rapid pitch down and acceleration.

With the non-linear D term applied, I can now achieve relatively reliable roll control very close to the stall speed.  The divergent instability is still there, but it is at a higher frequency and a much lower speed, clearing the way for operation much closer to the stall break than was possible before.

This work was done in X-plane 9, using an airframe model of my own forward-swept flying wing concept.  The APM code was modified from Arduplane 2.28, using Michael Oborne's AP Mission Planner 1.1.42




Views: 2465

Comment by Mark Colwell on March 13, 2012 at 6:53am

Nice !

We need more analysis of this caliber, Thanks and continue please..

Comment by Ryan Beall on March 13, 2012 at 7:43am

I'm pretty sure there are gain de-weighting based on indicated airspeed.  Beings your true airspeed is relatively constant for normal 0-400ft agl flights this isn't a bad assumption.  However, in your case you really should estimate your true airspeed and deweight the PID's based on that.  I'd probably use the 2% per 1000' rule of thumb and see how close  that gets you.  That should help linearize your controls for sure beings a PID is a PID for a given dynamic pressure!


Comment by Simon Wunderlin on March 13, 2012 at 11:21am

Andrew Rabbitt wrote:

... my own forward-swept flying wing concept ...

Care to share a little bit more info on this or is it a top secret skunk work project?



Comment by Chris Card on March 13, 2012 at 1:06pm

This is quite interesting, I'd been wondering if ,(given the right aircraft with large control surfaces) the stabilize mode would be able to "pan-cake" the aircraft while it dropped altitude in a stall.

Comment by fix8oscill8 on March 13, 2012 at 4:08pm

Very nice!

Why did you tweak the .css file instead of the AP_PID code?

Comment by Andrew Rabbitt on March 13, 2012 at 4:20pm

@Monroe - I barely understand it myself, but it seems to work! :)

@Ryan - The de-weighting on IAS still is there.  I have just added additional de-weighting for the derivative term and made it, in effect, a 1/v³ law to eliminate the effect as quickly as possible as you accelerate away from the stall.  In normal cruise flight, I can't get much satisfaction out of the derivative term, so I usually leave it at zero.  The IAS/TAS is another issue entirely.  I think this D - de-weighting needs to be a function of IAS/EAS (as is the stall condition), whereas the general gain de-weighting needs to be a function of TAS.  I'm not sure if I can do this in the simulation, whether APM-MP drags across enough info from X-plane to allow me to do the IAS-TAS calculation.  I need to look at this!

@Simon.  Soon!  Very soon! ;)

@Chris Card:  Possibly, but I think the descent rate would be still huge.  I can't think of a reason why you'd want to do this, apart from being quite cool, but maybe you can imagine something useful to use such capability for.

@fix8oscill8:  The AP_PID doesn't appear to be used.  At least I spent a bunch of time modifying it and wondering why there was no effect.  It wasn't until I read through the code carefully that I discovered that there was a PID library function as well as an AP_PID.  I don't know why the duplication, but it's confusing... 

Comment by Ryan Beall on March 14, 2012 at 7:40am

An easy estimation is:

TAS = 1.02*((altitude - sealevel_altitude)/1000)+IAS;

Comment by Gary Hunkin on March 14, 2012 at 1:09pm
Stall warning indicators come in several forms. I prefer airspeed measurement mixed with an airvane mounted in a laminar airflow region such as the side of the aircraft near the nose. This is for pusher configurations. The vane is damped to ensure it does not oscillate. It will then point in the direction of airflow. In a stall situation air will cause the vane to point away from the nose direction. Couple this with airspeed and wing position compared to level and you can begin to predict stall and tip stall. The Beechjet 400A is a prime example.
Comment by Andrew Rabbitt on March 14, 2012 at 3:59pm

Ryan, it depends on what you need TAS for, but even so I think there's something wrong with your estimate model.  Here's my results of your calculation, but maybe I've got something wrong...?

Gary, I think it should be possible to do stall estimation entirely within software, meaning no pesky hardware complications are necessary.  Of course you have to model the entire airframe and know it's C_L and C_D characteristics, but these can be estimated by logging the appropriate data on a flying aircraft.  Anyway, my objective isn't to have stall warning, but to have the flight conttroller allow flight as close to the stall as possible, but limiting it at some stall margin (1.2*Vs or similar).  Obviously, some allowance has to be made for vertical air currents disturbing the system more quickly than it can measure and react to.

Comment by Ryan Beall on March 14, 2012 at 4:33pm

Well it is for sure a linear approximation.  The actual equation is the square root of the density ratios recalling from the top of my head so it for sure isn't linear but it is just the rule of thumb used for pilots.  We like to keep it simple.  It's like the required decent rate equation for a 3 degree glideslope.... 5 x groundspeed = rate of decent in fps.  Just a ballpark figure.  If you want to get a more accurate model you would have to calc your density on the ground and then density at altitude either using an atmospheric model or back it out using temp and pressure.  Let me know if you need me to bounce you some equations.  I got them laying around, but work is kinda crushing me at the moment.  


You need to be a member of DIY Drones to add comments!

Join DIY Drones


Season Two of the Trust Time Trial (T3) Contest 
A list of all T3 contests is here. The current round, the Vertical Horizontal one, is here

© 2020   Created by Chris Anderson.   Powered by

Badges  |  Report an Issue  |  Terms of Service