Compare commits

..

10 Commits

48 changed files with 1784 additions and 1665 deletions

View File

@@ -6,7 +6,7 @@
version="1.2" version="1.2"
id="svg251" id="svg251"
sodipodi:docname="ustation_stage_motion.svg" sodipodi:docname="ustation_stage_motion.svg"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)" inkscape:version="1.4.1 (93de688d07, 2025-03-30)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@@ -21,15 +21,15 @@
inkscape:pagecheckerboard="0" inkscape:pagecheckerboard="0"
inkscape:document-units="pt" inkscape:document-units="pt"
showgrid="false" showgrid="false"
inkscape:zoom="5.656854" inkscape:zoom="2.828427"
inkscape:cx="239.35566" inkscape:cx="134.52707"
inkscape:cy="59.131807" inkscape:cy="70.710681"
inkscape:window-width="2534" inkscape:window-width="2534"
inkscape:window-height="1367" inkscape:window-height="1367"
inkscape:window-x="11" inkscape:window-x="11"
inkscape:window-y="60" inkscape:window-y="60"
inkscape:window-maximized="1" inkscape:window-maximized="1"
inkscape:current-layer="g28" inkscape:current-layer="layer1"
inkscape:snap-midpoints="true" inkscape:snap-midpoints="true"
inkscape:snap-smooth-nodes="true" inkscape:snap-smooth-nodes="true"
inkscape:snap-intersection-paths="true" inkscape:snap-intersection-paths="true"
@@ -1645,5 +1645,16 @@
</g> </g>
</g> </g>
</g> </g>
<text
xml:space="preserve"
style="font-size:10px;line-height:1.25;font-family:'Latin Modern Roman';-inkscape-font-specification:'Latin Modern Roman, Normal';text-align:center;text-anchor:middle;fill:#a2142f;stroke-width:0.75"
x="-66.452881"
y="32.661747"
id="text1"><tspan
sodipodi:role="line"
style="font-size:10px;fill:#a2142f;stroke-width:0.75"
x="-66.452881"
y="32.661747"
id="tspan2">X-ray</tspan></text>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -8,7 +8,7 @@
args.x0 (1,1) double {mustBeNumeric} = 0 % Rest position of the Joint in the X direction [m] 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.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] args.z0 (1,1) double {mustBeNumeric} = 0 % Rest position of the Joint in the Z direction [m]
args.sample_pos (1,1) double {mustBeNumeric} = 0.8 % Height of the measurment point [m] args.sample_pos (1,1) double {mustBeNumeric} = 0.775 % Height of the measurment point [m]
end end
granite = struct(); granite = struct();
@@ -25,6 +25,7 @@
granite.density = args.density; % [kg/m3] granite.density = args.density; % [kg/m3]
granite.STEP = 'granite.STEP'; granite.STEP = 'granite.STEP';
% Z-offset for the initial position of the sample with respect to the granite top surface.
granite.sample_pos = args.sample_pos; % [m] granite.sample_pos = args.sample_pos; % [m]
granite.K = args.K; % [N/m] granite.K = args.K; % [N/m]
@@ -43,3 +44,5 @@ elseif exist('./matlab', 'dir')
save('matlab/mat/nass_model_stages.mat', 'granite'); save('matlab/mat/nass_model_stages.mat', 'granite');
end end
end end
end

View File

@@ -32,3 +32,4 @@ elseif exist('./matlab', 'dir')
save('matlab/mat/nass_model_stages.mat', 'ground'); save('matlab/mat/nass_model_stages.mat', 'ground');
end end
end end
end

View File

@@ -105,3 +105,4 @@ elseif exist('./matlab', 'dir')
save('matlab/mat/nass_model_stages.mat', 'micro_hexapod'); save('matlab/mat/nass_model_stages.mat', 'micro_hexapod');
end end
end end
end

View File

@@ -32,6 +32,7 @@
ry.stage.density = 7800; % [kg/m3] ry.stage.density = 7800; % [kg/m3]
ry.stage.STEP = 'Tilt_Stage.STEP'; ry.stage.STEP = 'Tilt_Stage.STEP';
% Z-Offset so that the center of rotation matches the sample center;
ry.z_offset = 0.58178; % [m] ry.z_offset = 0.58178; % [m]
ry.Ry_init = args.Ry_init; % [rad] ry.Ry_init = args.Ry_init; % [rad]
@@ -52,3 +53,5 @@ elseif exist('./matlab', 'dir')
save('matlab/mat/nass_model_stages.mat', 'ry'); save('matlab/mat/nass_model_stages.mat', 'ry');
end end
end end
end

View File

@@ -43,3 +43,5 @@ elseif exist('./matlab', 'dir')
save('matlab/mat/nass_model_stages.mat', 'rz'); save('matlab/mat/nass_model_stages.mat', 'rz');
end end
end end
end

View File

@@ -67,3 +67,5 @@ elseif exist('./matlab', 'dir')
save('matlab/mat/nass_model_stages.mat', 'ty'); save('matlab/mat/nass_model_stages.mat', 'ty');
end end
end end
end

View File

@@ -0,0 +1,90 @@
%% ustation_1_kinematics.m
%% Clear Workspace and Close figures
clear; close all; clc;
%% Intialize Laplace variable
s = zpk('s');
%% Path for functions, data and scripts
addpath('./mat/'); % Path for Data
addpath('./src/'); % Path for functions
addpath('./STEPS/'); % Path for STEPS
addpath('./subsystems/'); % Path for Subsystems Simulink files
% Simulink Model name
mdl = 'ustation_simscape';
load('nass_model_conf_simulink.mat');
%% Colors for the figures
colors = colororder;
%% Frequency Vector
freqs = logspace(log10(10), log10(2e3), 1000);
%% Stage setpoints
Dy = 1e-3; % Translation Stage [m]
Ry = 3*pi/180; % Tilt Stage [rad]
Rz = 180*pi/180; % Spindle [rad]
%% Stage individual Homogeneous transformations
% Translation Stage
Rty = [1 0 0 0;
0 1 0 Dy;
0 0 1 0;
0 0 0 1];
% Tilt Stage - Pure rotating aligned with Ob
Rry = [ cos(Ry) 0 sin(Ry) 0;
0 1 0 0;
-sin(Ry) 0 cos(Ry) 0;
0 0 0 1];
% Spindle - Rotation along the Z axis
Rrz = [cos(Rz) -sin(Rz) 0 0 ;
sin(Rz) cos(Rz) 0 0 ;
0 0 1 0 ;
0 0 0 1 ];
% Micro-Station homogeneous transformation
Ttot = Rty*Rry*Rrz;
%% Compute translations and rotations (Euler angles) induced by the micro-station
ustation_dx = Ttot(1,4);
ustation_dy = Ttot(2,4);
ustation_dz = Ttot(3,4);
ustation_ry = atan2( Ttot(1, 3), sqrt(Ttot(1, 1)^2 + Ttot(1, 2)^2));
ustation_rx = atan2(-Ttot(2, 3)/cos(ustation_ry), Ttot(3, 3)/cos(ustation_ry));
ustation_rz = atan2(-Ttot(1, 2)/cos(ustation_ry), Ttot(1, 1)/cos(ustation_ry));
%% Verification using the Simscape model
% All stages are initialized as rigid bodies to avoid any guiding error
initializeGround( 'type', 'rigid');
initializeGranite( 'type', 'rigid');
initializeTy( 'type', 'rigid');
initializeRy( 'type', 'rigid');
initializeRz( 'type', 'rigid');
initializeMicroHexapod('type', 'rigid');
initializeLoggingConfiguration('log', 'all');
initializeReferences('Dy_amplitude', Dy, ...
'Ry_amplitude', Ry, ...
'Rz_amplitude', Rz);
initializeDisturbances('enable', false);
set_param(conf_simulink, 'StopTime', '0.5');
% Simulation is performed
sim(mdl);
% Sample's motion is computed from "external metrology"
T_sim = [simout.y.R.Data(:,:,end), [simout.y.x.Data(end); simout.y.y.Data(end); simout.y.z.Data(end)]; [0,0,0,1]];
sim_dx = T_sim(1,4);
sim_dy = T_sim(2,4);
sim_dz = T_sim(3,4);
sim_ry = atan2( T_sim(1, 3), sqrt(T_sim(1, 1)^2 + T_sim(1, 2)^2));
sim_rx = atan2(-T_sim(2, 3)/cos(sim_ry), T_sim(3, 3)/cos(sim_ry));
sim_rz = atan2(-T_sim(1, 2)/cos(sim_ry), T_sim(1, 1)/cos(sim_ry));

View File

