diff --git a/figs/images/simscape_model_axisc.pdf b/figs/images/simscape_model_axisc.pdf new file mode 100644 index 0000000..4b2484b Binary files /dev/null and b/figs/images/simscape_model_axisc.pdf differ diff --git a/figs/images/simscape_model_axisc.png b/figs/images/simscape_model_axisc.png new file mode 100644 index 0000000..a2aeec5 Binary files /dev/null and b/figs/images/simscape_model_axisc.png differ diff --git a/figs/images/simscape_model_granite.pdf b/figs/images/simscape_model_granite.pdf new file mode 100644 index 0000000..d06ddf9 Binary files /dev/null and b/figs/images/simscape_model_granite.pdf differ diff --git a/figs/images/simscape_model_granite.png b/figs/images/simscape_model_granite.png new file mode 100644 index 0000000..7f3d7e4 Binary files /dev/null and b/figs/images/simscape_model_granite.png differ diff --git a/figs/images/simscape_model_ground.pdf b/figs/images/simscape_model_ground.pdf new file mode 100644 index 0000000..f9dfcf6 Binary files /dev/null and b/figs/images/simscape_model_ground.pdf differ diff --git a/figs/images/simscape_model_ground.png b/figs/images/simscape_model_ground.png new file mode 100644 index 0000000..4f7db57 Binary files /dev/null and b/figs/images/simscape_model_ground.png differ diff --git a/figs/images/simscape_model_micro_hexapod.png b/figs/images/simscape_model_micro_hexapod.png new file mode 100644 index 0000000..e9a9ad4 Binary files /dev/null and b/figs/images/simscape_model_micro_hexapod.png differ diff --git a/figs/images/simscape_model_mirror.pdf b/figs/images/simscape_model_mirror.pdf new file mode 100644 index 0000000..8adf364 Binary files /dev/null and b/figs/images/simscape_model_mirror.pdf differ diff --git a/figs/images/simscape_model_mirror.png b/figs/images/simscape_model_mirror.png new file mode 100644 index 0000000..d821f04 Binary files /dev/null and b/figs/images/simscape_model_mirror.png differ diff --git a/figs/images/simscape_model_nano_hexapod.png b/figs/images/simscape_model_nano_hexapod.png new file mode 100644 index 0000000..e9a9ad4 Binary files /dev/null and b/figs/images/simscape_model_nano_hexapod.png differ diff --git a/figs/images/simscape_model_ry.pdf b/figs/images/simscape_model_ry.pdf new file mode 100644 index 0000000..8c9d79f Binary files /dev/null and b/figs/images/simscape_model_ry.pdf differ diff --git a/figs/images/simscape_model_ry.png b/figs/images/simscape_model_ry.png new file mode 100644 index 0000000..235f582 Binary files /dev/null and b/figs/images/simscape_model_ry.png differ diff --git a/figs/images/simscape_model_rz.pdf b/figs/images/simscape_model_rz.pdf new file mode 100644 index 0000000..c98b230 Binary files /dev/null and b/figs/images/simscape_model_rz.pdf differ diff --git a/figs/images/simscape_model_rz.png b/figs/images/simscape_model_rz.png new file mode 100644 index 0000000..f4aafe6 Binary files /dev/null and b/figs/images/simscape_model_rz.png differ diff --git a/figs/images/simscape_model_sample.pdf b/figs/images/simscape_model_sample.pdf new file mode 100644 index 0000000..506e8ac Binary files /dev/null and b/figs/images/simscape_model_sample.pdf differ diff --git a/figs/images/simscape_model_sample.png b/figs/images/simscape_model_sample.png new file mode 100644 index 0000000..6d8787c Binary files /dev/null and b/figs/images/simscape_model_sample.png differ diff --git a/figs/images/simscape_model_ty.pdf b/figs/images/simscape_model_ty.pdf new file mode 100644 index 0000000..a0e58ba Binary files /dev/null and b/figs/images/simscape_model_ty.pdf differ diff --git a/figs/images/simscape_model_ty.png b/figs/images/simscape_model_ty.png new file mode 100644 index 0000000..e5bfb38 Binary files /dev/null and b/figs/images/simscape_model_ty.png differ diff --git a/figs/images/simscape_picture.png b/figs/images/simscape_picture.png new file mode 100644 index 0000000..a77fe07 Binary files /dev/null and b/figs/images/simscape_picture.png differ diff --git a/figs/images/simscape_picture_axisc.png b/figs/images/simscape_picture_axisc.png new file mode 100644 index 0000000..4147d96 Binary files /dev/null and b/figs/images/simscape_picture_axisc.png differ diff --git a/figs/images/simscape_picture_granite.png b/figs/images/simscape_picture_granite.png new file mode 100644 index 0000000..6d77fdf Binary files /dev/null and b/figs/images/simscape_picture_granite.png differ diff --git a/figs/images/simscape_picture_ground.png b/figs/images/simscape_picture_ground.png new file mode 100644 index 0000000..559dfb1 Binary files /dev/null and b/figs/images/simscape_picture_ground.png differ diff --git a/figs/images/simscape_picture_micro_hexapod.png b/figs/images/simscape_picture_micro_hexapod.png new file mode 100644 index 0000000..5eb73a5 Binary files /dev/null and b/figs/images/simscape_picture_micro_hexapod.png differ diff --git a/figs/images/simscape_picture_mirror.png b/figs/images/simscape_picture_mirror.png new file mode 100644 index 0000000..4a9f370 Binary files /dev/null and b/figs/images/simscape_picture_mirror.png differ diff --git a/figs/images/simscape_picture_nano_hexapod.png b/figs/images/simscape_picture_nano_hexapod.png new file mode 100644 index 0000000..32ffccd Binary files /dev/null and b/figs/images/simscape_picture_nano_hexapod.png differ diff --git a/figs/images/simscape_picture_ry.png b/figs/images/simscape_picture_ry.png new file mode 100644 index 0000000..c648f71 Binary files /dev/null and b/figs/images/simscape_picture_ry.png differ diff --git a/figs/images/simscape_picture_rz.png b/figs/images/simscape_picture_rz.png new file mode 100644 index 0000000..007d5b4 Binary files /dev/null and b/figs/images/simscape_picture_rz.png differ diff --git a/figs/images/simscape_picture_sample.png b/figs/images/simscape_picture_sample.png new file mode 100644 index 0000000..4598675 Binary files /dev/null and b/figs/images/simscape_picture_sample.png differ diff --git a/figs/images/simscape_picture_ty.png b/figs/images/simscape_picture_ty.png new file mode 100644 index 0000000..b97dfb8 Binary files /dev/null and b/figs/images/simscape_picture_ty.png differ diff --git a/simscape_subsystems/index.html b/simscape_subsystems/index.html index 6d75863..cf4a1c1 100644 --- a/simscape_subsystems/index.html +++ b/simscape_subsystems/index.html @@ -1,9 +1,10 @@ +
- ++The full Simscape Model is represented in Figure 1. +
+ + ++
+Figure 1: Screenshot of the Multi-Body Model representation
+This model is divided into multiple subsystems that are independent. +These subsystems are saved in separate files and imported in the main file using a block balled “subsystem reference”. +
+ ++Each stage is configured (geometry, mass properties, dynamic properties …) using one function. +
+ ++These functions are defined below. +
+ ++The model of the Ground is composed of: +
++
+Figure 2: Simscape model for the Ground
++
+Figure 3: Simscape picture for the Ground
+function [ground] = initializeGround() ++
-
+First, we initialize the granite
structure.
-This Matlab function is accessible here. -
-function [ref] = initializeReferences(opts_param) - %% Default values for opts - opts = struct( ... - 'Ts', 1e-3, ... % Sampling Frequency [s] - 'Dy_type', 'constant', ... % Either "constant" / "triangular" / "sinusoidal" - 'Dy_amplitude', 0, ... % Amplitude of the displacement [m] - 'Dy_period', 1, ... % Period of the displacement [s] - 'Ry_type', 'constant', ... % Either "constant" / "triangular" / "sinusoidal" - 'Ry_amplitude', 0, ... % Amplitude [rad] - 'Ry_period', 10, ... % Period of the displacement [s] - 'Rz_type', 'constant', ... % Either "constant" / "rotating" - 'Rz_amplitude', 0, ... % Initial angle [rad] - 'Rz_period', 1, ... % Period of the rotating [s] - 'Dh_type', 'constant', ... % For now, only constant is implemented - 'Dh_pos', [0; 0; 0; 0; 0; 0], ... % Initial position [m,m,m,rad,rad,rad] of the top platform (Pitch-Roll-Yaw Euler angles) - 'Rm_type', 'constant', ... % For now, only constant is implemented - 'Rm_pos', [0; pi], ... % Initial position of the two masses - 'Dn_type', 'constant', ... % For now, only constant is implemented - 'Dn_pos', [0; 0; 0; 0; 0; 0] ... % Initial position [m,m,m,rad,rad,rad] of the top platform - ); - - %% Populate opts with input parameters - if exist('opts_param','var') - for opt = fieldnames(opts_param)' - opts.(opt{1}) = opts_param.(opt{1}); - end - end - - %% Set Sampling Time - Ts = opts.Ts; - - %% Translation stage - Dy - t = 0:Ts:opts.Dy_period-Ts; % Time Vector [s] - Dy = zeros(length(t), 1); - switch opts.Dy_type - case 'constant' - Dy(:) = opts.Dy_amplitude; - case 'triangular' - Dy(:) = -4*opts.Dy_amplitude + 4*opts.Dy_amplitude/opts.Dy_period*t; - Dy(t<0.75*opts.Dy_period) = 2*opts.Dy_amplitude - 4*opts.Dy_amplitude/opts.Dy_period*t(t<0.75*opts.Dy_period); - Dy(t<0.25*opts.Dy_period) = 4*opts.Dy_amplitude/opts.Dy_period*t(t<0.25*opts.Dy_period); - case 'sinusoidal' - Dy(:) = opts.Dy_amplitude*sin(2*pi/opts.Dy_period*t); - otherwise - warning('Dy_type is not set correctly'); - end - Dy = struct('time', t, 'signals', struct('values', Dy)); - - - %% Tilt Stage - Ry - t = 0:Ts:opts.Ry_period-Ts; - Ry = zeros(length(t), 1); - - switch opts.Ry_type - case 'constant' - Ry(:) = opts.Ry_amplitude; - case 'triangular' - Ry(:) = -4*opts.Ry_amplitude + 4*opts.Ry_amplitude/opts.Ry_period*t; - Ry(t<0.75*opts.Ry_period) = 2*opts.Ry_amplitude - 4*opts.Ry_amplitude/opts.Ry_period*t(t<0.75*opts.Ry_period); - Ry(t<0.25*opts.Ry_period) = 4*opts.Ry_amplitude/opts.Ry_period*t(t<0.25*opts.Ry_period); - case 'sinusoidal' - - otherwise - warning('Ry_type is not set correctly'); - end - Ry = struct('time', t, 'signals', struct('values', Ry)); - - %% Spindle - Rz - t = 0:Ts:opts.Rz_period-Ts; - Rz = zeros(length(t), 1); - - switch opts.Rz_type - case 'constant' - Rz(:) = opts.Rz_amplitude; - case 'rotating' - Rz(:) = opts.Rz_amplitude+2*pi/opts.Rz_period*t; - otherwise - warning('Rz_type is not set correctly'); - end - Rz = struct('time', t, 'signals', struct('values', Rz)); - - %% Micro-Hexapod - t = [0, Ts]; - Dh = zeros(length(t), 6); - Dhl = zeros(length(t), 6); - - switch opts.Dh_type - case 'constant' - Dh = [opts.Dh_pos, opts.Dh_pos]; - - load('./mat/stages.mat', 'micro_hexapod'); - - AP = [opts.Dh_pos(1) ; opts.Dh_pos(2) ; opts.Dh_pos(3)]; - - tx = opts.Dh_pos(4); - ty = opts.Dh_pos(5); - tz = opts.Dh_pos(6); - - ARB = [cos(tz) -sin(tz) 0; - sin(tz) cos(tz) 0; - 0 0 1]*... - [ cos(ty) 0 sin(ty); - 0 1 0; - -sin(ty) 0 cos(ty)]*... - [1 0 0; - 0 cos(tx) -sin(tx); - 0 sin(tx) cos(tx)]; - - [Dhl] = inverseKinematicsHexapod(micro_hexapod, AP, ARB); - Dhl = [Dhl, Dhl]; - otherwise - warning('Dh_type is not set correctly'); - end - Dh = struct('time', t, 'signals', struct('values', Dh)); - Dhl = struct('time', t, 'signals', struct('values', Dhl)); - - %% Axis Compensation - Rm - t = [0, Ts]; - Rm = [opts.Rm_pos, opts.Rm_pos]; - Rm = struct('time', t, 'signals', struct('values', Rm)); - - %% Nano-Hexapod - t = [0, Ts]; - Dn = zeros(length(t), 6); - - switch opts.Dn_type - case 'constant' - Dn = [opts.Dn_pos, opts.Dn_pos]; - otherwise - warning('Dn_type is not set correctly'); - end - Dn = struct('time', t, 'signals', struct('values', Dn)); - - %% Save - save('./mat/nass_references.mat', 'Dy', 'Ry', 'Rz', 'Dh', 'Dhl', 'Rm', 'Dn', 'Ts'); -end +ground = struct();
-This Matlab function is accessible here. +We set the shape and density of the ground solid element.
-function [L] = inverseKinematicsHexapod(hexapod, AP, ARB) -% inverseKinematicsHexapod - Compute the initial position of each leg to have the wanted Hexapod's position -% -% Syntax: inverseKinematicsHexapod(hexapod, AP, ARB) -% -% Inputs: -% - hexapod - Hexapod object containing the geometry of the hexapod -% - AP - Position vector of point OB expressed in frame {A} in [m] -% - ARB - Rotation Matrix expressed in frame {A} +ground.shape = [2, 2, 0.5]; % [m] +ground.density = 2800; % [kg/m3] ++
+The ground
structure is saved.
+
save('./mat/stages.mat', 'ground', '-append');
- +The Simscape model of the granite is composed of:
+
-This Matlab function is accessible here.
+The output sample_pos
corresponds to the impact point of the X-ray.
+
+Figure 4: Simscape model for the Granite
++
+Figure 5: Simscape picture for the Granite
+function [ground] = initializeGround() - %% - ground = struct(); +function [granite] = initializeGranite(args) ++
arguments + args.density (1,1) double {mustBeNumeric, mustBeNonnegative} = 2800 % Density [kg/m3] + args.x0 (1,1) double {mustBeNumeric} = 0 % Rest position of the Joint in the X direction [m] + args.y0 (1,1) double {mustBeNumeric} = 0 % Rest position of the Joint in the Y direction [m] + args.z0 (1,1) double {mustBeNumeric} = 0 % Rest position of the Joint in the Z direction [m] end
-
+First, we initialize the granite
structure.
-This Matlab function is accessible here. -
-function [granite] = initializeGranite(opts_param) - %% Default values for opts - opts = struct('rigid', false); +granite = struct(); ++
+Properties of the Material and link to the geometry of the granite. +
+granite.density = args.density; % [kg/m3] +granite.STEP = './STEPS/granite/granite.STEP'; ++
+Stiffness of the connection with Ground. +
+granite.k.x = 4e9; % [N/m] +granite.k.y = 3e8; % [N/m] +granite.k.z = 8e8; % [N/m] ++
+Damping of the connection with Ground. +
+granite.c.x = 4.0e5; % [N/(m/s)] +granite.c.y = 1.1e5; % [N/(m/s)] +granite.c.z = 9.0e5; % [N/(m/s)] ++
+Equilibrium position of the Cartesian joint. +
+granite.x0 = args.x0; +granite.y0 = args.y0; +granite.z0 = args.z0; ++
+Z-offset for the initial position of the sample with respect to the granite top surface. +
+granite.sample_pos = 0.8; % [m]
+
+
+The granite
structure is saved.
+
save('./mat/stages.mat', 'granite', '-append'); ++
+The Simscape model of the Translation stage consist of: +
++
+Figure 6: Simscape model for the Translation Stage
++
+Figure 7: Simscape picture for the Translation Stage
+function [ty] = initializeTy(args) ++
arguments + args.x11 (1,1) double {mustBeNumeric} = 0 % [m] + args.z11 (1,1) double {mustBeNumeric} = 0 % [m] + args.x21 (1,1) double {mustBeNumeric} = 0 % [m] + args.z21 (1,1) double {mustBeNumeric} = 0 % [m] + args.x12 (1,1) double {mustBeNumeric} = 0 % [m] + args.z12 (1,1) double {mustBeNumeric} = 0 % [m] + args.x22 (1,1) double {mustBeNumeric} = 0 % [m] + args.z22 (1,1) double {mustBeNumeric} = 0 % [m] end
-
+First, we initialize the ty
structure.
-This Matlab function is accessible here. -
-function [ty] = initializeTy(opts_param) - %% Default values for opts - opts = struct('rigid', false); +ty = struct(); ++
+Define the density of the materials as well as the geometry (STEP files). +
+% Ty Granite frame +ty.granite_frame.density = 7800; % [kg/m3] => 43kg +ty.granite_frame.STEP = './STEPS/Ty/Ty_Granite_Frame.STEP'; - %% - ty = struct(); +% Guide Translation Ty +ty.guide.density = 7800; % [kg/m3] => 76kg +ty.guide.STEP = './STEPS/ty/Ty_Guide.STEP'; - %% Y-Translation - Static Properties - % Ty Granite frame - ty.granite_frame.density = 7800; % [kg/m3] - ty.granite_frame.color = [0.753 1 0.753]; - ty.granite_frame.STEP = './STEPS/Ty/Ty_Granite_Frame.STEP'; - % Guide Translation Ty - ty.guide.density = 7800; % [kg/m3] - ty.guide.color = [0.792 0.820 0.933]; - ty.guide.STEP = './STEPS/ty/Ty_Guide.STEP'; - % Ty - Guide_Translation12 - ty.guide12.density = 7800; % [kg/m3] - ty.guide12.color = [0.792 0.820 0.933]; - ty.guide12.STEP = './STEPS/Ty/Ty_Guide_12.STEP'; - % Ty - Guide_Translation11 - ty.guide11.density = 7800; % [kg/m3] - ty.guide11.color = [0.792 0.820 0.933]; - ty.guide11.STEP = './STEPS/ty/Ty_Guide_11.STEP'; - % Ty - Guide_Translation22 - ty.guide22.density = 7800; % [kg/m3] - ty.guide22.color = [0.792 0.820 0.933]; - ty.guide22.STEP = './STEPS/ty/Ty_Guide_22.STEP'; - % Ty - Guide_Translation21 - ty.guide21.density = 7800; % [kg/m3] - ty.guide21.color = [0.792 0.820 0.933]; - ty.guide21.STEP = './STEPS/Ty/Ty_Guide_21.STEP'; - % Ty - Plateau translation - ty.frame.density = 7800; % [kg/m3] - ty.frame.color = [0.792 0.820 0.933]; - ty.frame.STEP = './STEPS/ty/Ty_Stage.STEP'; - % Ty Stator Part - ty.stator.density = 5400; % [kg/m3] - ty.stator.color = [0.792 0.820 0.933]; - ty.stator.STEP = './STEPS/ty/Ty_Motor_Stator.STEP'; - % Ty Rotor Part - ty.rotor.density = 5400; % [kg/m3] - ty.rotor.color = [0.792 0.820 0.933]; - ty.rotor.STEP = './STEPS/ty/Ty_Motor_Rotor.STEP'; +% Ty - Guide_Translation12 +ty.guide12.density = 7800; % [kg/m3] +ty.guide12.STEP = './STEPS/Ty/Ty_Guide_12.STEP'; - ty.m = 1000; % TODO [kg] +% Ty - Guide_Translation11 +ty.guide11.density = 7800; % [kg/m3] +ty.guide11.STEP = './STEPS/ty/Ty_Guide_11.STEP'; - %% Y-Translation - Dynamicals Properties - if opts.rigid - ty.k.ax = 1e12; % Axial Stiffness for each of the 4 guidance (y) [N/m] - ty.k.rad = 1e12; % Radial Stiffness for each of the 4 guidance (x-z) [N/m] - else - ty.k.ax = 5e8; % Axial Stiffness for each of the 4 guidance (y) [N/m] - ty.k.rad = 5e7; % Radial Stiffness for each of the 4 guidance (x-z) [N/m] - end +% Ty - Guide_Translation22 +ty.guide22.density = 7800; % [kg/m3] +ty.guide22.STEP = './STEPS/ty/Ty_Guide_22.STEP'; - ty.c.ax = 0.1*sqrt(ty.k.ax*ty.m); - ty.c.rad = 0.1*sqrt(ty.k.rad*ty.m); +% Ty - Guide_Translation21 +ty.guide21.density = 7800; % [kg/m3] +ty.guide21.STEP = './STEPS/Ty/Ty_Guide_21.STEP'; - %% Save - save('./mat/stages.mat', 'ty', '-append'); +% Ty - Plateau translation +ty.frame.density = 7800; % [kg/m3] +ty.frame.STEP = './STEPS/ty/Ty_Stage.STEP'; + +% Ty Stator Part +ty.stator.density = 5400; % [kg/m3] +ty.stator.STEP = './STEPS/ty/Ty_Motor_Stator.STEP'; + +% Ty Rotor Part +ty.rotor.density = 5400; % [kg/m3] +ty.rotor.STEP = './STEPS/ty/Ty_Motor_Rotor.STEP'; ++
+Stiffness of the stage. +
+ty.k.ax = 5e8; % Axial Stiffness for each of the 4 guidance (y) [N/m] +ty.k.rad = 5e7; % Radial Stiffness for each of the 4 guidance (x-z) [N/m] ++
+Damping of the stage. +
+ty.c.ax = 70710; % [N/(m/s)] +ty.c.rad = 22360; % [N/(m/s)] ++
+Equilibrium position of the joints. +
+ty.x0_11 = args.x11; +ty.z0_11 = args.z11; +ty.x0_12 = args.x12; +ty.z0_12 = args.z12; +ty.x0_21 = args.x21; +ty.z0_21 = args.z21; +ty.x0_22 = args.x22; +ty.z0_22 = args.z22; ++
+The ty
structure is saved.
+
save('./mat/stages.mat', 'ty', '-append'); ++
+The Simscape model of the Tilt stage is composed of: +
++
+Figure 8: Simscape model for the Tilt Stage
++
+Figure 9: Simscape picture for the Tilt Stage
+function [ry] = initializeRy(args) ++
arguments + args.x11 (1,1) double {mustBeNumeric} = 0 % [m] + args.y11 (1,1) double {mustBeNumeric} = 0 % [m] + args.z11 (1,1) double {mustBeNumeric} = 0 % [m] + args.x12 (1,1) double {mustBeNumeric} = 0 % [m] + args.y12 (1,1) double {mustBeNumeric} = 0 % [m] + args.z12 (1,1) double {mustBeNumeric} = 0 % [m] + args.x21 (1,1) double {mustBeNumeric} = 0 % [m] + args.y21 (1,1) double {mustBeNumeric} = 0 % [m] + args.z21 (1,1) double {mustBeNumeric} = 0 % [m] + args.x22 (1,1) double {mustBeNumeric} = 0 % [m] + args.y22 (1,1) double {mustBeNumeric} = 0 % [m] + args.z22 (1,1) double {mustBeNumeric} = 0 % [m] end
-
+First, we initialize the ry
structure.
-This Matlab function is accessible here. -
-function [ry] = initializeRy(opts_param) - %% Default values for opts - opts = struct('rigid', false); +ry = struct(); ++
+Properties of the Material and link to the geometry of the Tilt stage. +
+% Ry - Guide for the tilt stage +ry.guide.density = 7800; % [kg/m3] +ry.guide.STEP = './STEPS/ry/Tilt_Guide.STEP'; - %% - ry = struct(); +% Ry - Rotor of the motor +ry.rotor.density = 2400; % [kg/m3] +ry.rotor.STEP = './STEPS/ry/Tilt_Motor_Axis.STEP'; - %% Tilt Stage - Static Properties - % Ry - Guide for the tilt stage - ry.guide.density = 7800; % [kg/m3] - ry.guide.color = [0.792 0.820 0.933]; - ry.guide.STEP = './STEPS/ry/Tilt_Guide.STEP'; - % Ry - Rotor of the motor - ry.rotor.density = 2400; % [kg/m3] - ry.rotor.color = [0.792 0.820 0.933]; - ry.rotor.STEP = './STEPS/ry/Tilt_Motor_Axis.STEP'; - % Ry - Motor - ry.motor.density = 3200; % [kg/m3] - ry.motor.color = [0.792 0.820 0.933]; - ry.motor.STEP = './STEPS/ry/Tilt_Motor.STEP'; - % Ry - Plateau Tilt - ry.stage.density = 7800; % [kg/m3] - ry.stage.color = [0.792 0.820 0.933]; - ry.stage.STEP = './STEPS/ry/Tilt_Stage.STEP'; +% Ry - Motor +ry.motor.density = 3200; % [kg/m3] +ry.motor.STEP = './STEPS/ry/Tilt_Motor.STEP'; - ry.m = 800; % TODO [kg] +% Ry - Plateau Tilt +ry.stage.density = 7800; % [kg/m3] +ry.stage.STEP = './STEPS/ry/Tilt_Stage.STEP'; ++
+Stiffness of the stage. +
+ry.k.tilt = 1e4; % Rotation stiffness around y [N*m/deg] +ry.k.h = 1e8; % Stiffness in the direction of the guidance [N/m] +ry.k.rad = 1e8; % Stiffness in the top direction [N/m] +ry.k.rrad = 1e8; % Stiffness in the side direction [N/m] ++
+Damping of the stage. +
+ry.c.tilt = 2.8e2; +ry.c.h = 2.8e4; +ry.c.rad = 2.8e4; +ry.c.rrad = 2.8e4; ++
+Equilibrium position of the joints. +
+ry.x0_11 = args.x11; +ry.y0_11 = args.y11; +ry.z0_11 = args.z11; +ry.x0_12 = args.x12; +ry.y0_12 = args.y12; +ry.z0_12 = args.z12; +ry.x0_21 = args.x21; +ry.y0_21 = args.y21; +ry.z0_21 = args.z21; +ry.x0_22 = args.x22; +ry.y0_22 = args.y22; +ry.z0_22 = args.z22; ++
+Z-Offset so that the center of rotation matches the sample center; +
+ry.z_offset = 0.58178; % [m]
+
+
+The ty
structure is saved.
+
save('./mat/stages.mat', 'ry', '-append'); ++
+The Simscape model of the Spindle is composed of: +
++
+Figure 10: Simscape model for the Spindle
++
+Figure 11: Simscape picture for the Spindle
+function [rz] = initializeRz(args) ++
arguments + args.rigid logical {mustBeNumericOrLogical} = false + args.x0 (1,1) double {mustBeNumeric} = 0 % [m] + args.y0 (1,1) double {mustBeNumeric} = 0 % [m] + args.z0 (1,1) double {mustBeNumeric} = 0 % [m] + args.rx0 (1,1) double {mustBeNumeric} = 0 % [rad] + args.ry0 (1,1) double {mustBeNumeric} = 0 % [rad] end
-
+First, we initialize the rz
structure.
-This Matlab function is accessible here. -
-function [rz] = initializeRz(opts_param) - %% Default values for opts - opts = struct('rigid', false); +rz = struct(); ++
+Properties of the Material and link to the geometry of the spindle. +
+% Spindle - Slip Ring +rz.slipring.density = 7800; % [kg/m3] +rz.slipring.STEP = './STEPS/rz/Spindle_Slip_Ring.STEP'; - %% - rz = struct(); +% Spindle - Rotor +rz.rotor.density = 7800; % [kg/m3] +rz.rotor.STEP = './STEPS/rz/Spindle_Rotor.STEP'; - %% Spindle - Static Properties - % Spindle - Slip Ring - rz.slipring.density = 7800; % [kg/m3] - rz.slipring.color = [0.792 0.820 0.933]; - rz.slipring.STEP = './STEPS/rz/Spindle_Slip_Ring.STEP'; - % Spindle - Rotor - rz.rotor.density = 7800; % [kg/m3] - rz.rotor.color = [0.792 0.820 0.933]; - rz.rotor.STEP = './STEPS/rz/Spindle_Rotor.STEP'; - % Spindle - Stator - rz.stator.density = 7800; % [kg/m3] - rz.stator.color = [0.792 0.820 0.933]; - rz.stator.STEP = './STEPS/rz/Spindle_Stator.STEP'; +% Spindle - Stator +rz.stator.density = 7800; % [kg/m3] +rz.stator.STEP = './STEPS/rz/Spindle_Stator.STEP'; ++
+Stiffness of the stage. +
+rz.k.rot = 1e6; % TODO - Rotational Stiffness (Rz) [N*m/deg] +rz.k.tilt = 1e6; % Rotational Stiffness (Rx, Ry) [N*m/deg] +rz.k.ax = 2e9; % Axial Stiffness (Z) [N/m] +rz.k.rad = 7e8; % Radial Stiffness (X, Y) [N/m] ++
+Damping of the stage. +
+rz.c.rot = 1.6e3; +rz.c.tilt = 1.6e3; +rz.c.ax = 7.1e4; +rz.c.rad = 4.2e4; ++
+Equilibrium position of the joints. +
+rz.x0 = args.x0; +rz.y0 = args.y0; +rz.z0 = args.z0; +rz.rx0 = args.rx0; +rz.ry0 = args.ry0; ++
+The rz
structure is saved.
+
save('./mat/stages.mat', 'rz', '-append'); ++
+
+Figure 12: Simscape model for the Micro-Hexapod
++
+Figure 13: Simscape picture for the Micro-Hexapod
+function [micro_hexapod] = initializeMicroHexapod(args) ++
arguments + % initializeFramesPositions + args.H (1,1) double {mustBeNumeric, mustBePositive} = 350e-3 + args.MO_B (1,1) double {mustBeNumeric} = 270e-3 + % generateGeneralConfiguration + args.FH (1,1) double {mustBeNumeric, mustBePositive} = 50e-3 + args.FR (1,1) double {mustBeNumeric, mustBePositive} = 175.5e-3 + args.FTh (6,1) double {mustBeNumeric} = [-10, 10, 120-10, 120+10, 240-10, 240+10]*(pi/180) + args.MH (1,1) double {mustBeNumeric, mustBePositive} = 45e-3 + args.MR (1,1) double {mustBeNumeric, mustBePositive} = 118e-3 + args.MTh (6,1) double {mustBeNumeric} = [-60+10, 60-10, 60+10, 180-10, 180+10, -60-10]*(pi/180) + % initializeStrutDynamics + args.Ki (6,1) double {mustBeNumeric, mustBeNonnegative} = 2e7*ones(6,1) + args.Ci (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.4e3*ones(6,1) + % initializeCylindricalPlatforms + args.Fpm (1,1) double {mustBeNumeric, mustBePositive} = 10 + args.Fph (1,1) double {mustBeNumeric, mustBePositive} = 26e-3 + args.Fpr (1,1) double {mustBeNumeric, mustBePositive} = 207.5e-3 + args.Mpm (1,1) double {mustBeNumeric, mustBePositive} = 10 + args.Mph (1,1) double {mustBeNumeric, mustBePositive} = 26e-3 + args.Mpr (1,1) double {mustBeNumeric, mustBePositive} = 150e-3 + % initializeCylindricalStruts + args.Fsm (1,1) double {mustBeNumeric, mustBePositive} = 1 + args.Fsh (1,1) double {mustBeNumeric, mustBePositive} = 100e-3 + args.Fsr (1,1) double {mustBeNumeric, mustBePositive} = 25e-3 + args.Msm (1,1) double {mustBeNumeric, mustBePositive} = 1 + args.Msh (1,1) double {mustBeNumeric, mustBePositive} = 100e-3 + args.Msr (1,1) double {mustBeNumeric, mustBePositive} = 25e-3 + % inverseKinematics + args.AP (3,1) double {mustBeNumeric} = zeros(3,1) + args.ARB (3,3) double {mustBeNumeric} = eye(3) + % Equilibrium position of each leg + args.dLeq (6,1) double {mustBeNumeric} = zeros(6,1) end
-This Matlab function is accessible here. -
- +function [micro_hexapod] = initializeMicroHexapod(opts_param) - %% Default values for opts - opts = struct(... - 'rigid', false, ... - 'AP', zeros(3, 1), ... % Wanted position in [m] of OB with respect to frame {A} - 'ARB', eye(3) ... % Rotation Matrix that represent the wanted orientation of frame {B} with respect to frame {A} - ); +micro_hexapod = initializeFramesPositions('H', args.H, 'MO_B', args.MO_B); +micro_hexapod = generateGeneralConfiguration(micro_hexapod, 'FH', args.FH, 'FR', args.FR, 'FTh', args.FTh, 'MH', args.MH, 'MR', args.MR, 'MTh', args.MTh); +micro_hexapod = computeJointsPose(micro_hexapod); +micro_hexapod = initializeStrutDynamics(micro_hexapod, 'Ki', args.Ki, 'Ci', args.Ci); +micro_hexapod = initializeCylindricalPlatforms(micro_hexapod, 'Fpm', args.Fpm, 'Fph', args.Fph, 'Fpr', args.Fpr, 'Mpm', args.Mpm, 'Mph', args.Mph, 'Mpr', args.Mpr); +micro_hexapod = initializeCylindricalStruts(micro_hexapod, 'Fsm', args.Fsm, 'Fsh', args.Fsh, 'Fsr', args.Fsr, 'Msm', args.Msm, 'Msh', args.Msh, 'Msr', args.Msr); +micro_hexapod = computeJacobian(micro_hexapod); +[Li, dLi] = inverseKinematics(micro_hexapod, 'AP', args.AP, 'ARB', args.ARB); +micro_hexapod.Li = Li; +micro_hexapod.dLi = dLi; ++
+Equilibrium position of the each joint. +
+micro_hexapod.dLeq = args.dLeq; ++
+The micro_hexapod
structure is saved.
+
save('./mat/stages.mat', 'micro_hexapod', '-append'); ++
+The Simscape model of the Center of gravity compensator is composed of: +
++
+Figure 14: Simscape model for the Center of Mass compensation system
++
+Figure 15: Simscape picture for the Center of Mass compensation system
+function [axisc] = initializeAxisc() ++
+First, we initialize the axisc
structure.
+
axisc = struct(); ++
+Properties of the Material and link to the geometry files. +
+% Structure +axisc.structure.density = 3400; % [kg/m3] +axisc.structure.STEP = './STEPS/axisc/axisc_structure.STEP'; + +% Wheel +axisc.wheel.density = 2700; % [kg/m3] +axisc.wheel.STEP = './STEPS/axisc/axisc_wheel.STEP'; + +% Mass +axisc.mass.density = 7800; % [kg/m3] +axisc.mass.STEP = './STEPS/axisc/axisc_mass.STEP'; + +% Gear +axisc.gear.density = 7800; % [kg/m3] +axisc.gear.STEP = './STEPS/axisc/axisc_gear.STEP'; ++
+The axisc
structure is saved.
+
save('./mat/stages.mat', 'axisc', '-append'); ++
+The Simscape Model of the mirror is just a solid body.
+The output mirror_center
corresponds to the center of the Sphere and is the point of measurement for the metrology
+
+
+Figure 16: Simscape model for the Mirror
++
+Figure 17: Simscape picture for the Mirror
+function [] = initializeMirror(args) ++
arguments + args.shape char {mustBeMember(args.shape,{'spherical', 'conical'})} = 'spherical' + args.angle (1,1) double {mustBeNumeric, mustBePositive} = 45 % [deg] end
-
+First, we initialize the mirror
structure.
mirror = struct(); ++
-This Matlab function is accessible here. +We define the geometrical values.
+mirror.h = 50; % Height of the mirror [mm] +mirror.thickness = 25; % Thickness of the plate supporting the sample [mm] +mirror.hole_rad = 120; % radius of the hole in the mirror [mm] +mirror.support_rad = 100; % radius of the support plate [mm] +mirror.jacobian = 150; % point of interest offset in z (above the top surfave) [mm] +mirror.rad = 180; % radius of the mirror (at the bottom surface) [mm] ++
function [axisc] = initializeAxisc()
- %%
- axisc = struct();
+mirror.density = 2400; % Density of the material [kg/m3]
+
+
mirror.cone_length = mirror.rad*tand(args.angle)+mirror.h+mirror.jacobian; % Distance from Apex point of the cone to jacobian point ++
+Now we define the Shape of the mirror. +We first start with the internal part. +
+mirror.shape = [... + 0 mirror.h-mirror.thickness + mirror.hole_rad mirror.h-mirror.thickness; ... + mirror.hole_rad 0; ... + mirror.rad 0 ... +]; ++
+Then, we define the reflective used part of the mirror. +
+if strcmp(args.shape, 'spherical') + mirror.sphere_radius = sqrt((mirror.jacobian+mirror.h)^2+mirror.rad^2); % Radius of the sphere [mm] - %% Save - save('./mat/stages.mat', 'axisc', '-append'); + for z = linspace(0, mirror.h, 101) + mirror.shape = [mirror.shape; sqrt(mirror.sphere_radius^2-(z-mirror.jacobian-mirror.h)^2) z]; + end +elseif strcmp(args.shape, 'conical') + mirror.shape = [mirror.shape; mirror.rad+mirror.h/tand(args.angle) mirror.h]; +else + error('Shape should be either conical or spherical'); +end ++
+Finally, we close the shape. +
+mirror.shape = [mirror.shape; 0 mirror.h]; ++
+The mirror
structure is saved.
+
save('./mat/stages.mat', 'mirror', '-append'); ++
+
+Figure 18: Simscape model for the Nano Hexapod
++
+Figure 19: Simscape picture for the Nano Hexapod
+function [nano_hexapod] = initializeNanoHexapod(args) ++
arguments + % initializeFramesPositions + args.H (1,1) double {mustBeNumeric, mustBePositive} = 90e-3 + args.MO_B (1,1) double {mustBeNumeric} = 175e-3 + % generateGeneralConfiguration + args.FH (1,1) double {mustBeNumeric, mustBePositive} = 15e-3 + args.FR (1,1) double {mustBeNumeric, mustBePositive} = 100e-3 + args.FTh (6,1) double {mustBeNumeric} = [-10, 10, 120-10, 120+10, 240-10, 240+10]*(pi/180) + args.MH (1,1) double {mustBeNumeric, mustBePositive} = 15e-3 + args.MR (1,1) double {mustBeNumeric, mustBePositive} = 90e-3 + args.MTh (6,1) double {mustBeNumeric} = [-60+10, 60-10, 60+10, 180-10, 180+10, -60-10]*(pi/180) + % initializeStrutDynamics + args.actuator char {mustBeMember(args.actuator,{'piezo', 'lorentz'})} = 'piezo' + % initializeCylindricalPlatforms + args.Fpm (1,1) double {mustBeNumeric, mustBePositive} = 1 + args.Fph (1,1) double {mustBeNumeric, mustBePositive} = 10e-3 + args.Fpr (1,1) double {mustBeNumeric, mustBePositive} = 150e-3 + args.Mpm (1,1) double {mustBeNumeric, mustBePositive} = 1 + args.Mph (1,1) double {mustBeNumeric, mustBePositive} = 10e-3 + args.Mpr (1,1) double {mustBeNumeric, mustBePositive} = 100e-3 + % initializeCylindricalStruts + args.Fsm (1,1) double {mustBeNumeric, mustBePositive} = 0.1 + args.Fsh (1,1) double {mustBeNumeric, mustBePositive} = 50e-3 + args.Fsr (1,1) double {mustBeNumeric, mustBePositive} = 5e-3 + args.Msm (1,1) double {mustBeNumeric, mustBePositive} = 0.1 + args.Msh (1,1) double {mustBeNumeric, mustBePositive} = 50e-3 + args.Msr (1,1) double {mustBeNumeric, mustBePositive} = 5e-3 + % inverseKinematics + args.AP (3,1) double {mustBeNumeric} = zeros(3,1) + args.ARB (3,3) double {mustBeNumeric} = eye(3) + % Equilibrium position of each leg + args.dLeq (6,1) double {mustBeNumeric} = zeros(6,1) end
-This Matlab function is accessible here. -
+nano_hexapod = initializeFramesPositions('H', args.H, 'MO_B', args.MO_B); +nano_hexapod = generateGeneralConfiguration(nano_hexapod, 'FH', args.FH, 'FR', args.FR, 'FTh', args.FTh, 'MH', args.MH, 'MR', args.MR, 'MTh', args.MTh); +nano_hexapod = computeJointsPose(nano_hexapod); +if strcmp(args.actuator, 'piezo') + nano_hexapod = initializeStrutDynamics(nano_hexapod, 'Ki', 1e7*ones(6,1), 'Ci', 1e2*ones(6,1)); +elseif strcmp(args.actuator, 'lorentz') + nano_hexapod = initializeStrutDynamics(nano_hexapod, 'Ki', 1e4*ones(6,1), 'Ci', 1e2*ones(6,1)); +else + error('args.actuator should be piezo or lorentz'); +end +nano_hexapod = initializeCylindricalPlatforms(nano_hexapod, 'Fpm', args.Fpm, 'Fph', args.Fph, 'Fpr', args.Fpr, 'Mpm', args.Mpm, 'Mph', args.Mph, 'Mpr', args.Mpr); +nano_hexapod = initializeCylindricalStruts(nano_hexapod, 'Fsm', args.Fsm, 'Fsh', args.Fsh, 'Fsr', args.Fsr, 'Msm', args.Msm, 'Msh', args.Msh, 'Msr', args.Msr); +nano_hexapod = computeJacobian(nano_hexapod); +[Li, dLi] = inverseKinematics(nano_hexapod, 'AP', args.AP, 'ARB', args.ARB); +nano_hexapod.Li = Li; +nano_hexapod.dLi = dLi; ++
function [] = initializeMirror(opts_param) - %% Default values for opts - opts = struct(... - 'shape', 'spherical', ... % spherical or conical - 'angle', 45 ... - ); +nano_hexapod.dLeq = args.dLeq; ++
save('./mat/stages.mat', 'nano_hexapod', '-append'); ++
+The Simscape model of the sample environment is composed of: +
++
+Figure 20: Simscape model for the Sample
++
+Figure 21: Simscape picture for the Sample
+function [sample] = initializeSample(args) ++
arguments + args.radius (1,1) double {mustBeNumeric, mustBePositive} = 0.1 % [m] + args.height (1,1) double {mustBeNumeric, mustBePositive} = 0.3 % [m] + args.mass (1,1) double {mustBeNumeric, mustBePositive} = 50 % [kg] + args.freq (1,1) double {mustBeNumeric, mustBePositive} = 100 % [Hz] + args.offset (1,1) double {mustBeNumeric} = 0 % [m] + args.x0 (1,1) double {mustBeNumeric} = 0 % [m] + args.y0 (1,1) double {mustBeNumeric} = 0 % [m] + args.z0 (1,1) double {mustBeNumeric} = 0 % [m] end
-
+First, we initialize the sample
structure.
-This Matlab function is accessible here. -
-function [nano_hexapod] = initializeNanoHexapod(opts_param) - %% Default values for opts - opts = struct('actuator', 'piezo'); +sample = struct(); ++
+We define the geometrical parameters of the sample as well as its mass and position. +
+sample.radius = args.radius; % [m] +sample.height = args.height; % [m] +sample.mass = args.mass; % [kg] +sample.offset = args.offset; % [m] ++
+Stiffness of the sample fixation. +
+sample.k.x = sample.mass * (2*pi * args.freq)^2; % [N/m] +sample.k.y = sample.mass * (2*pi * args.freq)^2; % [N/m] +sample.k.z = sample.mass * (2*pi * args.freq)^2; % [N/m] ++
+Damping of the sample fixation. +
+sample.c.x = 0.1*sqrt(sample.k.x*sample.mass); % [N/(m/s)] +sample.c.y = 0.1*sqrt(sample.k.y*sample.mass); % [N/(m/s)] +sample.c.z = 0.1*sqrt(sample.k.z*sample.mass); % [N/(m/s)] ++
+Equilibrium position of the Cartesian joint corresponding to the sample fixation. +
+sample.x0 = args.x0; % [m] +sample.y0 = args.y0; % [m] +sample.z0 = args.z0; % [m] ++
+The sample
structure is saved.
+
save('./mat/stages.mat', 'sample', '-append'); ++
function [ref] = initializeReferences(args) ++
arguments + % Sampling Frequency [s] + args.Ts (1,1) double {mustBeNumeric, mustBePositive} = 1e-3 + % Maximum simulation time [s] + args.Tmax (1,1) double {mustBeNumeric, mustBePositive} = 100 + % Either "constant" / "triangular" / "sinusoidal" + args.Dy_type char {mustBeMember(args.Dy_type,{'constant', 'triangular', 'sinusoidal'})} = 'constant' + % Amplitude of the displacement [m] + args.Dy_amplitude (1,1) double {mustBeNumeric} = 0 + % Period of the displacement [s] + args.Dy_period (1,1) double {mustBeNumeric, mustBePositive} = 1 + % Either "constant" / "triangular" / "sinusoidal" + args.Ry_type char {mustBeMember(args.Ry_type,{'constant', 'triangular', 'sinusoidal'})} = 'constant' + % Amplitude [rad] + args.Ry_amplitude (1,1) double {mustBeNumeric} = 0 + % Period of the displacement [s] + args.Ry_period (1,1) double {mustBeNumeric, mustBePositive} = 1 + % Either "constant" / "rotating" + args.Rz_type char {mustBeMember(args.Rz_type,{'constant', 'rotating'})} = 'constant' + % Initial angle [rad] + args.Rz_amplitude (1,1) double {mustBeNumeric} = 0 + % Period of the rotating [s] + args.Rz_period (1,1) double {mustBeNumeric, mustBePositive} = 1 + % For now, only constant is implemented + args.Dh_type char {mustBeMember(args.Dh_type,{'constant'})} = 'constant' + % Initial position [m,m,m,rad,rad,rad] of the top platform (Pitch-Roll-Yaw Euler angles) + args.Dh_pos (6,1) double {mustBeNumeric} = zeros(6, 1), ... + % For now, only constant is implemented + args.Rm_type char {mustBeMember(args.Rm_type,{'constant'})} = 'constant' + % Initial position of the two masses + args.Rm_pos (2,1) double {mustBeNumeric} = [0; pi] + % For now, only constant is implemented + args.Dn_type char {mustBeMember(args.Dn_type,{'constant'})} = 'constant' + % Initial position [m,m,m,rad,rad,rad] of the top platform + args.Dn_pos (6,1) double {mustBeNumeric} = zeros(6,1) end
%% Set Sampling Time +Ts = args.Ts; +Tmax = args.Tmax; + +%% Low Pass Filter to filter out the references +s = zpk('s'); +w0 = 2*pi*10; +xi = 1; +H_lpf = 1/(1 + 2*xi/w0*s + s^2/w0^2); ++
%% Translation stage - Dy +t = 0:Ts:Tmax; % Time Vector [s] +Dy = zeros(length(t), 1); +Dyd = zeros(length(t), 1); +Dydd = zeros(length(t), 1); +switch args.Dy_type + case 'constant' + Dy(:) = args.Dy_amplitude; + Dyd(:) = 0; + Dydd(:) = 0; + case 'triangular' + % This is done to unsure that we start with no displacement + Dy_raw = args.Dy_amplitude*sawtooth(2*pi*t/args.Dy_period,1/2); + i0 = find(t>=args.Dy_period/4,1); + Dy(1:end-i0+1) = Dy_raw(i0:end); + Dy(end-i0+2:end) = Dy_raw(end); % we fix the last value + + % The signal is filtered out + Dy = lsim(H_lpf, Dy, t); + Dyd = lsim(H_lpf*s, Dy, t); + Dydd = lsim(H_lpf*s^2, Dy, t); + case 'sinusoidal' + Dy(:) = args.Dy_amplitude*sin(2*pi/args.Dy_period*t); + Dyd = args.Dy_amplitude*2*pi/args.Dy_period*cos(2*pi/args.Dy_period*t); + Dydd = -args.Dy_amplitude*(2*pi/args.Dy_period)^2*sin(2*pi/args.Dy_period*t); + otherwise + warning('Dy_type is not set correctly'); +end + +Dy = struct('time', t, 'signals', struct('values', Dy), 'deriv', Dyd, 'dderiv', Dydd); ++
%% Tilt Stage - Ry +t = 0:Ts:Tmax; % Time Vector [s] +Ry = zeros(length(t), 1); +Ryd = zeros(length(t), 1); +Rydd = zeros(length(t), 1); + +switch args.Ry_type + case 'constant' + Ry(:) = args.Ry_amplitude; + Ryd(:) = 0; + Rydd(:) = 0; + case 'triangular' + Ry_raw = args.Ry_amplitude*sawtooth(2*pi*t/args.Ry_period,1/2); + i0 = find(t>=args.Ry_period/4,1); + Ry(1:end-i0+1) = Ry_raw(i0:end); + Ry(end-i0+2:end) = Ry_raw(end); % we fix the last value + + % The signal is filtered out + Ry = lsim(H_lpf, Ry, t); + Ryd = lsim(H_lpf*s, Ry, t); + Rydd = lsim(H_lpf*s^2, Ry, t); + case 'sinusoidal' + Ry(:) = args.Ry_amplitude*sin(2*pi/args.Ry_period*t); + + Ryd = args.Ry_amplitude*2*pi/args.Ry_period*cos(2*pi/args.Ry_period*t); + Rydd = -args.Ry_amplitude*(2*pi/args.Ry_period)^2*sin(2*pi/args.Ry_period*t); + otherwise + warning('Ry_type is not set correctly'); +end + +Ry = struct('time', t, 'signals', struct('values', Ry), 'deriv', Ryd, 'dderiv', Rydd); ++
%% Spindle - Rz +t = 0:Ts:Tmax; % Time Vector [s] +Rz = zeros(length(t), 1); +Rzd = zeros(length(t), 1); +Rzdd = zeros(length(t), 1); + +switch args.Rz_type + case 'constant' + Rz(:) = args.Rz_amplitude; + Rzd(:) = 0; + Rzdd(:) = 0; + case 'rotating' + Rz(:) = args.Rz_amplitude+2*pi/args.Rz_period*t; + + % The signal is filtered out + Rz = lsim(H_lpf, Rz, t); + Rzd = lsim(H_lpf*s, Rz, t); + Rzdd = lsim(H_lpf*s^2, Rz, t); + otherwise + warning('Rz_type is not set correctly'); +end + +Rz = struct('time', t, 'signals', struct('values', Rz), 'deriv', Rzd, 'dderiv', Rzdd); ++
%% Micro-Hexapod +t = [0, Ts]; +Dh = zeros(length(t), 6); +Dhl = zeros(length(t), 6); + +switch args.Dh_type + case 'constant' + Dh = [args.Dh_pos, args.Dh_pos]; + + load('mat/stages.mat', 'micro_hexapod'); + + AP = [args.Dh_pos(1) ; args.Dh_pos(2) ; args.Dh_pos(3)]; + + tx = args.Dh_pos(4); + ty = args.Dh_pos(5); + tz = args.Dh_pos(6); + + ARB = [cos(tz) -sin(tz) 0; + sin(tz) cos(tz) 0; + 0 0 1]*... + [ cos(ty) 0 sin(ty); + 0 1 0; + -sin(ty) 0 cos(ty)]*... + [1 0 0; + 0 cos(tx) -sin(tx); + 0 sin(tx) cos(tx)]; + + [~, Dhl] = inverseKinematics(micro_hexapod, 'AP', AP, 'ARB', ARB); + Dhl = [Dhl, Dhl]; + otherwise + warning('Dh_type is not set correctly'); +end + +Dh = struct('time', t, 'signals', struct('values', Dh)); +Dhl = struct('time', t, 'signals', struct('values', Dhl)); ++
%% Axis Compensation - Rm +t = [0, Ts]; + +Rm = [args.Rm_pos, args.Rm_pos]; +Rm = struct('time', t, 'signals', struct('values', Rm)); ++
%% Nano-Hexapod +t = [0, Ts]; +Dn = zeros(length(t), 6); + +switch args.Dn_type + case 'constant' + Dn = [args.Dn_pos, args.Dn_pos]; + otherwise + warning('Dn_type is not set correctly'); +end + +Dn = struct('time', t, 'signals', struct('values', Dn)); ++
%% Save + save('mat/nass_references.mat', 'Dy', 'Ry', 'Rz', 'Dh', 'Dhl', 'Rm', 'Dn', 'Ts'); +end ++
function [] = initializeDisturbances(args) +% initializeDisturbances - Initialize the disturbances +% +% Syntax: [] = initializeDisturbances(args) +% +% Inputs: +% - args - + ++
arguments + % Global parameter to enable or disable the disturbances + args.enable logical {mustBeNumericOrLogical} = true + % Ground Motion - X direction + args.Dwx logical {mustBeNumericOrLogical} = true + % Ground Motion - Y direction + args.Dwy logical {mustBeNumericOrLogical} = true + % Ground Motion - Z direction + args.Dwz logical {mustBeNumericOrLogical} = true + % Translation Stage - X direction + args.Fty_x logical {mustBeNumericOrLogical} = true + % Translation Stage - Z direction + args.Fty_z logical {mustBeNumericOrLogical} = true + % Spindle - Z direction + args.Frz_z logical {mustBeNumericOrLogical} = true +end ++
load('./disturbances/mat/dist_psd.mat', 'dist_f'); ++
-This Matlab function is accessible here. +We remove the first frequency point that usually is very large.
++We define some parameters that will be used in the algorithm. +
+Fs = 2*dist_f.f(end); % Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz] +N = 2*length(dist_f.f); % Number of Samples match the one of the wanted PSD +T0 = N/Fs; % Signal Duration [s] +df = 1/T0; % Frequency resolution of the DFT [Hz] + % Also equal to (dist_f.f(2)-dist_f.f(1)) +t = linspace(0, T0, N+1)'; % Time Vector [s] +Ts = 1/Fs; % Sampling Time [s] ++
phi = dist_f.psd_gm; +C = zeros(N/2,1); +for i = 1:N/2 + C(i) = sqrt(phi(i)*df); +end ++
function [cedrat] = initializeCedratPiezo(opts_param) - %% Default values for opts - opts = struct(); +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)))];; + Dwx = N/sqrt(2)*ifft(Cx); % Ground Motion - x direction [m] +else + Dwx = zeros(length(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)))];; + Dwy = N/sqrt(2)*ifft(Cx); % Ground Motion - y direction [m] +else + Dwy = zeros(length(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)))];; + Dwz = N/sqrt(2)*ifft(Cx); % Ground Motion - z direction [m] +else + Dwz = zeros(length(t), 1); +end ++
if args.Fty_x && args.enable + phi = dist_f.psd_ty; % TODO - we take here the vertical direction which is wrong but approximate + C = zeros(N/2,1); + for i = 1:N/2 + C(i) = sqrt(phi(i)*df); end - - %% Stewart Object - cedrat = struct(); - cedrat.k = 10e7; % Linear Stiffness of each "blade" [N/m] - cedrat.ka = 10e7; % Linear Stiffness of the stack [N/m] - - cedrat.c = 0.1*sqrt(1*cedrat.k); % [N/(m/s)] - cedrat.ca = 0.1*sqrt(1*cedrat.ka); % [N/(m/s)] - - cedrat.L = 80; % Total Width of the Actuator[mm] - cedrat.H = 45; % Total Height of the Actuator [mm] - cedrat.L2 = sqrt((cedrat.L/2)^2 + (cedrat.H/2)^2); % Length of the elipsoidal sections [mm] - cedrat.alpha = 180/pi*atan2(cedrat.L/2, cedrat.H/2); % [deg] - - %% Save - save('./mat/stages.mat', 'cedrat', '-append'); + 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] + Fty_x = u; +else + Fty_x = zeros(length(t), 1); end
if args.Fty_z && args.enable + phi = dist_f.psd_ty; + C = zeros(N/2,1); + for i = 1:N/2 + C(i) = sqrt(phi(i)*df); + 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] + Fty_z = u; +else + Fty_z = zeros(length(t), 1); +end ++
if args.Frz_z && args.enable + phi = dist_f.psd_rz; + C = zeros(N/2,1); + for i = 1:N/2 + C(i) = sqrt(phi(i)*df); + 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] + Frz_z = u; +else + Frz_z = zeros(length(t), 1); +end ++
u = zeros(length(t), 6); +Fd = u; ++
Dwx = Dwx - Dwx(1); +Dwy = Dwy - Dwy(1); +Dwz = Dwz - Dwz(1); +Fty_x = Fty_x - Fty_x(1); +Fty_z = Fty_z - Fty_z(1); +Frz_z = Frz_z - Frz_z(1); ++
save('mat/nass_disturbances.mat', 'Dwx', 'Dwy', 'Dwz', 'Fty_x', 'Fty_z', 'Frz_z', 'Fd', 'Ts', 't'); ++
-This Matlab function is accessible here. +
function [sample] = initializeSample(opts_param) - %% Default values for opts - sample = struct('radius', 100, ... - 'height', 300, ... - 'mass', 50, ... - 'offset', 0, ... - 'color', [0.45, 0.45, 0.45] ... - ); - - %% Populate opts with input parameters - if exist('opts_param','var') - for opt = fieldnames(opts_param)' - sample.(opt{1}) = opts_param.(opt{1}); - end +function [geophone] = initializeZAxisGeophone(args) + arguments + args.mass (1,1) double {mustBeNumeric, mustBePositive} = 1e-3 % [kg] + args.freq (1,1) double {mustBeNumeric, mustBePositive} = 1 % [Hz] end %% - sample.k.x = 1e8; - sample.c.x = 0.1*sqrt(sample.k.x*sample.mass); + geophone.m = args.mass; - sample.k.y = 1e8; - sample.c.y = 0.1*sqrt(sample.k.y*sample.mass); + %% The Stiffness is set to have the damping resonance frequency + geophone.k = geophone.m * (2*pi*args.freq)^2; - sample.k.z = 1e8; - sample.c.z = 0.1*sqrt(sample.k.z*sample.mass); + %% We set the damping value to have critical damping + geophone.c = 2*sqrt(geophone.m * geophone.k); %% Save - save('./mat/stages.mat', 'sample', '-append'); + save('./mat/geophone_z_axis.mat', 'geophone'); end
function [accelerometer] = initializeZAxisAccelerometer(args) + arguments + args.mass (1,1) double {mustBeNumeric, mustBePositive} = 1e-3 % [kg] + args.freq (1,1) double {mustBeNumeric, mustBePositive} = 5e3 % [Hz] + end + + %% + accelerometer.m = args.mass; + + %% The Stiffness is set to have the damping resonance frequency + accelerometer.k = accelerometer.m * (2*pi*args.freq)^2; + + %% We set the damping value to have critical damping + accelerometer.c = 2*sqrt(accelerometer.m * accelerometer.k); + + %% Gain correction of the accelerometer to have a unity gain until the resonance + accelerometer.gain = -accelerometer.k/accelerometer.m; + + %% Save + save('./mat/accelerometer_z_axis.mat', 'accelerometer'); +end ++