phd-simscape-nass/simscape-nass.org

145 KiB
Raw Blame History

Simscape Model - Nano Active Stabilization System

Introduction   ignore

From last sections:

  • Uniaxial: No stiff nano-hexapod (should also demonstrate that here)
  • Rotating: No soft nano-hexapod, Decentralized IFF can be used robustly by adding parallel stiffness

In this section:

  • Take the model of the nano-hexapod with stiffness 1um/N
  • Apply decentralized IFF
  • Apply HAC-LAC
  • Check robustness to payload change
  • Simulation of experiments

Control Kinematics

<<sec:nass_kinematics>>

Introduction   ignore

  • Explained during the last section: HAC-IFF Decentralized IFF Centralized HAC, control in the frame of the struts
  • To compute the positioning errors in the frame of the struts

    • Compute the wanted pose of the sample with respect to the granite using the micro-station kinematics (Section ref:ssec:nass_ustation_kinematics)
    • Measure the sample pose with respect to the granite using the external metrology and internal metrology for Rz (Section ref:ssec:nass_sample_pose_error)
    • Compute the sample pose error and map these errors in the frame of the struts (Section ref:ssec:nass_error_struts)
  • The complete control architecture is shown in Section ref:ssec:nass_control_architecture
  • positioning_error: Explain how the NASS control is made (computation of the wanted position, measurement of the sample position, computation of the errors)
  • Schematic with micro-station + nass + metrology + control system => explain what is inside the control system
/tdehaeze/phd-simscape-nass/media/commit/b9a5308fa3902167e7d305a76026e1e209d5e91a/figs/nass_concept_schematic.png
Figure caption

Micro Station Kinematics

<<ssec:nass_ustation_kinematics>>

  • from ref:ssec:ustation_kinematics, computation of the wanted sample pose from the setpoint of each stage.

wanted pose = Tdy * Try * Trz * Tu

Computation of the sample's pose error

<<ssec:nass_sample_pose_error>>

From metrology (here supposed to be perfect 6-DoF), compute the sample's pose error. Has to invert the homogeneous transformation.

In reality, 5DoF metrology => have to estimate the Rz using spindle encoder + nano-hexapod internal metrology (micro-hexapod does not perform Rz rotation).

Position error in the frame of the struts

<<ssec:nass_error_struts>>

Explain how to compute the errors in the frame of the struts (rotating):

  • Errors in the granite frame
  • Errors in the frame of the nano-hexapod
  • Errors in the frame of the struts => used for control

Control Architecture

<<ssec:nass_control_architecture>>

  • Say that there are many control strategies. It will be the topic of chapter 2.3. Here, we start with something simple: control in the frame of the struts
