Determination of the optimal nano-hexapod’s stiffness for reducing the effect of disturbances
Table of Contents
- sec:psd_disturbances
- sec:effect_disturbances
- sec:granite_stiffness
- sec:open_loop_budget_error
- sec:closed_loop_budget_error
1 Spectral Density of Disturbances
The level of disturbances has been identified form experiments. This is detailed in this document.
1.1 Load of the identified disturbances
load('./mat/dist_psd.mat', 'dist_f');
1.2 Plots
2 Effect of disturbances on the position error
2.1 Initialization
We initialize all the stages with the default parameters.
initializeGround(); initializeGranite(); initializeTy(); initializeRy(); initializeRz(); initializeMicroHexapod(); initializeAxisc(); initializeMirror();
We use a sample mass of 10kg.
initializeSample('mass', 10);
initializeSimscapeConfiguration('gravity', true); initializeDisturbances('enable', false); initializeLoggingConfiguration('log', 'none'); initializeController();
2.2 Identification
Inputs:
Dwx
: Ground displacement in the \(x\) directionDwy
: Ground displacement in the \(y\) directionDwz
: Ground displacement in the \(z\) directionFty_x
: Forces applied by the Translation stage in the \(x\) directionFty_z
: Forces applied by the Translation stage in the \(z\) directionFrz_z
: Forces applied by the Spindle in the \(z\) directionFd
: Direct forces applied at the center of mass of the Payload
Ks = logspace(3,9,7); % [N/m]
%% Name of the Simulink File mdl = 'nass_model'; %% Micro-Hexapod clear io; io_i = 1; io(io_i) = linio([mdl, '/Disturbances'], 1, 'openinput', [], 'Dwx'); io_i = io_i + 1; % X Ground motion io(io_i) = linio([mdl, '/Disturbances'], 1, 'openinput', [], 'Dwy'); io_i = io_i + 1; % Y Ground motion io(io_i) = linio([mdl, '/Disturbances'], 1, 'openinput', [], 'Dwz'); io_i = io_i + 1; % Z Ground motion io(io_i) = linio([mdl, '/Disturbances'], 1, 'openinput', [], 'Fty_x'); io_i = io_i + 1; % Parasitic force Ty - X io(io_i) = linio([mdl, '/Disturbances'], 1, 'openinput', [], 'Fty_z'); io_i = io_i + 1; % Parasitic force Ty - Z io(io_i) = linio([mdl, '/Disturbances'], 1, 'openinput', [], 'Frz_z'); io_i = io_i + 1; % Parasitic force Rz - Z io(io_i) = linio([mdl, '/Disturbances'], 1, 'openinput', [], 'Fd'); io_i = io_i + 1; % Direct forces io(io_i) = linio([mdl, '/Tracking Error'], 1, 'openoutput', [], 'En'); io_i = io_i + 1; % Position Error
for i = 1:length(Ks) initializeNanoHexapod('k', Ks(i)); % Run the linearization G = linearize(mdl, io); G.InputName = {'Dwx', 'Dwy', 'Dwz', 'Fty_x', 'Fty_z', 'Frz_z', 'Fdx', 'Fdy', 'Fdz', 'Mdx', 'Mdy', 'Mdz'}; G.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'}; Gd(i) = {minreal(G)}; end
2.3 Plots
Effect of Stages vibration (Filtering). Effect of Ground motion (Transmissibility). Direct Forces (Compliance).
2.4 Save
save('./mat/opt_stiffness_disturbances.mat', 'Gd')
3 Effect of granite stiffness
3.1 Analytical Analysis
Figure 1: Figure caption
If we write the equation of motion of the system in Figure 1, we obtain:
\begin{align} m^\prime s^2 x^\prime &= (c^\prime s + k^\prime) (x - x^\prime) \\ ms^2 x &= (c^\prime s + k^\prime) (x^\prime - x) + (cs + k) (x_w - x) \end{align}If we note \(d = x^\prime - x\), we obtain:
\begin{equation} \label{org4396920} \frac{d}{x_w} = \frac{-m^\prime s^2 (cs + k)}{ (m^\prime s^2 + c^\prime s + k^\prime) (ms^2 + cs + k) + m^\prime s^2(c^\prime s + k^\prime)} \end{equation}3.2 Soft Granite
Let’s initialize a soft granite that will act as an isolation stage from ground motion.
initializeGranite('K', 5e5*ones(3,1), 'C', 5e3*ones(3,1));
Ks = logspace(3,9,7); % [N/m]
for i = 1:length(Ks) initializeNanoHexapod('k', Ks(i)); G = linearize(mdl, io); G.InputName = {'Dwx', 'Dwy', 'Dwz', 'Fty_x', 'Fty_z', 'Frz_z', 'Fdx', 'Fdy', 'Fdz', 'Mdx', 'Mdy', 'Mdz'}; G.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'}; Gdr(i) = {minreal(G)}; end
3.3 Effect of the Granite transfer function
4 Open Loop Budget Error
4.1 Load of the identified disturbances and transfer functions
load('./mat/dist_psd.mat', 'dist_f'); load('./mat/opt_stiffness_disturbances.mat', 'Gd')
4.2 Equations
4.3 Results
Effect of all disturbances
freqs = dist_f.f; figure; hold on; for i = 1:length(Ks) plot(freqs, sqrt(dist_f.psd_rz).*abs(squeeze(freqresp(Gd{i}('Ez', 'Frz_z'), freqs, 'Hz')))); end hold off; set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log'); xlabel('Frequency [Hz]'); ylabel('ASD $\left[\frac{m}{\sqrt{Hz}}\right]$') legend('Location', 'southwest'); xlim([2, 500]);
4.4 Cumulative Amplitude Spectrum
freqs = dist_f.f; figure; hold on; for i = 1:length(Ks) plot(freqs, sqrt(flip(-cumtrapz(flip(freqs), flip(dist_f.psd_ty.*abs(squeeze(freqresp(Gd{i}('Ez', 'Fty_z'), freqs, 'Hz'))).^2)))), '-', ... 'DisplayName', sprintf('$k = %.0g$ [N/m]', Ks(i))); end plot([freqs(1) freqs(end)], [10e-9 10e-9], 'k--', 'HandleVisibility', 'off'); hold off; set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log'); xlabel('Frequency [Hz]'); ylabel('CAS $[m]$') legend('Location', 'southwest'); xlim([2, 500]); ylim([1e-10 1e-6]);
freqs = dist_f.f; figure; hold on; for i = 1:length(Ks) plot(freqs, sqrt(flip(-cumtrapz(flip(freqs), flip(dist_f.psd_rz.*abs(squeeze(freqresp(Gd{i}('Ez', 'Frz_z'), freqs, 'Hz'))).^2)))), '-', ... 'DisplayName', sprintf('$k = %.0g$ [N/m]', Ks(i))); end plot([freqs(1) freqs(end)], [10e-9 10e-9], 'k--', 'HandleVisibility', 'off'); hold off; set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log'); xlabel('Frequency [Hz]'); ylabel('CAS $[m]$') legend('Location', 'southwest'); xlim([2, 500]); ylim([1e-10 1e-6]);
Ground motion
freqs = dist_f.f; figure; hold on; for i = 1:length(Ks) plot(freqs, sqrt(flip(-cumtrapz(flip(freqs), flip(dist_f.psd_gm.*abs(squeeze(freqresp(Gd{i}('Ez', 'Dwz'), freqs, 'Hz'))).^2)))), '-', ... 'DisplayName', sprintf('$k = %.0g$ [N/m]', Ks(i))); end plot([freqs(1) freqs(end)], [10e-9 10e-9], 'k--', 'HandleVisibility', 'off'); hold off; set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log'); xlabel('Frequency [Hz]'); ylabel('CAS $E_y$ $[m]$') legend('Location', 'northeast'); xlim([2, 500]); ylim([1e-10 1e-6]);
freqs = dist_f.f; figure; hold on; for i = 1:length(Ks) plot(freqs, sqrt(flip(-cumtrapz(flip(freqs), flip(dist_f.psd_gm.*abs(squeeze(freqresp(Gd{i}('Ex', 'Dwx'), freqs, 'Hz'))).^2)))), '-', ... 'DisplayName', sprintf('$k = %.0g$ [N/m]', Ks(i))); end plot([freqs(1) freqs(end)], [10e-9 10e-9], 'k--', 'HandleVisibility', 'off'); hold off; set(gca, 'xscale', 'log'); set(gca, 'yscale', 'lin'); xlabel('Frequency [Hz]'); ylabel('CAS $E_y$ $[m]$') legend('Location', 'northeast'); xlim([2, 500]);
freqs = dist_f.f; figure; hold on; for i = 1:length(Ks) plot(freqs, sqrt(flip(-cumtrapz(flip(freqs), flip(dist_f.psd_gm.*abs(squeeze(freqresp(Gd{i}('Ey', 'Dwy'), freqs, 'Hz'))).^2)))), '-', ... 'DisplayName', sprintf('$k = %.0g$ [N/m]', Ks(i))); end plot([freqs(1) freqs(end)], [10e-9 10e-9], 'k--', 'HandleVisibility', 'off'); hold off; set(gca, 'xscale', 'log'); set(gca, 'yscale', 'lin'); xlabel('Frequency [Hz]'); ylabel('CAS $E_y$ $[m]$') legend('Location', 'northeast'); xlim([2, 500]);
Sum of all perturbations
psd_tot = zeros(length(freqs), length(Ks)); for i = 1:length(Ks) psd_tot(:,i) = dist_f.psd_gm.*abs(squeeze(freqresp(Gd{i}('Ez', 'Dwz' ), freqs, 'Hz'))).^2 + ... dist_f.psd_ty.*abs(squeeze(freqresp(Gd{i}('Ez', 'Fty_z'), freqs, 'Hz'))).^2 + ... dist_f.psd_rz.*abs(squeeze(freqresp(Gd{i}('Ez', 'Frz_z'), freqs, 'Hz'))).^2; end
freqs = dist_f.f; figure; hold on; for i = 1:length(Ks) plot(freqs, sqrt(flip(-cumtrapz(flip(freqs), flip(psd_tot(:,i))))), '-', ... 'DisplayName', sprintf('$k = %.0g$ [N/m]', Ks(i))); end plot([freqs(1) freqs(end)], [10e-9 10e-9], 'k--', 'HandleVisibility', 'off'); hold off; set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log'); xlabel('Frequency [Hz]'); ylabel('CAS $E_z$ $[m]$') legend('Location', 'northeast'); xlim([1, 500]); ylim([1e-10 1e-6]);
5 Closed Loop Budget Error
5.1 Reduction thanks to feedback - Required bandwidth
wc = 1*2*pi; % [rad/s] xic = 0.5; S = (s/wc)/(1 + s/wc); bodeFig({S}, logspace(-1,2,1000))
wc = [1, 5, 10, 20, 50, 100, 200]; S1 = {zeros(length(wc), 1)}; S2 = {zeros(length(wc), 1)}; for j = 1:length(wc) L = (2*pi*wc(j))/s; % Simple integrator S1{j} = 1/(1 + L); L = ((2*pi*wc(j))/s)^2*(1 + s/(2*pi*wc(j)/2))/(1 + s/(2*pi*wc(j)*2)); S2{j} = 1/(1 + L); end
freqs = dist_f.f; figure; hold on; i = 6; for j = 1:length(wc) set(gca,'ColorOrderIndex',j); plot(freqs, sqrt(flip(-cumtrapz(flip(freqs), flip(abs(squeeze(freqresp(S1{j}, freqs, 'Hz'))).^2.*psd_tot(:,i))))), '-', ... 'DisplayName', sprintf('$\\omega_c = %.0f$ [Hz]', wc(j))); end plot(freqs, sqrt(flip(-cumtrapz(flip(freqs), flip(psd_tot(:,i))))), 'k-', ... 'DisplayName', 'Open-Loop'); plot([freqs(1) freqs(end)], [10e-9 10e-9], 'k--', 'HandleVisibility', 'off'); hold off; set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log'); xlabel('Frequency [Hz]'); ylabel('CAS $E_y$ $[m]$') legend('Location', 'northeast'); xlim([0.5, 500]); ylim([1e-10 1e-6]);
wc = logspace(0, 3, 100); Dz1_rms = zeros(length(Ks), length(wc)); Dz2_rms = zeros(length(Ks), length(wc)); for i = 1:length(Ks) for j = 1:length(wc) L = (2*pi*wc(j))/s; Dz1_rms(i, j) = sqrt(trapz(freqs, abs(squeeze(freqresp(1/(1 + L), freqs, 'Hz'))).^2.*psd_tot(:,i))); L = ((2*pi*wc(j))/s)^2*(1 + s/(2*pi*wc(j)/2))/(1 + s/(2*pi*wc(j)*2)); Dz2_rms(i, j) = sqrt(trapz(freqs, abs(squeeze(freqresp(1/(1 + L), freqs, 'Hz'))).^2.*psd_tot(:,i))); end end
freqs = dist_f.f; figure; hold on; for i = 1:length(Ks) set(gca,'ColorOrderIndex',i); plot(wc, Dz1_rms(i, :), '-', ... 'DisplayName', sprintf('$k = %.0g$ [N/m]', Ks(i))) set(gca,'ColorOrderIndex',i); plot(wc, Dz2_rms(i, :), '--', ... 'HandleVisibility', 'off') end hold off; set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log'); xlabel('Control Bandwidth [Hz]'); ylabel('$E_z\ [m, rms]$') legend('Location', 'southwest'); xlim([1, 500]);