@@ -0,0 +1,321 @@
%% ustation_2_modeling.m
%% Clear Workspace and Close figures
clear; close all; clc;
%% Intialize Laplace variable
s = zpk('s');
%% Path for functions, data and scripts
addpath('./mat/'); % Path for Data
addpath('./src/'); % Path for functions
addpath('./STEPS/'); % Path for STEPS
addpath('./subsystems/'); % Path for Subsystems Simulink files
% Simulink Model name
mdl = 'ustation_simscape';
load('nass_model_conf_simulink.mat');
%% Colors for the figures
colors = colororder;
%% Frequency Vector
freqs = logspace(log10(10), log10(2e3), 1000);
%% Indentify the model dynamics from the 3 hammer imapcts
% To the motion of each solid body at their CoM
% All stages are initialized
initializeGround( 'type', 'rigid');
initializeGranite( 'type', 'flexible');
initializeTy( 'type', 'flexible');
initializeRy( 'type', 'flexible');
initializeRz( 'type', 'flexible');
initializeMicroHexapod('type', 'flexible');
initializeLoggingConfiguration('log', 'none');
initializeReferences();
initializeDisturbances('enable', false);
% Input/Output definition
clear io; io_i = 1;
io(io_i) = linio([mdl, '/Micro-Station/Translation Stage/Flexible/F_hammer'], 1, 'openinput'); io_i = io_i + 1;
io(io_i) = linio([mdl, '/Micro-Station/Granite/Flexible/accelerometer'], 1, 'openoutput'); io_i = io_i + 1;
io(io_i) = linio([mdl, '/Micro-Station/Translation Stage/Flexible/accelerometer'], 1, 'openoutput'); io_i = io_i + 1;
io(io_i) = linio([mdl, '/Micro-Station/Tilt Stage/Flexible/accelerometer'], 1, 'openoutput'); io_i = io_i + 1;
io(io_i) = linio([mdl, '/Micro-Station/Spindle/Flexible/accelerometer'], 1, 'openoutput'); io_i = io_i + 1;
io(io_i) = linio([mdl, '/Micro-Station/Micro Hexapod/Flexible/accelerometer'], 1, 'openoutput'); io_i = io_i + 1;
% Run the linearization
G_ms = linearize(mdl, io, 0);
G_ms.InputName = {'Fx', 'Fy', 'Fz'};
G_ms.OutputName = {'gtop_x', 'gtop_y', 'gtop_z', 'gtop_rx', 'gtop_ry', 'gtop_rz', ...
'ty_x', 'ty_y', 'ty_z', 'ty_rx', 'ty_ry', 'ty_rz', ...
'ry_x', 'ry_y', 'ry_z', 'ry_rx', 'ry_ry', 'ry_rz', ...
'rz_x', 'rz_y', 'rz_z', 'rz_rx', 'rz_ry', 'rz_rz', ...
'hexa_x', 'hexa_y', 'hexa_z', 'hexa_rx', 'hexa_ry', 'hexa_rz'};
% Load estimated FRF at 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'};
stages = {'gbot', 'gtop', 'ty', 'ry', 'rz', 'hexa'};
f = logspace(log10(10), log10(500), 1000);
%% Spindle - X response
n_stg = 5; % Measured Stage
n_dir = 1; % Measured DoF: x, y, z, Rx, Ry, Rz
n_exc = 1; % Hammer impact: x, y, z
figure;
hold on;
plot(freqs, abs(squeeze(frfs_CoM(6*(n_stg-1) + n_dir, n_exc, :))), 'DisplayName', 'Measurement');
plot(f, abs(squeeze(freqresp(G_ms([stages{n_stg}, '_', dirs{n_dir}], ['F', dirs{n_exc}]), f, 'Hz'))), 'DisplayName', 'Model');
text(50, 2e-2,{'$D_x/F_x$ - Spindle'},'VerticalAlignment','bottom','HorizontalAlignment','center')
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('Magnitude [$m/s^2/N$]');
leg = legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 1);
leg.ItemTokenSize(1) = 15;
xlim([10, 200]);
ylim([1e-6, 1e-1])
%% Hexapod - Y response
n_stg = 6; % Measured Stage
n_dir = 2; % Measured DoF: x, y, z, Rx, Ry, Rz
n_exc = 2; % Hammer impact: x, y, z
figure;
hold on;
plot(freqs, abs(squeeze(frfs_CoM(6*(n_stg-1) + n_dir, n_exc, :))), 'DisplayName', 'Measurement');
plot(f, abs(squeeze(freqresp(G_ms([stages{n_stg}, '_', dirs{n_dir}], ['F', dirs{n_exc}]), f, 'Hz'))), 'DisplayName', 'Model');
text(50, 2e-2,{'$D_y/F_y$ - Hexapod'},'VerticalAlignment','bottom','HorizontalAlignment','center')
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('Magnitude [$m/s^2/N$]');
leg = legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 1);
leg.ItemTokenSize(1) = 15;
xlim([10, 200]);
ylim([1e-6, 1e-1])
%% Tilt stage - Z response
n_stg = 4; % Measured Stage
n_dir = 3; % Measured DoF: x, y, z, Rx, Ry, Rz
n_exc = 3; % Hammer impact: x, y, z
figure;
hold on;
plot(freqs, abs(squeeze(frfs_CoM(6*(n_stg-1) + n_dir, n_exc, :))), 'DisplayName', 'Measurement');
plot(f, abs(squeeze(freqresp(G_ms([stages{n_stg}, '_', dirs{n_dir}], ['F', dirs{n_exc}]), f, 'Hz'))), 'DisplayName', 'Model');
text(50, 2e-2,{'$D_z/F_z$ - Tilt'},'VerticalAlignment','bottom','HorizontalAlignment','center')
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('Magnitude [$m/s^2/N$]');
leg = legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 1);
leg.ItemTokenSize(1) = 15;
xlim([10, 200]);
ylim([1e-6, 1e-1])
% Positions and orientation of accelerometers
% | *Num* | *Position* | *Orientation* | *Sensibility* | *Channels* |
% |-------+------------+---------------+---------------+------------|
% | 1 | [0, +A, 0] | [x, y, z] | 1V/g | 1-3 |
% | 2 | [-B, 0, 0] | [x, y, z] | 1V/g | 4-6 |
% | 3 | [0, -A, 0] | [x, y, z] | 0.1V/g | 7-9 |
% | 4 | [+B, 0, 0] | [x, y, z] | 1V/g | 10-12 |
%
% Measuerment channels
%
% | Acc Number | Dir | Channel Number |
% |------------+-----+----------------|
% | 1 | x | 1 |
% | 1 | y | 2 |
% | 1 | z | 3 |
% | 2 | x | 4 |
% | 2 | y | 5 |
% | 2 | z | 6 |
% | 3 | x | 7 |
% | 3 | y | 8 |
% | 3 | z | 9 |
% | 4 | x | 10 |
% | 4 | y | 11 |
% | 4 | z | 12 |
% | Hammer | | 13 |
% 10 measurements corresponding to 10 different Hammer impact locations
% | *Num* | *Direction* | *Position* | Accelerometer position | Jacobian number |
% |-------+-------------+------------+------------------------+-----------------|
% | 1 | -Y | [0, +A, 0] | 1 | -2 |
% | 2 | -Z | [0, +A, 0] | 1 | -3 |
% | 3 | X | [-B, 0, 0] | 2 | 4 |
% | 4 | -Z | [-B, 0, 0] | 2 | -6 |
% | 5 | Y | [0, -A, 0] | 3 | 8 |
% | 6 | -Z | [0, -A, 0] | 3 | -9 |
% | 7 | -X | [+B, 0, 0] | 4 | -10 |
% | 8 | -Z | [+B, 0, 0] | 4 | -12 |
% | 9 | -X | [0, -A, 0] | 3 | -7 |
% | 10 | -X | [0, +A, 0] | 1 | -1 |
%% Jacobian for accelerometers
% aX = Ja . aL
d = 0.14; % [m]
Ja = [1 0 0 0 0 -d;
0 1 0 0 0 0;
0 0 1 d 0 0;
1 0 0 0 0 0;
0 1 0 0 0 -d;
0 0 1 0 d 0;
1 0 0 0 0 d;
0 1 0 0 0 0;
0 0 1 -d 0 0;
1 0 0 0 0 0;
0 1 0 0 0 d;
0 0 1 0 -d 0];
Ja_inv = pinv(Ja);
%% Jacobian for hammer impacts
% F = Jf' tau
Jf = [0 -1 0 0 0 0;
0 0 -1 -d 0 0;
1 0 0 0 0 0;
0 0 -1 0 -d 0;
0 1 0 0 0 0;
0 0 -1 d 0 0;
-1 0 0 0 0 0;
0 0 -1 0 d 0;
-1 0 0 0 0 -d;
-1 0 0 0 0 d]';
Jf_inv = pinv(Jf);
%% Load raw measurement data
% "Track1" to "Track12" are the 12 accelerometers
% "Track13" is the instrumented hammer force sensor
data = [
load('ustation_compliance_hammer_1.mat'), ...
load('ustation_compliance_hammer_2.mat'), ...
load('ustation_compliance_hammer_3.mat'), ...
load('ustation_compliance_hammer_4.mat'), ...
load('ustation_compliance_hammer_5.mat'), ...
load('ustation_compliance_hammer_6.mat'), ...
load('ustation_compliance_hammer_7.mat'), ...
load('ustation_compliance_hammer_8.mat'), ...
load('ustation_compliance_hammer_9.mat'), ...
load('ustation_compliance_hammer_10.mat')];
%% Prepare the FRF computation
Ts = 1e-3; % Sampling Time [s]
Nfft = floor(1/Ts); % Number of points for the FFT computation
win = ones(Nfft, 1); % Rectangular window
[~, f] = tfestimate(data(1).Track13, data(1).Track1, win, [], Nfft, 1/Ts);
% Samples taken before and after the hammer "impact"
pre_n = floor(0.1/Ts);
post_n = Nfft - pre_n - 1;
%% Compute the FRFs for the 10 hammer impact locations.
% The FRF from hammer force the 12 accelerometers are computed
% for each of the 10 hammer impacts and averaged
G_raw = zeros(12,10,length(f));
for i = 1:10 % For each impact location
% Find the 10 impacts
[~, impacts_i] = find(diff(data(i).Track13 > 50)==1);
% Only keep the first 10 impacts if there are more than 10 impacts
if length(impacts_i)>10
impacts_i(11:end) = [];
end
% Average the FRF for the 10 impacts
for impact_i = impacts_i
i_start = impact_i - pre_n;
i_end = impact_i + post_n;
data_in = data(i).Track13(i_start:i_end); % [N]
% Remove hammer DC offset
data_in = data_in - mean(data_in(end-pre_n:end));
% Combine all outputs [m/s^2]
data_out = [data(i).Track1( i_start:i_end); ...
data(i).Track2( i_start:i_end); ...
data(i).Track3( i_start:i_end); ...
data(i).Track4( i_start:i_end); ...
data(i).Track5( i_start:i_end); ...
data(i).Track6( i_start:i_end); ...
data(i).Track7( i_start:i_end); ...
data(i).Track8( i_start:i_end); ...
data(i).Track9( i_start:i_end); ...
data(i).Track10(i_start:i_end); ...
data(i).Track11(i_start:i_end); ...
data(i).Track12(i_start:i_end)];
[frf, ~] = tfestimate(data_in, data_out', win, [], Nfft, 1/Ts);
G_raw(:,i,:) = squeeze(G_raw(:,i,:)) + 0.1*frf'./(-(2*pi*f').^2);
end
end
%% Compute transfer function in cartesian frame using Jacobian matrices
% FRF_cartesian = inv(Ja) * FRF * inv(Jf)
FRF_cartesian = pagemtimes(Ja_inv, pagemtimes(G_raw, Jf_inv));
%% Identification of the compliance of the micro-station
% Initialize simulation with default parameters (flexible elements)
initializeGround();
initializeGranite();
initializeTy();
initializeRy();
initializeRz();
initializeMicroHexapod();
initializeReferences();
initializeSimscapeConfiguration();
initializeLoggingConfiguration();
% Input/Output definition
clear io; io_i = 1;
io(io_i) = linio([mdl, '/Micro-Station/Micro Hexapod/Flexible/Fm'], 1, 'openinput'); io_i = io_i + 1; % Direct Forces/Torques applied on the micro-hexapod top platform
io(io_i) = linio([mdl, '/Micro-Station/Micro Hexapod/Flexible/Dm'], 1, 'output'); io_i = io_i + 1; % Absolute displacement of the top platform
% Run the linearization
Gm = linearize(mdl, io, 0);
Gm.InputName = {'Fmx', 'Fmy', 'Fmz', 'Mmx', 'Mmy', 'Mmz'};
Gm.OutputName = {'Dx', 'Dy', 'Dz', 'Drx', 'Dry', 'Drz'};
%% Extracted FRF of the compliance of the micro-station in the Cartesian frame from the Simscape model
figure;
hold on;
plot(f, abs(squeeze(FRF_cartesian(1,1,:))), '-', 'color', [colors(1,:), 0.5], 'linewidth', 2.5, 'DisplayName', '$D_x/F_x$ - Measured')
plot(f, abs(squeeze(FRF_cartesian(2,2,:))), '-', 'color', [colors(2,:), 0.5], 'linewidth', 2.5, 'DisplayName', '$D_y/F_y$ - Measured')
plot(f, abs(squeeze(FRF_cartesian(3,3,:))), '-', 'color', [colors(3,:), 0.5], 'linewidth', 2.5, 'DisplayName', '$D_z/F_z$ - Measured')
plot(f, abs(squeeze(freqresp(Gm(1,1), f, 'Hz'))), '-', 'color', colors(1,:), 'DisplayName', '$D_x/F_x$ - Model')
plot(f, abs(squeeze(freqresp(Gm(2,2), f, 'Hz'))), '-', 'color', colors(2,:), 'DisplayName', '$D_y/F_y$ - Model')
plot(f, abs(squeeze(freqresp(Gm(3,3), f, 'Hz'))), '-', 'color', colors(3,:), 'DisplayName', '$D_z/F_z$ - Model')
hold off;
leg = legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 2);
leg.ItemTokenSize(1) = 15;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('Magnitude [m/N]');
xlim([20, 500]); ylim([2e-10, 1e-6]);
xticks([20, 50, 100, 200, 500])
%% Extracted FRF of the compliance of the micro-station in the Cartesian frame from the Simscape model
figure;
hold on;
plot(f, abs(squeeze(FRF_cartesian(4,4,:))), '-', 'color', [colors(1,:), 0.5], 'linewidth', 2.5, 'DisplayName', '$R_x/M_x$ - Measured')
plot(f, abs(squeeze(FRF_cartesian(5,5,:))), '-', 'color', [colors(2,:), 0.5], 'linewidth', 2.5, 'DisplayName', '$R_y/M_y$ - Measured')
plot(f, abs(squeeze(FRF_cartesian(6,6,:))), '-', 'color', [colors(3,:), 0.5], 'linewidth', 2.5, 'DisplayName', '$R_z/M_z$ - Measured')
plot(f, abs(squeeze(freqresp(Gm(4,4), f, 'Hz'))), '-', 'color', colors(1,:), 'DisplayName', '$R_x/M_x$ - Model')
plot(f, abs(squeeze(freqresp(Gm(5,5), f, 'Hz'))), '-', 'color', colors(2,:), 'DisplayName', '$R_y/M_y$ - Model')
plot(f, abs(squeeze(freqresp(Gm(6,6), f, 'Hz'))), '-', 'color', colors(3,:), 'DisplayName', '$R_z/M_z$ - Model')
hold off;
leg = legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 2);
leg.ItemTokenSize(1) = 15;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('Magnitude [rad/Nm]');
xlim([20, 500]); ylim([2e-7, 1e-4]);
xticks([20, 50, 100, 200, 500])

