diff --git a/figs/unused/ustation_hexapod_strut.svg b/figs/unused/ustation_hexapod_strut.svg new file mode 100644 index 0000000..ed68f6d Binary files /dev/null and b/figs/unused/ustation_hexapod_strut.svg differ diff --git a/figs/unused/ustation_schematic_dof.pdf b/figs/unused/ustation_schematic_dof.pdf new file mode 100644 index 0000000..7de4758 Binary files /dev/null and b/figs/unused/ustation_schematic_dof.pdf differ diff --git a/figs/unused/ustation_schematic_dof.png b/figs/unused/ustation_schematic_dof.png new file mode 100644 index 0000000..226650d Binary files /dev/null and b/figs/unused/ustation_schematic_dof.png differ diff --git a/figs/unused/ustation_schematic_dof.svg b/figs/unused/ustation_schematic_dof.svg new file mode 100644 index 0000000..3ccfafe Binary files /dev/null and b/figs/unused/ustation_schematic_dof.svg differ diff --git a/figs/unused/ustation_stage_ry.pdf b/figs/unused/ustation_stage_ry.pdf new file mode 100644 index 0000000..0dcd3b2 Binary files /dev/null and b/figs/unused/ustation_stage_ry.pdf differ diff --git a/figs/unused/ustation_stage_ry.png b/figs/unused/ustation_stage_ry.png new file mode 100644 index 0000000..703d104 Binary files /dev/null and b/figs/unused/ustation_stage_ry.png differ diff --git a/figs/unused/ustation_stage_ry.svg b/figs/unused/ustation_stage_ry.svg new file mode 100644 index 0000000..56300cb Binary files /dev/null and b/figs/unused/ustation_stage_ry.svg differ diff --git a/figs/unused/ustation_stage_rz.svg b/figs/unused/ustation_stage_rz.svg new file mode 100644 index 0000000..f57c259 Binary files /dev/null and b/figs/unused/ustation_stage_rz.svg differ diff --git a/figs/unused/ustation_stage_ty.pdf b/figs/unused/ustation_stage_ty.pdf new file mode 100644 index 0000000..b640936 Binary files /dev/null and b/figs/unused/ustation_stage_ty.pdf differ diff --git a/figs/unused/ustation_stage_ty.png b/figs/unused/ustation_stage_ty.png new file mode 100644 index 0000000..f47d3b8 Binary files /dev/null and b/figs/unused/ustation_stage_ty.png differ diff --git a/figs/unused/ustation_stage_ty.svg b/figs/unused/ustation_stage_ty.svg new file mode 100644 index 0000000..02557a0 Binary files /dev/null and b/figs/unused/ustation_stage_ty.svg differ diff --git a/figs/ustation_dist_source_ground_motion.pdf b/figs/ustation_dist_source_ground_motion.pdf new file mode 100644 index 0000000..1e23f1b Binary files /dev/null and b/figs/ustation_dist_source_ground_motion.pdf differ diff --git a/figs/ustation_dist_source_ground_motion.png b/figs/ustation_dist_source_ground_motion.png new file mode 100644 index 0000000..3e7c8a3 Binary files /dev/null and b/figs/ustation_dist_source_ground_motion.png differ diff --git a/figs/ustation_dist_source_ground_motion_time.pdf b/figs/ustation_dist_source_ground_motion_time.pdf new file mode 100644 index 0000000..55193d6 Binary files /dev/null and b/figs/ustation_dist_source_ground_motion_time.pdf differ diff --git a/figs/ustation_dist_source_ground_motion_time.png b/figs/ustation_dist_source_ground_motion_time.png new file mode 100644 index 0000000..197e50d Binary files /dev/null and b/figs/ustation_dist_source_ground_motion_time.png differ diff --git a/figs/ustation_dist_source_spindle.pdf b/figs/ustation_dist_source_spindle.pdf new file mode 100644 index 0000000..9e7b7b8 Binary files /dev/null and b/figs/ustation_dist_source_spindle.pdf differ diff --git a/figs/ustation_dist_source_spindle.png b/figs/ustation_dist_source_spindle.png new file mode 100644 index 0000000..a261864 Binary files /dev/null and b/figs/ustation_dist_source_spindle.png differ diff --git a/figs/ustation_dist_source_spindle_time.pdf b/figs/ustation_dist_source_spindle_time.pdf new file mode 100644 index 0000000..4c3ab85 Binary files /dev/null and b/figs/ustation_dist_source_spindle_time.pdf differ diff --git a/figs/ustation_dist_source_spindle_time.png b/figs/ustation_dist_source_spindle_time.png new file mode 100644 index 0000000..6392661 Binary files /dev/null and b/figs/ustation_dist_source_spindle_time.png differ diff --git a/figs/ustation_dist_source_translation_stage.pdf b/figs/ustation_dist_source_translation_stage.pdf new file mode 100644 index 0000000..8d9dd74 Binary files /dev/null and b/figs/ustation_dist_source_translation_stage.pdf differ diff --git a/figs/ustation_dist_source_translation_stage.png b/figs/ustation_dist_source_translation_stage.png new file mode 100644 index 0000000..e993b8c Binary files /dev/null and b/figs/ustation_dist_source_translation_stage.png differ diff --git a/figs/ustation_dist_source_translation_stage_time.pdf b/figs/ustation_dist_source_translation_stage_time.pdf new file mode 100644 index 0000000..6c053ff Binary files /dev/null and b/figs/ustation_dist_source_translation_stage_time.pdf differ diff --git a/figs/ustation_dist_source_translation_stage_time.png b/figs/ustation_dist_source_translation_stage_time.png new file mode 100644 index 0000000..72ccacd Binary files /dev/null and b/figs/ustation_dist_source_translation_stage_time.png differ diff --git a/figs/ustation_errors_dy_vertical.pdf b/figs/ustation_errors_dy_vertical.pdf index 1a526eb..3c3a7ec 100644 Binary files a/figs/ustation_errors_dy_vertical.pdf and b/figs/ustation_errors_dy_vertical.pdf differ diff --git a/figs/ustation_errors_dy_vertical_remove_mean.pdf b/figs/ustation_errors_dy_vertical_remove_mean.pdf index 7f6700c..d81ca3b 100644 Binary files a/figs/ustation_errors_dy_vertical_remove_mean.pdf and b/figs/ustation_errors_dy_vertical_remove_mean.pdf differ diff --git a/figs/ustation_errors_model_dy_vertical.pdf b/figs/ustation_errors_model_dy_vertical.pdf new file mode 100644 index 0000000..dbd349a Binary files /dev/null and b/figs/ustation_errors_model_dy_vertical.pdf differ diff --git a/figs/ustation_errors_model_dy_vertical.png b/figs/ustation_errors_model_dy_vertical.png new file mode 100644 index 0000000..8e9275d Binary files /dev/null and b/figs/ustation_errors_model_dy_vertical.png differ diff --git a/figs/ustation_errors_model_spindle_axial.pdf b/figs/ustation_errors_model_spindle_axial.pdf new file mode 100644 index 0000000..f1a23f3 Binary files /dev/null and b/figs/ustation_errors_model_spindle_axial.pdf differ diff --git a/figs/ustation_errors_model_spindle_axial.png b/figs/ustation_errors_model_spindle_axial.png new file mode 100644 index 0000000..c8bf813 Binary files /dev/null and b/figs/ustation_errors_model_spindle_axial.png differ diff --git a/figs/ustation_errors_model_spindle_radial.pdf b/figs/ustation_errors_model_spindle_radial.pdf new file mode 100644 index 0000000..2d7bef2 Binary files /dev/null and b/figs/ustation_errors_model_spindle_radial.pdf differ diff --git a/figs/ustation_errors_model_spindle_radial.png b/figs/ustation_errors_model_spindle_radial.png new file mode 100644 index 0000000..de13163 Binary files /dev/null and b/figs/ustation_errors_model_spindle_radial.png differ diff --git a/figs/ustation_errors_spindle_axial.pdf b/figs/ustation_errors_spindle_axial.pdf index 691fbe7..ce3d6f7 100644 Binary files a/figs/ustation_errors_spindle_axial.pdf and b/figs/ustation_errors_spindle_axial.pdf differ diff --git a/figs/ustation_errors_spindle_radial.pdf b/figs/ustation_errors_spindle_radial.pdf index 97a38f7..f72a1ce 100644 Binary files a/figs/ustation_errors_spindle_radial.pdf and b/figs/ustation_errors_spindle_radial.pdf differ diff --git a/figs/ustation_errors_spindle_radial.png b/figs/ustation_errors_spindle_radial.png index 71f0580..e581ff3 100644 Binary files a/figs/ustation_errors_spindle_radial.png and b/figs/ustation_errors_spindle_radial.png differ diff --git a/figs/ustation_errors_spindle_tilt.pdf b/figs/ustation_errors_spindle_tilt.pdf index 4c5d85d..97a416b 100644 Binary files a/figs/ustation_errors_spindle_tilt.pdf and b/figs/ustation_errors_spindle_tilt.pdf differ diff --git a/figs/ustation_ground_disturbance.pdf b/figs/ustation_ground_disturbance.pdf new file mode 100644 index 0000000..05a64ab Binary files /dev/null and b/figs/ustation_ground_disturbance.pdf differ diff --git a/figs/ustation_ground_disturbance.png b/figs/ustation_ground_disturbance.png new file mode 100644 index 0000000..78ac47f Binary files /dev/null and b/figs/ustation_ground_disturbance.png differ diff --git a/figs/ustation_model_sensitivity_ground_motion.pdf b/figs/ustation_model_sensitivity_ground_motion.pdf index e3768ec..1d7ec5b 100644 Binary files a/figs/ustation_model_sensitivity_ground_motion.pdf and b/figs/ustation_model_sensitivity_ground_motion.pdf differ diff --git a/figs/ustation_model_sensitivity_rz.pdf b/figs/ustation_model_sensitivity_rz.pdf index 5e89c4a..a5a06f5 100644 Binary files a/figs/ustation_model_sensitivity_rz.pdf and b/figs/ustation_model_sensitivity_rz.pdf differ diff --git a/figs/ustation_model_sensitivity_ty.pdf b/figs/ustation_model_sensitivity_ty.pdf index f91e64b..83e25d0 100644 Binary files a/figs/ustation_model_sensitivity_ty.pdf and b/figs/ustation_model_sensitivity_ty.pdf differ diff --git a/matlab/mat/nass_model_conf_log.mat b/matlab/mat/nass_model_conf_log.mat new file mode 100644 index 0000000..4175754 Binary files /dev/null and b/matlab/mat/nass_model_conf_log.mat differ diff --git a/matlab/mat/nass_model_conf_simscape.mat b/matlab/mat/nass_model_conf_simscape.mat new file mode 100644 index 0000000..e0cb862 Binary files /dev/null and b/matlab/mat/nass_model_conf_simscape.mat differ diff --git a/matlab/mat/nass_model_conf_simulink.mat b/matlab/mat/nass_model_conf_simulink.mat new file mode 100644 index 0000000..6d01d43 Binary files /dev/null and b/matlab/mat/nass_model_conf_simulink.mat differ diff --git a/matlab/mat/nass_model_disturbances.mat b/matlab/mat/nass_model_disturbances.mat new file mode 100644 index 0000000..a109888 Binary files /dev/null and b/matlab/mat/nass_model_disturbances.mat differ diff --git a/matlab/mat/nass_model_references.mat b/matlab/mat/nass_model_references.mat new file mode 100644 index 0000000..d14e973 Binary files /dev/null and b/matlab/mat/nass_model_references.mat differ diff --git a/matlab/mat/nass_model_stages.mat b/matlab/mat/nass_model_stages.mat new file mode 100644 index 0000000..da939ba Binary files /dev/null and b/matlab/mat/nass_model_stages.mat differ diff --git a/matlab/mat/ustation_compliance_hammer_1.mat b/matlab/mat/ustation_compliance_hammer_1.mat new file mode 100644 index 0000000..08a494b Binary files /dev/null and b/matlab/mat/ustation_compliance_hammer_1.mat differ diff --git a/matlab/mat/ustation_compliance_hammer_10.mat b/matlab/mat/ustation_compliance_hammer_10.mat new file mode 100644 index 0000000..db3aaff Binary files /dev/null and b/matlab/mat/ustation_compliance_hammer_10.mat differ diff --git a/matlab/mat/ustation_compliance_hammer_2.mat b/matlab/mat/ustation_compliance_hammer_2.mat new file mode 100644 index 0000000..7767eda Binary files /dev/null and b/matlab/mat/ustation_compliance_hammer_2.mat differ diff --git a/matlab/mat/ustation_compliance_hammer_3.mat b/matlab/mat/ustation_compliance_hammer_3.mat new file mode 100644 index 0000000..04a411d Binary files /dev/null and b/matlab/mat/ustation_compliance_hammer_3.mat differ diff --git a/matlab/mat/ustation_compliance_hammer_4.mat b/matlab/mat/ustation_compliance_hammer_4.mat new file mode 100644 index 0000000..b228762 Binary files /dev/null and b/matlab/mat/ustation_compliance_hammer_4.mat differ diff --git a/matlab/mat/ustation_compliance_hammer_5.mat b/matlab/mat/ustation_compliance_hammer_5.mat new file mode 100644 index 0000000..31fc676 Binary files /dev/null and b/matlab/mat/ustation_compliance_hammer_5.mat differ diff --git a/matlab/mat/ustation_compliance_hammer_6.mat b/matlab/mat/ustation_compliance_hammer_6.mat new file mode 100644 index 0000000..8371fab Binary files /dev/null and b/matlab/mat/ustation_compliance_hammer_6.mat differ diff --git a/matlab/mat/ustation_compliance_hammer_7.mat b/matlab/mat/ustation_compliance_hammer_7.mat new file mode 100644 index 0000000..d7ef120 Binary files /dev/null and b/matlab/mat/ustation_compliance_hammer_7.mat differ diff --git a/matlab/mat/ustation_compliance_hammer_8.mat b/matlab/mat/ustation_compliance_hammer_8.mat new file mode 100644 index 0000000..8be524e Binary files /dev/null and b/matlab/mat/ustation_compliance_hammer_8.mat differ diff --git a/matlab/mat/ustation_compliance_hammer_9.mat b/matlab/mat/ustation_compliance_hammer_9.mat new file mode 100644 index 0000000..6bad103 Binary files /dev/null and b/matlab/mat/ustation_compliance_hammer_9.mat differ diff --git a/matlab/mat/ustation_disturbance_psd.mat b/matlab/mat/ustation_disturbance_psd.mat new file mode 100644 index 0000000..4d83415 Binary files /dev/null and b/matlab/mat/ustation_disturbance_psd.mat differ diff --git a/matlab/mat/ustation_disturbance_sensitivity.mat b/matlab/mat/ustation_disturbance_sensitivity.mat new file mode 100644 index 0000000..0dd3038 Binary files /dev/null and b/matlab/mat/ustation_disturbance_sensitivity.mat differ diff --git a/matlab/mat/ustation_errors_spindle.mat b/matlab/mat/ustation_errors_spindle.mat new file mode 100644 index 0000000..6b8085a Binary files /dev/null and b/matlab/mat/ustation_errors_spindle.mat differ diff --git a/matlab/mat/ustation_errors_ty.mat b/matlab/mat/ustation_errors_ty.mat new file mode 100644 index 0000000..ac2d6ac Binary files /dev/null and b/matlab/mat/ustation_errors_ty.mat differ diff --git a/matlab/mat/ustation_frf_com.mat b/matlab/mat/ustation_frf_com.mat new file mode 100644 index 0000000..1b07258 Binary files /dev/null and b/matlab/mat/ustation_frf_com.mat differ diff --git a/matlab/mat/ustation_frf_matrix.mat b/matlab/mat/ustation_frf_matrix.mat new file mode 100644 index 0000000..81194ab Binary files /dev/null and b/matlab/mat/ustation_frf_matrix.mat differ diff --git a/matlab/mat/ustation_ground_motion.mat b/matlab/mat/ustation_ground_motion.mat new file mode 100644 index 0000000..cc2b6f0 Binary files /dev/null and b/matlab/mat/ustation_ground_motion.mat differ diff --git a/matlab/src/circlefit.m b/matlab/src/circlefit.m new file mode 100644 index 0000000..db5c99f --- /dev/null +++ b/matlab/src/circlefit.m @@ -0,0 +1,21 @@ +function [xc,yc,R,a] = circlefit(x,y) +% +% [xc yx R] = circfit(x,y) +% +% fits a circle in x,y plane in a more accurate +% (less prone to ill condition ) +% procedure than circfit2 but using more memory +% x,y are column vector where (x(i),y(i)) is a measured point +% +% result is center point (yc,xc) and radius R +% an optional output is the vector of coeficient a +% describing the circle's equation +% +% x^2+y^2+a(1)*x+a(2)*y+a(3)=0 +% +% By: Izhak bucher 25/oct /1991, + x=x(:); y=y(:); + a=[x y ones(size(x))]\[-(x.^2+y.^2)]; + xc = -.5*a(1); + yc = -.5*a(2); + R = sqrt((a(1)^2+a(2)^2)/4-a(3)); diff --git a/matlab/src/initializeDisturbances.m b/matlab/src/initializeDisturbances.m index 37a4add..a50b141 100644 --- a/matlab/src/initializeDisturbances.m +++ b/matlab/src/initializeDisturbances.m @@ -10,15 +10,15 @@ arguments % Global parameter to enable or disable the disturbances args.enable logical {mustBeNumericOrLogical} = true % Ground Motion - X direction - args.Dwx logical {mustBeNumericOrLogical} = true + args.Dw_x logical {mustBeNumericOrLogical} = true % Ground Motion - Y direction - args.Dwy logical {mustBeNumericOrLogical} = true + args.Dw_y logical {mustBeNumericOrLogical} = true % Ground Motion - Z direction - args.Dwz logical {mustBeNumericOrLogical} = true + args.Dw_z logical {mustBeNumericOrLogical} = true % Translation Stage - X direction - args.Fty_x logical {mustBeNumericOrLogical} = true + args.Fdy_x logical {mustBeNumericOrLogical} = true % Translation Stage - Z direction - args.Fty_z logical {mustBeNumericOrLogical} = true + args.Fdy_z logical {mustBeNumericOrLogical} = true % Spindle - X direction args.Frz_x logical {mustBeNumericOrLogical} = true % Spindle - Y direction @@ -31,175 +31,163 @@ end rng("shuffle"); %% Ground Motion -load('dist_psd.mat', 'dist_f'); +if args.enable + % Load the PSD of disturbance + load('ustation_disturbance_psd.mat', 'gm_dist') -% Frequency Data -Dw.f = dist_f.f(2:end); -Dw.psd_x = dist_f.psd_gm(2:end); -Dw.psd_y = dist_f.psd_gm(2:end); -Dw.psd_z = dist_f.psd_gm(2:end); + % Frequency Data + Dw.f = gm_dist.f; + Dw.psd_x = gm_dist.pxx_x; + Dw.psd_y = gm_dist.pxx_y; + Dw.psd_z = gm_dist.pxx_z; -% Time data -Fs = 2*Dw.f(end); % Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz] -N = 2*length(Dw.f); % Number of Samples match the one of the wanted PSD -T0 = N/Fs; % Signal Duration [s] -Dw.t = linspace(0, T0, N+1)'; % Time Vector [s] + % Time data + Fs = 2*Dw.f(end); % Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz] + N = 2*length(Dw.f); % Number of Samples match the one of the wanted PSD + T0 = N/Fs; % Signal Duration [s] + Dw.t = linspace(0, T0, N+1)'; % Time Vector [s] -C = zeros(N/2,1); -for i = 1:N/2 - C(i) = sqrt(Dw.psd_x(i)/T0); -end - -if args.Dwx && args.enable - theta = 2*pi*rand(N/2,1); % Generate random phase [rad] - Cx = [0 ; C.*complex(cos(theta),sin(theta))]; - Cx = [Cx; flipud(conj(Cx(2:end)))];; - Dw.x = N/sqrt(2)*ifft(Cx); % Ground Motion - x direction [m] -else - Dw.x = zeros(length(Dw.t), 1); -end - -if args.Dwy && args.enable - theta = 2*pi*rand(N/2,1); % Generate random phase [rad] - Cx = [0 ; C.*complex(cos(theta),sin(theta))]; - Cx = [Cx; flipud(conj(Cx(2:end)))];; - Dw.y = N/sqrt(2)*ifft(Cx); % Ground Motion - y direction [m] -else - Dw.y = zeros(length(Dw.t), 1); -end - -if args.Dwy && args.enable - theta = 2*pi*rand(N/2,1); % Generate random phase [rad] - Cx = [0 ; C.*complex(cos(theta),sin(theta))]; - Cx = [Cx; flipud(conj(Cx(2:end)))];; - Dw.z = N/sqrt(2)*ifft(Cx); % Ground Motion - z direction [m] -else - Dw.z = zeros(length(Dw.t), 1); -end - -load('dist_psd.mat', 'dist_f'); -dist_f.f = dist_f.f(2:end); -dist_f.psd_gm = dist_f.psd_gm(2:end); -dist_f.psd_ty = dist_f.psd_ty(2:end); -dist_f.psd_rz = dist_f.psd_rz(2:end); - -%% Translation Stage -load('dist_psd.mat', 'dist_f'); - -% Frequency Data -Ty.f = dist_f.f(2:end); -Ty.psd_x = dist_f.psd_ty(2:end); % TODO - we take here the vertical direction which is wrong but approximate -Ty.psd_z = dist_f.psd_ty(2:end); - -% Time data -Fs = 2*Ty.f(end); % Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz] -N = 2*length(Ty.f); % Number of Samples match the one of the wanted PSD -T0 = N/Fs; % Signal Duration [s] -Ty.t = linspace(0, T0, N+1)'; % Time Vector [s] - -C = zeros(N/2,1); -for i = 1:N/2 - C(i) = sqrt(Ty.psd_x(i)/T0); -end - -% Translation Stage - X -if args.Fty_x && args.enable - phi = Ty.psd_x; + % ASD representation of the ground motion C = zeros(N/2,1); for i = 1:N/2 - C(i) = sqrt(phi(i)/T0); + C(i) = sqrt(Dw.psd_x(i)/T0); end - theta = 2*pi*rand(N/2,1); % Generate random phase [rad] - Cx = [0 ; C.*complex(cos(theta),sin(theta))]; - Cx = [Cx; flipud(conj(Cx(2:end)))];; - u = N/sqrt(2)*ifft(Cx); % Disturbance Force Ty x [N] - Ty.x = u; + + if args.Dw_x + theta = 2*pi*rand(N/2,1); % Generate random phase [rad] + Cx = [0 ; C.*complex(cos(theta),sin(theta))]; + Cx = [Cx; flipud(conj(Cx(2:end)))];; + Dw.x = N/sqrt(2)*ifft(Cx); % Ground Motion - x direction [m] + else + Dw.x = zeros(length(Dw.t), 1); + end + + if args.Dw_y + theta = 2*pi*rand(N/2,1); % Generate random phase [rad] + Cx = [0 ; C.*complex(cos(theta),sin(theta))]; + Cx = [Cx; flipud(conj(Cx(2:end)))];; + Dw.y = N/sqrt(2)*ifft(Cx); % Ground Motion - y direction [m] + else + Dw.y = zeros(length(Dw.t), 1); + end + + if args.Dw_y + theta = 2*pi*rand(N/2,1); % Generate random phase [rad] + Cx = [0 ; C.*complex(cos(theta),sin(theta))]; + Cx = [Cx; flipud(conj(Cx(2:end)))];; + Dw.z = N/sqrt(2)*ifft(Cx); % Ground Motion - z direction [m] + else + Dw.z = zeros(length(Dw.t), 1); + end + else - Ty.x = zeros(length(Ty.t), 1); + Dw.t = [0,1]; % Time Vector [s] + Dw.x = [0,0]; % Ground Motion - X [m] + Dw.y = [0,0]; % Ground Motion - Y [m] + Dw.z = [0,0]; % Ground Motion - Z [m] end -% Translation Stage - Z -if args.Fty_z && args.enable - phi = Ty.psd_z; +%% Translation stage +if args.enable + % Load the PSD of disturbance + load('ustation_disturbance_psd.mat', 'dy_dist') + + % Frequency Data + Dy.f = dy_dist.f; + Dy.psd_x = dy_dist.pxx_fx; + Dy.psd_z = dy_dist.pxx_fz; + + % Time data + Fs = 2*Dy.f(end); % Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz] + N = 2*length(Dy.f); % Number of Samples match the one of the wanted PSD + T0 = N/Fs; % Signal Duration [s] + Dy.t = linspace(0, T0, N+1)'; % Time Vector [s] + + % ASD representation of the disturbance voice C = zeros(N/2,1); for i = 1:N/2 - C(i) = sqrt(phi(i)/T0); + C(i) = sqrt(Dy.psd_x(i)/T0); end - theta = 2*pi*rand(N/2,1); % Generate random phase [rad] - Cx = [0 ; C.*complex(cos(theta),sin(theta))]; - Cx = [Cx; flipud(conj(Cx(2:end)))];; - u = N/sqrt(2)*ifft(Cx); % Disturbance Force Ty z [N] - Ty.z = u; + + if args.Fdy_x + theta = 2*pi*rand(N/2,1); % Generate random phase [rad] + Cx = [0 ; C.*complex(cos(theta),sin(theta))]; + Cx = [Cx; flipud(conj(Cx(2:end)))];; + Dy.x = N/sqrt(2)*ifft(Cx); % Translation stage disturbances - X direction [N] + else + Dy.x = zeros(length(Dy.t), 1); + end + + if args.Fdy_z + theta = 2*pi*rand(N/2,1); % Generate random phase [rad] + Cx = [0 ; C.*complex(cos(theta),sin(theta))]; + Cx = [Cx; flipud(conj(Cx(2:end)))];; + Dy.z = N/sqrt(2)*ifft(Cx); % Translation stage disturbances - Z direction [N] + else + Dy.z = zeros(length(Dy.t), 1); + end + else - Ty.z = zeros(length(Ty.t), 1); + Dy.t = [0,1]; % Time Vector [s] + Dy.x = [0,0]; % Translation Stage disturbances - X [N] + Dy.z = [0,0]; % Translation Stage disturbances - Z [N] end -%% Translation Stage -load('dist_psd.mat', 'dist_f'); +%% Spindle +if args.enable + % Load the PSD of disturbance + load('ustation_disturbance_psd.mat', 'rz_dist') -% Frequency Data -Rz.f = dist_f.f(2:end); -Rz.psd_x = dist_f.psd_rz(2:end); % TODO - we take here the vertical direction which is wrong but approximate -Rz.psd_y = dist_f.psd_rz(2:end); % TODO - we take here the vertical direction which is wrong but approximate -Rz.psd_z = dist_f.psd_rz(2:end); + % Frequency Data + Rz.f = rz_dist.f; + Rz.psd_x = rz_dist.pxx_fx; + Rz.psd_y = rz_dist.pxx_fy; + Rz.psd_z = rz_dist.pxx_fz; -% Time data -Fs = 2*Rz.f(end); % Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz] -N = 2*length(Rz.f); % Number of Samples match the one of the wanted PSD -T0 = N/Fs; % Signal Duration [s] -Rz.t = linspace(0, T0, N+1)'; % Time Vector [s] + % Time data + Fs = 2*Rz.f(end); % Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz] + N = 2*length(Rz.f); % Number of Samples match the one of the wanted PSD + T0 = N/Fs; % Signal Duration [s] + Rz.t = linspace(0, T0, N+1)'; % Time Vector [s] -C = zeros(N/2,1); -for i = 1:N/2 - C(i) = sqrt(Rz.psd_x(i)/T0); -end - -% Translation Stage - X -if args.Frz_x && args.enable - phi = Rz.psd_x; + % ASD representation of the disturbance voice C = zeros(N/2,1); for i = 1:N/2 - C(i) = sqrt(phi(i)/T0); + C(i) = sqrt(Rz.psd_x(i)/T0); end - theta = 2*pi*rand(N/2,1); % Generate random phase [rad] - Cx = [0 ; C.*complex(cos(theta),sin(theta))]; - Cx = [Cx; flipud(conj(Cx(2:end)))];; - u = N/sqrt(2)*ifft(Cx); % Disturbance Force Rz x [N] - Rz.x = u; -else - Rz.x = zeros(length(Rz.t), 1); -end -% Translation Stage - Y -if args.Frz_y && args.enable - phi = Rz.psd_y; - C = zeros(N/2,1); - for i = 1:N/2 - C(i) = sqrt(phi(i)/T0); + if args.Frz_x + theta = 2*pi*rand(N/2,1); % Generate random phase [rad] + Cx = [0 ; C.*complex(cos(theta),sin(theta))]; + Cx = [Cx; flipud(conj(Cx(2:end)))];; + Rz.x = N/sqrt(2)*ifft(Cx); % spindle disturbances - X direction [N] + else + Rz.x = zeros(length(Rz.t), 1); end - theta = 2*pi*rand(N/2,1); % Generate random phase [rad] - Cx = [0 ; C.*complex(cos(theta),sin(theta))]; - Cx = [Cx; flipud(conj(Cx(2:end)))];; - u = N/sqrt(2)*ifft(Cx); % Disturbance Force Rz y [N] - Rz.y = u; -else - Rz.y = zeros(length(Rz.t), 1); -end -% Translation Stage - Z -if args.Frz_z && args.enable - phi = Rz.psd_z; - C = zeros(N/2,1); - for i = 1:N/2 - C(i) = sqrt(phi(i)/T0); + if args.Frz_y + theta = 2*pi*rand(N/2,1); % Generate random phase [rad] + Cx = [0 ; C.*complex(cos(theta),sin(theta))]; + Cx = [Cx; flipud(conj(Cx(2:end)))];; + Rz.y = N/sqrt(2)*ifft(Cx); % spindle disturbances - Y direction [N] + else + Rz.y = zeros(length(Rz.t), 1); end - theta = 2*pi*rand(N/2,1); % Generate random phase [rad] - Cx = [0 ; C.*complex(cos(theta),sin(theta))]; - Cx = [Cx; flipud(conj(Cx(2:end)))];; - u = N/sqrt(2)*ifft(Cx); % Disturbance Force Rz z [N] - Rz.z = u; + + if args.Frz_z + theta = 2*pi*rand(N/2,1); % Generate random phase [rad] + Cx = [0 ; C.*complex(cos(theta),sin(theta))]; + Cx = [Cx; flipud(conj(Cx(2:end)))];; + Rz.z = N/sqrt(2)*ifft(Cx); % spindle disturbances - Z direction [N] + else + Rz.z = zeros(length(Rz.t), 1); + end + else - Rz.z = zeros(length(Rz.t), 1); + Rz.t = [0,1]; % Time Vector [s] + Rz.x = [0,0]; % Spindle disturbances - X [N] + Rz.y = [0,0]; % Spindle disturbances - X [N] + Rz.z = [0,0]; % Spindle disturbances - Z [N] end u = zeros(100, 6); @@ -208,22 +196,16 @@ Fd = u; Dw.x = Dw.x - Dw.x(1); Dw.y = Dw.y - Dw.y(1); Dw.z = Dw.z - Dw.z(1); -Ty.x = Ty.x - Ty.x(1); -Ty.z = Ty.z - Ty.z(1); + +Dy.x = Dy.x - Dy.x(1); +Dy.z = Dy.z - Dy.z(1); + Rz.x = Rz.x - Rz.x(1); Rz.y = Rz.y - Rz.y(1); Rz.z = Rz.z - Rz.z(1); if exist('./mat', 'dir') - if exist('./mat/nass_disturbances.mat', 'file') - save('mat/nass_disturbances.mat', 'Dw', 'Ty', 'Rz', 'Fd', 'args', '-append'); - else - save('mat/nass_disturbances.mat', 'Dw', 'Ty', 'Rz', 'Fd', 'args'); - end + save('mat/nass_disturbances.mat', 'Dw', 'Dy', 'Rz', 'Fd', 'args'); elseif exist('./matlab', 'dir') - if exist('./matlab/mat/nass_disturbances.mat', 'file') - save('matlab/mat/nass_disturbances.mat', 'Dw', 'Ty', 'Rz', 'Fd', 'args', '-append'); - else - save('matlab/mat/nass_disturbances.mat', 'Dw', 'Ty', 'Rz', 'Fd', 'args'); - end + save('matlab/mat/nass_disturbances.mat', 'Dw', 'Dy', 'Rz', 'Fd', 'args'); end diff --git a/matlab/ustation_simscape.slx b/matlab/ustation_simscape.slx index eb5a532..d78c9b7 100644 Binary files a/matlab/ustation_simscape.slx and b/matlab/ustation_simscape.slx differ diff --git a/simscape-micro-station.bib b/simscape-micro-station.bib index e69de29..a39bdf6 100644 --- a/simscape-micro-station.bib +++ b/simscape-micro-station.bib @@ -0,0 +1,22 @@ +@book{preumont94_random_vibrat_spect_analy, + author = {Andr{\'e} Preumont}, + title = {Random Vibration and Spectral Analysis}, + year = 1994, + publisher = {Springer Netherlands}, + url = {https://doi.org/10.1007/978-94-017-2840-9}, + doi = {10.1007/978-94-017-2840-9}, + series = {Solid Mechanics and Its Applications}, +} + + + +@book{taghirad13_paral, + author = {Taghirad, Hamid}, + title = {Parallel robots : mechanics and control}, + year = 2013, + publisher = {CRC Press}, + address = {Boca Raton, FL}, + isbn = 9781466555778, + keywords = {favorite, parallel robot}, +} + diff --git a/simscape-micro-station.org b/simscape-micro-station.org index 670c7c3..bf27765 100644 --- a/simscape-micro-station.org +++ b/simscape-micro-station.org @@ -279,8 +279,8 @@ Say which disturbances are considered: - Ty: x and z - Rz: z, x and y ? -** TODO [#C] Add screenshot of Simscape model -** TODO [#C] Make a comparison of the measured vibrations of the micro-station with the vibrations of the simscape model of the micro-station +** DONE [#C] Make a comparison of the measured vibrations of the micro-station with the vibrations of the simscape model of the micro-station +CLOSED: [2024-11-06 Wed 12:28] Do we have a correlation? At least in the frequency domain? Procedure: @@ -291,11 +291,8 @@ Procedure: - [ ] Compare with the measured vibrations -** WAIT [#B] I have no measurement of horizontal ground motion :@marc: - -- Wait for Marc reply - -** TODO [#A] Update the disturbances PSD signals +** DONE [#A] Update the disturbances PSD signals +CLOSED: [2024-11-06 Wed 12:28] [[*=initializeDisturbances=: Initialize Disturbances][=initializeDisturbances=: Initialize Disturbances]] @@ -311,6 +308,11 @@ Be able to pass custom =.mat= files (one mat file per disturbance)? - Maybe say that we remove the excentricity (by circle fit: show it in the figure) - Then the rest is modelled by stochastic disturbance +** TODO [#C] Add screenshot of Simscape model +** WAIT [#B] I have no measurement of horizontal ground motion :@marc: + +- Wait for Marc reply + ** Backup - Kinematics *** Frames Let's define the following frames: @@ -535,7 +537,7 @@ The power spectral density of the relative motion is computed below and the resu We can see that this is exactly the same as the Figure ref:fig:dist_effect_relative_motion. #+begin_src matlab psd_gm_d = gm.psd_gm.*abs(squeeze(freqresp(G('Dz', 'Dw')/s, gm.f, 'Hz'))).^2; -psd_ty_d = tyz.psd_f.*abs(squeeze(freqresp(G('Dz', 'Fty')/s, tyz.f, 'Hz'))).^2; +psd_ty_d = tyz.psd_f.*abs(squeeze(freqresp(G('Dz', 'Fdy')/s, tyz.f, 'Hz'))).^2; psd_rz_d = rz.psd_f.*abs(squeeze(freqresp(G('Dz', 'Frz')/s, rz.f, 'Hz'))).^2; #+end_src @@ -576,7 +578,7 @@ legend(); ax2 = subplot(2, 2, 2); hold on; -plot(dist.t, dist.Fty_x, 'DisplayName', '$F_{ty,x}$') +plot(dist.t, dist.Fdy_x, 'DisplayName', '$F_{ty,x}$') hold off; xlabel('Time [s]'); ylabel('Ty Forces [N]'); @@ -584,7 +586,7 @@ legend(); ax3 = subplot(2, 2, 3); hold on; -plot(dist.t, dist.Fty_z, 'DisplayName', '$F_{ty,z}$') +plot(dist.t, dist.Fdy_z, 'DisplayName', '$F_{ty,z}$') hold off; xlabel('Time [s]'); ylabel('Ty Forces [N]'); @@ -645,7 +647,7 @@ No disturbances: Ground Motion: #+begin_src matlab - initializeDisturbances('Fty_x', false, 'Fty_z', false, 'Frz_z', false); + initializeDisturbances('Fdy_x', false, 'Fdy_z', false, 'Frz_x', false, 'Frz_y', false, 'Frz_z', false); sim('nass_model'); sim_gm = simout; #+end_src @@ -659,7 +661,7 @@ Translation Stage Vibrations: Rotation Stage Vibrations: #+begin_src matlab - initializeDisturbances('Dwx', false, 'Dwy', false, 'Dwz', false, 'Fty_x', false, 'Fty_z', false); + initializeDisturbances('Dwx', false, 'Dwy', false, 'Dwz', false, 'Fdy_x', false, 'Fdy_z', false); sim('nass_model'); sim_rz = simout; #+end_src @@ -1277,7 +1279,6 @@ initializeReferences('Dy_amplitude', Dy, ... initializeDisturbances('enable', false); -load('mat/conf_simulink.mat'); set_param(conf_simulink, 'StopTime', '0.5'); % Simulation is performed @@ -1427,8 +1428,8 @@ G_ms.OutputName = {'gtop_x', 'gtop_y', 'gtop_z', 'gtop_rx', 'gtop_ry', 'gtop_rz' 'hexa_x', 'hexa_y', 'hexa_z', 'hexa_rx', 'hexa_ry', 'hexa_rz'}; % Load estimated FRF at CoM -load('/home/thomas/Cloud/work-projects/ID31-NASS/phd-thesis-chapters/A3-micro-station-modal-analysis/matlab/mat/frf_matrix.mat', 'freqs'); -load('/home/thomas/Cloud/work-projects/ID31-NASS/phd-thesis-chapters/A3-micro-station-modal-analysis/matlab/mat/frf_com.mat', 'frfs_CoM'); +load('ustation_frf_matrix.mat', 'freqs'); +load('ustation_frf_com.mat', 'frfs_CoM'); % Initialization of some variables to the figures dirs = {'x', 'y', 'z', 'rx', 'ry', 'rz'}; @@ -1955,28 +1956,68 @@ Vibrations induced by the scanning of the translation stage and of the spindle a The tilt stage and the micro-hexapod also have positioning errors, they are however not modelled here as these two stages are only used for pre-positioning and not for scanning. Therefore, from a control point of view, they are not important. -**** TODO Ground Motion +**** Ground Motion The ground motion is simply measured by using a sensitive 3-axis geophone placed on the ground. The generated voltages are recorded with a high resolution DAC, and converted to displacement using the Geophone sensitivity transfer function. +The obtained ground motion displacement is shown in Figure ref:fig:ustation_ground_disturbance. #+begin_src matlab -%% Ground Motion -% Load measured voltage generated by the geophone in X,Y and Z directions -load('ustation_dist_meas_ground_motion.mat', 'data'); +%% Compute Floor Motion Spectral Density +% Load floor motion data +% t: time in [s] +% V: measured voltage genrated by the geophone and amplified by a 60dB gain voltage amplifier [V] +load('ustation_ground_motion.mat', 't', 'V'); -% Sensitivity of the geophone -S0 = 88; % Sensitivity [V/(m/s)] -f0 = 2; % Cut-off frequency [Hz] +% Geophone Transfer Function +Tg = 88; % Sensitivity [V/(m/s)] +w0 = 2*2*pi; % Cut-off frequency [rad/s] +xi = 0.7; % Damping ratio -S = S0*(s/2/pi/f0)/(1+s/2/pi/f0); +G_geo = Tg*s*s^2/(s^2 + 2*xi*w0*s + w0^2); % Geophone's transfer function [V/m] -% Estimate the velocity and displacement from the measured Voltage -est_vel = lsim(inv(G0*S)*(s/2/pi)/(1+s/2/pi), data(:, 1), data(:, 3)); % Estimated velocity above 1Hz -est_vel = est_vel - mean(est_vel(data(:,3)>10)); % The mean value of the velocity if removed -est_dis = lsim(1/(1+s/2/pi), est_vel, data(:, 3)); % The velocity is integrated above 1Hz +% Voltage amplifier transfer function +g0 = 10^(60/20); % [abs] + +% Compute measured voltage PSD +Ts = (t(2)-t(1)); % Sampling Time [s] +Nfft = floor(2/Ts); +win = hanning(Nfft); +Noverlap = floor(Nfft/2); + +[pxx_V, f_gm] = pwelch(V, win, Noverlap, Nfft, 1/Ts); % [V^2/Hz] + +% Ground Motion ASD +pxx_gm_z = pxx_V./abs(squeeze(freqresp(G_geo*g0, f_gm, 'Hz'))).^2; % [m^2/Hz] +% Assumption here that horizontal ground motion is ~25% smaller +% than vertical one. +pxx_gm_x = (0.7)^2*pxx_gm_z; % [m^2/Hz] +pxx_gm_y = (0.8)^2*pxx_gm_z; % [m^2/Hz] #+end_src +#+begin_src matlab :exports none :results none +% Estimate ground motion +w0_min = 0.1*2*pi; +gm_z = lsim(inv(g0*G_geo)*((s/w0_min)/(1+s/w0_min))^3, detrend(V, 0), t); + +%% Measured ground motion +figure; +hold on; +plot(t(t>50)-50, 1e6*gm_z(t>50)) +hold off; +xlabel('Time [s]'); +ylabel('Vertical motion [$\mu$m]') +#+end_src + +#+begin_src matlab :tangle no :exports results :results file replace +exportFig('figs/ustation_ground_disturbance.pdf', 'width', 'wide', 'height', 'normal'); +#+end_src + +#+name: fig:ustation_ground_disturbance +#+caption: Measured ground motion +#+RESULTS: +[[file:figs/ustation_ground_disturbance.png]] + **** Ty Stage To measure the positioning errors of the translation stage, the setup shown in Figure ref:fig:ustation_errors_ty_setup is used. @@ -2070,6 +2111,10 @@ Noverlap = floor(Nfft/2); % Overlap for frequency analysis % Comnpute the power spectral density [pxx_dy_dz, f_dy] = pwelch(1e-6*detrend(ty_errors.ty_z, 1), win, Noverlap, Nfft, Fs); pxx_dy_dz = mean(pxx_dy_dz')'; + +% Having the PSD of the lateral error equal to the PSD of the vertical error +% is a reasonable assumption (and verified in practice) +pxx_dy_dx = pxx_dy_dz; #+end_src **** Spindle @@ -2099,7 +2144,10 @@ From the 5 measured displacements $[d_1,\,d_2,\,d_3,\,d_4,\,d_5]$, the translati A measurement is performed at 60rpm during 10 turns, and the obtained results are shown in Figure ref:fig:ustation_errors_spindle. A fraction of the radial (Figure ref:fig:ustation_errors_spindle_radial) and tilt (Figure ref:fig:ustation_errors_spindle_tilt) errors is linked to the fact that the two spheres are not perfectly aligned with the rotation axis of the Spindle. -However, it is in practice very difficult to align the "point-of-interest" of the sample with the rotation axis, so the NASS will be used to actively keep the PoI on the rotation axis. +This is displayed by the dashed circle. +After removing the best circular fit from the data, the vibrations induced by the Spindle may be viewed as stochastic disturbances. +However, some misalignment between the "point-of-interest" of the sample with the rotation axis will be considered as it is very difficult to align in practice. +The NASS will be used to actively keep the PoI on the rotation axis. The vertical motion induced by the scanning of the spindle is in the order of $\pm 30\,nm$ (Figure ref:fig:ustation_errors_spindle_axial). #+begin_src matlab @@ -2112,19 +2160,27 @@ spindle_errors = load('ustation_errors_spindle.mat'); #+begin_src matlab :exports none :results none %% Measured radial errors of the Spindle figure; -plot(1e6*spindle_errors.Dx(1:100:end), 1e6*spindle_errors.Dy(1:100:end)) +hold on; +plot(1e6*spindle_errors.Dx(1:100:end), 1e6*spindle_errors.Dy(1:100:end), 'DisplayName', 'Raw data') +% Compute best fitting circle +[x0, y0, R] = circlefit(spindle_errors.Dx, spindle_errors.Dy); +theta = linspace(0, 2*pi, 500); % Angle to plot the circle [rad] +plot(1e6*(x0 + R*cos(theta)), 1e6*(y0 + R*sin(theta)), '--', 'DisplayName', 'Best Fit') +hold off; xlabel('X displacement [$\mu$m]'); ylabel('Y displacement [$\mu$m]'); axis equal xlim([-1, 1]); ylim([-1, 1]); xticks([-1, -0.5, 0, 0.5, 1]); yticks([-1, -0.5, 0, 0.5, 1]); +leg = legend('location', 'none', 'FontSize', 8, 'NumColumns', 1); +leg.ItemTokenSize(1) = 15; #+end_src #+begin_src matlab :tangle no :exports results :results file none exportFig('figs/ustation_errors_spindle_radial.pdf', 'width', 'third', 'height', 'normal'); #+end_src -#+begin_src matlab +#+begin_src matlab :exports none :results none %% Measured axial errors of the Spindle figure; plot(spindle_errors.deg(1:100:end)/360, 1e9*spindle_errors.Dz(1:100:end)) @@ -2153,7 +2209,7 @@ exportFig('figs/ustation_errors_spindle_tilt.pdf', 'width', 'third', 'height', ' #+end_src #+name: fig:ustation_errors_spindle -#+caption: Measurement of the radial (\subref{fig:ustation_errors_spindle_radial}), axial (\subref{fig:ustation_errors_spindle_axial}) and tilt (\subref{fig:ustation_errors_spindle_tilt}) Spindle errors during a 60rpm spindle rotation. +#+caption: Measurement of the radial (\subref{fig:ustation_errors_spindle_radial}), axial (\subref{fig:ustation_errors_spindle_axial}) and tilt (\subref{fig:ustation_errors_spindle_tilt}) Spindle errors during a 60rpm spindle rotation. A circular best fit is shown by the dashed circle. It represents the misalignment of the spheres with the rotation axis. #+attr_latex: :options [htbp] #+begin_figure #+attr_latex: :caption \subcaption{\label{fig:ustation_errors_spindle_radial}Radial errors} @@ -2177,6 +2233,18 @@ exportFig('figs/ustation_errors_spindle_tilt.pdf', 'width', 'third', 'height', ' #+end_figure #+begin_src matlab +%% Remove the circular fit from the data +[x0, y0, R] = circlefit(spindle_errors.Dx, spindle_errors.Dy); + +% Search the best angular match +fun = @(theta)rms((spindle_errors.Dx - (x0 + R*cos(pi/180*spindle_errors.deg+theta(1)))).^2 + (spindle_errors.Dy - (y0 - R*sin(pi/180*spindle_errors.deg+theta(1)))).^2); +x0 = [0]; +delta_theta = fminsearch(fun, 0) + +% Compute the remaining error after removing the best circular fit +spindle_errors.Dx_err = spindle_errors.Dx - (x0 + R*cos(pi/180*spindle_errors.deg+delta_theta)); +spindle_errors.Dy_err = spindle_errors.Dy - (y0 - R*sin(pi/180*spindle_errors.deg+delta_theta)); + %% Convert the data to frequency domain Ts = (spindle_errors.t(end) - spindle_errors.t(1))/(length(spindle_errors.t)-1); % [s] Fs = 1/Ts; % [Hz] @@ -2187,11 +2255,9 @@ win = hanning(Nfft); % Windowing Noverlap = floor(Nfft/2); % Overlap for frequency analysis % Comnpute the power spectral density -[pxx_rz_dz, f_rz] = pwelch(spindle_errors.Dz, win, Noverlap, Nfft, Fs); -[pxx_rz_dx, ~ ] = pwelch(spindle_errors.Dx, win, Noverlap, Nfft, Fs); -[pxx_rz_dy, ~ ] = pwelch(spindle_errors.Dy, win, Noverlap, Nfft, Fs); -[pxx_rz_rx, ~ ] = pwelch(spindle_errors.Rx, win, Noverlap, Nfft, Fs); -[pxx_rz_ry, ~ ] = pwelch(spindle_errors.Ry, win, Noverlap, Nfft, Fs); +[pxx_rz_dz, f_rz] = pwelch(spindle_errors.Dz, win, Noverlap, Nfft, Fs); +[pxx_rz_dx, ~ ] = pwelch(spindle_errors.Dx_err, win, Noverlap, Nfft, Fs); +[pxx_rz_dy, ~ ] = pwelch(spindle_errors.Dy_err, win, Noverlap, Nfft, Fs); #+end_src ** Sensitivity to disturbances @@ -2211,7 +2277,7 @@ initializeRy(); initializeRz(); initializeMicroHexapod(); -initializeDisturbances(); +initializeDisturbances('enable', false); initializeSimscapeConfiguration('gravity', false); initializeLoggingConfiguration(); @@ -2220,8 +2286,8 @@ clear io; io_i = 1; io(io_i) = linio([mdl, '/Disturbances/Dwx'], 1, 'openinput'); io_i = io_i + 1; % Vertical Ground Motion io(io_i) = linio([mdl, '/Disturbances/Dwy'], 1, 'openinput'); io_i = io_i + 1; % Vertical Ground Motion io(io_i) = linio([mdl, '/Disturbances/Dwz'], 1, 'openinput'); io_i = io_i + 1; % Vertical Ground Motion -io(io_i) = linio([mdl, '/Disturbances/Fty_x'], 1, 'openinput'); io_i = io_i + 1; % Parasitic force Ty -io(io_i) = linio([mdl, '/Disturbances/Fty_z'], 1, 'openinput'); io_i = io_i + 1; % Parasitic force Ty +io(io_i) = linio([mdl, '/Disturbances/Fdy_x'], 1, 'openinput'); io_i = io_i + 1; % Parasitic force Ty +io(io_i) = linio([mdl, '/Disturbances/Fdy_z'], 1, 'openinput'); io_i = io_i + 1; % Parasitic force Ty io(io_i) = linio([mdl, '/Disturbances/Frz_x'], 1, 'openinput'); io_i = io_i + 1; % Parasitic force Rz io(io_i) = linio([mdl, '/Disturbances/Frz_y'], 1, 'openinput'); io_i = io_i + 1; % Parasitic force Rz io(io_i) = linio([mdl, '/Disturbances/Frz_z'], 1, 'openinput'); io_i = io_i + 1; % Parasitic force Rz @@ -2231,7 +2297,7 @@ io(io_i) = linio([mdl, '/Micro-Station/metrology_6dof/z'], 1, 'openoutput'); io_ % Run the linearization Gd = linearize(mdl, io, 0); -Gd.InputName = {'Dwx', 'Dwy', 'Dwz', 'Fty_x', 'Fty_z', 'Frz_x', 'Frz_y', 'Frz_z'}; +Gd.InputName = {'Dwx', 'Dwy', 'Dwz', 'Fdy_x', 'Fdy_z', 'Frz_x', 'Frz_y', 'Frz_z'}; Gd.OutputName = {'Dx', 'Dy', 'Dz'}; #+end_src @@ -2269,8 +2335,8 @@ exportFig('figs/ustation_model_sensitivity_ground_motion.pdf', 'width', 'third', %% Sensitivity to Translation stage disturbance forces figure; hold on; -plot(freqs, abs(squeeze(freqresp(Gd('Dx', 'Fty_x'), freqs, 'Hz'))), 'color', colors(1,:), 'DisplayName', '$D_x/F_{xD_y}$'); -plot(freqs, abs(squeeze(freqresp(Gd('Dz', 'Fty_z'), freqs, 'Hz'))), 'color', colors(3,:), 'DisplayName', '$D_z/F_{zD_y}$'); +plot(freqs, abs(squeeze(freqresp(Gd('Dx', 'Fdy_x'), freqs, 'Hz'))), 'color', colors(1,:), 'DisplayName', '$D_x/F_{xD_y}$'); +plot(freqs, abs(squeeze(freqresp(Gd('Dz', 'Fdy_z'), freqs, 'Hz'))), 'color', colors(3,:), 'DisplayName', '$D_z/F_{zD_y}$'); hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Amplitude [m/N]'); xlabel('Frequency [Hz]'); @@ -2326,43 +2392,212 @@ exportFig('figs/ustation_model_sensitivity_rz.pdf', 'width', 'third', 'height', #+end_subfigure #+end_figure -** TODO Obtained disturbance sources +** Obtained disturbance sources <> -- [ ] Display PSD of disturbances +From the measured effect of disturbances in Section ref:ssec:ustation_disturbances_meas and the sensitivity to disturbances extracted from the Simscape model in Section ref:ssec:ustation_disturbances_sensitivity, the power spectral density of the disturbance sources (i.e. forces applied in the stage's joint) can be estimated. +They are shown in Figure ref:fig:ustation_dist_sources. #+begin_src matlab -rz.psd_f = rz.pxsp_r./abs(squeeze(freqresp(G('Dz', 'Frz'), rz.f, 'Hz'))).^2; -tyz.psd_f = tyz.pxz_ty_r./abs(squeeze(freqresp(G('Dz', 'Fty'), tyz.f, 'Hz'))).^2; +%% Compute the PSD of the equivalent disturbance sources +pxx_rz_fx = pxx_rz_dx./abs(squeeze(freqresp(Gd('Dx', 'Frz_x'), f_rz, 'Hz'))).^2; +pxx_rz_fy = pxx_rz_dy./abs(squeeze(freqresp(Gd('Dy', 'Frz_y'), f_rz, 'Hz'))).^2; +pxx_rz_fz = pxx_rz_dz./abs(squeeze(freqresp(Gd('Dz', 'Frz_z'), f_rz, 'Hz'))).^2; + +pxx_dy_fx = pxx_dy_dx./abs(squeeze(freqresp(Gd('Dx', 'Fdy_x'), f_dy, 'Hz'))).^2; +pxx_dy_fz = pxx_dy_dz./abs(squeeze(freqresp(Gd('Dz', 'Fdy_z'), f_dy, 'Hz'))).^2; + +%% Save the PSD of the disturbance sources for further used +% in the Simscape model + +% Ground motion +min_f = 1; max_f = 500; +gm_dist.f = f_gm(f_gm < max_f & f_gm > min_f); +gm_dist.pxx_x = pxx_gm_x(f_gm < max_f & f_gm > min_f); +gm_dist.pxx_y = pxx_gm_y(f_gm < max_f & f_gm > min_f); +gm_dist.pxx_z = pxx_gm_z(f_gm < max_f & f_gm > min_f); + +% Translation stage +min_f = 0.5; max_f = 500; +dy_dist.f = f_dy(f_dy < max_f & f_dy > min_f); +dy_dist.pxx_fx = pxx_dy_fx(f_dy < max_f & f_dy > min_f); +dy_dist.pxx_fz = pxx_dy_fz(f_dy < max_f & f_dy > min_f); + +% Spindle +min_f = 1; max_f = 500; +rz_dist.f = f_rz(f_rz < max_f & f_rz > min_f); +rz_dist.pxx_fx = pxx_rz_fx(f_rz < max_f & f_rz > min_f); +rz_dist.pxx_fy = pxx_rz_fy(f_rz < max_f & f_rz > min_f); +rz_dist.pxx_fz = pxx_rz_fz(f_rz < max_f & f_rz > min_f); #+end_src -#+begin_src matlab -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] - -save('./mat/dist_psd.mat', 'dist_f'); +#+begin_src matlab :exports none :tangle no +% The identified dynamics are then saved for further use. +save('matlab/mat/ustation_disturbance_psd.mat', 'rz_dist', 'dy_dist', 'gm_dist') #+end_src -The obtained amplitude spectral densities of the disturbance forces are shown in Figure ref:fig:dist_force_psd. +#+begin_src matlab :eval no +% The identified dynamics are then saved for further use. +save('./mat/ustation_disturbance_psd.mat', 'rz_dist', 'dy_dist', 'gm_dist') +#+end_src -#+begin_src matlab :exports none +#+begin_src matlab :exports none :results none +%% Ground Motion 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; +plot(f_gm, sqrt(pxx_gm_x), 'DisplayName', '$D_{wx}$'); +plot(f_gm, sqrt(pxx_gm_y), 'DisplayName', '$D_{wy}$'); +plot(f_gm, sqrt(pxx_gm_z), 'DisplayName', '$D_{wz}$'); set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log'); -xlabel('Frequency [Hz]'); ylabel('ASD of the disturbance force $\left[\frac{N}{\sqrt{Hz}}\right]$') -legend('Location', 'southwest'); -xlim([2, 500]); +xlabel('Frequency [Hz]'); ylabel('Spectral Density $\left[\frac{m}{\sqrt{Hz}}\right]$') +xlim([1, 200]); +leg = legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 1); +leg.ItemTokenSize(1) = 15; #+end_src +#+begin_src matlab :tangle no :exports results :results file none +exportFig('figs/ustation_dist_source_ground_motion.pdf', 'width', 'third', 'height', 'normal'); +#+end_src + +#+begin_src matlab :exports none :results none +figure; +hold on; +plot(f_dy, sqrt(pxx_dy_fx), 'DisplayName', '$F_{xD_y}$'); +plot(f_dy, sqrt(pxx_dy_fz), 'DisplayName', '$F_{zD_y}$'); +set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log'); +xlabel('Frequency [Hz]'); ylabel('Spectral Density $\left[\frac{N}{\sqrt{Hz}}\right]$') +xlim([1, 200]); ylim([1e-3, 1e3]); +leg = legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 1); +leg.ItemTokenSize(1) = 15; +#+end_src + +#+begin_src matlab :tangle no :exports results :results file none +exportFig('figs/ustation_dist_source_translation_stage.pdf', 'width', 'third', 'height', 'normal'); +#+end_src + +#+begin_src matlab :exports none :results none +figure; +hold on; +plot(f_rz, sqrt(pxx_rz_fx), 'DisplayName', '$F_{xR_z}$'); +plot(f_rz, sqrt(pxx_rz_fy), 'DisplayName', '$F_{yR_z}$'); +plot(f_rz, sqrt(pxx_rz_fz), 'DisplayName', '$F_{zR_z}$'); +set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log'); +xlabel('Frequency [Hz]'); ylabel('Spectral Density $\left[\frac{N}{\sqrt{Hz}}\right]$') +xlim([1, 200]); ylim([1e-3, 1e3]); +leg = legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 1); +leg.ItemTokenSize(1) = 15; +#+end_src + +#+begin_src matlab :tangle no :exports results :results file none +exportFig('figs/ustation_dist_source_spindle.pdf', 'width', 'third', 'height', 'normal'); +#+end_src + +#+name: fig:ustation_dist_sources +#+caption: Measured spectral density of the micro-station disturbances sources. Ground motion (\subref{fig:ustation_dist_source_ground_motion}), translation stage (\subref{fig:ustation_dist_source_translation_stage}) and spindle (\subref{fig:ustation_dist_source_spindle}). +#+attr_latex: :options [htbp] +#+begin_figure +#+attr_latex: :caption \subcaption{\label{fig:ustation_dist_source_ground_motion}Ground Motion} +#+attr_latex: :options {0.33\textwidth} +#+begin_subfigure +#+attr_latex: :width 0.9\linewidth +[[file:figs/ustation_dist_source_ground_motion.png]] +#+end_subfigure +#+attr_latex: :caption \subcaption{\label{fig:ustation_dist_source_translation_stage}Translation Stage} +#+attr_latex: :options {0.33\textwidth} +#+begin_subfigure +#+attr_latex: :width 0.9\linewidth +[[file:figs/ustation_dist_source_translation_stage.png]] +#+end_subfigure +#+attr_latex: :caption \subcaption{\label{fig:ustation_dist_source_spindle}Spindle} +#+attr_latex: :options {0.33\textwidth} +#+begin_subfigure +#+attr_latex: :width 0.9\linewidth +[[file:figs/ustation_dist_source_spindle.png]] +#+end_subfigure +#+end_figure + +The disturbances are characterized by their power spectral densities as shown in Figure ref:fig:ustation_dist_sources. +However, in order to perform time domain simulations, disturbances needs to be represented by a time domain. +In order to generate stochastic time domain signals having the same power spectral densities as the ones estimated, the discrete inverse Fourier transform is used as explained in [[cite:&preumont94_random_vibrat_spect_analy chap. 12.11]]. +Examples of obtained time domain disturbance signals are shown in Figure ref:fig:ustation_dist_sources_time. + +#+begin_src matlab +%% Compute time domain disturbance signals +initializeDisturbances(); +load('nass_model_disturbances.mat'); +#+end_src + +#+begin_src matlab :exports none :results none +figure; +hold on; +plot(Rz.t, Rz.x, 'DisplayName', '$F_{xR_z}$'); +plot(Rz.t, Rz.y, 'DisplayName', '$F_{yR_z}$'); +plot(Rz.t, Rz.z, 'DisplayName', '$F_{zR_z}$'); +xlabel('Time [s]'); ylabel('Amplitude [N]') +xlim([0, 1]); ylim([-100, 100]); +leg = legend('location', 'northwest', 'FontSize', 8, 'NumColumns', 1); +leg.ItemTokenSize(1) = 15; +#+end_src + +#+begin_src matlab :tangle no :exports results :results file none +exportFig('figs/ustation_dist_source_spindle_time.pdf', 'width', 'third', 'height', 'normal'); +#+end_src + +#+begin_src matlab :exports none :results none +figure; +hold on; +plot(Dy.t, Dy.x, 'DisplayName', '$F_{xD_y}$'); +plot(Dy.t, Dy.z, 'DisplayName', '$F_{zD_y}$'); +xlabel('Time [s]'); ylabel('Amplitude [N]') +xlim([0, 1]); ylim([-60, 60]) +leg = legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 1); +leg.ItemTokenSize(1) = 15; +#+end_src + +#+begin_src matlab :tangle no :exports results :results file none +exportFig('figs/ustation_dist_source_translation_stage_time.pdf', 'width', 'third', 'height', 'normal'); +#+end_src + +#+begin_src matlab :exports none :results none +figure; +hold on; +plot(Dw.t, 1e6*Dw.x, 'DisplayName', '$D_{xf}$'); +plot(Dw.t, 1e6*Dw.y, 'DisplayName', '$D_{yf}$'); +plot(Dw.t, 1e6*Dw.z, 'DisplayName', '$D_{zf}$'); +xlabel('Time [s]'); ylabel('Amplitude [$\mu$m]') +xlim([0, 1]); ylim([-0.15, 0.15]) +leg = legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 1); +leg.ItemTokenSize(1) = 15; +#+end_src + +#+begin_src matlab :tangle no :exports results :results file none +exportFig('figs/ustation_dist_source_ground_motion_time.pdf', 'width', 'third', 'height', 'normal'); +#+end_src + +#+name: fig:ustation_dist_sources_time +#+caption: Generated time domain disturbance signals. Ground motion (\subref{fig:ustation_dist_source_ground_motion_time}), translation stage (\subref{fig:ustation_dist_source_translation_stage_time}) and spindle (\subref{fig:ustation_dist_source_spindle_time}). +#+attr_latex: :options [htbp] +#+begin_figure +#+attr_latex: :caption \subcaption{\label{fig:ustation_dist_source_ground_motion_time}Ground Motion} +#+attr_latex: :options {0.33\textwidth} +#+begin_subfigure +#+attr_latex: :width 0.9\linewidth +[[file:figs/ustation_dist_source_ground_motion_time.png]] +#+end_subfigure +#+attr_latex: :caption \subcaption{\label{fig:ustation_dist_source_translation_stage_time}Translation Stage} +#+attr_latex: :options {0.33\textwidth} +#+begin_subfigure +#+attr_latex: :width 0.9\linewidth +[[file:figs/ustation_dist_source_translation_stage_time.png]] +#+end_subfigure +#+attr_latex: :caption \subcaption{\label{fig:ustation_dist_source_spindle_time}Spindle} +#+attr_latex: :options {0.33\textwidth} +#+begin_subfigure +#+attr_latex: :width 0.9\linewidth +[[file:figs/ustation_dist_source_spindle_time.png]] +#+end_subfigure +#+end_figure + * Simulation of Scientific Experiments :PROPERTIES: :HEADER-ARGS:matlab+: :tangle matlab/ustation_4_experiments.m @@ -2371,23 +2606,6 @@ xlim([2, 500]); ** Introduction :ignore: -- [ ] Perfect tomography => no error -- [ ] Add vibrations and some off-center => results, compare with measurements -- [ ] Ty scans (-4.5mm to 4.5mm) => compare with measurements - -# The goal here is to simulate some scientific experiments with the Simscape model when no control is applied to the nano-hexapod. - -# This has several goals: -# - Validate the model -# - Estimate the expected error motion for the experiments -# - Estimate the stroke that we may need for the nano-hexapod -# - Compare with experiments when control is applied - -# The document in organized as follow: -# - In section ref:sec:tomo_no_dist a tomography experiment is performed where the sample is aligned with the rotation axis. No disturbance is included -# - In section ref:sec:tomo_dist, the same is done but with disturbance included -# - In section ref:sec:tomo_hexa_trans the micro-hexapod translate the sample such that its center of mass is no longer aligned with the rotation axis. No disturbance is included -# - In section ref:sec:ty_scans, scans with the translation stage are simulated with no perturbation included ** Matlab Init :noexport:ignore: #+begin_src matlab @@ -2414,11 +2632,19 @@ xlim([2, 500]); <> #+end_src +** Tomography Experiment +60rpm +ground motion + spindle vibrations +Measurement of the PoI position with respect to the granite +Results are shown in Figure ref:fig:ustation_errors_model_spindle. +Great match with measurements of Figure ref:fig:ustation_errors_spindle. -** Tomography Experiment with no disturbances #+begin_src matlab -%% Prepare the Simscape model for simulation -load('mat/conf_simulink.mat'); +%% Tomography experiment +% Sample is not centered with the rotation axis +% This is done by offsetfing the micro-hexapod by 0.9um +P_micro_hexapod = [0.9e-6; 0; 0]; % [m] + set_param(conf_simulink, 'StopTime', '10'); initializeGround(); @@ -2426,52 +2652,103 @@ initializeGranite(); initializeTy(); initializeRy(); initializeRz(); -initializeMicroHexapod(); +initializeMicroHexapod('AP', P_micro_hexapod); initializeSimscapeConfiguration('gravity', false); initializeLoggingConfiguration('log', 'all'); -#+end_src -#+begin_src matlab -%% First, perform "perfect tomography experiment" initializeDisturbances(... - 'Dwx', false, ... % Ground Motion - X direction - 'Dwy', false, ... % Ground Motion - Y direction - 'Dwz', false, ... % Ground Motion - Z direction - 'Fty_x', false, ... % Translation Stage - X direction - 'Fty_z', false, ... % Translation Stage - Z direction - 'Frz_x', false, ... % Spindle - X direction - 'Frz_y', false, ... % Spindle - Y direction - 'Frz_z', false); % Spindle - Z direction + 'Dw_x', true, ... % Ground Motion - X direction + 'Dw_y', true, ... % Ground Motion - Y direction + 'Dw_z', true, ... % Ground Motion - Z direction + 'Fdy_x', false, ... % Translation Stage - X direction + 'Fdy_z', false, ... % Translation Stage - Z direction + 'Frz_x', true, ... % Spindle - X direction + 'Frz_y', true, ... % Spindle - Y direction + 'Frz_z', true); % Spindle - Z direction initializeReferences(... 'Rz_type', 'rotating', ... - 'Rz_period', 1); + 'Rz_period', 1, ... + 'Dh_pos', [P_micro_hexapod; 0; 0; 0]); -sim(mdl) -tomo_align_no_dist = simout; +sim(mdl); +exp_tomography = simout; #+end_src #+begin_src matlab -start_t = 5; +%% Compare with the measurements +spindle_errors = load('ustation_errors_spindle.mat'); #+end_src -#+begin_src matlab :exports none +#+begin_src matlab :exports none :results none +%% Measured radial errors of the Spindle figure; hold on; -plot(tomo_align_no_dist.y.x.Time(1e3*start_t+1:end)-start_t, 1e9*tomo_align_no_dist.y.x.Data(1e3*start_t+1:end)) -plot(tomo_align_no_dist.y.y.Time(1e3*start_t+1:end)-start_t, 1e9*tomo_align_no_dist.y.y.Data(1e3*start_t+1:end)) -plot(tomo_align_no_dist.y.z.Time(1e3*start_t+1:end)-start_t, 1e9*detrend(tomo_align_no_dist.y.z.Data(1e3*start_t+1:end), 0)) +plot(1e6*spindle_errors.Dx(1:100:end), 1e6*spindle_errors.Dy(1:100:end), 'DisplayName', 'Measurements') +plot(1e6*exp_tomography.y.x.Data, 1e6*exp_tomography.y.y.Data, 'DisplayName', 'Simulation') hold off; -xlabel('Time [s]'); -ylabel('Error [nm]') +xlabel('X displacement [$\mu$m]'); ylabel('Y displacement [$\mu$m]'); +axis equal +xlim([-1, 1]); ylim([-1, 1]); +xticks([-1, -0.5, 0, 0.5, 1]); +yticks([-1, -0.5, 0, 0.5, 1]); +leg = legend('location', 'none', 'FontSize', 8, 'NumColumns', 1); +leg.ItemTokenSize(1) = 15; #+end_src -** Tomography Experiment with included disturbances +#+begin_src matlab :tangle no :exports results :results file none +exportFig('figs/ustation_errors_model_spindle_radial.pdf', 'width', 'half', 'height', 'normal'); +#+end_src + +#+begin_src matlab :exports none :results none +%% Measured axial errors of the Spindle +figure; +hold on; +plot(spindle_errors.deg(1:100:end)/360, 1e9*spindle_errors.Dz(1:100:end), 'DisplayName', 'Measurements') +plot(exp_tomography.y.z.Time, 1e9*exp_tomography.y.z.Data, 'DisplayName', 'Simulation') +hold off; +xlabel('Rotation [turn]'); ylabel('Z displacement [nm]'); +axis square +xlim([0,2]); ylim([-40, 40]); +leg = legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 1); +leg.ItemTokenSize(1) = 15; +#+end_src + +#+begin_src matlab :tangle no :exports results :results file none +exportFig('figs/ustation_errors_model_spindle_axial.pdf', 'width', 'half', 'height', 'normal'); +#+end_src + +#+name: fig:ustation_errors_model_spindle +#+caption: Measurement of strut flexible modes +#+attr_latex: :options [htbp] +#+begin_figure +#+attr_latex: :caption \subcaption{\label{fig:ustation_errors_model_spindle_radial}Radial error} +#+attr_latex: :options {0.49\textwidth} +#+begin_subfigure +#+attr_latex: :scale 1 +[[file:figs/ustation_errors_model_spindle_radial.png]] +#+end_subfigure +#+attr_latex: :caption \subcaption{\label{fig:ustation_errors_model_spindle_axial}Axial error} +#+attr_latex: :options {0.49\textwidth} +#+begin_subfigure +#+attr_latex: :scale 1 +[[file:figs/ustation_errors_model_spindle_axial.png]] +#+end_subfigure +#+end_figure + +** Raster Scans with the translation stage + + ++/-5mm constant velocity scans. +ground motion + translation stage vibrations +Measurement of the PoI position with respect to the granite +Results are shown in Figure ref:fig:ustation_errors_model_spindle. +Great match with measurements of Figure ref:fig:ustation_errors_spindle. + #+begin_src matlab -%% Prepare the Simscape model for simulation -load('mat/conf_simulink.mat'); -set_param(conf_simulink, 'StopTime', '2'); +%% Translation stage latteral scans +set_param(conf_simulink, 'StopTime', '4'); initializeGround(); initializeGranite(); @@ -2484,75 +2761,65 @@ initializeSimscapeConfiguration('gravity', false); initializeLoggingConfiguration('log', 'all'); initializeDisturbances(... - 'Dwx', true, ... % Ground Motion - X direction - 'Dwy', true, ... % Ground Motion - Y direction - 'Dwz', true, ... % Ground Motion - Z direction - 'Fty_x', false, ... % Translation Stage - X direction - 'Fty_z', false, ... % Translation Stage - Z direction - 'Frz_x', true, ... % Spindle - X direction - 'Frz_y', true, ... % Spindle - Y direction - 'Frz_z', true); % Spindle - Z direction - -initializeReferences(... - 'Rz_type', 'rotating', ... - 'Rz_period', 1); - -sim(mdl) -tomo_align_dist = simout; -#+end_src - -#+begin_src matlab :exports none -figure; -hold on; -plot(tomo_align_dist.y.x.Time, 1e6*tomo_align_dist.y.x.Data) -plot(tomo_align_dist.y.y.Time, 1e6*tomo_align_dist.y.y.Data) -plot(tomo_align_dist.y.z.Time, 1e6*tomo_align_dist.y.z.Data) -hold off; -#+end_src - -** Tomography when the micro-hexapod is not centered -#+begin_src matlab -%% Tomography when the micro-hexapod is not centered by 1um -P_micro_hexapod = [1e-6; 0; 0]; % [m] -initializeMicroHexapod('AP', P_micro_hexapod); - -initializeDisturbances(... - 'Dwx', false, ... % Ground Motion - X direction - 'Dwy', false, ... % Ground Motion - Y direction - 'Dwz', false, ... % Ground Motion - Z direction - 'Fty_x', false, ... % Translation Stage - X direction - 'Fty_z', false, ... % Translation Stage - Z direction + 'Dw_x', true, ... % Ground Motion - X direction + 'Dw_y', true, ... % Ground Motion - Y direction + 'Dw_z', true, ... % Ground Motion - Z direction + 'Fdy_x', true, ... % Translation Stage - X direction + 'Fdy_z', true, ... % Translation Stage - Z direction 'Frz_x', false, ... % Spindle - X direction 'Frz_y', false, ... % Spindle - Y direction 'Frz_z', false); % Spindle - Z direction initializeReferences(... - 'Rz_type', 'rotating', ... - 'Rz_period', 1, ... - 'Dh_pos', [P_micro_hexapod; 0; 0; 0]); + 'Dy_type', 'triangular', ... + 'Dy_amplitude', 5e-3, ... + 'Dy_period', 4); sim(mdl); -tomo_not_align = simout; +exp_latteral_scans = simout; #+end_src -#+begin_src matlab :exports none +#+begin_src matlab +%% Load the experimentally measured errors +ty_errors = load('ustation_errors_ty.mat'); + +% Compute best straight line to remove it from data +average_error = mean(ty_errors.ty_z')'; +straight_line = average_error - detrend(average_error, 1); +#+end_src + +#+begin_src matlab :exports none :results none figure; hold on; -plot(1e6*tomo_not_align.y.x.Data, 1e6*tomo_not_align.y.y.Data) +plot(ty_errors.setpoint, ty_errors.ty_z(:,1) - straight_line, 'DisplayName', 'Measurement') +plot(1e3*exp_latteral_scans.y.y.Data, 1e6*exp_latteral_scans.y.z.Data, 'DisplayName', 'Simulation') hold off; +xlabel('$D_y$ position [mm]'); ylabel('Vertical error [$\mu$m]'); +xlim([-5, 5]); ylim([-0.4, 0.4]); +leg = legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 1); +leg.ItemTokenSize(1) = 15; #+end_src -** Raster Scans with the translation stage -#+begin_src matlab -initializeReferences('Dy_type', 'triangular', 'Dy_amplitude', 10e-3, 'Dy_period', 1); -sim(mdl); -ty_scan_triangle = simout; -% save('./mat/experiment_tomography.mat', 'ty_scan_triangle', '-append'); +#+begin_src matlab :tangle no :exports results :results file none +xticks([-5:1:5]); yticks([-0.4:0.1:0.4]); +exportFig('figs/ustation_errors_model_dy_vertical.pdf', 'width', 'half', 'height', 'normal'); #+end_src +#+name: fig:ustation_errors_model_dy_vertical +#+caption: Figure caption +[[file:figs/ustation_errors_model_dy_vertical.png]] + * Conclusion <> +In order to have good model: +- kinematics +- dynamics +- disturbances + +Validated with time domain simulations. + + * Bibliography :ignore: #+latex: \printbibliography[heading=bibintoc,title={Bibliography}] @@ -2584,7 +2851,7 @@ addpath('./subsystems/'); % Path for Subsystems Simulink files % Simulink Model name mdl = 'ustation_simscape'; -load('conf_simulink.mat'); +load('nass_model_conf_simulink.mat'); #+end_src ** Initialize other elements @@ -2633,16 +2900,16 @@ freqs = logspace(log10(10), log10(2e3), 1000); *** Save the Structure #+begin_src matlab if exist('./mat', 'dir') - if exist('./mat/conf_simscape.mat', 'file') - save('mat/conf_simscape.mat', 'conf_simscape', '-append'); + if exist('./mat/nass_model_conf_simscape.mat', 'file') + save('mat/nass_model_conf_simscape.mat', 'conf_simscape', '-append'); else - save('mat/conf_simscape.mat', 'conf_simscape'); + save('mat/nass_model_conf_simscape.mat', 'conf_simscape'); end elseif exist('./matlab', 'dir') - if exist('./matlab/mat/conf_simscape.mat', 'file') - save('matlab/mat/conf_simscape.mat', 'conf_simscape', '-append'); + if exist('./matlab/mat/nass_model_conf_simscape.mat', 'file') + save('matlab/mat/nass_model_conf_simscape.mat', 'conf_simscape', '-append'); else - save('matlab/mat/conf_simscape.mat', 'conf_simscape'); + save('matlab/mat/nass_model_conf_simscape.mat', 'conf_simscape'); end end #+end_src @@ -2691,16 +2958,16 @@ end *** Save the Structure #+begin_src matlab if exist('./mat', 'dir') - if exist('./mat/conf_log.mat', 'file') - save('mat/conf_log.mat', 'conf_log', '-append'); + if exist('./mat/nass_model_conf_log.mat', 'file') + save('mat/nass_model_conf_log.mat', 'conf_log', '-append'); else - save('mat/conf_log.mat', 'conf_log'); + save('mat/nass_model_conf_log.mat', 'conf_log'); end elseif exist('./matlab', 'dir') - if exist('./matlab/mat/conf_log.mat', 'file') - save('matlab/mat/conf_log.mat', 'conf_log', '-append'); + if exist('./matlab/mat/nass_model_conf_log.mat', 'file') + save('matlab/mat/nass_model_conf_log.mat', 'conf_log', '-append'); else - save('matlab/mat/conf_log.mat', 'conf_log'); + save('matlab/mat/nass_model_conf_log.mat', 'conf_log'); end end #+end_src @@ -2891,7 +3158,7 @@ end case 'constant' Dh = [args.Dh_pos, args.Dh_pos]; - load('nass_stages.mat', 'micro_hexapod'); + load('nass_model_stages.mat', 'micro_hexapod'); AP = [args.Dh_pos(1) ; args.Dh_pos(2) ; args.Dh_pos(3)]; @@ -2922,21 +3189,20 @@ end *** Save the Structure #+begin_src matlab if exist('./mat', 'dir') - if exist('./mat/nass_references.mat', 'file') - save('mat/nass_references.mat', 'Dy', 'Ry', 'Rz', 'Dh', 'Dhl', 'args', 'Ts', '-append'); + if exist('./mat/nass_model_references.mat', 'file') + save('mat/nass_model_references.mat', 'Dy', 'Ry', 'Rz', 'Dh', 'Dhl', 'args', 'Ts', '-append'); else - save('mat/nass_references.mat', 'Dy', 'Ry', 'Rz', 'Dh', 'Dhl', 'args', 'Ts'); + save('mat/nass_model_references.mat', 'Dy', 'Ry', 'Rz', 'Dh', 'Dhl', 'args', 'Ts'); end elseif exist('./matlab', 'dir') - if exist('./matlab/mat/nass_references.mat', 'file') - save('matlab/mat/nass_references.mat', 'Dy', 'Ry', 'Rz', 'Dh', 'Dhl', 'args', 'Ts', '-append'); + if exist('./matlab/mat/nass_model_references.mat', 'file') + save('matlab/mat/nass_model_references.mat', 'Dy', 'Ry', 'Rz', 'Dh', 'Dhl', 'args', 'Ts', '-append'); else - save('matlab/mat/nass_references.mat', 'Dy', 'Ry', 'Rz', 'Dh', 'Dhl', 'args', 'Ts'); + save('matlab/mat/nass_model_references.mat', 'Dy', 'Ry', 'Rz', 'Dh', 'Dhl', 'args', 'Ts'); end end #+end_src - ** =initializeDisturbances=: Initialize Disturbances :PROPERTIES: :header-args:matlab+: :tangle matlab/src/initializeDisturbances.m @@ -2962,15 +3228,15 @@ arguments % Global parameter to enable or disable the disturbances args.enable logical {mustBeNumericOrLogical} = true % Ground Motion - X direction - args.Dwx logical {mustBeNumericOrLogical} = true + args.Dw_x logical {mustBeNumericOrLogical} = true % Ground Motion - Y direction - args.Dwy logical {mustBeNumericOrLogical} = true + args.Dw_y logical {mustBeNumericOrLogical} = true % Ground Motion - Z direction - args.Dwz logical {mustBeNumericOrLogical} = true + args.Dw_z logical {mustBeNumericOrLogical} = true % Translation Stage - X direction - args.Fty_x logical {mustBeNumericOrLogical} = true + args.Fdy_x logical {mustBeNumericOrLogical} = true % Translation Stage - Z direction - args.Fty_z logical {mustBeNumericOrLogical} = true + args.Fdy_z logical {mustBeNumericOrLogical} = true % Spindle - X direction args.Frz_x logical {mustBeNumericOrLogical} = true % Spindle - Y direction @@ -2988,186 +3254,169 @@ rng("shuffle"); *** Ground Motion #+begin_src matlab %% Ground Motion -load('dist_psd.mat', 'dist_f'); +if args.enable + % Load the PSD of disturbance + load('ustation_disturbance_psd.mat', 'gm_dist') -% Frequency Data -Dw.f = dist_f.f(2:end); -Dw.psd_x = dist_f.psd_gm(2:end); -Dw.psd_y = dist_f.psd_gm(2:end); -Dw.psd_z = dist_f.psd_gm(2:end); + % Frequency Data + Dw.f = gm_dist.f; + Dw.psd_x = gm_dist.pxx_x; + Dw.psd_y = gm_dist.pxx_y; + Dw.psd_z = gm_dist.pxx_z; -% Time data -Fs = 2*Dw.f(end); % Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz] -N = 2*length(Dw.f); % Number of Samples match the one of the wanted PSD -T0 = N/Fs; % Signal Duration [s] -Dw.t = linspace(0, T0, N+1)'; % Time Vector [s] + % Time data + Fs = 2*Dw.f(end); % Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz] + N = 2*length(Dw.f); % Number of Samples match the one of the wanted PSD + T0 = N/Fs; % Signal Duration [s] + Dw.t = linspace(0, T0, N+1)'; % Time Vector [s] -C = zeros(N/2,1); -for i = 1:N/2 - C(i) = sqrt(Dw.psd_x(i)/T0); -end + % ASD representation of the ground motion + C = zeros(N/2,1); + for i = 1:N/2 + C(i) = sqrt(Dw.psd_x(i)/T0); + end + + if args.Dw_x + theta = 2*pi*rand(N/2,1); % Generate random phase [rad] + Cx = [0 ; C.*complex(cos(theta),sin(theta))]; + Cx = [Cx; flipud(conj(Cx(2:end)))];; + Dw.x = N/sqrt(2)*ifft(Cx); % Ground Motion - x direction [m] + else + Dw.x = zeros(length(Dw.t), 1); + end + + if args.Dw_y + theta = 2*pi*rand(N/2,1); % Generate random phase [rad] + Cx = [0 ; C.*complex(cos(theta),sin(theta))]; + Cx = [Cx; flipud(conj(Cx(2:end)))];; + Dw.y = N/sqrt(2)*ifft(Cx); % Ground Motion - y direction [m] + else + Dw.y = zeros(length(Dw.t), 1); + end + + if args.Dw_y + theta = 2*pi*rand(N/2,1); % Generate random phase [rad] + Cx = [0 ; C.*complex(cos(theta),sin(theta))]; + Cx = [Cx; flipud(conj(Cx(2:end)))];; + Dw.z = N/sqrt(2)*ifft(Cx); % Ground Motion - z direction [m] + else + Dw.z = zeros(length(Dw.t), 1); + end -if args.Dwx && args.enable - theta = 2*pi*rand(N/2,1); % Generate random phase [rad] - Cx = [0 ; C.*complex(cos(theta),sin(theta))]; - Cx = [Cx; flipud(conj(Cx(2:end)))];; - Dw.x = N/sqrt(2)*ifft(Cx); % Ground Motion - x direction [m] else - Dw.x = zeros(length(Dw.t), 1); -end - -if args.Dwy && args.enable - theta = 2*pi*rand(N/2,1); % Generate random phase [rad] - Cx = [0 ; C.*complex(cos(theta),sin(theta))]; - Cx = [Cx; flipud(conj(Cx(2:end)))];; - Dw.y = N/sqrt(2)*ifft(Cx); % Ground Motion - y direction [m] -else - Dw.y = zeros(length(Dw.t), 1); -end - -if args.Dwy && args.enable - theta = 2*pi*rand(N/2,1); % Generate random phase [rad] - Cx = [0 ; C.*complex(cos(theta),sin(theta))]; - Cx = [Cx; flipud(conj(Cx(2:end)))];; - Dw.z = N/sqrt(2)*ifft(Cx); % Ground Motion - z direction [m] -else - Dw.z = zeros(length(Dw.t), 1); + Dw.t = [0,1]; % Time Vector [s] + Dw.x = [0,0]; % Ground Motion - X [m] + Dw.y = [0,0]; % Ground Motion - Y [m] + Dw.z = [0,0]; % Ground Motion - Z [m] end #+end_src -*** Translation Stage - - -We remove the first frequency point that usually is very large. -#+begin_src matlab :exports none -load('dist_psd.mat', 'dist_f'); -dist_f.f = dist_f.f(2:end); -dist_f.psd_gm = dist_f.psd_gm(2:end); -dist_f.psd_ty = dist_f.psd_ty(2:end); -dist_f.psd_rz = dist_f.psd_rz(2:end); -#+end_src - +*** Translation stage #+begin_src matlab -%% Translation Stage -load('dist_psd.mat', 'dist_f'); +%% Translation stage +if args.enable + % Load the PSD of disturbance + load('ustation_disturbance_psd.mat', 'dy_dist') -% Frequency Data -Ty.f = dist_f.f(2:end); -Ty.psd_x = dist_f.psd_ty(2:end); % TODO - we take here the vertical direction which is wrong but approximate -Ty.psd_z = dist_f.psd_ty(2:end); + % Frequency Data + Dy.f = dy_dist.f; + Dy.psd_x = dy_dist.pxx_fx; + Dy.psd_z = dy_dist.pxx_fz; -% Time data -Fs = 2*Ty.f(end); % Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz] -N = 2*length(Ty.f); % Number of Samples match the one of the wanted PSD -T0 = N/Fs; % Signal Duration [s] -Ty.t = linspace(0, T0, N+1)'; % Time Vector [s] + % Time data + Fs = 2*Dy.f(end); % Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz] + N = 2*length(Dy.f); % Number of Samples match the one of the wanted PSD + T0 = N/Fs; % Signal Duration [s] + Dy.t = linspace(0, T0, N+1)'; % Time Vector [s] -C = zeros(N/2,1); -for i = 1:N/2 - C(i) = sqrt(Ty.psd_x(i)/T0); -end - -% Translation Stage - X -if args.Fty_x && args.enable - phi = Ty.psd_x; + % ASD representation of the disturbance voice C = zeros(N/2,1); for i = 1:N/2 - C(i) = sqrt(phi(i)/T0); + C(i) = sqrt(Dy.psd_x(i)/T0); end - theta = 2*pi*rand(N/2,1); % Generate random phase [rad] - Cx = [0 ; C.*complex(cos(theta),sin(theta))]; - Cx = [Cx; flipud(conj(Cx(2:end)))];; - u = N/sqrt(2)*ifft(Cx); % Disturbance Force Ty x [N] - Ty.x = u; -else - Ty.x = zeros(length(Ty.t), 1); -end -% Translation Stage - Z -if args.Fty_z && args.enable - phi = Ty.psd_z; - C = zeros(N/2,1); - for i = 1:N/2 - C(i) = sqrt(phi(i)/T0); + if args.Fdy_x + theta = 2*pi*rand(N/2,1); % Generate random phase [rad] + Cx = [0 ; C.*complex(cos(theta),sin(theta))]; + Cx = [Cx; flipud(conj(Cx(2:end)))];; + Dy.x = N/sqrt(2)*ifft(Cx); % Translation stage disturbances - X direction [N] + else + Dy.x = zeros(length(Dy.t), 1); end - theta = 2*pi*rand(N/2,1); % Generate random phase [rad] - Cx = [0 ; C.*complex(cos(theta),sin(theta))]; - Cx = [Cx; flipud(conj(Cx(2:end)))];; - u = N/sqrt(2)*ifft(Cx); % Disturbance Force Ty z [N] - Ty.z = u; + + if args.Fdy_z + theta = 2*pi*rand(N/2,1); % Generate random phase [rad] + Cx = [0 ; C.*complex(cos(theta),sin(theta))]; + Cx = [Cx; flipud(conj(Cx(2:end)))];; + Dy.z = N/sqrt(2)*ifft(Cx); % Translation stage disturbances - Z direction [N] + else + Dy.z = zeros(length(Dy.t), 1); + end + else - Ty.z = zeros(length(Ty.t), 1); + Dy.t = [0,1]; % Time Vector [s] + Dy.x = [0,0]; % Translation Stage disturbances - X [N] + Dy.z = [0,0]; % Translation Stage disturbances - Z [N] end #+end_src *** Spindle #+begin_src matlab -%% Translation Stage -load('dist_psd.mat', 'dist_f'); +%% Spindle +if args.enable + % Load the PSD of disturbance + load('ustation_disturbance_psd.mat', 'rz_dist') -% Frequency Data -Rz.f = dist_f.f(2:end); -Rz.psd_x = dist_f.psd_rz(2:end); % TODO - we take here the vertical direction which is wrong but approximate -Rz.psd_y = dist_f.psd_rz(2:end); % TODO - we take here the vertical direction which is wrong but approximate -Rz.psd_z = dist_f.psd_rz(2:end); + % Frequency Data + Rz.f = rz_dist.f; + Rz.psd_x = rz_dist.pxx_fx; + Rz.psd_y = rz_dist.pxx_fy; + Rz.psd_z = rz_dist.pxx_fz; -% Time data -Fs = 2*Rz.f(end); % Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz] -N = 2*length(Rz.f); % Number of Samples match the one of the wanted PSD -T0 = N/Fs; % Signal Duration [s] -Rz.t = linspace(0, T0, N+1)'; % Time Vector [s] + % Time data + Fs = 2*Rz.f(end); % Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz] + N = 2*length(Rz.f); % Number of Samples match the one of the wanted PSD + T0 = N/Fs; % Signal Duration [s] + Rz.t = linspace(0, T0, N+1)'; % Time Vector [s] -C = zeros(N/2,1); -for i = 1:N/2 - C(i) = sqrt(Rz.psd_x(i)/T0); -end - -% Translation Stage - X -if args.Frz_x && args.enable - phi = Rz.psd_x; + % ASD representation of the disturbance voice C = zeros(N/2,1); for i = 1:N/2 - C(i) = sqrt(phi(i)/T0); + C(i) = sqrt(Rz.psd_x(i)/T0); end - theta = 2*pi*rand(N/2,1); % Generate random phase [rad] - Cx = [0 ; C.*complex(cos(theta),sin(theta))]; - Cx = [Cx; flipud(conj(Cx(2:end)))];; - u = N/sqrt(2)*ifft(Cx); % Disturbance Force Rz x [N] - Rz.x = u; -else - Rz.x = zeros(length(Rz.t), 1); -end -% Translation Stage - Y -if args.Frz_y && args.enable - phi = Rz.psd_y; - C = zeros(N/2,1); - for i = 1:N/2 - C(i) = sqrt(phi(i)/T0); + if args.Frz_x + theta = 2*pi*rand(N/2,1); % Generate random phase [rad] + Cx = [0 ; C.*complex(cos(theta),sin(theta))]; + Cx = [Cx; flipud(conj(Cx(2:end)))];; + Rz.x = N/sqrt(2)*ifft(Cx); % spindle disturbances - X direction [N] + else + Rz.x = zeros(length(Rz.t), 1); end - theta = 2*pi*rand(N/2,1); % Generate random phase [rad] - Cx = [0 ; C.*complex(cos(theta),sin(theta))]; - Cx = [Cx; flipud(conj(Cx(2:end)))];; - u = N/sqrt(2)*ifft(Cx); % Disturbance Force Rz y [N] - Rz.y = u; -else - Rz.y = zeros(length(Rz.t), 1); -end -% Translation Stage - Z -if args.Frz_z && args.enable - phi = Rz.psd_z; - C = zeros(N/2,1); - for i = 1:N/2 - C(i) = sqrt(phi(i)/T0); + if args.Frz_y + theta = 2*pi*rand(N/2,1); % Generate random phase [rad] + Cx = [0 ; C.*complex(cos(theta),sin(theta))]; + Cx = [Cx; flipud(conj(Cx(2:end)))];; + Rz.y = N/sqrt(2)*ifft(Cx); % spindle disturbances - Y direction [N] + else + Rz.y = zeros(length(Rz.t), 1); end - theta = 2*pi*rand(N/2,1); % Generate random phase [rad] - Cx = [0 ; C.*complex(cos(theta),sin(theta))]; - Cx = [Cx; flipud(conj(Cx(2:end)))];; - u = N/sqrt(2)*ifft(Cx); % Disturbance Force Rz z [N] - Rz.z = u; + + if args.Frz_z + theta = 2*pi*rand(N/2,1); % Generate random phase [rad] + Cx = [0 ; C.*complex(cos(theta),sin(theta))]; + Cx = [Cx; flipud(conj(Cx(2:end)))];; + Rz.z = N/sqrt(2)*ifft(Cx); % spindle disturbances - Z direction [N] + else + Rz.z = zeros(length(Rz.t), 1); + end + else - Rz.z = zeros(length(Rz.t), 1); + Rz.t = [0,1]; % Time Vector [s] + Rz.x = [0,0]; % Spindle disturbances - X [N] + Rz.y = [0,0]; % Spindle disturbances - X [N] + Rz.z = [0,0]; % Spindle disturbances - Z [N] end #+end_src @@ -3182,8 +3431,10 @@ Fd = u; Dw.x = Dw.x - Dw.x(1); Dw.y = Dw.y - Dw.y(1); Dw.z = Dw.z - Dw.z(1); -Ty.x = Ty.x - Ty.x(1); -Ty.z = Ty.z - Ty.z(1); + +Dy.x = Dy.x - Dy.x(1); +Dy.z = Dy.z - Dy.z(1); + Rz.x = Rz.x - Rz.x(1); Rz.y = Rz.y - Rz.y(1); Rz.z = Rz.z - Rz.z(1); @@ -3192,17 +3443,9 @@ Rz.z = Rz.z - Rz.z(1); *** Save the Structure #+begin_src matlab if exist('./mat', 'dir') - if exist('./mat/nass_disturbances.mat', 'file') - save('mat/nass_disturbances.mat', 'Dw', 'Ty', 'Rz', 'Fd', 'args', '-append'); - else - save('mat/nass_disturbances.mat', 'Dw', 'Ty', 'Rz', 'Fd', 'args'); - end + save('mat/nass_model_disturbances.mat', 'Dw', 'Dy', 'Rz', 'Fd', 'args'); elseif exist('./matlab', 'dir') - if exist('./matlab/mat/nass_disturbances.mat', 'file') - save('matlab/mat/nass_disturbances.mat', 'Dw', 'Ty', 'Rz', 'Fd', 'args', '-append'); - else - save('matlab/mat/nass_disturbances.mat', 'Dw', 'Ty', 'Rz', 'Fd', 'args'); - end + save('matlab/mat/nass_model_disturbances.mat', 'Dw', 'Dy', 'Rz', 'Fd', 'args'); end #+end_src @@ -3228,7 +3471,7 @@ end *** Simscape Configuration #+begin_src matlab - load('./mat/conf_simscape.mat', 'conf_simscape'); + load('./mat/nass_model_conf_simscape.mat', 'conf_simscape'); #+end_src #+begin_src matlab @@ -3245,7 +3488,7 @@ end *** Disturbances #+begin_src matlab - load('./mat/nass_disturbances.mat', 'args'); + load('./mat/nass_model_disturbances.mat', 'args'); #+end_src #+begin_src matlab @@ -3256,7 +3499,7 @@ end if args.Dwx && args.Dwy && args.Dwz fprintf('- Ground motion\n'); end - if args.Fty_x && args.Fty_z + if args.Fdy_x && args.Fdy_z fprintf('- Vibrations of the Translation Stage\n'); end if args.Frz_z @@ -3268,7 +3511,7 @@ end *** References #+begin_src matlab - load('./mat/nass_references.mat', 'args'); + load('./mat/nass_model_references.mat', 'args'); #+end_src #+begin_src matlab @@ -3325,20 +3568,9 @@ end fprintf('\n'); #+end_src -*** Controller -#+begin_src matlab - load('./mat/controller.mat', 'controller'); -#+end_src - -#+begin_src matlab - fprintf('Controller:\n'); - fprintf('- %s\n', controller.name); - fprintf('\n'); -#+end_src - *** Micro-Station #+begin_src matlab - load('./mat/stages.mat', 'ground', 'granite', 'ty', 'ry', 'rz', 'micro_hexapod', 'axisc'); + load('./mat/nass_model_stages.mat', 'ground', 'granite', 'ty', 'ry', 'rz', 'micro_hexapod', 'axisc'); #+end_src #+begin_src matlab @@ -3474,6 +3706,36 @@ end end #+end_src +** =circlefit= +:PROPERTIES: +:header-args:matlab+: :tangle matlab/src/circlefit.m +:header-args:matlab+: :comments none :mkdirp yes :eval no +:END: + +#+begin_src matlab +function [xc,yc,R,a] = circlefit(x,y) +% +% [xc yx R] = circfit(x,y) +% +% fits a circle in x,y plane in a more accurate +% (less prone to ill condition ) +% procedure than circfit2 but using more memory +% x,y are column vector where (x(i),y(i)) is a measured point +% +% result is center point (yc,xc) and radius R +% an optional output is the vector of coeficient a +% describing the circle's equation +% +% x^2+y^2+a(1)*x+a(2)*y+a(3)=0 +% +% By: Izhak bucher 25/oct /1991, + x=x(:); y=y(:); + a=[x y ones(size(x))]\[-(x.^2+y.^2)]; + xc = -.5*a(1); + yc = -.5*a(2); + R = sqrt((a(1)^2+a(2)^2)/4-a(3)); +#+end_src + ** Initialize Micro-Station Stages *** =initializeGround=: Ground :PROPERTIES: @@ -3526,16 +3788,16 @@ We set the shape and density of the ground solid element. **** Save the Structure #+begin_src matlab if exist('./mat', 'dir') - if exist('./mat/nass_stages.mat', 'file') - save('mat/nass_stages.mat', 'ground', '-append'); + if exist('./mat/nass_model_stages.mat', 'file') + save('mat/nass_model_stages.mat', 'ground', '-append'); else - save('mat/nass_stages.mat', 'ground'); + save('mat/nass_model_stages.mat', 'ground'); end elseif exist('./matlab', 'dir') - if exist('./matlab/mat/nass_stages.mat', 'file') - save('matlab/mat/nass_stages.mat', 'ground', '-append'); + if exist('./matlab/mat/nass_model_stages.mat', 'file') + save('matlab/mat/nass_model_stages.mat', 'ground', '-append'); else - save('matlab/mat/nass_stages.mat', 'ground'); + save('matlab/mat/nass_model_stages.mat', 'ground'); end end #+end_src @@ -3606,16 +3868,16 @@ Z-offset for the initial position of the sample with respect to the granite top **** Save the Structure #+begin_src matlab if exist('./mat', 'dir') - if exist('./mat/nass_stages.mat', 'file') - save('mat/nass_stages.mat', 'granite', '-append'); + if exist('./mat/nass_model_stages.mat', 'file') + save('mat/nass_model_stages.mat', 'granite', '-append'); else - save('mat/nass_stages.mat', 'granite'); + save('mat/nass_model_stages.mat', 'granite'); end elseif exist('./matlab', 'dir') - if exist('./matlab/mat/nass_stages.mat', 'file') - save('matlab/mat/nass_stages.mat', 'granite', '-append'); + if exist('./matlab/mat/nass_model_stages.mat', 'file') + save('matlab/mat/nass_model_stages.mat', 'granite', '-append'); else - save('matlab/mat/nass_stages.mat', 'granite'); + save('matlab/mat/nass_model_stages.mat', 'granite'); end end #+end_src @@ -3706,16 +3968,16 @@ Define the density of the materials as well as the geometry (STEP files). **** Save the Structure #+begin_src matlab if exist('./mat', 'dir') - if exist('./mat/nass_stages.mat', 'file') - save('mat/nass_stages.mat', 'ty', '-append'); + if exist('./mat/nass_model_stages.mat', 'file') + save('mat/nass_model_stages.mat', 'ty', '-append'); else - save('mat/nass_stages.mat', 'ty'); + save('mat/nass_model_stages.mat', 'ty'); end elseif exist('./matlab', 'dir') - if exist('./matlab/mat/nass_stages.mat', 'file') - save('matlab/mat/nass_stages.mat', 'ty', '-append'); + if exist('./matlab/mat/nass_model_stages.mat', 'file') + save('matlab/mat/nass_model_stages.mat', 'ty', '-append'); else - save('matlab/mat/nass_stages.mat', 'ty'); + save('matlab/mat/nass_model_stages.mat', 'ty'); end end #+end_src @@ -3797,16 +4059,16 @@ Z-Offset so that the center of rotation matches the sample center; **** Save the Structure #+begin_src matlab if exist('./mat', 'dir') - if exist('./mat/nass_stages.mat', 'file') - save('mat/nass_stages.mat', 'ry', '-append'); + if exist('./mat/nass_model_stages.mat', 'file') + save('mat/nass_model_stages.mat', 'ry', '-append'); else - save('mat/nass_stages.mat', 'ry'); + save('mat/nass_model_stages.mat', 'ry'); end elseif exist('./matlab', 'dir') - if exist('./matlab/mat/nass_stages.mat', 'file') - save('matlab/mat/nass_stages.mat', 'ry', '-append'); + if exist('./matlab/mat/nass_model_stages.mat', 'file') + save('matlab/mat/nass_model_stages.mat', 'ry', '-append'); else - save('matlab/mat/nass_stages.mat', 'ry'); + save('matlab/mat/nass_model_stages.mat', 'ry'); end end #+end_src @@ -3874,16 +4136,16 @@ Properties of the Material and link to the geometry of the spindle. **** Save the Structure #+begin_src matlab if exist('./mat', 'dir') - if exist('./mat/nass_stages.mat', 'file') - save('mat/nass_stages.mat', 'rz', '-append'); + if exist('./mat/nass_model_stages.mat', 'file') + save('mat/nass_model_stages.mat', 'rz', '-append'); else - save('mat/nass_stages.mat', 'rz'); + save('mat/nass_model_stages.mat', 'rz'); end elseif exist('./matlab', 'dir') - if exist('./matlab/mat/nass_stages.mat', 'file') - save('matlab/mat/nass_stages.mat', 'rz', '-append'); + if exist('./matlab/mat/nass_model_stages.mat', 'file') + save('matlab/mat/nass_model_stages.mat', 'rz', '-append'); else - save('matlab/mat/nass_stages.mat', 'rz'); + save('matlab/mat/nass_model_stages.mat', 'rz'); end end #+end_src @@ -4009,16 +4271,16 @@ end #+begin_src matlab micro_hexapod = stewart; if exist('./mat', 'dir') - if exist('./mat/nass_stages.mat', 'file') - save('mat/nass_stages.mat', 'micro_hexapod', '-append'); + if exist('./mat/nass_model_stages.mat', 'file') + save('mat/nass_model_stages.mat', 'micro_hexapod', '-append'); else - save('mat/nass_stages.mat', 'micro_hexapod'); + save('mat/nass_model_stages.mat', 'micro_hexapod'); end elseif exist('./matlab', 'dir') - if exist('./matlab/mat/nass_stages.mat', 'file') - save('matlab/mat/nass_stages.mat', 'micro_hexapod', '-append'); + if exist('./matlab/mat/nass_model_stages.mat', 'file') + save('matlab/mat/nass_model_stages.mat', 'micro_hexapod', '-append'); else - save('matlab/mat/nass_stages.mat', 'micro_hexapod'); + save('matlab/mat/nass_model_stages.mat', 'micro_hexapod'); end end #+end_src @@ -5103,7 +5365,7 @@ Otherwise, when the limbs' lengths derived yield complex numbers, then the posit * Footnotes [fn:10]Laser source is manufactured by Agilent (5519b) -[fn:9]The special optics (straightness interferometer and reflector) are the manufactured by Agilent (10774A). +[fn:9]The special optics (straightness interferometer and reflector) are manufactured by Agilent (10774A). [fn:8]C8 capacitive sensors and CPL290 capacitive driver electronics from Lion Precision [fn:7]The Spindle Error Analyzer is made by Lion Precision. [fn:6]The tools presented here are largely taken from [[cite:&taghirad13_paral]]. diff --git a/simscape-micro-station.pdf b/simscape-micro-station.pdf index b27c14f..faf6902 100644 Binary files a/simscape-micro-station.pdf and b/simscape-micro-station.pdf differ diff --git a/simscape-micro-station.tex b/simscape-micro-station.tex index 8ec0c39..81a7507 100644 --- a/simscape-micro-station.tex +++ b/simscape-micro-station.tex @@ -1,4 +1,4 @@ -% Created 2024-11-05 Tue 22:36 +% Created 2024-11-06 Wed 12:01 % Intended LaTeX compiler: pdflatex \documentclass[a4paper, 10pt, DIV=12, parskip=full, bibliography=totoc]{scrreprt} @@ -24,7 +24,6 @@ \begin{table}[htbp] -\caption{\label{tab:ustation_section_matlab_code}Report sections and corresponding Matlab files} \centering \begin{tabularx}{0.6\linewidth}{lX} \toprule @@ -36,6 +35,8 @@ Section \ref{sec:ustation_disturbances} & \texttt{ustation\_3\_disturbances.m}\\ Section \ref{sec:ustation_experiments} & \texttt{ustation\_4\_experiments.m}\\ \bottomrule \end{tabularx} +\caption{\label{tab:ustation_section_matlab_code}Report sections and corresponding Matlab files} + \end{table} \chapter{Micro-Station Kinematics} @@ -53,7 +54,6 @@ The micro-station degrees-of-freedom are summarized in Table \ref{tab:ustation_d \end{figure} \begin{table}[htbp] -\caption{\label{tab:ustation_dof_summary}Summary of the micro-station degrees-of-freedom} \centering \begin{tabularx}{\linewidth}{lX} \toprule @@ -65,6 +65,8 @@ Spindle & \(R_z = 360\,\text{deg}\)\\ Micro Hexapod & \(D_{xyz} = \pm 10\,mm\), \(R_{xyz} = \pm 3\,\text{deg}\)\\ \bottomrule \end{tabularx} +\caption{\label{tab:ustation_dof_summary}Summary of the micro-station degrees-of-freedom} + \end{table} There are different ways of modelling the stage dynamics in a multi-body model. @@ -424,7 +426,6 @@ The springs and dampers values were first estimated from the joints/stages speci The spring values are summarized in Table \ref{tab:ustation_6dof_stiffness_values}. \begin{table}[htbp] -\caption{\label{tab:ustation_6dof_stiffness_values}Summary of the stage stiffnesses. Contrained degrees-of-freedom are indicated by ``-''. The location of the 6-DoF joints in which the stiffnesses are defined are indicated by the frame in figures of Section \ref{ssec:ustation_stages}} \centering \begin{tabularx}{\linewidth}{Xcccccc} \toprule @@ -437,6 +438,8 @@ Spindle & \(700\,N/\mu m\) & \(700\,N/\mu m\) & \(2\,kN/\mu m\) & \(10\,Nm/\mu\t Hexapod & \(10\,N/\mu m\) & \(10\,N/\mu m\) & \(100\,N/\mu m\) & \(1.5\,Nm/rad\) & \(1.5\,Nm/rad\) & \(0.27\,Nm/rad\)\\ \bottomrule \end{tabularx} +\caption{\label{tab:ustation_6dof_stiffness_values}Summary of the stage stiffnesses. Contrained degrees-of-freedom are indicated by ``-''. The location of the 6-DoF joints in which the stiffnesses are defined are indicated by the frame in figures of Section \ref{ssec:ustation_stages}} + \end{table} \section{With comparison with the measurements} @@ -603,11 +606,18 @@ Therefore, from a control point of view, they are not important. The ground motion is simply measured by using a sensitive 3-axis geophone placed on the ground. The generated voltages are recorded with a high resolution DAC, and converted to displacement using the Geophone sensitivity transfer function. +The obtained ground motion displacement is shown in Figure \ref{fig:ustation_ground_disturbance}. + +\begin{figure}[htbp] +\centering +\includegraphics[scale=1]{figs/ustation_ground_disturbance.png} +\caption{\label{fig:ustation_ground_disturbance}Measured ground motion} +\end{figure} \paragraph{Ty Stage} To measure the positioning errors of the translation stage, the setup shown in Figure \ref{fig:ustation_errors_ty_setup} is used. -A special optical element (called a ``straightness interferometer''\footnote{The special optics (straightness interferometer and reflector) are the manufactured by Agilent (10774A).}) is fixed on top of the micro-station, while a laser source\footnote{Laser source is manufactured by Agilent (5519b)} and a straightness reflector are fixed on the ground. +A special optical element (called a ``straightness interferometer''\footnote{The special optics (straightness interferometer and reflector) are manufactured by Agilent (10774A).}) is fixed on top of the micro-station, while a laser source\footnote{Laser source is manufactured by Agilent (5519b)} and a straightness reflector are fixed on the ground. A similar setup is used to measure the horizontal deviation (i.e. in the \(x\) direction), as well as the pitch and yaw errors of the translation stage. \begin{figure}[htbp] @@ -664,7 +674,10 @@ From the 5 measured displacements \([d_1,\,d_2,\,d_3,\,d_4,\,d_5]\), the transla A measurement is performed at 60rpm during 10 turns, and the obtained results are shown in Figure \ref{fig:ustation_errors_spindle}. A fraction of the radial (Figure \ref{fig:ustation_errors_spindle_radial}) and tilt (Figure \ref{fig:ustation_errors_spindle_tilt}) errors is linked to the fact that the two spheres are not perfectly aligned with the rotation axis of the Spindle. -However, it is in practice very difficult to align the ``point-of-interest'' of the sample with the rotation axis, so the NASS will be used to actively keep the PoI on the rotation axis. +This is displayed by the dashed circle. +After removing the best circular fit from the data, the vibrations induced by the Spindle may be viewed as stochastic disturbances. +However, some misalignment between the ``point-of-interest'' of the sample with the rotation axis will be considered as it is very difficult to align in practice. +The NASS will be used to actively keep the PoI on the rotation axis. The vertical motion induced by the scanning of the spindle is in the order of \(\pm 30\,nm\) (Figure \ref{fig:ustation_errors_spindle_axial}). \begin{figure}[htbp] @@ -686,7 +699,7 @@ The vertical motion induced by the scanning of the spindle is in the order of \( \end{center} \subcaption{\label{fig:ustation_errors_spindle_tilt}Tilt errors} \end{subfigure} -\caption{\label{fig:ustation_errors_spindle}Measurement of the radial (\subref{fig:ustation_errors_spindle_radial}), axial (\subref{fig:ustation_errors_spindle_axial}) and tilt (\subref{fig:ustation_errors_spindle_tilt}) Spindle errors.} +\caption{\label{fig:ustation_errors_spindle}Measurement of the radial (\subref{fig:ustation_errors_spindle_radial}), axial (\subref{fig:ustation_errors_spindle_axial}) and tilt (\subref{fig:ustation_errors_spindle_tilt}) Spindle errors during a 60rpm spindle rotation. A circular best fit is shown by the dashed circle. It represents the misalignment of the spheres with the rotation axis.} \end{figure} \section{Sensitivity to disturbances} @@ -694,7 +707,6 @@ The vertical motion induced by the scanning of the spindle is in the order of \( In order to compute the disturbance source (i.e. forces) that induced the measured vibrations in Section \ref{ssec:ustation_disturbances_meas}, the transfer function from the disturbance sources to the stage vibration (i.e. the ``sensitivity to disturbances'') needs to be estimated. This is done using the multi-body that was presented in Section \ref{sec:ustation_modeling}. - The obtained transfer functions are shown in Figure \ref{fig:ustation_model_sensitivity}. \begin{figure}[htbp] @@ -722,161 +734,87 @@ The obtained transfer functions are shown in Figure \ref{fig:ustation_model_sens \section{Obtained disturbance sources} \label{ssec:ustation_disturbances_results} -\begin{itemize} -\item[{$\square$}] Display PSD of disturbances -\end{itemize} +From the measured effect of disturbances in Section \ref{ssec:ustation_disturbances_meas} and the sensitivity to disturbances extracted from the Simscape model in Section \ref{ssec:ustation_disturbances_sensitivity}, the power spectral density of the disturbance sources (i.e. forces applied in the stage's joint) can be estimated. +They are shown in Figure \ref{fig:ustation_dist_sources}. -The obtained amplitude spectral densities of the disturbance forces are shown in Figure \ref{fig:dist_force_psd}. +\begin{figure}[htbp] +\begin{subfigure}{0.33\textwidth} +\begin{center} +\includegraphics[scale=1,width=0.9\linewidth]{figs/ustation_dist_source_ground_motion.png} +\end{center} +\subcaption{\label{fig:ustation_dist_source_ground_motion}Ground Motion} +\end{subfigure} +\begin{subfigure}{0.33\textwidth} +\begin{center} +\includegraphics[scale=1,width=0.9\linewidth]{figs/ustation_dist_source_translation_stage.png} +\end{center} +\subcaption{\label{fig:ustation_dist_source_translation_stage}Translation Stage} +\end{subfigure} +\begin{subfigure}{0.33\textwidth} +\begin{center} +\includegraphics[scale=1,width=0.9\linewidth]{figs/ustation_dist_source_spindle.png} +\end{center} +\subcaption{\label{fig:ustation_dist_source_spindle}Spindle} +\end{subfigure} +\caption{\label{fig:ustation_dist_sources}Measured spectral density of the micro-station disturbances sources. Ground motion (\subref{fig:ustation_dist_source_ground_motion}), translation stage (\subref{fig:ustation_dist_source_translation_stage}) and spindle (\subref{fig:ustation_dist_source_spindle}).} +\end{figure} + +The disturbances are characterized by their power spectral densities as shown in Figure \ref{fig:ustation_dist_sources}. +However, in order to perform time domain simulations, disturbances needs to be represented by a time domain. +In order to generate stochastic time domain signals having the same power spectral densities as the ones estimated, the discrete inverse Fourier transform is used as explained in \cite[chap. 12.11]{preumont94_random_vibrat_spect_analy}. +Examples of obtained time domain disturbance signals are shown in Figure \ref{fig:ustation_dist_sources_time}. + +\begin{figure}[htbp] +\begin{subfigure}{0.33\textwidth} +\begin{center} +\includegraphics[scale=1,width=0.9\linewidth]{figs/ustation_dist_source_ground_motion_time.png} +\end{center} +\subcaption{\label{fig:ustation_dist_source_ground_motion_time}Ground Motion} +\end{subfigure} +\begin{subfigure}{0.33\textwidth} +\begin{center} +\includegraphics[scale=1,width=0.9\linewidth]{figs/ustation_dist_source_translation_stage_time.png} +\end{center} +\subcaption{\label{fig:ustation_dist_source_translation_stage_time}Translation Stage} +\end{subfigure} +\begin{subfigure}{0.33\textwidth} +\begin{center} +\includegraphics[scale=1,width=0.9\linewidth]{figs/ustation_dist_source_spindle_time.png} +\end{center} +\subcaption{\label{fig:ustation_dist_source_spindle_time}Spindle} +\end{subfigure} +\caption{\label{fig:ustation_dist_sources_time}Generated time domain disturbance signals. Ground motion (\subref{fig:ustation_dist_source_ground_motion_time}), translation stage (\subref{fig:ustation_dist_source_translation_stage_time}) and spindle (\subref{fig:ustation_dist_source_spindle_time}).} +\end{figure} \chapter{Simulation of Scientific Experiments} \label{sec:ustation_experiments} -The goal here is to simulate some scientific experiments with the Simscape model when no control is applied to the nano-hexapod. - -This has several goals: \begin{itemize} -\item Validate the model -\item Estimate the expected error motion for the experiments -\item Estimate the stroke that we may need for the nano-hexapod -\item Compare with experiments when control is applied +\item[{$\square$}] Perfect tomography => no error +\item[{$\square$}] Add vibrations and some off-center => results, compare with measurements +\item[{$\square$}] Ty scans (-4.5mm to 4.5mm) => compare with measurements \end{itemize} -The document in organized as follow: -\begin{itemize} -\item In section \ref{sec:simscape_model} the Simscape model is initialized -\item In section \ref{sec:tomo_no_dist} a tomography experiment is performed where the sample is aligned with the rotation axis. No disturbance is included -\item In section \ref{sec:tomo_dist}, the same is done but with disturbance included -\item In section \ref{sec:tomo_hexa_trans} the micro-hexapod translate the sample such that its center of mass is no longer aligned with the rotation axis. No disturbance is included -\item In section \ref{sec:ty_scans}, scans with the translation stage are simulated with no perturbation included -\end{itemize} -\section{Simscape Model} -\label{sec:simscape_model} - -We load the shared simulink configuration and we set the \texttt{StopTime}. -We first initialize all the stages. -The nano-hexapod is considered to be a rigid body. -No controller is used (Open Loop). -We don't gravity. -We log the signals for further analysis. -\section{Tomography Experiment with no disturbances} -\label{sec:tomo_no_dist} -In this section, a tomography experiment is performed with the sample aligned with the rotation axis. -No disturbance is included. -\subsection{Simulation Setup} -And we initialize the disturbances to be equal to zero. -We initialize the reference path for all the stages. -All stage is set to its zero position except the Spindle which is rotating at 60rpm. -We simulate the model. -And we save the obtained data. -\subsection{Analysis} +\section{Tomography Experiment} \begin{figure}[htbp] -\centering -\includegraphics[scale=1]{figs/exp_tomo_without_dist.png} -\caption{\label{fig:exp_tomo_without_dist}X-Y-Z translation of the sample w.r.t. granite when performing tomography experiment with no disturbances (\href{./figs/exp\_tomo\_without\_dist.png}{png}, \href{./figs/exp\_tomo\_without\_dist.pdf}{pdf})} +\begin{subfigure}{0.49\textwidth} +\begin{center} +\includegraphics[scale=1,scale=1]{figs/ustation_errors_model_spindle_radial.png} +\end{center} +\subcaption{\label{fig:ustation_errors_model_spindle_radial}Radial error} +\end{subfigure} +\begin{subfigure}{0.49\textwidth} +\begin{center} +\includegraphics[scale=1,scale=1]{figs/ustation_errors_model_spindle_axial.png} +\end{center} +\subcaption{\label{fig:ustation_errors_model_spindle_axial}Axial error} +\end{subfigure} +\caption{\label{fig:ustation_errors_model_spindle}Measurement of strut flexible modes} \end{figure} -\subsection{Conclusion} -\begin{important} -When everything is aligned, the resulting error motion is very small (nm range) and is quite negligible with respect to the error when disturbances are included. -This residual error motion probably comes from a small misalignment somewhere. -\end{important} - -\section{Tomography Experiment with included perturbations} -\label{sec:tomo_dist} -In this section, we also perform a tomography experiment with the sample's center of mass aligned with the rotation axis. -However this time, we include perturbations such as ground motion and stage vibrations. -\subsection{Simulation Setup} -We now activate the disturbances. -We initialize the reference path for all the stages. -All stage is set to its zero position except the Spindle which is rotating at 60rpm. -We simulate the model. -And we save the obtained data. -\subsection{Analysis} -\begin{figure}[htbp] -\centering -\includegraphics[scale=1]{figs/exp_tomo_dist.png} -\caption{\label{fig:exp_tomo_dist}X-Y-Z translations and rotations of the sample w.r.t. the granite when performing tomography experiment with disturbances (\href{./figs/exp\_tomo\_dist.png}{png}, \href{./figs/exp\_tomo\_dist.pdf}{pdf})} -\end{figure} - -\subsection{Conclusion} -\begin{important} -Here, no vibration is included in the X and Y directions. -\end{important} - -\section{Tomography Experiment with Ty raster scans} -\label{sec:tomo_dist_ty_scans} -In this section, we also perform a tomography experiment with scans of the Translation stage. -All the perturbations are included. -\subsection{Simulation Setup} -We now activate the disturbances. -We initialize the reference path for all the stages. -The Spindle which is rotating at 60rpm and the translation stage not moving as it would take a long time to simulate. -However, vibrations of the Ty stage are included. -We simulate the model. -And we save the obtained data. -\subsection{Analysis} -\begin{figure}[htbp] -\centering -\includegraphics[scale=1]{figs/exp_scans_rz_dist.png} -\caption{\label{fig:exp_scans_rz_dist}X-Y-Z translations and rotations of the sample w.r.t. the granite when performing tomography experiment and scans with the translation stage at the same time} -\end{figure} - -\subsection{Conclusion} - -\section{Tomography when the micro-hexapod is not centered} -\label{sec:tomo_hexa_trans} -In this section, the sample's center of mass is not aligned with the rotation axis anymore. -This is due to the fact that the micro-hexapod has performed some displacement. - -No disturbances are included. -\subsection{Simulation Setup} -We first set the wanted translation of the Micro Hexapod. -We initialize the reference path. -We initialize the stages. -And we initialize the disturbances to zero. -We simulate the model. -And we save the obtained data. -\subsection{Analysis} -\begin{figure}[htbp] -\centering -\includegraphics[scale=1]{figs/exp_tomo_offset.png} -\caption{\label{fig:exp_tomo_offset}X-Y-Z translation of the sample w.r.t. granite when performing tomography experiment with no disturbances (\href{./figs/exp\_tomo\_offset.png}{png}, \href{./figs/exp\_tomo\_offset.pdf}{pdf})} -\end{figure} - -\subsection{Conclusion} -\begin{important} -The main motion error are 1Hz X-Y translations and constant Ry error. -This is mainly due to finite stiffness of the elements. -\end{important} \section{Raster Scans with the translation stage} -\label{sec:ty_scans} -In this section, scans with the translation stage are performed. -\subsection{Simulation Setup} -We initialize the stages. -And we initialize the disturbances to zero. -We set the reference path to be a triangular signal for the Translation Stage. -We simulate the model. -And we save the obtained data. -We now set the reference path to be a sinusoidal signal for the Translation Stage. -We simulate the model. -And we save the obtained data. -\subsection{Analysis} -\begin{figure}[htbp] -\centering -\includegraphics[scale=1]{figs/exp_ty_scan.png} -\caption{\label{fig:exp_ty_scan}X-Y-Z translation of the sample w.r.t. granite when performing tomography experiment with no disturbances (\href{./figs/exp\_ty\_scan.png}{png}, \href{./figs/exp\_ty\_scan.pdf}{pdf})} -\end{figure} - -\subsection{Conclusion} -\begin{important} -Scans with the translation stage induces some errors in the Y direction and Rx translations. - -Also, scanning with a sinusoidal wave induces less position errors and at lower frequencies. -Thus, this should be preferred. -\end{important} \chapter{Conclusion} \label{sec:uniaxial_conclusion} - \printbibliography[heading=bibintoc,title={Bibliography}] \end{document}