diff --git a/Analysis/ground_motion_ol_cl.m b/Analysis/ground_motion_ol_cl.m index 2dd51cc..e620911 100644 --- a/Analysis/ground_motion_ol_cl.m +++ b/Analysis/ground_motion_ol_cl.m @@ -138,10 +138,10 @@ han_windows = hanning(ceil(length(gm_cl.Dsample.Time)/10)); figure; hold on; -plot(freqs_z_ol, sqrt(psd_z_ol), '-', 'Color', [0 0.4470 0.7410], 'DisplayName', '$Dg \rightarrow D_x$ - OL (sim)'); -plot(freqs, dz_ol, '--', 'Color', [0 0.4470 0.7410], 'DisplayName', '$Dg \rightarrow D_x$ - OL (th)'); -plot(freqs_z, sqrt(psd_z), '-', 'Color', [0.8500 0.3250 0.0980], 'DisplayName', '$Dg \rightarrow D_x$ - CL (sim)'); -plot(freqs, dz_cl, '--', 'Color', [0.8500 0.3250 0.0980], 'DisplayName', '$Dg \rightarrow D_x$ - CL (th)'); +plot(freqs_z_ol, sqrt(psd_z_ol), '-', 'Color', [0 0.4470 0.7410], 'DisplayName', '$Dg \to D_x$ - OL (sim)'); +plot(freqs, dz_ol, '--', 'Color', [0 0.4470 0.7410], 'DisplayName', '$Dg \to D_x$ - OL (th)'); +plot(freqs_z, sqrt(psd_z), '-', 'Color', [0.8500 0.3250 0.0980], 'DisplayName', '$Dg \to D_x$ - CL (sim)'); +plot(freqs, dz_cl, '--', 'Color', [0.8500 0.3250 0.0980], 'DisplayName', '$Dg \to D_x$ - CL (th)'); set(gca,'xscale','log'); set(gca,'yscale','log'); xlabel('Frequency [Hz]'); ylabel('PSD [$m/\sqrt{Hz}$]'); legend('location', 'southwest'); diff --git a/Control/cl_tf.m b/Control/cl_tf.m index 8cc6696..dafd902 100644 --- a/Control/cl_tf.m +++ b/Control/cl_tf.m @@ -6,7 +6,7 @@ load('./mat/G_xg_to_d.mat', 'G_xg_to_d'); load('./mat/G_f_to_d.mat', 'G_1', 'G_20', 'G_50'); load('./mat/controller.mat', 'K'); -%% +%% S = minreal(inv(tf(eye(6))+G_20*K)); T = minreal((tf(eye(6))+G_20*K)\G_20*K); diff --git a/Identification/Micro_Station_Identification.slx b/Identification/Micro_Station_Identification.slx deleted file mode 100644 index ea037d8..0000000 Binary files a/Identification/Micro_Station_Identification.slx and /dev/null differ diff --git a/Identification/compare_measurements.m b/Identification/compare_measurements.m deleted file mode 100644 index ec00ad5..0000000 --- a/Identification/compare_measurements.m +++ /dev/null @@ -1,191 +0,0 @@ -%% Script Description -% Compare identification from the Simscape model -% with the identification on the real system. - -%% -clear; -close all; -clc - -%% Get Measurement Object -% load('~/ownCloud/Measurements/2017-11-17 - Marc/data/2017_11_17.mat', 'm_object') -load([char(java.lang.System.getProperty('user.home')), '\ownCloud\Measurements\2018-01-12 - Marc\data\2018_01_12_pc.mat'], 'm_object') - -%% Get Measurements -% Define Options for measurements -meas_opts = struct( ... - 'coh_min', 50, ... - 'freq_min', 20 ... -); - -measure_dirs = {{'tx', 'tx'}, {'ty', 'ty'}, {'tz', 'tz'}}; - -% Get measures -measures = getAllMeasure(m_object, 'marble', 'hexa', measure_dirs, meas_opts); - -%% -load('./mat/id_G_h_h.mat', 'G_h_h'); -load('./mat/id_G_g_g.mat', 'G_g_g'); -load('./mat/id_G_h_g.mat', 'G_h_g'); - -%% -freqs = logspace(1, 3, 2000); - -%% Granite to Granite -figure; -hold on; -plot(measures.Fmx.Dmx.freq_filt, abs(measures.Fmx.Dmx.resp_filt)) -plot(freqs, abs(squeeze(freqresp(G_g_g(1, 1), freqs, 'Hz')))); -hold off; -set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); -xlabel('Frequency [$Hz$]'); ylabel('Amplitude [$m/N$]'); -legend({'meas.', 'id.'}, 'location', 'northwest'); -title('Transfer function: $F(Granite)_x \rightarrow D(granite)_x$'); -exportFig('comp_model_meas_Fmx_Dmx', struct('path', 'Identification')); - -% -figure; -hold on; -plot(measures.Fmy.Dmy.freq_filt, abs(measures.Fmy.Dmy.resp_filt)) -plot(freqs, abs(squeeze(freqresp(G_g_g(2, 2), freqs, 'Hz')))); -hold off; -set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); -xlabel('Frequency [$Hz$]'); ylabel('Amplitude [$m/N$]'); -legend({'meas.', 'id.'}, 'location', 'northwest'); -title('Transfer function: $F(Granite)_y \rightarrow D(granite)_y$'); -exportFig('comp_model_meas_Fmy_Dmy', struct('path', 'Identification')); - -% -figure; -hold on; -plot(measures.Fmz.Dmz.freq_filt, abs(measures.Fmz.Dmz.resp_filt)) -plot(freqs, abs(squeeze(freqresp(G_g_g(3, 3), freqs, 'Hz')))); -hold off; -set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); -xlabel('Frequency [$Hz$]'); ylabel('Amplitude [$m/N$]'); -legend({'meas.', 'id.'}, 'location', 'northwest'); -title('Transfer function: $F(Granite)_z \rightarrow D(granite)_z$'); -exportFig('comp_model_meas_Fmz_Dmz', struct('path', 'Identification')); - -% All together -figure; -hold on; -plot(measures.Fmx.Dmx.freq_filt, abs(measures.Fmx.Dmx.resp_filt), '-', 'Color', [0 0.4470 0.7410], 'DisplayName', '$F_{m_x} \rightarrow D_{m_x}$ - meas.') -plot(freqs, abs(squeeze(freqresp(G_g_g(1, 1), freqs, 'Hz'))), '--', 'Color', [0 0.4470 0.7410], 'DisplayName', '$F_{m_x} \rightarrow D_{m_x}$ - model'); - -plot(measures.Fmy.Dmy.freq_filt, abs(measures.Fmy.Dmy.resp_filt), '-', 'Color', [0.8500 0.3250 0.0980], 'DisplayName', '$F_{m_y} \rightarrow D_{m_y}$ - meas.') -plot(freqs, abs(squeeze(freqresp(G_g_g(2, 2), freqs, 'Hz'))), '--', 'Color', [0.8500 0.3250 0.0980], 'DisplayName', '$F_{m_y} \rightarrow D_{m_y}$ - model'); - -plot(measures.Fmz.Dmz.freq_filt, abs(measures.Fmz.Dmz.resp_filt), '-', 'Color', [0.9290 0.6940 0.1250], 'DisplayName', '$F_{m_z} \rightarrow D_{m_z}$ - meas.') -plot(freqs, abs(squeeze(freqresp(G_g_g(3, 3), freqs, 'Hz'))), '--', 'Color', [0.9290 0.6940 0.1250], 'DisplayName', '$F_{m_z} \rightarrow D_{m_z}$ - model'); -hold off; -set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); -xlabel('Frequency [Hz]'); ylabel('Amplitude [m/N]'); -legend('location', 'northeast'); -exportFig('comp_model_meas_Fm_Dm', 'wide-tall', struct('path', 'Identification')); - -%% Hexapod to Hexapod -figure; -hold on; -plot(measures.Fhx.Dhx.freq_filt, abs(measures.Fhx.Dhx.resp_filt)) -plot(freqs, abs(squeeze(freqresp(G_h_h(1, 1), freqs, 'Hz')))); -hold off; -set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); -xlabel('Frequency [$Hz$]'); ylabel('Amplitude [$m/N$]'); -legend({'meas.', 'id.'}, 'location', 'northwest'); -title('Transfer function: $F(\mu Hexapod)_x \rightarrow D(\mu Hexapod)_x$'); -exportFig('comp_model_meas_Fhx_Dhx', struct('path', 'Identification')); - -% -figure; -hold on; -plot(measures.Fhy.Dhy.freq_filt, abs(measures.Fhy.Dhy.resp_filt)) -plot(freqs, abs(squeeze(freqresp(G_h_h(2, 2), freqs, 'Hz')))); -hold off; -set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); -xlabel('Frequency [$Hz$]'); ylabel('Amplitude [$m/N$]'); -legend({'meas.', 'id.'}, 'location', 'northwest'); -title('Transfer function: $F(\mu Hexapod)_y \rightarrow D(\mu Hexapod)_y$'); -exportFig('comp_model_meas_Fhy_Dhy', struct('path', 'Identification')); - -% -figure; -hold on; -plot(measures.Fhz.Dhz.freq_filt, abs(measures.Fhz.Dhz.resp_filt)) -plot(freqs, abs(squeeze(freqresp(G_h_h(3, 3), freqs, 'Hz')))); -hold off; -set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); -xlabel('Frequency [$Hz$]'); ylabel('Amplitude [$m/N$]'); -legend({'meas.', 'id.'}, 'location', 'northwest'); -title('Transfer function: $F(\mu Hexapod)_z \rightarrow D(\mu Hexapod)_z$'); -exportFig('comp_model_meas_Fhz_Dhz', struct('path', 'Identification')); - -% All together -figure; -hold on; -plot(measures.Fhx.Dhx.freq_filt, abs(measures.Fhx.Dhx.resp_filt), '-', 'Color', [0 0.4470 0.7410], 'DisplayName', '$F_{h_x} \rightarrow D_{h_x}$ - meas.') -plot(freqs, abs(squeeze(freqresp(G_h_h(1, 1), freqs, 'Hz'))), '--', 'Color', [0 0.4470 0.7410], 'DisplayName', '$F_{h_x} \rightarrow D_{h_x}$ - model'); - -plot(measures.Fhy.Dhy.freq_filt, abs(measures.Fhy.Dhy.resp_filt), '-', 'Color', [0.8500 0.3250 0.0980], 'DisplayName', '$F_{h_y} \rightarrow D_{h_y}$ - meas.') -plot(freqs, abs(squeeze(freqresp(G_h_h(2, 2), freqs, 'Hz'))), '--', 'Color', [0.8500 0.3250 0.0980], 'DisplayName', '$F_{h_y} \rightarrow D_{h_y}$ - model'); - -plot(measures.Fhz.Dhz.freq_filt, abs(measures.Fhz.Dhz.resp_filt), '-', 'Color', [0.9290 0.6940 0.1250], 'DisplayName', '$F_{h_z} \rightarrow D_{h_z}$ - meas.') -plot(freqs, abs(squeeze(freqresp(G_h_h(3, 3), freqs, 'Hz'))), '--', 'Color', [0.9290 0.6940 0.1250], 'DisplayName', '$F_{h_z} \rightarrow D_{h_z}$ - model'); -hold off; -set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); -xlabel('Frequency [Hz]'); ylabel('Amplitude [m/N]'); -legend('location', 'southwest'); -exportFig('comp_model_meas_Fh_Dh', 'wide-tall', struct('path', 'Identification')); - -%% Hexapod to Granite -figure; -hold on; -plot(measures.Fhx.Dmx.freq_filt, abs(measures.Fhx.Dmx.resp_filt)) -plot(freqs, abs(squeeze(freqresp(G_h_g(1, 1), freqs, 'Hz')))); -hold off; -set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); -xlabel('Frequency [$Hz$]'); ylabel('Amplitude [$m/N$]'); -legend({'meas.', 'id.'}, 'location', 'northwest'); -title('Transfer function: $F(\mu Hexapod)_x \rightarrow D(Granite)_x$'); -exportFig('comp_model_meas_Fhx_Dmx', struct('path', 'Identification')); - -% -figure; -hold on; -plot(measures.Fhy.Dmy.freq_filt, abs(measures.Fhy.Dmy.resp_filt)) -plot(freqs, abs(squeeze(freqresp(G_h_g(2, 2), freqs, 'Hz')))); -hold off; -set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); -xlabel('Frequency [$Hz$]'); ylabel('Amplitude [$m/N$]'); -legend({'meas.', 'id.'}, 'location', 'northwest'); -title('Transfer function: $F(\mu Hexapod)_y \rightarrow D(Granite)_y$'); -exportFig('comp_model_meas_Fhy_Dmy', struct('path', 'Identification')); - -% -figure; -hold on; -plot(measures.Fhz.Dmz.freq_filt, abs(measures.Fhz.Dmz.resp_filt)) -plot(freqs, abs(squeeze(freqresp(G_h_g(3, 3), freqs, 'Hz')))); -hold off; -set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); -xlabel('Frequency [$Hz$]'); ylabel('Amplitude [$m/N$]'); -legend({'meas.', 'id.'}, 'location', 'northwest'); -title('Transfer function: $F(\mu Hexapod)_z \rightarrow D(Granite)_z$'); -exportFig('comp_model_meas_Fhz_Dmz', struct('path', 'Identification')); - -% All together -figure; -hold on; -plot(measures.Fhx.Dmx.freq_filt, abs(measures.Fhx.Dmx.resp_filt), '-', 'Color', [0 0.4470 0.7410], 'DisplayName', '$F_{h_x} \rightarrow D_{m_x}$ - meas.') -plot(freqs, abs(squeeze(freqresp(G_h_g(1, 1), freqs, 'Hz'))), '--', 'Color', [0 0.4470 0.7410], 'DisplayName', '$F_{h_x} \rightarrow D_{m_x}$ - model'); - -plot(measures.Fhy.Dmy.freq_filt, abs(measures.Fhy.Dmy.resp_filt), '-', 'Color', [0.8500 0.3250 0.0980], 'DisplayName', '$F_{h_y} \rightarrow D_{m_y}$ - meas.') -plot(freqs, abs(squeeze(freqresp(G_h_g(2, 2), freqs, 'Hz'))), '--', 'Color', [0.8500 0.3250 0.0980], 'DisplayName', '$F_{h_y} \rightarrow D_{m_y}$ - model'); - -plot(measures.Fhz.Dmz.freq_filt, abs(measures.Fhz.Dmz.resp_filt), '-', 'Color', [0.9290 0.6940 0.1250], 'DisplayName', '$F_{h_z} \rightarrow D_{m_z}$ - meas.') -plot(freqs, abs(squeeze(freqresp(G_h_g(3, 3), freqs, 'Hz'))), '--', 'Color', [0.9290 0.6940 0.1250], 'DisplayName', '$F_{h_z} \rightarrow D_{m_z}$ - model'); -hold off; -set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); -xlabel('Frequency [Hz]'); ylabel('Amplitude [m/N]'); -legend('location', 'southwest'); -exportFig('comp_model_meas_Fh_Dm', 'wide-tall', struct('path', 'Identification')); diff --git a/Identification/compare_nass_micro_station.m b/Identification/compare_nass_micro_station.m deleted file mode 100644 index fc79ed7..0000000 --- a/Identification/compare_nass_micro_station.m +++ /dev/null @@ -1,41 +0,0 @@ -%% Script Description -% Compare the plan when on top of a rigid support -% and on top of the micro-station (flexible support) - -%% -clear; close all; clc; - -%% Load Transfer Functions -load('./mat/G_nass.mat', 'G_nass_1', 'G_nass_20', 'G_nass_50'); -load('./stewart-simscape/mat/G_cart.mat', 'G_cart_1', 'G_cart_20', 'G_cart_50') -load('./mat/G_f_to_d.mat', 'G_1', 'G_20', 'G_50') - -%% Compare NASS alone and NASS on top of the Station -freqs = logspace(1, 4, 1000); - -bodeFig({G_nass_50(1, 1), G_cart_50(1, 1)}, freqs, struct('phase', true)) -legend({'$F_{n_x} \rightarrow D_{n_x}$ - $\mu$-station', '$F_{n_x} \rightarrow D_{n_x}$ - Rigid support'}) -legend('location', 'southwest') - -bodeFig({G_nass_50(2, 2), G_cart_50(2, 2)}, freqs, struct('phase', true)) -legend({'$F_{n_y} \rightarrow D_{n_y}$ - $\mu$-station', '$F_{n_y} \rightarrow D_{n_y}$ - rigid support'}) -legend('location', 'southwest') - -bodeFig({G_nass_50(3, 3), G_cart_50(3, 3)}, freqs, struct('phase', true)) -legend({'$F_{n_z} \rightarrow D_{n_z}$ - $\mu$-station', '$F_{n_z} \rightarrow D_{n_z}$ - rigid support'}) -legend('location', 'southwest') - -%% Compare Displacement of the NASS with Displacement of the Sample -freqs = logspace(1, 3, 1000); - -bodeFig({G_nass_50(1, 1), G_50(1, 1)}, freqs, struct('phase', true)) -legend({'$F_{n_x} \rightarrow D_{n_x}$', '$F_{n_x} \rightarrow D_{s_x}$'}) -legend('location', 'southwest') - -bodeFig({G_nass_50(2, 2), G_50(2, 2)}, freqs, struct('phase', true)) -legend({'$F_{n_y} \rightarrow D_{n_y}$', '$F_{n_y} \rightarrow D_{s_y}$'}) -legend('location', 'southwest') - -bodeFig({G_nass_50(3, 3), G_50(3, 3)}, freqs, struct('phase', true)) -legend({'$F_{n_z} \rightarrow D_{n_z}$', '$F_{n_z} \rightarrow D_{s_z}$'}) -legend('location', 'southwest') diff --git a/config.m b/config.m index 48c56eb..f8c8d17 100644 --- a/config.m +++ b/config.m @@ -5,3 +5,8 @@ % addpath('./initialize/'); % addpath('./src/'); % addpath('./stewart-simscape/'); + +%% +freqs = logspace(-1, 3, 1000); +save_fig = false; +save('./mat/config.mat', 'freqs', 'save_fig'); diff --git a/identification/id_G.m b/identification/id_G.m index 21a5d12..876464d 100644 --- a/identification/id_G.m +++ b/identification/id_G.m @@ -7,19 +7,22 @@ clear; close all; clc; %% +initializeNanoHexapod(struct('actuator', 'lorentz')); initializeSample(struct('mass', 1)); -[G_1, G_1_raw] = identifyG(); - -%% -initializeSample(struct('mass', 20)); - -[G_20, G_20_raw] = identifyG(); +G_1_vc = identifyG(); + +initializeNanoHexapod(struct('actuator', 'piezo')); +G_1_pz = identifyG(); %% +initializeNanoHexapod(struct('actuator', 'lorentz')); initializeSample(struct('mass', 50)); -[G_50, G_50_raw] = identifyG(); +G_50_vc = identifyG(); + +initializeNanoHexapod(struct('actuator', 'piezo')); +G_50_pz = identifyG(); %% Save the obtained transfer functions -save('./mat/G_f_to_d.mat', 'G_1', 'G_20', 'G_50'); +save('./mat/G_f_to_d.mat', 'G_1_vc', 'G_1_pz', 'G_50_vc', 'G_50_pz'); diff --git a/identification/id_G_plots.m b/identification/id_G_plots.m index 429df4a..3d15275 100644 --- a/identification/id_G_plots.m +++ b/identification/id_G_plots.m @@ -2,62 +2,114 @@ clear; close all; clc; %% Load the transfer functions -load('./mat/G_f_to_d.mat', 'G_1', 'G_20', 'G_50'); +load('./mat/G_f_to_d.mat', 'G_1_vc', 'G_1_pz', 'G_50_vc', 'G_50_pz'); + +%% Load Configuration file +load('./mat/config.mat', 'save_fig', 'freqs'); %% -freqs = logspace(0, 3, 1000); - -bodeFig({G_1(1, 1), G_1(2, 2), G_1(3, 3)}, freqs, struct('phase', true)) -legend({'$F_{n_x} \rightarrow D_{x}$ - $M = 1Kg$', ... - '$F_{n_y} \rightarrow D_{y}$ - $M = 1Kg$', ... - '$F_{n_z} \rightarrow D_{z}$ - $M = 1Kg$'}) -legend('location', 'southwest') -exportFig('G_xyz_1', 'normal-normal', struct('path', 'identification')) - -bodeFig({G_20(1, 1), G_20(2, 2), G_20(3, 3)}, struct('phase', true)) -legend({'$F_{n_x} \rightarrow D_{x}$ - $M = 20Kg$', ... - '$F_{n_y} \rightarrow D_{y}$ - $M = 20Kg$', ... - '$F_{n_z} \rightarrow D_{z}$ - $M = 20Kg$'}) -legend('location', 'southwest') -exportFig('G_xyz_20', 'normal-normal', struct('path', 'identification')) - -bodeFig({G_1(1, 1), G_20(1, 1), G_50(1, 1)}, struct('phase', true)) -legend({'$F_{n_x} \rightarrow D_{x}$ - $M = 1Kg$', ... - '$F_{n_x} \rightarrow D_{x}$ - $M = 20Kg$', ... - '$F_{n_x} \rightarrow D_{x}$ - $M = 50Kg$'}) -legend('location', 'southwest') -exportFig('G_x_mass', 'normal-normal', struct('path', 'identification')) - -bodeFig({G_1(2, 2), G_20(2, 2), G_50(2, 2)}, struct('phase', true)) -legend({'$F_{n_y} \rightarrow D_{y}$ - $M = 1Kg$', ... - '$F_{n_y} \rightarrow D_{y}$ - $M = 20Kg$', ... - '$F_{n_y} \rightarrow D_{y}$ - $M = 50Kg$'}) -legend('location', 'southwest') -exportFig('G_y_mass', 'half-normal') - -bodeFig({G_1(3, 3), G_20(3, 3), G_50(3, 3)}, struct('phase', true)) -legend({'$F_{n_z} \rightarrow D_{z}$ - $M = 1Kg$', ... - '$F_{n_z} \rightarrow D_{z}$ - $M = 20Kg$', ... - '$F_{n_z} \rightarrow D_{z}$ - $M = 50Kg$'}) -legend('location', 'southwest') -exportFig('G_z_mass', 'normal-normal', struct('path', 'identification')) - - -%% -bodeFig({G_1(2, 2), G_20(2, 2), G_50(2, 2)}, freqs, struct('phase', true)) -legend({'$M = 1Kg$', ... - '$M = 20Kg$', ... - '$M = 50Kg$'}) -exportFig('G_y_mass_article', 'half-normal', struct('path', 'identification')) - -%% -freqs = logspace(-1, 3, 1000); -bodeFig({G_1(1, 1), G_20(1, 1), G_50(1, 1)}, freqs, struct('phase', true)) +figure; +% Amplitude +ax1 = subaxis(2,1,1); +hold on; +plot(freqs, abs(squeeze(freqresp(G_1_vc('Dx', 'Fnx'), freqs, 'Hz')))); +plot(freqs, abs(squeeze(freqresp(G_1_pz('Dx', 'Fnx'), freqs, 'Hz')))); +set(gca,'ColorOrderIndex',1); +plot(freqs, abs(squeeze(freqresp(G_50_vc('Dx', 'Fnx'), freqs, 'Hz'))), '--'); +plot(freqs, abs(squeeze(freqresp(G_50_pz('Dx', 'Fnx'), freqs, 'Hz'))), '--'); +set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); +set(gca, 'XTickLabel',[]); ylabel('Amplitude [m/N]'); -legend({'$1Kg$', ... - '$20Kg$', ... - '$50Kg$'}) -legend('location', 'southwest') -set(gca,'YTick',[1e-8, 1e-6, 1e-4]) -ylim([1e-9, 1e-3]) -exportFig('G_x_mass', 'half-short', struct('path', 'identification')) +hold off; + +% Phase +ax2 = subaxis(2,1,2); +hold on; +plot(freqs, 180/pi*angle(squeeze(freqresp(G_1_vc('Dx', 'Fnx'), freqs, 'Hz'))), 'DisplayName', 'VC - Light'); +plot(freqs, 180/pi*angle(squeeze(freqresp(G_1_pz('Dx', 'Fnx'), freqs, 'Hz'))), 'DisplayName', 'PZ - Light'); +set(gca,'ColorOrderIndex',1) +plot(freqs, 180/pi*angle(squeeze(freqresp(G_50_vc('Dx', 'Fnx'), freqs, 'Hz'))), '--', 'DisplayName', 'VC - Heavy'); +plot(freqs, 180/pi*angle(squeeze(freqresp(G_50_pz('Dx', 'Fnx'), freqs, 'Hz'))), '--', 'DisplayName', 'PZ - Heavy'); +set(gca,'xscale','log'); +yticks(-1800:90:1800); +ylim([-180 180]); +xlabel('Frequency [Hz]'); ylabel('Phase [deg]'); +legend('Location', 'southwest'); +hold off; + +linkaxes([ax1,ax2],'x'); + +if save_fig; exportFig('comp_models_plant_x_x', 'normal-normal', struct('path', 'identification')); end + +%% +figure; +% Amplitude +ax1 = subaxis(2,1,1); +hold on; +plot(freqs, abs(squeeze(freqresp(G_1_vc('Dz', 'Fnz'), freqs, 'Hz')))); +plot(freqs, abs(squeeze(freqresp(G_1_pz('Dz', 'Fnz'), freqs, 'Hz')))); +set(gca,'ColorOrderIndex',1); +plot(freqs, abs(squeeze(freqresp(G_50_vc('Dz', 'Fnz'), freqs, 'Hz'))), '--'); +plot(freqs, abs(squeeze(freqresp(G_50_pz('Dz', 'Fnz'), freqs, 'Hz'))), '--'); +set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); +set(gca, 'XTickLabel',[]); +ylabel('Amplitude [m/N]'); +hold off; + +% Phase +ax2 = subaxis(2,1,2); +hold on; +plot(freqs, 180/pi*angle(squeeze(freqresp(G_1_vc('Dz', 'Fnz'), freqs, 'Hz'))), 'DisplayName', 'VC - Light'); +plot(freqs, 180/pi*angle(squeeze(freqresp(G_1_pz('Dz', 'Fnz'), freqs, 'Hz'))), 'DisplayName', 'PZ - Light'); +set(gca,'ColorOrderIndex',1) +plot(freqs, 180/pi*angle(squeeze(freqresp(G_50_vc('Dz', 'Fnz'), freqs, 'Hz'))), '--', 'DisplayName', 'VC - Heavy'); +plot(freqs, 180/pi*angle(squeeze(freqresp(G_50_pz('Dz', 'Fnz'), freqs, 'Hz'))), '--', 'DisplayName', 'PZ - Heavy'); +set(gca,'xscale','log'); +yticks(-1800:90:1800); +ylim([-180 180]); +xlabel('Frequency [Hz]'); ylabel('Phase [deg]'); +legend('Location', 'southwest'); +hold off; + +linkaxes([ax1,ax2],'x'); + +if save_fig; exportFig('comp_models_plant_z_z', 'normal-normal', struct('path', 'identification')); end + +%% Plot all the coupling +figure; + +for i_input = 1:3 + for i_output = 1:3 + subaxis(3,3,3*(i_input-1)+i_output); + hold on; + plot(freqs, abs(squeeze(freqresp(G_1_vc(i_output, i_input), freqs, 'Hz')))); + plot(freqs, abs(squeeze(freqresp(G_1_pz(i_output, i_input), freqs, 'Hz')))); + set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); + xlim([freqs(1) freqs(end)]); ylim([1e-12, 1e-2]); + yticks([1e-12, 1e-8, 1e-4]); xticks([0.1 1 10 100 1000]); + if i_output > 1; set(gca,'yticklabel',[]); end + if i_input < 3; set(gca,'xticklabel',[]); end + hold off; + end +end + +if save_fig; exportFig('comp_models_plant_coupling_all', 'full-tall', struct('path', 'identification')); end + +%% Plot some coupling +figure; +hold on; +plot(freqs, abs(squeeze(freqresp(G_1_vc('Dx', 'Fnx'), freqs, 'Hz'))), 'DisplayName', 'VC - Light - $Fx \to Dx$'); +plot(freqs, abs(squeeze(freqresp(G_1_pz('Dx', 'Fnx'), freqs, 'Hz'))), 'DisplayName', 'PZ - Light - $Fx \to Dx$'); +set(gca,'ColorOrderIndex',1); +plot(freqs, abs(squeeze(freqresp(G_1_vc('Dy', 'Fnx'), freqs, 'Hz'))), '--', 'DisplayName', 'VC - Heavy - $Fx \to Dy$'); +plot(freqs, abs(squeeze(freqresp(G_1_pz('Dy', 'Fnx'), freqs, 'Hz'))), '--', 'DisplayName', 'PZ - Heavy - $Fx \to Dy$'); +set(gca,'ColorOrderIndex',1); +plot(freqs, abs(squeeze(freqresp(G_1_vc('Dz', 'Fnx'), freqs, 'Hz'))), '-.', 'DisplayName', 'VC - Heavy - $Fx \to Dz$'); +plot(freqs, abs(squeeze(freqresp(G_1_pz('Dz', 'Fnx'), freqs, 'Hz'))), '-.', 'DisplayName', 'PZ - Heavy - $Fx \to Dz$'); +set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); +xlabel('Frequency [Hz]'); ylabel('Amplitude [m/m]'); +legend('Location', 'southwest'); +xticks('manual'); xlim([freqs(1) freqs(end)]); +hold off; + +if save_fig; exportFig('comp_models_plant_coupling', 'normal-normal', struct('path', 'identification')); end diff --git a/identification/id_Gd.m b/identification/id_Gd.m index ef72575..67cfce0 100644 --- a/identification/id_Gd.m +++ b/identification/id_Gd.m @@ -1,19 +1,28 @@ %% Script Description % Identification of the transfer function -% from Ground Motion to sample displacement. +% from Ground Motion to measured displacement %% clear; close all; clc; -%% -initializeSample(struct('mass', 20)); -initializeSimConf(struct('cl_time', 0)); +%% Open Loop - Light Sample +initializeSample(struct('mass', 1)); -%% Open Loop -[Gd_ol_20, Gd_ol_20_raw] = identifyGd(struct('cl', false)); +initializeNanoHexapod(struct('actuator', 'lorentz')); +Gd_ol_1_vc = identifyGd(struct('cl', false)); -%% Close Loop -[Gd_cl_20, Gd_cl_20_raw] = identifyGd(struct('cl', true)); +initializeNanoHexapod(struct('actuator', 'piezo')); +Gd_ol_1_pz = identifyGd(struct('cl', false)); + +%% Open Loop - Heavy Sample +initializeSample(struct('mass', 50)); + +initializeNanoHexapod(struct('actuator', 'lorentz')); +Gd_ol_50_vc = identifyGd(struct('cl', false)); + +initializeNanoHexapod(struct('actuator', 'piezo')); +Gd_ol_50_pz = identifyGd(struct('cl', false)); %% Save the identified transfer functions -save('./mat/Gd_ol_cl.mat', 'Gd_ol_20', 'Gd_cl_20'); +save('./mat/G_xw_to_d.mat', ... + 'Gd_ol_1_vc', 'Gd_ol_1_pz', 'Gd_ol_50_vc', 'Gd_ol_50_pz'); diff --git a/identification/id_Gd_plots.m b/identification/id_Gd_plots.m index b892a71..2855759 100644 --- a/identification/id_Gd_plots.m +++ b/identification/id_Gd_plots.m @@ -2,11 +2,38 @@ clear; close all; clc; %% Load the identified transfer functions -load('./mat/Gd_ol_cl.mat', 'Gd_ol_20', 'Gd_cl_20'); +load('./mat/G_xw_to_d.mat', ... + 'Gd_ol_1_vc', 'Gd_ol_1_pz', 'Gd_ol_50_vc', 'Gd_ol_50_pz'); -%% -freqs = logspace(0, 3, 1000); -bodeFig({Gd_ol_20(1, 1), Gd_cl_20(1, 1)}, freqs, struct('ylabel', 'Amplitude [m/m]')) -legend({'OL', 'CL'}); +%% Load Configuration file +load('./mat/config.mat', 'save_fig', 'freqs'); -exportFig('transmissibility_ol_cl', 'half-normal', struct('path', 'identification')); +%% Transfer function from ground displacement to measured displacement +figure; +hold on; +plot(freqs, abs(squeeze(freqresp(Gd_ol_1_vc('Dz', 'Dgz'), freqs, 'Hz'))), 'DisplayName', 'VC - Light'); +plot(freqs, abs(squeeze(freqresp(Gd_ol_1_pz('Dz', 'Dgz'), freqs, 'Hz'))), 'DisplayName', 'PZ - Light'); +set(gca,'ColorOrderIndex',1); +plot(freqs, abs(squeeze(freqresp(Gd_ol_50_vc('Dz', 'Dgz'), freqs, 'Hz'))), '--', 'DisplayName', 'VC - Heavy'); +plot(freqs, abs(squeeze(freqresp(Gd_ol_50_pz('Dz', 'Dgz'), freqs, 'Hz'))), '--', 'DisplayName', 'PZ - Heavy'); +set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); +ylabel('Amplitude [m/m]'); +hold off; +legend('Location', 'southwest'); + +if save_fig; exportFig('comp_models_xw_to_d', 'normal-normal', struct('path', 'identification')); end + +%% Transfer function from direct force to measured displacement +figure; +hold on; +plot(freqs, abs(squeeze(freqresp(Gd_ol_1_vc('Dz', 'Fsz'), freqs, 'Hz'))), 'DisplayName', 'VC - Light'); +plot(freqs, abs(squeeze(freqresp(Gd_ol_1_pz('Dz', 'Fsz'), freqs, 'Hz'))), 'DisplayName', 'PZ - Light'); +set(gca,'ColorOrderIndex',1); +plot(freqs, abs(squeeze(freqresp(Gd_ol_50_vc('Dz', 'Fsz'), freqs, 'Hz'))), '--', 'DisplayName', 'VC - Heavy'); +plot(freqs, abs(squeeze(freqresp(Gd_ol_50_pz('Dz', 'Fsz'), freqs, 'Hz'))), '--', 'DisplayName', 'PZ - Heavy'); +set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); +ylabel('Amplitude [m/N]'); +hold off; +legend('Location', 'southwest'); + +if save_fig; exportFig('comp_models_fi_to_d', 'normal-normal', struct('path', 'identification')); end diff --git a/identification/id_main.m b/identification/id_main.m index c401d9b..1525bc1 100644 --- a/identification/id_main.m +++ b/identification/id_main.m @@ -8,7 +8,7 @@ run id_G.m % Plot de obtained transfer functions run id_G_plots.m -%% Identification of transfer function from ground motion to displacement +%% Identification of transfer function from disturbances to displacement % Compute the transfer function of Gd run id_Gd.m @@ -22,16 +22,12 @@ run id_micro_station.m % Plot de obtained transfer functions run id_micro_station_plots.m +% Compare the measurements of Marc with the model +run id_micro_station_comp_meas.m + %% Identification of all the stages % Compute the transfer functions of each stage from act. to sens. run id_stages.m % Plot de obtained transfer functions run id_stages_plots.m - -%% Identification of the nass -% Compute the transfer functions -run id_nass.m - -% Plot de obtained transfer functions -run id_nass.m diff --git a/identification/id_micro_station.m b/identification/id_micro_station.m index 2304218..8a3d86d 100644 --- a/identification/id_micro_station.m +++ b/identification/id_micro_station.m @@ -11,48 +11,21 @@ options = linearizeOptions; options.SampleTime = 0; %% Name of the Simulink File -mdl = 'Micro_Station_Identification'; +mdl = 'sim_micro_station'; %% Micro-Hexapod % Input/Output definition -io(1) = linio([mdl, '/Micro-Station/Fm'],1,'input'); -io(2) = linio([mdl, '/Micro-Station/Micro_Hexapod_Inertial_Sensor'],1,'output'); +io(1) = linio([mdl, '/Micro-Station/Fm_ext'],1,'openinput'); +io(2) = linio([mdl, '/Micro-Station/Fg_ext'],1,'openinput'); +io(3) = linio([mdl, '/Micro-Station/Dm_inertial'],1,'output'); +io(4) = linio([mdl, '/Micro-Station/Dg_inertial'],1,'output'); % Run the linearization -G_h_h_raw = linearize(mdl,io, 0); -G_h_h_raw = G_h_h_raw(1:3, 1:3); -G_h_h = preprocessIdTf(G_h_h_raw, 10, 10000); +G_ms = linearize(mdl, io, 0); % Input/Output names -G_h_h.InputName = {'Fux', 'Fuy', 'Fuz'}; -G_h_h.OutputName = {'Dux', 'Duy', 'Duz'}; - -%% Granite -% Input/Output definition -io(1) = linio([mdl, '/Micro-Station/F_granite'],1,'input'); -io(2) = linio([mdl, '/Micro-Station/Granite_Inertial_Sensor'],1,'output'); - -% Run the linearization -G_g_g_raw = linearize(mdl,io, 0); -G_g_g = preprocessIdTf(G_g_g_raw, 10, 10000); - -% Input/Output names -G_g_g.InputName = {'Fgx', 'Fgy', 'Fgz'}; -G_g_g.OutputName = {'Dgx', 'Dgy', 'Dgz'}; - -%% Micro Hexapod to Granite -% Input/Output definition -io(1) = linio([mdl, '/Micro-Station/Fm'],1,'input'); -io(2) = linio([mdl, '/Micro-Station/Granite_Inertial_Sensor'],1,'output'); - -% Run the linearization -G_h_g_raw = linearize(mdl,io, 0); -G_h_g_raw = G_h_g_raw(1:3, 1:3); -G_h_g = preprocessIdTf(G_h_g_raw, 10, 10000); - -% Input/Output names -G_h_g.InputName = {'Fhx', 'Fhy', 'Fhz'}; -G_h_g.OutputName = {'Dgx', 'Dgy', 'Dgz'}; +G_ms.InputName = {'Fmx', 'Fmy', 'Fmz', 'Fgx', 'Fgy', 'Fgz'}; +G_ms.OutputName = {'Dmx', 'Dmy', 'Dmz', 'Dgx', 'Dgy', 'Dgz'}; %% Save the obtained transfer functions -save('./mat/id_micro_station.mat', 'G_h_h', 'G_g_g', 'G_h_g'); +save('./mat/id_micro_station.mat', 'G_ms'); diff --git a/identification/id_micro_station_comp_meas.m b/identification/id_micro_station_comp_meas.m new file mode 100644 index 0000000..4d60ada --- /dev/null +++ b/identification/id_micro_station_comp_meas.m @@ -0,0 +1,100 @@ +%% Script Description +% Compare identification from the Simscape model +% with the identification on the real system. + +%% +clear; close all; clc; + +%% Load the obtained transfer functions +load('./mat/id_micro_station.mat', 'G_ms'); + +%% Load Configuration file +load('./mat/config.mat', 'save_fig', 'freqs'); + +%% Get Measurement Object +load('2018_01_12.mat', 'm_object'); + +%% Get Measurements Data +opts = struct('freq_min', 10, 'est_backend', 'idfrd'); +meas_sys = getDynamicTFs(m_object, 'marble', 'hexa', {'tx', 'tx'}, opts); + +%% Granite to Granite +figure; +% Amplitude +ax1 = subaxis(2,1,1); +hold on; +plot(freqs, abs(squeeze(freqresp(G_ms('Dgz', 'Fgz'), freqs, 'Hz')))); +plot(freqs, abs(squeeze(freqresp(meas_sys('Dmx', 'Fmx'), freqs, 'Hz'))), '.'); +set(gca,'xscale','log'); set(gca,'yscale','log'); +ylabel('Amplitude [m/N]'); +set(gca, 'XTickLabel',[]); +legend({'Model', 'Meas.'}); +hold off; +% Phase +ax2 = subaxis(2,1,2); +hold on; +plot(freqs, 180/pi*angle(squeeze(freqresp(G_ms('Dgz', 'Fgz'), freqs, 'Hz')))); +plot(freqs, 180/pi*angle(squeeze(freqresp(meas_sys('Dmx', 'Fmx'), freqs, 'Hz'))), '.'); +set(gca,'xscale','log'); +ylim([-180, 180]); +yticks([-180, -90, 0, 90, 180]); +xlabel('Frequency [Hz]'); ylabel('Phase [deg]'); +hold off; + +linkaxes([ax1,ax2],'x'); + +if save_fig; exportFig('comp_meas_g_g', 'normal-normal', struct('path', 'identification')); end + +%% Hexapod to Hexapod +figure; +% Amplitude +ax1 = subaxis(2,1,1); +hold on; +plot(freqs, abs(squeeze(freqresp(G_ms('Dmz', 'Fmz'), freqs, 'Hz')))); +plot(freqs, abs(squeeze(freqresp(meas_sys('Dhx', 'Fhx'), freqs, 'Hz'))), '.'); +set(gca,'xscale','log'); set(gca,'yscale','log'); +ylabel('Amplitude [m/N]'); +set(gca, 'XTickLabel',[]); +legend({'Model', 'Meas.'}); +hold off; +% Phase +ax2 = subaxis(2,1,2); +hold on; +plot(freqs, 180/pi*angle(squeeze(freqresp(G_ms('Dmz', 'Fmz'), freqs, 'Hz')))); +plot(freqs, 180/pi*angle(squeeze(freqresp(meas_sys('Dhx', 'Fhx'), freqs, 'Hz'))), '.'); +set(gca,'xscale','log'); +ylim([-180, 180]); +yticks([-180, -90, 0, 90, 180]); +xlabel('Frequency [Hz]'); ylabel('Phase [deg]'); +hold off; + +linkaxes([ax1,ax2],'x'); + +if save_fig; exportFig('comp_meas_m_m', 'normal-normal', struct('path', 'identification')); end + +%% Hexapod to Granite +figure; +% Amplitude +ax1 = subaxis(2,1,1); +hold on; +plot(freqs, abs(squeeze(freqresp(G_ms('Dmz', 'Fgz'), freqs, 'Hz')))); +plot(freqs, abs(squeeze(freqresp(meas_sys('Dhx', 'Fmx'), freqs, 'Hz'))), '.'); +set(gca,'xscale','log'); set(gca,'yscale','log'); +ylabel('Amplitude [m/N]'); +set(gca, 'XTickLabel',[]); +legend({'Model', 'Meas.'}); +hold off; +% Phase +ax2 = subaxis(2,1,2); +hold on; +plot(freqs, 180/pi*angle(squeeze(freqresp(G_ms('Dmz', 'Fgz'), freqs, 'Hz')))); +plot(freqs, 180/pi*angle(squeeze(freqresp(meas_sys('Dhx', 'Fmx'), freqs, 'Hz'))), '.'); +set(gca,'xscale','log'); +ylim([-180, 180]); +yticks([-180, -90, 0, 90, 180]); +xlabel('Frequency [Hz]'); ylabel('Phase [deg]'); +hold off; + +linkaxes([ax1,ax2],'x'); + +if save_fig; exportFig('comp_meas_m_g', 'normal-normal', struct('path', 'identification')); end diff --git a/identification/id_micro_station_plots.m b/identification/id_micro_station_plots.m index 47f287c..23d16d4 100644 --- a/identification/id_micro_station_plots.m +++ b/identification/id_micro_station_plots.m @@ -2,28 +2,28 @@ clear; close all; clc; %% Load the obtained transfer functions -load('./mat/id_micro_station.mat', 'G_h_h', 'G_g_g', 'G_h_g'); +load('./mat/id_micro_station.mat', 'G_ms'); + +%% Load Configuration file +load('./mat/config.mat', 'save_fig', 'freqs'); %% Micro-Hexapod - -bodeFig({G_h_h(1, 1), G_h_h(2, 2), G_h_h(3, 3)}) -legend({'$F_{h_x} \rightarrow D_{h_x}$', '$F_{h_y} \rightarrow D_{h_y}$', '$F_{h_z} \rightarrow D_{h_z}$'}) +bodeFig({G_ms('Dmx', 'Fmx'), G_ms('Dmy', 'Fmy'), G_ms('Dmz', 'Fmz')}, freqs) +legend({'$F_{hx} \to D_{hx}$', '$F_{hy} \to D_{hy}$', '$F_{hz} \to D_{hz}$'}) legend('location', 'southwest') -exportFig('id_marc_h_to_h', 'normal-normal', struct('path', 'identification')) + +if save_fig; exportFig('id_marc_m_m', 'normal-normal', struct('path', 'identification')); end %% Granite - -% Bode Plot of the linearized function -bodeFig({G_g_g(1, 1), G_g_g(2, 2), G_g_g(3, 3)}) -legend({'$F_{g_x} \rightarrow D_{g_x}$', '$F_{g_y} \rightarrow D_{g_y}$', '$F_{g_z} \rightarrow D_{g_z}$'}) +bodeFig({G_ms('Dgx', 'Fgx'), G_ms('Dgy', 'Fgy'), G_ms('Dgz', 'Fgz')}, freqs) +legend({'$F_{gx} \to D_{gx}$', '$F_{gy} \to D_{gy}$', '$F_{gz} \to D_{gz}$'}) legend('location', 'southwest') -exportFig('id_marc_g_to_g', 'normal-normal', struct('path', 'identification')) + +if save_fig; exportFig('id_marc_g_g', 'normal-normal', struct('path', 'identification')); end %% Micro Hexapod to Granite - -% Bode Plot of the linearized function -bodeFig({G_h_g(1, 1), G_h_g(2, 2), G_h_g(3, 3)}) -legend({'$F_{h_x} \rightarrow D_{g_x}$', '$F_{h_y} \rightarrow D_{g_y}$', '$F_{h_z} \rightarrow D_{g_z}$'}) +bodeFig({G_ms('Dmx', 'Fgx'), G_ms('Dmy', 'Fgy'), G_ms('Dmz', 'Fgz')}, freqs) +legend({'$F_{hx} \to D_{gx}$', '$F_{hy} \to D_{gy}$', '$F_{hz} \to D_{gz}$'}) legend('location', 'southwest') -exportFig('id_marc_h_to_g', 'normal-normal', struct('path', 'identification')) +if save_fig; exportFig('id_marc_m_g', 'normal-normal', struct('path', 'identification')); end diff --git a/identification/id_nass.m b/identification/id_nass.m deleted file mode 100644 index ac4bb19..0000000 --- a/identification/id_nass.m +++ /dev/null @@ -1,24 +0,0 @@ -%% Script Description -% Identification of the NASS from cartesian actuation -% to cartesian displacement. - -%% -clear; close all; clc; - -%% -initializeSample(struct('mass', 1)); - -G_nass_1 = identifyNass(); - -%% -initializeSample(struct('mass', 20)); - -G_nass_20 = identifyNass(); - -%% -initializeSample(struct('mass', 50)); - -G_nass_50 = identifyNass(); - -%% Save Transfer Functions -save('./mat/G_nass.mat', 'G_nass_1', 'G_nass_20', 'G_nass_50'); diff --git a/identification/id_nass_plots.m b/identification/id_nass_plots.m deleted file mode 100644 index d3d3404..0000000 --- a/identification/id_nass_plots.m +++ /dev/null @@ -1,36 +0,0 @@ -%% -clear; close all; clc; - -%% Load Transfer Functions -load('./mat/G_nass.mat', 'G_nass_1', 'G_nass_20', 'G_nass_50'); - -%% -freqs = logspace(1, 4, 1000); - -bodeFig({G_nass_1(1, 1), G_nass_1(2, 2), G_nass_1(3, 3)}, struct('phase', true)) -legend({'$F_{n_x} \rightarrow D_{n_x}$ - $M = 1Kg$', ... - '$F_{n_y} \rightarrow D_{n_y}$ - $M = 1Kg$', ... - '$F_{n_z} \rightarrow D_{n_z}$ - $M = 1Kg$'}) -legend('location', 'southwest') -exportFig('nass_cart_xyz', 'normal-normal', struct('path', 'identification')) - -bodeFig({G_nass_1(1, 1), G_nass_20(1, 1), G_nass_50(1, 1)}, struct('phase', true)) -legend({'$F_{n_x} \rightarrow D_{n_x}$ - $M = 1Kg$', ... - '$F_{n_x} \rightarrow D_{n_x}$ - $M = 20Kg$', ... - '$F_{n_x} \rightarrow D_{n_x}$ - $M = 50Kg$'}) -legend('location', 'southwest') -exportFig('nass_cart_x_mass', 'normal-normal', struct('path', 'identification')) - -bodeFig({G_nass_1(2, 2), G_nass_20(2, 2), G_nass_50(2, 2)}, struct('phase', true)) -legend({'$F_{n_x} \rightarrow D_{n_x}$ - $M = 1Kg$', ... - '$F_{n_x} \rightarrow D_{n_x}$ - $M = 20Kg$', ... - '$F_{n_x} \rightarrow D_{n_x}$ - $M = 50Kg$'}) -legend('location', 'southwest') -exportFig('nass_cart_y_mass', 'normal-normal', struct('path', 'identification')) - -bodeFig({G_nass_1(3, 3), G_nass_20(3, 3), G_nass_50(3, 3)}, struct('phase', true)) -legend({'$F_{n_z} \rightarrow D_{n_z}$ - $M = 1Kg$', ... - '$F_{n_z} \rightarrow D_{n_z}$ - $M = 20Kg$', ... - '$F_{n_z} \rightarrow D_{n_z}$ - $M = 50Kg$'}) -legend('location', 'southwest') -exportFig('nass_cart_z_mass', 'normal-normal', struct('path', 'identification')) diff --git a/identification/id_stages.m b/identification/id_stages.m index 700ef92..b96b043 100644 --- a/identification/id_stages.m +++ b/identification/id_stages.m @@ -8,27 +8,20 @@ clear; close all; clc; %% initializeSample(struct('mass', 20)); -%% Options for preprocessing the identified transfer functions -f_low = 10; % [Hz] -f_high = 10000; % [Hz] - %% Options for Linearized options = linearizeOptions; options.SampleTime = 0; %% Name of the Simulink File -mdl = 'Micro_Station_Identification'; +mdl = 'sim_nano_station'; %% Y-Translation Stage % Input/Output definition -io(1) = linio([mdl, '/Micro-Station/Fy'], 1,'input'); +io(1) = linio([mdl, '/Micro-Station/Fy'], 1,'openinput'); io(2) = linio([mdl, '/Micro-Station/Translation y'],1,'output'); % Run the linearization -G_ty_raw = linearize(mdl,io, 0); - -% Post-process the linearized function -G_ty = preprocessIdTf(G_ty_raw, f_low, f_high); +G_ty = linearize(mdl,io, 0); % Input/Output names G_ty.InputName = {'Fy'}; @@ -36,14 +29,11 @@ G_ty.OutputName = {'Dy'}; %% Tilt Stage % Input/Output definition -io(1) = linio([mdl, '/Micro-Station/Ry'], 1,'input'); +io(1) = linio([mdl, '/Micro-Station/Ry'], 1,'openinput'); io(2) = linio([mdl, '/Micro-Station/Tilt'],1,'output'); % Run the linearization -G_ry_raw = linearize(mdl,io, 0); - -% Post-process the linearized function -G_ry = preprocessIdTf(G_ry_raw, f_low, f_high); +G_ry = linearize(mdl,io, 0); % Input/Output names G_ry.InputName = {'My'}; @@ -51,14 +41,11 @@ G_ry.OutputName = {'Ry'}; %% Spindle % Input/Output definition -io(1) = linio([mdl, '/Micro-Station/Rz'], 1,'input'); +io(1) = linio([mdl, '/Micro-Station/Rz'], 1,'openinput'); io(2) = linio([mdl, '/Micro-Station/Spindle'],1,'output'); % Run the linearization -G_rz_raw = linearize(mdl,io, 0); - -% Post-process the linearized function -G_rz = preprocessIdTf(G_rz_raw, f_low, f_high); +G_rz = linearize(mdl,io, 0); % Input/Output names G_rz.InputName = {'Mz'}; @@ -66,14 +53,11 @@ G_rz.OutputName = {'Rz'}; %% Hexapod Symetrie % Input/Output definition -io(1) = linio([mdl, '/Micro-Station/Fm'], 1,'input'); +io(1) = linio([mdl, '/Micro-Station/Fm'], 1,'openinput'); io(2) = linio([mdl, '/Micro-Station/Micro_Hexapod'],1,'output'); % Run the linearization -G_hexa_raw = linearize(mdl,io, 0); - -% Post-process the linearized function -G_hexa = preprocessIdTf(G_hexa_raw, f_low, f_high); +G_hexa = linearize(mdl,io, 0); % Input/Output names G_hexa.InputName = {'Fhexa_x', 'Fhexa_y', 'Fhexa_z', 'Mhexa_x', 'Mhexa_y', 'Mhexa_z'}; @@ -81,14 +65,11 @@ G_hexa.OutputName = {'Dhexa_x', 'Dhexa_y', 'Dhexa_z', 'Rhexa_x', 'Rhexa_y', 'Rhe %% NASS % Input/Output definition -io(1) = linio([mdl, '/Micro-Station/Fn'], 1,'input'); +io(1) = linio([mdl, '/Micro-Station/Fn'], 1,'openinput'); io(2) = linio([mdl, '/Micro-Station/Nano_Hexapod'],1,'output'); % Run the linearization -G_nass_raw = linearize(mdl,io, 0); - -% Post-process the linearized function -G_nass = preprocessIdTf(G_nass_raw, f_low, f_high); +G_nass = linearize(mdl,io, 0); % Input/Output names G_nass.InputName = {'Fnass_x', 'Fnass_y', 'Fnass_z', 'Mnass_x', 'Mnass_y', 'Mnass_z'}; diff --git a/identification/id_stages_plots.m b/identification/id_stages_plots.m index ffabf71..6389bf3 100644 --- a/identification/id_stages_plots.m +++ b/identification/id_stages_plots.m @@ -10,41 +10,41 @@ load('./mat/identified_tf.mat', 'G_ty', 'G_ry', 'G_rz', 'G_hexa', 'G_nass'); %% Y-Translation Stage bodeFig({G_ty}, struct('phase', true)) -legend({'$F_{y} \rightarrow D_{y}$'}) +legend({'$F_{y} \to D_{y}$'}) exportFig('id_ty', 'normal-normal', struct('path', 'identification')) %% Tilt Stage bodeFig({G_ry}, struct('phase', true)) -legend({'$M_{y} \rightarrow R_{y}$'}) +legend({'$M_{y} \to R_{y}$'}) exportFig('id_ry', 'normal-normal', struct('path', 'identification')) %% Spindle bodeFig({G_rz}, struct('phase', true)) -legend({'$M_{z} \rightarrow R_{z}$'}) +legend({'$M_{z} \to R_{z}$'}) exportFig('id_ry', 'normal-normal', struct('path', 'identification')) %% Hexapod Symetrie bodeFig({G_hexa(1, 1), G_hexa(2, 2), G_hexa(3, 3)}, struct('phase', true)) -legend({'$F_{h_x} \rightarrow D_{h_x}$', '$F_{h_y} \rightarrow D_{h_y}$', '$F_{h_z} \rightarrow D_{h_z}$'}) +legend({'$F_{h_x} \to D_{h_x}$', '$F_{h_y} \to D_{h_y}$', '$F_{h_z} \to D_{h_z}$'}) exportFig('id_hexapod_trans', 'normal-normal', struct('path', 'identification')) bodeFig({G_hexa(4, 4), G_hexa(5, 5), G_hexa(6, 6)}, struct('phase', true)) -legend({'$M_{h_x} \rightarrow R_{h_x}$', '$M_{h_y} \rightarrow R_{h_y}$', '$M_{h_z} \rightarrow R_{h_z}$'}) +legend({'$M_{h_x} \to R_{h_x}$', '$M_{h_y} \to R_{h_y}$', '$M_{h_z} \to R_{h_z}$'}) exportFig('id_hexapod_rot', 'normal-normal', struct('path', 'identification')) bodeFig({G_hexa(1, 1), G_hexa(2, 1), G_hexa(3, 1)}, struct('phase', true)) -legend({'$F_{h_x} \rightarrow D_{h_x}$', '$F_{h_x} \rightarrow D_{h_y}$', '$F_{h_x} \rightarrow D_{h_z}$'}) +legend({'$F_{h_x} \to D_{h_x}$', '$F_{h_x} \to D_{h_y}$', '$F_{h_x} \to D_{h_z}$'}) exportFig('id_hexapod_coupling', 'normal-normal', struct('path', 'identification')) %% NASS bodeFig({G_nass(1, 1), G_nass(2, 2), G_nass(3, 3)}, struct('phase', true)) -legend({'$F_{n_x} \rightarrow D_{n_x}$', '$F_{n_y} \rightarrow D_{n_y}$', '$F_{n_z} \rightarrow D_{n_z}$'}) +legend({'$F_{n_x} \to D_{n_x}$', '$F_{n_y} \to D_{n_y}$', '$F_{n_z} \to D_{n_z}$'}) exportFig('id_nass_trans', 'normal-normal', struct('path', 'identification')) bodeFig({G_nass(4, 4), G_nass(5, 5), G_nass(6, 6)}, struct('phase', true)) -legend({'$M_{n_x} \rightarrow R_{n_x}$', '$M_{n_y} \rightarrow R_{n_y}$', '$M_{n_z} \rightarrow R_{n_z}$'}) +legend({'$M_{n_x} \to R_{n_x}$', '$M_{n_y} \to R_{n_y}$', '$M_{n_z} \to R_{n_z}$'}) exportFig('id_nass_rot', 'normal-normal', struct('path', 'identification')) bodeFig({G_nass(1, 1), G_nass(2, 1), G_nass(3, 1)}, struct('phase', true)) -legend({'$F_{n_x} \rightarrow D_{n_x}$', '$F_{n_x} \rightarrow D_{n_y}$', '$F_{n_x} \rightarrow D_{n_z}$'}) +legend({'$F_{n_x} \to D_{n_x}$', '$F_{n_x} \to D_{n_y}$', '$F_{n_x} \to D_{n_z}$'}) exportFig('id_nass_coupling', 'normal-normal', struct('path', 'identification')) diff --git a/identification/sim_micro_station.slx b/identification/sim_micro_station.slx new file mode 100644 index 0000000..9577e75 Binary files /dev/null and b/identification/sim_micro_station.slx differ diff --git a/identification/sim_nano_station.slx b/identification/sim_nano_station.slx new file mode 100644 index 0000000..f2a100e Binary files /dev/null and b/identification/sim_nano_station.slx differ diff --git a/initialize/initializeNanoHexapod.m b/initialize/initializeNanoHexapod.m index 4b30953..2cfebae 100644 --- a/initialize/initializeNanoHexapod.m +++ b/initialize/initializeNanoHexapod.m @@ -43,9 +43,11 @@ function [nano_hexapod] = initializeNanoHexapod(opts_param) Leg.stroke = 80e-6; % Maximum Stroke of each leg [m] if strcmp(opts.actuator, 'piezo') - Leg.k.ax = 5e7; % Stiffness of each leg [N/m] + Leg.k.ax = 1e7; % Stiffness of each leg [N/m] + elseif strcmp(opts.actuator, 'lorentz') + Leg.k.ax = 1e4; % Stiffness of each leg [N/m] else - Leg.k.ax = 1e5; % Stiffness of each leg [N/m] + error('opts.actuator should be piezo or lorentz'); end Leg.ksi.ax = 10; % Maximum amplification at resonance [] Leg.rad.bottom = 12; % Radius of the cylinder of the bottom part [mm] diff --git a/main.m b/main.m index 9d00f84..7e3fbea 100644 --- a/main.m +++ b/main.m @@ -4,6 +4,9 @@ clear; close all; clc; %% Open the project simulinkproject('./'); +%% General Configuration +run config.m + %% Initialization % Initialize the perturbations run init_perturbations.m diff --git a/src/identifyG.m b/src/identifyG.m index 3687a0a..8e82b9f 100644 --- a/src/identifyG.m +++ b/src/identifyG.m @@ -1,8 +1,6 @@ function [G, G_raw] = identifyG(opts_param) %% Default values for opts - opts = struct('f_low', 0.1, ... - 'f_high', 10000 ... - ); + opts = struct(); %% Populate opts with input parameters if exist('opts_param','var') @@ -16,19 +14,15 @@ function [G, G_raw] = identifyG(opts_param) options.SampleTime = 0; %% Name of the Simulink File - mdl = 'Micro_Station_Identification'; + mdl = 'sim_nano_station'; %% Centralized control (Cartesian coordinates) % Input/Output definition - io(1) = linio([mdl, '/Micro-Station/Fn'], 1,'input'); + io(1) = linio([mdl, '/Micro-Station/Fn'], 1,'openinput'); io(2) = linio([mdl, '/Micro-Station/Sample'],1,'output'); % Run the linearization - G_raw = linearize(mdl,io, 0); - G_raw.InputName = {'Fnx', 'Fny', 'Fnz', 'Mnx', 'Mny', 'Mnz'}; - G_raw.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'}; - - G = preprocessIdTf(G_raw, opts.f_low, opts.f_high); + G = linearize(mdl,io, 0); G.InputName = {'Fnx', 'Fny', 'Fnz', 'Mnx', 'Mny', 'Mnz'}; G.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'}; end diff --git a/src/identifyGd.m b/src/identifyGd.m index 0745d6a..a7f5506 100644 --- a/src/identifyGd.m +++ b/src/identifyGd.m @@ -1,9 +1,6 @@ function [Gd, Gd_raw] = identifyGd(opts_param) %% Default values for opts - opts = struct('cl', true, ... % CL or OL - 'f_low', 0.1, ... - 'f_high', 10000 ... - ); + opts = struct('cl', true); %% Populate opts with input parameters if exist('opts_param','var') @@ -18,22 +15,21 @@ function [Gd, Gd_raw] = identifyGd(opts_param) %% Name of the Simulink File if opts.cl + % Make sure that the loop is closed + initializeSimConf(struct('cl_time', 0)); mdl = 'Assemblage'; else - mdl = 'Micro_Station_Identification'; + mdl = 'sim_nano_station'; end %% Centralized control (Cartesian coordinates) % Input/Output definition - io(1) = linio([mdl, '/Micro-Station/Gm'], 1,'input'); - io(2) = linio([mdl, '/Micro-Station/Sample'],1,'output'); + io(1) = linio([mdl, '/Micro-Station/Gm'], 1,'openinput'); + io(2) = linio([mdl, '/Micro-Station/Fs_ext'], 1,'openinput'); + io(3) = linio([mdl, '/Micro-Station/Sample'], 1,'output'); % Run the linearization - Gd_raw = linearize(mdl,io, 0); - Gd_raw.InputName = {'Dgx', 'Dgy', 'Dgz'}; - Gd_raw.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'}; - - Gd = preprocessIdTf(Gd_raw, opts.f_low, opts.f_high); - Gd.InputName = {'Dgx', 'Dgy', 'Dgz'}; + Gd = linearize(mdl,io, 0); + Gd.InputName = {'Dgx', 'Dgy', 'Dgz', 'Fsx', 'Fsy', 'Fsz'}; Gd.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'}; end diff --git a/src/identifyNass.m b/src/identifyNass.m index 0645f66..7fbdb9f 100644 --- a/src/identifyNass.m +++ b/src/identifyNass.m @@ -1,8 +1,6 @@ function [G_cart, G_cart_raw] = identifyNass(opts_param) %% Default values for opts - opts = struct('f_low', 1,... - 'f_high', 10000 ... - ); + opts = struct(); %% Populate opts with input parameters if exist('opts_param','var') @@ -16,17 +14,15 @@ function [G_cart, G_cart_raw] = identifyNass(opts_param) options.SampleTime = 0; %% Name of the Simulink File - mdl = 'Micro_Station_Identification'; + mdl = 'sim_nano_station'; %% Centralized control (Cartesian coordinates) % Input/Output definition - io(1) = linio([mdl, '/Micro-Station/Fn'], 1,'input'); - io(2) = linio([mdl, '/Micro-Station/Nano_Hexapod'],1,'output'); + io(1) = linio([mdl, '/Micro-Station/Fn'], 1, 'openinput'); + io(2) = linio([mdl, '/Micro-Station/Nano_Hexapod'], 1, 'output'); % Run the linearization - G_cart_raw = linearize(mdl,io, 0); - - G_cart = preprocessIdTf(G_cart_raw, opts.f_low, opts.f_high); + G_cart = linearize(mdl,io, 0); % Input/Output names G_cart.InputName = {'Fnx', 'Fny', 'Fnz', 'Mnx', 'Mny', 'Mnz'}; diff --git a/src/preprocessIdTf.m b/src/preprocessIdTf.m deleted file mode 100644 index 779b5a0..0000000 --- a/src/preprocessIdTf.m +++ /dev/null @@ -1,5 +0,0 @@ -function [G] = preprocessIdTf(G0, f_low, f_high) - [~,G1] = freqsep(G0, 2*pi*f_low); - [G2,~] = freqsep(G1, 2*pi*f_high); - G = minreal(G2); -end