BOUNDING PID INTREGRATED ERROR & OUTPUT

  Hi All

 

   I know that this subject has been beaten to death, but I'm new to this algorithm and I've done some research and put together a small function that is intended to control the throttle on my UAV.  I have a maximum input to the speed controller of 1.0 and a minimum input of -1.0.  In addition to that I have also a maximum increment of 0.1 and a minimum decrement of -0.1.  Now with that said I of course need to somehow keep the PID algorithm from spitting out wild values which will cause overshoot and errors in the controller.  Can you guys take a look at the snipped of code below and point me in the right direction here.

 

update_throttle_pid.h

 

float update_throttle_PID( float target_velocity )

{

float suggested_incr, throttle_error, throttle_minimum_incr;

 

throttle_error = (velocity - target_velocity);

 

if ( (throttle_integrated_error + throttle_error * DATA_RATE) > 1.0) { throttle_integrated_error = 1.0; }

else if ( (throttle_integrated_error + throttle_error * DATA_RATE) > -1.0) { throttle_integrated_error = -1.0; }

else { throttle_integrated_error += throttle_error * DATA_RATE; }

 

suggested_incr = throttle_error * .001 + throttle_integrated_error * 0.0001 + velocity_derivative * 1.0;

 

if ( suggested_incr > 0.1 ) {

 

throttle_minimum_incr = 0.1;

 

} else if ( suggested_incr < -0.1 ) {

 

throttle_minimum_incr = -0.1;

 

} else {

 

throttle_minimum_incr = suggested_incr;

 

}

 

return ( throttle_minimum_incr );

}

You need to be a member of diydrones to add comments!

Join diydrones

Email me when people reply –

Replies

  • Only found one error, here's the correction

    /*...*/

    else if ( (throttle_integrated_error + throttle_error * DATA_RATE) < -1.0) { throttle_integrated_error = -1.0; }

    /*...*/

     

     I really must ask about this statement though:

    throttle_integrated_error += throttle_error * DATA_RATE

     

    Is this statement where you do your integration?

     

    If so, your not doing the "real" integration, but rather what is called the Discrete-Time Integration (a better name for it is accumulation).

     

    If you can remember back to Calculus 1 & 2, there where several approximations to integrating, one of them of course is the Riemann sum. The Riemann sum can be thought as the accumulation of quadrahedrons.

     

    Imagine a rectangle with a base of Ts and a height of x( k ). The area of this rectangle then would be:

    x( k ) * Ts

     

    Now, to do a Right-sum integral of x( k ):

    y = from k = 0 to infinity { sum( x( n ) * Ts ) }

     

    A single iteration of a Right-sided Reimann sum in the C languague would be:

    y += x * Ts;

     

    The disadvantage to Ride-side Reimann sums is that there's some area that is not accounted for during each iteration. This is practically unavoidable, however, and the only way to get a more accurate integral is to decrease the sampling period.

     

    However, a more accurate Reimann sum may be done by using the Trapezoidal Rule, which uses trapazoids instead of rectangles to approximate the area:

    y = from k = 0 to infinity { sum( ( x[ k ] - x[ k-1 ] ) * ( Ts / 2 ) )  }

     

    In the C langauge, a single iteration would be:

    y += ( x[ k ] - x[ k-1 ] ) / (Ts / 2);

     

    Since trapezoids fit curves more closely than rectangles, the integral is more accurate and with less error.

    In a different way of thinking, the trapezoid rule linearly interpolates the curve between the sample points before caclulating the area beneath it.

     

    As always, the disadvantage of increased accuracy is more memory usage and slower execution (you have to store the previous data sample to perform the Trapezoidal Rule.) Try out both, and see which one works best for your UAV.

This reply was deleted.

Activity