%% 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);