24 KiB
		
	
	
	
	
	
	
	
			
		
		
	
	Determination of the optimal nano-hexapod's stiffness for reducing the effect of disturbances
- Introduction
- Disturbances
- Effect of disturbances on the position error
- Effect of granite stiffness
- Open Loop Budget Error
- Closed Loop Budget Error
- Conclusion
Introduction ignore
In this document is studied how the stiffness of the nano-hexapod will impact the effect of disturbances on the position error of the sample.
It is divided in the following sections:
- Section sec:psd_disturbances: the disturbances are listed and their Power Spectral Densities (PSD) are shown
- Section sec:effect_disturbances: the transfer functions from disturbances to the position error of the sample are computed for a wide range of nano-hexapod stiffnesses
- Section sec:granite_stiffness:
- Section sec:open_loop_budget_error: from both the PSD of the disturbances and the transfer function from disturbances to sample's position errors, we compute the resulting PSD and Cumulative Amplitude Spectrum (CAS)
- Section sec:closed_loop_budget_error: from a simplistic model is computed the required control bandwidth to reduce the position error to acceptable values
Disturbances
<<sec:psd_disturbances>>
Introduction ignore
The main disturbances considered here are:
- $D_w$: Ground displacement in the $x$, $y$ and $z$ directions
- $F_{ty}$: Forces applied by the Translation stage in the $x$ and $z$ directions
- $F_{rz}$: Forces applied by the Spindle in the $z$ direction
- $F_d$: Direct forces applied at the center of mass of the Payload
The level of these disturbances has been identified form experiments which are detailed in this document.
Plots ignore
The measured Amplitude Spectral Densities (ASD) of these forces are shown in Figures fig:opt_stiff_dist_gm and fig:opt_stiff_dist_fty_frz.
In this study, the expected frequency content of the direct forces applied to the payload is not considered.
<<plt-matlab>>
<<plt-matlab>>
Effect of disturbances on the position error
<<sec:effect_disturbances>>
Introduction ignore
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();Identification
Inputs:
- Dwx: Ground displacement in the $x$ direction
- Dwy: Ground displacement in the $y$ direction
- Dwz: Ground displacement in the $z$ direction
- Fty_x: Forces applied by the Translation stage in the $x$ direction
- Fty_z: Forces applied by the Translation stage in the $z$ direction
- Frz_z: Forces applied by the Spindle in the $z$ direction
- Fd: 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)};
  endPlots
Effect of Stages vibration (Filtering).
Effect of Ground motion (Transmissibility).
Direct Forces (Compliance).
Save
  save('./mat/opt_stiffness_disturbances.mat', 'Gd')Effect of granite stiffness
<<sec:granite_stiffness>>
Analytical Analysis
  \begin{tikzpicture}
    % ====================
    % Parameters
    % ====================
    \def\massw{2.2}  % Width of the masses
    \def\massh{0.8}  % Height of the masses
    \def\spaceh{1.2} % Height of the springs/dampers
    \def\dispw{0.3}  % Width of the dashed line for the displacement
    \def\disph{0.5}  % Height of the arrow for the displacements
    \def\bracs{0.05} % Brace spacing vertically
    \def\brach{-10pt} % Brace shift horizontaly
    % ====================
    % ====================
    % Ground
    % ====================
    \draw (-0.5*\massw, 0) -- (0.5*\massw, 0);
    \draw[dashed] (0.5*\massw, 0) -- ++(\dispw, 0) coordinate(dlow);
    \draw[->] (0.5*\massw+0.5*\dispw, 0) -- ++(0, \disph) node[right]{$x_{w}$};
    % ====================
    % Micro Station
    % ====================
    \begin{scope}[shift={(0, 0)}]
      % Mass
      \draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m$};
      % Spring, Damper, and Actuator
      \draw[spring] (-0.4*\massw, 0)   -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k$};
      \draw[damper] (0, 0)             -- ( 0, \spaceh)          node[midway, left=0.2]{$c$};
      % Displacements
      \draw[dashed] (0.5*\massw, \spaceh) -- ++(\dispw, 0);
      \draw[->] (0.5*\massw+0.5*\dispw, \spaceh) -- ++(0, \disph) node[right]{$x$};
      % Legend
      \draw[decorate, decoration={brace, amplitude=8pt}, xshift=\brach] %
        (-0.5*\massw, \bracs) -- (-0.5*\massw, \spaceh+\massh-\bracs) %
        node[midway,rotate=90,anchor=south,yshift=10pt,align=center]{Granite};
    \end{scope}
    % ====================
    % Nano Station
    % ====================
    \begin{scope}[shift={(0, \spaceh+\massh)}]
      % Mass
      \draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m^\prime$};
      % Spring, Damper, and Actuator
      \draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k^\prime$};
      \draw[damper] (0, 0)           -- ( 0, \spaceh)          node[midway, left=0.2]{$c^\prime$};
      % Displacements
      \draw[dashed] (0.5*\massw, \spaceh) -- ++(\dispw, 0) coordinate(dhigh);
      \draw[->] (0.5*\massw+0.5*\dispw, \spaceh) -- ++(0, \disph) node[right]{$x^\prime$};
      % Legend
      \draw[decorate, decoration={brace, amplitude=8pt}, xshift=\brach] %
        (-0.5*\massw, \bracs) -- (-0.5*\massw, \spaceh+\massh-\bracs) %
        node[midway,rotate=90,anchor=south,yshift=10pt,align=center]{Positioning\\Stages};
    \end{scope}
  \end{tikzpicture}If we write the equation of motion of the system in Figure fig:2dof_system_granite_stiffness, 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} \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}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)};
  endEffect of the Granite transfer function
Open Loop Budget Error
<<sec:open_loop_budget_error>>
Introduction ignore
Load of the identified disturbances and transfer functions
  load('./mat/dist_psd.mat', 'dist_f');
  load('./mat/opt_stiffness_disturbances.mat', 'Gd')Equations
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]);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]);Closed Loop Budget Error
<<sec:closed_loop_budget_error>>
Introduction ignore
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]);