OCST: Gain Margin
Lukas Reichlin
lukas.reichlin at swissonline.ch
Fri Jul 3 09:37:30 CDT 2009
> From: lukas.reichlin at swissonline.ch
> To: dastew at sympatico.ca; help-octave at octave.org
> Subject: Re: OCST: Gain Margin
> Date: Fri, 3 Jul 2009 12:19:50 +0200
>
>
> From: lukas.reichlin at swissonline.ch
> To: help-octave at octave.org
> Subject: Re: OCST: Gain Margin
> Date: Fri, 3 Jul 2009 09:48:16 +0200
>
> Dear Octave Community,
>
> I wrote an objective function to optimize an Aström/Hägglund PID
> Controller numerically by fminsearch. Versions for Octave and Matlab/
> SImulink can be found here:
>
> http://n.ethz.ch/student/lukasre/download/optiPID/
>
> The Octave control package is quite limited. However, I managed to get
> along quite easily except for one thing: the gain margin of a system.
> In Matlab, there's [gamma, phi, w_gamma, w_phi] = margin(sys). I
> couldn't think of a way to calculate the gain margin numerically. Is
> there any control systems engineer out there who knows how to
> implement an algorithm for the problem? Help would be very
> appreciated.
>
> Regards,
> Lukas
>
> BTW: Despite I implemented the routine quite differently, the
> conformity of the results between Matlab and Octave is simply
> fantastic :-)
> _______________________________________________
> Help-octave mailing list
> Help-octave at octave.org
> https://www-old.cae.wisc.edu/mailman/listinfo/help-octave
>
>
> If you look at what I did you might get some ideas.
>
> http://dougs.homeip.net/qtoctave/bode1w.m
>
> Doug Stewart
>
> Thanks for your help! If I understood your code correctly, the
> following code should do the job:
>
> Regards,
> Lukas
>
>
> I cleaned this up and added some comments. If it works the way you
> want, then
> we should put it in the controls tool box.
>
>
> Doug Stewart
>
> Thank you. I corrected some minor typos and added my family name :-)
> I think this hack needs some serious testing before it's added to
> anything ;-) Especially because the accuracy relies on how tightly
> spaced the frequency vector of bode(sys) is.
>
> Regards,
> Lukas
>
>
> Thanks Lucas
>
> If you think it is important to use a finer resolution for the
> frequencies then we could:
> 1) find the frequencies the way we are now.
> 2) call bode again with a frequency vector that is just in a narrow
> band around these frequencies;
> 3) recalculate the GM and PM
>
> Do you think this is a good plan?
> Doug
I've done it for the gain margin. I don't know what happens if w(ix-1)
or w(ix+1) doesn't exist ...
Another idea would be to calculate the roots of a polynomial. I have
to think about that.
Regards,
Lukas
## Copyright (C) 2009 Doug Stewart and Lukas Reichlin
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
%
%function function [gamma, phi, w_gamma, w_phi] = margin(sys);
% gamma = Gain Margin ( as gain not dbs)
% w_gamma = radian frequency for the Gain Margin
% phi = Phase Margin ( in degrees)
% w_phi = radian frequency for the Phase margin
%
% This function calls bode - see help bode for details about bode.
% This Function was written for continuous time systems
function [gamma, phi, w_gamma, w_phi] = margin(sys);
%if(! isstruct(sys) )
% error("The input must be a system type variable. margin(sys)")
% Get Frequency Response
[mag, pha, w] = bode(sys);
% fix the phase wrap around
phw = unwrap(pha * pi/180);
pha = phw * 180/pi;
% find the Gain Margin and its location
[x, ix] = min(abs(pha + 180));
if (x > 1)
gamma = "INF";
ix = length(pha);
else
gamma = 1/mag(ix);
endif
w_gamma = w(ix);
% Fine Tuning of Gain Margin Result
w_low = w(ix-1);
w_high = w(ix+1);
n_steps = 10000;
dw = (w_high - w_low) / n_steps;
w_fine = w_low : dw : w_high;
[mag_fine, pha_fine, w_fine] = bode(sys, w_fine);
[x_fine, ix_fine] = min(abs(pha_fine + 180));
gamma = 1/mag_fine(ix_fine);
w_gamma = w_fine(ix_fine)
% find the Phase Margin and its location
[pmx, ipmx] = min(abs(mag - 1));
phi = 180 + pha(ipmx);
w_phi = w(ipmx);
endfunction
-------------- next part --------------
An HTML attachment was scrubbed...
URL: https://www-old.cae.wisc.edu/pipermail/help-octave/attachments/20090703/38059872/attachment.html
More information about the Help-octave
mailing list