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