\begin{tikzpicture}
  % Blocs
  \node[block={2.0cm}{1.0cm}, fill=colorblue!20!white] (metrology) {Metrology};
  \node[block={2.0cm}{2.0cm}, below=0.1 of metrology, align=center, fill=colorblue!20!white] (nhexa) {Nano\\Hexapod};
  \node[block={3.0cm}{1.5cm}, below=0.1 of nhexa, align=center, fill=colorblue!20!white] (ustation) {Micro\\Station};

  \coordinate[] (inputf)  at ($(nhexa.south west)!0.5!(nhexa.north west)$);
  \coordinate[] (outputfn) at ($(nhexa.south east)!0.3!(nhexa.north east)$);
  \coordinate[] (outputde) at ($(nhexa.south east)!0.7!(nhexa.north east)$);

  \coordinate[] (outputDy) at ($(ustation.south east)!0.1!(ustation.north east)$);
  \coordinate[] (outputRy) at ($(ustation.south east)!0.5!(ustation.north east)$);
  \coordinate[] (outputRz) at ($(ustation.south east)!0.9!(ustation.north east)$);

  \node[block={1.0cm}{1.0cm}, right=0.5 of outputde, fill=colorred!20!white] (Rz_kinematics) {$\bm{J}_{R_z}^{-1}$};
  \node[block={2.0cm}{2.0cm}, right=2.2 of ustation, align=center, fill=colorred!20!white] (ustation_kinematics) {Compute\\Reference\\Position};
  \node[block={2.0cm}{2.0cm}, right=0.8 of ustation_kinematics, align=center, fill=colorred!20!white] (compute_error) {Compute\\Error\\Position};
  \node[block={2.0cm}{2.0cm}, above=0.8 of compute_error, align=center, fill=colorred!20!white] (compute_pos) {Compute\\Sample\\Position};
  \node[block={1.0cm}{1.0cm}, right=0.8 of compute_error, fill=colorred!20!white] (hexa_jacobian) {$\bm{J}$};

  \coordinate[] (inputMetrology) at ($(compute_error.north east)!0.3!(compute_error.north west)$);
  \coordinate[] (inputRz) at ($(compute_error.north east)!0.7!(compute_error.north west)$);

  \node[addb={+}{}{}{}{}, right=0.4 of Rz_kinematics, fill=colorred!20!white] (addRz) {};
  \draw[->] (Rz_kinematics.east) -- (addRz.west);
  \draw[->] (outputRz-|addRz)node[branch]{} -- (addRz.south);

  \draw[->] (outputDy) node[above right]{$r_{D_y}$} -- (outputDy-|ustation_kinematics.west);
  \draw[->] (outputRy) node[above right]{$r_{R_y}$} -- (outputRy-|ustation_kinematics.west);
  \draw[->] (outputRz) node[above right]{$r_{R_z}$} -- (outputRz-|ustation_kinematics.west);

  \draw[->] (metrology.east)node[above right]{$[D_x,\,D_y,\,D_z,\,R_x,\,R_y]$} -- (compute_pos.west|-metrology);
  \draw[->] (addRz.east)node[above right]{$R_z$} -- (compute_pos.west|-addRz);
  \draw[->] (compute_pos.south)node -- (compute_error.north)node[above right]{$\bm{y}_{\mathcal{X}}$};

  \draw[->] (outputde) -- (Rz_kinematics.west) node[above left]{$\bm{\mathcal{L}}$};
  \draw[->] (ustation_kinematics.east) -- (compute_error.west) node[above left]{$\bm{r}_{\mathcal{X}}$};
  \draw[->] (compute_error.east) -- (hexa_jacobian.west) node[above left]{$\bm{\epsilon\mathcal{X}}$};
  \draw[->] (hexa_jacobian.east) -- ++(1.8, 0) node[above left]{$\bm{\epsilon\mathcal{L}}$};

  \draw[->] (outputfn) -- ($(outputfn-|hexa_jacobian.east) + (1.0, 0)$)coordinate(fn) node[above left]{$\bm{f}_n$};

  \begin{scope}[on background layer]
    \node[fit={(metrology.north-|ustation.west) (hexa_jacobian.east|-compute_error.south)}, fill=black!10!white, draw, dashed, inner sep=4pt] (plant) {};
    \node[anchor={north east}] at (plant.north east){$\text{Plant}$};
  \end{scope}

  \node[block, above=0.2 of plant, fill=coloryellow!20!white] (Kiff) {$\bm{K}_{\text{IFF}}$};
  \draw[->] ($(fn)-(0.6,0)$)node[branch]{} |- (Kiff.east);

  \node[addb={+}{}{}{}{}, left=0.8 of inputf] (addf) {};
  \draw[->] (Kiff.west) -| (addf.north);

  \begin{scope}[on background layer]
    \node[fit={(plant.south-|fn) (addf.west|-Kiff.north)}, fill=black!20!white, draw, dashed, inner sep=4pt] (damped_plant) {};
    \node[anchor={north east}] at (damped_plant.north east){$\text{Damped Plant}$};
  \end{scope}

  \begin{scope}[on background layer]
    \node[fit={(metrology.north-|ustation.west) (hexa_jacobian.east|-compute_error.south)}, fill=black!10!white, draw, dashed, inner sep=4pt] (plant) {};
    \node[anchor={north east}] at (plant.north east){$\text{Plant}$};
  \end{scope}

  \node[block, left=0.8 of addf, fill=colorgreen!20!white] (Khac) {$\bm{K}_{\text{HAC}}$};
  \draw[->] ($(hexa_jacobian.east)+(1.4,0)$)node[branch]{} |- ($(Khac.west)+(-0.4, -3.4)$) |- (Khac.west);
  \draw[->] (Khac.east) -- node[midway, above]{$\bm{f}^{\prime}$} (addf.west);
  \draw[->] (addf.east) -- (inputf) node[above left]{$\bm{f}$};
\end{tikzpicture}

/tdehaeze/phd-simscape-nass/media/commit/b9a5308fa3902167e7d305a76026e1e209d5e91a/figs/nass_control_architecture.png

Decentralized Active Damping

<<sec:nass_active_damping>>

Introduction   ignore

  • How to apply/optimize IFF on an hexapod?
  • Robustness to payload mass
  • Root Locus
  • Damping optimization
  • Parallel stiffness?

Explain which samples are tested:

IFF Plant

  • Show how it changes with the payload mass (1, 25, 50)
  • Effect of rotation (no rotation - 60rpm)
  • Added parallel stiffness