View File

@@ -0,0 +1,345 @@
%% ustation_3_disturbances.m
%% Clear Workspace and Close figures
clear; close all; clc;
%% Intialize Laplace variable
s = zpk('s');
%% Path for functions, data and scripts
addpath('./mat/'); % Path for Data
addpath('./src/'); % Path for functions
addpath('./STEPS/'); % Path for STEPS
addpath('./subsystems/'); % Path for Subsystems Simulink files
% Simulink Model name
mdl = 'ustation_simscape';
load('nass_model_conf_simulink.mat');
%% Colors for the figures
colors = colororder;
%% Frequency Vector
freqs = logspace(log10(10), log10(2e3), 1000);
%% Compute Floor Motion Spectral Density
% Load floor motion data
% velocity in [m/s] is measured in X, Y and Z directions
load('ustation_ground_motion.mat', 'Ts', 'Fs', 'vel_x', 'vel_y', 'vel_z', 't');
% Estimate ground displacement from measured velocity
% This is done by integrating the motion
gm_x = lsim(1/(s+0.1*2*pi), vel_x, t);
gm_y = lsim(1/(s+0.1*2*pi), vel_y, t);
gm_z = lsim(1/(s+0.1*2*pi), vel_z, t);
Nfft = floor(2/Ts);
win = hanning(Nfft);
Noverlap = floor(Nfft/2);
[pxx_gm_vx, f_gm] = pwelch(vel_x, win, Noverlap, Nfft, 1/Ts);
[pxx_gm_vy, ~] = pwelch(vel_y, win, Noverlap, Nfft, 1/Ts);
[pxx_gm_vz, ~] = pwelch(vel_z, win, Noverlap, Nfft, 1/Ts);
% Convert PSD in velocity to PSD in displacement
pxx_gm_x = pxx_gm_vx./((2*pi*f_gm).^2);
pxx_gm_y = pxx_gm_vy./((2*pi*f_gm).^2);
pxx_gm_z = pxx_gm_vz./((2*pi*f_gm).^2);
%% Measured ground motion
figure;
hold on;
plot(t, 1e6*gm_x, 'DisplayName', '$D_{xf}$')
plot(t, 1e6*gm_y, 'DisplayName', '$D_{yf}$')
plot(t, 1e6*gm_z, 'DisplayName', '$D_{zf}$')
hold off;
xlabel('Time [s]');
ylabel('Ground motion [$\mu$m]')
xlim([0, 5]); ylim([-2, 2])
leg = legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 1);
leg.ItemTokenSize(1) = 15;
%% Ty errors
% Setpoint is in [mm]
% Vertical error is in [um]
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);
%% Measurement of the linear (vertical) deviation of the Translation stage
figure;
hold on;
plot(ty_errors.setpoint, ty_errors.ty_z(:,1), '-', 'color', colors(1,:), 'DisplayName', 'Raw data')
plot(ty_errors.setpoint, ty_errors.ty_z(:,2:end), '-', 'color', colors(1,:), 'HandleVisibility', 'off')
plot(ty_errors.setpoint, straight_line, '--', 'color', colors(2,:), 'DisplayName', 'Linear fit')
hold off;
xlabel('$D_y$ position [mm]'); ylabel('Vertical error [$\mu$m]');
xlim([-5, 5]); ylim([-8, 8]);
legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 1);
%% Measurement of the linear (vertical) deviation of the Translation stage - Remove best linear fit
figure;
plot(ty_errors.setpoint, ty_errors.ty_z - straight_line, 'k-')
xlabel('$D_y$ position [mm]'); ylabel('Residual vertical error [$\mu$m]');
xlim([-5, 5]); ylim([-0.4, 0.4]);
%% Convert the data to frequency domain
% Suppose a certain constant velocity scan
delta_ty = (ty_errors.setpoint(end) - ty_errors.setpoint(1))/(length(ty_errors.setpoint) - 1); % [mm]
ty_vel = 8*1.125; % [mm/s]
Ts = delta_ty/ty_vel;
Fs = 1/Ts;
% Frequency Analysis
Nfft = floor(length(ty_errors.setpoint)); % Number of frequency points
win = hanning(Nfft); % Windowing
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;
%% Spindle Errors
% Errors are already converted to x,y,z,Rx,Ry
% Units are in [m] and [rad]
spindle_errors = load('ustation_errors_spindle.mat');
%% Measured radial errors of the Spindle
figure;
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;
%% Measured axial errors of the Spindle
figure;
plot(spindle_errors.deg(1:100:end)/360, 1e9*spindle_errors.Dz(1:100:end))
xlabel('Rotation [turn]'); ylabel('Z displacement [nm]');
axis square
xlim([0,2]); ylim([-40, 40]);
%% Measured tilt errors of the Spindle
figure;
plot(1e6*spindle_errors.Rx(1:100:end), 1e6*spindle_errors.Ry(1:100:end))
xlabel('X angle [$\mu$rad]'); ylabel('Y angle [$\mu$rad]');
axis equal
xlim([-35, 35]); ylim([-35, 35]);
xticks([-30, -15, 0, 15, 30]);
yticks([-30, -15, 0, 15, 30]);
%% 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]
% Frequency Analysis
Nfft = floor(2.0*Fs); % Number of frequency points
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_err, win, Noverlap, Nfft, Fs);
[pxx_rz_dy, ~ ] = pwelch(spindle_errors.Dy_err, win, Noverlap, Nfft, Fs);
%% Extract sensitivity to disturbances from the Simscape model
% Initialize stages
initializeGround();
initializeGranite();
initializeTy();
initializeRy();
initializeRz();
initializeMicroHexapod();
initializeDisturbances('enable', false);
initializeSimscapeConfiguration('gravity', false);
initializeLoggingConfiguration();
% Configure inputs and outputs
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/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
io(io_i) = linio([mdl, '/Micro-Station/metrology_6dof/x'], 1, 'openoutput'); io_i = io_i + 1; % Relative motion - Hexapod/Granite
io(io_i) = linio([mdl, '/Micro-Station/metrology_6dof/y'], 1, 'openoutput'); io_i = io_i + 1; % Relative motion - Hexapod/Granite
io(io_i) = linio([mdl, '/Micro-Station/metrology_6dof/z'], 1, 'openoutput'); io_i = io_i + 1; % Relative motion - Hexapod/Granite
% Run the linearization
Gd = linearize(mdl, io, 0);
Gd.InputName = {'Dwx', 'Dwy', 'Dwz', 'Fdy_x', 'Fdy_z', 'Frz_x', 'Frz_y', 'Frz_z'};
Gd.OutputName = {'Dx', 'Dy', 'Dz'};
% The identified dynamics are then saved for further use.
save('./mat/ustation_disturbance_sensitivity.mat', 'Gd')
%% Sensitivity to Ground motion
freqs = logspace(log10(10), log10(2e2), 1000);
figure;
hold on;
plot(freqs, abs(squeeze(freqresp(Gd('Dx', 'Dwx'), freqs, 'Hz'))), 'DisplayName', '$D_x/D_{xf}$');
plot(freqs, abs(squeeze(freqresp(Gd('Dy', 'Dwy'), freqs, 'Hz'))), 'DisplayName', '$D_y/D_{yf}$');
plot(freqs, abs(squeeze(freqresp(Gd('Dz', 'Dwz'), freqs, 'Hz'))), 'DisplayName', '$D_z/D_{zf}$');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/m]'); xlabel('Frequency [Hz]');
leg = legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 1);
leg.ItemTokenSize(1) = 15;
%% Sensitivity to Translation stage disturbance forces
figure;
hold on;
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]');
ylim([1e-10, 1e-7]);
leg = legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 1);
leg.ItemTokenSize(1) = 15;
%% Sensitivity to Spindle disturbance forces
figure;
hold on;
plot(freqs, abs(squeeze(freqresp(Gd('Dx', 'Frz_x'), freqs, 'Hz'))), 'DisplayName', '$D_x/F_{xR_z}$');
plot(freqs, abs(squeeze(freqresp(Gd('Dy', 'Frz_y'), freqs, 'Hz'))), 'DisplayName', '$D_y/F_{yR_z}$');
plot(freqs, abs(squeeze(freqresp(Gd('Dz', 'Frz_z'), freqs, 'Hz'))), 'DisplayName', '$D_z/F_{zR_z}$');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); xlabel('Frequency [Hz]');
ylim([1e-10, 1e-7]);
leg = legend('location', 'northwest', 'FontSize', 8, 'NumColumns', 1);
leg.ItemTokenSize(1) = 15;
%% 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 = 100;
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);
% The identified dynamics are then saved for further use.
save('./mat/ustation_disturbance_psd.mat', 'rz_dist', 'dy_dist', 'gm_dist')
%% Ground Motion
figure;
hold on;
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('Spectral Density $\left[\frac{m}{\sqrt{Hz}}\right]$')
xlim([1, 200]);
leg = legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 1);
leg.ItemTokenSize(1) = 15;
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;
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;
%% Compute time domain disturbance signals
initializeDisturbances();
load('nass_model_disturbances.mat');
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;
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;
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.6, 0.6])
leg = legend('location', 'northwest', 'FontSize', 8, 'NumColumns', 1);
leg.ItemTokenSize(1) = 15;

View File

