You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

系统辨识中傅里叶分析计算相位响应的问题求助

问题描述

我想要编写代码输出用于系统辨识的实验频率响应。为验证效果,我采用建模正弦信号和建模系统的响应进行测试。为排除暂态过程及未来测量噪声的影响,希望通过傅里叶分析确定系统输出的幅值和相位。幅值计算正常,但相位存在问题。

我试过自己编写的代码以及Matlab文档中的代码,最终采用了某视频中的代码,但相位问题仍未解决。我分别查看输入频率下的幅值和相位,并与lsqcurvefit的结果进行对比。我的代码如下:

close all, clear, clc;

step_t = 0.01;

T = 5;
w = (2*pi)/T;
Am = 2;

t_real = 0:step_t:100;

sin_mass = Am*sin(w*t_real);

Tf = 10;
sys = tf([0 1],[Tf 1])

y = lsim(sys,sin_mass,t_real);

figure()
plot(t_real, sin_mass, t_real, y),grid on
legend('input','output')

[f,F_x_f]=fourier(t_real,y,'sinus');

% plot the magnitude spectrum
figure(2)
stem(f,abs(F_x_f))
grid on
xlim([0,20])
xlabel('Frequency in Hz')
ylabel('Amplitude spectrum of the force in N')

% plot the phase spectrum
figure(3)
stem(f,angle(F_x_f))
grid on
xlim([0,20])
xlabel('Frequency in Hz')
ylabel('Phase spectrum of the force in °')

[M,I] = min(abs(f-(1/T)));

out_prob = F_x_f(I);

Amplitude_est = abs(out_prob)
Phase_est = angle(out_prob)

f_out = @(x,u)x(1)*sin(w*u + x(2));

par0 = [Am,0];

par_out = lsqcurvefit(f_out, par0, t_real, y')

y_est = par_out(1)*sin(w*t_real + par_out(2));

figure()
plot(t_real, y, t_real, y_est),grid on
legend('output','output est')

视频中的fourier函数如下:

function [f,X_f]=fourier(t,x_t,modus)
    % check if mode is set
    if nargin<3
        % set to default value
        modus='pulse';
    end
    
    % Number of values -> scalar
    N=length(t);

    % maximum time (in s) -> scalar
    t_max=t(N);
    % Time step (in s) -> scalar
    t_step=t(2);
    % maximum frequency (in Hz) -> scalar
    f_max=0.5/t_step;
        
    % perform Fourier transform -> vector of length N
    if strcmp(modus,'pulse')
        % the unit of the spectrum is 1/Hz (e.g. V/Hz, A/Hz, ...)
        XX(1:N)=t_max/(N-1)*fft(x_t);        
    elseif strcmp(modus,'sinus')
        % the unit of the spectrum is 1 (e.g. V, A, ...)
        XX(1:N)=2/N*fft(x_t);
    else
        error(['The modus ',modus,' is unknown.'])
    end
    % Meaning:
    % for even N:
    %   XX(1) contains the DC component (real)
    %   XX(2:N/2) contains the positive frequency components in ascending order (usually complex)
    %   XX(N/2+1) contains the highest frequency (real)
    %   XX(N/2+2:end) contains the negative frequency components in decreasing order (usually complex)
    % for odd N:
    %   XX(1) contains the DC component (real)
    %   XX(2:(N+1)/2) contains the positive frequency components in ascending order (usually complex)
    %   XX((N+3)/2:end) contains the negative frequency components in decreasing order (usually complex)   
    
    % check whether N is even or odd
    if mod(N,2)
        % N is odd
        % create frequency spectrum -> row vector
        X_f(1:(N+1)/2)=XX(1:(N+1)/2);
        % create frequency range (in Hz) -> row vector
        f=linspace(0,f_max*(N-1)/N,(N+1)/2);
    else
        % N is even
        % create frequency spectrum -> row vector
        X_f(1:N/2+1)=XX(1:N/2+1);
        % create frequency range (in Hz) -> row vector
        f=linspace(0,f_max,N/2+1);
    end
end

内容的提问来源于stack exchange,提问作者Ilmir Gogorev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 01:03:11