Hello Jeff,

I found the same bug some days ago and I reported it here on the lists. Your solution was also my first approach, but it did not work for the Integrator-part. The value ep_n is wrong for the next cycle.

But after a looooooooooot of testing I found this solution:

        // Integrator anti-windup logic:
        if ( delta_u_n > (u_max - u_n_1) ) {
            // We have to add the maxium, which is posibble and then
            // to reduce the input value for the next cylcle accordingly
            ep_n = (ep_n * u_max )/(delta_u_n+ u_n_1 );
if ( Td > 0.0 ) edf_n = (edf_n * u_max ) / ( delta_u_n + u_n_1 );
            delta_u_n =u_max - u_n_1 ;
            // delta_u_n = u_max - u_n_1;
            // ep_n = delta_u_n / Kp;
            //ep_n =- u_max/Kp;
if ( debug ) cout << "Max saturation " << " New delta_u_n = " << delta_u_n << " New ep_n = "<< ep_n << " ew edf_n = " << edf_n << endl;
        } else if ( delta_u_n < (u_min - u_n_1) ) {
            // We have to add the maxium, which is posibble and then
            // to reduce the input value for the next cylcle accordingly
            ep_n = (ep_n * u_min )/( delta_u_n + u_n_1 );
if ( Td > 0.0 ) edf_n = (edf_n * u_min ) /(delta_u_n + u_n_1 ) ;
            delta_u_n =u_min - u_n_1 ;
            // delta_u_n = u_min - u_n_1;
            // ep_n = delta_u_n / Kp;
            //ep_n =- u_min/Kp;
if ( debug ) cout << "Min saturation " << " New delta_u_n = " << delta_u_n << " New ep_n = "<< ep_n << " New edf_n = " << edf_n << endl;
        }


I tested it for a P and a PI-controller. I haven't tested yet the D-part, but I hope, it will work too

It would be nice, if you also could test this solution.

Feed back is welcome

Kind regards

Hans-Georg




Jeff McBride wrote:
I have been playing around with the autopilot this evening, and
noticed something that seems to me to be broken.

I ran into a problem where I would see a really large change in output
(delta_u_n) but the output would not change (yes, this probably also
means my gains need some adjusting), e.g.:

----- From debug output -------
Updating Yaw Stabilization
  input = 119.876 ref = 0.000610361
  ep_n = -119.875  ep_n_1 = -118.088 e_n = -119.875 ed_n = -119.876 delta_u_n =
-2.96522
P:-0.268029 I:-2.69719 D:0
 min saturation
  output = 0.982904
-------------------------------------------

So I checked the code in xmlauto.cxx and found that yes, these lines
were responsible for zeroing delta_u_n:

----------------- From xmlauto.cxx ----------------
       // Integrator anti-windup logic:
       if ( delta_u_n > (u_max - u_n_1) ) {
            delta_u_n = 0;
            if ( debug ) cout << " max saturation " << endl;
        } else if ( delta_u_n < (u_min - u_n_1) ) {
            delta_u_n = 0;
            if ( debug ) cout << " min saturation " << endl;
        }
-------------------------------------------------------------

Perhaps I am not understanding this correctly (this PID controller is
not like any I have seen before), but it seems to me that it should
read:

       // Integrator anti-windup logic:
       if ( delta_u_n > (u_max - u_n_1) ) {
            delta_u_n = u_max - u_n_1; // <--- CHANGED
            if ( debug ) cout << " max saturation " << endl;
        } else if ( delta_u_n < (u_min - u_n_1) ) {
            delta_u_n = u_min - u_n_1 // <-- CHANGED
            if ( debug ) cout << " min saturation " << endl;
        }

-Jeff

_______________________________________________
Flightgear-devel mailing list
[email protected]
http://mail.flightgear.org/mailman/listinfo/flightgear-devel
2f585eeea02e2c79d7b1d8c4963bae2d



_______________________________________________
Flightgear-devel mailing list
[email protected]
http://mail.flightgear.org/mailman/listinfo/flightgear-devel
2f585eeea02e2c79d7b1d8c4963bae2d

Reply via email to