add all files
This commit is contained in:
210
C5-test-bench-id31/test_id31_1_metrology.m
Normal file
210
C5-test-bench-id31/test_id31_1_metrology.m
Normal file
@@ -0,0 +1,210 @@
|
||||
%% test_id31_1_metrology.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
|
||||
|
||||
%% Data directory
|
||||
data_dir = './mat/';
|
||||
|
||||
%% Colors for the figures
|
||||
colors = colororder;
|
||||
|
||||
%% Frequency Vector
|
||||
freqs = logspace(log10(1), log10(2e3), 1000);
|
||||
|
||||
%% Sampling Time
|
||||
Ts = 1e-4;
|
||||
|
||||
%% Specifications for Experiments
|
||||
specs_dz_peak = 50; % [nm]
|
||||
specs_dy_peak = 100; % [nm]
|
||||
specs_ry_peak = 0.85; % [urad]
|
||||
specs_dz_rms = 15; % [nm RMS]
|
||||
specs_dy_rms = 30; % [nm RMS]
|
||||
specs_ry_rms = 0.25; % [urad RMS]
|
||||
|
||||
%% Geometrical parameters of the metrology system
|
||||
H = 150e-3;
|
||||
l1 = (150-48-42)*1e-3;
|
||||
l2 = (76.2+48+42-150)*1e-3;
|
||||
|
||||
% Computation of the Transformation matrix
|
||||
Hm = [ 0 1 0 -l2 0;
|
||||
0 1 0 l1 0;
|
||||
-1 0 0 0 -l2;
|
||||
-1 0 0 0 l1;
|
||||
0 0 -1 0 0];
|
||||
|
||||
%% Angular alignment
|
||||
% Load Data
|
||||
data_it0 = h5scan(data_dir, 'alignment', 'h1rx_h1ry', 1);
|
||||
data_it1 = h5scan(data_dir, 'alignment', 'h1rx_h1ry_0002', 3);
|
||||
data_it2 = h5scan(data_dir, 'alignment', 'h1rx_h1ry_0002', 5);
|
||||
|
||||
% Offset wrong points
|
||||
i_it0 = find(abs(data_it0.Rx_int_filtered(2:end)-data_it0.Rx_int_filtered(1:end-1))>1e-5);
|
||||
data_it0.Rx_int_filtered(i_it0+1:end) = data_it0.Rx_int_filtered(i_it0+1:end) + data_it0.Rx_int_filtered(i_it0) - data_it0.Rx_int_filtered(i_it0+1);
|
||||
i_it1 = find(abs(data_it1.Rx_int_filtered(2:end)-data_it1.Rx_int_filtered(1:end-1))>1e-5);
|
||||
data_it1.Rx_int_filtered(i_it1+1:end) = data_it1.Rx_int_filtered(i_it1+1:end) + data_it1.Rx_int_filtered(i_it1) - data_it1.Rx_int_filtered(i_it1+1);
|
||||
i_it2 = find(abs(data_it2.Rx_int_filtered(2:end)-data_it2.Rx_int_filtered(1:end-1))>1e-5);
|
||||
data_it2.Rx_int_filtered(i_it2+1:end) = data_it2.Rx_int_filtered(i_it2+1:end) + data_it2.Rx_int_filtered(i_it2) - data_it2.Rx_int_filtered(i_it2+1);
|
||||
|
||||
% Compute circle fit and get radius
|
||||
[~, ~, R_it0, ~] = circlefit(1e6*data_it0.Rx_int_filtered, 1e6*data_it0.Ry_int_filtered);
|
||||
[~, ~, R_it1, ~] = circlefit(1e6*data_it1.Rx_int_filtered, 1e6*data_it1.Ry_int_filtered);
|
||||
[~, ~, R_it2, ~] = circlefit(1e6*data_it2.Rx_int_filtered, 1e6*data_it2.Ry_int_filtered);
|
||||
|
||||
%% Rx/Ry alignment of the spheres using the micro-station
|
||||
figure;
|
||||
hold on;
|
||||
plot(1e6*data_it0.Rx_int_filtered, 1e6*data_it0.Ry_int_filtered, '-', ...
|
||||
'DisplayName', sprintf('$R_0 = %.0f \\mu$rad', R_it0))
|
||||
plot(1e6*data_it1.Rx_int_filtered, 1e6*data_it1.Ry_int_filtered, '-', ...
|
||||
'DisplayName', sprintf('$R_1 = %.0f \\mu$rad', R_it1))
|
||||
plot(1e6*data_it2.Rx_int_filtered, 1e6*data_it2.Ry_int_filtered, '-', 'color', colors(5,:), ...
|
||||
'DisplayName', sprintf('$R_2 = %.0f \\mu$rad', R_it2))
|
||||
hold off;
|
||||
xlabel('$R_x$ [$\mu$rad]'); ylabel('$R_y$ [$\mu$rad]');
|
||||
axis equal
|
||||
legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 1);
|
||||
xlim([-600, 300]);
|
||||
ylim([-100, 800]);
|
||||
|
||||
%% Eccentricity alignment
|
||||
% Load Data
|
||||
data_it0 = h5scan(data_dir, 'alignment', 'h1rx_h1ry_0002', 5);
|
||||
data_it1 = h5scan(data_dir, 'alignment', 'h1dx_h1dy', 1);
|
||||
|
||||
% Offset wrong points
|
||||
i_it0 = find(abs(data_it0.Dy_int_filtered(2:end)-data_it0.Dy_int_filtered(1:end-1))>1e-5);
|
||||
data_it0.Dy_int_filtered(i_it0+1:end) = data_it0.Dy_int_filtered(i_it0+1:end) + data_it0.Dy_int_filtered(i_it0) - data_it0.Dy_int_filtered(i_it0+1);
|
||||
|
||||
% Compute circle fit and get radius
|
||||
[~, ~, R_it0, ~] = circlefit(1e6*data_it0.Dx_int_filtered, 1e6*data_it0.Dy_int_filtered);
|
||||
[~, ~, R_it1, ~] = circlefit(1e6*data_it1.Dx_int_filtered, 1e6*data_it1.Dy_int_filtered);
|
||||
|
||||
%% Dx/Dy alignment of the spheres using the micro-station
|
||||
figure;
|
||||
hold on;
|
||||
plot(1e6*data_it0.Dx_int_filtered, 1e6*data_it0.Dy_int_filtered, '-', ...
|
||||
'DisplayName', sprintf('$R_0 = %.0f \\mu$m', R_it0))
|
||||
plot(1e6*data_it1.Dx_int_filtered, 1e6*data_it1.Dy_int_filtered, '-', ...
|
||||
'DisplayName', sprintf('$R_1 = %.0f \\mu$m', R_it1))
|
||||
hold off;
|
||||
xlabel('$D_x$ [$\mu$m]'); ylabel('$D_y$ [$\mu$m]');
|
||||
axis equal
|
||||
legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 1);
|
||||
xlim([-1, 21]);
|
||||
ylim([-8, 14]);
|
||||
|
||||
%% Estimated acceptance of the metrology
|
||||
% This is estimated by moving the spheres using the micro-hexapod
|
||||
|
||||
% Dx
|
||||
data_dx = h5scan(data_dir, 'metrology_acceptance_new_align', 'dx', 1);
|
||||
|
||||
dx_acceptance = zeros(5,1);
|
||||
|
||||
for i = [1:size(dx_acceptance, 1)]
|
||||
% Find range in which the interferometers are measuring displacement
|
||||
dx_di = diff(data_dx.(sprintf('d%i', i))) == 0;
|
||||
if sum(dx_di) > 0
|
||||
dx_acceptance(i) = data_dx.h1tx(find(dx_di(501:end), 1) + 500) - ...
|
||||
data_dx.h1tx(find(flip(dx_di(1:500)), 1));
|
||||
else
|
||||
dx_acceptance(i) = data_dx.h1tx(end) - data_dx.h1tx(1);
|
||||
end
|
||||
end
|
||||
|
||||
% Dy
|
||||
data_dy = h5scan(data_dir, 'metrology_acceptance_new_align', 'dy', 1);
|
||||
|
||||
dy_acceptance = zeros(5,1);
|
||||
|
||||
for i = [1:size(dy_acceptance, 1)]
|
||||
% Find range in which the interferometers are measuring displacement
|
||||
dy_di = diff(data_dy.(sprintf('d%i', i))) == 0;
|
||||
if sum(dy_di) > 0
|
||||
dy_acceptance(i) = data_dy.h1ty(find(dy_di(501:end), 1) + 500) - ...
|
||||
data_dy.h1ty(find(flip(dy_di(1:500)), 1));
|
||||
else
|
||||
dy_acceptance(i) = data_dy.h1ty(end) - data_dy.h1ty(1);
|
||||
end
|
||||
end
|
||||
|
||||
% Dz
|
||||
data_dz = h5scan(data_dir, 'metrology_acceptance_new_align', 'dz', 1);
|
||||
|
||||
dz_acceptance = zeros(5,1);
|
||||
|
||||
for i = [1:size(dz_acceptance, 1)]
|
||||
% Find range in which the interferometers are measuring displacement
|
||||
dz_di = diff(data_dz.(sprintf('d%i', i))) == 0;
|
||||
if sum(dz_di) > 0
|
||||
dz_acceptance(i) = data_dz.h1tz(find(dz_di(501:end), 1) + 500) - ...
|
||||
data_dz.h1tz(find(flip(dz_di(1:500)), 1));
|
||||
else
|
||||
dz_acceptance(i) = data_dz.h1tz(end) - data_dz.h1tz(1);
|
||||
end
|
||||
end
|
||||
|
||||
%% Interferometer noise estimation
|
||||
data = load("test_id31_interf_noise.mat");
|
||||
|
||||
Ts = 1e-4;
|
||||
Nfft = floor(5/Ts);
|
||||
win = hanning(Nfft);
|
||||
Noverlap = floor(Nfft/2);
|
||||
|
||||
[pxx_int, f] = pwelch(detrend(data.d, 0), win, Noverlap, Nfft, 1/Ts);
|
||||
|
||||
% Uncorrelated noise: square root of the sum of the squares
|
||||
pxx_cart = pxx_int*sum(inv(Hm).^2, 2)';
|
||||
|
||||
rms_dxy = sqrt(trapz(f(f>1), pxx_cart((f>1),1))); % < 0.3 nm RMS
|
||||
rms_dz = sqrt(trapz(f(f>1), pxx_cart((f>1),3))); % < 0.3 nm RMS
|
||||
rms_rxy = sqrt(trapz(f(f>1), pxx_cart((f>1),4))); % 5 nrad RMS
|
||||
|
||||
figure;
|
||||
hold on;
|
||||
plot(f, sqrt(pxx_cart(:,1)), 'DisplayName', sprintf('$D_{x,y}$, %.1f nmRMS', rms_dxy));
|
||||
plot(f, sqrt(pxx_cart(:,3)), 'DisplayName', sprintf('$D_{z}$, %.1f nmRMS', rms_dz));
|
||||
plot(f, sqrt(pxx_cart(:,4)), 'DisplayName', sprintf('$R_{x,y}$, %.1f nradRMS', rms_rxy));
|
||||
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
|
||||
xlabel('Frequency [Hz]'); ylabel('ASD $\left[\frac{nm,\ nrad}{\sqrt{Hz}}\right]$')
|
||||
xlim([1, 1e3]); ylim([1e-3, 1]);
|
||||
leg = legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 1);
|
||||
leg.ItemTokenSize(1) = 15;
|
||||
|
||||
%% X-Y scan with the micro-hexapod, and record of the vertical interferometer
|
||||
data = h5scan(data_dir, 'metrology_acceptance', 'after_int_align_meshXY', 1);
|
||||
|
||||
x = 1e3*detrend(data.h1tx, 0); % [um]
|
||||
y = 1e3*detrend(data.h1ty, 0); % [um]
|
||||
z = 1e6*data.Dz_int_filtered - max(data.Dz_int_filtered); % [um]
|
||||
|
||||
mdl = scatteredInterpolant(x, y, z);
|
||||
[xg, yg] = meshgrid(unique(x), unique(y));
|
||||
zg = mdl(xg, yg);
|
||||
|
||||
% Fit a sphere to the data
|
||||
[sphere_center,sphere_radius] = sphereFit(1e-3*[x, y, z]);
|
||||
|
||||
%% XY mapping of the Z measurement by the interferometer
|
||||
figure;
|
||||
[~,c] = contour3(xg,yg,zg,30);
|
||||
c.LineWidth = 3;
|
||||
xlabel('$D_x$ [$\mu$m]');
|
||||
ylabel('$D_y$ [$\mu$m]');
|
||||
zlabel('$D_z$ [$\mu$m]');
|
||||
zlim([-1, 0]);
|
||||
xticks(-100:50:100); yticks(-100:50:100); zticks(-1:0.2:0);
|
Reference in New Issue
Block a user