Re: [Flightgear-devel] PID Controller Bug the next
Hans-Georg Wunder wrote: Jeff McBride wrote: The patch committed by Erik: http://cvs.flightgear.org/cgi-bin/viewcvs/viewcvs.cgi/source/src/Autopilot/xmlauto.cxx.diff?r1=1.19&r2=1.20&cvsroot=FlightGear-0.9 should fix this. This is what would happen when you set delta_u_n = u_max - u_n_1 : delta_u_n > (u_max - u_n_1) 0.6 > (0.5 - 0.0) : true delta_u_n = u_max - u_n_1 = 0.5 - 0.0 = 0.5 u_n = u_n_1 + delta_u_n = 0.0 + 0.5 = 0.5 and at the next time step let's assume that delta_u_n But consider this scenario for next step: Assume Kp = 1. This means that the previous error e_n_1 = 0.6. Say the new error e_n = 0.5. delta_u_n = Kp(e_n - e_n_1) = -0.1 Now, this new delta when aplied to the saturated output will be: u_n = 0.5 - 0.1 = 0.4 ; The correct proportional component of the output should be 0.5 In the ideal scenario, the delta_u_n = -0.1 would be applied to u_n=0.6 to yield 0.5, but because of the saturation, the P component becomes offset. This offset will be compensated for by the I component after some time, but it shouldn't have to be. As I said before, I think the best solution is to track the "true" PID output (in this case 0.6) while outputing the saturated value and disable the integral component (with either a hard or soft limit) when the controller is saturated. Hans-Georg's suggested scaling of ep_n essentially fixes the problem. The one technical problem I have come to see with this approach is that it assumes that the entire output movement into saturation is due to the P part: ep_n = ep_n*u_max/(delta_u_n+u_n) This says that, for example, if the output only moved by half of the calculated increase because of saturation, we should change the current proportional position (saved in ep_n_1)to half its calculated value. This basically works because any large movements in one step are likely to be dominated by P, and in most (if not all) cases the error generated when the output moves back out of saturation is small and quickly compensated by the I part. I believe this is why the output of his latest test run using his fix returns to 0.0019 or 0.00175 after the reference is returned to 0, rather than returning to exactly u_n=0. Clearly this error is small and will not represent a proplem in this case. -Jeff I see your point. In saturation the relation between P-Part, I-Part and D-part seems to be changed. I will verify that in the next days. Hans-Georg I have set the controller in debug mode and extracted the the values for P I and D. Every line is double, I don't know why. P:-0.1 I:-0.00058 D:-0 output = -0.100583 P:-0.1 I:-0.00058 D:-0 output = -0.100583 --> step to 0.1 P:-0 I:-0.00058 D:-0 output = -0.101167--> output is increasing due to I P:-0 I:-0.00058 D:-0 output = -0.101167 P:-0 I:-0.00058 D:-0 output = -0.10175 P:-0 I:-0.00058 D:-0 output = -0.10175 P:-0 I:-0.00067 D:-0 output = -0.102417 P:-0 I:-0.00067 D:-0 output = -0.102417 P:-0 I:-0.0005 D:-0 output = -0.102917 P:-0 I:-0.0005 D:-0 output = -0.102917 P:-0 I:-0.00058 D:-0 output = -0.1035 P:-0 I:-0.00058 D:-0 output = -0.1035 P:-0 I:-0.00058 D:-0 output = -0.104083 P:-0 I:-0.00058 D:-0 output = -0.104083 P:-0 I:-0.00058 D:-0 output = -0.104667 P:-0 I:-0.00058 D:-0 output = -0.104667 P:-0 I:-0.00067 D:-0 output = -0.105333 P:-0 I:-0.00067 D:-0 output = -0.105333 P:-0 I:-0.00058 D:-0 output = -0.105917 P:-0 I:-0.00058 D:-0 output = -0.105917 P:-0 I:-0.00058 D:-0 output = -0.1065 P:-0 I:-0.00058 D:-0 output = -0.49625 P:-0 I:-0.00058 D:-0 output = -0.49625 P:-0 I:-0.00058 D:-0 output = -0.496833 P:-0 I:-0.00058 D:-0 output = -0.496833 P:-0 I:-0.00058 D:-0 output = -0.497417 P:-0 I:-0.00058 D:-0 output = -0.497417 P:-0 I:-0.00058 D:-0 output = -0.498 P:-0 I:-0.00058 D:-0 output = -0.498 P:-0 I:-0.00058 D:-0 output = -0.498583 P:-0 I:-0.00058 D:-0 output = -0.498583 P:-0 I:-0.00067 D:-0 output = -0.49925 P:-0 I:-0.00067 D:-0 output = -0.49925 P:-0 I:-0.0005 D:-0 output = -0.49975 P:-0 I:-0.0005 D:-0 output = -0.49975 P:-0 I:-0.00067 D:-0 output = -0.5 --> Saturation, every thing is fine P:-0 I:-0.00067 D:-0 output = -0.5 P:-8.32639e-05 I:-0.0005D:-0 output = -0.5 P:-8.32639e-05 I:-0.0005 D:-0 output = -0.5 P:-0.000116517 I:-0.00058 D:-0 output = -0.5 I don't know where the P-part comes from P:-0.000116517 I:-0.00058 D:-0 output = -0.5 P:-0.000139774 I:-0.00058 D:-0 output = -0.5 P:-0.000139774 I:-0.00058 D:-0 output = -0.5 P:-0.000144413 I:-0.00058 D:-0 output = -0.5 P:-0.000144413 I:-0.00058 D:-0 output = -0.5 P:-0.000145338 I:-0.00058 D:-0 output = -0.5 P:-0.000145338 I:-0.00058 D:-0 output = -0.5 P:-0.000145522 I:-0.
Re: [Flightgear-devel] PID Controller Bug
Jeff McBride wrote: The patch committed by Erik: http://cvs.flightgear.org/cgi-bin/viewcvs/viewcvs.cgi/source/src/Autopilot/xmlauto.cxx.diff?r1=1.19&r2=1.20&cvsroot=FlightGear-0.9 should fix this. This is what would happen when you set delta_u_n = u_max - u_n_1 : delta_u_n > (u_max - u_n_1) 0.6 > (0.5 - 0.0) : true delta_u_n = u_max - u_n_1 = 0.5 - 0.0 = 0.5 u_n = u_n_1 + delta_u_n = 0.0 + 0.5 = 0.5 and at the next time step let's assume that delta_u_n But consider this scenario for next step: Assume Kp = 1. This means that the previous error e_n_1 = 0.6. Say the new error e_n = 0.5. delta_u_n = Kp(e_n - e_n_1) = -0.1 Now, this new delta when aplied to the saturated output will be: u_n = 0.5 - 0.1 = 0.4 ; The correct proportional component of the output should be 0.5 In the ideal scenario, the delta_u_n = -0.1 would be applied to u_n=0.6 to yield 0.5, but because of the saturation, the P component becomes offset. This offset will be compensated for by the I component after some time, but it shouldn't have to be. As I said before, I think the best solution is to track the "true" PID output (in this case 0.6) while outputing the saturated value and disable the integral component (with either a hard or soft limit) when the controller is saturated. Hans-Georg's suggested scaling of ep_n essentially fixes the problem. The one technical problem I have come to see with this approach is that it assumes that the entire output movement into saturation is due to the P part: ep_n = ep_n*u_max/(delta_u_n+u_n) This says that, for example, if the output only moved by half of the calculated increase because of saturation, we should change the current proportional position (saved in ep_n_1)to half its calculated value. This basically works because any large movements in one step are likely to be dominated by P, and in most (if not all) cases the error generated when the output moves back out of saturation is small and quickly compensated by the I part. I believe this is why the output of his latest test run using his fix returns to 0.0019 or 0.00175 after the reference is returned to 0, rather than returning to exactly u_n=0. Clearly this error is small and will not represent a proplem in this case. -Jeff I see your point. In saturation the relation between P-Part, I-Part and D-part seems to be changed. I will verify that in the next days. Hans-Georg ___ Flightgear-devel mailing list Flightgear-devel@flightgear.org http://mail.flightgear.org/mailman/listinfo/flightgear-devel 2f585eeea02e2c79d7b1d8c4963bae2d ___ Flightgear-devel mailing list Flightgear-devel@flightgear.org http://mail.flightgear.org/mailman/listinfo/flightgear-devel 2f585eeea02e2c79d7b1d8c4963bae2d
Re: [Flightgear-devel] PID Controller Bug?
Roy Vegard Ovesen wrote: On Thursday 29 September 2005 13:51, Hans-Georg Wunder wrote: Time, reference,input,output 09:10:00,0,0,0 09:10:01,0.6,0,-0.4999 Jump into saturation. Thats OK. Only a P-Part, no I-Part 09:10:02,0.6,0,-0.4999 snip! 09:10:13,0.6,0,-0.4999 09:10:15,0,0,0.0999Here the output value should return to zero, because there is no I-Part Maybe it should?! In this example, the output flips from the min saturation to max-saturation. In a two phase controller (climb - altitude), it impossible to control the aircraft. Are you saying that it's not possible to make cascade configurations? We've had cascade configurations since day one! The problem is, that the change of input is store in ep_n. Only the changes are given to the output. But in saturation the change is not given to the output because of the windup logic The controller gets out of sync Same test with delta_u_n =u_max - u_n_1 and ep_n = (ep_n * u_max )/(delta_u_n+ u_n_1 ); (My solution. Meanwhile I think it is not necessary to change the edf_n-value, because the windup logic is for the integrator part, but I am not completly convinced. snip! This should work in any situation. Of course I can not deny the fact that your altering of ep_n does return the output closer to zero in one time step for the open loop case, but what about the closed loop case? Open loop PID controllers are really useless. Does this altering of ep_n improve the performance when used in closed loop controllers? A simple closed loop consists of a controller and a plant and a feedback. It is one common way to describe the controller with the answer of step a function in an open loop configuration. I think that some of the "problems" that your tests expose can be traced back to the fact that you use an open loop configuration. I suggest that you do some tests with closed loop controllers to see if there is any performance gain. I also suggest that you fiddle around with the beta value, try setting it to zero. PS! I'm a bit disappointed by the BESTune application. I seems that the demo version is able to recognize the original input data, and when you try to change them it barks that it don't want to use anything but the _original_ input data. It does display the custom input data, but it does not seem to calculate useable values for Kp, Ti and Td. ___ Flightgear-devel mailing list Flightgear-devel@flightgear.org http://mail.flightgear.org/mailman/listinfo/flightgear-devel 2f585eeea02e2c79d7b1d8c4963bae2d
Re: [Flightgear-devel] PID Controller Bug?
On Thursday 29 September 2005 13:51, Hans-Georg Wunder wrote: > Time, reference,input,output > 09:10:00,0,0,0 > 09:10:01,0.6,0,-0.4999 Jump into saturation. Thats OK. > Only a P-Part, no I-Part > 09:10:02,0.6,0,-0.4999 snip! > 09:10:13,0.6,0,-0.4999 > 09:10:15,0,0,0.0999Here the output value should > return to zero, because there is no I-Part Maybe it should?! > > In this example, the output flips from the min saturation > to max-saturation. In a two phase controller (climb - altitude), > it impossible to control the aircraft. Are you saying that it's not possible to make cascade configurations? We've had cascade configurations since day one! > The problem is, that the change of input is store in ep_n. > Only the changes are given to the output. But in saturation > the change is not given to the output because of the windup logic > The controller gets out of sync > > Same test with delta_u_n =u_max - u_n_1 and ep_n = (ep_n * u_max > )/(delta_u_n+ u_n_1 ); > (My solution. Meanwhile I think it is not necessary to change the > edf_n-value, because the windup > logic is for the integrator part, but I am not completly convinced. snip! > > This should work in any situation. > Of course I can not deny the fact that your altering of ep_n does return the output closer to zero in one time step for the open loop case, but what about the closed loop case? Open loop PID controllers are really useless. Does this altering of ep_n improve the performance when used in closed loop controllers? I think that some of the "problems" that your tests expose can be traced back to the fact that you use an open loop configuration. I suggest that you do some tests with closed loop controllers to see if there is any performance gain. I also suggest that you fiddle around with the beta value, try setting it to zero. PS! I'm a bit disappointed by the BESTune application. I seems that the demo version is able to recognize the original input data, and when you try to change them it barks that it don't want to use anything but the _original_ input data. It does display the custom input data, but it does not seem to calculate useable values for Kp, Ti and Td. -- Roy Vegard Ovesen ___ Flightgear-devel mailing list Flightgear-devel@flightgear.org http://mail.flightgear.org/mailman/listinfo/flightgear-devel 2f585eeea02e2c79d7b1d8c4963bae2d
Re: [Flightgear-devel] PID Controller Bug
> The patch committed by Erik: > > http://cvs.flightgear.org/cgi-bin/viewcvs/viewcvs.cgi/source/src/Autopilot/xmlauto.cxx.diff?r1=1.19&r2=1.20&cvsroot=FlightGear-0.9 > > should fix this. This is what would happen when you set > delta_u_n = u_max - u_n_1 : > > delta_u_n > (u_max - u_n_1) > 0.6 > (0.5 - 0.0) : true > delta_u_n = u_max - u_n_1 = 0.5 - 0.0 = 0.5 > u_n = u_n_1 + delta_u_n = 0.0 + 0.5 = 0.5 > > and at the next time step let's assume that delta_u_n But consider this scenario for next step: Assume Kp = 1. This means that the previous error e_n_1 = 0.6. Say the new error e_n = 0.5. delta_u_n = Kp(e_n - e_n_1) = -0.1 Now, this new delta when aplied to the saturated output will be: u_n = 0.5 - 0.1 = 0.4 ; The correct proportional component of the output should be 0.5 In the ideal scenario, the delta_u_n = -0.1 would be applied to u_n=0.6 to yield 0.5, but because of the saturation, the P component becomes offset. This offset will be compensated for by the I component after some time, but it shouldn't have to be. As I said before, I think the best solution is to track the "true" PID output (in this case 0.6) while outputing the saturated value and disable the integral component (with either a hard or soft limit) when the controller is saturated. Hans-Georg's suggested scaling of ep_n essentially fixes the problem. The one technical problem I have come to see with this approach is that it assumes that the entire output movement into saturation is due to the P part: ep_n = ep_n*u_max/(delta_u_n+u_n) This says that, for example, if the output only moved by half of the calculated increase because of saturation, we should change the current proportional position (saved in ep_n_1)to half its calculated value. This basically works because any large movements in one step are likely to be dominated by P, and in most (if not all) cases the error generated when the output moves back out of saturation is small and quickly compensated by the I part. I believe this is why the output of his latest test run using his fix returns to 0.0019 or 0.00175 after the reference is returned to 0, rather than returning to exactly u_n=0. Clearly this error is small and will not represent a proplem in this case. -Jeff ___ Flightgear-devel mailing list Flightgear-devel@flightgear.org http://mail.flightgear.org/mailman/listinfo/flightgear-devel 2f585eeea02e2c79d7b1d8c4963bae2d
Re: [Flightgear-devel] PID Controller Bug?
I hope, this description is not to long, but I think it is very important to have a working controller code First the test results, at the end you will find the test decription for the test controller and a little nasal script for logging. o Behaviour with delta_u_n = 0 and an input jump function of 0.2 No saturation at the beginning. Time, reference,input,output 21:59:17,0,0,0 21:59:18,0,0,0 21:59:19,0,0.2,0.2008 Here I changed the input value from 0 to 0.2 and we see the proportionel gain of -1 (P-part) 21:59:20,0,0.2,0.22116665 Here the integrator part is added. 21:59:21,0,0.2,0.24149997 21:59:22,0,0.2,0.26183332 21:59:23,0,0.2,0.2822 21:59:24,0,0.2,0.30250005 21:59:25,0,0.2,0.32283342 21:59:26,0,0.2,0.34283345 21:59:27,0,0.2,0.36316682 21:59:28,0,0.2,0.38350018 21:59:29,0,0.2,0.40383355 21:59:30,0,0.2,0.42433358 21:59:31,0,0.2,0.44466694 21:59:32,0,0.2,0.46500031 21:59:33,0,0.2,0.48533367 21:59:34,0,0.2,0.49950036 Here the windup logic limits the output value to 0.5 21:59:35,0,0.2,0.49950036 21:59:36,0,0.2,0.49950036 21:59:37,0,0.2,0.49950036 21:59:38,0,0.2,0.49950036 21:59:39,0,0.2,0.49950036 21:59:40,0,0.2,0.49950036 21:59:41,0,0.2,0.49950036 21:59:42,0,0.2,0.49950036 21:59:43,0,0.2,0.49950036 21:59:44,0,0.2,0.49950036 21:59:45,0,0.2,0.49950036 Everything is fine ! Behaviour with delta_u_n = 0 and an input jump function of 0.6 Saturation at the beginning o Time, reference,input,output 21:56:54,0,0,0 21:56:55,0,0,0 21:56:56,0,0,0 21:56:57,0,0,0 21:56:58,0,0,0 21:56:59,0,0.6,0.02549 Here the P-part is missing There has to be a jump to u_max 21:57:00,0,0.6,0.08803 21:57:01,0,0.6,0.15050001 21:57:02,0,0.6,0.2131 21:57:03,0,0.6,0.2732 21:57:04,0,0.6,0.33350002 21:57:05,0,0.6,0.39350003 21:57:06,0,0.6,0.4533 21:57:07,0,0.6,0.49950004 Kind regards Hans-Georg P.S.: The test result for delta_u_n = u_max - U Test controller: Test controller false /autopilot/test/status go /autopilot/test/input /autopilot/test/reference /autopilot/test/output -1 1 1 0.0 1 0 -0.5 0.5 For logging puposes I wrote a little nasal script: # # Function to log # print_test = func { ref_log= getprop("/autopilot/test/reference"); input_log = getprop("/autopilot/test/input"); output_log = getprop("/autopilot/test/output"); time_log = getprop("/sim/time/gmt-string"); print(time_log,",",ref_log,",", input_log,",",output_log); # Re-schedule the next call if(getprop("/autopilot/test/status") != "go") { print("Log disabled"); } else { #print("Set timer"); settimer(print_test,1); } } Kind regards Hans-Georg ___ Flightgear-devel mailing list Flightgear-devel@flightgear.org http://mail.flightgear.org/mailman/listinfo/flightgear-devel 2f585eeea02e2c79d7b1d8c4963bae2d
Re: [Flightgear-devel] PID Controller Bug?
Roy Vegard Ovesen wrote: On Wednesday 28 September 2005 21:03, Hans-Georg Wunder wrote: The original problem is, when there is an input change from 0 to u_max/kp, the output value is zero. This is wrong. It has to be u_max. The fix from Erik was also my first approach. But it does not solve the problem. Under some circumstances the controller stays in saturation for ever. If you tune the PID controller to be a P only controller (Ti=inf, Td=0) then this can happen because of steady state error that can not be reduced by a P only controller. Maybe I did not stress this enough in my last post on this subject: The velocity form of the PID controller should _not_ be used as a P only controller! I do not talk about a P only controller and about the steady state error of a P only controller. The error happens, when the input value is a step function, which drives the controller directly into the windup logic. Then the output value is zero. All other cases are working fine. I found a site with a good explanation of the PID equation: http://bestune.50megs.com/typeABC.htm There is no windup logic in these equations. The equation that most of the controllers in FlightGear autopilots use is the type B. The equations here are of the independent type. We use the dependent type, but that does not matter. Our PID equation is actually able to act as type A, through type B to type C. This is done with the gamma and beta values. Gamma is the weighing of the reference for the derivative error: ed_n = gamma * r_n - y_n. beta is the weighing for the proportional error: ep_n = beta * r_n - y_n. So for a type A controller we would set gamma = 1 and beta = 1. For the type B, gamma = 0 and beta = 1, and finally for type C, gamma = 0 and beta = 0. Notice that we have complete power over how much we want to weigh the reference value for the derivative and proportional error term. I think, my solution solves the problem, but it would be great, if Jeff is also able to test it. The guys at BESTune claims that the type C controller is the best. I suggest that you try setting beta = 0 to make you controllers type C. I'm sorry but I'm very sceptical to your idea of altering ep_n and ed_n on saturation. Also on BESTune's site they have a demo of their BESTune application. It's Windows only, but I'm very exited about this app. I'm going to try and test it this weekend. I suggest that you check it out too. I really think that it can prove to be very helpfull in tuning our controllers. First of all I will do some tests to clarify my problem and my solution. Thank you for your detailed answer Hans-Georg ___ Flightgear-devel mailing list Flightgear-devel@flightgear.org http://mail.flightgear.org/mailman/listinfo/flightgear-devel 2f585eeea02e2c79d7b1d8c4963bae2d
Re: [Flightgear-devel] PID Controller Bug?
See below... On 9/28/05, Roy Vegard Ovesen <[EMAIL PROTECTED]> wrote: > On Wednesday 28 September 2005 21:03, Hans-Georg Wunder wrote: > > The original problem is, when there is an input change from 0 to > > u_max/kp, the output value is zero. This is wrong. It has to be u_max. > > The fix from Erik was also my first approach. But it does not solve the > > problem. Under some circumstances the controller stays in saturation for > > ever. > > If you tune the PID controller to be a P only controller (Ti=inf, Td=0) then > this can happen because of steady state error that can not be reduced by a P > only controller. Maybe I did not stress this enough in my last post on this > subject: But in some cases, such as when Kp*e is greater than u_max-u_n, the output is not changed. It isn't that the proportional output is not enough to get rid of the error, it is that the proportional output is being ignored because it would put the output past the user set limit. The correct behaviour should be to move the output to the user limit. > > The velocity form of the PID controller should _not_ be used as a P only > controller! > > I found a site with a good explanation of the PID equation: > > http://bestune.50megs.com/typeABC.htm > Good site! > > The guys at BESTune claims that the type C controller is the best. I suggest > that you try setting beta = 0 to make you controllers type C. I'm sorry but > I'm very sceptical to your idea of altering ep_n and ed_n on saturation. I can see your problem with it. In fact, I think it may be technically wrong because it assumes that the proportional component is the only thing contributing to the saturation of the controller. But something must be done to correctly handle saturation. One possibility would be to internally track the actual PID output when it goes past saturation (but limit the output value). This does not provide any anti-windup protection though, so some kind of anti-windup would need to be added. One method I have found referenced at several sites uses the amount of saturation as a feedback to the integral term: v_n : PID calculated output u_n : Control output (u_n = v_n except in saturation, when it equals u_max or u_min) s_n : saturation (s_n = u_n - v_n) Then the integral contribution would be I = Ki*e_n + Ks*s_n (Ks defines how tightly windup is controlled). > > Roy Vegard Ovesen > -Jeff ___ Flightgear-devel mailing list Flightgear-devel@flightgear.org http://mail.flightgear.org/mailman/listinfo/flightgear-devel 2f585eeea02e2c79d7b1d8c4963bae2d
Re: [Flightgear-devel] PID Controller Bug?
On Wednesday 28 September 2005 21:03, Hans-Georg Wunder wrote: > The original problem is, when there is an input change from 0 to > u_max/kp, the output value is zero. This is wrong. It has to be u_max. > The fix from Erik was also my first approach. But it does not solve the > problem. Under some circumstances the controller stays in saturation for > ever. If you tune the PID controller to be a P only controller (Ti=inf, Td=0) then this can happen because of steady state error that can not be reduced by a P only controller. Maybe I did not stress this enough in my last post on this subject: The velocity form of the PID controller should _not_ be used as a P only controller! I found a site with a good explanation of the PID equation: http://bestune.50megs.com/typeABC.htm The equation that most of the controllers in FlightGear autopilots use is the type B. The equations here are of the independent type. We use the dependent type, but that does not matter. Our PID equation is actually able to act as type A, through type B to type C. This is done with the gamma and beta values. Gamma is the weighing of the reference for the derivative error: ed_n = gamma * r_n - y_n. beta is the weighing for the proportional error: ep_n = beta * r_n - y_n. So for a type A controller we would set gamma = 1 and beta = 1. For the type B, gamma = 0 and beta = 1, and finally for type C, gamma = 0 and beta = 0. Notice that we have complete power over how much we want to weigh the reference value for the derivative and proportional error term. > I think, my solution solves the problem, but it would be great, if > Jeff is also able to test it. The guys at BESTune claims that the type C controller is the best. I suggest that you try setting beta = 0 to make you controllers type C. I'm sorry but I'm very sceptical to your idea of altering ep_n and ed_n on saturation. Also on BESTune's site they have a demo of their BESTune application. It's Windows only, but I'm very exited about this app. I'm going to try and test it this weekend. I suggest that you check it out too. I really think that it can prove to be very helpfull in tuning our controllers. -- Roy Vegard Ovesen ___ Flightgear-devel mailing list Flightgear-devel@flightgear.org http://mail.flightgear.org/mailman/listinfo/flightgear-devel 2f585eeea02e2c79d7b1d8c4963bae2d
Re: [Flightgear-devel] PID Controller Bug?
Hans-Georg Wunder wrote: It would be great, if you also test the code. This PID code has been working well (and untouched for quite some time now.) What bug/problem are we trying to fix here? Curt. -- Curtis Olsonhttp://www.flightgear.org/~curt HumanFIRST Program http://www.humanfirst.umn.edu/ FlightGear Project http://www.flightgear.org Unique text:2f585eeea02e2c79d7b1d8c4963bae2d ___ Flightgear-devel mailing list Flightgear-devel@flightgear.org http://mail.flightgear.org/mailman/listinfo/flightgear-devel 2f585eeea02e2c79d7b1d8c4963bae2d
Re: [Flightgear-devel] PID Controller Bug?
It would be great, if you also test the code. Hans-Georg Jeff McBride wrote: Ahh, yes. I see your point. Since the change in output is based on change in error (not current error), if the amount of output shift is altered but the last error (ep_n_1) is not the two will effectively become out of sync. In fact, the same thing must have been happening when delta_u_n was being set to 0 when saturation occurred. But, the integral component should correct for this after a little bit. I am not convinced that you need to adjust edf_n, or that you should. IMHO, there is no reason that the rate of change information cannot be used when the controller is in saturation, and there is no way for the derivative error to "wind-up". But I agree with your scaling of ep_n to match the change in output. Good call. It looks like Erik did commit a patch, and it looks like it does not include your adjustment to ep_n. So, it is still broken (though, I think it may be an improvement). I don't currently have a linux box to compile FG on, and I have not tackled the problem of compiling on Visual Studio, so I am unable to test this code at the moment (though I will have a linux box for development soon!). I appreciate all the development everyone has done, as I have found FG to be a great tool for both work and play. Hopefully I can find some way to contribute myself in the near future. -Jeff ___ Flightgear-devel mailing list Flightgear-devel@flightgear.org http://mail.flightgear.org/mailman/listinfo/flightgear-devel 2f585eeea02e2c79d7b1d8c4963bae2d ___ Flightgear-devel mailing list Flightgear-devel@flightgear.org http://mail.flightgear.org/mailman/listinfo/flightgear-devel 2f585eeea02e2c79d7b1d8c4963bae2d
Re: [Flightgear-devel] PID Controller Bug?
The original problem is, when there is an input change from 0 to u_max/kp, the output value is zero. This is wrong. It has to be u_max. The fix from Erik was also my first approach. But it does not solve the problem. Under some circumstances the controller stays in saturation for ever. I think, my solution solves the problem, but it would be great, if Jeff is also able to test it. Hans-Georg Curtis L. Olson wrote: I seem to recall Erik commited a change to the autopilot code in the last week or so. Does that fix something? Did that introduce a new problem? This is pretty subtle, complex code so people shouldn't be messing with it too much unless they are really sure they know what's going on with it. Curt. snip-- ___ Flightgear-devel mailing list Flightgear-devel@flightgear.org http://mail.flightgear.org/mailman/listinfo/flightgear-devel 2f585eeea02e2c79d7b1d8c4963bae2d
Re: [Flightgear-devel] PID Controller Bug?
Ahh, yes. I see your point. Since the change in output is based on change in error (not current error), if the amount of output shift is altered but the last error (ep_n_1) is not the two will effectively become out of sync. In fact, the same thing must have been happening when delta_u_n was being set to 0 when saturation occurred. But, the integral component should correct for this after a little bit. I am not convinced that you need to adjust edf_n, or that you should. IMHO, there is no reason that the rate of change information cannot be used when the controller is in saturation, and there is no way for the derivative error to "wind-up". But I agree with your scaling of ep_n to match the change in output. Good call. It looks like Erik did commit a patch, and it looks like it does not include your adjustment to ep_n. So, it is still broken (though, I think it may be an improvement). I don't currently have a linux box to compile FG on, and I have not tackled the problem of compiling on Visual Studio, so I am unable to test this code at the moment (though I will have a linux box for development soon!). I appreciate all the development everyone has done, as I have found FG to be a great tool for both work and play. Hopefully I can find some way to contribute myself in the near future. -Jeff ___ Flightgear-devel mailing list Flightgear-devel@flightgear.org http://mail.flightgear.org/mailman/listinfo/flightgear-devel 2f585eeea02e2c79d7b1d8c4963bae2d
Re: [Flightgear-devel] PID Controller Bug?
I seem to recall Erik commited a change to the autopilot code in the last week or so. Does that fix something? Did that introduce a new problem? This is pretty subtle, complex code so people shouldn't be messing with it too much unless they are really sure they know what's going on with it. Curt. Hans-Georg Wunder wrote: 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 looot 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 Flightgear-devel@flightgear.org http://mail.flightgear.org/mailman/listinfo/flightgear-devel 2f585eeea02e2c79d7b1d8c4963bae2d ___ Flightgear-devel mailing list Flightgear-devel@flightgear.org http://mail.flightgear.org/mailman/listinfo/flightgear-devel 2f585eeea02e2c79d7b1d8c4963bae2d -- Curtis Olsonhttp://www.flightgear.org/~curt HumanFIRST Program http://www.humanfirst.umn.edu/ FlightGear Project http://www.flightgear.org Unique text:2f585eeea02e2c79d7b1d8c4963bae2d ___ Flightgear-devel mailing list Flightgear-devel@flightgear.org http://mail.flightgear.org/mailman/listinfo/flightgear-devel 2f585eeea02e2c79d7b1d8c4963bae2d
Re: [Flightgear-devel] PID Controller Bug?
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 looot 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 Flightgear-devel@flightgear.org http://mail.flightgear.org/mailman/listinfo/flightgear-devel 2f585eeea02e2c79d7b1d8c4963bae2d ___ Flightgear-devel mailing list Flightgear-devel@flightgear.org http://mail.flightgear.org/mailman/listinfo/flightgear-devel 2f585eeea02e2c79d7b1d8c4963bae2d