%% Identify the IFF plant dynamics using the Simscape model

% Initialize each Simscape model elements
initializeGround();
initializeGranite();
initializeTy();
initializeRy();
initializeRz();
initializeMicroHexapod();
initializeSimplifiedNanoHexapod();
initializeSample('type', 'cylindrical', 'm', 1);

% Initial Simscape Configuration
initializeSimscapeConfiguration('gravity', false);
initializeDisturbances('enable', false);
initializeLoggingConfiguration('log', 'none');
initializeController('type', 'open-loop');
initializeReferences();

% Input/Output definition
clear io; io_i = 1;
io(io_i) = linio([mdl, '/Controller'], 1, 'openinput');             io_i = io_i + 1; % Actuator Inputs [N]
io(io_i) = linio([mdl, '/NASS'],       3, 'openoutput', [], 'fn');  io_i = io_i + 1; % Force Sensors [N]
%% Identify for multi payload masses (no rotation)
initializeReferences(); % No Spindle Rotation
initializeSample('type', 'cylindrical', 'm', 1);
G_iff_m1 = linearize(mdl, io);
G_iff_m1.InputName  = {'f1',  'f2',  'f3',  'f4',  'f5',  'f6'};
G_iff_m1.OutputName = {'fn1', 'fn2', 'fn3', 'fn4', 'fn5', 'fn6'};

initializeSample('type', 'cylindrical', 'm', 25);
G_iff_m25 = linearize(mdl, io);
G_iff_m25.InputName  = {'f1',  'f2',  'f3',  'f4',  'f5',  'f6'};
G_iff_m25.OutputName = {'fn1', 'fn2', 'fn3', 'fn4', 'fn5', 'fn6'};

initializeSample('type', 'cylindrical', 'm', 50);
G_iff_m50 = linearize(mdl, io);
G_iff_m50.InputName  = {'f1',  'f2',  'f3',  'f4',  'f5',  'f6'};
G_iff_m50.OutputName = {'fn1', 'fn2', 'fn3', 'fn4', 'fn5', 'fn6'};
%% Effect of Rotation
initializeReferences(...
    'Rz_type', 'rotating', ...
    'Rz_period', 1); % 360 deg/s
initializeSample('type', 'cylindrical', 'm', 1);
G_iff_m1_Rz = linearize(mdl, io, 0.1);
G_iff_m1_Rz.InputName  = {'f1',  'f2',  'f3',  'f4',  'f5',  'f6'};
G_iff_m1_Rz.OutputName = {'fn1', 'fn2', 'fn3', 'fn4', 'fn5', 'fn6'};

Coupling

Effect of rotation

Effect of payload mass

Controller Design

Low pass filter needs to be added (because now: DC gain)

\begin{equation}\label{eq:nass_kiff} \bm{K}_{\text{IFF}}(s) = g ⋅ \begin{bmatrix} K_{\text{IFF}}(s) & & 0 \\ & \ddots & \\ 0 & & K_{\text{IFF}}(s) \end{bmatrix}, \quad K_{\text{IFF}}(s) = \frac{1}{s}

\end{equation}

%% IFF Controller Design
% Second order high pass filter
wz = 2*pi*3;
xiz = 0.7;
Ghpf = (s^2/wz^2)/(s^2/wz^2 + 2*xiz*s/wz + 1);

Kiff = -200 * ...              % Gain
       1/(0.01*2*pi + s) * ... % LPF: provides integral action
       Ghpf * ...              % 2nd order HPF (limit low frequency gain)
       eye(6);                 % Diagonal 6x6 controller (i.e. decentralized)

Kiff.InputName = {'fm1', 'fm2', 'fm3', 'fm4', 'fm5', 'fm6'};
Kiff.OutputName = {'f1', 'f2', 'f3', 'f4', 'f5', 'f6'};
% The designed IFF controller is saved
save('./mat/nass_K_iff.mat', 'Kiff');

Loop Gain:

Root Locus => Stability

  • Use Integral controller (with parallel stiffness)
  • Show Root Locus (show that without parallel stiffness => unstable?)
  • Choose optimal gain. Here in MIMO, cannot have optimal damping for all modes. (there is a paper that tries to optimize that)
  • Show robustness to change of payload (loci?) / Change of rotating velocity ?
  • Reference to paper showing stability in MIMO for decentralized IFF

Sensitivity to disturbances

Disturbances:

  • floor motion
  • Spindle X and Z
  • Direct forces?
  • Compute sensitivity to disturbances with and without IFF (and compare without the NASS)
  • Maybe noise budgeting, but may be complex in MIMO… ?

