scipy.signal.bode отличается от Matlab bode для State Space / Transfer Function - PullRequest
0 голосов
/ 25 апреля 2019

Я использую набор инструментов идентификации системы Matlab для оценки модели Передаточная функция / Пространство состояний для экспериментально заданной частотной характеристики SISO.Тем не менее, я хочу использовать модель в Python для некоторых других махинаций.Проблема возникает еще до этого.

Я экспортирую данные через JSON и импортирую их в python, затем использую scipy.signal для создания объектов signal.StateSpace или signal.TransferFunction из данных, а именно матриц A, B, C, D, K (который не нужен scipy, в любом случае равен 0) и время выборки dt для массивов StateSpace или числителя / знаменателя плюс время выборки dt для TransferFunction.

Мне кажется, что я упускаю что-то важное, не так много параметров, которые нужно изменить, параметры модели одинаковы как в 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()

Это сравнение экспериментальных данных ответа с оценками tf / ss в matlab.

https://imgur.com/a/fAUXDql

Это нормальный график Бодетри в matlab (я предполагаю, что matlab исправляет начальные точки).

https://imgur.com/a/Mt1IPU2

Это сюжет Боде (дискретный) любой модели tf / ss из scipy.

град / фаза Овеr Hz

https://imgur.com/a/om7Tmwu

Для меня это выглядит ... немного не так, а.У кого-нибудь есть опыт в этом?Или я просто слепой?

РЕДАКТИРОВАТЬ: так как я не могу публиковать изображения, ссылки должны будут сделать

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...