How to modify H-infinity controller set up to scale controller output?

21 vues (au cours des 30 derniers jours)
Jiten Parmar
Jiten Parmar le 11 Mai 2023
Commenté : Jiten Parmar le 16 Mai 2023
I have the linear wind turbine model as follows:
b1=-356.3851;
b2=145.1693;
Bd=6.215E6;
Kd=8.67637E8;
Jr=38677056;
Jg=534.116;
N=97;
R=63;
p=1.225;
A=[(b1-Bd)/Jr Bd/(N*Jr) -Kd/Jr;
Bd/(N*Jg) -Bd/(N^2*Jg) Kd/(N*Jg);
1 -1/N 0];
B=[0 b2/Jr;
-1/Jg 0;
0 0];
C=[1 0 0];
D=[0 0];
lin=ss(A,B,C,D);
lin.InputName={'tg','v'}; %tg is control signal, v is external input (disturbance)
lin.OutputName={'wr'}; %output is rotor speed which is to be controlled
Then the closed loop system:
R=tf(1); %gain of 1 to make the summation block
R.u='faker'; R.y='r'; %r is the reference
error=sumblk('e=wr-r');
We = makeweight(40,[1000000,0.3],0);
We.u='e'; We.y='we';
lincon=connect(lin,R,error,We,{'v','tg','faker'},{'wr','we','e'});
Controller synthesis and closed loop with controller:
[KH,g0,g]=hinfsyn(lincon,1,1);
KH=balred(KH,3);
KH.u='e'; KH.y='tg';
Con=connect(lincon,KH,{'v','faker'},{'wr','we'});
step(Con)
As you can see on the top right graph (from faker (which is the same as r) to the output wr), the settling time is around 15 seconds. I reached this after a ton of experimentation with regards to the error weight We. Firstly, if there is a way to obtain a settling time of less than 5 seconds, please let me know. Before the experimentation, it was in magnitudes of 10^5 seconds. Additionally, if there is a systematic way to obtain We thats better than just trial and error, I would like to know that as well.
Anyway, developing this system in simulink and running it has the following outcome where the yellow is the system response and blue is the reference. It is lagging behind and hardly follows the reference:
However, if I simply put a static gain of 10 on the controller output, the response is much better:
So my question is, how can I modify the controller set up so that it produces an output that does not require me to place a static gain? I have tried various weights on the control signal tg but I have not had any success.

Réponse acceptée