Centralized Active Vibration Control

<<sec:nass_hac>>

Introduction   ignore

  • uncertainty_experiment: Effect of experimental conditions on the plant (payload mass, Ry position, Rz position, Rz velocity, etc…)
  • Effect of micro-station compliance
  • Effect of IFF
  • Effect of payload mass
  • Decoupled plant
  • Controller design

From control kinematics:

  • Talk about issue of not estimating Rz from external metrology? (maybe could be nice to discuss that during the experiments!)
  • Show what happens is Rz is not estimated (for instance supposed equaled to zero => increased coupling)

HAC Plant

  • Compute transfer function from $\bm{f}$ to $\bm{\epsilon\mathcal{L}}$ (with IFF applied) for all masses
  • Show effect of rotation
  • Show effect of payload mass
  • Compare with undamped plants
%% Identify the IFF plant dynamics using the Simscape model

% Initialize each Simscape model elements
initializeGround();
initializeGranite();
initializeTy();
initializeRy();
initializeRz();
initializeMicroHexapod();
initializeSimplifiedNanoHexapod();
initializeSample('type', 'cylindrical', 'm', 1);

% Initial Simscape Configuration
initializeSimscapeConfiguration('gravity', false);
initializeDisturbances('enable', false);
initializeLoggingConfiguration('log', 'none');
initializeController('type', 'open-loop');
initializeReferences();

% Input/Output definition
clear io; io_i = 1;
io(io_i) = linio([mdl, '/Controller'],     1, 'input');                  io_i = io_i + 1; % Actuator Inputs [N]
io(io_i) = linio([mdl, '/Tracking Error'], 1, 'openoutput', [], 'EdL');  io_i = io_i + 1; % Strut errors [m]
%% Identify HAC Plant without using IFF
initializeSample('type', 'cylindrical', 'm', 1);
G_m1 = linearize(mdl, io);
G_m1.InputName  = {'f1', 'f2', 'f3', 'f4', 'f5', 'f6'};
G_m1.OutputName = {'l1', 'l2', 'l3', 'l4', 'l5', 'l6'};

initializeSample('type', 'cylindrical', 'm', 25);
G_m25 = linearize(mdl, io);
G_m25.InputName  = {'f1', 'f2', 'f3', 'f4', 'f5', 'f6'};
G_m25.OutputName = {'l1', 'l2', 'l3', 'l4', 'l5', 'l6'};

initializeSample('type', 'cylindrical', 'm', 50);
G_m50 = linearize(mdl, io);
G_m50.InputName  = {'f1', 'f2', 'f3', 'f4', 'f5', 'f6'};
G_m50.OutputName = {'l1', 'l2', 'l3', 'l4', 'l5', 'l6'};
%% Effect of Rotation
initializeSample('type', 'cylindrical', 'm', 1);
initializeReferences(...
    'Rz_type', 'rotating', ...
    'Rz_period', 1); % 360 deg/s

G_m1_Rz = linearize(mdl, io, 0.1);
G_m1_Rz.InputName  = {'f1',  'f2',  'f3',  'f4',  'f5',  'f6'};
G_m1_Rz.OutputName = {'l1', 'l2', 'l3', 'l4', 'l5', 'l6'};

Effect of rotation:

bodeFig({G_m1(1,1), G_m1_Rz(1,1)}, struct('phase', true));

Effect of IFF:

%% Identify HAC Plant without using IFF
initializeReferences(); % No Spindle Rotation
initializeController('type', 'iff'); % Implemented IFF controller
load('nass_K_iff.mat', 'Kiff'); % Load designed IFF controller

initializeSample('type', 'cylindrical', 'm', 1);
G_hac_m1 = linearize(mdl, io);
G_hac_m1.InputName  = {'f1', 'f2', 'f3', 'f4', 'f5', 'f6'};
G_hac_m1.OutputName = {'l1', 'l2', 'l3', 'l4', 'l5', 'l6'};

initializeSample('type', 'cylindrical', 'm', 25);
G_hac_m25 = linearize(mdl, io);
G_hac_m25.InputName  = {'f1', 'f2', 'f3', 'f4', 'f5', 'f6'};
G_hac_m25.OutputName = {'l1', 'l2', 'l3', 'l4', 'l5', 'l6'};

initializeSample('type', 'cylindrical', 'm', 50);
G_hac_m50 = linearize(mdl, io);
G_hac_m50.InputName  = {'f1', 'f2', 'f3', 'f4', 'f5', 'f6'};
G_hac_m50.OutputName = {'l1', 'l2', 'l3', 'l4', 'l5', 'l6'};
%% Check stability
isstable(G_hac_m1) && isstable(G_hac_m25) && isstable(G_hac_m50)
bodeFig({G_m1(1,1), G_hac_m1(1,1)}, struct('phase', true));

