最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

matlab - How to calculate the phase response? - Stack Overflow

programmeradmin3浏览0评论

Good afternoon. I want to write a code to output experimental frequency response for system identification. For verification I use the modeled sinusoid and the response of the modeled system. To exclude the influence of transient process and in the future measurement noise, I want to determine the amplitude and phase of the system output using Fourier analysis. The amplitude is fine, but the phase is a problem.

I tried my own code and the code from Matlab doc. I decided on the code from the video: . I still have a problem with the phase. I watch amplitude and phase at the input frequency respectively. I compared with the results of lsqcurvefit. My code:

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')

Function fourier from the video:

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
发布评论

评论列表(0)

  1. 暂无评论