我正在使用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估计值的比较。
这是在Matlab中这三个函数的正常波特图(我想Matlab会确定起点)。
这是scipy中任一tf / ss模型的波德图(离散图)。
度/相超过Hz
在我看来,这有点...嗯。有人对此有经验吗?还是我只是盲目的?
编辑:由于我无法发布图片,因此链接必须要做