scipy.signal.bode与状态空间/传递函数的Matlab预编码不同

时间:2019-04-25 17:15:13

标签: python matlab scipy controls

我正在使用matlab的系统识别工具箱来估算实验给出的SISO频率响应的传递函数/状态空间模型。但是,我想将python中的模型用于其他一些恶作剧。问题甚至在此之前发生。

我通过JSON导出数据,并将其导入python中,然后使用scipy.signal从数据中创建signal.StateSpace或signal.TransferFunction对象,即矩阵A,B,C,D,K(scipy可以不需要,仍然是0),StateSpace或分子/分母数组的采样时间dt加上TransferFunction的采样时间dt。

我觉得我缺少一些必不可少的东西,没有太多要更改的参数,python和MATLAB中的模型参数相同。

这基本上是我的matlab代码:

% Import the data
tbl = readtable("fra.csv", opts);

%% Convert to output type
FrequencyHz = tbl.FrequencyHz1;
AmplitudeVpp = tbl.AmplitudeVpp1;
GaindB = tbl.GaindB1;
Phase = tbl.Phase1;

%% Define complex response data
m = 10 .^ (GaindB / 20)
phi = Phase .* pi / 180
z = m .*exp( 1i * phi )

Ts = 5e-05

gfr = idfrd(z, FrequencyHz, Ts)
% subgfr = fselect(gfr, 0, 1e4)
clf

%% estimation of state space and transfer function models
ss = ssest(gfr, 10)
sspvec = getpvec(ss)
tf = tfest(gfr, 10, 10)  % 10 poles and zeros? explicitly?
bode(gfr, ss, tf)
% compare(gfr, ss, tf)

%% moving legend
% L = findobj(gcf,'type','legend');
% L.Location = 'southwest'; % move legend to non-overlapping location

%% Save stuff to JSON

[A, B, C, D, K, x0] = idssdata(ss)
[num, den, ts] = tfdata(tf)

data = struct
data.ss = struct
data.tf = struct
data.ss.A = A
data.ss.B = B
data.ss.C = C
data.ss.D = D
data.ss.K = K
data.tf.num = num
data.tf.den = den
data.tf.ts = ts
jstring = savejson('', data, 'out.json')

fileID = fopen('test.txt', 'w')
fprintf(fileID, jstring, 'char')
fclose(fileID)

这就是我在jupyter中所做的:

import json
from scipy import signal
import matplotlib.pyplot as plt

with open('FRD_est_matlab/out.json', 'r') as file:
    data = json.load(file)
ss = data.get('ss')
tf = data.get('tf')
ssm = signal.StateSpace(ss['A'], ss['B'], ss['C'], ss['D'], dt=5e-05)
tfm = signal.TransferFunction(tf['num'][0], tf['den'][0], dt=5e-05)
print(ssm)
# print(tfm)

hz = np.logspace(0, 5, 500)
rad_n = hz * 2 * np.pi / (1 / 5e-05)
w, mag, phase = signal.dbode(tfm, w=rad_n)  # w in rad/s, mag in dB, phase in deg
w = w / 2 / np.pi  # w in Hz

plt.figure('Magnitude')
plt.semilogx(w, mag)# Bode magnitude plot
plt.figure('Phase')
plt.semilogx(w, phase)  # Bode phase plot
plt.show()

这是在matlab中实验响应数据与tf / ss估计值的比较。

https://imgur.com/a/fAUXDql

这是在Matlab中这三个函数的正常波特图(我想Matlab会确定起点)。

https://imgur.com/a/Mt1IPU2

这是scipy中任一tf / ss模型的波德图(离散图)。

度/相超过Hz

https://imgur.com/a/om7Tmwu

在我看来,这有点...嗯。有人对此有经验吗?还是我只是盲目的?

编辑:由于我无法发布图片,因此链接必须要做

0 个答案:

没有答案