@@ -0,0 +1,141 @@
%% ustation_4_experiments.m
%% Clear Workspace and Close figures
clear; close all; clc;
%% Intialize Laplace variable
s = zpk('s');
%% Path for functions, data and scripts
addpath('./mat/'); % Path for Data
addpath('./src/'); % Path for functions
addpath('./STEPS/'); % Path for STEPS
addpath('./subsystems/'); % Path for Subsystems Simulink files
% Simulink Model name
mdl = 'ustation_simscape';
load('nass_model_conf_simulink.mat');
%% Colors for the figures
colors = colororder;
%% Frequency Vector
freqs = logspace(log10(10), log10(2e3), 1000);
%% 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();
initializeGranite();
initializeTy();
initializeRy();
initializeRz();
initializeMicroHexapod('AP', P_micro_hexapod);
initializeSimscapeConfiguration('gravity', false);
initializeLoggingConfiguration('log', 'all');
initializeDisturbances(...
'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, ...
'Dh_pos', [P_micro_hexapod; 0; 0; 0]);
sim(mdl);
exp_tomography = simout;
%% Compare with the measurements
spindle_errors = load('ustation_errors_spindle.mat');
%% Measured radial errors of the Spindle
figure;
hold on;
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('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;
%% Measured axial errors of the Spindle
figure;
hold on;
plot(spindle_errors.deg(1:100:end)/360, detrend(1e9*spindle_errors.Dz(1:100:end), 0), 'DisplayName', 'Measurements')
plot(exp_tomography.y.z.Time, detrend(1e9*exp_tomography.y.z.Data, 0), '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;
%% Translation stage latteral scans
set_param(conf_simulink, 'StopTime', '2');
initializeGround();
initializeGranite();
initializeTy();
initializeRy();
initializeRz();
initializeMicroHexapod();
initializeSimscapeConfiguration('gravity', false);
initializeLoggingConfiguration('log', 'all');
initializeDisturbances(...
'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(...
'Dy_type', 'triangular', ...
'Dy_amplitude', 4.5e-3, ...
'Dy_period', 2);
sim(mdl);
exp_latteral_scans = simout;
% 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);
% Only plot data for the scan from -4.5mm to 4.5mm
dy_setpoint = 1e3*exp_latteral_scans.y.y.Data(exp_latteral_scans.y.y.time > 0.5 & exp_latteral_scans.y.y.time < 1.5);
dz_error = detrend(1e6*exp_latteral_scans.y.z.Data(exp_latteral_scans.y.y.time > 0.5 & exp_latteral_scans.y.y.time < 1.5), 0);
figure;
hold on;
plot(ty_errors.setpoint, detrend(ty_errors.ty_z(:,1) - straight_line, 0), 'color', colors(1,:), 'DisplayName', 'Measurement')
% plot(ty_errors.setpoint, detrend(ty_errors.ty_z(:,[4,6]) - straight_line, 0), 'color', colors(1,:), 'HandleVisibility', 'off')
plot(dy_setpoint, dz_error, 'color', colors(2,:), '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;

Binary file not shown.

View File

@@ -12,5 +12,12 @@
\setabbreviationstyle[acronym]{long-short} \setabbreviationstyle[acronym]{long-short}
\setglossarystyle{long-name-desc} \setglossarystyle{long-name-desc}
\usepackage{amssymb}
\usepackage{amsmath}
\usepackage{cases}
\usepackage{empheq}
\makeindex \makeindex
\makeglossaries \makeglossaries
\usepackage{bm}

View File

@@ -2,7 +2,6 @@
\usepackage{enumitem} \usepackage{enumitem}
\usepackage{caption,tabularx,booktabs} \usepackage{caption,tabularx,booktabs}
\usepackage{bm}
\usepackage{xpatch} % Recommanded for biblatex \usepackage{xpatch} % Recommanded for biblatex
\usepackage[ % use biblatex for bibliography \usepackage[ % use biblatex for bibliography

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -1,4 +1,4 @@
% Created 2024-11-06 Wed 18:35 % Created 2025-04-07 Mon 16:40
% Intended LaTeX compiler: pdflatex % Intended LaTeX compiler: pdflatex
\documentclass[a4paper, 10pt, DIV=12, parskip=full, bibliography=totoc]{scrreprt} \documentclass[a4paper, 10pt, DIV=12, parskip=full, bibliography=totoc]{scrreprt}
@@ -7,13 +7,13 @@
\bibliography{simscape-micro-station.bib} \bibliography{simscape-micro-station.bib}
\author{Dehaeze Thomas} \author{Dehaeze Thomas}
\date{\today} \date{\today}
\title{Simscape Model - Micro Station} \title{Multi-Body Model - Micro Station}
\hypersetup{ \hypersetup{
pdfauthor={Dehaeze Thomas}, pdfauthor={Dehaeze Thomas},
pdftitle={Simscape Model - Micro Station}, pdftitle={Multi-Body Model - Micro Station},
pdfkeywords={}, pdfkeywords={},
pdfsubject={}, pdfsubject={},
pdfcreator={Emacs 29.4 (Org mode 9.6)}, pdfcreator={Emacs 30.1 (Org mode 9.7.26)},
pdflang={English}} pdflang={English}}
\usepackage{biblatex} \usepackage{biblatex}
@@ -23,7 +23,6 @@
\tableofcontents \tableofcontents
\clearpage \clearpage
From the start of this work, it became increasingly clear that an accurate micro-station model was necessary. From the start of this work, it became increasingly clear that an accurate micro-station model was necessary.
First, during the uniaxial study, it became clear that the micro-station dynamics affects the nano-hexapod dynamics. First, during the uniaxial study, it became clear that the micro-station dynamics affects the nano-hexapod dynamics.
@@ -43,18 +42,16 @@ Disturbances affecting the positioning accuracy also need to be modeled properly
To do so, the effects of these disturbances were first measured experimental and then injected into the multi-body model (Section \ref{sec:ustation_disturbances}). To do so, the effects of these disturbances were first measured experimental and then injected into the multi-body model (Section \ref{sec:ustation_disturbances}).
To validate the accuracy of the micro-station model, ``real world'' experiments are simulated and compared with measurements in Section \ref{sec:ustation_experiments}. To validate the accuracy of the micro-station model, ``real world'' experiments are simulated and compared with measurements in Section \ref{sec:ustation_experiments}.
\chapter{Micro-Station Kinematics} \chapter{Micro-Station Kinematics}
\label{sec:ustation_kinematics} \label{sec:ustation_kinematics}
The micro-station consists of 4 stacked positioning stages (Figure \ref{fig:ustation_cad_view}). The micro-station consists of 4 stacked positioning stages (Figure \ref{fig:ustation_cad_view}).
From bottom to top, the stacked stages are the translation stage \(D_y\), the tilt stage \(R_y\), the rotation stage (Spindle) \(R_z\) and the positioning hexapod. From bottom to top, the stacked stages are the translation stage \(D_y\), the tilt stage \(R_y\), the rotation stage (Spindle) \(R_z\) and the positioning hexapod.
Such a stacked architecture allows high mobility, but the overall stiffness is reduced, and the dynamics is very complex. complex dynamics. Such a stacked architecture allows high mobility, but the overall stiffness is reduced, and the dynamics is very complex.
\begin{figure}[htbp] \begin{figure}[htbp]
\centering \centering
\includegraphics[scale=1,width=\linewidth]{figs/ustation_cad_view.png} \includegraphics[scale=1,width=\linewidth]{figs/ustation_cad_view.png}
\caption{\label{fig:ustation_cad_view}CAD view of the micro-station with the translation stage (in blue), tilt stage (in red), rotation stage (in yellow) and positioning hexapod (in purple). On top of these four stages, a solid part (shown in green) will be replaced by the stabilization stage.} \caption{\label{fig:ustation_cad_view}CAD view of the micro-station with the translation stage (in blue), tilt stage (in red), rotation stage (in yellow) and positioning hexapod (in purple).}
\end{figure} \end{figure}
There are different ways of modeling the stage dynamics in a multi-body model. There are different ways of modeling the stage dynamics in a multi-body model.
@@ -65,7 +62,6 @@ s can be tuned separately for each DoF.
The ``controlled'' DoF of each stage (for instance the \(D_y\) direction for the translation stage) is modeled as infinitely rigid (i.e. its motion is imposed by a ``setpoint'') while the other DoFs have limited stiffness to model the different micro-station modes. The ``controlled'' DoF of each stage (for instance the \(D_y\) direction for the translation stage) is modeled as infinitely rigid (i.e. its motion is imposed by a ``setpoint'') while the other DoFs have limited stiffness to model the different micro-station modes.
\section{Motion Stages} \section{Motion Stages}
\label{ssec:ustation_stages} \label{ssec:ustation_stages}
\paragraph{Translation Stage} \paragraph{Translation Stage}
The translation stage is used to position and scan the sample laterally with respect to the X-ray beam. The translation stage is used to position and scan the sample laterally with respect to the X-ray beam.
@@ -75,7 +71,6 @@ It was later replaced with a stepper motor and lead-screw, as the feedback contr
An optical linear encoder is used to measure the stage motion and for controlling the position. An optical linear encoder is used to measure the stage motion and for controlling the position.
Four cylindrical bearings\footnote{Ball cage (N501) and guide bush (N550) from Mahr are used.} are used to guide the motion (i.e. minimize the parasitic motions) and have high stiffness. Four cylindrical bearings\footnote{Ball cage (N501) and guide bush (N550) from Mahr are used.} are used to guide the motion (i.e. minimize the parasitic motions) and have high stiffness.
\paragraph{Tilt Stage} \paragraph{Tilt Stage}
The tilt stage is guided by four linear motion guides\footnote{HCR 35 A C1, from THK.} which are placed such that the center of rotation coincide with the X-ray beam. The tilt stage is guided by four linear motion guides\footnote{HCR 35 A C1, from THK.} which are placed such that the center of rotation coincide with the X-ray beam.
@@ -99,14 +94,12 @@ To precisely control the \(R_y\) angle, a stepper motor and two optical encoders
\captionof{figure}{\label{fig:ustation_ry_stage}Tilt Stage} \captionof{figure}{\label{fig:ustation_ry_stage}Tilt Stage}
\end{center} \end{center}
\end{minipage} \end{minipage}
\paragraph{Spindle} \paragraph{Spindle}
Then, a rotation stage is used for tomography experiments. Then, a rotation stage is used for tomography experiments.
It is composed of an air bearing spindle\footnote{Made by LAB Motion Systems.}, whose angular position is controlled with a 3 phase synchronous motor based on the reading of 4 optical encoders. It is composed of an air bearing spindle\footnote{Made by LAB Motion Systems.}, whose angular position is controlled with a 3 phase synchronous motor based on the reading of 4 optical encoders.
Additional rotary unions and slip-rings are used to be able to pass electrical signals, fluids and gazes through the rotation stage. Additional rotary unions and slip-rings are used to be able to pass electrical signals, fluids and gazes through the rotation stage.
\paragraph{Micro-Hexapod} \paragraph{Micro-Hexapod}
Finally, a Stewart platform\footnote{Modified Zonda Hexapod by Symetrie.} is used to position the sample. Finally, a Stewart platform\footnote{Modified Zonda Hexapod by Symetrie.} is used to position the sample.
@@ -128,7 +121,6 @@ It can also be used to precisely position the PoI vertically with respect to the
\captionof{figure}{\label{fig:ustation_hexapod_stage}Micro Hexapod} \captionof{figure}{\label{fig:ustation_hexapod_stage}Micro Hexapod}
\end{center} \end{center}
\end{minipage} \end{minipage}
\section{Mathematical description of a rigid body motion} \section{Mathematical description of a rigid body motion}
\label{ssec:ustation_motion_description} \label{ssec:ustation_motion_description}
In this section, mathematical tools\footnote{The tools presented here are largely taken from \cite{taghirad13_paral}.} that are used to describe the motion of positioning stages are introduced. In this section, mathematical tools\footnote{The tools presented here are largely taken from \cite{taghirad13_paral}.} that are used to describe the motion of positioning stages are introduced.
@@ -176,21 +168,17 @@ The \emph{orientation} of a rigid body is the same at all its points (by definit
Hence, the orientation of a rigid body can be viewed as that of a moving frame attached to the rigid body. Hence, the orientation of a rigid body can be viewed as that of a moving frame attached to the rigid body.
It can be represented in several different ways: the rotation matrix, the screw axis representation, and the Euler angles are common descriptions. It can be represented in several different ways: the rotation matrix, the screw axis representation, and the Euler angles are common descriptions.
The rotation matrix \({}^A\mathbf{R}_B\) is a \(3 \times 3\) matrix containing the Cartesian unit vectors of frame \(\{\mathbf{B}\}\) represented in frame \(\{\mathbf{A}\}\) \eqref{eq:ustation_rotation_matrix}. The rotation matrix \({}^A\bm{R}_B\) is a \(3 \times 3\) matrix containing the Cartesian unit vectors \([{}^A\hat{\bm{x}}_B,\ {}^A\hat{\bm{y}}_B,\ {}^A\hat{\bm{z}}_B]\) of frame \(\{\bm{B}\}\) represented in frame \(\{\bm{A}\}\) \eqref{eq:ustation_rotation_matrix}.
\begin{equation}\label{eq:ustation_rotation_matrix} \begin{equation}\label{eq:ustation_rotation_matrix}
{}^A\mathbf{R}_B = \left[ {}^A\hat{\mathbf{x}}_B | {}^A\hat{\mathbf{y}}_B | {}^A\hat{\mathbf{z}}_B \right] = \begin{bmatrix} {}^A\bm{R}_B = \left[ {}^A\hat{\bm{x}}_B | {}^A\hat{\bm{y}}_B | {}^A\hat{\bm{z}}_B \right]
u_{x} & v_{x} & z_{x} \\
u_{y} & v_{y} & z_{y} \\
u_{z} & v_{z} & z_{z}
\end{bmatrix}
\end{equation} \end{equation}
Consider a pure rotation of a rigid body (\(\{\bm{A}\}\) and \(\{\bm{B}\}\) are coincident at their origins, as shown in Figure \ref{fig:ustation_rotation}). Consider a pure rotation of a rigid body (\(\{\bm{A}\}\) and \(\{\bm{B}\}\) are coincident at their origins, as shown in Figure \ref{fig:ustation_rotation}).
The rotation matrix can be used to express the coordinates of a point \(P\) in a fixed frame \(\{A\}\) (i.e. \({}^AP\)) from its coordinate in the moving frame \(\{B\}\) using Equation \eqref{eq:ustation_rotation}. The rotation matrix can be used to express the coordinates of a point \(P\) in a fixed frame \(\{A\}\) (i.e. \({}^AP\)) from its coordinate in the moving frame \(\{B\}\) using Equation \eqref{eq:ustation_rotation}.
\begin{equation} \label{eq:ustation_rotation} \begin{equation} \label{eq:ustation_rotation}
{}^AP = {}^A\mathbf{R}_B {}^BP {}^AP = {}^A\bm{R}_B {}^BP
\end{equation} \end{equation}
@@ -198,17 +186,17 @@ For rotations along \(x\), \(y\) or \(z\) axis, the formulas of the correspondin
\begin{subequations}\label{eq:ustation_rotation_matrices_xyz} \begin{subequations}\label{eq:ustation_rotation_matrices_xyz}
\begin{align} \begin{align}
\mathbf{R}_x(\theta_x) &= \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos(\theta_x) & -\sin(\theta_x) \\ 0 & \sin(\theta_x) & \cos(\theta_x) \end{bmatrix} \\ \bm{R}_x(\theta_x) &= \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos(\theta_x) & -\sin(\theta_x) \\ 0 & \sin(\theta_x) & \cos(\theta_x) \end{bmatrix} \\
\mathbf{R}_y(\theta_y) &= \begin{bmatrix} \cos(\theta_y) & 0 & \sin(\theta_y) \\ 0 & 1 & 0 \\ -\sin(\theta_y) & 0 & \cos(\theta_y) \end{bmatrix} \\ \bm{R}_y(\theta_y) &= \begin{bmatrix} \cos(\theta_y) & 0 & \sin(\theta_y) \\ 0 & 1 & 0 \\ -\sin(\theta_y) & 0 & \cos(\theta_y) \end{bmatrix} \\
\mathbf{R}_z(\theta_z) &= \begin{bmatrix} \cos(\theta_z) & -\sin(\theta_z) & 0 \\ \sin(\theta_z) & \cos(\theta_x) & 0 \\ 0 & 0 & 1 \end{bmatrix} \bm{R}_z(\theta_z) &= \begin{bmatrix} \cos(\theta_z) & -\sin(\theta_z) & 0 \\ \sin(\theta_z) & \cos(\theta_z) & 0 \\ 0 & 0 & 1 \end{bmatrix}
\end{align} \end{align}
\end{subequations} \end{subequations}
Sometimes, it is useful to express a rotation as a combination of three rotations described by \(\mathbf{R}_x\), \(\mathbf{R}_y\) and \(\mathbf{R}_z\). Sometimes, it is useful to express a rotation as a combination of three rotations described by \(\bm{R}_x\), \(\bm{R}_y\) and \(\bm{R}_z\).
The order of rotation is very important\footnote{Rotations are non commutative in 3D.}, therefore, in this study, rotations are expressed as three successive rotations about the coordinate axes of the moving frame \eqref{eq:ustation_rotation_combination}. The order of rotation is very important\footnote{Rotations are non commutative in 3D.}, therefore, in this study, rotations are expressed as three successive rotations about the coordinate axes of the moving frame \eqref{eq:ustation_rotation_combination}.
\begin{equation}\label{eq:ustation_rotation_combination} \begin{equation}\label{eq:ustation_rotation_combination}
{}^A\mathbf{R}_B(\alpha, \beta, \gamma) = \mathbf{R}_u(\alpha) \mathbf{R}_v(\beta) \mathbf{R}_c(\gamma) {}^A\bm{R}_B(\alpha, \beta, \gamma) = \bm{R}_u(\alpha) \bm{R}_v(\beta) \bm{R}_c(\gamma)
\end{equation} \end{equation}
Such rotation can be parameterized by three Euler angles \((\alpha,\ \beta,\ \gamma)\), which can be computed from a given rotation matrix using equations \eqref{eq:ustation_euler_angles}. Such rotation can be parameterized by three Euler angles \((\alpha,\ \beta,\ \gamma)\), which can be computed from a given rotation matrix using equations \eqref{eq:ustation_euler_angles}.
@@ -220,7 +208,6 @@ Such rotation can be parameterized by three Euler angles \((\alpha,\ \beta,\ \ga
\gamma &= \text{atan2}(-R_{12}/\cos(\beta),\ R_{11}/\cos(\beta)) \gamma &= \text{atan2}(-R_{12}/\cos(\beta),\ R_{11}/\cos(\beta))
\end{align} \end{align}
\end{subequations} \end{subequations}
\paragraph{Motion of a Rigid Body} \paragraph{Motion of a Rigid Body}
Since the relative positions of a rigid body with respect to a moving frame \(\{B\}\) attached to it are fixed for all time, it is sufficient to know the position of the origin of the frame \(O_B\) and the orientation of the frame \(\{B\}\) with respect to the fixed frame \(\{A\}\), to represent the position of any point \(P\) in the space. Since the relative positions of a rigid body with respect to a moving frame \(\{B\}\) attached to it are fixed for all time, it is sufficient to know the position of the origin of the frame \(O_B\) and the orientation of the frame \(\{B\}\) with respect to the fixed frame \(\{A\}\), to represent the position of any point \(P\) in the space.
@@ -228,24 +215,24 @@ Since the relative positions of a rigid body with respect to a moving frame \(\{
Therefore, the pose of a rigid body can be fully determined by: Therefore, the pose of a rigid body can be fully determined by:
\begin{enumerate} \begin{enumerate}
\item The position vector of point \(O_B\) with respect to frame \(\{A\}\) which is denoted \({}^AP_{O_B}\) \item The position vector of point \(O_B\) with respect to frame \(\{A\}\) which is denoted \({}^AP_{O_B}\)
\item The orientation of the rigid body, or the moving frame \(\{B\}\) attached to it with respect to the fixed frame \(\{A\}\), that is represented by \({}^A\mathbf{R}_B\). \item The orientation of the rigid body, or the moving frame \(\{B\}\) attached to it with respect to the fixed frame \(\{A\}\), that is represented by \({}^A\bm{R}_B\).
\end{enumerate} \end{enumerate}
The position of any point \(P\) of the rigid body with respect to the fixed frame \(\{\mathbf{A}\}\), which is denoted \({}^A\mathbf{P}\) may be determined thanks to the \emph{Chasles' theorem}, which states that if the pose of a rigid body \(\{{}^A\mathbf{R}_B, {}^AP_{O_B}\}\) is given, then the position of any point \(P\) of this rigid body with respect to \(\{\mathbf{A}\}\) is given by Equation \eqref{eq:ustation_chasles_therorem}. The position of any point \(P\) of the rigid body with respect to the fixed frame \(\{\bm{A}\}\), which is denoted \({}^A\bm{P}\) may be determined thanks to the \emph{Chasles' theorem}, which states that if the pose of a rigid body \(\{{}^A\bm{R}_B, {}^AP_{O_B}\}\) is given, then the position of any point \(P\) of this rigid body with respect to \(\{\bm{A}\}\) is given by Equation \eqref{eq:ustation_chasles_therorem}.
\begin{equation} \label{eq:ustation_chasles_therorem} \begin{equation} \label{eq:ustation_chasles_therorem}
{}^AP = {}^A\mathbf{R}_B {}^BP + {}^AP_{O_B} {}^AP = {}^A\bm{R}_B {}^BP + {}^AP_{O_B}
\end{equation} \end{equation}
While equation \eqref{eq:ustation_chasles_therorem} can describe the motion of a rigid body, it can be written in a more convenient way using \(4 \times 4\) homogeneous transformation matrices and \(4 \times 1\) homogeneous coordinates. While equation \eqref{eq:ustation_chasles_therorem} can describe the motion of a rigid body, it can be written in a more convenient way using \(4 \times 4\) homogeneous transformation matrices and \(4 \times 1\) homogeneous coordinates.
The homogeneous transformation matrix is composed of the rotation matrix \({}^A\mathbf{R}_B\) representing the orientation and the position vector \({}^AP_{O_B}\) representing the translation. The homogeneous transformation matrix is composed of the rotation matrix \({}^A\bm{R}_B\) representing the orientation and the position vector \({}^AP_{O_B}\) representing the translation.
It is partitioned as shown in Equation \eqref{eq:ustation_homogeneous_transformation_parts}. It is partitioned as shown in Equation \eqref{eq:ustation_homogeneous_transformation_parts}.
\begin{equation}\label{eq:ustation_homogeneous_transformation_parts} \begin{equation}\label{eq:ustation_homogeneous_transformation_parts}
{}^A\mathbf{T}_B = {}^A\bm{T}_B =
\left[ \begin{array}{ccc|c} \left[ \begin{array}{ccc|c}
& & & \\ & & & \\
& {}^A\mathbf{R}_B & & {}^AP_{O_B} \\ & {}^A\bm{R}_B & & {}^AP_{O_B} \\
& & & \cr & & & \cr
\hline \hline
0 & 0 & 0 & 1 0 & 0 & 0 & 1
@@ -259,12 +246,12 @@ Then, \({}^AP\) can be computed from \({}^BP\) and the homogeneous transformatio
= =
\left[ \begin{array}{ccc|c} \left[ \begin{array}{ccc|c}
& & & \\ & & & \\
& {}^A\mathbf{R}_B & & {}^AP_{O_B} \\ & {}^A\bm{R}_B & & {}^AP_{O_B} \\
& & & \cr & & & \cr
\hline \hline
0 & 0 & 0 & 1 0 & 0 & 0 & 1
\end{array} \right] \end{array} \right]
\left[ \begin{array}{c} \\ {}^BP \\ \cr \hline 1 \end{array} \right] \quad \Rightarrow \quad {}^AP = {}^A\mathbf{R}_B {}^BP + {}^AP_{O_B} \left[ \begin{array}{c} \\ {}^BP \\ \cr \hline 1 \end{array} \right] \quad \Rightarrow \quad {}^AP = {}^A\bm{R}_B {}^BP + {}^AP_{O_B}
\end{equation} \end{equation}
One key advantage of homogeneous transformation is that it can easily be generalized for consecutive transformations. One key advantage of homogeneous transformation is that it can easily be generalized for consecutive transformations.
@@ -278,29 +265,28 @@ Frame \(\{A\}\) represents the initial location, frame \(\{B\}\) is an intermedi
\end{figure} \end{figure}
Furthermore, suppose the position vector of a point \(P\) of the rigid body is given in the final location, that is \({}^CP\) is given, and the position of this point is to be found in the fixed frame \(\{A\}\), that is \({}^AP\). Furthermore, suppose the position vector of a point \(P\) of the rigid body is given in the final location, that is \({}^CP\) is given, and the position of this point is to be found in the fixed frame \(\{A\}\), that is \({}^AP\).
Since the locations of the rigid body are known relative to each other, \({}^CP\) can be transformed to \({}^BP\) using \({}^B\mathbf{T}_C\) using \({}^BP = {}^B\mathbf{T}_C {}^CP\). Since the locations of the rigid body are known relative to each other, \({}^CP\) can be transformed to \({}^BP\) using \({}^B\bm{T}_C\) using \({}^BP = {}^B\bm{T}_C {}^CP\).
Similarly, \({}^BP\) can be transformed into \({}^AP\) using \({}^AP = {}^A\mathbf{T}_B {}^BP\). Similarly, \({}^BP\) can be transformed into \({}^AP\) using \({}^AP = {}^A\bm{T}_B {}^BP\).
Combining the two relations, Equation \eqref{eq:ustation_consecutive_transformations} is obtained. Combining the two relations, Equation \eqref{eq:ustation_consecutive_transformations} is obtained.
This shows that combining multiple transformations is equivalent as to compute \(4 \times 4\) matrix multiplications. This shows that combining multiple transformations is equivalent as to compute \(4 \times 4\) matrix multiplications.
\begin{equation}\label{eq:ustation_consecutive_transformations} \begin{equation}\label{eq:ustation_consecutive_transformations}
{}^AP = \underbrace{{}^A\mathbf{T}_B {}^B\mathbf{T}_C}_{{}^A\mathbf{T}_C} {}^CP {}^AP = \underbrace{{}^A\bm{T}_B {}^B\bm{T}_C}_{{}^A\bm{T}_C} {}^CP
\end{equation} \end{equation}
Another key advantage of homogeneous transformation is the easy inverse transformation, which can be computed using Equation \eqref{eq:ustation_inverse_homogeneous_transformation}. Another key advantage of homogeneous transformation is the easy inverse transformation, which can be computed using Equation \eqref{eq:ustation_inverse_homogeneous_transformation}.
\begin{equation}\label{eq:ustation_inverse_homogeneous_transformation} \begin{equation}\label{eq:ustation_inverse_homogeneous_transformation}
{}^B\mathbf{T}_A = {}^A\mathbf{T}_B^{-1} = {}^B\bm{T}_A = {}^A\bm{T}_B^{-1} =
\left[ \begin{array}{ccc|c} \left[ \begin{array}{ccc|c}
& & & \\ & & & \\
& {}^A\mathbf{R}_B^T & & -{}^A \mathbf{R}_B^T {}^AP_{O_B} \\ & {}^A\bm{R}_B^{\intercal} & & -{}^A \bm{R}_B^{\intercal} {}^AP_{O_B} \\
& & & \cr & & & \cr
\hline \hline
0 & 0 & 0 & 1 \\ 0 & 0 & 0 & 1 \\
\end{array} \right] \end{array} \right]
\end{equation} \end{equation}
\section{Micro-Station Kinematics} \section{Micro-Station Kinematics}
\label{ssec:ustation_kinematics} \label{ssec:ustation_kinematics}
@@ -320,50 +306,51 @@ The motion induced by a positioning stage can be described by a homogeneous tran
As any motion stage induces parasitic motion in all 6 DoF, the transformation matrix representing its induced motion can be written as in \eqref{eq:ustation_translation_stage_errors}. As any motion stage induces parasitic motion in all 6 DoF, the transformation matrix representing its induced motion can be written as in \eqref{eq:ustation_translation_stage_errors}.
\begin{equation}\label{eq:ustation_translation_stage_errors} \begin{equation}\label{eq:ustation_translation_stage_errors}
{}^A\mathbf{T}_B(D_x, D_y, D_z, \theta_x, \theta_y, \theta_z) = {}^A\bm{T}_B(D_x, D_y, D_z, \theta_x, \theta_y, \theta_z) =
\left[ \begin{array}{ccc|c} \left[ \begin{array}{ccc|c}
& & & D_x \\ & & & D_x \\
& \mathbf{R}_x(\theta_x) \mathbf{R}_y(\theta_y) \mathbf{R}_z(\theta_z) & & D_y \\ & \bm{R}_x(\theta_x) \bm{R}_y(\theta_y) \bm{R}_z(\theta_z) & & D_y \\
& & & D_z \cr & & & D_z \cr
\hline \hline
0 & 0 & 0 & 1 0 & 0 & 0 & 1
\end{array} \right] \end{array} \right]
\end{equation} \end{equation}
The homogeneous transformation matrix corresponding to the micro-station \(\mathbf{T}_{\mu\text{-station}}\) is simply equal to the matrix multiplication of the homogeneous transformation matrices of the individual stages as shown in Equation \eqref{eq:ustation_transformation_station}. The homogeneous transformation matrix corresponding to the micro-station \(\bm{T}_{\mu\text{-station}}\) is simply equal to the matrix multiplication of the homogeneous transformation matrices of the individual stages as shown in Equation \eqref{eq:ustation_transformation_station}.
\begin{equation}\label{eq:ustation_transformation_station} \begin{equation}\label{eq:ustation_transformation_station}
\mathbf{T}_{\mu\text{-station}} = \mathbf{T}_{D_y} \cdot \mathbf{T}_{R_y} \cdot \mathbf{T}_{R_z} \cdot \mathbf{T}_{\mu\text{-hexapod}} \bm{T}_{\mu\text{-station}} = \bm{T}_{D_y} \cdot \bm{T}_{R_y} \cdot \bm{T}_{R_z} \cdot \bm{T}_{\mu\text{-hexapod}}
\end{equation} \end{equation}
\(\mathbf{T}_{\mu\text{-station}}\) represents the pose of the sample (supposed to be rigidly fixed on top of the positioning-hexapod) with respect to the granite. \(\bm{T}_{\mu\text{-station}}\) represents the pose of the sample (supposed to be rigidly fixed on top of the positioning-hexapod) with respect to the granite.
If the transformation matrices of the individual stages are each representing a perfect motion (i.e. the stages are supposed to have no parasitic motion), \(\mathbf{T}_{\mu\text{-station}}\) then represent the pose setpoint of the sample with respect to the granite. If the transformation matrices of the individual stages are each representing a perfect motion (i.e. the stages are supposed to have no parasitic motion), \(\bm{T}_{\mu\text{-station}}\) then represents the pose setpoint of the sample with respect to the granite.
The transformation matrices for the translation stage, tilt stage, spindle, and positioning hexapod can be written as shown in Equation \eqref{eq:ustation_transformation_matrices_stages}. The transformation matrices for the translation stage, tilt stage, spindle, and positioning hexapod can be written as shown in Equation \eqref{eq:ustation_transformation_matrices_stages}.
The setpoints are \(D_y\) for the translation stage, \(\theta_y\) for the tilt-stage, \(\theta_z\) for the spindle, \([D_{\mu x},\ D_{\mu y}, D_{\mu z}]\) for the micro-hexapod translations and \([\theta_{\mu x},\ \theta_{\mu y}, \theta_{\mu z}]\) for the micro-hexapod rotations.
\begin{equation}\label{eq:ustation_transformation_matrices_stages} \begin{equation}\label{eq:ustation_transformation_matrices_stages}
\begin{align} \begin{align}
\mathbf{T}_{D_y} &= \begin{bmatrix} \bm{T}_{D_y} &= \begin{bmatrix}
1 & 0 & 0 & 0 \\ 1 & 0 & 0 & 0 \\
0 & 1 & 0 & D_y \\ 0 & 1 & 0 & D_y \\
0 & 0 & 1 & 0 \\ 0 & 0 & 1 & 0 \\
0 & 0 & 0 & 1 0 & 0 & 0 & 1
\end{bmatrix} \quad \end{bmatrix} \quad
\mathbf{T}_{\mu\text{-hexapod}} = \bm{T}_{\mu\text{-hexapod}} =
\left[ \begin{array}{ccc|c} \left[ \begin{array}{ccc|c}
& & & D_{\mu x} \\ & & & D_{\mu x} \\
& \mathbf{R}_x(\theta_{\mu x}) \mathbf{R}_y(\theta_{\mu y}) \mathbf{R}_{z}(\theta_{\mu z}) & & D_{\mu y} \\ & \bm{R}_x(\theta_{\mu x}) \bm{R}_y(\theta_{\mu y}) \bm{R}_{z}(\theta_{\mu z}) & & D_{\mu y} \\
& & & D_{\mu z} \cr & & & D_{\mu z} \cr
\hline \hline
0 & 0 & 0 & 1 0 & 0 & 0 & 1
\end{array} \right] \\ \end{array} \right] \\
\mathbf{T}_{R_z} &= \begin{bmatrix} \bm{T}_{R_z} &= \begin{bmatrix}
\cos(\theta_z) & -\sin(\theta_z) & 0 & 0 \\ \cos(\theta_z) & -\sin(\theta_z) & 0 & 0 \\
\sin(\theta_z) & \cos(\theta_z) & 0 & 0 \\ \sin(\theta_z) & \cos(\theta_z) & 0 & 0 \\
0 & 0 & 1 & 0 \\ 0 & 0 & 1 & 0 \\
0 & 0 & 0 & 1 0 & 0 & 0 & 1
\end{bmatrix} \quad \end{bmatrix} \quad
\mathbf{T}_{R_y} = \begin{bmatrix} \bm{T}_{R_y} = \begin{bmatrix}
\cos(\theta_y) & 0 & \sin(\theta_y) & 0 \\ \cos(\theta_y) & 0 & \sin(\theta_y) & 0 \\
0 & 1 & 0 & 0 \\ 0 & 1 & 0 & 0 \\
-\sin(\theta_y) & 0 & \cos(\theta_y) & 0 \\ -\sin(\theta_y) & 0 & \cos(\theta_y) & 0 \\
@@ -371,7 +358,6 @@ The transformation matrices for the translation stage, tilt stage, spindle, and
\end{bmatrix} \end{bmatrix}
\end{align} \end{align}
\end{equation} \end{equation}
\chapter{Micro-Station Dynamics} \chapter{Micro-Station Dynamics}
\label{sec:ustation_modeling} \label{sec:ustation_modeling}
In this section, the multi-body model of the micro-station is presented. In this section, the multi-body model of the micro-station is presented.
@@ -381,7 +367,7 @@ The inertia of the solid bodies and the stiffness properties of the guiding mech
The obtained dynamics is then compared with the modal analysis performed on the micro-station (Section \ref{ssec:ustation_model_comp_dynamics}). The obtained dynamics is then compared with the modal analysis performed on the micro-station (Section \ref{ssec:ustation_model_comp_dynamics}).
As the dynamics of the nano-hexapod is impacted by the micro-station compliance, the most important dynamical characteristic that should be well modeled is the overall compliance of the micro-station. As the dynamics of the nano-hexapod is impacted by the micro-station compliance, the most important dynamical characteristic that should be well modeled is the overall compliance of the micro-station.
To do so, the 6-DoF compliance of the micro-station is measured and then compared with the 6-DoF compliance extracted from the Simscape model (Section \ref{ssec:ustation_model_compliance}). To do so, the 6-DoF compliance of the micro-station is measured and then compared with the 6-DoF compliance extracted from the multi-body model (Section \ref{ssec:ustation_model_compliance}).
\section{Multi-Body Model} \section{Multi-Body Model}
\label{ssec:ustation_model_simscape} \label{ssec:ustation_model_simscape}
@@ -396,7 +382,7 @@ External forces can be used to model disturbances, and ``sensors'' can be used t
\begin{figure}[htbp] \begin{figure}[htbp]
\centering \centering
\includegraphics[scale=1]{figs/ustation_simscape_stage_example.png} \includegraphics[scale=1]{figs/ustation_simscape_stage_example.png}
\caption{\label{fig:ustation_simscape_stage_example}Example of a stage (here the tilt-stage) represented in the multi-body model (Simscape). It is composed of two solid bodies connected by a 6-DoF joint. One joint DoF (here the tilt angle) can be imposed, the other DoFs are represented by springs and dampers. Additional disturbances forces for all DoF can be included} \caption{\label{fig:ustation_simscape_stage_example}Example of a stage (here the tilt-stage) represented in the multi-body model software (Simscape). It is composed of two solid bodies connected by a 6-DoF joint. One joint DoF (here the tilt angle) can be imposed, the other DoFs are represented by springs and dampers. Additional disturbing forces for all DoF can be included}
\end{figure} \end{figure}
Therefore, the micro-station is modeled by several solid bodies connected by joints. Therefore, the micro-station is modeled by several solid bodies connected by joints.
@@ -408,7 +394,7 @@ The obtained 3D representation of the multi-body model is shown in Figure \ref{f
\begin{figure}[htbp] \begin{figure}[htbp]
\centering \centering
\includegraphics[scale=1,width=0.8\linewidth]{figs/ustation_simscape_model.jpg} \includegraphics[scale=1,width=0.8\linewidth]{figs/ustation_simscape_model.jpg}
\caption{\label{fig:ustation_simscape_model}3D view of the micro-station Simscape model} \caption{\label{fig:ustation_simscape_model}3D view of the micro-station multi-body model}
\end{figure} \end{figure}
The ground is modeled by a solid body connected to the ``world frame'' through a joint only allowing 3 translations. The ground is modeled by a solid body connected to the ``world frame'' through a joint only allowing 3 translations.
@@ -422,6 +408,7 @@ The springs and dampers values were first estimated from the joint/stage specifi
The spring values are summarized in Table \ref{tab:ustation_6dof_stiffness_values}. The spring values are summarized in Table \ref{tab:ustation_6dof_stiffness_values}.
\begin{table}[htbp] \begin{table}[htbp]
\caption{\label{tab:ustation_6dof_stiffness_values}Summary of the stage stiffnesses. The contrained degrees-of-freedom are indicated by ``-''. The frames in which the 6-DoF joints are defined are indicated in figures found in Section \ref{ssec:ustation_stages}}
\centering \centering
\begin{tabularx}{\linewidth}{Xcccccc} \begin{tabularx}{\linewidth}{Xcccccc}
\toprule \toprule
@@ -434,19 +421,16 @@ 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\)\\ 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 \bottomrule
\end{tabularx} \end{tabularx}
\caption{\label{tab:ustation_6dof_stiffness_values}Summary of the stage stiffnesses. The contrained degrees-of-freedom are indicated by ``-''. The frames in which the 6-DoF joints are defined are indicated in figures found in Section \ref{ssec:ustation_stages}}
\end{table} \end{table}
\section{Comparison with the measured dynamics} \section{Comparison with the measured dynamics}
\label{ssec:ustation_model_comp_dynamics} \label{ssec:ustation_model_comp_dynamics}
The dynamics of the micro-station was measured by placing accelerometers on each stage and by impacting the translation stage with an instrumented hammer in three directions. The dynamics of the micro-station was measured by placing accelerometers on each stage and by impacting the translation stage with an instrumented hammer in three directions.
The obtained FRFs were then projected at the CoM of each stage. The obtained FRFs were then projected at the CoM of each stage.
To gain a first insight into the accuracy of the obtained model, the FRFs from the hammer impacts to the acceleration of each stage were extracted from the Simscape model and compared with the measurements in Figure \ref{fig:ustation_comp_com_response}. To gain a first insight into the accuracy of the obtained model, the FRFs from the hammer impacts to the acceleration of each stage were extracted from the multi-body model and compared with the measurements in Figure \ref{fig:ustation_comp_com_response}.
Even though there is some similarity between the model and the measurements (similar overall shapes and amplitudes), it is clear that the Simscape model does not accurately represent the complex micro-station dynamics. Even though there is some similarity between the model and the measurements (similar overall shapes and amplitudes), it is clear that the multi-body model does not accurately represent the complex micro-station dynamics.
Tuning the numerous model parameters to better match the measurements is a highly non-linear optimization problem that is difficult to solve in practice. Tuning the numerous model parameters to better match the measurements is a highly non-linear optimization problem that is difficult to solve in practice.
\begin{figure}[htbp] \begin{figure}[htbp]
@@ -468,9 +452,8 @@ Tuning the numerous model parameters to better match the measurements is a highl
\end{center} \end{center}
\subcaption{\label{fig:ustation_comp_com_response_ry_z}Tilt, $z$ response} \subcaption{\label{fig:ustation_comp_com_response_ry_z}Tilt, $z$ response}
\end{subfigure} \end{subfigure}
\caption{\label{fig:ustation_comp_com_response}FRFs between the hammer impacts on the translation stage and the measured stage acceleration expressed at its CoM. Comparison of the measured and extracted FRFs from the Simscape model. Different directions are computed for different stages.} \caption{\label{fig:ustation_comp_com_response}FRFs between the hammer impacts on the translation stage and the measured stage acceleration expressed at its CoM. Comparison of the measured and extracted FRFs from the multi-body model. Different directions are computed for different stages.}
\end{figure} \end{figure}
\section{Micro-station compliance} \section{Micro-station compliance}
\label{ssec:ustation_model_compliance} \label{ssec:ustation_model_compliance}
@@ -490,10 +473,10 @@ For each impact position, 10 impacts were performed to average and improve the d
\caption{\label{fig:ustation_compliance_meas}Schematic of the measurement setup used to estimate the compliance of the micro-station. The top platform of the positioning hexapod is shown with four 3-axis accelerometers (shown in red) are on top. 10 hammer impacts are performed at different locations (shown in blue).} \caption{\label{fig:ustation_compliance_meas}Schematic of the measurement setup used to estimate the compliance of the micro-station. The top platform of the positioning hexapod is shown with four 3-axis accelerometers (shown in red) are on top. 10 hammer impacts are performed at different locations (shown in blue).}
\end{figure} \end{figure}
To convert the 12 acceleration signals \(a_{\mathcal{L}} = [a_{1x}\ a_{1y}\ a_{1z}\ a_{2x}\ \dots\ a_{4z}]\) to the acceleration expressed in the frame \(\{\mathcal{X}\}\) \(a_{\mathcal{X}} = [a_{dx}\ a_{dy}\ a_{dz}\ a_{rx}\ a_{ry}\ a_{rz}]\), a Jacobian matrix \(\mathbf{J}_a\) is written based on the positions and orientations of the accelerometers \eqref{eq:ustation_compliance_acc_jacobian}. To convert the 12 acceleration signals \(a_{\mathcal{L}} = [a_{1x}\ a_{1y}\ a_{1z}\ a_{2x}\ \dots\ a_{4z}]\) to the acceleration expressed in the frame \(\{\mathcal{X}\}\) \(a_{\mathcal{X}} = [a_{dx}\ a_{dy}\ a_{dz}\ a_{rx}\ a_{ry}\ a_{rz}]\), a Jacobian matrix \(\bm{J}_a\) is written based on the positions and orientations of the accelerometers \eqref{eq:ustation_compliance_acc_jacobian}.
\begin{equation}\label{eq:ustation_compliance_acc_jacobian} \begin{equation}\label{eq:ustation_compliance_acc_jacobian}
\mathbf{J}_a = \begin{bmatrix} \bm{J}_a = \begin{bmatrix}
1 & 0 & 0 & 0 & 0 &-d \\ 1 & 0 & 0 & 0 & 0 &-d \\
0 & 1 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 \\
0 & 0 & 1 & d & 0 & 0 \\ 0 & 0 & 1 & d & 0 & 0 \\
@@ -512,13 +495,13 @@ To convert the 12 acceleration signals \(a_{\mathcal{L}} = [a_{1x}\ a_{1y}\ a_{1
Then, the acceleration in the cartesian frame can be computed using \eqref{eq:ustation_compute_cart_acc}. Then, the acceleration in the cartesian frame can be computed using \eqref{eq:ustation_compute_cart_acc}.
\begin{equation}\label{eq:ustation_compute_cart_acc} \begin{equation}\label{eq:ustation_compute_cart_acc}
a_{\mathcal{X}} = \mathbf{J}_a^\dagger \cdot a_{\mathcal{L}} a_{\mathcal{X}} = \bm{J}_a^\dagger \cdot a_{\mathcal{L}}
\end{equation} \end{equation}
Similar to what is done for the accelerometers, a Jacobian matrix \(\mathbf{J}_F\) is computed \eqref{eq:ustation_compliance_force_jacobian} and used to convert the individual hammer forces \(F_{\mathcal{L}}\) to force and torques \(F_{\mathcal{X}}\) applied at the center of the micro-hexapod top plate (defined by frame \(\{\mathcal{X}\}\) in Figure \ref{fig:ustation_compliance_meas}). Similar to what is done for the accelerometers, a Jacobian matrix \(\bm{J}_F\) is computed \eqref{eq:ustation_compliance_force_jacobian} and used to convert the individual hammer forces \(F_{\mathcal{L}}\) to force and torques \(F_{\mathcal{X}}\) applied at the center of the micro-hexapod top plate (defined by frame \(\{\mathcal{X}\}\) in Figure \ref{fig:ustation_compliance_meas}).
\begin{equation}\label{eq:ustation_compliance_force_jacobian} \begin{equation}\label{eq:ustation_compliance_force_jacobian}
\mathbf{J}_F = \begin{bmatrix} \bm{J}_F = \begin{bmatrix}
0 & -1 & 0 & 0 & 0 & 0\\ 0 & -1 & 0 & 0 & 0 & 0\\
0 & 0 & -1 & -d & 0 & 0\\ 0 & 0 & -1 & -d & 0 & 0\\
1 & 0 & 0 & 0 & 0 & 0\\ 1 & 0 & 0 & 0 & 0 & 0\\
@@ -535,11 +518,11 @@ Similar to what is done for the accelerometers, a Jacobian matrix \(\mathbf{J}_F
The equivalent forces and torques applied at center of \(\{\mathcal{X}\}\) are then computed using \eqref{eq:ustation_compute_cart_force}. The equivalent forces and torques applied at center of \(\{\mathcal{X}\}\) are then computed using \eqref{eq:ustation_compute_cart_force}.
\begin{equation}\label{eq:ustation_compute_cart_force} \begin{equation}\label{eq:ustation_compute_cart_force}
F_{\mathcal{X}} = \mathbf{J}_F^t \cdot F_{\mathcal{L}} F_{\mathcal{X}} = \bm{J}_F^{\intercal} \cdot F_{\mathcal{L}}
\end{equation} \end{equation}
Using the two Jacobian matrices, the FRF from the 10 hammer impacts to the 12 accelerometer outputs can be converted to the FRF from 6 forces/torques applied at the origin of frame \(\{\mathcal{X}\}\) to the 6 linear/angular accelerations of the top platform expressed with respect to \(\{\mathcal{X}\}\). Using the two Jacobian matrices, the FRF from the 10 hammer impacts to the 12 accelerometer outputs can be converted to the FRF from 6 forces/torques applied at the origin of frame \(\{\mathcal{X}\}\) to the 6 linear/angular accelerations of the top platform expressed with respect to \(\{\mathcal{X}\}\).
These FRFs were then used for comparison with the Simscape model. These FRFs were then used for comparison with the multi-body model.
The compliance of the micro-station multi-body model was extracted by computing the transfer function from forces/torques applied on the hexapod's top platform to the ``absolute'' motion of the top platform. The compliance of the micro-station multi-body model was extracted by computing the transfer function from forces/torques applied on the hexapod's top platform to the ``absolute'' motion of the top platform.
These results are compared with the measurements in Figure \ref{fig:ustation_frf_compliance_model}. These results are compared with the measurements in Figure \ref{fig:ustation_frf_compliance_model}.
@@ -558,21 +541,20 @@ Considering the complexity of the micro-station compliance dynamics, the model c
\end{center} \end{center}
\subcaption{\label{fig:ustation_frf_compliance_Rxyz_model}Compliance in rotation} \subcaption{\label{fig:ustation_frf_compliance_Rxyz_model}Compliance in rotation}
\end{subfigure} \end{subfigure}
\caption{\label{fig:ustation_frf_compliance_model}Compliance of the micro-station expressed in frame \(\{\mathcal{X}\}\). The measured FRFs are display by solid lines, while the FRFs extracted from the multi-body models are shown by dashed lines. Both translation terms (\subref{fig:ustation_frf_compliance_xyz_model}) and rotational terms (\subref{fig:ustation_frf_compliance_Rxyz_model}) are displayed.} \caption{\label{fig:ustation_frf_compliance_model}Compliance of the micro-station expressed in frame \(\{\mathcal{X}\}\). The measured FRFs are display by translucent lines, while the FRFs extracted from the multi-body models are shown by opaque lines. Both translation terms (\subref{fig:ustation_frf_compliance_xyz_model}) and rotational terms (\subref{fig:ustation_frf_compliance_Rxyz_model}) are displayed.}
\end{figure} \end{figure}
\chapter{Estimation of Disturbances} \chapter{Estimation of Disturbances}
\label{sec:ustation_disturbances} \label{sec:ustation_disturbances}
The goal of this section is to obtain a realistic representation of disturbances affecting the micro-station. The goal of this section is to obtain a realistic representation of disturbances affecting the micro-station.
These disturbance sources are then used during time domain simulations to accurately model the micro-station behavior. These disturbance sources are then used during time domain simulations to accurately model the micro-station behavior.
The focus on stochastic disturbances because, in principle, it is possible to calibrate the repeatable part of disturbances. The focus is on stochastic disturbances because, in principle, it is possible to calibrate the repeatable part of disturbances.
Such disturbances include ground motions and vibrations induces by scanning the translation stage and the spindle. Such disturbances include ground motions and vibrations induce by scanning the translation stage and the spindle.
In the multi-body model, stage vibrations are modeled as internal forces applied in the stage joint. In the multi-body model, stage vibrations are modeled as internal forces applied in the stage joint.
In practice, disturbance forces cannot be directly measured. In practice, disturbance forces cannot be directly measured.
Instead, the vibrations of the micro-station's top platform induced by the disturbances were measured (Section \ref{ssec:ustation_disturbances_meas}). Instead, the vibrations of the micro-station's top platform induced by the disturbances were measured (Section \ref{ssec:ustation_disturbances_meas}).
To estimate the equivalent disturbance force that induces such vibration, the transfer functions from disturbance sources (i.e. forces applied in the stages' joint) to the displacements of the micro-station's top platform with respect to the granite are extracted from the Simscape model (Section \ref{ssec:ustation_disturbances_sensitivity}). To estimate the equivalent disturbance force that induces such vibration, the transfer functions from disturbance sources (i.e. forces applied in the stages' joint) to the displacements of the micro-station's top platform with respect to the granite are extracted from the multi-body model (Section \ref{ssec:ustation_disturbances_sensitivity}).
Finally, the obtained disturbance sources are compared in Section \ref{ssec:ustation_disturbances_results}. Finally, the obtained disturbance sources are compared in Section \ref{ssec:ustation_disturbances_results}.
\section{Disturbance measurements} \section{Disturbance measurements}
\label{ssec:ustation_disturbances_meas} \label{ssec:ustation_disturbances_meas}
@@ -583,7 +565,7 @@ The tilt stage and the micro-hexapod also have positioning errors; however, they
Therefore, from a control perspective, they are not important. Therefore, from a control perspective, they are not important.
\paragraph{Ground Motion} \paragraph{Ground Motion}
The ground motion was measured by using a sensitive 3-axis geophone\footnote{A 3-Axis L4C geophone manufactured Sercel was used.} placed on the ground. The ground motion was measured by using a sensitive 3-axis geophone shown in Figure \ref{fig:ustation_geophone_picture} placed on the ground.
The generated voltages were recorded with a high resolution DAC, and converted to displacement using the Geophone sensitivity transfer function. The generated voltages were 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}. The obtained ground motion displacement is shown in Figure \ref{fig:ustation_ground_disturbance}.
@@ -600,7 +582,6 @@ The obtained ground motion displacement is shown in Figure \ref{fig:ustation_gro
\captionof{figure}{\label{fig:ustation_geophone_picture}(3D) L-4C geophone} \captionof{figure}{\label{fig:ustation_geophone_picture}(3D) L-4C geophone}
\end{center} \end{center}
\end{minipage} \end{minipage}
\paragraph{Ty Stage} \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. To measure the positioning errors of the translation stage, the setup shown in Figure \ref{fig:ustation_errors_ty_setup} is used.
@@ -610,7 +591,7 @@ A similar setup was used to measure the horizontal deviation (i.e. in the \(x\)
\begin{figure}[htbp] \begin{figure}[htbp]
\centering \centering
\includegraphics[scale=1]{figs/ustation_errors_ty_setup.png} \includegraphics[scale=1]{figs/ustation_errors_ty_setup.png}
\caption{\label{fig:ustation_errors_ty_setup}Experimental setup to measure the flatness (vertical deviation) of the translation stage} \caption{\label{fig:ustation_errors_ty_setup}Experimental setup to measure the straightness (vertical deviation) of the translation stage}
\end{figure} \end{figure}
Six scans were performed between \(-4.5\,mm\) and \(4.5\,mm\). Six scans were performed between \(-4.5\,mm\) and \(4.5\,mm\).
@@ -635,7 +616,6 @@ Similar result is obtained for the \(x\) lateral direction.
\end{subfigure} \end{subfigure}
\caption{\label{fig:ustation_errors_dy}Measurement of the linear (vertical) deviation of the Translation stage (\subref{fig:ustation_errors_dy_vertical}). A linear fit is then removed from the data (\subref{fig:ustation_errors_dy_vertical_remove_mean}).} \caption{\label{fig:ustation_errors_dy}Measurement of the linear (vertical) deviation of the Translation stage (\subref{fig:ustation_errors_dy_vertical}). A linear fit is then removed from the data (\subref{fig:ustation_errors_dy_vertical_remove_mean}).}
\end{figure} \end{figure}
\paragraph{Spindle} \paragraph{Spindle}
To measure the positioning errors induced by the Spindle, a ``Spindle error analyzer''\footnote{The Spindle Error Analyzer is made by Lion Precision.} is used as shown in Figure \ref{fig:ustation_rz_meas_lion_setup}. To measure the positioning errors induced by the Spindle, a ``Spindle error analyzer''\footnote{The Spindle Error Analyzer is made by Lion Precision.} is used as shown in Figure \ref{fig:ustation_rz_meas_lion_setup}.
@@ -688,7 +668,6 @@ The vertical motion induced by scanning the spindle is in the order of \(\pm 30\
\end{subfigure} \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 during a 60rpm spindle rotation. The circular best fit is shown by the dashed circle. It represents the misalignment of the spheres with the rotation axis.} \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. The circular best fit is shown by the dashed circle. It represents the misalignment of the spheres with the rotation axis.}
\end{figure} \end{figure}
\section{Sensitivity to disturbances} \section{Sensitivity to disturbances}
\label{ssec:ustation_disturbances_sensitivity} \label{ssec:ustation_disturbances_sensitivity}
@@ -717,11 +696,10 @@ The obtained transfer functions are shown in Figure \ref{fig:ustation_model_sens
\end{subfigure} \end{subfigure}
\caption{\label{fig:ustation_model_sensitivity}Extracted transfer functions from disturbances to relative motion between the micro-station's top platform and the granite. The considered disturbances are the ground motion (\subref{fig:ustation_model_sensitivity_ground_motion}), the translation stage vibrations (\subref{fig:ustation_model_sensitivity_ty}), and the spindle vibrations (\subref{fig:ustation_model_sensitivity_rz}).} \caption{\label{fig:ustation_model_sensitivity}Extracted transfer functions from disturbances to relative motion between the micro-station's top platform and the granite. The considered disturbances are the ground motion (\subref{fig:ustation_model_sensitivity_ground_motion}), the translation stage vibrations (\subref{fig:ustation_model_sensitivity_ty}), and the spindle vibrations (\subref{fig:ustation_model_sensitivity_rz}).}
\end{figure} \end{figure}
\section{Obtained disturbance sources} \section{Obtained disturbance sources}
\label{ssec:ustation_disturbances_results} \label{ssec:ustation_disturbances_results}
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. From the measured effect of disturbances in Section \ref{ssec:ustation_disturbances_meas} and the sensitivity to disturbances extracted from the multi-body 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.
The obtained power spectral density of the disturbances are shown in Figure \ref{fig:ustation_dist_sources}. The obtained power spectral density of the disturbances are shown in Figure \ref{fig:ustation_dist_sources}.
\begin{figure}[htbp] \begin{figure}[htbp]
@@ -748,7 +726,7 @@ The obtained power spectral density of the disturbances are shown in Figure \ref
The disturbances are characterized by their power spectral densities, as shown in Figure \ref{fig:ustation_dist_sources}. The disturbances are characterized by their power spectral densities, as shown in Figure \ref{fig:ustation_dist_sources}.
However, to perform time domain simulations, disturbances must be represented by a time domain signal. However, to perform time domain simulations, disturbances must be represented by a time domain signal.
To generate stochastic time-domain signals with a specific power spectral densities, the discrete inverse Fourier transform is used, as explained in \cite[chap. 12.11]{preumont94_random_vibrat_spect_analy}. To generate stochastic time-domain signals with a specific power spectral density, the discrete inverse Fourier transform is used, as explained in \cite[chap. 12.11]{preumont94_random_vibrat_spect_analy}.
Examples of the obtained time-domain disturbance signals are shown in Figure \ref{fig:ustation_dist_sources_time}. Examples of the obtained time-domain disturbance signals are shown in Figure \ref{fig:ustation_dist_sources_time}.
\begin{figure}[htbp] \begin{figure}[htbp]
@@ -772,7 +750,6 @@ Examples of the obtained time-domain disturbance signals are shown in Figure \re
\end{subfigure} \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}).} \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} \end{figure}
\chapter{Simulation of Scientific Experiments} \chapter{Simulation of Scientific Experiments}
\label{sec:ustation_experiments} \label{sec:ustation_experiments}
To fully validate the micro-station multi-body model, two time-domain simulations corresponding to typical use cases were performed. To fully validate the micro-station multi-body model, two time-domain simulations corresponding to typical use cases were performed.
@@ -804,8 +781,7 @@ A good correlation with the measurements is observed both for radial errors (Fig
\end{subfigure} \end{subfigure}
\caption{\label{fig:ustation_errors_model_spindle}Simulation results for a tomography experiment at constant velocity of 60rpm. The comparison is made with measurements for both radial (\subref{fig:ustation_errors_model_spindle_radial}) and axial errors (\subref{fig:ustation_errors_model_spindle_axial}).} \caption{\label{fig:ustation_errors_model_spindle}Simulation results for a tomography experiment at constant velocity of 60rpm. The comparison is made with measurements for both radial (\subref{fig:ustation_errors_model_spindle_radial}) and axial errors (\subref{fig:ustation_errors_model_spindle_axial}).}
\end{figure} \end{figure}
\section{Scans with the translation stage}
\section{Raster Scans with the translation stage}
\label{sec:ustation_experiments_ty_scans} \label{sec:ustation_experiments_ty_scans}
A second experiment was performed in which the translation stage was scanned at constant velocity. A second experiment was performed in which the translation stage was scanned at constant velocity.
@@ -819,9 +795,8 @@ A similar error amplitude was observed, thus indicating that the multi-body mode
\includegraphics[scale=1]{figs/ustation_errors_model_dy_vertical.png} \includegraphics[scale=1]{figs/ustation_errors_model_dy_vertical.png}
\caption{\label{fig:ustation_errors_model_dy_vertical}Vertical errors during a constant-velocity scan of the translation stage. Comparison of the measurements and simulated errors.} \caption{\label{fig:ustation_errors_model_dy_vertical}Vertical errors during a constant-velocity scan of the translation stage. Comparison of the measurements and simulated errors.}
\end{figure} \end{figure}
\chapter*{Conclusion} \chapter*{Conclusion}
\label{sec:uniaxial_conclusion} \label{sec:ustation_conclusion}
In this study, a multi-body model of the micro-station was developed. In this study, a multi-body model of the micro-station was developed.
It was difficult to match the measured dynamics obtained from the modal analysis of the micro-station. It was difficult to match the measured dynamics obtained from the modal analysis of the micro-station.
@@ -830,6 +805,5 @@ After tuning the model parameters, a good match with the measured compliance was
The disturbances affecting the sample position should also be well modeled. The disturbances affecting the sample position should also be well modeled.
After experimentally estimating the disturbances (Section \ref{sec:ustation_disturbances}), the multi-body model was finally validated by performing a tomography simulation (Figure \ref{fig:ustation_errors_model_spindle}) as well as a simulation in which the translation stage was scanned (Figure \ref{fig:ustation_errors_model_dy_vertical}). After experimentally estimating the disturbances (Section \ref{sec:ustation_disturbances}), the multi-body model was finally validated by performing a tomography simulation (Figure \ref{fig:ustation_errors_model_spindle}) as well as a simulation in which the translation stage was scanned (Figure \ref{fig:ustation_errors_model_dy_vertical}).
\printbibliography[heading=bibintoc,title={Bibliography}] \printbibliography[heading=bibintoc,title={Bibliography}]
\end{document} \end{document}