I want to determine the linearized transfer function from a non-linear system made in Simulink. I can see that it should be possible to use the linmod function in Matlab but when I try this
[num,den]=linmod('sys')
I'm not getting the numerator and denominator but instead the state space matrix etc. Can anyone help?
Try the function balred instead: documentation
rsys = balred(sys,ORDERS) computes a reduced-order approximation rsys
of the LTI model sys. The desired order (number of states) for rsys is
specified by ORDERS. You can try multiple orders at once by setting
ORDERS to a vector of integers, in which case rsys is a vector of
reduced-order models. balred uses implicit balancing techniques to
compute the reduced- order approximation rsys.
example:
Q = tf([1 2 3 4 5],[5 4 3 2 1])
Q =
s^4 + 2 s^3 + 3 s^2 + 4 s + 5
-------------------------------
5 s^4 + 4 s^3 + 3 s^2 + 2 s + 1
Q_lin = balred(Q,2)
Q_lin =
3.276 s^2 - 2.06 s + 2.394
--------------------------
s^2 - 0.2757 s + 0.4789
balred(Q,1)
is not working for my example, as there are 2 unstable poles, but it may works for your system.
linmod always returns a state-space representation (see documentation). Use tf to convert your stae-space representation to a transfer function:
Conversion to Transfer Function
tfsys = tf(sys) converts the dynamic
system model sys to transfer function form. The output tfsys is a tf
model object representing sys expressed as a transfer function.
BTW, if you have Simulink Control Design, a better alternative to linmod is linearize.
Related
I was given a step response graph, and from it, obtained a transfer function. The loop includes a plant and a PID controller, and I know the PID values that produced the output graph. I verified that the transfer function I found was correct by applying a step input, and the output graph matches the one I saw.
My code looks like this:
T = tf([.00248,-.00011,.000163],[1,.01,.00041])%plant and controller(P*C) with feedback
C = pid(2.5,0.5,0.1)%PID values
%T = feedback(C*plant,1)%need to find plant
step(T)
From this, I need to find the plant transfer function so that i can use it to find the optimal PID values instead of the ones it is using now.
If you look at the control loop with unity feedback:
You have for the closed-loop transfer function (that's your T):
Y(s) / U(s) = P*C / (1 + P*C) = T
If you reverse the relationship, you can express P as a function of C and T:
P = T / (C * (1-T))
In MATLAB, I would combine this with the use of the function minreal to obtain a minimum realisation of the transfer function:
>> T = tf([.00248,-.00011,.000163],[1,.01,.00041])
Transfer function 'T' from input 'u1' to output ...
0.00248 s^2 - 0.00011 s + 0.000163
y1: ----------------------------------
s^2 + 0.01 s + 0.00041
Continuous-time model.
>> C = pid(2.5,0.5,0.1)
Transfer function 'C' from input 'u1' to output ...
0.1 s^2 + 2.5 s + 0.5
y1: ---------------------
s
Continuous-time model.
>> P = minreal(T / (C * (1-T)))
Transfer function 'P' from input 'u1' to output ...
0.02486 s^3 - 0.001103 s^2 + 0.001634 s
y1: --------------------------------------------------
s^4 + 25.01 s^3 + 5.254 s^2 + 0.05687 s + 0.001238
Continuous-time model.
I have a datasheet (around 100 samples) where for a real SISO system (DC motor), I know the input and output. With tfest command, I can form first order to nth order transfer function using the same data (loaded with iddata function) for the system.
But in real life the system can be either 1st order or nth order.
Like in MATLAB, using same iddat (contains the sample values), I can generate following transfer functions:
sys1 = tfest(iddat, 1, 1, 0.5); %number of zero=1, pole=1, 1st order system
sys1 =
From input "u1" to output "y1":
exp(-0.5*s) * (2.932 s - 0.1862) / (s + 1.082)
sys = tfest(iddat, 3, 2, 0.5);%number of zero=3, pole=2, 2nd order system
sys =
From input "u1" to output "y1":
exp(-0.5*s) * (0.1936 s^2 - 0.02193 s + 0.0006905) / ( s^3 + 0.07175 s^2 + 0.05526 s + 1.772e-13)
Can someone explain the scenario?
Fitting a model to an experimental data requires a minimum amount of knowledge about the underlying physical system.
Here you have a DC motor which probably does not have any zeros and no DC gain but you are forcing matlab to fit a proper 3rd order transfer function and it is giving you the closest one (not necessarily the correct one).
Instead remove the half a second delay and let the function find the time constant for you. So
tfest(iddat,1);
would be sufficient (or try with 3 if you are suspicious about the motor drive).
You are given a transfer function G(s)=1.81K(s+20)/(0.03338(s^3+10s^2+32s+32)). This system is connected with unity negative feedback . Determine the smallest positive value of K which makes the closed-loop system unstable. Give the answer to 3 d.p.
Correct Answer:
0.531 ± 0.02
This question is set by my lecturer and I have no idea how to do it.
The closed loop system will become unstable as soon as the rlocus function is no longer in the LHP. Either of the two lines when they intersect with 0 on the x-axis. Assume K=1 at first as we are multiplying by the gain.
>> G=tf([1.81 36.2],[0.03338 0.3338 1.0682 1.0682])
G =
1.81 s + 36.2
------------------------------------------
0.03338 s^3 + 0.3338 s^2 + 1.068 s + 1.068
Continuous-time transfer function.
>> rlocus(G)
you should see that when the real axis is 0 the gain is at 0.531.
if we want greater accuracy we can simply use the rlocfind(G,(point that it is 0)
A smart friend of mine showed me that "Routh Array" is the key for this equation.
Expand the polynomial as you have it, therefore you will have this:
VARS TERM VALUE
A s^3 0.03338
B s^2 0.3338
C s 1.06816 + 1.81Κ
D 1.06816 + 36.2Κ
Equate them as A*D=B*C and you will have the term "s^3" on both sides and then you can cancel it out and solve for K.
(0.03338)(1.06816 + 36.2K) s^3 = (0.3338)(1.06816 + 1.81K) s^3
0.0357 + 1.2084K = 0.3566 + 0.6042K
(1.2084 - 0.6042) K = 0.3566-0.0357
K = 0.5311155247
Otherwise use the rlocus function in MATLAB.
Im trying to design a PID compensator with Matlab.
I'm doing the following:
My plant has this transfer function:
plant
( 0.0195 s - 6.5 )/ (1.74e-06 s^2 - 0.003 s - 1)
So, using the PID tune function, specifying the desired crossover frequency:
>> [info,pid_c] = pidtune(plant,'PID',(2E6/6)*2*pi)
info =
Kp + Ki * 1/s
with Kp = 162, Ki = 1.96e+08
Continuous-time PI controller in parallel form.
pid_c =
Stable: 1
CrossoverFrequency: 2.0944e+06
PhaseMargin: 60.0000
But, when I close the loop and analyse the poles of the system I see that there's a pole in the right semi-plane:
>> pid_c = 162 + 1.96E8/s
pid_c =
( 162 s + 1.96e08 ) / s
Continuous-time transfer function.
>> sys=feedback(plant*pid_c,1)
sys =
(3.159 s^2 + 3.821e06 s - 1.274e09 )/ ( 1.74e-06 s^3 + 3.156 s^2 + 3.821e06 s - 1.274e09)
Continuous-time transfer function.
>> pole(sys)
ans =
1.0e+06 *
-0.9071 + 1.1721i
-0.9071 - 1.1721i
0.0003 <==== RSP pole
My intuition says I should get away with this pole by adding a (s+0.0003) to the numerator of the PID:
>> pid_c=pid_c*(s+0.0003)
pid_c =
( 162 s^2 + 1.96e08 s + 5.88e04 )/ s
But it doesnt work at all, and the tranfer function of my closed-loop goes like that:
sys =
(3.159 s^3 + 3.821e06 s^2 - 1.274e09 s - 3.822e05) / (3.159 s^3 + 3.821e06 s^2 - 1.274e09 s - 3.822e05)
and off course thats wrong.
I really appreciate your help.
The problem is because you are not calling pidtune correctly. The first variable returned is the controller, the second the information about closed-loop stability, not the other way round. From the documentation:
[C,info] = pidtune(...) returns the data structure info, which
contains information about closed-loop stability, the selected
open-loop gain crossover frequency, and the actual phase margin.
So I would change the code to:
[pid_c,info] = pidtune(plant,'PID',(2E6/6)*2*pi);
sys=minreal(feedback(pid_c*plant,1));
pole(sys)
The second error you make is that the pole isn't at 0.0003, but at 0.0003 * 1e6. If you are going to rely on what is displayed on the screen, you should at least use format long g to have more significant digits.
Also, note that I have used minreal to compute a minimum realisation of the closed-loop transfer function, as you seem to be having a mix of very large and very small number, not a good combination.
What I Have to do :
Perform the linearization in the vicinity of the operating point. Determine the linearized transfer
This is my non-linear operating point model ('op') with step :
This is my non-linear operating point model ('linmod'), where I have replaced step -> In and to workspace -> Out
Parameter Kn = 948;
For transfer function I did:
[num,den] = linmod('test');
G = tf(num,den);
0.3333 s^2 + 83.33 s + 23.33
--------------------------------------
s^4 + 333.3 s^3 + 2.09e04 s^2 + 5833 s
If I change the value of Kn, and re-run simulation + linmod, I get the exact same transfer function.
Also, I do not quite understand in the mathlab help what is
[A,B,C,D] = linmod['linmod',x,u]
I know that matrixes A,B,C,D are used in
x' = Ax + Bu and
y = Cx + Du
But I do not know what to do from here.
Also a question :
Do I need to use linear or non-linear model for linmod ?