nass-simscape/disturbances/matlab/modal_frf_coh.m

344 lines
13 KiB
Matlab

%% Clear Workspace and Close figures
clear; close all; clc;
%% Intialize Laplace variable
s = zpk('s');
open 'simscape/sim_micro_station_disturbances.slx'
% Identification
% <<sec:identification>>
% The transfer functions from the disturbance forces to the relative velocity of the hexapod with respect to the granite are computed using the Simscape Model representing the experimental setup with the code below.
%% Options for Linearized
options = linearizeOptions;
options.SampleTime = 0;
%% Name of the Simulink File
mdl = 'sim_micro_station_disturbances';
%% Micro-Hexapod
% Input/Output definition
io(1) = linio([mdl, '/Dw'], 1, 'input'); % Ground Motion
io(2) = linio([mdl, '/Fty'], 1, 'input'); % Parasitic force Ty
io(3) = linio([mdl, '/Frz'], 1, 'input'); % Parasitic force Rz
io(4) = linio([mdl, '/Dgm'], 1, 'output'); % Absolute motion - Granite
io(5) = linio([mdl, '/Dhm'], 1, 'output'); % Absolute Motion - Hexapod
io(6) = linio([mdl, '/Vm'], 1, 'output'); % Relative Velocity hexapod/granite
% Run the linearization
G = linearize(mdl, io, 0);
% Input/Output names
G.InputName = {'Dw', 'Fty', 'Frz'};
G.OutputName = {'Dgm', 'Dhm', 'Vm'};
% Sensitivity to Disturbances
% <<sec:sensitivity_disturbances>>
freqs = logspace(0, 3, 1000);
figure;
title('$D_w$ to $D$');
hold on;
plot(freqs, abs(squeeze(freqresp(G('Vm', 'Dw')/s, freqs, 'Hz'))), 'k-');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/m]'); xlabel('Frequency [Hz]');
% #+NAME: fig:sensitivity_dist_gm
% #+CAPTION: Sensitivity to Ground Motion ([[./figs/sensitivity_dist_gm.png][png]], [[./figs/sensitivity_dist_gm.pdf][pdf]])
% [[file:figs/sensitivity_dist_gm.png]]
freqs = logspace(0, 3, 1000);
figure;
title('$F_{ty}$ to $D$');
hold on;
plot(freqs, abs(squeeze(freqresp(G('Vm', 'Fty')/s, freqs, 'Hz'))), 'k-');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); xlabel('Frequency [Hz]');
% #+NAME: fig:sensitivity_dist_fty
% #+CAPTION: Sensitivity to vertical forces applied by the Ty stage ([[./figs/sensitivity_dist_fty.png][png]], [[./figs/sensitivity_dist_fty.pdf][pdf]])
% [[file:figs/sensitivity_dist_fty.png]]
freqs = logspace(0, 3, 1000);
figure;
title('$F_{rz}$ to $D$');
hold on;
plot(freqs, abs(squeeze(freqresp(G('Vm', 'Frz')/s, freqs, 'Hz'))), 'k-');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); xlabel('Frequency [Hz]');
% Power Spectral Density of the effect of the disturbances
% <<sec:psd_dist>>
% The PSD of the relative velocity between the hexapod and the marble in $[(m/s)^2/Hz]$ are loaded for the following sources of disturbance:
% - Slip Ring Rotation
% - Scan of the translation stage (effect in the vertical direction and in the horizontal direction)
% Also, the Ground Motion is measured.
gm = load('./disturbances/mat/psd_gm.mat', 'f', 'psd_gm', 'psd_gv');
rz = load('./disturbances/mat/pxsp_r.mat', 'f', 'pxsp_r');
tyz = load('./disturbances/mat/pxz_ty_r.mat', 'f', 'pxz_ty_r');
tyx = load('./disturbances/mat/pxe_ty_r.mat', 'f', 'pxe_ty_r');
gm.f = gm.f(2:end);
rz.f = rz.f(2:end);
tyz.f = tyz.f(2:end);
tyx.f = tyx.f(2:end);
gm.psd_gm = gm.psd_gm(2:end); % PSD of Ground Motion [m^2/Hz]
gm.psd_gv = gm.psd_gv(2:end); % PSD of Ground Velocity [(m/s)^2/Hz]
rz.pxsp_r = rz.pxsp_r(2:end); % PSD of Relative Velocity [(m/s)^2/Hz]
tyz.pxz_ty_r = tyz.pxz_ty_r(2:end); % PSD of Relative Velocity [(m/s)^2/Hz]
tyx.pxe_ty_r = tyx.pxe_ty_r(2:end); % PSD of Relative Velocity [(m/s)^2/Hz]
% We now compute the relative velocity between the hexapod and the granite due to ground motion.
gm.psd_rv = gm.psd_gm.*abs(squeeze(freqresp(G('Vm', 'Dw'), gm.f, 'Hz'))).^2;
% The Power Spectral Density of the relative motion/velocity of the hexapod with respect to the granite are shown in figures [[fig:dist_effect_relative_velocity]] and [[fig:dist_effect_relative_motion]].
% The Cumulative Amplitude Spectrum of the relative motion is shown in figure [[fig:dist_effect_relative_motion_cas]].
figure;
hold on;
plot(gm.f, sqrt(gm.psd_rv), 'DisplayName', 'Ground Motion');
plot(tyz.f, sqrt(tyz.pxz_ty_r), 'DisplayName', 'Ty');
plot(rz.f, sqrt(rz.pxsp_r), 'DisplayName', 'Rz');
hold off;
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
xlabel('Frequency [Hz]'); ylabel('ASD of the measured velocity $\left[\frac{m/s}{\sqrt{Hz}}\right]$')
legend('Location', 'southwest');
xlim([2, 500]);
% #+NAME: fig:dist_effect_relative_velocity
% #+CAPTION: Amplitude Spectral Density of the relative velocity of the hexapod with respect to the granite due to different sources of perturbation ([[./figs/dist_effect_relative_velocity.png][png]], [[./figs/dist_effect_relative_velocity.pdf][pdf]])
% [[file:figs/dist_effect_relative_velocity.png]]
figure;
hold on;
plot(gm.f, sqrt(gm.psd_rv)./(2*pi*gm.f), 'DisplayName', 'Ground Motion');
plot(tyz.f, sqrt(tyz.pxz_ty_r)./(2*pi*tyz.f), 'DisplayName', 'Ty');
plot(rz.f, sqrt(rz.pxsp_r)./(2*pi*rz.f), 'DisplayName', 'Rz');
hold off;
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
xlabel('Frequency [Hz]'); ylabel('ASD of the displacement $\left[\frac{m}{\sqrt{Hz}}\right]$')
legend('Location', 'southwest');
xlim([2, 500]);
% #+NAME: fig:dist_effect_relative_motion
% #+CAPTION: Amplitude Spectral Density of the relative displacement of the hexapod with respect to the granite due to different sources of perturbation ([[./figs/dist_effect_relative_motion.png][png]], [[./figs/dist_effect_relative_motion.pdf][pdf]])
% [[file:figs/dist_effect_relative_motion.png]]
figure;
hold on;
plot(gm.f, flip(sqrt(-cumtrapz(flip(gm.f), flip(gm.psd_rv./((2*pi*gm.f).^2))))), 'DisplayName', 'Ground Motion');
plot(tyz.f, flip(sqrt(-cumtrapz(flip(tyz.f), flip(tyz.pxz_ty_r./((2*pi*tyz.f).^2))))), 'DisplayName', 'Ty');
plot(rz.f, flip(sqrt(-cumtrapz(flip(rz.f), flip(rz.pxsp_r./((2*pi*rz.f).^2))))), 'DisplayName', 'Rz');
hold off;
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
xlabel('Frequency [Hz]'); ylabel('CAS of the relative displacement $[m]$')
legend('Location', 'southwest');
xlim([2, 500]); ylim([1e-11, 1e-6]);
% Compute the Power Spectral Density of the disturbance force
% <<sec:psd_force_dist>>
% Now, from the extracted transfer functions from the disturbance force to the relative motion of the hexapod with respect to the granite (section [[sec:sensitivity_disturbances]]) and from the measured PSD of the relative motion (section [[sec:psd_dist]]), we can compute the PSD of the disturbance force.
rz.psd_f = rz.pxsp_r./abs(squeeze(freqresp(G('Vm', 'Frz'), rz.f, 'Hz'))).^2;
tyz.psd_f = tyz.pxz_ty_r./abs(squeeze(freqresp(G('Vm', 'Fty'), tyz.f, 'Hz'))).^2;
figure;
hold on;
set(gca,'ColorOrderIndex',2);
plot(tyz.f, sqrt(tyz.psd_f), 'DisplayName', 'F - Ty');
plot(rz.f, sqrt(rz.psd_f), 'DisplayName', 'F - Rz');
hold off;
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
xlabel('Frequency [Hz]'); ylabel('ASD of the disturbance force $\left[\frac{F}{\sqrt{Hz}}\right]$')
legend('Location', 'southwest');
xlim([2, 500]);
% Noise Budget
% <<sec:noise_budget>>
% Now, from the compute spectral density of the disturbance sources, we can compute the resulting relative motion of the Hexapod with respect to the granite using the model.
% We should verify that this is coherent with the measurements.
% Power Spectral Density of the relative Displacement
psd_gm_d = gm.psd_gm.*abs(squeeze(freqresp(G('Vm', 'Dw')/s, gm.f, 'Hz'))).^2;
psd_ty_d = tyz.psd_f.*abs(squeeze(freqresp(G('Vm', 'Fty')/s, tyz.f, 'Hz'))).^2;
psd_rz_d = rz.psd_f.*abs(squeeze(freqresp(G('Vm', 'Frz')/s, rz.f, 'Hz'))).^2;
figure;
hold on;
plot(gm.f, sqrt(psd_gm_d), 'DisplayName', 'Ground Motion');
plot(tyz.f, sqrt(psd_ty_d), 'DisplayName', 'Ty');
plot(rz.f, sqrt(psd_rz_d), 'DisplayName', 'Rz');
plot(rz.f, sqrt(psd_gm_d + psd_ty_d + psd_rz_d), 'k--', 'DisplayName', 'tot');
hold off;
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
xlabel('Frequency [Hz]'); ylabel('ASD of the relative motion $\left[\frac{m}{\sqrt{Hz}}\right]$')
legend('Location', 'southwest');
xlim([2, 500]);
% #+NAME: fig:psd_effect_dist_verif
% #+CAPTION: Computed Effect of the disturbances on the relative displacement hexapod/granite ([[./figs/psd_effect_dist_verif.png][png]], [[./figs/psd_effect_dist_verif.pdf][pdf]])
% [[file:figs/psd_effect_dist_verif.png]]
figure;
hold on;
plot(gm.f, flip(sqrt(-cumtrapz(flip(gm.f), flip(psd_gm_d)))), 'DisplayName', 'Ground Motion');
plot(gm.f, flip(sqrt(-cumtrapz(flip(gm.f), flip(psd_ty_d)))), 'DisplayName', 'Ty');
plot(gm.f, flip(sqrt(-cumtrapz(flip(gm.f), flip(psd_rz_d)))), 'DisplayName', 'Rz');
plot(gm.f, flip(sqrt(-cumtrapz(flip(gm.f), flip(psd_gm_d + psd_ty_d + psd_rz_d)))), 'k-', 'DisplayName', 'tot');
hold off;
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
xlabel('Frequency [Hz]'); ylabel('Cumulative Amplitude Spectrum [m]')
legend('location', 'northeast');
xlim([2, 500]); ylim([1e-11, 1e-6]);
% Approximation
% We approximate the PSD of the disturbance with the following transfer functions.
G_ty = 0.1*(s+634.3)*(s+283.7)/((s+2*pi)*(s+2*pi));
G_rz = 0.5*(s+418.8)*(s+36.51)*(s^2 + 110.9*s + 3.375e04)/((s+0.7324)*(s+0.546)*(s^2 + 0.6462*s + 2.391e04));
G_gm = 0.002*(s^2 + 3.169*s + 27.74)/(s*(s+32.73)*(s+8.829)*(s+7.983)^2);
% We compute the effect of these approximate disturbances on $D$.
% Power Spectral Density of the relative Displacement
psd_gm_s = abs(squeeze(freqresp(G_gm*G('Vm', 'Dw')/s, gm.f, 'Hz'))).^2;
psd_ty_s = abs(squeeze(freqresp(G_ty*G('Vm', 'Fty')/s, gm.f, 'Hz'))).^2;
psd_rz_s = abs(squeeze(freqresp(G_rz*G('Vm', 'Frz')/s, gm.f, 'Hz'))).^2;
figure;
ax1 = subplot(1, 2, 1);
hold on;
set(gca,'ColorOrderIndex',2);
plot(gm.f, sqrt(psd_ty_d), 'DisplayName', 'F - Ty');
plot(gm.f, sqrt(psd_rz_d), 'DisplayName', 'F - Rz');
set(gca,'ColorOrderIndex',2);
plot(gm.f, sqrt(psd_ty_s), '--', 'HandleVisibility', 'off');
plot(gm.f, sqrt(psd_rz_s), '--', 'HandleVisibility', 'off');
hold off;
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
xlabel('Frequency [Hz]'); ylabel('ASD of the disturbance force $\left[\frac{F}{\sqrt{Hz}}\right]$')
legend('Location', 'southwest');
xlim([2, 500]);
ax2 = subplot(1, 2, 2);
hold on;
plot(gm.f, sqrt(psd_gm_d), 'DisplayName', 'D - Gm');
set(gca,'ColorOrderIndex',1);
plot(gm.f, sqrt(psd_gm_s), '--', 'HandleVisibility', 'off');
hold off;
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
xlabel('Frequency [Hz]'); ylabel('ASD of the ground displacement $\left[\frac{m}{\sqrt{Hz}}\right]$')
legend('Location', 'southwest');
xlim([2, 500]);
% #+NAME: fig:estimate_spectral_density_disturbances
% #+CAPTION: Estimated spectral density of the disturbances ([[./figs/estimate_spectral_density_disturbances.png][png]], [[./figs/estimate_spectral_density_disturbances.pdf][pdf]])
% [[file:figs/estimate_spectral_density_disturbances.png]]
figure;
hold on;
plot(gm.f, flip(sqrt(-cumtrapz(flip(gm.f), flip(psd_gm_d)))), 'DisplayName', 'Gm');
plot(gm.f, flip(sqrt(-cumtrapz(flip(gm.f), flip(psd_ty_d)))), 'DisplayName', 'Ty');
plot(gm.f, flip(sqrt(-cumtrapz(flip(gm.f), flip(psd_rz_d)))), 'DisplayName', 'Rz');
plot(gm.f, flip(sqrt(-cumtrapz(flip(gm.f), flip(psd_gm_d + psd_ty_d + psd_rz_d)))), 'k-', 'DisplayName', 'tot');
set(gca,'ColorOrderIndex',1);
plot(gm.f, flip(sqrt(-cumtrapz(flip(gm.f), flip(psd_gm_s)))), '--', 'HandleVisibility', 'off');
plot(gm.f, flip(sqrt(-cumtrapz(flip(gm.f), flip(psd_ty_s)))), '--', 'HandleVisibility', 'off');
plot(gm.f, flip(sqrt(-cumtrapz(flip(gm.f), flip(psd_rz_s)))), '--', 'HandleVisibility', 'off');
plot(gm.f, flip(sqrt(-cumtrapz(flip(gm.f), flip(psd_gm_s + psd_ty_s + psd_rz_s)))), 'k--', 'HandleVisibility', 'off');
hold off;
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
xlabel('Frequency [Hz]'); ylabel('Cumulative Amplitude Spectrum [m]')
legend('location', 'northeast');
xlim([2, 500]); ylim([1e-11, 1e-6]);
% Save
% The PSD of the disturbance force are now saved for further noise budgeting when control is applied (the mat file is accessible [[file:mat/dist_psd.mat][here]]).
dist_f = struct();
dist_f.f = gm.f; % Frequency Vector [Hz]
dist_f.psd_gm = gm.psd_gm; % Power Spectral Density of the Ground Motion [m^2/Hz]
dist_f.psd_ty = tyz.psd_f; % Power Spectral Density of the force induced by the Ty stage in the Z direction [N^2/Hz]
dist_f.psd_rz = rz.psd_f; % Power Spectral Density of the force induced by the Rz stage in the Z direction [N^2/Hz]
dist_f.G_gm = G_ty;
dist_f.G_ty = G_rz;
dist_f.G_rz = G_gm;
save('./disturbances/mat/dist_psd.mat', 'dist_f');
% Display Obtained Disturbances
initDisturbances();
load('./mat/nass_disturbances.mat', 'Dwx', 'Dwy', 'Dwz', 'Fty_x', 'Fty_z', 'Frz_z', 'Fd', 'Ts', 't');
figure;
hold on;
plot(t, Dwx, 'DisplayName', 'Dw x');
plot(t, Dwy, 'DisplayName', 'Dw y');
plot(t, Dwz, 'DisplayName', 'Dw z');
hold off;
xlabel('Time [s]'); ylabel('Amplitude [m]');
legend('location', 'north east');
figure;
hold on;
plot(t, Fty_x, 'DisplayName', 'Ty x');
plot(t, Fty_z, 'DisplayName', 'Ty z');
plot(t, Frz_z, 'DisplayName', 'Rz z');
hold off;
xlabel('Time [s]'); ylabel('Force [N]');
legend('location', 'north east');