diff --git a/A1-nass-uniaxial-model/mat/uniaxial_disturbance_psd.mat b/A1-nass-uniaxial-model/mat/uniaxial_disturbance_psd.mat index b72cd90..06e050a 100644 --- a/A1-nass-uniaxial-model/mat/uniaxial_disturbance_psd.mat +++ b/A1-nass-uniaxial-model/mat/uniaxial_disturbance_psd.mat @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:38f0fa7063da05cd7119ae10b0cea958155cfaa9483d77e3e1a24f6271f8f778 -size 18684 +oid sha256:79ee73b3355ee98859f9a43b341c1faed1b6d2c6bc2414fc4c84ac07f9ee29fb +size 16997 diff --git a/A1-nass-uniaxial-model/uniaxial_3_disturbances.m b/A1-nass-uniaxial-model/uniaxial_3_disturbances.m index 8b29b99..69285a8 100644 --- a/A1-nass-uniaxial-model/uniaxial_3_disturbances.m +++ b/A1-nass-uniaxial-model/uniaxial_3_disturbances.m @@ -65,11 +65,12 @@ load('meas_spindle_on.mat', 't', 'vg', 'vh'); spindle_off = load('meas_spindle_off.mat', 't', 'vg', 'vh'); % No Rotation % Compute Power Spectral Density of the relative velocity between granite and hexapod during spindle rotation -Fs = 1/(t(2)-t(1)); % Sampling Frequency [Hz] -win = hanning(ceil(2*Fs)); % Hanning window +Ts = t(2)-t(1); % Sampling Time [s] +Nfft = floor(2/Ts); +win = hanning(Nfft); -[psd_vft, f] = pwelch(vh-vg, win, [], [], Fs); % [(m/s)^2/Hz] -[psd_off, ~] = pwelch(spindle_off.vh-spindle_off.vg, win, [], [], Fs); % [(m/s)^2/Hz] +[psd_vft, f] = pwelch(vh-vg, win, Noverlap, Nfft, 1/Ts); % [(m/s)^2/Hz] +[psd_off, ~] = pwelch(spindle_off.vh-spindle_off.vg, win, Noverlap, Nfft, 1/Ts); % [(m/s)^2/Hz] % Disable the Nano-Hexpod for now model_config = struct(); diff --git a/A1-nass-uniaxial-model/uniaxial_4_dynamic_noise_budget.m b/A1-nass-uniaxial-model/uniaxial_4_dynamic_noise_budget.m index 1eb9287..3baf19f 100644 --- a/A1-nass-uniaxial-model/uniaxial_4_dynamic_noise_budget.m +++ b/A1-nass-uniaxial-model/uniaxial_4_dynamic_noise_budget.m @@ -56,7 +56,7 @@ set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Amplitude $d/x_{f}$ [m/m]'); xlabel('Frequency [Hz]'); xticks([1e0, 1e1, 1e2]); leg = legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 1); -leg.ItemTokenSize(1) = 15 +leg.ItemTokenSize(1) = 15; xlim([1, 500]); %% Cumulative Amplitude Spectrum of the relative motion d, due to both the floor motion and the stage vibrations @@ -72,7 +72,7 @@ hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('CAS [m]'); xlabel('Frequency [Hz]'); leg = legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 2); -leg.ItemTokenSize(1) = 15 +leg.ItemTokenSize(1) = 15; xlim([1, 500]); ylim([1e-12, 3e-6]) @@ -104,7 +104,7 @@ hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('CAS [m]'); xlabel('Frequency [Hz]'); leg = legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 1); -leg.ItemTokenSize(1) = 15 +leg.ItemTokenSize(1) = 15; xlim([1, 500]); ylim([1e-12, 3e-6]) diff --git a/A1-nass-uniaxial-model/uniaxial_5_active_damping.m b/A1-nass-uniaxial-model/uniaxial_5_active_damping.m index 3f58d84..df6a950 100644 --- a/A1-nass-uniaxial-model/uniaxial_5_active_damping.m +++ b/A1-nass-uniaxial-model/uniaxial_5_active_damping.m @@ -221,19 +221,25 @@ G_dvf_pz_heavy = feedback(G_pz_heavy, K_dvf_pz, 'name', +1); %% Verify Stability % IFF -isstable(G_iff_vc_light) && isstable(G_iff_vc_mid) && isstable(G_iff_vc_heavy) && ... -isstable(G_iff_md_light) && isstable(G_iff_md_mid) && isstable(G_iff_md_heavy) && ... -isstable(G_iff_pz_light) && isstable(G_iff_pz_mid) && isstable(G_iff_pz_heavy) +if not(isstable(G_iff_vc_light) && isstable(G_iff_vc_mid) && isstable(G_iff_vc_heavy) && ... + isstable(G_iff_md_light) && isstable(G_iff_md_mid) && isstable(G_iff_md_heavy) && ... + isstable(G_iff_pz_light) && isstable(G_iff_pz_mid) && isstable(G_iff_pz_heavy)) + warning("One of the damped plant with decentralized IFF is not stable."); +end % RDC -isstable(G_rdc_vc_light) && isstable(G_rdc_vc_mid) && isstable(G_rdc_vc_heavy) && ... -isstable(G_rdc_md_light) && isstable(G_rdc_md_mid) && isstable(G_rdc_md_heavy) && ... -isstable(G_rdc_pz_light) && isstable(G_rdc_pz_mid) && isstable(G_rdc_pz_heavy) +if not(isstable(G_rdc_vc_light) && isstable(G_rdc_vc_mid) && isstable(G_rdc_vc_heavy) && ... + isstable(G_rdc_md_light) && isstable(G_rdc_md_mid) && isstable(G_rdc_md_heavy) && ... + isstable(G_rdc_pz_light) && isstable(G_rdc_pz_mid) && isstable(G_rdc_pz_heavy)) + warning("One of the damped plant with decentralized RDC is not stable."); +end % DVF -isstable(G_dvf_vc_light) && isstable(G_dvf_vc_mid) && isstable(G_dvf_vc_heavy) && ... -isstable(G_dvf_md_light) && isstable(G_dvf_md_mid) && isstable(G_dvf_md_heavy) && ... -isstable(G_dvf_pz_light) && isstable(G_dvf_pz_mid) && isstable(G_dvf_pz_heavy) +if not(isstable(G_dvf_vc_light) && isstable(G_dvf_vc_mid) && isstable(G_dvf_vc_heavy) && ... + isstable(G_dvf_md_light) && isstable(G_dvf_md_mid) && isstable(G_dvf_md_heavy) && ... + isstable(G_dvf_pz_light) && isstable(G_dvf_pz_mid) && isstable(G_dvf_pz_heavy)) + warning("One of the damped plant with decentralized DVF is not stable."); +end %% Save Damped Plants save('./mat/uniaxial_damped_plants.mat', 'G_iff_vc_light', 'G_iff_md_light', 'G_iff_pz_light', ... diff --git a/A1-nass-uniaxial-model/uniaxial_6_hac_lac.m b/A1-nass-uniaxial-model/uniaxial_6_hac_lac.m index 5b19292..be4de37 100644 --- a/A1-nass-uniaxial-model/uniaxial_6_hac_lac.m +++ b/A1-nass-uniaxial-model/uniaxial_6_hac_lac.m @@ -258,7 +258,7 @@ hold off; set(gca, 'XScale', 'lin'); set(gca, 'YScale', 'lin'); xlabel('Real'); ylabel('Imag'); leg = legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 1); -leg.ItemTokenSize(1) = 15 +leg.ItemTokenSize(1) = 15; xlim([-3.8, 0.2]); ylim([-2, 2]); axis square; @@ -279,7 +279,7 @@ hold off; set(gca, 'XScale', 'lin'); set(gca, 'YScale', 'lin'); xlabel('Real'); ylabel('Imag'); leg = legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 1); -leg.ItemTokenSize(1) = 15 +leg.ItemTokenSize(1) = 15; xlim([-3.8, 0.2]); ylim([-2, 2]); axis square; @@ -300,7 +300,7 @@ hold off; set(gca, 'XScale', 'lin'); set(gca, 'YScale', 'lin'); xlabel('Real'); ylabel('Imag'); leg = legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 1); -leg.ItemTokenSize(1) = 15 +leg.ItemTokenSize(1) = 15; xlim([-3.8, 0.2]); ylim([-2, 2]); axis square; @@ -319,7 +319,7 @@ ylabel('Loop Gain'); set(gca, 'XTickLabel',[]); ylim([1e-3, 1e3]); yticks([1e-2, 1, 1e2]) leg = legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 1); -leg.ItemTokenSize(1) = 15 +leg.ItemTokenSize(1) = 15; ax2 = nexttile; hold on; @@ -413,11 +413,17 @@ G_hac_iff_pz_mid = feedback(G_iff_pz_mid , K_hac_pz, 'name', -1); G_hac_iff_pz_heavy = feedback(G_iff_pz_heavy, K_hac_pz, 'name', -1); %% Verify Stability -isstable(G_hac_iff_vc_light) && isstable(G_hac_iff_vc_mid) && isstable(G_hac_iff_vc_heavy) +if not(isstable(G_hac_iff_vc_light) && isstable(G_hac_iff_vc_mid) && isstable(G_hac_iff_vc_heavy)) + warning("One of the damped plant with VC and decentralized IFF is not stable."); +end -isstable(G_hac_iff_md_light) && isstable(G_hac_iff_md_mid) && isstable(G_hac_iff_md_heavy) +if not(isstable(G_hac_iff_md_light) && isstable(G_hac_iff_md_mid) && isstable(G_hac_iff_md_heavy)) + warning("One of the damped plant with MD and decentralized IFF is not stable."); +end -isstable(G_hac_iff_pz_light) && isstable(G_hac_iff_pz_mid) && isstable(G_hac_iff_pz_heavy) +if not(isstable(G_hac_iff_pz_light) && isstable(G_hac_iff_pz_mid) && isstable(G_hac_iff_pz_heavy)) + warning("One of the damped plant with PZ and decentralized IFF is not stable."); +end %% Change of sensitivity to disturbances with LAC and with HAC-LAC figure; diff --git a/A1-nass-uniaxial-model/uniaxial_8_payload_dynamics.m b/A1-nass-uniaxial-model/uniaxial_8_payload_dynamics.m index 9bc3708..8fd8bb5 100644 --- a/A1-nass-uniaxial-model/uniaxial_8_payload_dynamics.m +++ b/A1-nass-uniaxial-model/uniaxial_8_payload_dynamics.m @@ -324,18 +324,18 @@ G_iff_vc_light_rigid = feedback(G_vc_light_rigid, K_iff_vc, 'name', +1); G_iff_vc_light_soft = feedback(G_vc_light_soft , K_iff_vc, 'name', +1); G_iff_vc_light_stiff = feedback(G_vc_light_stiff, K_iff_vc, 'name', +1); -isstable(G_iff_vc_light_rigid) -isstable(G_iff_vc_light_soft) -isstable(G_iff_vc_light_stiff) +if not(isstable(G_iff_vc_light_rigid) && isstable(G_iff_vc_light_soft) &&isstable(G_iff_vc_light_stiff)) + warning("One of the damped plant with VC and decentralized IFF is not stable."); +end % Stiff Nano-Hexapod G_iff_pz_light_rigid = feedback(G_pz_light_rigid, K_iff_pz, 'name', +1); G_iff_pz_light_soft = feedback(G_pz_light_soft , K_iff_pz, 'name', +1); G_iff_pz_light_stiff = feedback(G_pz_light_stiff, K_iff_pz, 'name', +1); -isstable(G_iff_pz_light_rigid) -isstable(G_iff_pz_light_soft) -isstable(G_iff_pz_light_stiff) +if not(isstable(G_iff_pz_light_rigid) && isstable(G_iff_pz_light_soft) && isstable(G_iff_pz_light_stiff)) + warning("One of the damped plant with PZ and decentralized IFF is not stable."); +end %% Compute closed-loop plants and verify stability % Soft Nano-Hexapod @@ -343,18 +343,18 @@ G_hac_iff_vc_light_rigid = feedback(G_iff_vc_light_rigid, K_hac_vc, 'name', -1); G_hac_iff_vc_light_soft = feedback(G_iff_vc_light_soft , K_hac_vc, 'name', -1); G_hac_iff_vc_light_stiff = feedback(G_iff_vc_light_stiff, K_hac_vc, 'name', -1); -isstable(G_hac_iff_vc_light_rigid) -isstable(G_hac_iff_vc_light_soft) -isstable(G_hac_iff_vc_light_stiff) +if not(isstable(G_hac_iff_vc_light_rigid) && isstable(G_hac_iff_vc_light_soft) && isstable(G_hac_iff_vc_light_stiff)) + warning("One of the damped plant with VC and decentralized IFF is not stable."); +end % Stiff Nano-Hexapod G_hac_iff_pz_light_rigid = feedback(G_iff_pz_light_rigid, K_hac_pz, 'name', -1); G_hac_iff_pz_light_soft = feedback(G_iff_pz_light_soft , K_hac_pz, 'name', -1); G_hac_iff_pz_light_stiff = feedback(G_iff_pz_light_stiff, K_hac_pz, 'name', -1); -isstable(G_hac_iff_pz_light_rigid) -isstable(G_hac_iff_pz_light_soft) -isstable(G_hac_iff_pz_light_stiff) +if not(isstable(G_hac_iff_pz_light_rigid) && isstable(G_hac_iff_pz_light_soft) && isstable(G_hac_iff_pz_light_stiff)) + warning("One of the damped plant with PZ and decentralized IFF is not stable."); +end %% Cumulative Amplitude Spectrum of d - Effect of Sample's flexibility figure; diff --git a/A2-nass-rotating-3dof-model/mat/nass_controllers.mat b/A2-nass-rotating-3dof-model/mat/nass_controllers.mat index bc22d33..a990737 100644 --- a/A2-nass-rotating-3dof-model/mat/nass_controllers.mat +++ b/A2-nass-rotating-3dof-model/mat/nass_controllers.mat @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c7319b331bed58b9ccd3e9781dae8111d1709808669d0ac72629bfab8e437b1d -size 3216 +oid sha256:29be8e5fc97498bd02e875633e171021e71f66e714074eb4979d9c2d0e7fd9d1 +size 3189 diff --git a/A2-nass-rotating-3dof-model/rotating_7_nano_hexapod.m b/A2-nass-rotating-3dof-model/rotating_7_nano_hexapod.m index a406ac2..e9406cc 100644 --- a/A2-nass-rotating-3dof-model/rotating_7_nano_hexapod.m +++ b/A2-nass-rotating-3dof-model/rotating_7_nano_hexapod.m @@ -221,6 +221,19 @@ i_iff_hpf_md = i_iff_hpf_md(end)+1; i_iff_hpf_pz = find(opt_iff_hpf_xi_pz > 0.95*max(opt_iff_hpf_xi_pz)); i_iff_hpf_pz = i_iff_hpf_pz(end)+1; +%% Define the obtained controllers +Kiff_hpf_vc = Kiff*opt_iff_hpf_gain_vc(i_iff_hpf_vc); +Kiff_hpf_vc.InputName = {'fu', 'fv'}; +Kiff_hpf_vc.OutputName = {'Fu', 'Fv'}; + +Kiff_hpf_md = Kiff*opt_iff_hpf_gain_md(i_iff_hpf_md); +Kiff_hpf_md.InputName = {'fu', 'fv'}; +Kiff_hpf_md.OutputName = {'Fu', 'Fv'}; + +Kiff_hpf_pz = Kiff*opt_iff_hpf_gain_pz(i_iff_hpf_pz); +Kiff_hpf_pz.InputName = {'fu', 'fv'}; +Kiff_hpf_pz.OutputName = {'Fu', 'Fv'}; + %% Optimal modified IFF parameters that yields maximum simultaneous damping figure; yyaxis left @@ -303,9 +316,9 @@ mn = 15; % Nano-Hexapod mass [kg] ms = 1; % Sample Mass [kg] %% IFF Controller -Kiff_vc = 1/(s + 0.1*sqrt(1e4/(mn+ms)))*eye(2); % IFF -Kiff_md = 1/(s + 0.1*sqrt(1e6/(mn+ms)))*eye(2); % IFF -Kiff_pz = 1/(s + 0.1*sqrt(1e8/(mn+ms)))*eye(2); % IFF +Kiff_vc = 1/(s + 0.1*sqrt(1e4/(mn+ms)))*eye(2); % IFF - VC +Kiff_md = 1/(s + 0.1*sqrt(1e6/(mn+ms)))*eye(2); % IFF - MD +Kiff_pz = 1/(s + 0.1*sqrt(1e8/(mn+ms)))*eye(2); % IFF - PZ %% General Configuration model_config = struct(); @@ -392,6 +405,19 @@ for kp_i = 1:length(kps_pz) opt_iff_kp_gain_pz(kp_i) = g_opt; end +%% Define the obtained controllers +Kiff_kp_vc = Kiff_vc*opt_iff_kp_gain_vc(i_kp_vc); +Kiff_kp_vc.InputName = {'fu', 'fv'}; +Kiff_kp_vc.OutputName = {'Fu', 'Fv'}; + +Kiff_kp_md = Kiff_md*opt_iff_kp_gain_md(i_kp_md); +Kiff_kp_md.InputName = {'fu', 'fv'}; +Kiff_kp_md.OutputName = {'Fu', 'Fv'}; + +Kiff_kp_pz = Kiff_pz*opt_iff_kp_gain_pz(i_kp_pz); +Kiff_kp_pz.InputName = {'fu', 'fv'}; +Kiff_kp_pz.OutputName = {'Fu', 'Fv'}; + %% Find result with wanted parallel stiffness [~, i_kp_vc] = min(abs(kps_vc - 1e3)); [~, i_kp_md] = min(abs(kps_md - 1e4)); diff --git a/A2-nass-rotating-3dof-model/rotating_8_nass.m b/A2-nass-rotating-3dof-model/rotating_8_nass.m index 12dfe9f..6306e2b 100644 --- a/A2-nass-rotating-3dof-model/rotating_8_nass.m +++ b/A2-nass-rotating-3dof-model/rotating_8_nass.m @@ -209,7 +209,7 @@ hold off; yticks(-360:90:360); ylim([ -200, 20]); -linkaxes([ax,ax2],'x'); +linkaxes([ax1,ax2],'x'); xlim([freqs_vc(1), freqs_vc(end)]); xticks([1e-1, 1e0, 1e1]); diff --git a/A6-simscape-nass/nass_1_active_damping.m b/A6-simscape-nass/nass_1_active_damping.m index cc68d21..47dd50c 100644 --- a/A6-simscape-nass/nass_1_active_damping.m +++ b/A6-simscape-nass/nass_1_active_damping.m @@ -268,8 +268,16 @@ xlim([freqs(1), freqs(end)]); %% Verify that parallel stiffness permits to have a stable plant Kiff_pure_int = -200/s*eye(6); -isstable(feedback(G_iff_m25_Rz, Kiff_pure_int, 1)) -isstable(feedback(G_iff_m25_Rz_no_kp, Kiff_pure_int, 1)) + +if not(isstable(feedback(G_iff_m25_Rz, Kiff_pure_int, 1))) + disp("Decentralized IFF is not stable with rotation") +end + +if isstable(feedback(G_iff_m25_Rz_no_kp, Kiff_pure_int, 1)) + disp("Parallel stiffness makes the decentralized IFF stable") +else + warning("Decentralized IFF is not stable even with the parallel stiffness") +end %% IFF Controller Design % Second order high pass filter diff --git a/B1-nass-geometry/detail_kinematics_1_geometry.m b/B1-nass-geometry/detail_kinematics_1_geometry.m index 12c58d3..a8baaaa 100644 --- a/B1-nass-geometry/detail_kinematics_1_geometry.m +++ b/B1-nass-geometry/detail_kinematics_1_geometry.m @@ -5,7 +5,6 @@ clear; close all; clc; s = zpk('s'); %% Path for functions, data and scripts -addpath('./mat/'); % Path for data addpath('./src/'); % Path for functions addpath('./subsystems/'); % Path for Subsystems Simulink files diff --git a/B1-nass-geometry/detail_kinematics_2_cubic.m b/B1-nass-geometry/detail_kinematics_2_cubic.m index e22295d..304bf78 100644 --- a/B1-nass-geometry/detail_kinematics_2_cubic.m +++ b/B1-nass-geometry/detail_kinematics_2_cubic.m @@ -5,7 +5,6 @@ clear; close all; clc; s = zpk('s'); %% Path for functions, data and scripts -addpath('./mat/'); % Path for data addpath('./src/'); % Path for functions addpath('./subsystems/'); % Path for Subsystems Simulink files diff --git a/B1-nass-geometry/detail_kinematics_3_nano_hexapod.m b/B1-nass-geometry/detail_kinematics_3_nano_hexapod.m index 756bdb4..991cb4a 100644 --- a/B1-nass-geometry/detail_kinematics_3_nano_hexapod.m +++ b/B1-nass-geometry/detail_kinematics_3_nano_hexapod.m @@ -5,7 +5,6 @@ clear; close all; clc; s = zpk('s'); %% Path for functions, data and scripts -addpath('./mat/'); % Path for data addpath('./src/'); % Path for functions addpath('./subsystems/'); % Path for Subsystems Simulink files @@ -97,7 +96,7 @@ for Dx = Dxs end end -sprintf('Actuator stroke should be from %.0f um to %.0f um', 1e6*L_min, 1e6*L_max) +disp(sprintf('Actuator stroke should be from %.0f um to %.0f um', 1e6*L_min, 1e6*L_max)) %% Compute mobility in translation with combined angular motion % Direction of motion (spherical coordinates) @@ -232,5 +231,5 @@ for Dx = Dxs end end -sprintf('Fixed joint stroke should be %.1f mrad', 1e3*max(max_angles_F)) -sprintf('Mobile joint stroke should be %.1f mrad', 1e3*max(max_angles_M)) +disp(sprintf('Fixed joint stroke should be %.1f mrad', 1e3*max(max_angles_F))) +disp(sprintf('Mobile joint stroke should be %.1f mrad', 1e3*max(max_angles_M))) diff --git a/B2-nass-fem/src/extractNodes.m b/B2-nass-fem/src/extractNodes.m new file mode 100644 index 0000000..7454b36 --- /dev/null +++ b/B2-nass-fem/src/extractNodes.m @@ -0,0 +1,91 @@ +function [int_xyz, int_i, n_xyz, n_i, nodes] = extractNodes(filename) +% extractNodes - +% +% Syntax: [n_xyz, nodes] = extractNodes(filename) +% +% Inputs: +% - filename - relative or absolute path of the file that contains the Matrix +% +% Outputs: +% - n_xyz - +% - nodes - table containing the node numbers and corresponding dof of the interfaced DoFs + +arguments + filename +end + +fid = fopen(filename,'rt'); + +if fid == -1 + error('Error opening the file'); +end + +n_xyz = []; % Contains nodes coordinates +n_i = []; % Contains nodes indices + +n_num = []; % Contains node numbers +n_dof = {}; % Contains node directions + +while 1 + % Read a line + nextline = fgetl(fid); + + % End of the file + if ~isstr(nextline), break, end + + % Line just before the list of nodes coordinates + if contains(nextline, 'NODE') && ... + contains(nextline, 'X') && ... + contains(nextline, 'Y') && ... + contains(nextline, 'Z') + + while 1 + nextline = fgetl(fid); + + if nextline < 0, break, end + + c = sscanf(nextline, ' %f'); + + if isempty(c), break, end + + n_xyz = [n_xyz; c(2:4)']; + n_i = [n_i; c(1)]; + end + end + + if nextline < 0, break, end + + % Line just before the list of node DOF + if contains(nextline, 'NODE') && ... + contains(nextline, 'LABEL') + + while 1 + nextline = fgetl(fid); + + if nextline < 0, break, end + + c = sscanf(nextline, ' %d %s'); + + if isempty(c), break, end + + n_num = [n_num; c(1)]; + + n_dof{length(n_dof)+1} = char(c(2:end)'); + end + + nodes = table(n_num, string(n_dof'), 'VariableNames', {'node_i', 'node_dof'}); + end + + if nextline < 0, break, end +end + +fclose(fid); + +int_i = unique(nodes.('node_i')); % indices of interface nodes + +% Extract XYZ coordinates of only the interface nodes +if length(n_xyz) > 0 && length(n_i) > 0 + int_xyz = n_xyz(logical(sum(n_i.*ones(1, length(int_i)) == int_i', 2)), :); +else + int_xyz = n_xyz; +end diff --git a/C5-test-bench-id31/mat/align_int_enc_Rz_tx_first_scan.h5 b/C5-test-bench-id31/mat/align_int_enc_Rz_tx_first_scan.h5 new file mode 100644 index 0000000..17fd420 Binary files /dev/null and b/C5-test-bench-id31/mat/align_int_enc_Rz_tx_first_scan.h5 differ diff --git a/C5-test-bench-id31/mat/align_int_enc_Rz_verif-after-correct-offset.h5 b/C5-test-bench-id31/mat/align_int_enc_Rz_verif-after-correct-offset.h5 new file mode 100644 index 0000000..078aae5 Binary files /dev/null and b/C5-test-bench-id31/mat/align_int_enc_Rz_verif-after-correct-offset.h5 differ diff --git a/C5-test-bench-id31/mat/alignment_h1dx_h1dy.h5 b/C5-test-bench-id31/mat/alignment_h1dx_h1dy.h5 new file mode 100644 index 0000000..32b7b37 Binary files /dev/null and b/C5-test-bench-id31/mat/alignment_h1dx_h1dy.h5 differ diff --git a/C5-test-bench-id31/mat/alignment_h1rx_h1ry.h5 b/C5-test-bench-id31/mat/alignment_h1rx_h1ry.h5 new file mode 100644 index 0000000..3330102 Binary files /dev/null and b/C5-test-bench-id31/mat/alignment_h1rx_h1ry.h5 differ diff --git a/C5-test-bench-id31/mat/alignment_h1rx_h1ry_0002.h5 b/C5-test-bench-id31/mat/alignment_h1rx_h1ry_0002.h5 new file mode 100644 index 0000000..2d7f8af Binary files /dev/null and b/C5-test-bench-id31/mat/alignment_h1rx_h1ry_0002.h5 differ diff --git a/C5-test-bench-id31/mat/metrology_acceptance_after_int_align_meshXY.h5 b/C5-test-bench-id31/mat/metrology_acceptance_after_int_align_meshXY.h5 new file mode 100644 index 0000000..9a87127 Binary files /dev/null and b/C5-test-bench-id31/mat/metrology_acceptance_after_int_align_meshXY.h5 differ diff --git a/C5-test-bench-id31/mat/metrology_acceptance_new_align_dx.h5 b/C5-test-bench-id31/mat/metrology_acceptance_new_align_dx.h5 new file mode 100644 index 0000000..b28ffc5 Binary files /dev/null and b/C5-test-bench-id31/mat/metrology_acceptance_new_align_dx.h5 differ diff --git a/C5-test-bench-id31/mat/metrology_acceptance_new_align_dy.h5 b/C5-test-bench-id31/mat/metrology_acceptance_new_align_dy.h5 new file mode 100644 index 0000000..dea9f1a Binary files /dev/null and b/C5-test-bench-id31/mat/metrology_acceptance_new_align_dy.h5 differ diff --git a/C5-test-bench-id31/mat/metrology_acceptance_new_align_dz.h5 b/C5-test-bench-id31/mat/metrology_acceptance_new_align_dz.h5 new file mode 100644 index 0000000..4bf4f5b Binary files /dev/null and b/C5-test-bench-id31/mat/metrology_acceptance_new_align_dz.h5 differ diff --git a/C5-test-bench-id31/src/h5scan.m b/C5-test-bench-id31/src/h5scan.m index b013d77..d84e1c2 100644 --- a/C5-test-bench-id31/src/h5scan.m +++ b/C5-test-bench-id31/src/h5scan.m @@ -1,102 +1,61 @@ -function [cntrs,tp] = h5scan(pth,smp,ds,sn,varargin) +% function [cntrs,tp] = h5scan(pth,smp,ds,sn,varargin) +function [cntrs,tp] = h5scan(ds,sn) + if ~isstr(ds), ds = sprintf('%.4d',ds); end; -i = cellfun(@(x) isa(x,'detector'),varargin); -if any(i), det = varargin{i}; varargin = varargin(~i); else, det = []; end; -if ~isstr(ds), ds = sprintf('%.4d',ds); end; + f = sprintf('%s.h5',ds); + h = h5info(f,sprintf('/%d.1/measurement',sn)); + fid = H5F.open(f); + for i = 1:length(h.Links) + nm = h.Links(i).Name; + try + id = H5D.open(fid,h.Links(i).Value{1}); + cntrs.(nm) = H5D.read(id); + H5D.close(id); + if ~isempty(det) & strcmp(nm,det.name), cntrs.(nm) = integrate(det,double(cntrs.(nm))); end; + end + [~,tp.(nm)] = fileparts(h.Links(i).Value{1}); + end + try + h = h5info(f,sprintf('/%d.2/measurement',sn)); + catch + h = []; + end + if ~isempty(h) + for i = 1:length(h.Links) + nm = h.Links(i).Name; + try + id = H5D.open(fid,h.Links(i).Value{1}); + cntrs.part2.(nm) = H5D.read(id); + H5D.close(id); + end + [~,tp.part2.(nm)] = fileparts(h.Links(i).Value{1}); + end + end -f = sprintf('%s/%s/%s_%s/%s_%s.h5',pth,smp,smp,ds,smp,ds); -h = h5info(f,sprintf('/%d.1/measurement',sn)); -fid = H5F.open(f); -for i = 1:length(h.Links), - nm = h.Links(i).Name; - try, - id = H5D.open(fid,h.Links(i).Value{1}); - cntrs.(nm) = H5D.read(id); - H5D.close(id); - if ~isempty(det) & strcmp(nm,det.name), cntrs.(nm) = integrate(det,double(cntrs.(nm))); end; - catch, - warning('solving problem with %s\n',nm); - cntrs.(nm) = vrtlds(sprintf('%s/%s/%s_%s/scan%.4d/',pth,smp,smp,ds,sn),nm,det); - end; - [~,tp.(nm)] = fileparts(h.Links(i).Value{1}); -end; -try, - h = h5info(f,sprintf('/%d.2/measurement',sn)); -catch, - h = []; -end; -if ~isempty(h), - for i = 1:length(h.Links), - nm = h.Links(i).Name; - try, - id = H5D.open(fid,h.Links(i).Value{1}); - cntrs.part2.(nm) = H5D.read(id); - H5D.close(id); - catch, - warning('solving problem with %s\n',nm); - cntrs.part2.(nm) = vrtlds(sprintf('%s/%s/%s_%s/scan%.4d/',pth,smp,smp,ds,sn),nm,det); - end; - [~,tp.part2.(nm)] = fileparts(h.Links(i).Value{1}); - end; -end; -if length(varargin), - fn = sprintf('/%d.1/instrument/positioners/',sn); - h = h5info(f,fn); - [~,k,m] = intersect({h.Datasets.Name},varargin,'stable'); - h.Datasets = h.Datasets(k); - for i = 1:length(h.Datasets), - id = H5D.open(fid,[fn h.Datasets(i).Name]); - cntrs.(h.Datasets(i).Name) = H5D.read(id); - H5D.close(id); - end; -end; + H5F.close(fid); -H5F.close(fid); + %%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%% + function A = vrtlds(f,nm,det) + n = 0; A = []; + fn = sprintf('%s/%s_%.4d.h5',f,nm,n); -function A = vrtlds(f,nm,det) -%try, - n = 0; A = []; - fn = sprintf('%s/%s_%.4d.h5',f,nm,n); - while exist(fn) == 2, - fid = H5F.open(fn); n = n+1; - id = H5D.open(fid,sprintf('/entry_0000/ESRF-ID31/%s/data',nm)); - if 2 < nargin & strcmp(nm,'p3') & ~isempty(det), - fprintf('integrating %s\n',fn); - if isempty(A), - A = integrate(det,double(H5D.read(id)),1); - else, - tmp = integrate(det,double(H5D.read(id)),1); A.y = cat(2,A.y,tmp.y); A.y0 = cat(2,A.y0,tmp.y0); - end; - else, - fprintf('loading %s\n',fn); - A = cat(3,A,H5D.read(id)); - end; - H5D.close(id); H5F.close(fid); - fn = sprintf('%s/%s_%.4d.h5',f,nm,n); - end; -%catch, -% A = []; -%end; - -% fid = H5F.open... -% id = H5D.open... -% sid = H5D.get_space(id); -% [ndims,h5_dims]=H5S.get_simple_extent_dims(sid) - -% Read a 2x3 hyperslab of data from a dataset, starting in the 4th row and 5th column of the example dataset. -% Create a property list identifier, then open the HDF5 file and the dataset /g1/g1.1/dset1.1.1. - -% fid = H5F.open('example.h5'); -% id = H5D.open(fid,'/g1/g1.1/dset1.1.1'); - -% dims = ([500 1679 1475]; -% msid = H5S.create_simple(3,dims,[]); -% sid = H5D.get_space(id); -% offset = [n*500 0 0]; -% block = dims; % d1: 500 or min(d1tot-n*500,500) -% H5S.select_hyperslab(sid,'H5S_SELECT_SET',offset,[],[],block); -% data = H5D.read(id,'H5ML_DEFAULT',msid,sid,'H5P_DEFAULT'); -% H5D.close(id); -% H5F.close(fid); + while exist(fn) == 2 + fid = H5F.open(fn); n = n+1; + id = H5D.open(fid,sprintf('/entry_0000/ESRF-ID31/%s/data',nm)); + if 2 < nargin & strcmp(nm,'p3') & ~isempty(det) + fprintf('integrating %s\n',fn); + if isempty(A) + A = integrate(det,double(H5D.read(id)),1); + else + tmp = integrate(det,double(H5D.read(id)),1); A.y = cat(2,A.y,tmp.y); A.y0 = cat(2,A.y0,tmp.y0); + end + else + fprintf('loading %s\n',fn); + A = cat(3,A,H5D.read(id)); + end + H5D.close(id); H5F.close(fid); + fn = sprintf('%s/%s_%.4d.h5',f,nm,n); + end + end +end diff --git a/C5-test-bench-id31/test_id31_1_metrology.m b/C5-test-bench-id31/test_id31_1_metrology.m index dc9c7e3..f9d088d 100644 --- a/C5-test-bench-id31/test_id31_1_metrology.m +++ b/C5-test-bench-id31/test_id31_1_metrology.m @@ -46,9 +46,9 @@ Hm = [ 0 1 0 -l2 0; %% Angular alignment % Load Data -data_it0 = h5scan(data_dir, 'alignment', 'h1rx_h1ry', 1); -data_it1 = h5scan(data_dir, 'alignment', 'h1rx_h1ry_0002', 3); -data_it2 = h5scan(data_dir, 'alignment', 'h1rx_h1ry_0002', 5); +data_it0 = h5scan('alignment_h1rx_h1ry', 1); +data_it1 = h5scan('alignment_h1rx_h1ry_0002', 3); +data_it2 = h5scan('alignment_h1rx_h1ry_0002', 5); % Offset wrong points i_it0 = find(abs(data_it0.Rx_int_filtered(2:end)-data_it0.Rx_int_filtered(1:end-1))>1e-5); @@ -81,8 +81,8 @@ ylim([-100, 800]); %% Eccentricity alignment % Load Data -data_it0 = h5scan(data_dir, 'alignment', 'h1rx_h1ry_0002', 5); -data_it1 = h5scan(data_dir, 'alignment', 'h1dx_h1dy', 1); +data_it0 = h5scan('alignment_h1rx_h1ry_0002', 5); +data_it1 = h5scan('alignment_h1dx_h1dy', 1); % Offset wrong points i_it0 = find(abs(data_it0.Dy_int_filtered(2:end)-data_it0.Dy_int_filtered(1:end-1))>1e-5); @@ -110,7 +110,7 @@ ylim([-8, 14]); % This is estimated by moving the spheres using the micro-hexapod % Dx -data_dx = h5scan(data_dir, 'metrology_acceptance_new_align', 'dx', 1); +data_dx = h5scan('metrology_acceptance_new_align_dx', 1); dx_acceptance = zeros(5,1); @@ -126,7 +126,7 @@ for i = [1:size(dx_acceptance, 1)] end % Dy -data_dy = h5scan(data_dir, 'metrology_acceptance_new_align', 'dy', 1); +data_dy = h5scan('metrology_acceptance_new_align_dy', 1); dy_acceptance = zeros(5,1); @@ -142,7 +142,7 @@ for i = [1:size(dy_acceptance, 1)] end % Dz -data_dz = h5scan(data_dir, 'metrology_acceptance_new_align', 'dz', 1); +data_dz = h5scan('metrology_acceptance_new_align_dz', 1); dz_acceptance = zeros(5,1); @@ -186,7 +186,7 @@ leg = legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 1); leg.ItemTokenSize(1) = 15; %% X-Y scan with the micro-hexapod, and record of the vertical interferometer -data = h5scan(data_dir, 'metrology_acceptance', 'after_int_align_meshXY', 1); +data = h5scan('metrology_acceptance_after_int_align_meshXY', 1); x = 1e3*detrend(data.h1tx, 0); % [um] y = 1e3*detrend(data.h1ty, 0); % [um] diff --git a/C5-test-bench-id31/test_id31_2_open_loop_plant.m b/C5-test-bench-id31/test_id31_2_open_loop_plant.m index ae88b2c..8c70335 100644 --- a/C5-test-bench-id31/test_id31_2_open_loop_plant.m +++ b/C5-test-bench-id31/test_id31_2_open_loop_plant.m @@ -198,10 +198,10 @@ linkaxes([ax1,ax2],'x'); xlim([1, 1e3]); %% Load Data -data_1_dx = h5scan(data_dir, 'align_int_enc_Rz', 'tx_first_scan', 2); -data_1_dy = h5scan(data_dir, 'align_int_enc_Rz', 'tx_first_scan', 3); -data_2_dx = h5scan(data_dir, 'align_int_enc_Rz', 'verif-after-correct-offset', 1); -data_2_dy = h5scan(data_dir, 'align_int_enc_Rz', 'verif-after-correct-offset', 2); +data_1_dx = h5scan('align_int_enc_Rz_tx_first_scan', 2); +data_1_dy = h5scan('align_int_enc_Rz_tx_first_scan', 3); +data_2_dx = h5scan('align_int_enc_Rz_verif-after-correct-offset', 1); +data_2_dy = h5scan('align_int_enc_Rz_verif-after-correct-offset', 2); % Estimation of Rz misalignment p1 = polyfit(data_1_dx.Dx_int_filtered, data_1_dx.Dy_int_filtered, 1);