简体   繁体   中英

State space system gives different bode plot then transfer function matrix

I have a state space system with matrices A,B,C and D.

I can either create a state space system , sys1 = ss(A,B,C,D) , of it or compute the transfer function matrix , sys2 = C*inv(z*I - A)*B + D

However when I draw the bode plot of both systems, they are different while they should be the same.

What is going wrong here? Does anyone have a clue? I know btw that the bodeplot generated by sys1 is correct.

The system can be downloaded here: https://dl.dropboxusercontent.com/u/20782274/system.mat

clear all;
close all;
clc;

Ts = 0.01;
z = tf('z',Ts);

% Discrete system
A = [0 1 0; 0 0 1; 0.41 -1.21 1.8];
B = [0; 0; 0.01];
C = [7 -73 170];
D = 1;

% Set as state space
sys1 = ss(A,B,C,D,Ts);

% Compute transfer function
sys2 = C*inv(z*eye(3) - A)*B + D;

% Compute the actual transfer function
[num,den] = ss2tf(A,B,C,D);
sys3 = tf(num,den,Ts);

% Show bode
bode(sys1,'b',sys2,'r--',sys3,'g--');

Edit: I made a small mistake, the transfer function matrix is sys2 = C*inv(z*I - A)*B + D , instead of sys2 = C*inv(z*I - A)*B - D which I did wrote done before. The problem still holds.


Edit 2: I have noticted that when I compute the denominator, it is correct.

syms z;
collect(det(z*eye(3) - A),z)

Your assumption that sys2 = C*inv(z*I- A)*B + D is incorrect. The correct equivalent to your state-space system (A,B,C,D) is sys2 = C*inv(s*I- A)*B + D . If you want to express it in terms of z , you'll need to invert the relationship z = exp(s*T) . sys1 is the correct representation of your state-space system. What I would suggest for sys2 is to do as follows:

sys1 = ss(mjlsCE.A,mjlsCE.B,mjlsCE.C,mjlsCE.D,Ts);
sys1_c = d2c(sys1);
s = tf('s');
sys2_c = sys1_c.C*inv(s*eye(length(sys1_c.A)) - sys1_c.A)*sys1_c.B + sys1_c.D;
sys2_d = c2d(sys2_c,Ts);

That should give you the correct result.

Due to inacurracy of the inverse function extra unobservable poles and zeros are added to the system. For this reason you need to compute the minimal realization of your transfer function matrix.

Meaning

% Compute transfer function
sys2 = minreal(C*inv(z*eye(3) - A)*B + D);

What you are noticing is actually a numerical instability regarding pole-zero pair cancellations. If you run the following code:

A = [0, 1, 0; 0, 0, 1; 0.41, -1.21, 1.8] ;
B = [0; 0; 0.01] ;
C = [7, -73, 170] ;
D = 1 ;

sys_ss = ss(A, B, C, D) ;

sys_tf_simp = tf(sys_ss) ;

s = tf('s') ;
sys_tf_full = tf(C*inv(s*eye(3) - A)*B + D) ;

zero(sys_tf_simp)
zero(sys_tf_full)

pole(sys_tf_simp)
pole(sys_tf_full)

you will see that the transfer function formulated by matrices directly has a lot more poles and zeros than the one formulated by MatLab's tf function. You will also notice that every single pair of these "extra" poles and zeros are equal- meaning that they cancel with each other if you were to simply the rational expression. MatLab's tf presents the simplified form, with equal pole-zero pairs cancelled out. This is algebraically equivalent to the unsimplified form, but not numerically.

When you call bode on the unsimplified transfer function, MatLab begins its numerical plotting routine with the pole-zero pairs not cancelled algebraically. If the computer was perfect, the result would be the same as in the simplified case. However, numerical error when evaluating the numerator and denominators effectively leaves some of the pole-zero pairs "uncancelled" and as many of these poles are in the far right side of the s plane, they drastically influence the output behavior.

Check out this link for info on this same problem but from the perspective of design: http://ctms.engin.umich.edu/CTMS/index.php?aux=Extras_PZ

In your original code, you can think of the output drawn in green as what the naive designer wanted to see when he cancelled all his unstable poles with zeros, but the output drawn in red is what he actually got because in practice, finite-precision and real-world tolerances prevent the poles and zeros from cancelling perfectly.

Why is an unobservable / uncontrollable pole? I think this issue comes only because the inverse of a transfer function matrix is inaccurate in Matlab.

Note:

  1. A is 3x3 and the minimal realization has also order 3.
  2. What you did is the inverse of a transfer function matrix, not a symbolic or numeric matrix.

# Discrete system
Ts = 0.01;
A = [0 1 0; 0 0 1; 0.41 -1.21 1.8];
B = [0; 0; 0.01];
C = [7 -73 170];
D = 1;

z = tf('z', Ts)) # z is a discrete tf
A1 = z*eye(3) - A # a tf matrix with a direct feedthrough matrix A

# inverse it, multiply with C and B from left and right, and plus D
G = D + C*inv(A1)*B 

G is now a scalar (SISO) transfer function.

Without "minreal", G has order 9 (funny, I don't know how Matlab computes it, perhaps the "Adj(.)/det(.)" method). Matlab cannot cancel the common factors in the numerator and the denominator, because z is of class 'tf' rather than a symbolic variable.

Do you agree or do I have misunderstanding?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM