201 lines
6.6 KiB
Mathematica
201 lines
6.6 KiB
Mathematica
|
%% Clear Workspace and Close figures
|
||
|
clear; close all; clc;
|
||
|
|
||
|
%% Intialize Laplace variable
|
||
|
s = zpk('s');
|
||
|
|
||
|
addpath('./mat/');
|
||
|
|
||
|
% Load Data
|
||
|
% Both the measurement data during the identification test and during an "huddle test" are loaded.
|
||
|
|
||
|
id = load('identification_noise_opt_iff.mat', 'd', 'acc_1', 'acc_2', 'geo_1', 'geo_2', 'f_meas', 'u', 't');
|
||
|
ht = load('huddle_test.mat', 'd', 'acc_1', 'acc_2', 'geo_1', 'geo_2', 'f_meas', 'u', 't');
|
||
|
|
||
|
ht.d = detrend(ht.d, 0);
|
||
|
ht.acc_1 = detrend(ht.acc_1, 0);
|
||
|
ht.acc_2 = detrend(ht.acc_2, 0);
|
||
|
ht.geo_1 = detrend(ht.geo_1, 0);
|
||
|
ht.geo_2 = detrend(ht.geo_2, 0);
|
||
|
ht.f_meas = detrend(ht.f_meas, 0);
|
||
|
|
||
|
id.d = detrend(id.d, 0);
|
||
|
id.acc_1 = detrend(id.acc_1, 0);
|
||
|
id.acc_2 = detrend(id.acc_2, 0);
|
||
|
id.geo_1 = detrend(id.geo_1, 0);
|
||
|
id.geo_2 = detrend(id.geo_2, 0);
|
||
|
id.f_meas = detrend(id.f_meas, 0);
|
||
|
|
||
|
% Compare PSD during Huddle and and during identification
|
||
|
% The Power Spectral Density of the measured motion during the huddle test and during the identification test are compared in Figures [[fig:comp_psd_huddle_test_identification_acc]] and [[fig:comp_psd_huddle_test_identification_geo]].
|
||
|
|
||
|
|
||
|
Ts = ht.t(2) - ht.t(1);
|
||
|
win = hann(ceil(10/Ts));
|
||
|
|
||
|
[p_id_d, f] = pwelch(id.d, win, [], [], 1/Ts);
|
||
|
[p_id_acc1, ~] = pwelch(id.acc_1, win, [], [], 1/Ts);
|
||
|
[p_id_acc2, ~] = pwelch(id.acc_2, win, [], [], 1/Ts);
|
||
|
[p_id_geo1, ~] = pwelch(id.geo_1, win, [], [], 1/Ts);
|
||
|
[p_id_geo2, ~] = pwelch(id.geo_2, win, [], [], 1/Ts);
|
||
|
|
||
|
[p_ht_d, ~] = pwelch(ht.d, win, [], [], 1/Ts);
|
||
|
[p_ht_acc1, ~] = pwelch(ht.acc_1, win, [], [], 1/Ts);
|
||
|
[p_ht_acc2, ~] = pwelch(ht.acc_2, win, [], [], 1/Ts);
|
||
|
[p_ht_geo1, ~] = pwelch(ht.geo_1, win, [], [], 1/Ts);
|
||
|
[p_ht_geo2, ~] = pwelch(ht.geo_2, win, [], [], 1/Ts);
|
||
|
[p_ht_fmeas, ~] = pwelch(ht.f_meas, win, [], [], 1/Ts);
|
||
|
|
||
|
figure;
|
||
|
hold on;
|
||
|
set(gca, 'ColorOrderIndex', 1);
|
||
|
plot(f, p_ht_acc1, 'DisplayName', 'Huddle Test');
|
||
|
set(gca, 'ColorOrderIndex', 1);
|
||
|
plot(f, p_ht_acc2, 'HandleVisibility', 'off');
|
||
|
set(gca, 'ColorOrderIndex', 2);
|
||
|
plot(f, p_id_acc1, 'DisplayName', 'Identification Test');
|
||
|
set(gca, 'ColorOrderIndex', 2);
|
||
|
plot(f, p_id_acc2, 'HandleVisibility', 'off');
|
||
|
hold off;
|
||
|
set(gca, 'Xscale', 'log'); set(gca, 'Yscale', 'log');
|
||
|
ylabel('PSD [$V^2/Hz$]'); xlabel('Frequency [Hz]');
|
||
|
title('Huddle Test - Accelerometers')
|
||
|
legend('location', 'northwest');
|
||
|
xlim([5e-1, 5e3]); ylim([1e-10, 1e-2])
|
||
|
|
||
|
|
||
|
|
||
|
% #+name: fig:comp_psd_huddle_test_identification_acc
|
||
|
% #+caption: Comparison of the PSD of the measured motion during the Huddle test and during the identification
|
||
|
% #+RESULTS:
|
||
|
% [[file:figs/comp_psd_huddle_test_identification_acc.png]]
|
||
|
|
||
|
|
||
|
figure;
|
||
|
hold on;
|
||
|
set(gca, 'ColorOrderIndex', 1);
|
||
|
plot(f, p_ht_geo1, 'DisplayName', 'Huddle Test');
|
||
|
set(gca, 'ColorOrderIndex', 1);
|
||
|
plot(f, p_ht_geo2, 'HandleVisibility', 'off');
|
||
|
set(gca, 'ColorOrderIndex', 2);
|
||
|
plot(f, p_id_geo1, 'DisplayName', 'Identification Test');
|
||
|
set(gca, 'ColorOrderIndex', 2);
|
||
|
plot(f, p_id_geo2, 'HandleVisibility', 'off');
|
||
|
hold off;
|
||
|
set(gca, 'Xscale', 'log'); set(gca, 'Yscale', 'log');
|
||
|
ylabel('PSD [$V^2/Hz$]'); xlabel('Frequency [Hz]');
|
||
|
title('Huddle Test - Geophones')
|
||
|
legend('location', 'northeast');
|
||
|
xlim([1e-1, 5e3]); ylim([1e-11, 1e-4]);
|
||
|
|
||
|
% Compute transfer functions
|
||
|
% The transfer functions from the motion as measured by the interferometer (and that should represent the absolute motion of the mass) to the inertial sensors are estimated:
|
||
|
|
||
|
[tf_acc1_est, f] = tfestimate(id.d, id.acc_1, win, [], [], 1/Ts);
|
||
|
[co_acc1_est, ~] = mscohere( id.d, id.acc_1, win, [], [], 1/Ts);
|
||
|
[tf_acc2_est, ~] = tfestimate(id.d, id.acc_2, win, [], [], 1/Ts);
|
||
|
[co_acc2_est, ~] = mscohere( id.d, id.acc_2, win, [], [], 1/Ts);
|
||
|
|
||
|
[tf_geo1_est, ~] = tfestimate(id.d, id.geo_1, win, [], [], 1/Ts);
|
||
|
[co_geo1_est, ~] = mscohere( id.d, id.geo_1, win, [], [], 1/Ts);
|
||
|
[tf_geo2_est, ~] = tfestimate(id.d, id.geo_2, win, [], [], 1/Ts);
|
||
|
[co_geo2_est, ~] = mscohere( id.d, id.geo_2, win, [], [], 1/Ts);
|
||
|
|
||
|
|
||
|
|
||
|
% The obtained coherence are shown in Figure [[fig:id_sensor_dynamics_coherence]].
|
||
|
|
||
|
|
||
|
figure;
|
||
|
hold on;
|
||
|
set(gca, 'ColorOrderIndex', 1);
|
||
|
plot(f, co_acc1_est, '-', 'DisplayName', 'Accelerometer')
|
||
|
set(gca, 'ColorOrderIndex', 1);
|
||
|
plot(f, co_acc2_est, '-', 'HandleVisibility', 'off')
|
||
|
set(gca, 'ColorOrderIndex', 2);
|
||
|
plot(f, co_geo1_est, '-', 'DisplayName', 'Geophone')
|
||
|
set(gca, 'ColorOrderIndex', 2);
|
||
|
plot(f, co_geo2_est, '-', 'HandleVisibility', 'off')
|
||
|
set(gca, 'Xscale', 'log'); set(gca, 'Yscale', 'lin');
|
||
|
ylabel('Coherence'); xlabel('Frequency [Hz]');
|
||
|
hold off;
|
||
|
xlim([2, 2e3]); ylim([0, 1])
|
||
|
legend();
|
||
|
|
||
|
|
||
|
|
||
|
% #+name: fig:id_sensor_dynamics_coherence
|
||
|
% #+caption: Coherence for the estimation of the sensor dynamics
|
||
|
% #+RESULTS:
|
||
|
% [[file:figs/id_sensor_dynamics_coherence.png]]
|
||
|
|
||
|
% We also make a simplified model of the inertial sensors to be compared with the identified dynamics.
|
||
|
|
||
|
G_acc = 1/(1 + s/2/pi/2500); % [V/(m/s2)]
|
||
|
G_geo = -1200*s^2/(s^2 + 2*0.7*2*pi*2*s + (2*pi*2)^2); % [[V/(m/s)]
|
||
|
|
||
|
|
||
|
|
||
|
% The model and identified dynamics show good agreement (Figures [[fig:id_sensor_dynamics_accelerometers]] and [[fig:id_sensor_dynamics_geophones]].)
|
||
|
|
||
|
|
||
|
figure;
|
||
|
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
|
||
|
|
||
|
ax1 = nexttile([2,1]);
|
||
|
hold on;
|
||
|
plot(f, abs(tf_acc1_est./(1i*2*pi*f).^2), '.')
|
||
|
plot(f, abs(tf_acc2_est./(1i*2*pi*f).^2), '.')
|
||
|
plot(f, abs(squeeze(freqresp(G_acc, f, 'Hz'))), 'k-')
|
||
|
set(gca, 'Xscale', 'log'); set(gca, 'Yscale', 'log');
|
||
|
ylabel('Amplitude $\left[\frac{V}{m/s^2}\right]$'); set(gca, 'XTickLabel',[]);
|
||
|
hold off;
|
||
|
|
||
|
ax2 = nexttile;
|
||
|
hold on;
|
||
|
plot(f, 180/pi*angle(tf_acc1_est./(1i*2*pi*f).^2), '.')
|
||
|
plot(f, 180/pi*angle(tf_acc2_est./(1i*2*pi*f).^2), '.')
|
||
|
plot(f, 180/pi*angle(squeeze(freqresp(G_acc, f, 'Hz'))), 'k-')
|
||
|
set(gca, 'Xscale', 'log'); set(gca, 'Yscale', 'lin');
|
||
|
ylabel('Phase'); xlabel('Frequency [Hz]');
|
||
|
hold off;
|
||
|
ylim([-180, 180]);
|
||
|
yticks([-180, -90, 0, 90, 180]);
|
||
|
|
||
|
linkaxes([ax1,ax2], 'x');
|
||
|
xlim([2, 2e3]);
|
||
|
|
||
|
|
||
|
|
||
|
% #+name: fig:id_sensor_dynamics_accelerometers
|
||
|
% #+caption: Identified dynamics of the accelerometers
|
||
|
% #+RESULTS:
|
||
|
% [[file:figs/id_sensor_dynamics_accelerometers.png]]
|
||
|
|
||
|
|
||
|
figure;
|
||
|
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
|
||
|
|
||
|
ax1 = nexttile([2,1]);
|
||
|
hold on;
|
||
|
plot(f, abs(tf_geo1_est./(1i*2*pi*f)), '.')
|
||
|
plot(f, abs(tf_geo2_est./(1i*2*pi*f)), '.')
|
||
|
plot(f, abs(squeeze(freqresp(G_geo, f, 'Hz'))), 'k-')
|
||
|
set(gca, 'Xscale', 'log'); set(gca, 'Yscale', 'log');
|
||
|
ylabel('Amplitude $\left[\frac{V}{m/s}\right]$'); set(gca, 'XTickLabel',[]);
|
||
|
hold off;
|
||
|
|
||
|
ax2 = nexttile;
|
||
|
hold on;
|
||
|
plot(f, 180/pi*angle(tf_geo1_est./(1i*2*pi*f)), '.')
|
||
|
plot(f, 180/pi*angle(tf_geo2_est./(1i*2*pi*f)), '.')
|
||
|
plot(f, 180/pi*angle(squeeze(freqresp(G_geo, f, 'Hz'))), 'k-')
|
||
|
set(gca, 'Xscale', 'log'); set(gca, 'Yscale', 'lin');
|
||
|
ylabel('Phase'); xlabel('Frequency [Hz]');
|
||
|
hold off;
|
||
|
ylim([-180, 180]);
|
||
|
yticks([-180, -90, 0, 90, 180]);
|
||
|
|
||
|
linkaxes([ax1,ax2], 'x');
|
||
|
xlim([0.5, 2e3]);
|