Система состояний пространства дает другой боде, чем матрица передаточной функции

У меня есть система пространства состояний с матрицами 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.

Замечания:

  1. A 3x3, и минимальная реализация также имеет порядок 3.
  2. То, что вы сделали, это обратная матрица передаточной функции, а не символьная или числовая матрица.

# 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', а не к символической переменной.

Вы согласны или у меня есть недоразумение?

Другие вопросы по тегам