Effect of payload mass

bodeFig({G_hac_m1(1,1), G_hac_m25(1,1), G_hac_m50(1,1)}, freqs, struct('phase', true));

Advantage of using IFF:

Controller design

  • Show design HAC with formulas and parameters
  • Show robustness with Loci for all masses

\begin{equation}\label{eq:nass_robust_hac} K_{\text{HAC}}(s) = g_0 ⋅ _brace{\frac{ω_c}{s}}_{\text{int}} ⋅ _brace{\frac{1}{\sqrt{α}}\frac{1 + \frac{s}{ω_c/\sqrt{α}}}{1 + \frac{s}{ω_c\sqrt{α}}}}_{\text{lead}} ⋅ _brace{\frac{1}{1 + \frac{s}{ω_0}}}_{\text{LPF}}, \quad ≤ft( ω_c = 2π5\,\text{rad/s},\ α = 2,\ ω_0 = 2π30\,\text{rad/s} \right)

\end{equation}

%% HAC Design
% Wanted crossover
wc = 2*pi*10; % [rad/s]

% Integrator
H_int = wc/s;

% Lead to increase phase margin
a  = 4;  % Amount of phase lead / width of the phase lead / high frequency gain
H_lead = 1/sqrt(a)*(1 + s/(wc/sqrt(a)))/(1 + s/(wc*sqrt(a)));

% Low Pass filter to increase robustness
H_lpf = 1/(1 + s/2/pi/100);

% Gain to have unitary crossover at 5Hz
H_gain = 1./abs(evalfr(G_hac_m25(1,1), 1j*wc));

% Decentralized HAC
Khac = -H_gain  * ... % Gain
        H_int   * ... % Integrator
        H_lead  * ... % Lead
        H_lpf   * ... % Low Pass filter
        eye(6);       % 6x6 Diagonal
% The designed HAC controller is saved
save('./mat/nass_K_hac.mat', 'Khac');

"Decentralized" Loop Gain:

Characteristic Loci for three masses:

Sensitivity to disturbances

  • Compute transfer functions from spindle vertical error to sample vertical error with HAC-IFF Compare without the NASS, and with just IFF
  • Same for horizontal

Tomography experiment

  • With HAC-IFF, perform tomography experiment, and compare with open-loop
  • Take into account disturbances, metrology sensor noise. Maybe say here that we don't take in account other noise sources as they will be optimized latter (detail design phase)
  • Tomography + lateral scans (same as what was done in open loop here)
  • Validation of concept
% 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]

open(mdl);
set_param(mdl, 'StopTime', '2');

initializeGround();
initializeGranite();
initializeTy();
initializeRy();
initializeRz();
initializeMicroHexapod('AP', P_micro_hexapod);
initializeSample('type', 'cylindrical', 'm', 1);

initializeSimscapeConfiguration('gravity', false);
initializeLoggingConfiguration('log', 'all', 'Ts', 1e-3);

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

% Open-Loop Simulation without Nano-Hexapod
initializeSimplifiedNanoHexapod('type', 'none');
initializeController('type', 'open-loop');
sim(mdl);
exp_tomo_ol_m1 = simout;
% Closed-Loop Simulation with NASS
initializeSimplifiedNanoHexapod();
initializeController('type', 'hac-iff');
load('nass_K_iff.mat', 'Kiff');
load('nass_K_hac.mat', 'Khac');
sim(mdl);
exp_tomo_cl_m1 = simout;
% Closed-Loop Simulation with NASS - Other masses
initializeSample('type', 'cylindrical', 'm', 25);
sim(mdl);
exp_tomo_cl_m25 = simout;
initializeSample('type', 'cylindrical', 'm', 50);
sim(mdl);
exp_tomo_cl_m50 = simout;

/tdehaeze/phd-simscape-nass/media/commit/b9a5308fa3902167e7d305a76026e1e209d5e91a/figs/nass_tomography_hac_iff_m1.png

/tdehaeze/phd-simscape-nass/media/commit/b9a5308fa3902167e7d305a76026e1e209d5e91a/figs/nass_tomography_hac_iff_m25.png

/tdehaeze/phd-simscape-nass/media/commit/b9a5308fa3902167e7d305a76026e1e209d5e91a/figs/nass_tomography_hac_iff_m50.png

Conclusion

<<sec:nass_conclusion>>

Bibliography   ignore