Система состояний пространства дает другой боде, чем матрица передаточной функции
У меня есть система пространства состояний с матрицами A,B,C и D.
Я могу либо создать систему пространства состояний, sys1 = ss(A,B,C,D)
или вычислить матрицу передаточной функции, sys2 = C*inv(z*I - A)*B + D
Однако когда я рисую график Боде для обеих систем, они различаются, хотя они должны быть одинаковыми.
Что здесь не так? У кого-нибудь есть ключ? Я знаю, кстати, что бодеплот, созданный sys1
верно.
Систему можно скачать здесь: 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--');
Редактировать: я сделал небольшую ошибку, матрица передаточной функции sys2 = C*inv(z*I - A)*B + D
, вместо sys2 = C*inv(z*I - A)*B - D
что я написал ранее. Проблема все еще остается.
Редактировать 2: я заметил, что когда я вычисляю знаменатель, это правильно.
syms z;
collect(det(z*eye(3) - A),z)
4 ответа
Из-за неточности обратной функции в систему добавляются дополнительные ненаблюдаемые полюсы и нули. По этой причине вам необходимо вычислить минимальную реализацию вашей матрицы передаточных функций.
Имея в виду
% Compute transfer function
sys2 = minreal(C*inv(z*eye(3) - A)*B + D);
Ваше предположение, что sys2 = C*inv(z*I- A)*B + D
это неверно. Правильный эквивалент вашей системы пространства состояний (A,B,C,D) sys2 = C*inv(s*I- A)*B + D
, Если вы хотите выразить это с точки зрения z
вам нужно будет перевернуть отношения z = exp(s*T)
, sys1
является правильным представлением вашей системы пространства состояний. Что бы я предложил для sys2
это сделать следующим образом:
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);
Это должно дать вам правильный результат.
Что вы заметили, так это на самом деле численная нестабильность в отношении аннулирования пары полюс-ноль. Если вы запустите следующий код:
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)
вы увидите, что передаточная функция, сформулированная непосредственно матрицами, имеет намного больше полюсов и нулей, чем та, которая сформулирована tf-функцией MatLab. Вы также заметите, что каждая пара этих "лишних" полюсов и нулей равны - это означает, что они взаимно сокращаются, если вы просто используете рациональное выражение. Matfab tf представляет упрощенную форму с равными парами полюс-ноль, которые исключаются. Это алгебраически эквивалентно не упрощенной форме, но не численно.
Когда вы вызываете bode для не упрощенной передаточной функции, MatLab начинает свою процедуру числового построения с пар полюс-ноль, которые не аннулируются алгебраически. Если бы компьютер был идеальным, результат был бы таким же, как в упрощенном случае. Однако числовая ошибка при оценке числителя и знаменателей фактически оставляет некоторые пары полюс-ноль "не отмененными", и, поскольку многие из этих полюсов находятся в дальней правой части плоскости s, они существенно влияют на поведение вывода.
Проверьте эту ссылку для получения информации об этой же проблеме, но с точки зрения дизайна: http://ctms.engin.umich.edu/CTMS/index.php?aux=Extras_PZ
В исходном коде вы можете думать о выводе, нарисованном зеленым цветом, как о том, что наивный дизайнер хотел увидеть, когда он отменил все свои нестабильные полюса с нулями, но вывод, нарисованный красным, это то, что он на самом деле получил, потому что на практике конечная точность и реальные допуски препятствуют тому, чтобы полюсы и нули полностью отменили.
Почему ненаблюдаемый / неуправляемый полюс? Я думаю, что эта проблема возникает только потому, что обратная матрица передаточной функции является неточной в Matlab.
Замечания:
- A 3x3, и минимальная реализация также имеет порядок 3.
- То, что вы сделали, это обратная матрица передаточной функции, а не символьная или числовая матрица.
# 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 теперь скалярная (SISO) передаточная функция.
Без "minreal" G имеет порядок 9 (забавно, я не знаю, как Matlab вычисляет его, возможно, метод "Adj(.)/ Det(.)"). Matlab не может отменить общие множители в числителе и знаменателе, потому что z относится к классу 'tf', а не к символической переменной.
Вы согласны или у меня есть недоразумение?