Paul
Paul le 14 Mai 2023
Modifié(e) : Paul le 15 Mai 2023
Hi Jiten,
I believe there are some issue with the code, which I've modified as follows.
Define the plant
b1 = -356.3851;
b2 = 145.1693;
Bd = 6.215E6;
Kd = 8.67637E8;
Jr = 38677056;
Jg = 534.116;
N = 97;
R = 63;
p = 1.225;
A = [(b1-Bd)/Jr Bd/(N*Jr) -Kd/Jr;
Bd/(N*Jg) -Bd/(N^2*Jg) Kd/(N*Jg);
1 -1/N 0];
B = [0 b2/Jr;
-1/Jg 0;
0 0];
C = [1 0 0];
D = [0 0];
lin = ss(A,B,C,D);
lin.InputName = {'tg','v'}; %tg is control signal, v is external input (disturbance)
lin.OutputName = {'wr'}; %output is rotor speed which is to be controlled
I didn't see a reason to define anything other than the error block, so I got rid of R. Also, I prefer to define the error as r - wr. These changes are just preferences on my part.
%R=tf(1); %gain of 1 to make the summation block
%R.u='faker'; R.y='r'; %r is the reference
%error=sumblk('e=wr-r');
error = sumblk('e = r - wr');
This weight on the error, or sensitivity, signal doesn't really reflect the design goal. If you want the time constant to be about 5 seconds, we want the weight to cross 0 db at about 1/5 = 0.2 rad/sec. I made it -6 dB at that frequency. Modify if necessary, but these should be good to get started.
%We = makeweight(40,[1000000,0.3],0);
We = makeweight(100,[0.2,0.5],0.1);
We.u = 'e'; We.y = 'we';
Here, the last input of lincon should be the control input, not the reference input. Also, wr, which is unweighted, is included as an output. Typically, wr, or the complementary sensitivity, would also be frequency weighted. But since it wasn't, I wasn't sure what the intent was, so I've not included wr in the output vector.
%lincon=connect(lin,R,error,We,{'v','tg','faker'},{'wr','we','e'});
lincon = connect(lin,error,We,{'v','r','tg'},{'we','e'});
%Controller synthesis and closed loop with controller:
[KH,g0,g] = hinfsyn(lincon,1,1);
g
g = 0.1009
I didn't reduce the order of KH, just want to see the basic design.
%KH=balred(KH,3);
KH.u = 'e'; KH.y = 'tg';
Now, we want to connect the controller to the actual plant, not the frequency weighted plant.
%Con=connect(lincon,KH,{'v','faker'},{'wr','we'});
Con = connect(lin,KH,error,{'v','r'},{'wr','e'});
Step response from r to wr. Response as desired
figure
step(Con(1,2))
Amplitude comparison of the sensitivity transfer function to inv(We). The former is shaped by the latter.
figure
opts = bodeoptions;
opts.PhaseVisible = 'off';
bodeplot(Con(2,2),inv(We),opts),grid
I suspect that this controller has high bandwidth, because nothing in the design is explicitly constraining the bandwidth. Typically, that is done by including a frequency dependent weight on the complementary sensitivity, or wr, in the H-inf optimization.
Edit: Now I see that hinfsyn has an optional input, gamTry, which is another possbility for limiting the bandwidth. We see from the plot above that KH over-achieved relative to the design goal, and that the final value of g(amma) was around 0.1. So maybe using gamTry = 1 would pull the blue curve to the left, which would still be consistent with the design goal, and would reduce the bandwidth.
Let's try:
gamTry = 1;
[KH,g0,g] = hinfsyn(lincon,1,1,gamTry);
g
g = 0.4755
Hmm, don't know why hinfsyn yielded a lower such a lower g(amma) than gamTry, but it's not inconsistent with the doc. Anyway ...
KH.u = 'e'; KH.y = 'tg';
Con = connect(lin,KH,error,{'v','r'},{'wr','e'});
figure
step(Con(1,2))
figure
opts = bodeoptions;
opts.PhaseVisible = 'off';
bodeplot(Con(2,2),inv(We),opts),grid
We see a much slower step response and the sensitivity transfer function pulled to the left.
  3 commentaires
Paul
Paul le 15 Mai 2023
1. If you mean the connect function as use to build the lincon input to hinfsyn, then weights should be used on the outputs and the inputs as necessary to specify the design goals. Sometimes the weights are frequency depedendent, as is (almost?) always the case for the sensitivity and complementary sensitivity. In other cases the weights can be just a constant to to reflect relative magnitude between inputs such as input disturbance and sensor measurement noise, for example. But keep in mind that by using a constant weight on an input or output we're telling the optimziation that the input has the same content at all frequencies and that we care about the magnitude of the output at all frequencies. Sometimes this approach is fine, but sometimes additional frequency depedendent weights are needed. You can always look at the frequency response of the second output of hinfsyn, which is the weighted, closed loop system, to see which weighted input/output responses are constraining further reduction in g(amma) and at which frequencies these responses are large, so as to get information on how to update the weighted model for design if needed.
2. Yes, I meant the last input of the lincon. Thanks for catching that. I'll edit the Answer accordingly. The reason comes directly from how hinfsyn works. lincon must be formed with input vector [w;u] and output vector [z;y]. So the control inputs (u) and the feedback signals (y) must come last in the inputs/outputs to lincon. The second and third inputs to hinfsyn designate the number of elements of y and u respectively, which is how hinfsyn knows how to form the controller to minimize the norm of the closed loop transfer function from w to z.
Jiten Parmar
Jiten Parmar le 16 Mai 2023
  1. That makes sense! Thank you!
  2. I was over looking the basics with this concept. Thank you again!

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur H-Infinity Synthesis dans Help Center et File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by