phd-nass-uniaxial-model/nass-uniaxial-model.org

6188 lines
298 KiB
Org Mode

#+TITLE: Nano Active Stabilization System - Uniaxial Model
:DRAWER:
#+LANGUAGE: en
#+EMAIL: dehaeze.thomas@gmail.com
#+AUTHOR: Dehaeze Thomas
#+HTML_LINK_HOME: ../index.html
#+HTML_LINK_UP: ../index.html
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="https://research.tdehaeze.xyz/css/style.css"/>
#+HTML_HEAD: <script type="text/javascript" src="https://research.tdehaeze.xyz/js/script.js"></script>
#+BIND: org-latex-image-default-option "scale=1"
#+BIND: org-latex-image-default-width ""
#+LATEX_CLASS: scrreprt
#+LATEX_CLASS_OPTIONS: [a4paper, 10pt, DIV=12, parskip=full, bibliography=totoc]
#+LATEX_HEADER: \input{preamble.tex}
#+LATEX_HEADER_EXTRA: \input{preamble_extra.tex}
#+LATEX_HEADER_EXTRA: \bibliography{nass-uniaxial-model.bib}
#+BIND: org-latex-bib-compiler "biber"
#+PROPERTY: header-args:matlab :session *MATLAB*
#+PROPERTY: header-args:matlab+ :comments org
#+PROPERTY: header-args:matlab+ :exports none
#+PROPERTY: header-args:matlab+ :results none
#+PROPERTY: header-args:matlab+ :eval no-export
#+PROPERTY: header-args:matlab+ :noweb yes
#+PROPERTY: header-args:matlab+ :mkdirp yes
#+PROPERTY: header-args:matlab+ :output-dir figs
#+PROPERTY: header-args:matlab+ :tangle no
#+PROPERTY: header-args:latex :headers '("\\usepackage{tikz}" "\\usepackage{import}" "\\import{$HOME/Cloud/tikz/org/}{config.tex}")
#+PROPERTY: header-args:latex+ :imagemagick t :fit yes
#+PROPERTY: header-args:latex+ :iminoptions -scale 100% -density 150
#+PROPERTY: header-args:latex+ :imoutoptions -quality 100
#+PROPERTY: header-args:latex+ :results file raw replace
#+PROPERTY: header-args:latex+ :buffer no
#+PROPERTY: header-args:latex+ :tangle no
#+PROPERTY: header-args:latex+ :eval no-export
#+PROPERTY: header-args:latex+ :exports results
#+PROPERTY: header-args:latex+ :mkdirp yes
#+PROPERTY: header-args:latex+ :output-dir figs
#+PROPERTY: header-args:latex+ :post pdf2svg(file=*this*, ext="png")
:END:
#+begin_export html
<hr>
<p>This report is also available as a <a href="./nass-uniaxial-model.pdf">pdf</a>.</p>
<hr>
#+end_export
#+latex: \clearpage
* Build :noexport:
#+NAME: startblock
#+BEGIN_SRC emacs-lisp :results none :tangle no
(add-to-list 'org-latex-classes
'("scrreprt"
"\\documentclass{scrreprt}"
("\\chapter{%s}" . "\\chapter*{%s}")
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
))
;; Remove automatic org heading labels
(defun my-latex-filter-removeOrgAutoLabels (text backend info)
"Org-mode automatically generates labels for headings despite explicit use of `#+LABEL`. This filter forcibly removes all automatically generated org-labels in headings."
(when (org-export-derived-backend-p backend 'latex)
(replace-regexp-in-string "\\\\label{sec:org[a-f0-9]+}\n" "" text)))
(add-to-list 'org-export-filter-headline-functions
'my-latex-filter-removeOrgAutoLabels)
;; Use no package by default
(setq org-latex-packages-alist nil)
(setq org-latex-default-packages-alist nil)
;; Do not include the subtitle inside the title
(setq org-latex-subtitle-separate t)
(setq org-latex-subtitle-format "\\subtitle{%s}")
(setq org-export-before-parsing-hook '(org-ref-glossary-before-parsing
org-ref-acronyms-before-parsing))
#+END_SRC
* Notes :noexport:
Prefix is =uniaxial=
* Glossary and Acronyms - Tables :ignore:
#+name: glossary
| label | name | description |
|-------+-------------------------+----------------------------------------------------------|
| ms | \ensuremath{m_s} | Mass of the sample |
| mn | \ensuremath{m_n} | Mass of the nano-hexapod |
| mh | \ensuremath{m_h} | Mass of the micro-hexapod |
| mt | \ensuremath{m_t} | Mass of the micro-station stages |
| mg | \ensuremath{m_g} | Mass of the granite |
| xf | \ensuremath{x_f} | Floor motion |
| ft | \ensuremath{f_t} | Disturbance force of the micro-station |
| fs | \ensuremath{f_s} | Direct forces applied on the sample |
| d | \ensuremath{d} | Measured motion between the nano-hexapod and the granite |
| fn | \ensuremath{f_n} | Force sensor on the nano-hexapod |
| psdx | \ensuremath{\Phi_{x}} | Power spectral density of signal $x$ |
| asdx | \ensuremath{\Gamma_{x}} | Amplitude spectral density of signal $x$ |
| cpsx | \ensuremath{\Phi_{x}} | Cumulative Power Spectrum of signal $x$ |
| casx | \ensuremath{\Gamma_{x}} | Cumulative Amplitude Spectrum of signal $x$ |
#+name: acronyms
| key | abbreviation | full form |
|--------+--------------+------------------------------------------------|
| haclac | HAC-LAC | High Authority Control - Low Authority Control |
| hac | HAC | High Authority Control |
| lac | LAC | Low Authority Control |
| nass | NASS | Nano Active Stabilization System |
| asd | ASD | Amplitude Spectral Density |
| psd | PSD | Power Spectral Density |
| cps | CPS | Cumulative Power Spectrum |
| cas | CAS | Cumulative Amplitude Spectrum |
| frf | FRF | Frequency Response Function |
* Introduction :ignore:
In this report, a uniaxial model of the acrfull:nass is developed and used to have a first idea of the challenges involved in this complex system.
Note that in this study, only the vertical direction is considered (which is the most stiff), but other directions were considered as well and yields to similar conclusions.
The model is schematically shown in Figure ref:fig:uniaxial_overview_model_sections where the colors are representing the studied parts in different sections.
In order to have a relevant model, the micro-station dynamics is first identified and its model is tuned to match the measurements (Section ref:sec:micro_station_model).
Then, a model of the nano-hexapod is added on top of the micro-station.
With added sample and sensors, this gives a uniaxial dynamical model of the acrshort:nass that will be used for further analysis (Section ref:sec:nano_station_model).
The disturbances affecting the position stability are identified experimentally (Section ref:sec:uniaxial_disturbances) and included in the model for dynamical noise budgeting (Section ref:sec:uniaxial_noise_budgeting).
In all the following analysis, three nano-hexapod stiffnesses are considered to better understand the trade-offs and to find the most adequate nano-hexapod design.
Three sample masses are also considered to verify the robustness of the applied control strategies with respect to a change of sample.
In order to improve the position stability of the sample, an acrfull:haclac strategy is applied.
It consists of first actively damp the plant (the acrshort:lac part), and then applying a position control on the damped plant (the acrshort:hac part).
Three active damping techniques are studied (Section ref:sec:uniaxial_active_damping) which are used to both reduce the effect of disturbances as well as render the system easier to control afterwards.
Once the system is well damped, a feedback position controller is applied, and the obtained performance are compared (Section ref:sec:uniaxial_position_control).
Two key effects that may limit that positioning performances are then considered: the limited micro-station compliance (Section ref:sec:uniaxial_support_compliance) and the presence of dynamics between the nano-hexapod and the sample's point of interest (Section ref:sec:uniaxial_payload_dynamics).
Conclusion remarks are given in Section ref:sec:uniaxial_conclusion.
#+begin_src latex :file uniaxial_overview_model_sections.pdf
\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.4} % Width of the dashed line for the displacement
\def\disph{0.3} % Height of the arrow for the displacements
\def\bracs{0.05} % Brace spacing vertically
\def\brach{-12pt} % Brace shift horizontaly
\def\fsensh{0.2} % Height of the force sensor
\def\velsize{0.2} % Size of the velocity sensor
% ====================
% IFF
% ====================
% Ground
% ====================
\draw[draw=colorblue] (-0.5*\massw, 0) -- (0.5*\massw, 0);
\draw[dashed,draw=coloryellow] (0.5*\massw, 0) -- ++(\dispw, 0);
\draw[->, color=coloryellow] (0.5*\massw+0.5*\dispw, 0) -- ++(0, 2*\disph) node[right, color=coloryellow]{$x_{f}$};
% ====================
% ====================
% Granite
\begin{scope}[shift={(0, 0)}]
% Mass
\draw[draw=colorblue,fill=colorblue!10!white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5,color=colorblue]{$m_{g}$};
% Spring, Damper, and Actuator
\draw[spring,draw=colorblue] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1, color=colorblue]{$k_{g}$};
\draw[damper={colorblue}{}{}] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2, color=colorblue]{$c_{g}$};
% 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]{Granite};
% Displacements
\draw[dashed, draw=colorpurple] (0.5*\massw, \spaceh+\massh) -- ++(7.5*\dispw, 0) coordinate(xg);
\end{scope}
% ====================
% ====================
% Stages
\begin{scope}[shift={(0, \spaceh+\massh)}]
% Mass
\draw[draw=colorblue,fill=colorblue!10!white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5,color=colorblue]{$m_{t}$};
% Spring, Damper, and Actuator
\draw[spring,draw=colorblue] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1,color=colorblue]{$k_{t}$};
\draw[damper={colorblue}{}{}] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2,color=colorblue]{$c_{t}$};
% Disturbance
\draw[actuator={0.45}{0.2}{coloryellow}] ( 0.3*\massw, 0) -- (0.3*\massw, \spaceh) node[midway, right=0.1, color=coloryellow](ft){$f_{t}$};
% 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]{$T_y$/$R_y$/$R_z$};
\end{scope}
% ====================
% ====================
% Hexapod
\begin{scope}[shift={(0, 2*(\spaceh+\massh))}]
% Mass
\draw[draw=colorblue,fill=colorblue!10!white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5,color=colorblue]{$m_h$};
% Spring, Damper, and Actuator
\draw[spring,draw=colorblue] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1,color=colorblue]{$k_h$};
\draw[damper={colorblue}{}{}] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2,color=colorblue]{$c_h$};
% 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]{$\mu\text{-hexa}$};
\end{scope}
% ====================
% ====================
% NASS
\begin{scope}[shift={(0, 3*(\spaceh+\massh))}]
% Mass
\draw[draw=colorred,fill=colorred!10!white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5,color=colorred]{$m_{n}$};
% Force Sensor
\node[forcesensor={\massw}{\fsensh}{colorgreen}] (fsensn) at (0, \spaceh-\fsensh){};
\node[right, color=colorgreen] (fn) at (fsensn.east) {$f_n$};
% Spring, Damper, and Actuator
\draw[spring,draw=colorred] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh-\fsensh) node[midway, left=0.1,color=colorred]{$k_{n}$};
\draw[damper={colorred}{}{}] (0, 0) -- ( 0, \spaceh-\fsensh) node[midway, left=0.2,color=colorred]{$c_{n}$};
\draw[actuator={0.4}{0.2}{colorred}] ( 0.3*\massw, 0) -- (0.3*\massw, \spaceh-\fsensh) node[midway, right=0.1,color=colorred](f){$f$};
% 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]{$\nu\text{-hexa}$};
% Displacements
\draw[dashed,draw=colorpurple] (0.5*\massw, \spaceh+\massh) -- ++(7.5*\dispw, 0) coordinate(xnpos);
\end{scope}
% ====================
% ====================
% sample
\begin{scope}[shift={(0, 4*(\spaceh+\massh))}]
% Mass
\draw[draw=colorcyan,fill=colorcyan!10!white] (-0.3*\massw, \spaceh) rectangle (0.3*\massw, \spaceh+\massh) node[pos=0.5, color=colorcyan]{$m_{s}$};
% Spring, Damper, and Actuator
\draw[spring,draw=colorcyan] (-0.2*\massw, 0) -- (-0.2*\massw, \spaceh) node[midway, left=0.1, color=colorcyan]{$k_{s}$};
\draw[damper={colorcyan}{}{}] ( 0.2*\massw, 0) -- ( 0.2*\massw, \spaceh) node[midway, left=0.2, color=colorcyan]{$c_{s}$};
% 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]{Sample};
% External Force
\draw[->, color=coloryellow] (0, \spaceh+\massh) node[]{$\bullet$} -- ++(0, 0.5*\massh) node[right, color=coloryellow]{$f_s$};
\end{scope}
% ====================
% Measured displacement
\draw[<->, dashed, draw=colorpurple] ($(xg)+(-0.1, 0)$) -- node[left, color=colorpurple](d){$d$} ($(xnpos)+(-0.1, 0)$);
% ====================
% IFF Control
\node[block={2em}{2em}, right=1.0 of fn, color=colorgreen, fill=colorgreen!10!white] (iff) {$K_{\textsc{IFF}}$};
\node[addb, draw=colorgreen, fill=colorgreen!10!white, right=0.5 of f.east] (ctrladd) {};
\node[block={2em}{2em}, color=colorpurple, fill=colorpurple!10!white] (Khac) at (ctrladd|-d) {$K_{\textsc{HAC}}$};
\draw[->, draw=colorgreen] (fn.east) -- (iff.west);
\draw[->, draw=colorgreen] (iff.south) |- (ctrladd.east);
\draw[->, draw=colorgreen] (ctrladd.west) -- (f.east);
\draw[->, draw=colorpurple] (d.west) -- (Khac.east);
\draw[->, draw=colorpurple] (Khac.north) -- (ctrladd.south) node[below right, color=colorpurple]{$f^{\prime}$};
% ====================
\end{tikzpicture}
#+end_src
#+name: fig:uniaxial_overview_model_sections
#+caption: Uniaxial Micro-Station model in blue (Section ref:sec:micro_station_model), Nano-Hexapod models in red (Section ref:sec:nano_station_model), Disturbances in yellow (Section ref:sec:uniaxial_disturbances), Active Damping in green (Section ref:sec:uniaxial_active_damping), Position control in purple (Section ref:sec:uniaxial_position_control) and Sample dynamics in cyan (Section ref:sec:uniaxial_payload_dynamics)
#+RESULTS:
[[file:figs/uniaxial_overview_model_sections.png]]
* Micro Station Model
:PROPERTIES:
:HEADER-ARGS:matlab+: :tangle matlab/uniaxial_1_micro_station_model.m
:END:
<<sec:micro_station_model>>
** Introduction :ignore:
In this section, a uni-axial model of the micro-station is tuned in order to match measurements made on the micro-station.
The measurement setup is shown in Figure ref:fig:uniaxial_ustation_first_meas_dynamics where several geophones[fn:1] are fixed to the micro-station and an instrumented hammer is used to inject forces on different stages of the micro-station.
From the measured frequency response functions (FRF), the model can be tuned to approximate the uniaxial dynamics of the micro-station.
#+name: fig:uniaxial_ustation_first_meas_dynamics
#+caption: Experimental setup used for the first dynamical measurements on the Micro-Station. Geophones are fixed to different stages of the micro-station.
#+attr_latex: :width \linewidth
[[file:figs/uniaxial_ustation_first_meas_dynamics.jpg]]
** Matlab Init :noexport:ignore:
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
<<matlab-dir>>
#+end_src
#+begin_src matlab :exports none :results silent :noweb yes
<<matlab-init>>
#+end_src
#+begin_src matlab :tangle no :noweb yes
<<m-init-path>>
#+end_src
#+begin_src matlab :eval no :noweb yes
<<m-init-path-tangle>>
#+end_src
#+begin_src matlab :noweb yes
<<m-init-other>>
#+end_src
#+begin_src matlab
%% Uniaxial Simscape model name
mdl = 'nass_uniaxial_model';
#+end_src
#+begin_src matlab
%% Frequency Vector [Hz]
freqs = logspace(0, 3, 1000);
#+end_src
** Measured dynamics
The measurement setup is schematically shown in Figure ref:fig:uniaxial_ustation_meas_dynamics_schematic where two vertical hammer hits are performed, one on the Granite (force $F_{g}$), and one on the micro-hexapod's top platform (force $F_{h}$).
The vertical inertial motion of the granite $x_{g}$ and the micro-hexapod's top platform $x_{h}$ are measured using geophones.
Three frequency response functions are computed: one from $F_{h}$ to $x_{h}$ (i.e. the compliance of the micro-station), one from $F_{g}$ to $x_{h}$ (or from $F_{h}$ to $x_{g}$) and one from $F_{g}$ to $x_{g}$.
Due to the bad coherence at low frequency, these frequency response functions will only be shown between 20 and 200Hz (solid lines in Figure ref:fig:uniaxial_comp_frf_meas_model).
#+begin_src latex :file uniaxial_ustation_meas_dynamics_schematic.pdf :results file raw silent
\begin{tikzpicture}
% Parameters
\def\blockw{6.0cm}
\def\blockh{1.2cm}
\def\tiltdeg{0}
\coordinate[] (rotationpoint) at (0, 4.5*\blockh);
\begin{scope}[rotate around={\tiltdeg:(rotationpoint)}]
% Tilt
\path[] ([shift=(-120:4*\blockh)]rotationpoint) coordinate(beginarc) arc (-120:-110:4*\blockh) %
-- ([shift=(-70:4*\blockh)]rotationpoint) arc (-70:-60:4*\blockh)%
|- ++(-0.15*\blockw, 0.6*\blockh) coordinate (spindlene)%
|- ($(beginarc) + (0.15*\blockw, 0.2*\blockh)$) coordinate (spindlesw) -- ++(0, 0.4*\blockh) coordinate(tiltte) -| cycle;
% Spindle
\coordinate[] (spindlese) at (spindlesw-|spindlene);
\draw[fill=black!30] ($(spindlese)+(-0.1,0.1)+(-0.1*\blockw, 0)$) -| ($(spindlene)+(-0.1, 0)$) -| coordinate[pos=0.25](spindletop) ($(spindlesw)+(0.1,0.1)$) -| ++(0.1*\blockw, -\blockh) -| coordinate[pos=0.25](spindlebot) cycle;
% \draw[dashed, color=black!60] ($(spindletop)+(0, 0.2)$) -- ($(spindlebot)+(0,-0.2)$);
% Tilt
\draw[fill=black!60] ([shift=(-120:4*\blockh)]rotationpoint) coordinate(beginarc) arc (-120:-110:4*\blockh) %
-- ([shift=(-70:4*\blockh)]rotationpoint) arc (-70:-60:4*\blockh)%
|- coordinate (tiltne) ++(-0.15*\blockw, 0.6*\blockh) coordinate (spindlene)%
|- ($(beginarc) + (0.15*\blockw, 0.2*\blockh)$) coordinate (spindlesw) -- ++(0, 0.4*\blockh) -| cycle;
% Micro-Hexapod
\begin{scope}[shift={(spindletop)}]
% Parameters definitions
\def\baseh{0.22*\blockh} % Height of the base
\def\naceh{0.18*\blockh} % Height of the nacelle
\def\baser{0.22*\blockw} % Radius of the base
\def\nacer{0.18*\blockw} % Radius of the nacelle
\def\armr{0.2*\blockh} % Radius of the arms
\def\basearmborder{0.2}
\def\nacearmborder{0.2}
\def\xnace{0} \def\ynace{\blockh-\naceh} \def\anace{0}
\def\xbase{0} \def\ybase{0} \def\abase{0}
% Hexapod1
\begin{scope}[shift={(\xbase, \ybase)}, rotate=\abase]
% Base
\draw[fill=white] (-\baser, 0) coordinate[](uhexabot) rectangle (\baser, \baseh);
\coordinate[] (armbasel) at (-\baser+\basearmborder+\armr, \baseh);
\coordinate[] (armbasec) at (0, \baseh);
\coordinate[] (armbaser) at (\baser-\basearmborder-\armr, \baseh);
\begin{scope}[shift={(\xnace, \ynace)}, rotate=\anace]
\draw[fill=white] (-\nacer, 0) rectangle (\nacer, \naceh);
\coordinate[] (uhexatop) at (0, \naceh);
\coordinate[] (armnacel) at (-\nacer+\nacearmborder+\armr, 0);
\coordinate[] (armnacec) at (0, 0);
\coordinate[] (armnacer) at (\nacer-\nacearmborder-\armr, 0);
\end{scope}
\draw[] (armbasec) -- (armnacer);
\draw[] (armbasec) -- (armnacel);
\draw[] (armbasel) -- coordinate(mhexaw) (armnacel);
\draw[] (armbasel) -- (armnacec);
\draw[] (armbaser) -- (armnacec);
\draw[] (armbaser) -- coordinate(mhexae) (armnacer);
\end{scope}
\end{scope}
\begin{scope}[shift={(uhexatop)}] % Geophone - Hexapod
\draw[draw=colorgreen, fill=colorgreen!10!white] (-0.3, 0) rectangle node[midway, color=colorgreen, rotate=90]{\tiny geophone} (0.3, 1.2);
\draw[rounded corners=0.1, draw=colorgreen, fill=colorgreen!10!white] (-0.1, 1.2) -- ++(0, 0.1) -- ++(0.1, 0.1) -- ++(0.1, -0.1) -- ++(0, -0.1) --cycle;
\node[fill,shape=circle,minimum size=3pt,inner sep=0pt, color=colorgreen] at (0, 1.4){};
\draw[out=90, in=180, draw=colorgreen] (0, 1.4) to ++(0.4, 0.2) node[right, color=colorgreen]{$x_{h}$};
\end{scope}
\begin{scope}[shift={(uhexatop)}] % Instrumented Hammer - Hexapod
\begin{scope}[shift={(-1.5, 0)}]
\draw[fill=white, rounded corners=0.2, draw=colorblue, fill=colorblue!10!white] (-0.5, 0.42) rectangle (0.5, 0.58);
\draw[fill=white, rounded corners=0.2, draw=colorblue, fill=colorblue!10!white] (0.5, 0.15) rectangle (0.7, 0.8);
\draw[fill=white, rounded corners=0.2, color=colorblue] (0.55, 0.15) rectangle (0.65, 0);
\draw[out=180, in=0, draw=colorblue] (-0.5, 0.5) to ++(-0.6, -0.1) node[above, color=colorblue]{$F_{h}$};
\node[fill,shape=circle,minimum size=3pt,inner sep=0pt, color=colorblue] at (-0.5, 0.5){};
\end{scope}
\end{scope}
\end{scope}
\begin{scope}[shift={(0, -0.3*\blockh)}]
% Translation Stage - fixed part
\draw[fill=black!40] (-0.5*\blockw, 0) coordinate[](tyb) rectangle (0.5*\blockw, 0.15*\blockh);
\coordinate[] (measposbot) at (0.5*\blockw, 0);
% Translation Stage - mobile part
\draw[fill=black!10, fill opacity=0.5] (-0.5*\blockw, 0.2*\blockh) -- (-0.5*\blockw, 1.5*\blockh) coordinate[](tyt) -- (0.5*\blockw, 1.5*\blockh) -- (0.5*\blockw, 0.2*\blockh) -- (0.35*\blockw, 0.2*\blockh) -- (0.35*\blockw, 0.8*\blockh) -- (-0.35*\blockw, 0.8*\blockh) -- (-0.35*\blockw, 0.2*\blockh) -- cycle;
% Translation Guidance
\draw[dashed, color=black!60] ($(-0.5*\blockw, 0)+( 0.075*\blockw,0.5*\blockh)$) circle (0.2*\blockh);
\draw[dashed, color=black!60] ($( 0.5*\blockw, 0)+(-0.075*\blockw,0.5*\blockh)$) circle (0.2*\blockh);
% \draw[fill, color=black] ($( 0.5*\blockw, 0)+(-0.075*\blockw,0.5*\blockh)$) circle (0.04);
% \node[draw, circle, inner sep=0pt, minimum size=0.3cm, label=above:$T_y$] at ($( 0.5*\blockw, 0)+(-0.075*\blockw,0.5*\blockh)$){};
% Tilt Guidance
\draw[dashed, color=black!60] ([shift=(-107:4.1*\blockh)]rotationpoint) arc (-107:-120:4.1*\blockh);
\draw[dashed, color=black!60] ([shift=( -73:4.1*\blockh)]rotationpoint) arc (-73:-60:4.1*\blockh);
\begin{scope}[shift={(4.0, 0)}] % Geophone - Granite
\draw[draw=colorgreen, fill=colorgreen!10!white] (-0.3, 0) rectangle node[midway, color=colorgreen, rotate=90]{\tiny geophone} (0.3, 1.2);
\draw[rounded corners=0.1, draw=colorgreen, fill=colorgreen!10!white] (-0.1, 1.2) -- ++(0, 0.1) -- ++(0.1, 0.1) -- ++(0.1, -0.1) -- ++(0, -0.1) --cycle;
\node[fill,shape=circle,minimum size=3pt,inner sep=0pt, color=colorgreen] at (0, 1.4){};
\draw[out=90, in=180, draw=colorgreen] (0, 1.4) to ++(0.4, 0.2) node[right, color=colorgreen]{$x_{g}$};
\end{scope}
\begin{scope}[shift={(-4.0, 0)}] % Instrumented Hammer - Granite
\draw[fill=white, rounded corners=0.2, draw=colorblue, fill=colorblue!10!white] (-0.5, 0.42) rectangle (0.5, 0.58);
\draw[fill=white, rounded corners=0.2, draw=colorblue, fill=colorblue!10!white] (0.5, 0.15) rectangle (0.7, 0.8);
\draw[fill=white, rounded corners=0.2, color=colorblue] (0.55, 0.15) rectangle (0.65, 0);
\draw[out=180, in=0, draw=colorblue] (-0.5, 0.5) to ++(-0.6, -0.1) node[above, color=colorblue]{$F_{g}$};
\node[fill,shape=circle,minimum size=3pt,inner sep=0pt, color=colorblue] at (-0.5, 0.5){};
\end{scope}
\end{scope}
% Granite
\draw[fill=black!40] (-0.8*\blockw, -0.3*\blockh) rectangle node[midway]{Granite} (0.8*\blockw, -1.5*\blockh);
% Vertical line
% \draw[dashed, color=black] (spindlebot) -- ++(0, 2*\blockh);
% \node[] at ($(spindlebot)+(0, 1.1*\blockh)$) {\AxisRotator[rotate=-90]};
% \node[right, shift={(0.3,0)}] at ($(spindlebot)+(0, 1.1*\blockh)$) {$\theta_z$};
% Axis
\begin{scope}[shift={(-0.6*\blockw, 2.5*\blockh)}]
\def\axissize{0.8cm}
\draw[->] (0, 0) -- ++(0, \axissize) node[right]{$z$};
\draw[->] (0, 0) -- ++(-\axissize, 0) node[above]{$x$};
\draw[fill, color=black] (0, 0) circle (0.05*\axissize);
\node[draw, circle, inner sep=0pt, minimum size=0.4*\axissize, label=right:$y$] (yaxis) at (0, 0){};
\end{scope}
\end{tikzpicture}
#+end_src
#+name: fig:micro_station_uniaxial_model
#+caption: Schematic of the Micro-Station measurement setup and uniaxial model.
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_ustation_meas_dynamics_schematic}Measurement setup - Schematic}
#+attr_latex: :options {0.69\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_ustation_meas_dynamics_schematic.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_model_micro_station}Uniaxial model of the micro-station}
#+attr_latex: :options {0.29\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_model_micro_station.png]]
#+end_subfigure
#+end_figure
#+begin_src matlab
%% Load measured FRF
load('meas_microstation_frf.mat');
#+end_src
** Uniaxial Model
The uni-axial model of the micro-station is shown in Figure ref:fig:uniaxial_model_micro_station.
It consists of a mass spring damper system with 3 degrees of freedom.
One mass-spring-damper system represents the granite (with mass $m_g$, stiffness $k_g$ and damping $c_g$).
Another mass-spring-damper system represents the different micro-station stages (the $T_y$ stage, the $R_y$ stage and the $R_z$ stage) with mass $m_t$, damping $c_t$ and stiffness $k_t$.
Finally, a third mass-spring-damper system represents the micro-hexapod with mass $m_h$, damping $c_h$ and stiffness $k_h$.
The masses of the different stages are estimated from the 3D model, while the stiffnesses are from the data-sheet of the manufacturers.
The damping coefficients are tuned to match the identified damping from the measurements.
The obtained parameters are summarized in Table ref:tab:uniaxial_ustation_parameters.
#+name: tab:uniaxial_ustation_parameters
#+caption: Physical parameters used for the micro-station uniaxial model
#+attr_latex: :environment tabularx :width 0.9\linewidth :align lXXX
#+attr_latex: :center t :booktabs t
| *Stage* | *Mass* | *Stiffness* | *Damping* |
|---------------------+-------------------------+----------------------+-----------------------------|
| Micro-Hexapod | $m_h = 15\,\text{kg}$ | $k_h = 61\,N/\mu m$ | $c_h = 3\,\frac{kN}{m/s}$ |
| $T_y$, $R_y$, $R_z$ | $m_t = 1200\,\text{kg}$ | $k_t = 520\,N/\mu m$ | $c_t = 80\,\frac{kN}{m/s}$ |
| Granite | $m_g = 2500\,\text{kg}$ | $k_g = 950\,N/\mu m$ | $c_g = 250\,\frac{kN}{m/s}$ |
Two disturbances are considered (shows in red): the Floor motion $x_f$ and the Stage vibrations represented by $f_t$.
The hammer impacts $F_{h}, F_{g}$ are shown in blue while the measured inertial motion $x_{h}, x_{g}$ are shown in black.
#+begin_src latex :file uniaxial_model_micro_station.pdf :results file raw silent
\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.4} % Width of the dashed line for the displacement
\def\disph{0.4} % Height of the arrow for the displacements
\def\bracs{0.05} % Brace spacing vertically
\def\brach{-12pt} % Brace shift horizontaly
\def\fsensh{0.2} % Height of the force sensor
\def\velsize{0.2} % Size of the velocity sensor
% ====================
% ====================
% Floor
% ====================
\draw (-0.5*\massw, 0) -- (0.5*\massw, 0);
\draw[dashed] (0.5*\massw, 0) -- ++(\dispw, 0);
\draw[->, draw=colorred] (0.5*\massw+0.5*\dispw, 0) -- ++(0, \disph) node[right, color=colorred]{$x_{f}$};
% ====================
% ====================
% Granite
\begin{scope}[shift={(0, 0)}]
% Mass
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m_{g}$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k_{g}$};
\draw[damper] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2]{$c_{g}$};
% 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]{Granite};
% Displacement
\draw[dashed] (0.5*\massw, \spaceh+\massh) -- ++(\dispw, 0);
\draw[->] (0.5*\massw+0.5*\dispw, \spaceh+\massh) -- ++(0, \disph) node[right]{$x_{g}$};
\end{scope}
% ====================
% ====================
% Stages
\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_{t}$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k_{t}$};
\draw[damper] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2]{$c_{t}$};
% Disturbance
\draw[actuator={0.45}{0.2}{colorred}] ( 0.3*\massw, 0) -- (0.3*\massw, \spaceh) node[midway, right=0.1, color=colorred](ft){$f_t$};
% 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]{$T_y$/$R_y$/$R_z$};
% External Force
\draw[->, color=colorblue] (0, 0)node[branch] -- ++(0, 1.5*\dispw) node[below right]{$F_g$};
% % Displacement
% \draw[dashed] (0.5*\massw, \spaceh+\massh) -- ++(\dispw, 0);
% \draw[->] (0.5*\massw+0.5*\dispw, \spaceh+\massh) -- ++(0, \disph) node[right]{$x_{t}$};
\end{scope}
% ====================
% ====================
% Hexapod
\begin{scope}[shift={(0, 2*(\spaceh+\massh))}]
% Mass
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m_{h}$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k_{h}$};
\draw[damper] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2]{$c_{h}$};
% 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]{$\mu\text{Hexa}$};
% Displacement
\draw[dashed] (0.5*\massw, \spaceh+\massh) -- ++(\dispw, 0);
\draw[->] (0.5*\massw+0.5*\dispw, \spaceh+\massh) -- ++(0, \disph) node[right]{$x_{h}$};
% External Force
\draw[->, color=colorblue] (0, \spaceh+\massh)node[branch] -- ++(0, 1.5*\dispw) node[below right]{$F_h$};
\end{scope}
% ====================
\end{tikzpicture}
#+end_src
#+BEGIN_SRC matlab
%% Parameters - Mass
mh = 15; % Micro Hexapod [kg]
mt = 1200; % Ty + Ry + Rz [kg]
mg = 2500; % Granite [kg]
#+END_SRC
#+BEGIN_SRC matlab
%% Parameters - Stiffnesses
kh = 6.11e+07; % [N/m]
kt = 5.19e+08; % [N/m]
kg = 9.50e+08; % [N/m]
#+END_SRC
#+BEGIN_SRC matlab
%% Parameters - damping
ch = 2*0.05*sqrt(kh*mh); % [N/(m/s)]
ct = 2*0.05*sqrt(kt*mt); % [N/(m/s)]
cg = 2*0.08*sqrt(kg*mg); % [N/(m/s)]
#+END_SRC
#+begin_src matlab :exports none :tangle no
%% Save model parameters
save('./matlab/mat/uniaxial_micro_station_parameters.mat', 'mh', 'mt', 'mg', 'ch', 'ct', 'cg', 'kh', 'kt', 'kg')
#+end_src
#+begin_src matlab :exports none :eval no
%% Save model parameters
save('./mat/uniaxial_micro_station_parameters.mat', 'mh', 'mt', 'mg', 'ch', 'ct', 'cg', 'kh', 'kt', 'kg')
#+end_src
#+begin_src matlab :exports none
%% Disable the Nano-Hexpod for now
model_config = struct();
model_config.nhexa = "none";
model_config.controller = "open_loop";
%% Identify the transfer function from u to taum
clear io; io_i = 1;
io(io_i) = linio([mdl, '/micro_station/Fg'], 1, 'openinput'); io_i = io_i + 1; % Hammer on Granite
io(io_i) = linio([mdl, '/micro_station/Fh'], 1, 'openinput'); io_i = io_i + 1; % Hammer on Hexapod
io(io_i) = linio([mdl, '/micro_station/xg'], 1, 'openoutput'); io_i = io_i + 1; % Absolute motion of Granite
io(io_i) = linio([mdl, '/micro_station/xh'], 1, 'openoutput'); io_i = io_i + 1; % Absolute motion of Hexapod
%% Perform the model extraction
G_id = linearize(mdl, io, 0.0);
G_id.InputName = {'Fg', 'Fh'};
G_id.OutputName = {'Dg', 'Dh'};
#+end_src
** Comparison of the model and measurements
The transfer functions from injected forces by the hammers to the measured inertial motion of the micro-hexapod and the granite are extracted from the uniaxial model and compared with the measurements in Figure ref:fig:uniaxial_comp_frf_meas_model.
Because the uniaxial model has 3 degrees of freedom, only three modes with frequencies at $70\,\text{Hz}$, $140\,\text{Hz}$ and $320\,\text{Hz}$ are modelled.
From Figure ref:fig:uniaxial_comp_frf_meas_model, it is clear that many more modes could be measured and that the uniaxial model does not perfectly match the measured frequency response functions.
However, the goal is not to have a perfect match with the measurement (this would require a much more complex model) but to have a first approximation.
More accurate models will be used later on.
#+begin_src matlab :exports none :results none
%% Comparison of the measured FRF and identified ones from the uni-axial model
figure;
tiledlayout(3, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
ax1 = nexttile([2,1]);
hold on;
plot(f(f>20), abs(frf_Fhz_to_Dhz(f>20)), '-', 'color', colors(1,:), 'DisplayName', '$x_{h,z}/F_{h,z}$');
plot(f(f>20), abs(frf_Fgz_to_Dhz(f>20)), '-', 'color', colors(2,:), 'DisplayName', '$x_{h,z}/F_{g,z}$');
plot(f(f>20), abs(frf_Fgz_to_Dgz(f>20)), '-', 'color', colors(3,:), 'DisplayName', '$x_{g,z}/F_{g,z}$');
plot(freqs, abs(squeeze(freqresp(G_id('Dh', 'Fh'), freqs, 'Hz'))), '--', 'color', colors(1,:), 'DisplayName', '$x_{h,z}/F_{h,z}$ (model)');
plot(freqs, abs(squeeze(freqresp(G_id('Dh', 'Fg'), freqs, 'Hz'))), '--', 'color', colors(2,:), 'DisplayName', '$x_{h,z}/F_{g,z}$ (model)');
plot(freqs, abs(squeeze(freqresp(G_id('Dg', 'Fg'), freqs, 'Hz'))), '--', 'color', colors(3,:), 'DisplayName', '$x_{g,z}/F_{g,z}$ (model)');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
ylim([1e-10, 2e-7]);
legend('location', 'northwest', 'FontSize', 8, 'NumColumns', 2);
ax2 = nexttile;
hold on;
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_id('Dh', 'Fh'), freqs, 'Hz')))), '--', 'color', colors(1,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_id('Dh', 'Fg'), freqs, 'Hz')))), '--', 'color', colors(2,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_id('Dg', 'Fg'), freqs, 'Hz')))), '--', 'color', colors(3,:));
plot(f(f>20), 180/pi*unwrap(angle(frf_Fhx_to_Dhx(f>20))), '-', 'color', colors(1,:));
plot(f(f>30), 180/pi*unwrap(angle(frf_Fgx_to_Dhx(f>30))), '-', 'color', colors(2,:));
plot(f(f>20), 180/pi*unwrap(angle(frf_Fgx_to_Dgx(f>20))), '-', 'color', colors(3,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
hold off;
yticks(-360:90:360);
ylim([-360, 90]);
linkaxes([ax1,ax2],'x');
xlim([1, 500]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_comp_frf_meas_model.pdf', 'width', 'wide', 'height', 'tall');
#+end_src
#+name: fig:uniaxial_comp_frf_meas_model
#+caption: Comparison of the measured FRF and identified ones from the uni-axial model
#+RESULTS:
[[file:figs/uniaxial_comp_frf_meas_model.png]]
* Nano-Hexapod Model
:PROPERTIES:
:HEADER-ARGS:matlab+: :tangle matlab/uniaxial_2_nano_hexapod_model.m
:END:
<<sec:nano_station_model>>
** Introduction :ignore:
A model of the nano-hexapod and sample is now added on top of the uni-axial model of the micro-station (Figure ref:fig:uniaxial_model_micro_station_nass).
Disturbances (shown in red) are gls:fs the direct forces applied to the sample (for instance cable forces), gls:ft representing the vibrations induced when scanning the different stages and gls:xf the floor motion.
The control signal is the force applied by the nano-hexapod $f$ and the measurement is the relative motion between the sample and the granite $d$.
The sample is here considered as a rigid body and rigidly fixed to the nano-hexapod.
The effect of having resonances between the sample's point of interest and the nano-hexapod actuator will be considered in Section ref:sec:uniaxial_payload_dynamics.
#+begin_src latex :file uniaxial_model_micro_station_nass.pdf
\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.4} % Width of the dashed line for the displacement
\def\disph{0.3} % Height of the arrow for the displacements
\def\bracs{0.05} % Brace spacing vertically
\def\brach{-12pt} % Brace shift horizontaly
\def\fsensh{0.2} % Height of the force sensor
\def\velsize{0.2} % Size of the velocity sensor
% ====================
% ====================
% Ground
% ====================
\draw (-0.5*\massw, 0) -- (0.5*\massw, 0);
\draw[dashed] (0.5*\massw, 0) -- ++(\dispw, 0);
\draw[->, color=colorred] (0.5*\massw+0.5*\dispw, 0) -- ++(0, 2*\disph) node[right, color=colorred]{$x_{f}$};
% ====================
% ====================
% Marble
\begin{scope}[shift={(0, 0)}]
% Mass
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m_{g}$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k_{g}$};
\draw[damper] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2]{$c_{g}$};
% 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]{Granite};
% Displacements
\draw[dashed] (0.5*\massw, \spaceh+\massh) -- ++(2*\dispw, 0) coordinate(xm) -- ++(\dispw, 0) coordinate(dbot);
\end{scope}
% ====================
% ====================
% Stages
\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_{t}$};
% % Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k_{t}$};
\draw[damper] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2]{$c_{t}$};
\draw[actuator={0.45}{0.2}{colorred}] ( 0.3*\massw, 0) -- (0.3*\massw, \spaceh) node[midway, right=0.1, color=colorred](ft){$f_{t}$};
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]{$T_y$/$R_y$/$R_z$};
\end{scope}
% ====================
% ====================
% Hexapod
\begin{scope}[shift={(0, 2*(\spaceh+\massh))}]
% Mass
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m_{h}$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k_{h}$};
\draw[damper] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2]{$c_{h}$};
% 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]{$\mu\text{-hexa}$};
\end{scope}
% ====================
% ====================
% NASS
\begin{scope}[shift={(0, 3*(\spaceh+\massh))}]
% Mass
\draw[fill=colorblue!10!white, draw=colorblue] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5,color=colorblue]{$m_{n}$};
% Spring, Damper, and Actuator
\draw[spring, draw=colorblue] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1, color=colorblue]{$k_{n}$};
\draw[damper={colorblue}{}{}] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2, color=colorblue]{$c_{n}$};
\draw[actuator={0.4}{0.2}{colorblue}] ( 0.3*\massw, 0) -- (0.3*\massw, \spaceh) node[midway, right=0.1, color=colorblue](F){$f$};
% Displacements
\draw[dashed] (0.5*\massw, \spaceh+\massh) -- ++(2*\dispw, 0) coordinate(xn) -- ++(\dispw, 0) coordinate(drtop);
% 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]{$\nu\text{-hexa}$};
\end{scope}
% ====================
% ====================
% sample
\begin{scope}[shift={(0, 4*(\spaceh+\massh))}]
% Mass
\draw[fill=colorgreen!10!white, draw=colorgreen] (-0.3*\massw, 0) rectangle (0.3*\massw, \massh) node[pos=0.5,color=colorgreen]{$m_{s}$};
% External Force
\draw[->, color=colorred] (0, \massh) node[]{$\bullet$} -- ++(0, 0.5*\massh) node[right, color=colorred]{$f_s$};
\end{scope}
% ====================
% ====================
% Measured Displacement
\draw[<->, dashed] (xm) -- node[midway, right]{$d$} (xn);
% ====================
\end{tikzpicture}
#+end_src
#+name: fig:uniaxial_model_micro_station_nass_with_tf
#+caption: Uniaxial model of the NASS (\subref{fig:uniaxial_model_micro_station_nass}) with the the micro-station shown in black, the nano-hexapod represented in blue and the sample represented in green. Disturbances are shown in red. Extracted transfer function from $f$ to $d$ (\subref{fig:uniaxial_plant_first_params}).
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_model_micro_station_nass}Uniaxial mass-spring-damper model of the NASS}
#+attr_latex: :options {0.39\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_model_micro_station_nass.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_plant_first_params}Bode Plot of the transfer function from actuator forces $f$ to measured displacement $d$ by the metrology}
#+attr_latex: :options {0.59\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_plant_first_params.png]]
#+end_subfigure
#+end_figure
** Matlab Init :noexport:ignore:
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
<<matlab-dir>>
#+end_src
#+begin_src matlab :exports none :results silent :noweb yes
<<matlab-init>>
#+end_src
#+begin_src matlab :tangle no :noweb yes
<<m-init-path>>
#+end_src
#+begin_src matlab :eval no :noweb yes
<<m-init-path-tangle>>
#+end_src
#+begin_src matlab :noweb yes
<<m-init-other>>
#+end_src
#+begin_src matlab
%% Uniaxial Simscape model name
mdl = 'nass_uniaxial_model';
#+end_src
#+begin_src matlab
%% Frequency Vector [Hz]
freqs = logspace(0, 3, 1000);
#+end_src
#+begin_src matlab
%% Load the micro-station parameters
load('uniaxial_micro_station_parameters.mat')
#+end_src
** Nano-Hexapod Parameters
The nano-hexapod is represented by a mass spring damper system (shown in blue in Figure ref:fig:uniaxial_model_micro_station_nass).
Its mass gls:mn is set to $15\,\text{kg}$ while its stiffness $k_n$ can vary depending on the chosen architecture/technology.
The sample is represented by a mass gls:ms that can vary from $1\,\text{kg}$ up to $50\,\text{kg}$.
As a first example, the nano-hexapod stiffness of is set at $k_n = 10\,N/\mu m$ and the sample mass is chosen at $m_s = 10\,\text{kg}$.
#+begin_src matlab
%% Nano-Hexapod Parameters
mn = 15; % [kg]
kn = 1e7; % [N/m]
cn = 2*0.01*sqrt(mn*kn); % [N/(m/s)]
%% Sample Mass
ms = 10; % [kg]
#+end_src
** Obtained Dynamic Response
The sensitivity to disturbances (i.e. the transfer functions from $x_f,f_t,f_s$ to $d$) can be extracted from the uniaxial model of Figure ref:fig:uniaxial_model_micro_station_nass and are shown in Figure ref:fig:uniaxial_sensitivity_dist_first_params.
The /plant/ (i.e. the transfer function from actuator force $f$ to measured displacement $d$) is shown in Figure ref:fig:uniaxial_plant_first_params.
For further analysis, 9 "configurations" of the uniaxial NASS model of Figure ref:fig:uniaxial_model_micro_station_nass will be considered: three nano-hexapod stiffnesses ($k_n = 0.01\,N/\mu m$, $k_n = 1\,N/\mu m$ and $k_n = 100\,N/\mu m$) combined with three sample's masses ($m_s = 1\,kg$, $m_s = 25\,kg$ and $m_s = 50\,kg$).
#+begin_src matlab :exports none
%% Use 1DoF Nano-Hexpod model
model_config = struct();
model_config.nhexa = "1dof";
model_config.controller = "open_loop";
%% Identify the transfer function from disturbances and force actuator to d
clear io; io_i = 1;
io(io_i) = linio([mdl, '/controller'], 1, 'openinput'); io_i = io_i + 1; % Force Actuator
io(io_i) = linio([mdl, '/fs'], 1, 'openinput'); io_i = io_i + 1; % Force applied on the sample
io(io_i) = linio([mdl, '/micro_station/xf'], 1, 'openinput'); io_i = io_i + 1; % Floor Motion
io(io_i) = linio([mdl, '/micro_station/ft'], 1, 'openinput'); io_i = io_i + 1; % Stage disturbances
io(io_i) = linio([mdl, '/d'] , 1, 'openoutput'); io_i = io_i + 1; % Metrology
%% Perform the model extraction
G_ol = linearize(mdl, io, 0.0);
G_ol.InputName = {'f', 'fs', 'xf', 'ft'};
G_ol.OutputName = {'d'};
#+end_src
#+begin_src matlab :exports none :results none
%% Sensitivity to disturbances - Fs
figure;
plot(freqs, abs(squeeze(freqresp(G_ol('d', 'fs'), freqs, 'Hz'))));
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude $d/f_{s}$ [m/N]'); xlabel('Frequency [Hz]');
xticks([1e0, 1e1, 1e2]);
xlim([1, 500]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file none
exportFig('figs/uniaxial_sensitivity_dist_first_params_fs.pdf', 'width', 'third', 'height', 'normal');
#+end_src
#+begin_src matlab :exports none :results none
%% Sensitivity to disturbances - Ft
figure;
plot(freqs, abs(squeeze(freqresp(G_ol('d', 'ft'), freqs, 'Hz'))));
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude $d/f_{t}$ [m/N]'); xlabel('Frequency [Hz]');
xticks([1e0, 1e1, 1e2]);
xlim([1, 500]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file none
exportFig('figs/uniaxial_sensitivity_dist_first_params_ft.pdf', 'width', 'third', 'height', 'normal');
#+end_src
#+begin_src matlab :exports none :results none
%% Sensitivity to disturbances - xf
figure;
plot(freqs, abs(squeeze(freqresp(G_ol('d', 'xf'), freqs, 'Hz'))));
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude $d/x_{f}$ [m/m]'); xlabel('Frequency [Hz]');
xticks([1e0, 1e1, 1e2]);
xlim([1, 500]);
ylim([1e-2, 1e2]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file none
exportFig('figs/uniaxial_sensitivity_dist_first_params_xf.pdf', 'width', 'third', 'height', 'normal');
#+end_src
#+name: fig:uniaxial_sensitivity_dist_first_params
#+caption: Sensitivity of the relative motion $d$ to disturbances: $f_s$ the direct forces applied on the sample (\subref{fig:uniaxial_sensitivity_dist_first_params_fs}), $f_t$ disturbances from the micro-station stages (\subref{fig:uniaxial_sensitivity_dist_first_params_ft}) and $x_f$ the floor motion (\subref{fig:uniaxial_sensitivity_dist_first_params_fs})
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_sensitivity_dist_first_params_fs}Direct forces}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_sensitivity_dist_first_params_fs.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_sensitivity_dist_first_params_ft}$\mu\text{-station}$ disturbances}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_sensitivity_dist_first_params_ft.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_sensitivity_dist_first_params_xf}Floor motion}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_sensitivity_dist_first_params_xf.png]]
#+end_subfigure
#+end_figure
#+begin_src matlab :exports none :results none
%% Bode Plot of the transfer function from actuator forces to measured displacement by the metrology
figure;
tiledlayout(3, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
ax1 = nexttile([2,1]);
hold on;
plot(freqs, abs(squeeze(freqresp(G_ol('d', 'f'), freqs, 'Hz'))));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude $d/f$ [m/N]'); set(gca, 'XTickLabel',[]);
ax2 = nexttile;
hold on;
plot(freqs, 180/pi*angle(squeeze(freqresp(G_ol('d', 'f'), freqs, 'Hz'))));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
hold off;
yticks(-360:90:360);
ylim([-180, 0]);
linkaxes([ax1,ax2],'x');
xlim([1, 500]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file none
exportFig('figs/uniaxial_plant_first_params.pdf', 'width', 'half', 'height', 600);
#+end_src
** Identification of all combination of stiffnesses / masses :noexport:
#+begin_src matlab :exports none
%% Use 1DoF Nano-Hexpod model
model_config = struct();
model_config.nhexa = "1dof";
model_config.controller = "open_loop";
%% Nano-Hexapod Mass
mn = 15; % Nano-Hexapod mass [kg]
%% Identification of all combination of stiffnesses / masses
clear io; io_i = 1;
io(io_i) = linio([mdl, '/controller'], 1, 'openinput'); io_i = io_i + 1; % Actuator Force
io(io_i) = linio([mdl, '/micro_station/xf'], 1, 'openinput'); io_i = io_i + 1; % Floor Motion
io(io_i) = linio([mdl, '/micro_station/ft'], 1, 'openinput'); io_i = io_i + 1; % Stage vibrations
io(io_i) = linio([mdl, '/fs'], 1, 'openinput'); io_i = io_i + 1; % Direct sample forces
io(io_i) = linio([mdl, '/dL'], 1, 'openoutput'); io_i = io_i + 1; % Relative Motion Sensor
io(io_i) = linio([mdl, '/fm'], 1, 'openoutput'); io_i = io_i + 1; % Force Sensor
io(io_i) = linio([mdl, '/vn'] , 1, 'openoutput'); io_i = io_i + 1; % Geophone
io(io_i) = linio([mdl, '/d'] , 1, 'openoutput'); io_i = io_i + 1; % Metrology Output
#+end_src
#+begin_src matlab :exports none
%% Light Sample
ms = 1; % Sample Mass [kg]
% Voice Coil (i.e. soft) Nano-Hexapod
kn = 1e4; % Nano-Hexapod Stiffness [N/m]
cn = 2*0.01*sqrt((ms + mn)*kn); % Nano-Hexapod Damping [N/(m/s)]
G_vc_light = linearize(mdl, io, 0.0);
G_vc_light.InputName = {'f', 'xf', 'ft', 'fs'};
G_vc_light.OutputName = {'dL', 'fm', 'vn', 'd'};
% APA (i.e. relatively stiff) Nano-Hexapod
kn = 1e6; % Nano-Hexapod Stiffness [N/m]
cn = 2*0.01*sqrt((ms + mn)*kn); % Nano-Hexapod Damping [N/(m/s)]
G_md_light = linearize(mdl, io, 0.0);
G_md_light.InputName = {'f', 'xf', 'ft', 'fs'};
G_md_light.OutputName = {'dL', 'fm', 'vn', 'd'};
% Piezoelectric (i.e. stiff) Nano-Hexapod
kn = 1e8; % Nano-Hexapod Stiffness [N/m]
cn = 2*0.01*sqrt((ms + mn)*kn); % Nano-Hexapod Damping [N/(m/s)]
G_pz_light = linearize(mdl, io, 0.0);
G_pz_light.InputName = {'f', 'xf', 'ft', 'fs'};
G_pz_light.OutputName = {'dL', 'fm', 'vn', 'd'};
%% Mid Sample
ms = 25; % Sample Mass [kg]
% Voice Coil (i.e. soft) Nano-Hexapod
kn = 1e4; % Nano-Hexapod Stiffness [N/m]
cn = 2*0.01*sqrt((ms + mn)*kn); % Nano-Hexapod Damping [N/(m/s)]
G_vc_mid = linearize(mdl, io, 0.0);
G_vc_mid.InputName = {'f', 'xf', 'ft', 'fs'};
G_vc_mid.OutputName = {'dL', 'fm', 'vn', 'd'};
% APA (i.e. relatively stiff) Nano-Hexapod
kn = 1e6; % Nano-Hexapod Stiffness [N/m]
cn = 2*0.01*sqrt((ms + mn)*kn); % Nano-Hexapod Damping [N/(m/s)]
G_md_mid = linearize(mdl, io, 0.0);
G_md_mid.InputName = {'f', 'xf', 'ft', 'fs'};
G_md_mid.OutputName = {'dL', 'fm', 'vn', 'd'};
% Piezoelectric (i.e. stiff) Nano-Hexapod
kn = 1e8; % Nano-Hexapod Stiffness [N/m]
cn = 2*0.01*sqrt((ms + mn)*kn); % Nano-Hexapod Damping [N/(m/s)]
G_pz_mid = linearize(mdl, io, 0.0);
G_pz_mid.InputName = {'f', 'xf', 'ft', 'fs'};
G_pz_mid.OutputName = {'dL', 'fm', 'vn', 'd'};
%% Heavy Sample
ms = 50; % Sample Mass [kg]
% Voice Coil (i.e. soft) Nano-Hexapod
kn = 1e4; % Nano-Hexapod Stiffness [N/m]
cn = 2*0.01*sqrt((ms + mn)*kn); % Nano-Hexapod Damping [N/(m/s)]
G_vc_heavy = linearize(mdl, io, 0.0);
G_vc_heavy.InputName = {'f', 'xf', 'ft', 'fs'};
G_vc_heavy.OutputName = {'dL', 'fm', 'vn', 'd'};
% APA (i.e. relatively stiff) Nano-Hexapod
kn = 1e6; % Nano-Hexapod Stiffness [N/m]
cn = 2*0.01*sqrt((ms + mn)*kn); % Nano-Hexapod Damping [N/(m/s)]
G_md_heavy = linearize(mdl, io, 0.0);
G_md_heavy.InputName = {'f', 'xf', 'ft', 'fs'};
G_md_heavy.OutputName = {'dL', 'fm', 'vn', 'd'};
% Piezoelectric (i.e. stiff) Nano-Hexapod
kn = 1e8; % Nano-Hexapod Stiffness [N/m]
cn = 2*0.01*sqrt((ms + mn)*kn); % Nano-Hexapod Damping [N/(m/s)]
G_pz_heavy = linearize(mdl, io, 0.0);
G_pz_heavy.InputName = {'f', 'xf', 'ft', 'fs'};
G_pz_heavy.OutputName = {'dL', 'fm', 'vn', 'd'};
#+end_src
#+begin_src matlab :exports none :tangle no
%% Save All Identified Plants
save('./matlab/mat/uniaxial_plants.mat', 'G_vc_light', 'G_md_light', 'G_pz_light', ...
'G_vc_mid', 'G_md_mid', 'G_pz_mid', ...
'G_vc_heavy', 'G_md_heavy', 'G_pz_heavy');
#+end_src
#+begin_src matlab :exports none :eval no
%% Save All Identified Plants
save('./mat/uniaxial_plants.mat', 'G_vc_light', 'G_md_light', 'G_pz_light', ...
'G_vc_mid', 'G_md_mid', 'G_pz_mid', ...
'G_vc_heavy', 'G_md_heavy', 'G_pz_heavy');
#+end_src
* Disturbance Identification
:PROPERTIES:
:HEADER-ARGS:matlab+: :tangle matlab/uniaxial_3_disturbances.m
:END:
<<sec:uniaxial_disturbances>>
** Introduction :ignore:
In order to quantify disturbances (red signals in Figure ref:fig:uniaxial_model_micro_station_nass), three geophones[fn:2] are used.
One is located on the floor, another one on the granite and the last one on the micro-hexapod's top platform (see Figure ref:fig:uniaxial_ustation_meas_disturbances).
The geophone located on the floor is used to measured the floor motion $x_f$ while the other two geophones are used to measure vibrations introduced by scanning of the $T_y$ stage and $R_z$ stage (see Figure ref:fig:uniaxial_ustation_dynamical_id_setup).
#+begin_src latex :file uniaxial_ustation_meas_disturbances.pdf
\begin{tikzpicture}
% Parameters
\def\blockw{6.0cm}
\def\blockh{1.2cm}
\def\tiltdeg{0}
\coordinate[] (rotationpoint) at (0, 4.5*\blockh);
\begin{scope}[rotate around={\tiltdeg:(rotationpoint)}]
% Tilt
\path[] ([shift=(-120:4*\blockh)]rotationpoint) coordinate(beginarc) arc (-120:-110:4*\blockh) %
-- ([shift=(-70:4*\blockh)]rotationpoint) arc (-70:-60:4*\blockh)%
|- ++(-0.15*\blockw, 0.6*\blockh) coordinate (spindlene)%
|- ($(beginarc) + (0.15*\blockw, 0.2*\blockh)$) coordinate (spindlesw) -- ++(0, 0.4*\blockh) coordinate(tiltte) -| cycle;
% Spindle
\coordinate[] (spindlese) at (spindlesw-|spindlene);
\draw[fill=black!30] ($(spindlese)+(-0.1,0.1)+(-0.1*\blockw, 0)$) -| ($(spindlene)+(-0.1, 0)$) -| coordinate[pos=0.25](spindletop) ($(spindlesw)+(0.1,0.1)$) -| ++(0.1*\blockw, -\blockh) -| coordinate[pos=0.25](spindlebot) cycle;
% \draw[dashed, color=black!60] ($(spindletop)+(0, 0.2)$) -- ($(spindlebot)+(0,-0.2)$);
% Tilt
\draw[fill=black!60] ([shift=(-120:4*\blockh)]rotationpoint) coordinate(beginarc) arc (-120:-110:4*\blockh) %
-- ([shift=(-70:4*\blockh)]rotationpoint) arc (-70:-60:4*\blockh)%
|- coordinate (tiltne) ++(-0.15*\blockw, 0.6*\blockh) coordinate (spindlene)%
|- ($(beginarc) + (0.15*\blockw, 0.2*\blockh)$) coordinate (spindlesw) -- ++(0, 0.4*\blockh) -| cycle;
% Micro-Hexapod
\begin{scope}[shift={(spindletop)}]
% Parameters definitions
\def\baseh{0.22*\blockh} % Height of the base
\def\naceh{0.18*\blockh} % Height of the nacelle
\def\baser{0.22*\blockw} % Radius of the base
\def\nacer{0.18*\blockw} % Radius of the nacelle
\def\armr{0.2*\blockh} % Radius of the arms
\def\basearmborder{0.2}
\def\nacearmborder{0.2}
\def\xnace{0} \def\ynace{\blockh-\naceh} \def\anace{0}
\def\xbase{0} \def\ybase{0} \def\abase{0}
% Hexapod
\begin{scope}[shift={(\xbase, \ybase)}, rotate=\abase]
% Base
\draw[fill=white] (-\baser, 0) coordinate[](uhexabot) rectangle (\baser, \baseh);
\coordinate[] (armbasel) at (-\baser+\basearmborder+\armr, \baseh);
\coordinate[] (armbasec) at (0, \baseh);
\coordinate[] (armbaser) at (\baser-\basearmborder-\armr, \baseh);
\begin{scope}[shift={(\xnace, \ynace)}, rotate=\anace]
\draw[fill=white] (-\nacer, 0) rectangle (\nacer, \naceh);
\coordinate[] (uhexatop) at (0, \naceh);
\coordinate[] (armnacel) at (-\nacer+\nacearmborder+\armr, 0);
\coordinate[] (armnacec) at (0, 0);
\coordinate[] (armnacer) at (\nacer-\nacearmborder-\armr, 0);
\end{scope}
\draw[] (armbasec) -- (armnacer);
\draw[] (armbasec) -- (armnacel);
\draw[] (armbasel) -- coordinate(mhexaw) (armnacel);
\draw[] (armbasel) -- (armnacec);
\draw[] (armbaser) -- (armnacec);
\draw[] (armbaser) -- coordinate(mhexae) (armnacer);
\end{scope}
\end{scope}
\begin{scope}[shift={(uhexatop)}] % Geophone - Hexapod
\draw[rounded corners=0.1, draw=colorred, fill=colorred!10!white] (-0.5, 0.2) -- ++(0, -0.1) -- ++(0.1, -0.1) -- ++(0.1, 0.1) -- ++(0, 0.1) --cycle;
\draw[rounded corners=0.1, draw=colorred, fill=colorred!10!white] ( 0.3, 0.2) -- ++(0, -0.1) -- ++(0.1, -0.1) -- ++(0.1, 0.1) -- ++(0, 0.1) --cycle;
\draw[draw=colorred, fill=colorred!10!white] (0.6, 0.4) rectangle ++(0.2, 0.2);
\node[shape=circle,minimum size=3pt,inner sep=0pt, draw=colorred, fill=colorred] at (0.8, 0.5){};
\draw[out=0, in=180, draw=colorred] (0.8, 0.5) to ++(0.6, -0.1) node[above, color=colorred]{$x_h$};
\draw[draw=colorred, fill=colorred!10!white] (-0.6, 0.2) rectangle node[midway, color=colorred]{\tiny geophone} (0.6, 0.8);
\end{scope}
\end{scope}
\begin{scope}[shift={(0, -0.3*\blockh)}]
% Translation Stage - fixed part
\draw[fill=black!40] (-0.5*\blockw, 0) coordinate[](tyb) rectangle (0.5*\blockw, 0.15*\blockh);
\coordinate[] (measposbot) at (0.5*\blockw, 0);
% Translation Stage - mobile part
\draw[fill=black!10, fill opacity=0.5] (-0.5*\blockw, 0.2*\blockh) -- (-0.5*\blockw, 1.5*\blockh) coordinate[](tyt) -- (0.5*\blockw, 1.5*\blockh) -- (0.5*\blockw, 0.2*\blockh) -- (0.35*\blockw, 0.2*\blockh) -- (0.35*\blockw, 0.8*\blockh) -- (-0.35*\blockw, 0.8*\blockh) -- (-0.35*\blockw, 0.2*\blockh) -- cycle;
% Translation Guidance
\draw[dashed, color=black!60] ($(-0.5*\blockw, 0)+( 0.075*\blockw,0.5*\blockh)$) circle (0.2*\blockh);
\draw[dashed, color=black!60] ($( 0.5*\blockw, 0)+(-0.075*\blockw,0.5*\blockh)$) circle (0.2*\blockh);
\draw[fill, color=black] ($( 0.5*\blockw, 0)+(-0.075*\blockw,0.5*\blockh)$) circle (0.04);
\node[draw, circle, inner sep=0pt, minimum size=0.3cm, label=above:$T_y$] at ($( 0.5*\blockw, 0)+(-0.075*\blockw,0.5*\blockh)$){};
% Tilt Guidance
\draw[dashed, color=black!60] ([shift=(-107:4.1*\blockh)]rotationpoint) arc (-107:-120:4.1*\blockh);
\draw[dashed, color=black!60] ([shift=( -73:4.1*\blockh)]rotationpoint) arc (-73:-60:4.1*\blockh);
\begin{scope}[shift={(4.0, 0)}] % Geophone - Granite
\draw[rounded corners=0.1, draw=colorred, fill=colorred!10!white] (-0.5, 0.2) -- ++(0, -0.1) -- ++(0.1, -0.1) -- ++(0.1, 0.1) -- ++(0, 0.1) --cycle;
\draw[rounded corners=0.1, draw=colorred, fill=colorred!10!white] ( 0.3, 0.2) -- ++(0, -0.1) -- ++(0.1, -0.1) -- ++(0.1, 0.1) -- ++(0, 0.1) --cycle;
\draw[draw=colorred, fill=colorred!10!white] (0.6, 0.4) rectangle ++(0.2, 0.2);
\node[shape=circle,minimum size=3pt,inner sep=0pt, draw=colorred, fill=colorred] at (0.8, 0.5){};
\draw[out=0, in=180, draw=colorred] (0.8, 0.5) to ++(0.6, -0.1) node[above, color=colorred]{$x_g$};
\draw[draw=colorred, fill=colorred!10!white] (-0.6, 0.2) rectangle node[midway, color=colorred]{\tiny geophone} (0.6, 0.8);
\end{scope}
\end{scope}
% Granite
\draw[fill=black!40] (-0.8*\blockw, -0.3*\blockh) rectangle node[midway]{Granite} (0.8*\blockw, -1.5*\blockh);
\begin{scope}[shift={(4.0, -1.5*\blockh)}] % Geophone - Floor
\draw[rounded corners=0.1, draw=colorred, fill=colorred!10!white] (-0.5, 0.2) -- ++(0, -0.1) -- ++(0.1, -0.1) -- ++(0.1, 0.1) -- ++(0, 0.1) --cycle;
\draw[rounded corners=0.1, draw=colorred, fill=colorred!10!white] ( 0.3, 0.2) -- ++(0, -0.1) -- ++(0.1, -0.1) -- ++(0.1, 0.1) -- ++(0, 0.1) --cycle;
\draw[draw=colorred, fill=colorred!10!white] (0.6, 0.4) rectangle ++(0.2, 0.2);
\node[shape=circle,minimum size=3pt,inner sep=0pt, draw=colorred, fill=colorred] at (0.8, 0.5){};
\draw[out=0, in=180, draw=colorred] (0.8, 0.5) to ++(0.6, -0.1) node[above, color=colorred]{$x_f$};
\draw[draw=colorred, fill=colorred!10!white] (-0.6, 0.2) rectangle node[midway, color=colorred]{\tiny geophone} (0.6, 0.8);
\end{scope}
% Vertical line
\draw[dashed, color=black] (spindlebot) -- ++(0, 2*\blockh);
\node[] at ($(spindlebot)+(0, 1.1*\blockh)$) {\AxisRotator[rotate=-90]};
\node[right, shift={(0.3,0)}] at ($(spindlebot)+(0, 1.1*\blockh)$) {$\theta_z$};
% Axis
\begin{scope}[shift={(-0.6*\blockw, 2.5*\blockh)}]
\def\axissize{0.8cm}
\draw[->] (0, 0) -- ++(0, \axissize) node[right]{$z$};
\draw[->] (0, 0) -- ++(-\axissize, 0) node[above]{$x$};
\draw[fill, color=black] (0, 0) circle (0.05*\axissize);
\node[draw, circle, inner sep=0pt, minimum size=0.4*\axissize, label=right:$y$] (yaxis) at (0, 0){};
\end{scope}
\end{tikzpicture}
#+end_src
#+name: fig:uniaxial_ustation_meas_disturbances_setup
#+caption: Identification of the disturbances coming from the micro-station. Measurement schematic is shown in (\subref{fig:uniaxial_ustation_meas_disturbances}). A picture of the setup is shown in (\subref{fig:uniaxial_ustation_dynamical_id_setup})
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_ustation_meas_disturbances}Disturbance measurement setup - Schematic}
#+attr_latex: :options {0.49\textwidth}
#+begin_subfigure
#+attr_latex: :width 0.95\linewidth
[[file:figs/uniaxial_ustation_meas_disturbances.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_ustation_dynamical_id_setup}Two geophones are used to measure vibrations induced by $T_y$ and $R_z$ scans}
#+attr_latex: :options {0.49\textwidth}
#+begin_subfigure
#+attr_latex: :width 0.95\linewidth
[[file:figs/uniaxial_ustation_dynamical_id_setup.jpg]]
#+end_subfigure
#+end_figure
** Matlab Init :noexport:ignore:
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
<<matlab-dir>>
#+end_src
#+begin_src matlab :exports none :results silent :noweb yes
<<matlab-init>>
#+end_src
#+begin_src matlab :tangle no :noweb yes
<<m-init-path>>
#+end_src
#+begin_src matlab :eval no :noweb yes
<<m-init-path-tangle>>
#+end_src
#+begin_src matlab :noweb yes
<<m-init-other>>
#+end_src
#+begin_src matlab
%% Uniaxial Simscape model name
mdl = 'nass_uniaxial_model';
#+end_src
#+begin_src matlab
%% Frequency Vector [Hz]
freqs = logspace(0, 3, 1000);
#+end_src
#+begin_src matlab
%% Load the micro-station parameters
load('uniaxial_micro_station_parameters.mat');
#+end_src
** Ground Motion
In order to acquire the geophone signals, the measurement setup shown in Figure ref:fig:uniaxial_geophone_meas_chain is used.
The voltage generated by the geophone is amplified using a low noise voltage amplifier[fn:3] with a gain of 60dB before going to the ADC.
This is done in order to improve the signal over noise ratio.
To reconstruct the displacement $x_f$ from the measured voltage $\hat{V}_{x_f}$, the transfer function of the measurement chain from $x_f$ to $\hat{V}_{x_f}$ needs to be estimated.
First the transfer function $G_{geo}$ from the floor motion $x_{f}$ to generated geophone voltage $V_{x_f}$ is shown in eqref:eq:uniaxial_geophone_tf, with $T_g = 88\,\frac{V}{m/s}$ the sensitivity of the geophone, $f_0 = \frac{\omega_0}{2\pi} = 2\,\text{Hz}$ its resonance frequency and $\xi = 0.7$ its damping ratio.
This model of the geophone is taken from [[cite:&collette12_review]].
The gain of the voltage amplifier is $V^{\prime}_{x_f}/V_{x_f} = g_0 = 1000$.
\begin{equation}\label{eq:uniaxial_geophone_tf}
G_{geo}(s) = \frac{V_{x_f}}{x_f}(s) = T_{g} \cdot s \cdot \frac{s^2}{s^2 + 2 \xi \omega_0 s + \omega_0^2} \quad \left[ V/m \right]
\end{equation}
#+begin_src latex :file uniaxial_geophone_meas_chain.pdf
\begin{tikzpicture}
\draw[rounded corners=0.1, draw=colorblack, fill=colorblack!10!white] (-0.5, 0.2) -- ++(0, -0.1) -- ++(0.1, -0.1) -- ++(0.1, 0.1) -- ++(0, 0.1) --cycle;
\draw[rounded corners=0.1, draw=colorblack, fill=colorblack!10!white] ( 0.3, 0.2) -- ++(0, -0.1) -- ++(0.1, -0.1) -- ++(0.1, 0.1) -- ++(0, 0.1) --cycle;
\draw[draw=colorblack, fill=colorblack!10!white] (0.6, 0.4) rectangle ++(0.2, 0.2);
\node[shape=circle,minimum size=3pt,inner sep=0pt, draw=colorblack, fill=colorblack] at (0.8, 0.5){};
\draw[out=0, in=180, draw=colorblack] (0.8, 0.5) to ++(0.6, -0.1) coordinate[](geophone_output);
\draw[draw=colorblack, fill=colorblack!10!white] (-0.6, 0.2) rectangle node[midway, color=colorblack]{\tiny geophone} (0.6, 0.8);
\draw[dashed] (-1, 0) -- (1, 0);
\draw[->] (-0.8, 0) -- ++(0, 0.5)node[left]{$x_f$};
\node[gain right, minimum width=0.8cm, right=0.5 of geophone_output] (gain) {$g_0$};
\node[ADC, right=1 of gain] (adc) {ADC};
\draw[->] (geophone_output) -- (gain.west) node[above left]{$V_{x_f}$};
\draw[->] (gain.east) -- (adc.west) node[above left]{$V^{\prime}_{x_f}$};
\draw[->] (adc.east) -- ++(1, 0) node[above left]{$\hat{V}_{x_f}$};
\end{tikzpicture}
#+end_src
#+name: fig:uniaxial_geophone_meas_chain
#+caption: Measurement setup for one geophone. The inertial displacement $x$ is converted to a voltage $V$ by the geophone. This voltage is amplified by a factor $g_0 = 60\,dB$ using a low-noise voltage amplifier. It is then converted to a digital value $\hat{V}_x$ using a 16bit ADC.
#+RESULTS:
[[file:figs/uniaxial_geophone_meas_chain.png]]
#+begin_src matlab
%% Compute Floor Motion Spectral Density
% Load floor motion data
% t: time in [s]
% V: measured voltage genrated by the geophone and amplified by a 60dB gain voltage amplifier [V]
load('ground_motion_measurement.mat', 't', 'V');
% Geophone Transfer Function
Tg = 88; % Sensitivity [V/(m/s)]
w0 = 2*2*pi; % Cut-off frequency [rad/s]
xi = 0.7; % Damping ratio
G_geo = Tg*s*s^2/(s^2 + 2*xi*w0*s + w0^2); % Geophone's transfer function [V/m]
% Voltage amplifier transfer function
g0 = 10^(60/20); % [abs]
% Compute measured voltage PSD
Ts = (t(2)-t(1)); % Sampling Time [s]
Nfft = floor(2/Ts);
win = hanning(Nfft);
Noverlap = floor(Nfft/2);
[psd_V, f] = pwelch(V, win, Noverlap, Nfft, 1/Ts); % [V^2/Hz]
% Ground Motion ASD
psd_xf = psd_V./abs(squeeze(freqresp(G_geo*g0, f, 'Hz'))).^2; % [m^2/Hz]
#+end_src
The amplitude spectral density of the floor motion $\Gamma_{x_f}$ can be computed from the amplitude spectral density of measured voltage $\Gamma_{\hat{V}_{x_f}}$ using eqref:eq:uniaxial_asd_floor_motion.
The estimated amplitude spectral density $\Gamma_{x_f}$ of the floor motion $x_f$ is shown in Figure ref:fig:uniaxial_asd_floor_motion_id31.
\begin{equation}\label{eq:uniaxial_asd_floor_motion}
\Gamma_{x_f}(\omega) = \frac{\Gamma_{\hat{V}_{x_f}}(\omega)}{|G_{geo}(j\omega)| \cdot g_0} \quad \left[ m/\sqrt{\text{Hz}} \right]
\end{equation}
#+begin_src matlab :exports none :results none
%% Amplitude Spectral Density of the measured Floor motion on ID31
figure;
plot(f, sqrt(psd_xf), 'DisplayName', '$\Gamma_{x_{f}}$');
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
xlabel('Frequency [Hz]'); ylabel('Ampl. Spectral Density $\left[\frac{m}{\sqrt{Hz}}\right]$')
legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 1);
xlim([1, 500]);
xticks([1e0, 1e1, 1e2]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file none
exportFig('figs/uniaxial_asd_floor_motion_id31.pdf', 'width', 'half', 'height', 'normal');
#+end_src
#+name: fig:uniaxial_asd_disturbance
#+caption: Estimated amplitude spectral density of the floor motion $x_f$ (\subref{fig:uniaxial_asd_floor_motion_id31}) and of the stage disturbances $f_t$ (\subref{fig:uniaxial_asd_disturbance_force})
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_asd_floor_motion_id31}Estimated ASD of $x_f$}
#+attr_latex: :options {0.49\textwidth}
#+begin_subfigure
#+attr_latex: :width 0.95\linewidth
[[file:figs/uniaxial_asd_floor_motion_id31.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_asd_disturbance_force}Estimated ASD of $f_t$}
#+attr_latex: :options {0.49\textwidth}
#+begin_subfigure
#+attr_latex: :width 0.95\linewidth
[[file:figs/uniaxial_asd_disturbance_force.png]]
#+end_subfigure
#+end_figure
** Stage Vibration
In order to estimate the vibrations induced by the scanning of the micro-station stages, two geophones are used as shown in Figure ref:fig:uniaxial_ustation_dynamical_id_setup.
The vertical relative velocity between the top platform of the micro hexapod and the granite is estimated in two cases: first without moving the micro-station stages, and then during a Spindle rotation at 6rpm.
The vibrations induced by the $T_y$ stage are not considered here because the induced vibrations have less amplitude than the vibrations induced by the $R_z$ stage and because the $T_y$ stage can be scanned at lower velocities if the induced vibrations are found to be an issue.
#+begin_src matlab
%% Estimation of the Spectral density of the stage vibrations
% Measured velocity of granite and hexapod during spindle rotation
% t: time in [s]
% vg: measured granite velocity [m/s]
% vg: measured micro-hexapod's top platform velocity [m/s]
load('meas_spindle_on.mat', 't', 'vg', 'vh');
spindle_off = load('meas_spindle_off.mat', 't', 'vg', 'vh'); % No Rotation
% Compute Power Spectral Density of the relative velocity between granite and hexapod during spindle rotation
Fs = 1/(t(2)-t(1)); % Sampling Frequency [Hz]
win = hanning(ceil(2*Fs)); % Hanning window
[psd_vft, f] = pwelch(vh-vg, win, [], [], Fs); % [(m/s)^2/Hz]
[psd_off, ~] = pwelch(spindle_off.vh-spindle_off.vg, win, [], [], Fs); % [(m/s)^2/Hz]
% Disable the Nano-Hexpod for now
model_config = struct();
model_config.nhexa = "none";
model_config.controller = "open_loop";
% Identify the transfer function from u to taum
clear io; io_i = 1;
io(io_i) = linio([mdl, '/micro_station/ft'], 1, 'openinput'); io_i = io_i + 1; % Stage Disturbance Force
io(io_i) = linio([mdl, '/micro_station/xg'], 1, 'openoutput'); io_i = io_i + 1; % Absolute motion of Granite
io(io_i) = linio([mdl, '/micro_station/xh'], 1, 'openoutput'); io_i = io_i + 1; % Absolute motion of Hexapod
% Perform the model extraction
G = linearize(mdl, io, 0.0);
G.InputName = {'ft'};
G.OutputName = {'Dg', 'Dh'};
% Power Spectral Density of the equivalent force ft [N/Hz^2]
psd_ft = (psd_vft./(2*pi*f).^2)./abs(squeeze(freqresp(G('Dh', 'ft') - G('Dg', 'ft'), f, 'Hz'))).^2;
#+end_src
The amplitude spectral density of the relative motion with and without the Spindle rotation are compared in Figure ref:fig:uniaxial_asd_vibration_spindle_rotation.
It is shown that the spindle rotation increases the vibrations above $20\,\text{Hz}$.
The sharp peak observed at $24\,\text{Hz}$ is believed to be induced by electromagnetic interference between the currents in the spindle motor phases and the geophone cable because this peak is not observed when rotating the spindle "by hand".
#+begin_src matlab :exports none :results none
%% Amplitude Spectral Density of the relative motion measured between the granite and the micro-hexapod's top platform during Spindle rotating
figure;
hold on;
plot(f, sqrt(psd_vft)./(2*pi*f), 'DisplayName', '6rpm');
plot(f, sqrt(psd_off)./(2*pi*f), 'DisplayName', '0rpm');
hold off;
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
xlabel('Frequency [Hz]'); ylabel('Ampl. Spectral Density $\left[\frac{m}{\sqrt{Hz}}\right]$')
legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 1);
xlim([1, 500]); ylim([1e-12, 1e-7])
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_asd_vibration_spindle_rotation.pdf', 'width', 'wide', 'height', 'normal');
#+end_src
#+name: fig:uniaxial_asd_vibration_spindle_rotation
#+caption: Amplitude Spectral Density $\Gamma_{R_z}$ of the relative motion measured between the granite and the micro-hexapod's top platform during Spindle rotating
#+RESULTS:
[[file:figs/uniaxial_asd_vibration_spindle_rotation.png]]
In order to compute the equivalent disturbance force $f_t$ (Figure ref:fig:uniaxial_model_micro_station) that induces such motion, the transfer function $G_{f_t}(s)$ from $f_t$ to the relative motion between the micro-hexapod's top platform and the granite $(x_{h} - x_{g})$ is extracted from the model.
The amplitude spectral density $\Gamma_{f_{t}}$ of the disturbance force is them computed from eqref:eq:uniaxial_ft_asd and is shown in Figure ref:fig:uniaxial_asd_disturbance_force.
\begin{equation}\label{eq:uniaxial_ft_asd}
\Gamma_{f_{t}}(\omega) = \frac{\Gamma_{R_{z}}(\omega)}{|G_{f_t}(j\omega)|}
\end{equation}
#+begin_src matlab :exports none :results none
%% Estimated disturbance force ft from measurement and uniaxial model
figure;
hold on;
plot(f, sqrt(psd_ft), 'DisplayName', '$\Gamma_{f_{t}}$');
hold off;
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
xlabel('Frequency [Hz]'); ylabel('Ampl. Spectral Density $\left[\frac{N}{\sqrt{Hz}}\right]$')
xlim([1, 500]);
legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 1);
#+end_src
#+begin_src matlab :tangle no :exports results :results file none
exportFig('figs/uniaxial_asd_disturbance_force.pdf', 'width', 'half', 'height', 'normal');
#+end_src
#+begin_src matlab :exports none :tangle no
%% Save PSD of disturbances
save('./matlab/mat/uniaxial_disturbance_psd.mat', 'f', 'psd_ft', 'psd_xf');
#+end_src
#+begin_src matlab :exports none :eval no
%% Save PSD of disturbances
save('./mat/uniaxial_disturbance_psd.mat', 'f', 'psd_ft', 'psd_xf');
#+end_src
* Open-Loop Dynamic Noise Budgeting
:PROPERTIES:
:HEADER-ARGS:matlab+: :tangle matlab/uniaxial_4_dynamic_noise_budget.m
:END:
<<sec:uniaxial_noise_budgeting>>
** Introduction :ignore:
Now that a model of the acrshort:nass has been obtained (see section ref:sec:nano_station_model) and that the disturbances have been estimated (see section ref:sec:uniaxial_disturbances), it is possible to perform an /open-loop dynamic noise budgeting/.
In order to perform such noise budgeting, the disturbances needs to be modelled by their spectral densities (done in section ref:sec:uniaxial_disturbances).
Then, the transfer functions from disturbances to the performance metric (here the distance $d$) are computed (Section ref:ssec:uniaxial_noise_budget_sensitivity).
Finally, these two information are combined to estimate the corresponding spectral density of the performance metric.
This is very useful to identify what is limiting the performances in the system, or the compare the achievable performances with different system parameters (Section ref:ssec:uniaxial_noise_budget_result).
** Matlab Init :noexport:ignore:
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
<<matlab-dir>>
#+end_src
#+begin_src matlab :exports none :results silent :noweb yes
<<matlab-init>>
#+end_src
#+begin_src matlab :tangle no :noweb yes
<<m-init-path>>
#+end_src
#+begin_src matlab :eval no :noweb yes
<<m-init-path-tangle>>
#+end_src
#+begin_src matlab :noweb yes
<<m-init-other>>
#+end_src
#+begin_src matlab
%% Frequency Vector [Hz]
freqs = logspace(0, 3, 1000);
#+end_src
#+begin_src matlab
%% Load the PSD of disturbances
load('uniaxial_disturbance_psd.mat', 'f', 'psd_ft', 'psd_xf');
%% Load Plants Dynamics
load('uniaxial_plants.mat', 'G_vc_light', 'G_md_light', 'G_pz_light', ...
'G_vc_mid', 'G_md_mid', 'G_pz_mid', ...
'G_vc_heavy', 'G_md_heavy', 'G_pz_heavy');
#+end_src
** Sensitivity to disturbances
<<ssec:uniaxial_noise_budget_sensitivity>>
From the Uni-axial model of the acrshort:nass (Figure ref:fig:uniaxial_model_micro_station_nass), the transfer function from the disturbances ($f_s$, $x_f$ and $f_t$) to the displacement $d$ are computed.
This is done for two extreme sample masses $m_s = 1\,\text{kg}$ and $m_s = 50\,\text{kg}$ and three nano-hexapod stiffnesses:
- $k_n = 0.01\,N/\mu m$ that could represent a voice coil actuator with soft flexible guiding
- $k_n = 1\,N/\mu m$ that could represent a voice coil actuator with a stiff flexible guiding or a mechanically amplified piezoelectric actuator
- $k_n = 100\,N/\mu m$ that could represent a stiff piezoelectric stack actuator
The obtained sensitivity to disturbances for the three nano-hexapod stiffnesses are shown in Figure ref:fig:uniaxial_sensitivity_disturbances_nano_hexapod_stiffnesses for the sample mass $m_s = 1\,\text{kg}$ (same conclusions can be drawn with $m_s = 50\,\text{kg}$):
- The soft nano-hexapod is more sensitive to forces applied on the sample (cable forces for instance), which is expected due to its lower stiffness (Figure ref:fig:uniaxial_sensitivity_disturbances_nano_hexapod_stiffnesses_fs)
- Between the suspension mode of the nano-hexapod (here at 5Hz for the soft nano-hexapod) and the first mode of the micro-station (here at 70Hz), the disturbances induced by the stage vibrations are filtered out (Figure ref:fig:uniaxial_sensitivity_disturbances_nano_hexapod_stiffnesses_ft)
- Above the suspension mode of the nano-hexapod, the sample's inertial motion is unaffected by the floor motion, and therefore the sensitivity to floor motion is close to $1$ (Figure ref:fig:uniaxial_sensitivity_disturbances_nano_hexapod_stiffnesses_xf)
#+begin_src matlab :exports none :results none
%% Sensitivity to disturbances for three different nano-hexpod stiffnesses
figure;
hold on;
plot(freqs, abs(squeeze(freqresp(G_vc_light('d', 'fs'), freqs, 'Hz'))));
plot(freqs, abs(squeeze(freqresp(G_md_light('d', 'fs'), freqs, 'Hz'))));
plot(freqs, abs(squeeze(freqresp(G_pz_light('d', 'fs'), freqs, 'Hz'))));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude $d/f_{s}$ [m/N]'); xlabel('Frequency [Hz]');
xticks([1e0, 1e1, 1e2]);
xlim([1, 500]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file none
exportFig('figs/uniaxial_sensitivity_disturbances_nano_hexapod_stiffnesses_fs.pdf', 'width', 'third', 'height', 'normal');
#+end_src
#+begin_src matlab :exports none :results none
%% Sensitivity to disturbances for three different nano-hexpod stiffnesses
figure;
hold on;
plot(freqs, abs(squeeze(freqresp(G_vc_light('d', 'ft'), freqs, 'Hz'))));
plot(freqs, abs(squeeze(freqresp(G_md_light('d', 'ft'), freqs, 'Hz'))));
plot(freqs, abs(squeeze(freqresp(G_pz_light('d', 'ft'), freqs, 'Hz'))));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude $d/f_{t}$ [m/N]'); xlabel('Frequency [Hz]');
xticks([1e0, 1e1, 1e2]);
xlim([1, 500]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file none
exportFig('figs/uniaxial_sensitivity_disturbances_nano_hexapod_stiffnesses_ft.pdf', 'width', 'third', 'height', 'normal');
#+end_src
#+begin_src matlab :exports none :results none
%% Sensitivity to disturbances for three different nano-hexpod stiffnesses
figure;
hold on;
plot(freqs, abs(squeeze(freqresp(G_vc_light('d', 'xf'), freqs, 'Hz'))), 'DisplayName', '$k_n = 0.01\,N/\mu m$');
plot(freqs, abs(squeeze(freqresp(G_md_light('d', 'xf'), freqs, 'Hz'))), 'DisplayName', '$k_n = 1 \,N/\mu m$');
plot(freqs, abs(squeeze(freqresp(G_pz_light('d', 'xf'), freqs, 'Hz'))), 'DisplayName', '$k_n = 100 \,N/\mu m$');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude $d/x_{f}$ [m/m]'); xlabel('Frequency [Hz]');
xticks([1e0, 1e1, 1e2]);
leg = legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 1);
leg.ItemTokenSize(1) = 15
xlim([1, 500]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file none
exportFig('figs/uniaxial_sensitivity_disturbances_nano_hexapod_stiffnesses_xf.pdf', 'width', 'third', 'height', 'normal');
#+end_src
#+name: fig:uniaxial_sensitivity_disturbances_nano_hexapod_stiffnesses
#+caption: Sensitivity of $d$ to disturbances for three different nano-hexpod stiffnesses. $f_s$ the direct forces applied on the sample (\subref{fig:uniaxial_sensitivity_disturbances_nano_hexapod_stiffnesses_fs}), $f_t$ disturbances from the micro-station stages (\subref{fig:uniaxial_sensitivity_disturbances_nano_hexapod_stiffnesses_ft}) and $x_f$ the floor motion (\subref{fig:uniaxial_sensitivity_disturbances_nano_hexapod_stiffnesses_fs})
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_sensitivity_disturbances_nano_hexapod_stiffnesses_fs}Direct forces}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_sensitivity_disturbances_nano_hexapod_stiffnesses_fs.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_sensitivity_disturbances_nano_hexapod_stiffnesses_ft}$\mu\text{-station}$ disturbances}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_sensitivity_disturbances_nano_hexapod_stiffnesses_ft.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_sensitivity_disturbances_nano_hexapod_stiffnesses_xf}Floor motion}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_sensitivity_disturbances_nano_hexapod_stiffnesses_xf.png]]
#+end_subfigure
#+end_figure
** Open-Loop Dynamic Noise Budgeting
<<ssec:uniaxial_noise_budget_result>>
Now, the amplitude spectral density of the disturbances are taken into account to estimate the residual motion $d$ for each nano-hexapod and sample configuration.
The Cumulative Amplitude Spectrum of the relative motion $d$ due to both the floor motion $x_f$ and the stage vibrations $f_t$ are shown in Figure ref:fig:uniaxial_cas_d_disturbances_stiffnesses for the three nano-hexapod stiffnesses.
It is shown that the effect of the floor motion is much less than the effect of stage vibrations, except for the soft nano-hexapod below 5Hz.
The total cumulative amplitude spectrum of $d$ for the three nano-hexapod stiffnesses and for the two sample's masses are shown in Figure ref:fig:uniaxial_cas_d_disturbances_payload_masses.
The conclusion is that the sample's mass has little effect on the cumulative amplitude spectrum of the relative motion $d$.
#+begin_src matlab :exports none :results none
%% Cumulative Amplitude Spectrum of the relative motion d, due to both the floor motion and the stage vibrations
figure;
hold on;
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_vc_light('d', 'ft'), f, 'Hz'))).^2)))), '-', 'color', colors(1,:), 'DisplayName', '$f_t$');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_md_light('d', 'ft'), f, 'Hz'))).^2)))), '-', 'color', colors(2,:), 'DisplayName', '$f_t$');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_pz_light('d', 'ft'), f, 'Hz'))).^2)))), '-', 'color', colors(3,:), 'DisplayName', '$f_t$');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_xf.*abs(squeeze(freqresp(G_vc_light('d', 'xf'), f, 'Hz'))).^2)))), '--', 'color', colors(1,:), 'DisplayName', '$x_f$ ($k_n = 0.01\,N/\mu m$)');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_xf.*abs(squeeze(freqresp(G_md_light('d', 'xf'), f, 'Hz'))).^2)))), '--', 'color', colors(2,:), 'DisplayName', '$x_f$ ($k_n = 1 \,N/\mu m$)');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_xf.*abs(squeeze(freqresp(G_pz_light('d', 'xf'), f, 'Hz'))).^2)))), '--', 'color', colors(3,:), 'DisplayName', '$x_f$ ($k_n = 100 \,N/\mu m$)');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('CAS [m]'); xlabel('Frequency [Hz]');
leg = legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 2);
leg.ItemTokenSize(1) = 15
xlim([1, 500]);
ylim([1e-12, 3e-6])
#+end_src
#+begin_src matlab :tangle no :exports results :results file none
exportFig('figs/uniaxial_cas_d_disturbances_stiffnesses.pdf', 'width', 'half', 'height', 'normal');
#+end_src
#+begin_src matlab :exports none :results none
%% Cumulative Amplitude Spectrum of the relative motion d due to all disturbances, for two sample masses
figure;
hold on;
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_vc_light('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_vc_light('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', colors(1,:), 'DisplayName', '$m_s = 1\,kg$, $k_n = 0.01\,N/\mu m$');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_md_light('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_md_light('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', colors(2,:), 'DisplayName', '$m_s = 1\,kg$, $k_n = 1\,N/\mu m$');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_pz_light('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_pz_light('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', colors(3,:), 'DisplayName', '$m_s = 1\,kg$, $k_n = 100\,N/\mu m$');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_vc_heavy('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_vc_heavy('d', 'xf'), f, 'Hz'))).^2)))), '--', ...
'color', colors(1,:), 'DisplayName', '$m_s = 50\,kg$, $k_n = 0.01\,N/\mu m$');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_md_heavy('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_md_heavy('d', 'xf'), f, 'Hz'))).^2)))), '--', ...
'color', colors(2,:), 'DisplayName', '$m_s = 50\,kg$, $k_n = 1\,N/\mu m$');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_pz_heavy('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_pz_heavy('d', 'xf'), f, 'Hz'))).^2)))), '--', ...
'color', colors(3,:), 'DisplayName', '$m_s = 50\,kg$, $k_n = 100\,N/\mu m$');
plot([1, 1e3], [20e-9, 20e-9], 'k--', 'HandleVisibility', 'off');
text(4, 1e-8, '20 nm RMS', 'horizontalalignment', 'center');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('CAS [m]'); xlabel('Frequency [Hz]');
leg = legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 1);
leg.ItemTokenSize(1) = 15
xlim([1, 500]);
ylim([1e-12, 3e-6])
#+end_src
#+begin_src matlab :tangle no :exports results :results file none
exportFig('figs/uniaxial_cas_d_disturbances_payload_masses.pdf', 'width', 'half', 'height', 'normal');
#+end_src
#+name: fig:uniaxial_cas_d_disturbances
#+caption: Cumulative Amplitude Spectrum of the relative motion $d$. The effect of $x_f$ and $f_t$ are shown in (\subref{fig:uniaxial_cas_d_disturbances_stiffnesses}). The effect of sample mass for the three hexapod stiffnesses is shown in (\subref{fig:uniaxial_cas_d_disturbances_payload_masses}). The control objective of having a residual error of 20 nm RMS is shown by the horizontal black dashed line.
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_cas_d_disturbances_stiffnesses}Effect of floor motion $x_f$ and stage disturbances $f_t$}
#+attr_latex: :options {0.49\textwidth}
#+begin_subfigure
#+attr_latex: :width 0.95\linewidth
[[file:figs/uniaxial_cas_d_disturbances_stiffnesses.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_cas_d_disturbances_payload_masses}Effect of nano-hexapod stiffness $k_n$ and payload mass $m_s$}
#+attr_latex: :options {0.49\textwidth}
#+begin_subfigure
#+attr_latex: :width 0.95\linewidth
[[file:figs/uniaxial_cas_d_disturbances_payload_masses.png]]
#+end_subfigure
#+end_figure
** Conclusion
:PROPERTIES:
:UNNUMBERED: t
:END:
Open-loop residual vibrations of $d$ can be estimated from the low frequency value of the cumulative amplitude spectrum in Figure ref:fig:uniaxial_cas_d_disturbances_payload_masses.
This residual vibration of $d$ is found to be in the order of $100\,nm\,\text{RMS}$ for the stiff nano-hexapod ($k_n = 100\,N/\mu m$), $200\,nm\,\text{RMS}$ for the relatively stiff nano-hexapod ($k_n = 1\,N/\mu m$) and $1\,\mu m\,\text{RMS}$ for the soft nano-hexapod ($k_n = 0.01\,N/\mu m$).
From this analysis, it may be concluded that that the stiffer the nano-hexapod the better.
However, what is more important is the /closed-loop/ residual vibration of $d$ (i.e. while the feedback controller is used).
The goal is to have a closed-loop residual vibration $\epsilon_d \approx 20\,nm\,\text{RMS}$ (represented by an horizontal dashed black line in Figure ref:fig:uniaxial_cas_d_disturbances_payload_masses).
The bandwidth of the feedback controller leading to a closed-loop residual vibration of $20\,nm\,\text{RMS}$ can be estimated as the frequency where the cumulative amplitude spectrum crosses the black dashed line in Figure ref:fig:uniaxial_cas_d_disturbances_payload_masses.
# TODO - It would be important to link to a appendix where this is explained in more details, or add some references where this is explained
Closed loop bandwidth of $\approx 10\,\text{Hz}$ is found for the soft nano-hexapod ($k_n = 0.01\,N/\mu m$), $\approx 50\,\text{Hz}$ for the relatively stiff nano-hexapod ($k_n = 1\,N/\mu m$) and $\approx 100\,\text{Hz}$ for the stiff nano-hexapod ($k_n = 100\,N/\mu m$).
Therefore, while the /open-loop/ vibration is the lowest for the stiff nano-hexapod, it requires the largest feedback bandwidth to meet the specifications.
The advantage of the soft nano-hexapod can be explained by the natural isolation from the micro-station vibration above its suspension mode as shown in Figure ref:fig:uniaxial_sensitivity_disturbances_nano_hexapod_stiffnesses_ft.
* Active Damping
:PROPERTIES:
:HEADER-ARGS:matlab+: :tangle matlab/uniaxial_5_active_damping.m
:END:
<<sec:uniaxial_active_damping>>
** Introduction :ignore:
In this section, three active damping techniques are applied on the nano-hexapod (see Figure ref:fig:uniaxial_active_damping_strategies): Integral Force Feedback (IFF) cite:preumont91_activ, Relative Damping Control (RDC) [[cite:&preumont18_vibrat_contr_activ_struc_fourt_edition Chapter 7.2]] and Direct Velocity Feedback (DVF) cite:karnopp74_vibrat_contr_using_semi_activ_force_gener,serrand00_multic_feedb_contr_isolat_base_excit_vibrat,preumont02_force_feedb_versus_accel_feedb.
These damping strategies are first described (Section ref:ssec:uniaxial_active_damping_strategies) and are then compared in terms of achievable damping of the nano-hexapod mode (Section ref:ssec:uniaxial_active_damping_achievable_damping), reduction of the effect of disturbances (i.e. $x_f$, $f_t$ and $f_s$) on the displacement $d$ (Sections ref:ssec:uniaxial_active_damping_sensitivity_disturbances).
#+begin_src latex :file uniaxial_active_damping_strategies_iff.pdf :results file raw
\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.4} % Width of the dashed line for the displacement
\def\disph{0.3} % Height of the arrow for the displacements
\def\bracs{0.05} % Brace spacing vertically
\def\brach{-12pt} % Brace shift horizontaly
\def\fsensh{0.2} % Height of the force sensor
\def\velsize{0.2} % Size of the velocity sensor
% ====================
% IFF
\begin{scope}
% ====================
% Ground
% ====================
\draw (-0.5*\massw, 0) -- (0.5*\massw, 0);
\draw[dashed] (0.5*\massw, 0) -- ++(\dispw, 0);
\draw[->, color=colorpurple] (0.5*\massw+0.5*\dispw, 0) -- ++(0, 2*\disph) node[right, color=colorpurple]{$x_{f}$};
% ====================
% ====================
% Granite
\begin{scope}[shift={(0, 0)}]
% Mass
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m_{g}$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k_{g}$};
\draw[damper] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2]{$c_{g}$};
% 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]{Granite};
\end{scope}
% ====================
% ====================
% Stages
\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_{t}$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k_{t}$};
\draw[damper] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2]{$c_{t}$};
\draw[actuator={0.45}{0.2}{colorpurple}] ( 0.3*\massw, 0) -- (0.3*\massw, \spaceh) node[midway, right=0.1, color=colorpurple](ft){$f_{t}$};
% 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]{$T_y$/$R_y$/$R_z$};
\end{scope}
% ====================
% ====================
% Hexapod
\begin{scope}[shift={(0, 2*(\spaceh+\massh))}]
% Mass
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m_h$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k_h$};
\draw[damper] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2]{$c_h$};
% 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]{$\mu\text{-hexa}$};
\end{scope}
% ====================
% ====================
% NASS
\begin{scope}[shift={(0, 3*(\spaceh+\massh))}]
% Mass
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m_{n}$};
% Force Sensor
\node[forcesensor={\massw}{\fsensh}{colorblue}] (fsensn) at (0, \spaceh-\fsensh){};
\node[right, color=colorblue] (fn) at (fsensn.east) {$f_n$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh-\fsensh) node[midway, left=0.1]{$k_{n}$};
\draw[damper] (0, 0) -- ( 0, \spaceh-\fsensh) node[midway, left=0.2]{$c_{n}$};
\draw[actuator={0.4}{0.2}{black}] ( 0.3*\massw, 0) -- ( 0.3*\massw, \spaceh-\fsensh) node[midway, right=0.1](f){$f$};
% 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]{$\nu\text{-hexa}$};
\end{scope}
% ====================
% ====================
% sample
\begin{scope}[shift={(0, 4*(\spaceh+\massh))}]
% Mass
\draw[fill=white] (-0.3*\massw, 0) rectangle (0.3*\massw, \massh) node[pos=0.5]{$m_{s}$};
% External Force
\draw[->, color=colorpurple] (0, \massh) node[]{$\bullet$} -- ++(0, 0.5*\massh) node[right, color=colorpurple]{$f_s$};
\end{scope}
% ====================
% ====================
% IFF Control
\node[block={2em}{2em}, right=0.3 of fn, color=colorblue, fill=colorblue!10!white] (iff) {$K_{\text{IFF}}$};
\draw[->, draw=colorblue] (fn.east) -- (iff.west);
\draw[->, draw=colorblue] (iff.south) |- (f.east);
% ====================
\end{scope}
\end{tikzpicture}
#+end_src
#+begin_src latex :file uniaxial_active_damping_strategies_rdc.pdf :results file raw
\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.4} % Width of the dashed line for the displacement
\def\disph{0.3} % Height of the arrow for the displacements
\def\bracs{0.05} % Brace spacing vertically
\def\brach{-12pt} % Brace shift horizontaly
\def\fsensh{0.2} % Height of the force sensor
\def\velsize{0.2} % Size of the velocity sensor
% ====================
% RDC
\begin{scope}
% ====================
% Ground
% ====================
\draw (-0.5*\massw, 0) -- (0.5*\massw, 0);
\draw[dashed] (0.5*\massw, 0) -- ++(\dispw, 0);
\draw[->, color=colorpurple] (0.5*\massw+0.5*\dispw, 0) -- ++(0, 2*\disph) node[right, color=colorpurple]{$x_{f}$};
% ====================
% ====================
% Granite
\begin{scope}[shift={(0, 0)}]
% Mass
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m_{g}$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k_{g}$};
\draw[damper] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2]{$c_{g}$};
\end{scope}
% ====================
% ====================
% Stages
\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_{t}$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k_{t}$};
\draw[damper] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2]{$c_{t}$};
\draw[actuator={0.45}{0.2}{colorpurple}] ( 0.3*\massw, 0) -- (0.3*\massw, \spaceh) node[midway, right=0.1, color=colorpurple](ft){$f_{t}$};
\end{scope}
% ====================
% ====================
% Hexapod
\begin{scope}[shift={(0, 2*(\spaceh+\massh))}]
% Mass
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m_h$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k_h$};
\draw[damper] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2]{$c_h$};
\draw[dashed] (0.5*\massw, \spaceh+\massh) -- ++(2*\dispw, 0) coordinate(drbot);
\end{scope}
% ====================
% ====================
% NASS
\begin{scope}[shift={(0, 3*(\spaceh+\massh))}]
% Mass
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m_{n}$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k_{n}$};
\draw[damper] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2]{$c_{n}$};
\draw[actuator={0.4}{0.2}{black}] ( 0.3*\massw, 0) -- (0.3*\massw, \spaceh) node[midway, right=0.1](f){$f$};
\draw[dashed, draw=colorred] (0.5*\massw, \spaceh+\massh) -- ++(2*\dispw, 0) coordinate(drtop);
\end{scope}
% ====================
% ====================
% sample
\begin{scope}[shift={(0, 4*(\spaceh+\massh))}]
% Mass
\draw[fill=white] (-0.3*\massw, 0) rectangle (0.3*\massw, \massh) node[pos=0.5]{$m_{s}$};
% External Force
\draw[->, color=colorpurple] (0, \massh) node[]{$\bullet$} -- ++(0, 0.5*\massh) node[right, color=colorpurple]{$f_s$};
\end{scope}
% ====================
\draw[<->, dashed, draw=colorred] ($(drbot)+(-0.1, 0)$) -- ($(drtop)+(-0.1, 0)$) node[right, color=colorred](dr){$d\mathcal{L}$};
% ====================
% RDC Control
\node[block={2em}{2em}, below right=0.2 and -0.2 of dr, color=colorred, fill=colorred!10!white] (rdc) {$K_{\text{RDC}}$};
\draw[->, draw=colorred] (dr.east) -| (rdc.north);
\draw[->, draw=colorred] (rdc.south) |- (f.east);
% ====================
\end{scope}
\end{tikzpicture}
#+end_src
#+begin_src latex :file uniaxial_active_damping_strategies_dvf.pdf :results file raw
\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.4} % Width of the dashed line for the displacement
\def\disph{0.3} % Height of the arrow for the displacements
\def\bracs{0.05} % Brace spacing vertically
\def\brach{-12pt} % Brace shift horizontaly
\def\fsensh{0.2} % Height of the force sensor
\def\velsize{0.2} % Size of the velocity sensor
% ====================
% DVF
\begin{scope}
% ====================
% Ground
% ====================
\draw (-0.5*\massw, 0) -- (0.5*\massw, 0);
\draw[dashed] (0.5*\massw, 0) -- ++(\dispw, 0);
\draw[->, color=colorpurple] (0.5*\massw+0.5*\dispw, 0) -- ++(0, 2*\disph) node[right, color=colorpurple]{$x_{f}$};
% ====================
% ====================
% Marble
\begin{scope}[shift={(0, 0)}]
% Mass
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m_{g}$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k_{g}$};
\draw[damper] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2]{$c_{g}$};
\end{scope}
% ====================
% ====================
% Stages
\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_{t}$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k_{t}$};
\draw[damper] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2]{$c_{t}$};
\draw[actuator={0.45}{0.2}{colorpurple}] ( 0.3*\massw, 0) -- (0.3*\massw, \spaceh) node[midway, right=0.1, color=colorpurple](ft){$f_{t}$};
\end{scope}
% ====================
% ====================
% Hexapod
\begin{scope}[shift={(0, 2*(\spaceh+\massh))}]
% Mass
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m_{h}$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k_{h}$};
\draw[damper] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2]{$c_{h}$};
\end{scope}
% ====================
% ====================
% NASS
\begin{scope}[shift={(0, 3*(\spaceh+\massh))}]
% Mass
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m_{n}$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k_{n}$};
\draw[damper] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2]{$c_{n}$};
\draw[actuator={0.4}{0.2}{black}] ( 0.3*\massw, 0) -- (0.3*\massw, \spaceh) node[midway, right=0.1](f){$f$};
% Velocity Sensor
\node[inertialsensor={\velsize}{coloryellow}] (veln) at (0.5*\massw, \spaceh+\massh) {};
\node[right, color=coloryellow] (xn) at (veln.north east) {$v_n$};
\end{scope}
% ====================
% ====================
% sample
\begin{scope}[shift={(0, 4*(\spaceh+\massh))}]
% Mass
\draw[fill=white] (-0.3*\massw, 0) rectangle (0.3*\massw, \massh) node[pos=0.5]{$m_{s}$};
% External Force
\draw[->, color=colorpurple] (0, \massh) node[]{$\bullet$} -- ++(0, 0.5*\massh) node[right, color=colorpurple]{$f_s$};
\end{scope}
% ====================
% ====================
% DVF Control
\node[block={2em}{2em}, below right=0.4 and 0.1 of xn, color=coloryellow, fill=coloryellow!10!white] (ppf) {$K_{\text{DVF}}$};
\draw[->, draw=coloryellow] (xn.east) -| (ppf.north);
\draw[->, draw=coloryellow] (ppf.south) |- (f.east);
% ====================
\end{scope}
\end{tikzpicture}
#+end_src
#+name: fig:uniaxial_active_damping_strategies
#+caption: Three active damping strategies. Integral Force Feedback (\subref{fig:uniaxial_active_damping_strategies_iff}) using a force sensor, Relative Damping Control (\subref{fig:uniaxial_active_damping_strategies_rdc}) using a relative displacement sensor, and Direct Velocity Feedback (\subref{fig:uniaxial_active_damping_strategies_dvf}) using a geophone
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_active_damping_strategies_iff}IFF}
#+attr_latex: :options {0.37\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_active_damping_strategies_iff.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_active_damping_strategies_rdc}RDC}
#+attr_latex: :options {0.31\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_active_damping_strategies_rdc.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_active_damping_strategies_dvf}DVF}
#+attr_latex: :options {0.31\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_active_damping_strategies_dvf.png]]
#+end_subfigure
#+end_figure
** Matlab Init :noexport:ignore:
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
<<matlab-dir>>
#+end_src
#+begin_src matlab :exports none :results silent :noweb yes
<<matlab-init>>
#+end_src
#+begin_src matlab :tangle no :noweb yes
<<m-init-path>>
#+end_src
#+begin_src matlab :eval no :noweb yes
<<m-init-path-tangle>>
#+end_src
#+begin_src matlab :noweb yes
<<m-init-other>>
#+end_src
#+begin_src matlab
%% Frequency Vector [Hz]
freqs = logspace(0, 3, 1000);
#+end_src
#+begin_src matlab
%% Load the PSD of disturbances
load('uniaxial_disturbance_psd.mat', 'f', 'psd_ft', 'psd_xf');
#+end_src
#+begin_src matlab
%% Load Plants Dynamics
load('uniaxial_plants.mat', 'G_vc_light', 'G_md_light', 'G_pz_light', ...
'G_vc_mid', 'G_md_mid', 'G_pz_mid', ...
'G_vc_heavy', 'G_md_heavy', 'G_pz_heavy');
#+end_src
** Active Damping Strategies
<<ssec:uniaxial_active_damping_strategies>>
**** Integral Force Feedback (IFF)
The Integral Force Feedback strategy consists of using a force sensor in series with the actuator (see Figure ref:fig:uniaxial_active_damping_iff_schematic) and applying an "integral" feedback controller eqref:eq:uniaxial_iff_controller.
\begin{equation}\label{eq:uniaxial_iff_controller}
\boxed{K_{\text{IFF}}(s) = \frac{g}{s}}
\end{equation}
The mechanical equivalent of this IFF strategy is a dashpot in series with the actuator stiffness with a damping coefficient equal to the stiffness of the actuator divided by the controller gain $k/g$ (see Figure ref:fig:uniaxial_active_damping_iff_equiv).
#+begin_src latex :file uniaxial_active_damping_iff_schematic.pdf :results file raw
\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.4} % Width of the dashed line for the displacement
\def\disph{0.3} % Height of the arrow for the displacements
\def\bracs{0.05} % Brace spacing vertically
\def\brach{-12pt} % Brace shift horizontaly
\def\fsensh{0.2} % Height of the force sensor
\def\velsize{0.2} % Size of the velocity sensor
% ====================
\begin{scope}
% ====================
% Stage Below
\begin{scope}
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh);
\draw[spring] (-0.25*\massw, 0) -- (-0.25*\massw, \spaceh);
\draw[damper] ( 0.25*\massw, 0) -- ( 0.25*\massw, \spaceh);
\draw[decorate,decoration={zigzag,segment length=6pt},draw=black!50!white,very thick] (-0.5*\massw, 0) -- (0.5*\massw, 0);
\draw[draw=black!50!white,very thick, dashed] (-0.5*\massw, 0) -- ++(-0.5, 0);
\draw[draw=black!50!white,very thick, dashed] ( 0.5*\massw, 0) -- ++( 0.5, 0);
\end{scope}
% ====================
% ====================
% NASS
\begin{scope}[shift={(0, \spaceh+\massh)}]
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m$};
\node[forcesensor={\massw}{\fsensh}{colorblue}] (fsensn) at (0, \spaceh-\fsensh){};
\node[right, color=colorblue] (fn) at (fsensn.east) {$f_m$};
\draw[spring] (-0.25*\massw, 0) -- (-0.25*\massw, \spaceh-\fsensh) node[midway, left=0.1]{$k$};
\draw[actuator={0.4}{0.2}{black}] ( 0.25*\massw, 0) -- (0.25*\massw, \spaceh-\fsensh) coordinate[midway, shift={(0.1,0)}](f);
\end{scope}
% ====================
% ====================
% Stage Above
\begin{scope}[shift={(0, 2*(\spaceh+\massh))}]
\draw[spring] (-0.25*\massw, 0) -- (-0.25*\massw, \spaceh);
\draw[damper] ( 0.25*\massw, 0) -- ( 0.25*\massw, \spaceh);
\draw[decorate,decoration={zigzag,segment length=6pt},draw=black!50!white,very thick] (-0.5*\massw, \spaceh) -- (0.5*\massw, \spaceh);
\draw[draw=black!50!white,very thick, dashed] (-0.5*\massw, \spaceh) -- ++(-0.5, 0);
\draw[draw=black!50!white,very thick, dashed] ( 0.5*\massw, \spaceh) -- ++( 0.5, 0);
\end{scope}
% ====================
% ====================
% IFF Control
\node[block={2em}{2em}, right=1.0 of f, color=colorblue, fill=colorblue!10!white] (iff) {$g/s$};
\draw[->, draw=colorblue] (fn.east) -- ++(1.0, 0) |- (iff.east);
\draw[->, draw=colorblue] (iff.west) -- (f.east) node[above right, color=colorblue]{$f$};
% ====================
\end{scope}
\end{tikzpicture}
#+end_src
#+begin_src latex :file uniaxial_active_damping_iff_equiv.pdf :results file raw
\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.4} % Width of the dashed line for the displacement
\def\disph{0.3} % Height of the arrow for the displacements
\def\bracs{0.05} % Brace spacing vertically
\def\brach{-12pt} % Brace shift horizontaly
\def\fsensh{0.2} % Height of the force sensor
\def\velsize{0.2} % Size of the velocity sensor
% ====================
\begin{scope}[shift={(6, 0)}]
% ====================
% Stage Below
\begin{scope}
\draw[fill=white] (-0.5*\massw, 0.8*\spaceh) rectangle (0.5*\massw, 0.8*\spaceh+\massh);
\draw[spring] (-0.25*\massw, 0) -- (-0.25*\massw, 0.8*\spaceh);
\draw[damper] ( 0.25*\massw, 0) -- ( 0.25*\massw, 0.8*\spaceh);
\draw[decorate,decoration={zigzag,segment length=6pt},draw=black!50!white,very thick] (-0.5*\massw, 0) -- (0.5*\massw, 0);
\draw[draw=black!50!white,very thick, dashed] (-0.5*\massw, 0) -- ++(-0.5, 0);
\draw[draw=black!50!white,very thick, dashed] ( 0.5*\massw, 0) -- ++( 0.5, 0);
\end{scope}
% ====================
% ====================
% NASS
\begin{scope}[shift={(0, 0.8*\spaceh+\massh)}]
\draw[fill=white] (-0.5*\massw, 1.4*\spaceh) rectangle (0.5*\massw, 1.4*\spaceh+\massh) node[pos=0.5]{$m$};
\draw[spring] (0, 0) -- node[midway, left=0.1]{$k$} (0, 0.8*\spaceh);
\draw[damper={colorblue}{}{}] (0, 0.8*\spaceh) node[branch]{} -- (0, 1.4*\spaceh) node[midway, left=0.2, color=colorblue]{$k/g$};
\end{scope}
% ====================
% ====================
% Stage Above
\begin{scope}[shift={(0, 0.8*\spaceh+\massh+1.4*\spaceh+\massh)}]
\draw[spring] (-0.25*\massw, 0) -- (-0.25*\massw, 0.8*\spaceh);
\draw[damper] ( 0.25*\massw, 0) -- ( 0.25*\massw, 0.8*\spaceh);
\draw[decorate,decoration={zigzag,segment length=6pt},draw=black!50!white,very thick] (-0.5*\massw, 0.8*\spaceh) -- (0.5*\massw, 0.8*\spaceh);
\draw[draw=black!50!white,very thick, dashed] (-0.5*\massw, 0.8*\spaceh) -- ++(-0.5, 0);
\draw[draw=black!50!white,very thick, dashed] ( 0.5*\massw, 0.8*\spaceh) -- ++( 0.5, 0);
\end{scope}
% ====================
\end{scope}
% % Equiv
% \draw[double, <->, draw=colorblue, double distance=1.5] (3.0, 1.5*\spaceh+\massh) -- ++(1.5,0);
\end{tikzpicture}
#+end_src
#+name: fig:uniaxial_active_damping_iff
#+caption: Integral Force Feedback (\subref{fig:uniaxial_active_damping_iff_schematic}) is equivalent to a damper in series with the actuators stiffness (\subref{fig:uniaxial_active_damping_iff_equiv})
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_active_damping_iff_schematic}Integral Force Feedback}
#+attr_latex: :options {0.49\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_active_damping_iff_schematic.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_active_damping_iff_equiv}Equivalent mechanical representation}
#+attr_latex: :options {0.49\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_active_damping_iff_equiv.png]]
#+end_subfigure
#+end_figure
**** Relative Damping Control (RDC)
For the Relative Damping Control strategy, a relative motion sensor that measures the motion of the actuator is used (see Figure ref:fig:uniaxial_active_damping_rdc_schematic) and a "derivative" feedback controller is used eqref:eq:uniaxial_rdc_controller.
\begin{equation}\label{eq:uniaxial_rdc_controller}
\boxed{K_{\text{RDC}}(s) = - g \cdot s}
\end{equation}
The mechanical equivalent of RDC is a dashpot in parallel with the actuator with a damping coefficient equal to the controller gain $g$ (see Figure ref:fig:uniaxial_active_damping_rdc_equiv).
#+begin_src latex :file uniaxial_active_damping_rdc_schematic.pdf
\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.4} % Width of the dashed line for the displacement
\def\disph{0.3} % Height of the arrow for the displacements
\def\bracs{0.05} % Brace spacing vertically
\def\brach{-12pt} % Brace shift horizontaly
\def\fsensh{0.2} % Height of the force sensor
\def\velsize{0.2} % Size of the velocity sensor
% ====================
\begin{scope}
% ====================
% Stage Below
\begin{scope}
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh);
\draw[spring] (-0.25*\massw, 0) -- (-0.25*\massw, \spaceh);
\draw[damper] ( 0.25*\massw, 0) -- ( 0.25*\massw, \spaceh);
\draw[dashed, draw=colorred] (0.5*\massw, \spaceh+\massh) -- ++(1*\dispw, 0) coordinate(drbot);
\draw[decorate,decoration={zigzag,segment length=6pt},draw=black!50!white,very thick] (-0.5*\massw, 0) -- (0.5*\massw, 0);
\draw[draw=black!50!white,very thick, dashed] (-0.5*\massw, 0) -- ++(-0.5, 0);
\draw[draw=black!50!white,very thick, dashed] ( 0.5*\massw, 0) -- ++( 0.5, 0);
\end{scope}
% ====================
% ====================
% NASS
\begin{scope}[shift={(0, \spaceh+\massh)}]
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m$};
\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$};
\draw[actuator={0.4}{0.2}{black}] ( 0.3*\massw, 0) -- (0.3*\massw, \spaceh) coordinate[midway, shift={(0.1,0)}](f);
\draw[dashed, draw=colorred] (0.5*\massw, \spaceh+\massh) -- ++(1*\dispw, 0) coordinate(drtop);
\end{scope}
% ====================
% ====================
% Stage Above
\begin{scope}[shift={(0, 2*(\spaceh+\massh))}]
\draw[spring] (-0.25*\massw, 0) -- (-0.25*\massw, \spaceh);
\draw[damper] ( 0.25*\massw, 0) -- ( 0.25*\massw, \spaceh);
\draw[decorate,decoration={zigzag,segment length=6pt},draw=black!50!white,very thick] (-0.5*\massw, \spaceh) -- (0.5*\massw, \spaceh);
\draw[draw=black!50!white,very thick, dashed] (-0.5*\massw, \spaceh) -- ++(-0.5, 0);
\draw[draw=black!50!white,very thick, dashed] ( 0.5*\massw, \spaceh) -- ++( 0.5, 0);
\end{scope}
% ====================
\draw[<->, dashed, draw=colorred] ($(drbot)+(-0.1, 0)$) -- ($(drtop)+(-0.1, 0)$) node[right, color=colorred](dr){$d\mathcal{L}$};
% ====================
% RDC Control
\node[block={2em}{2em}, below right=0.2 and -0.3 of dr, color=colorred, fill=colorred!10!white] (rdc) {$-g \cdot s$};
\draw[->, draw=colorred] (dr.east) -| (rdc.north);
\draw[->, draw=colorred] (rdc.south) |- (f.east) node[above right, color=colorred]{$f$};
% ====================
\end{scope}
\end{tikzpicture}
#+end_src
#+begin_src latex :file uniaxial_active_damping_rdc_equiv.pdf
\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.4} % Width of the dashed line for the displacement
\def\disph{0.3} % Height of the arrow for the displacements
\def\bracs{0.05} % Brace spacing vertically
\def\brach{-12pt} % Brace shift horizontaly
\def\fsensh{0.2} % Height of the force sensor
\def\velsize{0.2} % Size of the velocity sensor
% ====================
\begin{scope}
% ====================
% Stage Below
\begin{scope}
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh);
\draw[spring] (-0.25*\massw, 0) -- (-0.25*\massw, \spaceh);
\draw[damper] ( 0.25*\massw, 0) -- ( 0.25*\massw, \spaceh);
\draw[decorate,decoration={zigzag,segment length=6pt},draw=black!50!white,very thick] (-0.5*\massw, 0) -- (0.5*\massw, 0);
\draw[draw=black!50!white,very thick, dashed] (-0.5*\massw, 0) -- ++(-0.5, 0);
\draw[draw=black!50!white,very thick, dashed] ( 0.5*\massw, 0) -- ++( 0.5, 0);
\end{scope}
% ====================
% ====================
% NASS
\begin{scope}[shift={(0, \spaceh+\massh)}]
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m$};
\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$};
\draw[damper={colorred}{}{}] ( 0.4*\massw, 0) -- ( 0.4*\massw, \spaceh) node[midway, left=0.15, color=colorred]{$g$};
\end{scope}
% ====================
% ====================
% Stage Above
\begin{scope}[shift={(0, 2*(\spaceh+\massh))}]
\draw[spring] (-0.25*\massw, 0) -- (-0.25*\massw, \spaceh);
\draw[damper] ( 0.25*\massw, 0) -- ( 0.25*\massw, \spaceh);
\draw[decorate,decoration={zigzag,segment length=6pt},draw=black!50!white,very thick] (-0.5*\massw, \spaceh) -- (0.5*\massw, \spaceh);
\draw[draw=black!50!white,very thick, dashed] (-0.5*\massw, \spaceh) -- ++(-0.5, 0);
\draw[draw=black!50!white,very thick, dashed] ( 0.5*\massw, \spaceh) -- ++( 0.5, 0);
\end{scope}
% ====================
\end{scope}
% % Equiv
% \draw[double, <->, draw=colorred, double distance=1.5] (3.0, 1.5*\spaceh+\massh) -- ++(1.5,0);
\end{tikzpicture}
#+end_src
#+name: fig:uniaxial_active_damping_rdc
#+caption: Relative Damping Control (\subref{fig:uniaxial_active_damping_rdc_schematic}) is equivalent to damper in parallel with the actuator (\subref{fig:uniaxial_active_damping_rdc_equiv})
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_active_damping_rdc_schematic}Relative motion control}
#+attr_latex: :options {0.49\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_active_damping_rdc_schematic.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_active_damping_rdc_equiv}Equivalent mechanical representation}
#+attr_latex: :options {0.49\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_active_damping_rdc_equiv.png]]
#+end_subfigure
#+end_figure
**** Direct Velocity Feedback (DVF)
Finally, the Direct Velocity Feedback strategy consists of using an inertial sensor (usually a geophone) that measures the "absolute" velocity of the body fixed on top of the actuator (see Figure ref:fig:uniaxial_active_damping_dvf_schematic).
This velocity is fed back to the actuator with a "proportional" controller eqref:eq:uniaxial_dvf_controller.
\begin{equation}\label{eq:uniaxial_dvf_controller}
\boxed{K_{\text{DVF}}(s) = - g}
\end{equation}
This is equivalent to a dashpot (with a damping coefficient equal to the controller gain $g$) between the body (on which the inertial sensor is fixed) and an inertial reference frame (see Figure ref:fig:uniaxial_active_damping_dvf_equiv).
This is usually refers to as "/sky hook damper/".
#+begin_src latex :file uniaxial_active_damping_dvf_schematic.pdf
\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.4} % Width of the dashed line for the displacement
\def\disph{0.3} % Height of the arrow for the displacements
\def\bracs{0.05} % Brace spacing vertically
\def\brach{-12pt} % Brace shift horizontaly
\def\fsensh{0.2} % Height of the force sensor
\def\velsize{0.2} % Size of the velocity sensor
% ====================
\begin{scope}
% ====================
% Stage Below
\begin{scope}
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh);
\draw[spring] (-0.25*\massw, 0) -- (-0.25*\massw, \spaceh);
\draw[damper] ( 0.25*\massw, 0) -- ( 0.25*\massw, \spaceh);
\draw[decorate,decoration={zigzag,segment length=6pt},draw=black!50!white,very thick] (-0.5*\massw, 0) -- (0.5*\massw, 0);
\draw[draw=black!50!white,very thick, dashed] (-0.5*\massw, 0) -- ++(-0.5, 0);
\draw[draw=black!50!white,very thick, dashed] ( 0.5*\massw, 0) -- ++( 0.5, 0);
\end{scope}
% ====================
% ====================
% NASS
\begin{scope}[shift={(0, \spaceh+\massh)}]
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m$};
\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$};
\draw[actuator={0.4}{0.2}{black}] ( 0.3*\massw, 0) -- (0.3*\massw, \spaceh) coordinate[midway, shift={(0.1,0)}](f);
% Velocity Sensor
\node[inertialsensor={\velsize}{coloryellow}] (veln) at (0.5*\massw, \spaceh+\massh) {};
\end{scope}
% ====================
% ====================
% Stage Above
\begin{scope}[shift={(0, 2*(\spaceh+\massh))}]
\draw[spring] (-0.25*\massw, 0) -- (-0.25*\massw, \spaceh);
\draw[damper] ( 0.25*\massw, 0) -- ( 0.25*\massw, \spaceh);
\draw[decorate,decoration={zigzag,segment length=6pt},draw=black!50!white,very thick] (-0.5*\massw, \spaceh) -- (0.5*\massw, \spaceh);
\draw[draw=black!50!white,very thick, dashed] (-0.5*\massw, \spaceh) -- ++(-0.5, 0);
\draw[draw=black!50!white,very thick, dashed] ( 0.5*\massw, \spaceh) -- ++( 0.5, 0);
\end{scope}
% ====================
% ====================
% DVF Control
\node[block={2em}{2em}, below right=0.3 and 0.4 of veln, color=coloryellow, fill=coloryellow!10!white] (ppf) {$-g$};
\draw[->, draw=coloryellow] (veln.east) node[above right, color=coloryellow]{$v$} -| (ppf.north);
\draw[->, draw=coloryellow] (ppf.south) |- (f.east) node[above right, color=coloryellow]{$f$};
% ====================
\end{scope}
\end{tikzpicture}
#+end_src
#+begin_src latex :file uniaxial_active_damping_dvf_equiv.pdf
\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.4} % Width of the dashed line for the displacement
\def\disph{0.3} % Height of the arrow for the displacements
\def\bracs{0.05} % Brace spacing vertically
\def\brach{-12pt} % Brace shift horizontaly
\def\fsensh{0.2} % Height of the force sensor
\def\velsize{0.2} % Size of the velocity sensor
% ====================
\begin{scope}
% ====================
% Stage Below
\begin{scope}
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh);
\draw[spring] (-0.25*\massw, 0) -- (-0.25*\massw, \spaceh);
\draw[damper] ( 0.25*\massw, 0) -- ( 0.25*\massw, \spaceh);
\draw[decorate,decoration={zigzag,segment length=6pt},draw=black!50!white,very thick] (-0.5*\massw, 0) -- (0.5*\massw, 0);
\draw[draw=black!50!white,very thick, dashed] (-0.5*\massw, 0) -- ++(-0.5, 0);
\draw[draw=black!50!white,very thick, dashed] ( 0.5*\massw, 0) -- ++( 0.5, 0);
\end{scope}
% ====================
% ====================
% NASS
\begin{scope}[shift={(0, \spaceh+\massh)}]
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m$};
\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$};
\draw[damper={coloryellow}{}{}] ( 0.8*\massw, \massh) -- ( 0.8*\massw, \massh+\spaceh)node[midway, left=0.2, color=coloryellow]{$g$};
\draw[draw=coloryellow] (0.5*\massw, \massh+\spaceh) -- ( 0.8*\massw, \massh+\spaceh);
\node[mground={0.5}{0.3}{coloryellow}] at (0.8*\massw, \massh);
\end{scope}
% ====================
% ====================
% Stage Above
\begin{scope}[shift={(0, 2*(\spaceh+\massh))}]
\draw[spring] (-0.25*\massw, 0) -- (-0.25*\massw, \spaceh);
\draw[damper] ( 0.25*\massw, 0) -- ( 0.25*\massw, \spaceh);
\draw[decorate,decoration={zigzag,segment length=6pt},draw=black!50!white,very thick] (-0.5*\massw, \spaceh) -- (0.5*\massw, \spaceh);
\draw[draw=black!50!white,very thick, dashed] (-0.5*\massw, \spaceh) -- ++(-0.5, 0);
\draw[draw=black!50!white,very thick, dashed] ( 0.5*\massw, \spaceh) -- ++( 0.5, 0);
\end{scope}
% ====================
\end{scope}
% % Equiv
% \draw[double, <->, draw=coloryellow, double distance=1.5] (2.5, 1.5*\spaceh+\massh) -- ++(1.5,0);
\end{tikzpicture}
#+end_src
#+name: fig:uniaxial_active_damping_dvf
#+caption: Direct velocity Feedback (\subref{fig:uniaxial_active_damping_dvf_schematic}) is equivalent to a "sky hook damper" (\subref{fig:uniaxial_active_damping_dvf_equiv})
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_active_damping_dvf_schematic}Direct velocity feedback}
#+attr_latex: :options {0.49\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_active_damping_dvf_schematic.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_active_damping_dvf_equiv}Equivalent mechanical representation}
#+attr_latex: :options {0.49\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_active_damping_dvf_equiv.png]]
#+end_subfigure
#+end_figure
** Plant Dynamics for Active Damping
<<ssec:uniaxial_active_damping_plants>>
The plant dynamics for all three active damping techniques are shown in Figure ref:fig:uniaxial_plant_active_damping_techniques.
All have /alternating poles and zeros/ meaning that the phase do not vary by more than $180\,\text{deg}$ which makes the design of a /robust/ damping controller very easy.
This alternating poles and zeros property is guaranteed for the IFF and RDC cases because the sensors are collocated with the actuator [[cite:&preumont18_vibrat_contr_activ_struc_fourt_edition Chapter 7]].
For the DVF controller, this property is not guaranteed, and may be lost if some flexibility between the nano-hexapod and the sample is considered [[cite:&preumont18_vibrat_contr_activ_struc_fourt_edition Chapter 8.4]].
When the nano-hexapod's suspension modes are at lower frequencies than the resonances of the micro-station (blue and red curves in Figure ref:fig:uniaxial_plant_active_damping_techniques), the resonances of the micro-stations have little impact on the IFF and DVF transfer functions.
For the stiff nano-hexapod (yellow curves), the micro-station dynamics can be seen on the transfer functions in Figure ref:fig:uniaxial_plant_active_damping_techniques.
Therefore, it is expected that the micro-station dynamics might impact the achievable damping if a stiff nano-hexapod is used.
#+begin_src matlab :exports none :results none
%% Damped plants for three considered payload masses - Comparison of active damping techniques
% Integral Force Feedback
figure;
tiledlayout(3, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
ax1 = nexttile([2,1]);
hold on;
plot(freqs, abs(squeeze(freqresp(G_vc_light('fm', 'f'), freqs, 'Hz'))), '-', 'color', colors(1,:), 'DisplayName', '$m_s = 1\,kg$');
plot(freqs, abs(squeeze(freqresp(G_vc_mid( 'fm', 'f'), freqs, 'Hz'))), '-.', 'color', colors(1,:), 'DisplayName', '$m_s = 25\,kg$');
plot(freqs, abs(squeeze(freqresp(G_vc_heavy('fm', 'f'), freqs, 'Hz'))), '--', 'color', colors(1,:), 'DisplayName', '$m_s = 50\,kg$');
plot(freqs, abs(squeeze(freqresp(G_md_light('fm', 'f'), freqs, 'Hz'))), '-', 'color', colors(2,:), 'HandleVisibility', 'off');
plot(freqs, abs(squeeze(freqresp(G_md_mid( 'fm', 'f'), freqs, 'Hz'))), '-.', 'color', colors(2,:), 'HandleVisibility', 'off');
plot(freqs, abs(squeeze(freqresp(G_md_heavy('fm', 'f'), freqs, 'Hz'))), '--', 'color', colors(2,:), 'HandleVisibility', 'off');
plot(freqs, abs(squeeze(freqresp(G_pz_light('fm', 'f'), freqs, 'Hz'))), '-', 'color', colors(3,:), 'HandleVisibility', 'off');
plot(freqs, abs(squeeze(freqresp(G_pz_mid( 'fm', 'f'), freqs, 'Hz'))), '-.', 'color', colors(3,:), 'HandleVisibility', 'off');
plot(freqs, abs(squeeze(freqresp(G_pz_heavy('fm', 'f'), freqs, 'Hz'))), '--', 'color', colors(3,:), 'HandleVisibility', 'off');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [N/N]'); set(gca, 'XTickLabel',[]);
ldg = legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 1);
ldg.ItemTokenSize = [20, 1];
ax1b = nexttile();
hold on;
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_vc_light('fm', 'f'), freqs, 'Hz')))), '-', 'color', colors(1,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_vc_mid( 'fm', 'f'), freqs, 'Hz')))), '-.', 'color', colors(1,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_vc_heavy('fm', 'f'), freqs, 'Hz')))), '--', 'color', colors(1,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_md_light('fm', 'f'), freqs, 'Hz')))), '-', 'color', colors(2,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_md_mid( 'fm', 'f'), freqs, 'Hz')))), '-.', 'color', colors(2,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_md_heavy('fm', 'f'), freqs, 'Hz')))), '--', 'color', colors(2,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_pz_light('fm', 'f'), freqs, 'Hz')))), '-', 'color', colors(3,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_pz_mid( 'fm', 'f'), freqs, 'Hz')))), '-.', 'color', colors(3,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_pz_heavy('fm', 'f'), freqs, 'Hz')))), '--', 'color', colors(3,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
xticks([1e0, 1e1, 1e2]);
yticks(-360:90:360);
ylim([-200, 20]);
linkaxes([ax1,ax1b],'x');
xlim([1, 1000]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_plant_active_damping_techniques_iff.pdf', 'width', 'third', 'height', 'tall');
#+end_src
#+begin_src matlab :exports none :results none
% Relative Motion Control
figure;
tiledlayout(3, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
ax2 = nexttile([2,1]);
hold on;
plot(freqs, abs(squeeze(freqresp(G_vc_light('dL', 'f'), freqs, 'Hz'))), '-', 'color', colors(1,:));
plot(freqs, abs(squeeze(freqresp(G_vc_mid( 'dL', 'f'), freqs, 'Hz'))), '-.', 'color', colors(1,:));
plot(freqs, abs(squeeze(freqresp(G_vc_heavy('dL', 'f'), freqs, 'Hz'))), '--', 'color', colors(1,:));
plot(freqs, abs(squeeze(freqresp(G_md_light('dL', 'f'), freqs, 'Hz'))), '-', 'color', colors(2,:));
plot(freqs, abs(squeeze(freqresp(G_md_mid( 'dL', 'f'), freqs, 'Hz'))), '-.', 'color', colors(2,:));
plot(freqs, abs(squeeze(freqresp(G_md_heavy('dL', 'f'), freqs, 'Hz'))), '--', 'color', colors(2,:));
plot(freqs, abs(squeeze(freqresp(G_pz_light('dL', 'f'), freqs, 'Hz'))), '-', 'color', colors(3,:));
plot(freqs, abs(squeeze(freqresp(G_pz_mid( 'dL', 'f'), freqs, 'Hz'))), '-.', 'color', colors(3,:));
plot(freqs, abs(squeeze(freqresp(G_pz_heavy('dL', 'f'), freqs, 'Hz'))), '--', 'color', colors(3,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
ax2b = nexttile();
hold on;
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_vc_light('dL', 'f'), freqs, 'Hz')))), '-', 'color', colors(1,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_vc_mid( 'dL', 'f'), freqs, 'Hz')))), '-.', 'color', colors(1,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_vc_heavy('dL', 'f'), freqs, 'Hz')))), '--', 'color', colors(1,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_md_light('dL', 'f'), freqs, 'Hz')))), '-', 'color', colors(2,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_md_mid( 'dL', 'f'), freqs, 'Hz')))), '-.', 'color', colors(2,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_md_heavy('dL', 'f'), freqs, 'Hz')))), '--', 'color', colors(2,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_pz_light('dL', 'f'), freqs, 'Hz')))), '-', 'color', colors(3,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_pz_mid( 'dL', 'f'), freqs, 'Hz')))), '-.', 'color', colors(3,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_pz_heavy('dL', 'f'), freqs, 'Hz')))), '--', 'color', colors(3,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
xticks([1e0, 1e1, 1e2]);
yticks(-360:90:360);
ylim([-200, 20]);
linkaxes([ax2,ax2b],'x');
xlim([1, 1000]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_plant_active_damping_techniques_rdc.pdf', 'width', 'third', 'height', 'tall');
#+end_src
#+begin_src matlab :exports none :results none
% Direct Velocity Feedback
figure;
tiledlayout(3, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
ax3 = nexttile([2,1]);
hold on;
plot(freqs, abs(squeeze(freqresp(G_vc_light('vn', 'f'), freqs, 'Hz'))), '-', 'color', colors(1,:), 'DisplayName', '$k_n = 0.01\,N/\mu m$');
plot(freqs, abs(squeeze(freqresp(G_vc_mid( 'vn', 'f'), freqs, 'Hz'))), '-.', 'color', colors(1,:), 'HandleVisibility', 'off');
plot(freqs, abs(squeeze(freqresp(G_vc_heavy('vn', 'f'), freqs, 'Hz'))), '--', 'color', colors(1,:), 'HandleVisibility', 'off');
plot(freqs, abs(squeeze(freqresp(G_md_light('vn', 'f'), freqs, 'Hz'))), '-', 'color', colors(2,:), 'DisplayName', '$k_n = 1\,N/\mu m$');
plot(freqs, abs(squeeze(freqresp(G_md_mid( 'vn', 'f'), freqs, 'Hz'))), '-.', 'color', colors(2,:), 'HandleVisibility', 'off');
plot(freqs, abs(squeeze(freqresp(G_md_heavy('vn', 'f'), freqs, 'Hz'))), '--', 'color', colors(2,:), 'HandleVisibility', 'off');
plot(freqs, abs(squeeze(freqresp(G_pz_light('vn', 'f'), freqs, 'Hz'))), '-', 'color', colors(3,:), 'DisplayName', '$k_n = 100\,N/\mu m$');
plot(freqs, abs(squeeze(freqresp(G_pz_mid( 'vn', 'f'), freqs, 'Hz'))), '-.', 'color', colors(3,:), 'HandleVisibility', 'off');
plot(freqs, abs(squeeze(freqresp(G_pz_heavy('vn', 'f'), freqs, 'Hz'))), '--', 'color', colors(3,:), 'HandleVisibility', 'off');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/s/N]'); set(gca, 'XTickLabel',[]);
ldg = legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 1);
ldg.ItemTokenSize = [20, 1];
ax3b = nexttile();
hold on;
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_vc_light('vn', 'f'), freqs, 'Hz')))), '-', 'color', colors(1,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_vc_mid( 'vn', 'f'), freqs, 'Hz')))), '-.', 'color', colors(1,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_vc_heavy('vn', 'f'), freqs, 'Hz')))), '--', 'color', colors(1,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_md_light('vn', 'f'), freqs, 'Hz')))), '-', 'color', colors(2,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_md_mid( 'vn', 'f'), freqs, 'Hz')))), '-.', 'color', colors(2,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_md_heavy('vn', 'f'), freqs, 'Hz')))), '--', 'color', colors(2,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_pz_light('vn', 'f'), freqs, 'Hz')))), '-', 'color', colors(3,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_pz_mid( 'vn', 'f'), freqs, 'Hz')))), '-.', 'color', colors(3,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_pz_heavy('vn', 'f'), freqs, 'Hz')))), '--', 'color', colors(3,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
xticks([1e0, 1e1, 1e2]);
yticks(-360:90:360);
ylim([-110, 110]);
linkaxes([ax3,ax3b],'x');
xlim([1, 1000]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_plant_active_damping_techniques_dvf.pdf', 'width', 'third', 'height', 'tall');
#+end_src
#+name: fig:uniaxial_plant_active_damping_techniques
#+caption: Plant dynamics for the three active damping techniques (IFF: \subref{fig:uniaxial_plant_active_damping_techniques_iff}, RDC: \subref{fig:uniaxial_plant_active_damping_techniques_rdc}, DVF: \subref{fig:uniaxial_plant_active_damping_techniques_dvf}), for three nano-hexapod stiffnesses ($k_n = 0.01\,N/\mu m$ in blue, $k_n = 1\,N/\mu m$ in red and $k_n = 100\,N/\mu m$ in yellow) and three sample's masses ($m_s = 1\,kg$: solid curves, $m_s = 25\,kg$: dot-dashed curves, and $m_s = 50\,kg$: dashed curves).
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_plant_active_damping_techniques_iff}IFF}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :width 0.99\linewidth
[[file:figs/uniaxial_plant_active_damping_techniques_iff.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_plant_active_damping_techniques_rdc}RDC}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :width 0.99\linewidth
[[file:figs/uniaxial_plant_active_damping_techniques_rdc.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_plant_active_damping_techniques_dvf}DVF}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :width 0.99\linewidth
[[file:figs/uniaxial_plant_active_damping_techniques_dvf.png]]
#+end_subfigure
#+end_figure
** Active Damping Controller Optimization and Damped plants :noexport:
#+begin_src matlab :exports none
%% Design of Active Damping controllers to have reasonable damping
% IFF
K_iff_vc = 20/(s + 2*pi*0.01);
K_iff_vc.InputName = {'fm'};
K_iff_vc.OutputName = {'f'};
K_iff_md = 200/(s + 2*pi*0.01);
K_iff_md.InputName = {'fm'};
K_iff_md.OutputName = {'f'};
K_iff_pz = 4000/(s + 2*pi*0.01);
K_iff_pz.InputName = {'fm'};
K_iff_pz.OutputName = {'f'};
% RDC
K_rdc_vc = -1e3*s;
K_rdc_vc.InputName = {'dL'};
K_rdc_vc.OutputName = {'f'};
K_rdc_md = -1e4*s;
K_rdc_md.InputName = {'dL'};
K_rdc_md.OutputName = {'f'};
K_rdc_pz = -1e5*s;
K_rdc_pz.InputName = {'dL'};
K_rdc_pz.OutputName = {'f'};
% DVF
K_dvf_vc = -tf(1e3);
K_dvf_vc.InputName = {'vn'};
K_dvf_vc.OutputName = {'f'};
K_dvf_md = -tf(8e3);
K_dvf_md.InputName = {'vn'};
K_dvf_md.OutputName = {'f'};
K_dvf_pz = -tf(2e5);
K_dvf_pz.InputName = {'vn'};
K_dvf_pz.OutputName = {'f'};
#+end_src
#+begin_src matlab :exports none :tangle no
%% Save Active Damping Controllers
save('./matlab/mat/uniaxial_active_damping_controllers.mat', 'K_iff_vc', 'K_iff_md', 'K_iff_pz', ...
'K_rdc_vc', 'K_rdc_md', 'K_rdc_pz', ...
'K_dvf_vc', 'K_dvf_md', 'K_dvf_pz');
#+end_src
#+begin_src matlab :exports none :eval no
%% Save Active Damping Controller
save('./mat/uniaxial_active_damping_controllers.mat', 'K_iff_vc', 'K_iff_md', 'K_iff_pz', ...
'K_rdc_vc', 'K_rdc_md', 'K_rdc_pz', ...
'K_dvf_vc', 'K_dvf_md', 'K_dvf_pz');
#+end_src
#+begin_src matlab :exports none
%% Compute Damped Plants
% IFF
G_iff_vc_light = feedback(G_vc_light, K_iff_vc, 'name', +1);
G_iff_vc_mid = feedback(G_vc_mid , K_iff_vc, 'name', +1);
G_iff_vc_heavy = feedback(G_vc_heavy, K_iff_vc, 'name', +1);
G_iff_md_light = feedback(G_md_light, K_iff_md, 'name', +1);
G_iff_md_mid = feedback(G_md_mid , K_iff_md, 'name', +1);
G_iff_md_heavy = feedback(G_md_heavy, K_iff_md, 'name', +1);
G_iff_pz_light = feedback(G_pz_light, K_iff_pz, 'name', +1);
G_iff_pz_mid = feedback(G_pz_mid , K_iff_pz, 'name', +1);
G_iff_pz_heavy = feedback(G_pz_heavy, K_iff_pz, 'name', +1);
% RDC
G_rdc_vc_light = feedback(G_vc_light, K_rdc_vc, 'name', +1);
G_rdc_vc_mid = feedback(G_vc_mid , K_rdc_vc, 'name', +1);
G_rdc_vc_heavy = feedback(G_vc_heavy, K_rdc_vc, 'name', +1);
G_rdc_md_light = feedback(G_md_light, K_rdc_md, 'name', +1);
G_rdc_md_mid = feedback(G_md_mid , K_rdc_md, 'name', +1);
G_rdc_md_heavy = feedback(G_md_heavy, K_rdc_md, 'name', +1);
G_rdc_pz_light = feedback(G_pz_light, K_rdc_pz, 'name', +1);
G_rdc_pz_mid = feedback(G_pz_mid , K_rdc_pz, 'name', +1);
G_rdc_pz_heavy = feedback(G_pz_heavy, K_rdc_pz, 'name', +1);
% DVF
G_dvf_vc_light = feedback(G_vc_light, K_dvf_vc, 'name', +1);
G_dvf_vc_mid = feedback(G_vc_mid , K_dvf_vc, 'name', +1);
G_dvf_vc_heavy = feedback(G_vc_heavy, K_dvf_vc, 'name', +1);
G_dvf_md_light = feedback(G_md_light, K_dvf_md, 'name', +1);
G_dvf_md_mid = feedback(G_md_mid , K_dvf_md, 'name', +1);
G_dvf_md_heavy = feedback(G_md_heavy, K_dvf_md, 'name', +1);
G_dvf_pz_light = feedback(G_pz_light, K_dvf_pz, 'name', +1);
G_dvf_pz_mid = feedback(G_pz_mid , K_dvf_pz, 'name', +1);
G_dvf_pz_heavy = feedback(G_pz_heavy, K_dvf_pz, 'name', +1);
#+end_src
#+begin_src matlab
%% Verify Stability
% IFF
isstable(G_iff_vc_light) && isstable(G_iff_vc_mid) && isstable(G_iff_vc_heavy) && ...
isstable(G_iff_md_light) && isstable(G_iff_md_mid) && isstable(G_iff_md_heavy) && ...
isstable(G_iff_pz_light) && isstable(G_iff_pz_mid) && isstable(G_iff_pz_heavy)
% RDC
isstable(G_rdc_vc_light) && isstable(G_rdc_vc_mid) && isstable(G_rdc_vc_heavy) && ...
isstable(G_rdc_md_light) && isstable(G_rdc_md_mid) && isstable(G_rdc_md_heavy) && ...
isstable(G_rdc_pz_light) && isstable(G_rdc_pz_mid) && isstable(G_rdc_pz_heavy)
% DVF
isstable(G_dvf_vc_light) && isstable(G_dvf_vc_mid) && isstable(G_dvf_vc_heavy) && ...
isstable(G_dvf_md_light) && isstable(G_dvf_md_mid) && isstable(G_dvf_md_heavy) && ...
isstable(G_dvf_pz_light) && isstable(G_dvf_pz_mid) && isstable(G_dvf_pz_heavy)
#+end_src
#+begin_src matlab :exports none :tangle no
%% Save Damped Plants
save('./matlab/mat/uniaxial_damped_plants.mat', 'G_iff_vc_light', 'G_iff_md_light', 'G_iff_pz_light', ...
'G_rdc_vc_light', 'G_rdc_md_light', 'G_rdc_pz_light', ...
'G_dvf_vc_light', 'G_dvf_md_light', 'G_dvf_pz_light', ...
'G_iff_vc_mid', 'G_iff_md_mid', 'G_iff_pz_mid', ...
'G_rdc_vc_mid', 'G_rdc_md_mid', 'G_rdc_pz_mid', ...
'G_dvf_vc_mid', 'G_dvf_md_mid', 'G_dvf_pz_mid', ...
'G_iff_vc_heavy', 'G_iff_md_heavy', 'G_iff_pz_heavy', ...
'G_rdc_vc_heavy', 'G_rdc_md_heavy', 'G_rdc_pz_heavy', ...
'G_dvf_vc_heavy', 'G_dvf_md_heavy', 'G_dvf_pz_heavy');
#+end_src
#+begin_src matlab :exports none :eval no
%% Save Damped Plants
save('./mat/uniaxial_damped_plants.mat', 'G_iff_vc_light', 'G_iff_md_light', 'G_iff_pz_light', ...
'G_rdc_vc_light', 'G_rdc_md_light', 'G_rdc_pz_light', ...
'G_dvf_vc_light', 'G_dvf_md_light', 'G_dvf_pz_light', ...
'G_iff_vc_mid', 'G_iff_md_mid', 'G_iff_pz_mid', ...
'G_rdc_vc_mid', 'G_rdc_md_mid', 'G_rdc_pz_mid', ...
'G_dvf_vc_mid', 'G_dvf_md_mid', 'G_dvf_pz_mid', ...
'G_iff_vc_heavy', 'G_iff_md_heavy', 'G_iff_pz_heavy', ...
'G_rdc_vc_heavy', 'G_rdc_md_heavy', 'G_rdc_pz_heavy', ...
'G_dvf_vc_heavy', 'G_dvf_md_heavy', 'G_dvf_pz_heavy');
#+end_src
** Achievable Damping and Damped Plants
<<ssec:uniaxial_active_damping_achievable_damping>>
In order to compare the added damping using the three considered active damping strategies, the root locus plot is used.
Indeed, the damping ratio $\xi$ of a pole in the complex plane can be estimated from the angle $\phi$ it makes with the imaginary axis eqref:eq:uniaxial_damping_ratio_angle.
Increasing the angle with the imaginary axis therefore means more damping is added to the considered resonance.
This is illustrated in Figure ref:fig:uniaxial_root_locus_damping_techniques_micro_station_mode by the dashed black line indicating maximum achievable damping.
\begin{equation}\label{eq:uniaxial_damping_ratio_angle}
\xi = \sin(\phi)
\end{equation}
The Root Locus for the three nano-hexapod stiffnesses and for the three active damping techniques are shown in Figure ref:fig:uniaxial_root_locus_damping_techniques.
All three active damping approach can lead to /critical damping/ of the nano-hexapod suspension mode (angle $\phi$ can be increased up to 90 degrees).
There is even some damping authority on micro-station modes in the following cases:
- IFF with a stiff nano-hexapod (Figure ref:fig:uniaxial_root_locus_damping_techniques_stiff) ::
This can be understood from the mechanical equivalent of IFF shown in Figure ref:fig:uniaxial_active_damping_iff_equiv considering an high stiffness $k$.
The micro-station top platform is connected to an inertial mass (the nano-hexapod) through a damper, which damps the micro-station suspension suspension mode.
- DVF with a stiff nano-hexapod (Figure ref:fig:uniaxial_root_locus_damping_techniques_stiff) ::
In that case, the "sky hook damper" (see mechanical equivalent of DVF in Figure ref:fig:uniaxial_active_damping_dvf_equiv) is connected to the micro-station top platform through the stiff nano-hexapod.
- RDC with a soft nano-hexapod (Figure ref:fig:uniaxial_root_locus_damping_techniques_micro_station_mode) ::
At the frequency of the micro-station mode, the nano-hexapod top mass is behaving as an inertial reference as the suspension mode of the soft nano-hexapod is at much lower frequency.
The micro-station and the nano-hexapod masses are connected through a large damper induced by RDC (see mechanical equivalent in Figure ref:fig:uniaxial_active_damping_rdc_equiv) which allows some damping of the micro-station.
#+begin_src matlab :exports none
%% Active Damping Robustness to change of sample's mass - Root Locus for all three damping techniques with 3 different sample's masses
% Soft Nano-Hexapod
figure;
hold on;
% IFF
plot(real(pole(G_vc_light('fm', 'f'))), imag(pole(G_vc_light('fm', 'f'))), 'x', 'color', colors(1,:), ...
'HandleVisibility', 'off');
plot(real(zero(G_vc_light('fm', 'f'))), imag(zero(G_vc_light('fm', 'f'))), 'o', 'color', colors(1,:), ...
'DisplayName', 'IFF');
for g = logspace(0,2,400)
clpoles = pole(feedback(G_vc_light('fm', 'f'), g/s, +1));
plot(real(clpoles), imag(clpoles), '.', 'color', colors(1,:), ...
'HandleVisibility', 'off');
end
% RDC
plot(real(pole(G_vc_light('dL', 'f'))), imag(pole(G_vc_light('dL', 'f'))), 'x', 'color', colors(2,:), ...
'HandleVisibility', 'off');
plot(real(zero(G_vc_light('dL', 'f'))), imag(zero(G_vc_light('dL', 'f'))), 'o', 'color', colors(2,:), ...
'DisplayName', 'RDC');
for g = logspace(1,3,400)
clpoles = pole(feedback(G_vc_light('dL', 'f'), -g*s, +1));
plot(real(clpoles), imag(clpoles), '.', 'color', colors(2,:), ...
'HandleVisibility', 'off');
end
% DVF
plot(real(pole(G_vc_light('vn', 'f'))), imag(pole(G_vc_light('vn', 'f'))), 'x', 'color', colors(3,:), ...
'HandleVisibility', 'off');
plot(real(zero(G_vc_light('vn', 'f'))), imag(zero(G_vc_light('vn', 'f'))), 'o', 'color', colors(3,:), ...
'DisplayName', 'DVF');
for g = logspace(1,3,400)
clpoles = pole(feedback(G_vc_light('vn', 'f'), -g, +1));
plot(real(clpoles), imag(clpoles), '.', 'color', colors(3,:), ...
'HandleVisibility', 'off');
end
hold off;
axis square;
xlabel('Real Part'); ylabel('Imaginary Part');
ldg = legend('location', 'northwest', 'FontSize', 8, 'NumColumns', 1);
ldg.ItemTokenSize = [10, 1];
xlim([-30, 0]); ylim([0, 30]);
ytickangle(90)
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_root_locus_damping_techniques_soft.pdf', 'width', 'third', 'height', 'normal');
#+end_src
#+begin_src matlab :exports none
% Medium-Stiff Nano-Hexapod
figure;
hold on;
% IFF
plot(real(pole(G_md_light('fm', 'f'))), imag(pole(G_md_light('fm', 'f'))), 'x', 'color', colors(1,:), ...
'HandleVisibility', 'off');
plot(real(zero(G_md_light('fm', 'f'))), imag(zero(G_md_light('fm', 'f'))), 'o', 'color', colors(1,:), ...
'HandleVisibility', 'off');
for g = logspace(0,3,400)
clpoles = pole(feedback(G_md_light('fm', 'f'), g/s, +1));
plot(real(clpoles), imag(clpoles), '.', 'color', colors(1,:), ...
'HandleVisibility', 'off');
end
% RDC
plot(real(pole(G_md_light('dL', 'f'))), imag(pole(G_md_light('dL', 'f'))), 'x', 'color', colors(2,:), ...
'HandleVisibility', 'off');
plot(real(zero(G_md_light('dL', 'f'))), imag(zero(G_md_light('dL', 'f'))), 'o', 'color', colors(2,:), ...
'HandleVisibility', 'off');
for g = logspace(2,4,400)
clpoles = pole(feedback(G_md_light('dL', 'f'), -g*s, +1));
plot(real(clpoles), imag(clpoles), '.', 'color', colors(2,:), ...
'HandleVisibility', 'off');
end
% DVF
plot(real(pole(G_md_light('vn', 'f'))), imag(pole(G_md_light('vn', 'f'))), 'x', 'color', colors(3,:), ...
'HandleVisibility', 'off');
plot(real(zero(G_md_light('vn', 'f'))), imag(zero(G_md_light('vn', 'f'))), 'o', 'color', colors(3,:), ...
'HandleVisibility', 'off');
for g = logspace(2,4,400)
clpoles = pole(feedback(G_md_light('vn', 'f'), -g, +1));
plot(real(clpoles), imag(clpoles), '.', 'color', colors(3,:), ...
'HandleVisibility', 'off');
end
hold off;
axis square;
xlabel('Real Part'); ylabel('Imaginary Part');
xlim([-300, 0]); ylim([0, 300]);
ytickangle(90)
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_root_locus_damping_techniques_mid.pdf', 'width', 'third', 'height', 'normal');
#+end_src
#+begin_src matlab :exports none
% Stiff Nano Hexapod
figure;
hold on;
% IFF
plot(real(pole(G_pz_light('fm', 'f'))), imag(pole(G_pz_light('fm', 'f'))), 'x', 'color', colors(1,:), ...
'HandleVisibility', 'off');
plot(real(zero(G_pz_light('fm', 'f'))), imag(zero(G_pz_light('fm', 'f'))), 'o', 'color', colors(1,:), ...
'HandleVisibility', 'off');
for g = logspace(2,5,400)
clpoles = pole(feedback(G_pz_light('fm', 'f'), g/s, +1));
plot(real(clpoles), imag(clpoles), '.', 'color', colors(1,:), ...
'HandleVisibility', 'off');
end
% RDC
plot(real(pole(G_pz_light('dL', 'f'))), imag(pole(G_pz_light('dL', 'f'))), 'x', 'color', colors(2,:), ...
'HandleVisibility', 'off');
plot(real(zero(G_pz_light('dL', 'f'))), imag(zero(G_pz_light('dL', 'f'))), 'o', 'color', colors(2,:), ...
'HandleVisibility', 'off');
for g = logspace(3,6,400)
clpoles = pole(feedback(G_pz_light('dL', 'f'), -g*s, +1));
plot(real(clpoles), imag(clpoles), '.', 'color', colors(2,:), ...
'HandleVisibility', 'off');
end
% DVF
plot(real(pole(G_pz_light('vn', 'f'))), imag(pole(G_pz_light('vn', 'f'))), 'x', 'color', colors(3,:), ...
'HandleVisibility', 'off');
plot(real(zero(G_pz_light('vn', 'f'))), imag(zero(G_pz_light('vn', 'f'))), 'o', 'color', colors(3,:), ...
'HandleVisibility', 'off');
for g = logspace(3,6,400)
clpoles = pole(feedback(G_pz_light('vn', 'f'), -g, +1));
plot(real(clpoles), imag(clpoles), '.', 'color', colors(3,:), ...
'HandleVisibility', 'off');
end
hold off;
axis square;
xlabel('Real Part'); ylabel('Imaginary Part');
xlim([-4000, 0]); ylim([0, 4000]);
ytickangle(90)
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_root_locus_damping_techniques_stiff.pdf', 'width', 'third', 'height', 'normal');
#+end_src
#+name: fig:uniaxial_root_locus_damping_techniques
#+caption: Root Loci for the three active damping techniques (IFF in blue, RDC in red and DVF in yellow). This is shown for three nano-hexapod stiffnesses. The Root Loci are zoomed on the suspension mode of the nano-hexapod.
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_root_locus_damping_techniques_soft}$k_n = 0.01\,N/\mu m$}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_root_locus_damping_techniques_soft.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_root_locus_damping_techniques_mid}$k_n = 1\,N/\mu m$}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_root_locus_damping_techniques_mid.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_root_locus_damping_techniques_stiff}$k_n = 100\,N/\mu m$}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_root_locus_damping_techniques_stiff.png]]
#+end_subfigure
#+end_figure
#+begin_src matlab :exports none :results none
%% Root Locus for the three damping techniques
figure;
hold on;
% IFF
plot(real(pole(G_md_mid('fm', 'f'))), imag(pole(G_md_mid('fm', 'f'))), 'x', 'color', colors(1,:), ...
'DisplayName', 'IFF');
plot(real(zero(G_md_mid('fm', 'f'))), imag(zero(G_md_mid('fm', 'f'))), 'o', 'color', colors(1,:), ...
'HandleVisibility', 'off');
for g = logspace(1,4,500)
clpoles = pole(feedback(G_md_mid('fm', 'f'), g/s, +1));
plot(real(clpoles), imag(clpoles), '.', 'color', colors(1,:), ...
'HandleVisibility', 'off');
end
% RDC
plot(real(pole(G_md_mid('dL', 'f'))), imag(pole(G_md_mid('dL', 'f'))), 'x', 'color', colors(2,:), ...
'DisplayName', 'RDC');
plot(real(zero(G_md_mid('dL', 'f'))), imag(zero(G_md_mid('dL', 'f'))), 'o', 'color', colors(2,:), ...
'HandleVisibility', 'off');
% Estimate the maximum damping added by RDC
gs = logspace(2,5,500);
phis = zeros(size(gs));
for i = 1:length(gs)
g = gs(i);
clpoles = pole(feedback(G_md_mid('dL', 'f'), -g*s, +1));
plot(real(clpoles), imag(clpoles), '.', 'color', colors(2,:), ...
'HandleVisibility', 'off');
% Estimate damping of u-station mode
ustation_pole = clpoles(imag(clpoles)>1000);
phis(i) = atan2(abs(real(ustation_pole)), abs(imag(ustation_pole)));
end
[~, i_max] = max(phis);
plot([0, -5e3*sin(phis(i_max))], [0, 5e3*cos(phis(i_max))], 'k--', 'HandleVisibility', 'off');
clpoles_max = pole(feedback(G_md_mid('dL', 'f'), -gs(i_max)*s, +1));
ustation_pole = clpoles_max(imag(clpoles_max)>1000);
plot(real(ustation_pole), imag(ustation_pole), 'kx', ...
'HandleVisibility', 'off');
% Plot angle
plot(-8e2*sin(0:0.01:max(phis)), 8e2*cos(sin(0:0.01:max(phis))), 'k-', 'HandleVisibility', 'off')
text(-200, 850, '$\phi$', 'horizontalalignment', 'center');
text(real(ustation_pole)-100, imag(ustation_pole), '$\xi = \sin(\phi)$', 'horizontalalignment', 'right');
% DVF
plot(real(pole(G_md_mid('vn', 'f'))), imag(pole(G_md_mid('vn', 'f'))), 'x', 'color', colors(3,:), ...
'DisplayName', 'DVF');
plot(real(zero(G_md_mid('vn', 'f'))), imag(zero(G_md_mid('vn', 'f'))), 'o', 'color', colors(3,:), ...
'HandleVisibility', 'off');
for g = logspace(2,5,500)
clpoles = pole(feedback(G_md_mid('vn', 'f'), -tf(g), +1));
plot(real(clpoles), imag(clpoles), '.', 'color', colors(3,:), ...
'HandleVisibility', 'off');
end
hold off;
xlim([-2100, 0]); ylim([0, 2100]);
axis square;
xlabel('Real Part'); ylabel('Imaginary Part');
ldg = legend('location', 'northwest', 'FontSize', 8, 'NumColumns', 1);
ldg.ItemTokenSize = [10, 1];
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_root_locus_damping_techniques_micro_station_mode.pdf', 'width', 'wide', 'height', 'normal');
#+end_src
#+name: fig:uniaxial_root_locus_damping_techniques_micro_station_mode
#+caption: Root Locus for the three damping techniques applied with the soft nano-hexapod. It is shown that the RDC active damping technique has some authority on one mode of the micro-station. This mode corresponds to the suspension mode of the micro-hexapod.
#+RESULTS:
[[file:figs/uniaxial_root_locus_damping_techniques_micro_station_mode.png]]
The transfer functions from the plant input $f$ to the relative displacement $d$ while the active damping is implemented are shown in Figure ref:fig:uniaxial_damped_plant_three_active_damping_techniques.
All three active damping techniques yield similar damped plants.
#+begin_src matlab :exports none :results none
%% Obtained damped transfer function from f to d for the three damping techniques
figure;
tiledlayout(3, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
ax1 = nexttile([2,1]);
hold on;
plot(freqs, abs(squeeze(freqresp(G_vc_mid('d', 'f'), freqs, 'Hz'))), 'k-', 'DisplayName', 'OL');
plot(freqs, abs(squeeze(freqresp(G_iff_vc_mid('d', 'f'), freqs, 'Hz'))), 'color', colors(1,:), 'DisplayName', 'IFF');
plot(freqs, abs(squeeze(freqresp(G_rdc_vc_mid('d', 'f'), freqs, 'Hz'))), 'color', colors(2,:), 'DisplayName', 'RDC');
plot(freqs, abs(squeeze(freqresp(G_dvf_vc_mid('d', 'f'), freqs, 'Hz'))), 'color', colors(3,:), 'DisplayName', 'DVF');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude $d/f$ [m/N]'); set(gca, 'XTickLabel',[]);
ax2 = nexttile();
hold on;
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_vc_mid('d', 'f'), freqs, 'Hz')))), 'k-');
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_iff_vc_mid('d', 'f'), freqs, 'Hz')))), 'color', colors(1,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_rdc_vc_mid('d', 'f'), freqs, 'Hz')))), 'color', colors(2,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_dvf_vc_mid('d', 'f'), freqs, 'Hz')))), 'color', colors(3,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
yticks(-360:90:360);
ylim([-270, 90]);
xticks([1e0, 1e1, 1e2]);
linkaxes([ax1,ax2],'x');
xlim([1, 500]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file none
exportFig('figs/uniaxial_damped_plant_three_active_damping_techniques_vc.pdf', 'width', 'third', 'height', 'normal');
#+end_src
#+begin_src matlab :exports none :results none
%% Obtained damped transfer function from f to d for the three damping techniques
figure;
tiledlayout(3, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
ax1 = nexttile([2,1]);
hold on;
plot(freqs, abs(squeeze(freqresp(G_md_mid('d', 'f'), freqs, 'Hz'))), 'k-', 'DisplayName', 'OL');
plot(freqs, abs(squeeze(freqresp(G_iff_md_mid('d', 'f'), freqs, 'Hz'))), 'color', colors(1,:), 'DisplayName', 'IFF');
plot(freqs, abs(squeeze(freqresp(G_rdc_md_mid('d', 'f'), freqs, 'Hz'))), 'color', colors(2,:), 'DisplayName', 'RDC');
plot(freqs, abs(squeeze(freqresp(G_dvf_md_mid('d', 'f'), freqs, 'Hz'))), 'color', colors(3,:), 'DisplayName', 'DVF');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude $d/f$ [m/N]'); set(gca, 'XTickLabel',[]);
ax2 = nexttile();
hold on;
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_md_mid('d', 'f'), freqs, 'Hz')))), 'k-');
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_iff_md_mid('d', 'f'), freqs, 'Hz')))), 'color', colors(1,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_rdc_md_mid('d', 'f'), freqs, 'Hz')))), 'color', colors(2,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_dvf_md_mid('d', 'f'), freqs, 'Hz')))), 'color', colors(3,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
yticks(-360:90:360);
ylim([-270, 90]);
xticks([1e0, 1e1, 1e2]);
linkaxes([ax1,ax2],'x');
xlim([1, 500]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file none
exportFig('figs/uniaxial_damped_plant_three_active_damping_techniques_md.pdf', 'width', 'third', 'height', 'normal');
#+end_src
#+begin_src matlab :exports none :results none
%% Obtained damped transfer function from f to d for the three damping techniques
figure;
tiledlayout(3, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
ax1 = nexttile([2,1]);
hold on;
plot(freqs, abs(squeeze(freqresp(G_pz_mid('d', 'f'), freqs, 'Hz'))), 'k-', 'DisplayName', 'OL');
plot(freqs, abs(squeeze(freqresp(G_iff_pz_mid('d', 'f'), freqs, 'Hz'))), 'color', colors(1,:), 'DisplayName', 'IFF');
plot(freqs, abs(squeeze(freqresp(G_rdc_pz_mid('d', 'f'), freqs, 'Hz'))), 'color', colors(2,:), 'DisplayName', 'RDC');
plot(freqs, abs(squeeze(freqresp(G_dvf_pz_mid('d', 'f'), freqs, 'Hz'))), 'color', colors(3,:), 'DisplayName', 'DVF');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude $d/f$ [m/N]'); set(gca, 'XTickLabel',[]);
leg = legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 1);
leg.ItemTokenSize(1) = 15;
ax2 = nexttile();
hold on;
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_pz_mid('d', 'f'), freqs, 'Hz')))), 'k-');
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_iff_pz_mid('d', 'f'), freqs, 'Hz')))), 'color', colors(1,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_rdc_pz_mid('d', 'f'), freqs, 'Hz')))), 'color', colors(2,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_dvf_pz_mid('d', 'f'), freqs, 'Hz')))), 'color', colors(3,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
yticks(-360:90:360);
ylim([-270, 90]);
xticks([1e0, 1e1, 1e2]);
linkaxes([ax1,ax2],'x');
xlim([1, 500]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file none
exportFig('figs/uniaxial_damped_plant_three_active_damping_techniques_pz.pdf', 'width', 'third', 'height', 'normal');
#+end_src
#+name: fig:uniaxial_damped_plant_three_active_damping_techniques
#+caption: Obtained damped transfer function from $f$ to $d$ for the three damping techniques.
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_damped_plant_three_active_damping_techniques_vc}$k_n = 0.01\,N/\mu m$}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :width 0.95\linewidth
[[file:figs/uniaxial_damped_plant_three_active_damping_techniques_vc.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_damped_plant_three_active_damping_techniques_md}$k_n = 1\,N/\mu m$}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :width 0.95\linewidth
[[file:figs/uniaxial_damped_plant_three_active_damping_techniques_md.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_damped_plant_three_active_damping_techniques_pz}$k_n = 100\,N/\mu m$}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :width 0.95\linewidth
[[file:figs/uniaxial_damped_plant_three_active_damping_techniques_pz.png]]
#+end_subfigure
#+end_figure
** Sensitivity to disturbances and Noise Budgeting
<<ssec:uniaxial_active_damping_sensitivity_disturbances>>
Reasonable gains are chosen for the three active damping strategies such that the nano-hexapod suspension mode is well damped.
The sensitivity to disturbances (direct forces $f_s$, stage vibrations $f_t$ and floor motion $x_f$) for all three active damping techniques are compared in Figure ref:fig:uniaxial_sensitivity_dist_active_damping.
The comparison is done with the nano-hexapod having a stiffness $k_n = 1\,N/\mu m$.
Several conclusions can be made by comparing of obtained sensitivity transfer functions:
- IFF degrades the sensitivity to direct forces on the sample (i.e. the compliance) below the resonance of the nano-hexapod (Figure ref:fig:uniaxial_sensitivity_dist_active_damping_fs).
This is a well known effect of using IFF for vibration isolation [[cite:&collette15_sensor_fusion_method_high_perfor]].
- RDC degrades the sensitivity to stage vibrations around the nano-hexapod's resonance as compared to the other two methods (Figure ref:fig:uniaxial_sensitivity_dist_active_damping_ft).
This is due to the fact that the equivalent damper in parallel with the actuator (see Figure ref:fig:uniaxial_active_damping_rdc_equiv) increases the transmission of the micro-station vibration to the sample which is not the same for the other two active damping strategies.
- both IFF and DVF degrade the sensitivity to floor motion below the resonance of the nano-hexapod (Figure ref:fig:uniaxial_sensitivity_dist_active_damping_xf).
#+begin_src matlab :exports none :results none
%% Change of sensitivity to disturbance with all three active damping strategies
% FS
figure;
hold on;
plot(freqs, abs(squeeze(freqresp(G_md_mid('d', 'fs'), freqs, 'Hz'))), 'k-');
plot(freqs, abs(squeeze(freqresp(G_iff_md_mid('d', 'fs'), freqs, 'Hz'))), 'color', colors(1,:));
plot(freqs, abs(squeeze(freqresp(G_rdc_md_mid('d', 'fs'), freqs, 'Hz'))), 'color', colors(2,:));
plot(freqs, abs(squeeze(freqresp(G_dvf_md_mid('d', 'fs'), freqs, 'Hz'))), 'color', colors(3,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude $d/f_{s}$ [m/N]'); xlabel('Frequency [Hz]');
xticks([1e0, 1e1, 1e2]);
xlim([1, 500]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_sensitivity_dist_active_damping_fs.pdf', 'width', 'third', 'height', 'normal');
#+end_src
#+begin_src matlab :exports none :results none
figure;
hold on;
plot(freqs, abs(squeeze(freqresp(G_md_mid('d', 'ft'), freqs, 'Hz'))), 'k-');
plot(freqs, abs(squeeze(freqresp(G_iff_md_mid('d', 'ft'), freqs, 'Hz'))), 'color', colors(1,:));
plot(freqs, abs(squeeze(freqresp(G_rdc_md_mid('d', 'ft'), freqs, 'Hz'))), 'color', colors(2,:));
plot(freqs, abs(squeeze(freqresp(G_dvf_md_mid('d', 'ft'), freqs, 'Hz'))), 'color', colors(3,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude $d/f_{t}$ [m/N]'); xlabel('Frequency [Hz]');
xticks([1e0, 1e1, 1e2]);
xlim([1, 500]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_sensitivity_dist_active_damping_ft.pdf', 'width', 'third', 'height', 'normal');
#+end_src
#+begin_src matlab :exports none :results none
figure;
hold on;
plot(freqs, abs(squeeze(freqresp(G_md_mid('d', 'xf'), freqs, 'Hz'))), 'k-', 'DisplayName', 'OL');
plot(freqs, abs(squeeze(freqresp(G_iff_md_mid('d', 'xf'), freqs, 'Hz'))), 'color', colors(1,:), 'DisplayName', 'IFF');
plot(freqs, abs(squeeze(freqresp(G_rdc_md_mid('d', 'xf'), freqs, 'Hz'))), 'color', colors(2,:), 'DisplayName', 'RDC');
plot(freqs, abs(squeeze(freqresp(G_dvf_md_mid('d', 'xf'), freqs, 'Hz'))), 'color', colors(3,:), 'DisplayName', 'DVF');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude $d/x_{f}$ [m/m]'); xlabel('Frequency [Hz]');
xticks([1e0, 1e1, 1e2]);
legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 1);
xlim([1, 500]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_sensitivity_dist_active_damping_xf.pdf', 'width', 'third', 'height', 'normal');
#+end_src
#+name: fig:uniaxial_sensitivity_dist_active_damping
#+caption: Change of sensitivity to disturbance with all three active damping strategies. $f_s$ the direct forces applied on the sample (\subref{fig:uniaxial_sensitivity_dist_active_damping_fs}), $f_t$ disturbances from the micro-station stages (\subref{fig:uniaxial_sensitivity_dist_active_damping_ft}) and $x_f$ the floor motion (\subref{fig:uniaxial_sensitivity_dist_active_damping_fs})
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_sensitivity_dist_active_damping_fs}Direct forces}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_sensitivity_dist_active_damping_fs.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_sensitivity_dist_active_damping_ft}$\mu\text{-station}$ disturbances}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_sensitivity_dist_active_damping_ft.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_sensitivity_dist_active_damping_xf}Floor motion}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_sensitivity_dist_active_damping_xf.png]]
#+end_subfigure
#+end_figure
From the amplitude spectral density of the disturbances (computed in Section ref:sec:uniaxial_disturbances) and the sensitivity to disturbances estimated with the three active damping strategies, a noise budget can be performed.
The cumulative amplitude spectrum of the distance $d$ with all three active damping techniques are shown in Figure ref:fig:uniaxial_cas_active_damping and compared with the open-loop case.
All three active damping methods are giving similar results.
#+begin_src matlab :exports none :results none
%% Cumulative Amplitude Spectrum of the distance d with all three active damping techniques
figure;
hold on;
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_vc_mid('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_vc_mid('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', 'black', 'DisplayName', 'OL');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_iff_vc_mid('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_iff_vc_mid('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', colors(1,:), 'DisplayName', 'IFF');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_rdc_vc_mid('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_rdc_vc_mid('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', colors(2,:), 'DisplayName', 'RDC');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_dvf_vc_mid('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_dvf_vc_mid('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', colors(3,:), 'DisplayName', 'DVF');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('CAS of $d$ [m]'); xlabel('Frequency [Hz]');
xticks([1e0, 1e1, 1e2]);
xlim([1, 500]);
ylim([2e-10, 3e-6])
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_cas_active_damping_soft.pdf', 'width', 450, 'height', 'normal');
#+end_src
#+begin_src matlab :exports none :results none
figure;
hold on;
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_md_mid('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_md_mid('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', 'black', 'DisplayName', 'OL');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_iff_md_mid('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_iff_md_mid('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', colors(1,:), 'DisplayName', 'IFF');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_rdc_md_mid('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_rdc_md_mid('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', colors(2,:), 'DisplayName', 'RDC');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_dvf_md_mid('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_dvf_md_mid('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', colors(3,:), 'DisplayName', 'DVF');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); set(gca, 'YTickLabel',[]);
xticks([1e0, 1e1, 1e2]);
xlim([1, 500]);
ylim([2e-10, 3e-6])
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_cas_active_damping_mid.pdf', 'width', 400, 'height', 'normal');
#+end_src
#+begin_src matlab :exports none :results none
figure;
hold on;
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_pz_mid('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_pz_mid('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', 'black', 'DisplayName', 'OL');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_iff_pz_mid('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_iff_pz_mid('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', colors(1,:), 'DisplayName', 'IFF');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_rdc_pz_mid('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_rdc_pz_mid('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', colors(2,:), 'DisplayName', 'RDC');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_dvf_pz_mid('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_dvf_pz_mid('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', colors(3,:), 'DisplayName', 'DVF');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); set(gca, 'YTickLabel',[]);
xticks([1e0, 1e1, 1e2]);
legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 1);
xlim([1, 500]);
ylim([2e-10, 3e-6])
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_cas_active_damping_stiff.pdf', 'width', 400, 'height', 'normal');
#+end_src
#+name: fig:uniaxial_cas_active_damping
#+caption: Comparison of the cumulative amplitude spectrum (CAS) of the distance $d$ for all three active damping techniques (OL in black, IFF in blue, RDC in red and DVF in yellow).
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_cas_active_damping_soft}$k_n = 0.01\,N/\mu m$}
#+attr_latex: :options {0.37\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_cas_active_damping_soft.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_cas_active_damping_mid}$k_n = 1\,N/\mu m$}
#+attr_latex: :options {0.31\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_cas_active_damping_mid.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_cas_active_damping_stiff}$k_n = 100\,N/\mu m$}
#+attr_latex: :options {0.31\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_cas_active_damping_stiff.png]]
#+end_subfigure
#+end_figure
** Conclusion
:PROPERTIES:
:UNNUMBERED: t
:END:
Three active damping strategies have been studied for the acrfull:nass.
Equivalent mechanical representations were derived in Section ref:ssec:uniaxial_active_damping_strategies which are helpful to understand the specific effects of each strategy.
The plant dynamics were then compared in Section ref:ssec:uniaxial_active_damping_plants and were found to all have alternating poles and zeros which helps the design of the active damping controller.
However, this property is not guaranteed for DVF.
The achievable damping of the nano-hexapod suspension mode can be made as large as possible for all three active damping techniques (Section ref:ssec:uniaxial_active_damping_achievable_damping).
Even some damping can be applied to some micro-station modes in specific cases.
The obtained damped plants were found to be similar.
The damping strategies were then compared in terms of reduction of disturbances in Section ref:ssec:uniaxial_active_damping_sensitivity_disturbances.
The comparison between the three active damping strategies is summarized in Table ref:tab:comp_active_damping.
It is difficult to conclude on the best active damping strategy for the acrfull:nass yet.
Which one will be used will be determined with the use of more accurate models and will depend on which is the easiest to implement in practice
#+name: tab:comp_active_damping
#+caption: Comparison of active damping strategies
#+attr_latex: :environment tabularx :width 0.9\linewidth :align Xccc
#+attr_latex: :center t :booktabs t :font \scriptsize
| | *IFF* | *RDC* | *DVF* |
|---------------------+-----------------------------+---------------------------+---------------------------------|
| *Sensor* | Force sensor | Relative motion sensor | Inertial sensor |
|---------------------+-----------------------------+---------------------------+---------------------------------|
| *Damping* | Up to critical | Up to critical | Up to Critical |
|---------------------+-----------------------------+---------------------------+---------------------------------|
| *Robustness* | Requires collocation | Requires collocation | Impacted by geophone resonances |
|---------------------+-----------------------------+---------------------------+---------------------------------|
| $f_s$ *Disturbance* | $\nearrow$ at low frequency | $\searrow$ near resonance | $\searrow$ near resonance |
| $f_t$ *Disturbance* | $\searrow$ near resonance | $\nearrow$ near resonance | $\searrow$ near resonance |
| $x_f$ *Disturbance* | $\nearrow$ at low frequency | $\searrow$ near resonance | $\nearrow$ at low frequency |
* Position Feedback Controller
:PROPERTIES:
:HEADER-ARGS:matlab+: :tangle matlab/uniaxial_6_hac_lac.m
:END:
<<sec:uniaxial_position_control>>
** Introduction :ignore:
The gls:haclac architecture is shown in Figure ref:fig:uniaxial_hac_lac_architecture.
It corresponds to a /two step/ control strategy:
- First, an active damping controller $\bm{K}_{\textsc{LAC}}$ is implemented (see Section ref:sec:uniaxial_active_damping).
It allows to reduce the vibration level, and it also makes the damped plant (transfer function from $u^{\prime}$ to $y$) easier to control than the undamped plant (transfer function from $u$ to $y$).
It is called /low authority/ control as it only slightly affects the system poles [[cite:&preumont18_vibrat_contr_activ_struc_fourt_edition Chapter 14.6]].
- Then, a position controller $\bm{K}_{\textsc{HAC}}$ is implemented which is used to control the position $d$.
This is called /high authority/ control as it usually relocates the system's poles.
In this section, Integral Force Feedback is used as the Low Authority Controller (the other two damping strategies would lead to the same conclusions here).
This control architecture applied on the uniaxial model is shown in Figure ref:fig:uniaxial_hac_lac_model.
#+begin_src latex :file uniaxial_hac_lac_architecture.pdf :results none
\begin{tikzpicture}
% Blocs
\node[block={3.0cm}{3.0cm}] (P) {Plant};
\coordinate[] (input) at ($(P.south west)!0.5!(P.north west)$);
\coordinate[] (outputH) at ($(P.south east)!0.2!(P.north east)$);
\coordinate[] (outputL) at ($(P.south east)!0.8!(P.north east)$);
\node[block, above=0.4 of P] (Klac) {$\bm{K}_{\textsc{LAC}}$};
\node[addb, left=0.6 of input] (addF) {};
\node[block, left=1.0 of addF] (Khac) {$\bm{K}_{\textsc{HAC}}$};
\node[addb={+}{}{}{}{-}, left=0.6 of Khac] (subr) {};
% Connections and labels
\draw[->] (outputL) -- ++(0.6, 0) coordinate(eastlac) |- (Klac.east);
\node[above right] at (outputL){$y^{\prime}$};
\draw[->] (Klac.west) -| (addF.north);
\draw[->] (addF.east) -- (input) node[above left]{$u$};
\draw[<-] (subr.west) --node[midway, above]{$r$} ++(-0.8, 0);
\draw[->] (outputH) -- ++(1.6, 0);
\draw[->] ($(outputH) + (1.2, 0)$)node[branch]{} node[above]{$y$} -- ++(0, -1.2) -| (subr.south);
\draw[->] (subr.east) -- (Khac.west) node[above left]{$\epsilon$};
\draw[->] (Khac.east) -- (addF.west) node[above left=0 and 0.2]{$u^{\prime}$};
\begin{scope}[on background layer]
\node[fit={(Klac.north-|eastlac) (addF.west|-P.south)}, fill=black!20!white, draw, dashed, inner sep=6pt] (Pi) {};
\node[anchor={north west}] at (Pi.north west){\small Damped Plant};
\end{scope}
\end{tikzpicture}
#+end_src
#+begin_src latex :file uniaxial_hac_lac_model.pdf :results silent
\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.4} % Width of the dashed line for the displacement
\def\disph{0.3} % Height of the arrow for the displacements
\def\bracs{0.05} % Brace spacing vertically
\def\brach{-12pt} % Brace shift horizontaly
\def\fsensh{0.2} % Height of the force sensor
\def\velsize{0.2} % Size of the velocity sensor
% ====================
% IFF
% ====================
% Ground
% ====================
\draw (-0.5*\massw, 0) -- (0.5*\massw, 0);
\draw[dashed] (0.5*\massw, 0) -- ++(\dispw, 0);
\draw[->, color=colorpurple] (0.5*\massw+0.5*\dispw, 0) -- ++(0, 2*\disph) node[right, color=colorpurple]{$x_{f}$};
% ====================
% ====================
% Granite
\begin{scope}[shift={(0, 0)}]
% Mass
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m_{g}$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k_{g}$};
\draw[damper] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2]{$c_{g}$};
% 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]{Granite};
% Displacements
\draw[dashed] (0.5*\massw, \spaceh+\massh) -- ++(7.5*\dispw, 0) coordinate(xg);
\end{scope}
% ====================
% ====================
% Stages
\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_{t}$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k_{t}$};
\draw[damper] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2]{$c_{t}$};
\draw[actuator={0.45}{0.2}{colorpurple}] ( 0.3*\massw, 0) -- (0.3*\massw, \spaceh) node[midway, right=0.1, color=colorpurple](ft){$f_{t}$};
% 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]{$T_y$/$R_y$/$R_z$};
\end{scope}
% ====================
% ====================
% Hexapod
\begin{scope}[shift={(0, 2*(\spaceh+\massh))}]
% Mass
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m_h$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k_h$};
\draw[damper] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2]{$c_h$};
% 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]{$\mu\text{-hexa}$};
\end{scope}
% ====================
% ====================
% NASS
\begin{scope}[shift={(0, 3*(\spaceh+\massh))}]
% Mass
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m_{n}$};
% Force Sensor
\node[forcesensor={\massw}{\fsensh}{colorblue}] (fsensn) at (0, \spaceh-\fsensh){};
\node[right, color=colorblue] (fn) at (fsensn.east) {$f_n$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh-\fsensh) node[midway, left=0.1]{$k_{n}$};
\draw[damper] (0, 0) -- ( 0, \spaceh-\fsensh) node[midway, left=0.2]{$c_{n}$};
\draw[actuator={0.4}{0.2}{black}] ( 0.3*\massw, 0) -- ( 0.3*\massw, \spaceh-\fsensh) node[midway, right=0.1](f){$f$};
% 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]{$\nu\text{-hexa}$};
% Displacements
\draw[dashed] (0.5*\massw, \spaceh+\massh) -- ++(7.5*\dispw, 0) coordinate(xnpos);
\end{scope}
% ====================
% ====================
% sample
\begin{scope}[shift={(0, 4*(\spaceh+\massh))}]
% Mass
\draw[fill=white] (-0.3*\massw, 0) rectangle (0.3*\massw, \massh) node[pos=0.5]{$m_{s}$};
% External Force
\draw[->, color=colorpurple] (0, \massh) node[]{$\bullet$} -- ++(0, 0.5*\massh) node[right, color=colorpurple]{$f_s$};
\end{scope}
% ====================
% Measured displacement
\draw[<->, dashed, draw=colorred] ($(xg)+(-0.1, 0)$) -- node[left, color=colorred](d){$d$} ($(xnpos)+(-0.1, 0)$);
% ====================
% IFF Control
\node[block={2em}{2em}, right=1.0 of fn, color=colorblue, fill=colorblue!10!white] (iff) {$K_{\textsc{IFF}}$};
\node[addb, right=0.5 of f.east] (ctrladd) {};
\node[block={2em}{2em}, color=colorred, fill=colorred!10!white] (Khac) at (ctrladd|-d) {$K_{\textsc{HAC}}$};
\draw[->, draw=colorblue] (fn.east) -- (iff.west);
\draw[->, draw=colorblue] (iff.south) |- (ctrladd.east);
\draw[->] (ctrladd.west) -- (f.east);
\draw[->, draw=colorred] (d.west) -- (Khac.east);
\draw[->, draw=colorred] (Khac.north) -- (ctrladd.south) node[below right, color=colorred]{$f^{\prime}$};
% ====================
\end{tikzpicture}
#+end_src
#+name: fig:uniaxial_hac_lac
#+caption: acrfull:haclac
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_hac_lac_architecture}Typical HAC-LAC Architecture}
#+attr_latex: :options {0.54\textwidth}
#+begin_subfigure
#+attr_latex: :width 1.0\linewidth
[[file:figs/uniaxial_hac_lac_architecture.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_hac_lac_model}Uniaxial model with HAC-IFF strategy}
#+attr_latex: :options {0.45\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_hac_lac_model.png]]
#+end_subfigure
#+end_figure
** Matlab Init :noexport:ignore:
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
<<matlab-dir>>
#+end_src
#+begin_src matlab :exports none :results silent :noweb yes
<<matlab-init>>
#+end_src
#+begin_src matlab :tangle no :noweb yes
<<m-init-path>>
#+end_src
#+begin_src matlab :eval no :noweb yes
<<m-init-path-tangle>>
#+end_src
#+begin_src matlab :noweb yes
<<m-init-other>>
#+end_src
#+begin_src matlab
%% Frequency Vector [Hz]
freqs = logspace(0, 3, 1000);
#+end_src
#+begin_src matlab
%% Load the PSD of disturbances
load('uniaxial_disturbance_psd.mat', 'f', 'psd_ft', 'psd_xf');
#+end_src
#+begin_src matlab
%% Load Plants Dynamics
load('uniaxial_plants.mat', 'G_vc_light', 'G_md_light', 'G_pz_light', ...
'G_vc_mid', 'G_md_mid', 'G_pz_mid', ...
'G_vc_heavy', 'G_md_heavy', 'G_pz_heavy');
#+end_src
#+begin_src matlab
%% Load Damped Plants
load('uniaxial_damped_plants.mat', 'G_iff_vc_light', 'G_iff_md_light', 'G_iff_pz_light', ...
'G_rdc_vc_light', 'G_rdc_md_light', 'G_rdc_pz_light', ...
'G_dvf_vc_light', 'G_dvf_md_light', 'G_dvf_pz_light', ...
'G_iff_vc_mid', 'G_iff_md_mid', 'G_iff_pz_mid', ...
'G_rdc_vc_mid', 'G_rdc_md_mid', 'G_rdc_pz_mid', ...
'G_dvf_vc_mid', 'G_dvf_md_mid', 'G_dvf_pz_mid', ...
'G_iff_vc_heavy', 'G_iff_md_heavy', 'G_iff_pz_heavy', ...
'G_rdc_vc_heavy', 'G_rdc_md_heavy', 'G_rdc_pz_heavy', ...
'G_dvf_vc_heavy', 'G_dvf_md_heavy', 'G_dvf_pz_heavy');
#+end_src
** Damped Plant Dynamics
<<ssec:uniaxial_position_control_damped_dynamics>>
The obtained damped plants for the three nano-hexapod stiffnesses are shown in Figure ref:fig:uniaxial_hac_iff_damped_plants_masses.
For $k_n = 0.01\,N/\mu m$ and $k_n = 1\,N/\mu m$, the dynamics is quite simple and can be well approximated by a second order plant (Figures ref:fig:uniaxial_hac_iff_damped_plants_masses_soft and ref:fig:uniaxial_hac_iff_damped_plants_masses_mid).
However, this is not the case for the stiff nano-hexapod ($k_n = 100\,N/\mu m$) where two modes can be seen (Figure ref:fig:uniaxial_hac_iff_damped_plants_masses_stiff).
This is due to the interaction between the micro-station (modelled modes at 70Hz, 140Hz and 320Hz) and the nano-hexapod.
Such effect will be further explained in Section ref:sec:uniaxial_support_compliance.
#+begin_src matlab :exports none :results none
%% Damped plant - Robustness to change of sample's mass
figure;
tiledlayout(3, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
ax1 = nexttile([2,1]);
hold on;
plot(freqs, abs(squeeze(freqresp(G_vc_light('d', 'f'), freqs, 'Hz'))), 'color', [colors(1,:), 0.5]);
plot(freqs, abs(squeeze(freqresp(G_iff_vc_light('d', 'f'), freqs, 'Hz'))), 'color', colors(1,:));
plot(freqs, abs(squeeze(freqresp(G_iff_vc_mid( 'd', 'f'), freqs, 'Hz'))), 'color', colors(2,:));
plot(freqs, abs(squeeze(freqresp(G_iff_vc_heavy('d', 'f'), freqs, 'Hz'))), 'color', colors(3,:));
loglog(10.^(0.4*cos([0:0.01:2*pi])+log10(100)), ...
10.^(0.8*sin([0:0.01:2*pi]-pi/4)+log10(8e-8)), 'k--');
text(20, 4e-8, sprintf('Small\nInteraction'), 'horizontalalignment', 'center');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
ylim([5e-10, 1e-3]);
ax1b = nexttile();
hold on;
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_vc_light('d', 'f'), freqs, 'Hz')))), 'color', [colors(1,:), 0.5]);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_iff_vc_light('d', 'f'), freqs, 'Hz')))), 'color', colors(1,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_iff_vc_mid( 'd', 'f'), freqs, 'Hz')))), 'color', colors(2,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_iff_vc_heavy('d', 'f'), freqs, 'Hz')))), 'color', colors(3,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
xticks([1e0, 1e1, 1e2]);
yticks(-360:90:360);
ylim([-200, 20]);
linkaxes([ax1,ax1b],'x');
xlim([1, 1e3]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_hac_iff_damped_plants_masses_soft.pdf', 'width', 400, 'height', 'tall');
#+end_src
#+begin_src matlab :exports none :results none
figure;
tiledlayout(3, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
ax2 = nexttile([2,1]);
hold on;
plot(freqs, abs(squeeze(freqresp(G_md_light('d', 'f'), freqs, 'Hz'))), 'color', [colors(1,:), 0.5]);
plot(freqs, abs(squeeze(freqresp(G_iff_md_light('d', 'f'), freqs, 'Hz'))), 'color', colors(1,:));
plot(freqs, abs(squeeze(freqresp(G_iff_md_mid( 'd', 'f'), freqs, 'Hz'))), 'color', colors(2,:));
plot(freqs, abs(squeeze(freqresp(G_iff_md_heavy('d', 'f'), freqs, 'Hz'))), 'color', colors(3,:));
loglog(10.^(0.4*cos([0:0.01:2*pi])+log10(200)), ...
10.^(0.8*sin([0:0.01:2*pi]-pi/4)+log10(2e-8)), 'k--');
text(40, 1e-8, sprintf('Small\nInteraction'), 'horizontalalignment', 'center');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
set(gca, 'XTickLabel',[]); set(gca, 'YTickLabel',[]);
ylim([5e-10, 1e-3]);
ax2b = nexttile();
hold on;
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_md_light('d', 'f'), freqs, 'Hz')))), 'color', [colors(1,:), 0.5]);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_iff_md_light('d', 'f'), freqs, 'Hz')))), 'color', colors(1,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_iff_md_mid( 'd', 'f'), freqs, 'Hz')))), 'color', colors(2,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_iff_md_heavy('d', 'f'), freqs, 'Hz')))), 'color', colors(3,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
xlabel('Frequency [Hz]'); set(gca, 'YTickLabel',[]);
xticks([1e0, 1e1, 1e2]);
yticks(-360:90:360);
ylim([-200, 20]);
linkaxes([ax2,ax2b],'x');
xlim([1, 1e3]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_hac_iff_damped_plants_masses_mid.pdf', 'width', 350, 'height', 'tall');
#+end_src
#+begin_src matlab :exports none :results none
figure;
tiledlayout(3, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
ax3 = nexttile([2,1]);
hold on;
plot(freqs, abs(squeeze(freqresp(G_pz_light('d', 'f'), freqs, 'Hz'))), 'color', [colors(1,:), 0.5], 'DisplayName', '$m_s = 1\,kg$, OL');
plot(freqs, abs(squeeze(freqresp(G_iff_pz_light('d', 'f'), freqs, 'Hz'))), 'color', colors(1,:), 'DisplayName', '$m_s = 1\,kg$, IFF');
plot(freqs, abs(squeeze(freqresp(G_iff_pz_mid( 'd', 'f'), freqs, 'Hz'))), 'color', colors(2,:), 'DisplayName', '$m_s = 25\,kg$, IFF');
plot(freqs, abs(squeeze(freqresp(G_iff_pz_heavy('d', 'f'), freqs, 'Hz'))), 'color', colors(3,:), 'DisplayName', '$m_s = 50\,kg$, IFF');
loglog(10.^(0.8*cos([0:0.01:2*pi])+log10(350)), ...
10.^(1.2*sin([0:0.01:2*pi])+log10(8e-9)), 'k--', 'HandleVisibility', 'off');
text(200, 5e-7, sprintf('$\\mu$ Station\nCoupling'), 'horizontalalignment', 'center');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
set(gca, 'XTickLabel',[]); set(gca, 'YTickLabel',[]);
ylim([5e-10, 1e-3]);
ldg = legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 1);
ldg.ItemTokenSize = [20, 1];
ax3b = nexttile();
hold on;
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_pz_light('d', 'f'), freqs, 'Hz')))), 'color', [colors(1,:), 0.5]);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_iff_pz_light('d', 'f'), freqs, 'Hz')))), 'color', colors(1,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_iff_pz_mid( 'd', 'f'), freqs, 'Hz')))), 'color', colors(2,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_iff_pz_heavy('d', 'f'), freqs, 'Hz')))), 'color', colors(3,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
xlabel('Frequency [Hz]'); set(gca, 'YTickLabel',[]);
xticks([1e0, 1e1, 1e2]);
yticks(-360:90:360);
ylim([-200, 20]);
linkaxes([ax3,ax3b],'x');
xlim([1, 1e3]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_hac_iff_damped_plants_masses_stiff.pdf', 'width', 350, 'height', 'tall');
#+end_src
#+name: fig:uniaxial_hac_iff_damped_plants_masses
#+caption: Obtained damped plant using Integral Force Feedback for three sample's masses
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_hac_iff_damped_plants_masses_soft}$k_n = 0.01\,N/\mu m$}
#+attr_latex: :options {0.37\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_hac_iff_damped_plants_masses_soft.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_hac_iff_damped_plants_masses_mid}$k_n = 1\,N/\mu m$}
#+attr_latex: :options {0.31\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_hac_iff_damped_plants_masses_mid.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_hac_iff_damped_plants_masses_stiff}$k_n = 100\,N/\mu m$}
#+attr_latex: :options {0.31\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_hac_iff_damped_plants_masses_stiff.png]]
#+end_subfigure
#+end_figure
** Position Feedback Controller
<<ssec:uniaxial_position_control_design>>
The objective is to design high authority feedback controllers for the three nano-hexapod's.
This controller must be robust to the change of sample's mass (from $1\,\text{kg}$ up to $50\,\text{kg}$).
The required feedback bandwidths were estimated in Section ref:sec:uniaxial_noise_budgeting:
- $f_b \approx 10\,\text{Hz}$ for the soft nano-hexapod ($k_n = 0.01\,N/\mu m$).
Near this frequency, the plants (shown in Figure ref:fig:uniaxial_hac_iff_damped_plants_masses_soft) are equivalent to a mass line (i.e. slope of $-40\,dB/\text{dec}$ and a phase of -180 degrees).
The gain of this mass line can vary up to a fact $\approx 5$ (suspended mass from $16\,kg$ up to $65\,kg$).
This means that the designed controller will need to have /large gain margins/ to be robust to the change of sample's mass.
- $\approx 50\,\text{Hz}$ for the relatively stiff nano-hexapod ($k_n = 1\,N/\mu m$).
Similarly to the soft nano-hexapod, the plants near the crossover frequency are equivalent to a mass line (Figure ref:fig:uniaxial_hac_iff_damped_plants_masses_mid).
It will be probably easier to have a little bit more bandwidth in this configuration to be further away from the nano-hexapod suspension mode.
- $\approx 100\,\text{Hz}$ for the stiff nano-hexapod ($k_n = 100\,N/\mu m$).
Contrary to the two first nano-hexapod stiffnesses, here the plants have more complex dynamics near the wanted crossover frequency (see Figure ref:fig:uniaxial_hac_iff_damped_plants_masses_stiff).
The micro-station is not stiff enough to have a clear stiffness line at this frequency.
Therefore, there are both a change of phase and gain depending on the sample's mass.
This makes the robust design of the controller a little bit more complicated.
Position feedback controllers are designed for each nano-hexapod such that it is stable for all considered sample masses with similar stability margins (see Nyquist plots in Figure ref:fig:uniaxial_nyquist_hac).
An arbitrary minimum modulus margin of $0.25$ was chosen when designing the controllers.
These high authority controllers are generally composed of a lag at low frequency for disturbance rejection, a lead to increase the phase margin near the crossover frequency and a low pass filter to increase the robustness to high frequency dynamics.
The controllers used for the three nano-hexapod are shown in Equation eqref:eq:uniaxial_hac_formulas, and the used parameters are summarized in Table ref:tab:uniaxial_feedback_controller_parameters.
\begin{subequations} \label{eq:uniaxial_hac_formulas}
\begin{align}
K_{\text{soft}}(s) &= g \cdot
\underbrace{\frac{s + \omega_0}{s + \omega_i}}_{\text{lag}} \cdot
\underbrace{\frac{1 + \frac{s}{\omega_c/\sqrt{a}}}{1 + \frac{s}{\omega_c \sqrt{a}}}}_{\text{lead}} \cdot
\underbrace{\frac{1}{1 + \frac{s}{\omega_l}}}_{\text{LPF}} \\
K_{\text{mid}}(s) &= g \cdot
\underbrace{\left(\frac{s + \omega_0}{s + \omega_i}\right)^2}_{\text{2 lags}} \cdot
\underbrace{\frac{1 + \frac{s}{\omega_c/\sqrt{a}}}{1 + \frac{s}{\omega_c \sqrt{a}}}}_{\text{lead}} \cdot
\underbrace{\frac{1}{1 + \frac{s}{\omega_l}}}_{\text{LPF}} \\
K_{\text{stiff}}(s) &= g \cdot
\underbrace{\left(\frac{1}{s + \omega_i}\right)^2}_{\text{2 lags}} \cdot
\underbrace{\left(\frac{1 + \frac{s}{\omega_c/\sqrt{a}}}{1 + \frac{s}{\omega_c \sqrt{a}}}\right)^2}_{\text{2 leads}} \cdot
\underbrace{\frac{1}{1 + \frac{s}{\omega_l}}}_{\text{LPF}}
\end{align}
\end{subequations}
#+name: tab:uniaxial_feedback_controller_parameters
#+caption: Parameters used for the position feedback controllers
#+attr_latex: :environment tabularx :width \linewidth :align lXXX
#+attr_latex: :center t :booktabs t
| | *Soft* | *Moderately stiff* | *Stiff* |
|--------+-------------------------------------------+--------------------------------------------+------------------------------------------|
| *Gain* | $g = 4 \cdot 10^5$ | $g = 3 \cdot 10^6$ | $g = 6 \cdot 10^{12}$ |
| *Lead* | $a = 5$, $\omega_c = 20\,Hz$ | $a = 4$, $\omega_c = 70\,Hz$ | $a = 5$, $\omega_c = 100\,Hz$ |
| *Lag* | $\omega_0 = 5\,Hz$, $\omega_i = 0.01\,Hz$ | $\omega_0 = 20\,Hz$, $\omega_i = 0.01\,Hz$ | $\omega_i = 0.01\,Hz$ |
| *LPF* | $\omega_l = 200\,Hz$ | $\omega_l = 300\,Hz$ | $\omega_l = 500\,Hz$ |
The loop gains corresponding to the designed high authority controllers for the three nano-hexapod are shown in Figure ref:fig:uniaxial_loop_gain_hac.
We can see that for the soft and moderately stiff nano-hexapod (Figures ref:fig:uniaxial_nyquist_hac_vc and ref:fig:uniaxial_nyquist_hac_md), the crossover frequency varies a lot with the sample mass.
This is due to the fact that the crossover frequency corresponds to the mass line of the plant (whose gain is inversely proportional to the mass).
For the stiff nano-hexapod (Figure ref:fig:uniaxial_nyquist_hac_pz), it was difficult to achieve the wanted closed-loop bandwidth of $\approx 100\,\text{Hz}$.
A cross-over frequency of $\approx 65\,\text{Hz}$ was achieved instead.
Note that these controllers were not designed using any optimization methods.
The goal is just to have a first estimation of the attainable performance.
#+begin_src matlab :exports none
%% High Authority Controller - Soft Nano-Hexapod
% Lead to increase phase margin
a = 5; % Amount of phase lead / width of the phase lead / high frequency gain
wc = 2*pi*20; % Frequency with the maximum phase lead [rad/s]
H_lead = (1 + s/(wc/sqrt(a)))/(1 + s/(wc*sqrt(a)));
% Lag at low frequency
H_lag = (s + 2*pi*5)/(s + 2*pi*0.01);
% Low Pass filter to increase robustness
H_lpf = 1/(1 + s/2/pi/200);
% High Authority Controller
K_hac_vc = 4e5 * ... % Gain
H_lead * ... % Lead
H_lag * ... % Lag
H_lpf; % LPF
K_hac_vc.InputName = {'d'};
K_hac_vc.OutputName = {'f'};
#+end_src
#+begin_src matlab :exports none
%% High Authority Controller - Mid Stiffness Nano-Hexapod
% Lead to increase phase margin
a = 4; % Amount of phase lead / width of the phase lead / high frequency gain
wc = 2*pi*70; % Frequency with the maximum phase lead [rad/s]
H_lead = (1 + s/(wc/sqrt(a)))/(1 + s/(wc*sqrt(a)));
% Lag at low frequency
H_lag = ((s + 2*pi*15)/(s + 2*pi*0.01))^2;
% Low Pass filter to increase robustness
H_lpf = 1/(1 + s/2/pi/300);
% High Authority Controller
K_hac_md = 3e6 * ... % Gain
H_lead * ... % Lead
H_lag * ... % Lag
H_lpf; % LPF
K_hac_md.InputName = {'d'};
K_hac_md.OutputName = {'f'};
#+end_src
#+begin_src matlab :exports none
%% High Authority Controller - Stiff Nano-Hexapod
% Lead to increase phase margin
a = 5; % Amount of phase lead / width of the phase lead / high frequency gain
wc = 2*pi*100; % Frequency with the maximum phase lead [rad/s]
H_lead = ((1 + s/(wc/sqrt(a)))/(1 + s/(wc*sqrt(a))))^2;
% Integrator
H_int = 1/(s + 2*pi*0.01)^2;
% Low Pass filter to increase robustness
H_lpf = 1/(1 + s/2/pi/500);
% High Authority Controller
K_hac_pz = 6e12 * ... % Gain
H_lead * ... % Lead
H_int * ... % Lag
H_lpf; % LPF
K_hac_pz.InputName = {'d'};
K_hac_pz.OutputName = {'f'};
#+end_src
#+begin_src matlab :exports none :tangle no
%% Save High Authority Controllers
save('./matlab/mat/uniaxial_high_authority_controllers.mat', ...
'K_hac_vc', 'K_hac_md', 'K_hac_pz');
#+end_src
#+begin_src matlab :exports none :eval no
%% Save High Authority Controllers
save('./mat/uniaxial_high_authority_controllers.mat', ...
'K_hac_vc', 'K_hac_md', 'K_hac_pz');
#+end_src
#+begin_src matlab :exports none
%% Compute Loop gain for Nyquist Plot
L_vc_light = squeeze(freqresp(K_hac_vc*G_iff_vc_light('d', 'f'), freqs, 'Hz'));
L_vc_mid = squeeze(freqresp(K_hac_vc*G_iff_vc_mid( 'd', 'f'), freqs, 'Hz'));
L_vc_heavy = squeeze(freqresp(K_hac_vc*G_iff_vc_heavy('d', 'f'), freqs, 'Hz'));
L_md_light = squeeze(freqresp(K_hac_md*G_iff_md_light('d', 'f'), freqs, 'Hz'));
L_md_mid = squeeze(freqresp(K_hac_md*G_iff_md_mid( 'd', 'f'), freqs, 'Hz'));
L_md_heavy = squeeze(freqresp(K_hac_md*G_iff_md_heavy('d', 'f'), freqs, 'Hz'));
L_pz_light = squeeze(freqresp(K_hac_pz*G_iff_pz_light('d', 'f'), freqs, 'Hz'));
L_pz_mid = squeeze(freqresp(K_hac_pz*G_iff_pz_mid( 'd', 'f'), freqs, 'Hz'));
L_pz_heavy = squeeze(freqresp(K_hac_pz*G_iff_pz_heavy('d', 'f'), freqs, 'Hz'));
#+end_src
#+begin_src matlab :exports none :results none
%% Nyquist Plot - Hight Authority Controller for all three nano-hexapod stiffnesses and all sample masses
figure;
hold on;
plot(real(L_vc_light), +imag(L_vc_light), '-', 'color', [colors(1,:), 0.5], 'DisplayName', '$k_n = 0.01\,N/\mu m$')
plot(real(L_vc_light), -imag(L_vc_light), '-', 'color', [colors(1,:), 0.5], 'HandleVisibility', 'off')
plot(real(L_vc_mid ), +imag(L_vc_mid ), '-', 'color', [colors(1,:), 0.5], 'HandleVisibility', 'off')
plot(real(L_vc_mid ), -imag(L_vc_mid ), '-', 'color', [colors(1,:), 0.5], 'HandleVisibility', 'off')
plot(real(L_vc_heavy), +imag(L_vc_heavy), '-', 'color', [colors(1,:), 0.5], 'HandleVisibility', 'off')
plot(real(L_vc_heavy), -imag(L_vc_heavy), '-', 'color', [colors(1,:), 0.5], 'HandleVisibility', 'off')
plot(real(L_md_light), +imag(L_md_light), '-', 'color', [colors(2,:), 0.5], 'DisplayName', '$k_n = 1\,N/\mu m$')
plot(real(L_md_light), -imag(L_md_light), '-', 'color', [colors(2,:), 0.5], 'HandleVisibility', 'off')
plot(real(L_md_mid ), +imag(L_md_mid ), '-', 'color', [colors(2,:), 0.5], 'HandleVisibility', 'off')
plot(real(L_md_mid ), -imag(L_md_mid ), '-', 'color', [colors(2,:), 0.5], 'HandleVisibility', 'off')
plot(real(L_md_heavy), +imag(L_md_heavy), '-', 'color', [colors(2,:), 0.5], 'HandleVisibility', 'off')
plot(real(L_md_heavy), -imag(L_md_heavy), '-', 'color', [colors(2,:), 0.5], 'HandleVisibility', 'off')
plot(real(L_pz_light), +imag(L_pz_light), '-', 'color', [colors(3,:), 0.5], 'DisplayName', '$k_n = 100\,N/\mu m$')
plot(real(L_pz_light), -imag(L_pz_light), '-', 'color', [colors(3,:), 0.5], 'HandleVisibility', 'off')
plot(real(L_pz_mid ), +imag(L_pz_mid ), '-', 'color', [colors(3,:), 0.5], 'HandleVisibility', 'off')
plot(real(L_pz_mid ), -imag(L_pz_mid ), '-', 'color', [colors(3,:), 0.5], 'HandleVisibility', 'off')
plot(real(L_pz_heavy), +imag(L_pz_heavy), '-', 'color', [colors(3,:), 0.5], 'HandleVisibility', 'off')
plot(real(L_pz_heavy), -imag(L_pz_heavy), '-', 'color', [colors(3,:), 0.5], 'HandleVisibility', 'off')
plot(-1, 0, 'kx', 'HandleVisibility', 'off');
hold off;
set(gca, 'XScale', 'lin'); set(gca, 'YScale', 'lin');
xlabel('Real'); ylabel('Imag');
legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 1);
xlim([-3.8, 0.2]); ylim([-2, 2]);
axis square;
#+end_src
#+begin_src matlab :exports none :results none
%% Nyquist Plot - Hight Authority Controller - Soft Nano-Hexapod
figure;
hold on;
plot(real(L_vc_light), +imag(L_vc_light), '-', 'color', colors(1,:), 'DisplayName', '$m_s = 1\,$kg')
plot(real(L_vc_light), -imag(L_vc_light), '-', 'color', colors(1,:), 'HandleVisibility', 'off')
plot(real(L_vc_mid ), +imag(L_vc_mid ), '-', 'color', colors(2,:), 'DisplayName', '$m_s = 25\,$kg')
plot(real(L_vc_mid ), -imag(L_vc_mid ), '-', 'color', colors(2,:), 'HandleVisibility', 'off')
plot(real(L_vc_heavy), +imag(L_vc_heavy), '-', 'color', colors(3,:), 'DisplayName', '$m_s = 50\,$kg')
plot(real(L_vc_heavy), -imag(L_vc_heavy), '-', 'color', colors(3,:), 'HandleVisibility', 'off')
% Minimum modul margin
vc_mod_margin = min([min(abs(L_vc_light + 1)), min(abs(L_vc_mid + 1)), min(abs(L_vc_heavy + 1))]);
plot(-1 + vc_mod_margin*cos(linspace(0,2*pi,100)), vc_mod_margin*sin(linspace(0,2*pi,100)), 'k-', 'DisplayName', sprintf('$r = %.2f$', vc_mod_margin))
plot(-1, 0, 'kx', 'HandleVisibility', 'off');
hold off;
set(gca, 'XScale', 'lin'); set(gca, 'YScale', 'lin');
xlabel('Real'); ylabel('Imag');
leg = legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 1);
leg.ItemTokenSize(1) = 15
xlim([-3.8, 0.2]); ylim([-2, 2]);
axis square;
#+end_src
#+begin_src matlab :tangle no :exports results :results file none
exportFig('figs/uniaxial_nyquist_hac_vc.pdf', 'width', 'third', 'height', 'normal');
#+end_src
#+begin_src matlab :exports none :results none
%% Nyquist Plot - Hight Authority Controller - Soft Nano-Hexapod
figure;
hold on;
plot(real(L_md_light), +imag(L_md_light), '-', 'color', colors(1,:), 'DisplayName', '$m_s = 1\,$kg')
plot(real(L_md_light), -imag(L_md_light), '-', 'color', colors(1,:), 'HandleVisibility', 'off')
plot(real(L_md_mid ), +imag(L_md_mid ), '-', 'color', colors(2,:), 'DisplayName', '$m_s = 25\,$kg')
plot(real(L_md_mid ), -imag(L_md_mid ), '-', 'color', colors(2,:), 'HandleVisibility', 'off')
plot(real(L_md_heavy), +imag(L_md_heavy), '-', 'color', colors(3,:), 'DisplayName', '$m_s = 50\,$kg')
plot(real(L_md_heavy), -imag(L_md_heavy), '-', 'color', colors(3,:), 'HandleVisibility', 'off')
% Minimum modul margin
md_mod_margin = min([min(abs(L_md_light + 1)), min(abs(L_md_mid + 1)), min(abs(L_md_heavy + 1))]);
plot(-1 + md_mod_margin*cos(linspace(0,2*pi,100)), md_mod_margin*sin(linspace(0,2*pi,100)), 'k-', 'DisplayName', sprintf('$r = %.2f$', md_mod_margin))
plot(-1, 0, 'kx', 'HandleVisibility', 'off');
hold off;
set(gca, 'XScale', 'lin'); set(gca, 'YScale', 'lin');
xlabel('Real'); ylabel('Imag');
leg = legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 1);
leg.ItemTokenSize(1) = 15
xlim([-3.8, 0.2]); ylim([-2, 2]);
axis square;
#+end_src
#+begin_src matlab :tangle no :exports results :results file none
exportFig('figs/uniaxial_nyquist_hac_md.pdf', 'width', 'third', 'height', 'normal');
#+end_src
#+begin_src matlab :exports none :results none
%% Nyquist Plot - Hight Authority Controller - Soft Nano-Hexapod
figure;
hold on;
plot(real(L_pz_light), +imag(L_pz_light), '-', 'color', colors(1,:), 'DisplayName', '$m_s = 1\,$kg')
plot(real(L_pz_light), -imag(L_pz_light), '-', 'color', colors(1,:), 'HandleVisibility', 'off')
plot(real(L_pz_mid ), +imag(L_pz_mid ), '-', 'color', colors(2,:), 'DisplayName', '$m_s = 25\,$kg')
plot(real(L_pz_mid ), -imag(L_pz_mid ), '-', 'color', colors(2,:), 'HandleVisibility', 'off')
plot(real(L_pz_heavy), +imag(L_pz_heavy), '-', 'color', colors(3,:), 'DisplayName', '$m_s = 50\,$kg')
plot(real(L_pz_heavy), -imag(L_pz_heavy), '-', 'color', colors(3,:), 'HandleVisibility', 'off')
% Minimum modul margin
pz_mod_margin = min([min(abs(L_pz_light + 1)), min(abs(L_pz_mid + 1)), min(abs(L_pz_heavy + 1))]);
plot(-1 + pz_mod_margin*cos(linspace(0,2*pi,100)), pz_mod_margin*sin(linspace(0,2*pi,100)), 'k-', 'DisplayName', sprintf('$r = %.2f$', pz_mod_margin))
plot(-1, 0, 'kx', 'HandleVisibility', 'off');
hold off;
set(gca, 'XScale', 'lin'); set(gca, 'YScale', 'lin');
xlabel('Real'); ylabel('Imag');
leg = legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 1);
leg.ItemTokenSize(1) = 15
xlim([-3.8, 0.2]); ylim([-2, 2]);
axis square;
#+end_src
#+begin_src matlab :tangle no :exports results :results file none
exportFig('figs/uniaxial_nyquist_hac_pz.pdf', 'width', 'third', 'height', 'normal');
#+end_src
#+name: fig:uniaxial_nyquist_hac
#+caption: Nyquist Plot for the High Authority Controller. The minimum modulus margin is illustrated by the black circle.
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_nyquist_hac_vc}$k_n = 0.01\,N/\mu m$}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_nyquist_hac_vc.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_nyquist_hac_md}$k_n = 1\,N/\mu m$}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_nyquist_hac_md.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_nyquist_hac_pz}$k_n = 100\,N/\mu m$}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_nyquist_hac_pz.png]]
#+end_subfigure
#+end_figure
#+begin_src matlab :exports none :results none
%% Loop Gain - High Authority Controller - Relatively soft nano-hexapod
figure;
tiledlayout(3, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
ax1 = nexttile([2,1]);
hold on;
plot(freqs, abs(L_vc_light), 'color', colors(1,:), 'DisplayName', '$m_s = 1\,$kg');
plot(freqs, abs(L_vc_mid), 'color', colors(2,:), 'DisplayName', '$m_s = 25\,$kg');
plot(freqs, abs(L_vc_heavy), 'color', colors(3,:), 'DisplayName', '$m_s = 50\,$kg');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Loop Gain'); set(gca, 'XTickLabel',[]);
ylim([1e-3, 1e3]);
yticks([1e-2, 1, 1e2])
leg = legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 1);
leg.ItemTokenSize(1) = 15
ax2 = nexttile;
hold on;
plot(freqs, 180/pi*unwrap(angle(L_vc_light)), 'color', colors(1,:));
plot(freqs, 180/pi*unwrap(angle(L_vc_mid )), 'color', colors(2,:));
plot(freqs, 180/pi*unwrap(angle(L_vc_heavy)), 'color', colors(3,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
hold off;
yticks(-360:45:360);
ylim([-225, -90]);
linkaxes([ax1,ax2],'x');
xlim([1, 500]);
xticks([1, 10, 100]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file none
exportFig('figs/uniaxial_loop_gain_hac_vc.pdf', 'width', 'third', 'height', 500);
#+end_src
#+begin_src matlab :exports none :results none
%% Loop Gain - High Authority Controller - Relatively stiff nano-hexapod
figure;
tiledlayout(3, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
ax1 = nexttile([2,1]);
hold on;
plot(freqs, abs(L_md_light), 'color', colors(1,:), 'DisplayName', '$m_s = 1\,$kg');
plot(freqs, abs(L_md_mid), 'color', colors(2,:), 'DisplayName', '$m_s = 25\,$kg');
plot(freqs, abs(L_md_heavy), 'color', colors(3,:), 'DisplayName', '$m_s = 50\,$kg');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Loop Gain'); set(gca, 'XTickLabel',[]);
ylim([1e-3, 1e3]);
yticks([1e-2, 1, 1e2])
ax2 = nexttile;
hold on;
plot(freqs, 180/pi*unwrap(angle(L_md_light)), 'color', colors(1,:));
plot(freqs, 180/pi*unwrap(angle(L_md_mid )), 'color', colors(2,:));
plot(freqs, 180/pi*unwrap(angle(L_md_heavy)), 'color', colors(3,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
hold off;
yticks(-360:45:360);
ylim([-225, -90]);
linkaxes([ax1,ax2],'x');
xlim([1, 500]);
xticks([1, 10, 100]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file none
exportFig('figs/uniaxial_loop_gain_hac_md.pdf', 'width', 'third', 'height', 500);
#+end_src
#+begin_src matlab :exports none :results none
%% Loop Gain - High Authority Controller - Stiff nano-hexapod
figure;
tiledlayout(3, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
ax1 = nexttile([2,1]);
hold on;
plot(freqs, abs(L_pz_light), 'color', colors(1,:), 'DisplayName', '$m_s = 1\,$kg');
plot(freqs, abs(L_pz_mid), 'color', colors(2,:), 'DisplayName', '$m_s = 25\,$kg');
plot(freqs, abs(L_pz_heavy), 'color', colors(3,:), 'DisplayName', '$m_s = 50\,$kg');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Loop Gain'); set(gca, 'XTickLabel',[]);
ylim([1e-3, 1e3]);
yticks([1e-2, 1, 1e2])
ax2 = nexttile;
hold on;
plot(freqs, 180/pi*unwrap(angle(L_pz_light)), 'color', colors(1,:));
plot(freqs, 180/pi*unwrap(angle(L_pz_mid )), 'color', colors(2,:));
plot(freqs, 180/pi*unwrap(angle(L_pz_heavy)), 'color', colors(3,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
hold off;
yticks(-360:45:360);
ylim([-225, -90]);
linkaxes([ax1,ax2],'x');
xlim([1, 500]);
xticks([1, 10, 100]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file none
exportFig('figs/uniaxial_loop_gain_hac_pz.pdf', 'width', 'third', 'height', 500);
#+end_src
#+name: fig:uniaxial_loop_gain_hac
#+caption: Loop gain for the High Authority Controller
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_loop_gain_hac_vc}$k_n = 0.01\,N/\mu m$}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :width 0.95\linewidth
[[file:figs/uniaxial_loop_gain_hac_vc.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_loop_gain_hac_md}$k_n = 1\,N/\mu m$}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :width 0.95\linewidth
[[file:figs/uniaxial_loop_gain_hac_md.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_loop_gain_hac_pz}$k_n = 100\,N/\mu m$}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :width 0.95\linewidth
[[file:figs/uniaxial_loop_gain_hac_pz.png]]
#+end_subfigure
#+end_figure
** Closed-Loop Noise Budgeting
<<ssec:uniaxial_position_control_cl_noise_budget>>
The high authority position feedback controllers are then implemented and the closed-loop sensitivity to disturbances are computed.
These are compared with the open-loop and damped plants cases in Figure ref:fig:uniaxial_sensitivity_dist_hac_lac for just one configuration (moderately stiff nano-hexapod with 25kg sample's mass).
As expected, the sensitivity to disturbances is decreased in the controller bandwidth and slightly increase outside this bandwidth.
#+begin_src matlab :exports none
%% Compute Closed Loop Systems
G_hac_iff_vc_light = feedback(G_iff_vc_light, K_hac_vc, 'name', -1);
G_hac_iff_vc_mid = feedback(G_iff_vc_mid , K_hac_vc, 'name', -1);
G_hac_iff_vc_heavy = feedback(G_iff_vc_heavy, K_hac_vc, 'name', -1);
G_hac_iff_md_light = feedback(G_iff_md_light, K_hac_md, 'name', -1);
G_hac_iff_md_mid = feedback(G_iff_md_mid , K_hac_md, 'name', -1);
G_hac_iff_md_heavy = feedback(G_iff_md_heavy, K_hac_md, 'name', -1);
G_hac_iff_pz_light = feedback(G_iff_pz_light, K_hac_pz, 'name', -1);
G_hac_iff_pz_mid = feedback(G_iff_pz_mid , K_hac_pz, 'name', -1);
G_hac_iff_pz_heavy = feedback(G_iff_pz_heavy, K_hac_pz, 'name', -1);
#+end_src
#+begin_src matlab :exports none
%% Verify Stability
isstable(G_hac_iff_vc_light) && isstable(G_hac_iff_vc_mid) && isstable(G_hac_iff_vc_heavy)
isstable(G_hac_iff_md_light) && isstable(G_hac_iff_md_mid) && isstable(G_hac_iff_md_heavy)
isstable(G_hac_iff_pz_light) && isstable(G_hac_iff_pz_mid) && isstable(G_hac_iff_pz_heavy)
#+end_src
#+begin_src matlab :exports none :results none
%% Change of sensitivity to disturbances with LAC and with HAC-LAC
figure;
hold on;
plot(freqs, abs(squeeze(freqresp(G_md_mid( 'd', 'fs'), freqs, 'Hz'))), 'k-');
plot(freqs, abs(squeeze(freqresp(G_iff_md_mid('d', 'fs'), freqs, 'Hz'))), 'color', colors(1,:));
plot(freqs, abs(squeeze(freqresp(G_hac_iff_md_mid('d', 'fs'), freqs, 'Hz'))), 'color', colors(2,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xticks([1e0, 1e1, 1e2]);
ylabel('Amplitude $d/f_{s}$ [m/N]'); xlabel('Frequency [Hz]');
xlim([1, 500]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_sensitivity_dist_hac_lac_fs.pdf', 'width', 'third', 'height', 'normal');
#+end_src
#+begin_src matlab :exports none :results none
figure;
hold on;
plot(freqs, abs(squeeze(freqresp(G_md_mid( 'd', 'ft'), freqs, 'Hz'))), 'k-');
plot(freqs, abs(squeeze(freqresp(G_iff_md_mid('d', 'ft'), freqs, 'Hz'))), 'color', colors(1,:));
plot(freqs, abs(squeeze(freqresp(G_hac_iff_md_mid('d', 'ft'), freqs, 'Hz'))), 'color', colors(2,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xticks([1e0, 1e1, 1e2]);
ylabel('Amplitude $d/f_{t}$ [m/N]'); xlabel('Frequency [Hz]');
xlim([1, 500]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_sensitivity_dist_hac_lac_ft.pdf', 'width', 'third', 'height', 'normal');
#+end_src
#+begin_src matlab :exports none :results none
figure;
hold on;
plot(freqs, abs(squeeze(freqresp(G_md_mid( 'd', 'xf'), freqs, 'Hz'))), 'k-', 'DisplayName', 'OL');
plot(freqs, abs(squeeze(freqresp(G_iff_md_mid('d', 'xf'), freqs, 'Hz'))), 'color', colors(1,:), 'DisplayName', 'IFF');
plot(freqs, abs(squeeze(freqresp(G_hac_iff_md_mid('d', 'xf'), freqs, 'Hz'))), 'color', colors(2,:), 'DisplayName', 'HAC-IFF');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xticks([1e0, 1e1, 1e2]);
ylabel('Amplitude $d/x_{f}$ [m/m]'); xlabel('Frequency [Hz]');
legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 1);
xlim([1, 500]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_sensitivity_dist_hac_lac_xf.pdf', 'width', 'third', 'height', 'normal');
#+end_src
#+name: fig:uniaxial_sensitivity_dist_hac_lac
#+caption: Change of sensitivity to disturbances with LAC and with acrshort:haclac. Nano-Hexapod with $k_n = 1\,N/\mu m$ and sample mass of $25\,kg$ are used. $f_s$ the direct forces applied on the sample (\subref{fig:uniaxial_sensitivity_dist_hac_lac_fs}), $f_t$ disturbances from the micro-station stages (\subref{fig:uniaxial_sensitivity_dist_hac_lac_ft}) and $x_f$ the floor motion (\subref{fig:uniaxial_sensitivity_dist_hac_lac_fs})
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_sensitivity_dist_hac_lac_fs}Direct forces}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_sensitivity_dist_hac_lac_fs.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_sensitivity_dist_hac_lac_ft}$\mu\text{-station}$ disturbances}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_sensitivity_dist_hac_lac_ft.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_sensitivity_dist_hac_lac_xf}Floor motion}
#+attr_latex: :options {0.33\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_sensitivity_dist_hac_lac_xf.png]]
#+end_subfigure
#+end_figure
The cumulative amplitude spectrum of the motion $d$ is computed for all nano-hexapod configurations, all sample masses and in the open-loop (OL), damped (IFF) and position controlled (HAC-IFF) cases.
The results are shown in Figure ref:fig:uniaxial_cas_hac_lac.
Obtained root mean square values of the distance $d$ are better for the soft nano-hexapod ($\approx 25\,nm$ to $\approx 35\,nm$ depending on the sample's mass) than for the stiffer nano-hexapod (from $\approx 30\,nm$ to $\approx 70\,nm$).
#+begin_src matlab :exports none :results none
%% Cumulative Amplitude Spectrum for all three nano-hexapod stiffnesses - Comparison of OL, IFF and HAC-LAC cases
figure;
hold on;
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_vc_mid('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_vc_mid('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [0,0,0,0.5], 'DisplayName', 'OL');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_vc_light('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_vc_light('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [0,0,0,0.5], 'HandleVisibility', 'off');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_vc_heavy('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_vc_heavy('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [0,0,0,0.5], 'HandleVisibility', 'off');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_iff_vc_mid('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_iff_vc_mid('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [colors(1,:), 0.5], 'DisplayName', 'IFF');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_iff_vc_light('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_iff_vc_light('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [colors(1,:), 0.5], 'HandleVisibility', 'off');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_iff_vc_heavy('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_iff_vc_heavy('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [colors(1,:), 0.5], 'HandleVisibility', 'off');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_hac_iff_vc_mid('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_hac_iff_vc_mid('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [colors(2,:), 0.5], 'DisplayName', 'HAC-IFF');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_hac_iff_vc_light('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_hac_iff_vc_light('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [colors(2,:), 0.5], 'HandleVisibility', 'off');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_hac_iff_vc_heavy('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_hac_iff_vc_heavy('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [colors(2,:), 0.5], 'HandleVisibility', 'off');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xticks([1e0, 1e1, 1e2]);
ylabel('CAS of $d$ [m]'); xlabel('Frequency [Hz]');
legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 1);
xlim([1, 500]);
ylim([2e-10, 3e-6])
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_cas_hac_lac_soft.pdf', 'width', 450, 'height', 'normal');
#+end_src
#+begin_src matlab :exports none :results none
figure;
hold on;
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_md_mid('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_md_mid('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [0,0,0,0.5]);
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_md_light('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_md_light('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [0,0,0,0.5]);
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_md_heavy('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_md_heavy('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [0,0,0,0.5]);
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_iff_md_mid('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_iff_md_mid('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [colors(1,:), 0.5]);
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_iff_md_light('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_iff_md_light('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [colors(1,:), 0.5]);
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_iff_md_heavy('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_iff_md_heavy('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [colors(1,:), 0.5]);
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_hac_iff_md_mid('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_hac_iff_md_mid('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [colors(2,:), 0.5]);
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_hac_iff_md_light('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_hac_iff_md_light('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [colors(2,:), 0.5]);
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_hac_iff_md_heavy('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_hac_iff_md_heavy('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [colors(2,:), 0.5]);
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xticks([1e0, 1e1, 1e2]);
xlabel('Frequency [Hz]'); set(gca, 'YTickLabel',[]);
xlim([1, 500]);
ylim([2e-10, 3e-6])
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_cas_hac_lac_mid.pdf', 'width', 400, 'height', 'normal');
#+end_src
#+begin_src matlab :exports none :results none
figure;
hold on;
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_pz_mid('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_pz_mid('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [0,0,0,0.5]);
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_pz_light('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_pz_light('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [0,0,0,0.5]);
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_pz_heavy('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_pz_heavy('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [0,0,0,0.5]);
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_iff_pz_mid('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_iff_pz_mid('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [colors(1,:), 0.5]);
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_iff_pz_light('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_iff_pz_light('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [colors(1,:), 0.5]);
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_iff_pz_heavy('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_iff_pz_heavy('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [colors(1,:), 0.5]);
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_hac_iff_pz_mid('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_hac_iff_pz_mid('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [colors(2,:), 0.5]);
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_hac_iff_pz_light('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_hac_iff_pz_light('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [colors(2,:), 0.5]);
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_hac_iff_pz_heavy('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_hac_iff_pz_heavy('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'color', [colors(2,:), 0.5]);
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xticks([1e0, 1e1, 1e2]);
xlabel('Frequency [Hz]'); set(gca, 'YTickLabel',[]);
xlim([1, 500]);
ylim([2e-10, 3e-6])
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_cas_hac_lac_stiff.pdf', 'width', 400, 'height', 'normal');
#+end_src
#+name: fig:uniaxial_cas_hac_lac
#+caption: Cumulative Amplitude Spectrum for all three nano-hexapod stiffnesses - Comparison of OL, IFF and acrshort:haclac cases
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_cas_hac_lac_soft}$k_n = 0.01\,N/\mu m$}
#+attr_latex: :options {0.37\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_cas_hac_lac_soft.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_cas_hac_lac_mid}$k_n = 1\,N/\mu m$}
#+attr_latex: :options {0.31\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_cas_hac_lac_mid.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_cas_hac_lac_stiff}$k_n = 100\,N/\mu m$}
#+attr_latex: :options {0.31\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_cas_hac_lac_stiff.png]]
#+end_subfigure
#+end_figure
** Conclusion
:PROPERTIES:
:UNNUMBERED: t
:END:
Based on the open-loop noise budgeting made in Section ref:sec:uniaxial_noise_budgeting, the closed-loop bandwidth required to obtain a vibration level of $\approx 20\,nm\,\text{RMS}$ was estimated.
In order to achieve such bandwidth, the acrshort:haclac strategy was followed which consists of first using an active damping controller (studied in Section ref:sec:uniaxial_active_damping) and then adding an high authority position feedback controller.
In this section, feedback controllers were designed in such a way that the required closed-loop bandwidth was reached while being robust to a change of payload mass.
The attainable vibration control performances were estimated for the three nano-hexapod stiffnesses and were found to be close to the required values.
Yet, the stiff nano-hexapod ($k_n = 100\,N/\mu m$) is requiring the largest feedback bandwidth that is shown to be difficult to achieve while being robust to the change of payload mass.
A slight advantage can be given to the soft nano-hexapod as it requires less feedback bandwidth while giving better stability results.
* Effect of limited micro-station compliance
:PROPERTIES:
:HEADER-ARGS:matlab+: :tangle matlab/uniaxial_7_support_compliance.m
:END:
<<sec:uniaxial_support_compliance>>
** Introduction :ignore:
In this section, the impact of the compliance of the support (i.e. the micro-station) on the dynamics of the plant to control is studied.
This is a critical point as the dynamics of the micro-station is complex, depends on the considered direction (see measurements in Figure ref:fig:uniaxial_comp_frf_meas_model) and may vary with position and time.
It would be much better to have a plant dynamics which is not impacted by the micro-station.
Therefore, the objective in this section is to obtain some guidance for the design of a nano-hexapod that will not by impacted by the complex micro-station dynamics.
In order to study this, two models are used (Figure ref:fig:uniaxial_support_compliance_models).
The first one consists of the nano-hexapod directly fixed on top of the granite, therefore neglecting any support compliance (Figure ref:fig:uniaxial_support_compliance_nano_hexapod_only).
The second one consists of the the nano-hexapod fixed on top of the micro-station having some limited compliance (Figure ref:fig:uniaxial_support_compliance_test_system)
#+begin_src latex :file uniaxial_support_compliance_nano_hexapod_only.pdf :results file raw silent
\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
% Granite
\draw[fill=white!70!black] (-1*\massw, -\massh) rectangle (\massw, 0) node[pos=0.5]{Granite};
\coordinate(origin) at (0,0);
% Nano Hexapod
\begin{scope}[shift={(0, 0)}]
% Mass
\draw[draw=colorred,fill=colorred!10!white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5, color=colorred]{$m_{n}$};
% Spring, Damper, and Actuator
\draw[spring,draw=colorred] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1, color=colorred]{$k_{n}$};
\draw[damper={colorred}{}{}] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2, color=colorred]{$c_{n}$};
\draw[actuator={0.4}{0.2}{colorred}] ( 0.4*\massw, 0) -- (0.4*\massw, \spaceh) node[midway, left=0.1, color=colorred](F){$f$};
% Displacements
\draw[dashed] (0.5*\massw, \spaceh) -- coordinate[near end](dhigh) ++(1.2, 0);
% 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]{$\nu$-hexapod};
\end{scope}
\draw[<->, dashed, colorred] (dhigh) --node[midway, right]{$L^\prime$} (origin-|dhigh);
\end{tikzpicture}
#+end_src
#+begin_src latex :file uniaxial_support_compliance_test_system.pdf :results file raw silent
\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
% Granite
\draw[fill=white!70!black] (-1*\massw, -\massh) rectangle (\massw, 0) node[pos=0.5]{Granite};
\coordinate(origin) at (0,0);
% Micro Station
\begin{scope}[shift={(0, 0)}]
% Mass
\draw[draw=colorblue,fill=colorblue!10!white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5, color=colorblue]{$m_{\mu}$};
% Spring, Damper, and Actuator
\draw[spring,draw=colorblue] (-0.3*\massw, 0) -- (-0.3*\massw, \spaceh) node[midway, left=0.1, color=colorblue]{$k_{\mu}$};
\draw[damper={colorblue}{}{}] ( 0.3*\massw, 0) -- ( 0.3*\massw, \spaceh) node[midway, left=0.2, color=colorblue]{$c_{\mu}$};
% Displacements
\draw[dashed] (0.5*\massw, \spaceh+\massh) -- coordinate[near end](dmid) ++(0.3, 0);
% 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]{$\mu$-station};
\end{scope}
% Nano Station
\begin{scope}[shift={(0, \spaceh+\massh)}]
% Mass
\draw[draw=colorred,fill=colorred!10!white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5, color=colorred]{$m_{n}$};
% Spring, Damper, and Actuator
\draw[spring,draw=colorred] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1, color=colorred]{$k_{n}$};
\draw[damper={colorred}{}{}] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2, color=colorred]{$c_{n}$};
\draw[actuator={0.4}{0.2}{colorred}] ( 0.4*\massw, 0) -- (0.4*\massw, \spaceh) node[midway, left=0.1, color=colorred](F){$f$};
% Displacements
\draw[dashed] (0.5*\massw, \spaceh) -- coordinate[near end](dhigh) ++(1.2, 0);
% 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]{$\nu$-hexapod};
\end{scope}
\draw[<->, dashed, coloryellow] (dhigh) --node[midway, right]{$d$} (origin-|dhigh);
\draw[<->, dashed, colorred] (dmid) --node[midway, right]{$L$} (dhigh-|dmid);
\end{tikzpicture}
#+end_src
#+name: fig:uniaxial_support_compliance_models
#+caption: Models used to study the effect of limited support compliance
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_support_compliance_nano_hexapod_only}Nano-Hexapod fixed directly on the Granite}
#+attr_latex: :options {0.49\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_support_compliance_nano_hexapod_only.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_support_compliance_test_system}Nano-Hexapod fixed on top of the Micro-Station}
#+attr_latex: :options {0.49\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_support_compliance_test_system.png]]
#+end_subfigure
#+end_figure
** Matlab Init :noexport:ignore:
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
<<matlab-dir>>
#+end_src
#+begin_src matlab :exports none :results silent :noweb yes
<<matlab-init>>
#+end_src
#+begin_src matlab :tangle no :noweb yes
<<m-init-path>>
#+end_src
#+begin_src matlab :eval no :noweb yes
<<m-init-path-tangle>>
#+end_src
#+begin_src matlab :noweb yes
<<m-init-other>>
#+end_src
#+begin_src matlab
%% Load the micro-station parameters
load('uniaxial_micro_station_parameters.mat')
#+end_src
#+begin_src matlab
%% Frequency Vector [Hz]
freqs = logspace(0, 3, 1000);
#+end_src
** Neglected support compliance
Let's first neglect the limited compliance of the micro-station and use the uniaxial model show in Figure ref:fig:uniaxial_support_compliance_nano_hexapod_only.
Let's choose a nano-hexapod mass (including the payload) of $20\,\text{kg}$ and three hexapod stiffnesses such that their resonance frequencies are at $\omega_{n} = 10\,\text{Hz}$, $\omega_{n} = 70\,\text{Hz}$ and $\omega_{n} = 400\,\text{Hz}$.
The obtained transfer functions from $F$ to $L^\prime$ (shown in Figure ref:fig:uniaxial_effect_support_compliance_neglected) are simple second order low pass filters.
When neglecting the support compliance, large feedback bandwidth can be achieve for all three Nano-Hexapod.
#+begin_src matlab :exports none
%% Nano-Hexapod Parameters
m = 20; % Mass [kg]
% "Soft" Nano-Hexapod
k_soft = m*(2*pi*10)^2; % Stiffness [N/m]
c_soft = 0.1*2*sqrt(m*k_soft); % Damping [N/(m/s)]
% "Mid" Nano-Hexapod
k_mid = m*(2*pi*70)^2; % Stiffness [N/m]
c_mid = 0.1*2*sqrt(m*k_mid); % Damping [N/(m/s)]
% "Stiff" Nano-Hexapod
k_stiff = m*(2*pi*350)^2; % Stiffness [N/m]
c_stiff = 0.1*2*sqrt(m*k_stiff); % Damping [N/(m/s)]
#+end_src
#+begin_src matlab :exports none
%% Compute the transfer functions for considered nano-hexapods - From F to L'
% "Soft" Nano-Hexapod
G_soft_a = 1/(m*s^2 + c_soft*s + k_soft); % Transfer function from F to L'
% "Mid" Nano-Hexapod
G_mid_a = 1/(m*s^2 + c_mid*s + k_mid); % Transfer function from F to L'
% "Stiff" Nano-Hexapod
G_stiff_a = 1/(m*s^2 + c_stiff*s + k_stiff); % Transfer function from F to L'
#+end_src
#+begin_src matlab :exports none :results none
%% Obtained transfer functions from F to L when neglecing support compliance
freqs = logspace(0, 3, 1000);
figure;
hold on;
plot(freqs, abs(squeeze(freqresp(G_soft_a, freqs, 'Hz'))), '-', 'color', colors(1,:));
text(50, 5e-5, '$\omega_n =$ 10Hz', 'horizontalalignment', 'center');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('Magnitude [m/N]');
xlim([freqs(1), freqs(end)]);
xticks([1e0, 1e1, 1e2]);
ylim([1e-9, 1e-4]);
yticks([1e-9, 1e-7, 1e-5]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_effect_support_compliance_neglected_soft.pdf', 'width', 450, 'height', 350);
#+end_src
#+begin_src matlab :exports none :results none
figure;
hold on;
plot(freqs, abs(squeeze(freqresp(G_mid_a, freqs, 'Hz'))), '-', 'color', colors(1,:));
text(70, 3e-6, '$\omega_n =$ 70Hz', 'horizontalalignment', 'center');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); set(gca, 'YTickLabel',[]);
xlim([freqs(1), freqs(end)]);
xticks([1e0, 1e1, 1e2]);
ylim([1e-9, 1e-4]);
yticks([1e-9, 1e-7, 1e-5]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_effect_support_compliance_neglected_mid.pdf', 'width', 400, 'height', 350);
#+end_src
#+begin_src matlab :exports none :results none
figure;
hold on;
plot(freqs, abs(squeeze(freqresp(G_stiff_a, freqs, 'Hz'))), '-', 'color', colors(1,:), ...
'DisplayName', '$L^\prime/F$');
text(200, 8e-8, '$\omega_n =$ 400Hz', 'horizontalalignment', 'center');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); set(gca, 'YTickLabel',[]);
legend('location', 'northeast');
xlim([freqs(1), freqs(end)]);
xticks([1e0, 1e1, 1e2]);
ylim([1e-9, 1e-4]);
yticks([1e-9, 1e-7, 1e-5]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_effect_support_compliance_neglected_stiff.pdf', 'width', 400, 'height', 350);
#+end_src
#+name: fig:uniaxial_effect_support_compliance_neglected
#+caption: Obtained transfer functions from $F$ to $L^{\prime}$ when neglecing support compliance
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_effect_support_compliance_neglected_soft}$\omega_{n} \ll \omega_{\mu}$}
#+attr_latex: :options {0.37\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_effect_support_compliance_neglected_soft.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_effect_support_compliance_neglected_mid}$\omega_{n} = \omega_{\mu}$}
#+attr_latex: :options {0.31\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_effect_support_compliance_neglected_mid.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_effect_support_compliance_neglected_stiff}$\omega_{n} \gg \omega_{\mu}$}
#+attr_latex: :options {0.31\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_effect_support_compliance_neglected_stiff.png]]
#+end_subfigure
#+end_figure
** Effect of support compliance on $L/F$
Let's now add some support compliance and use the model shown in Figure ref:fig:uniaxial_support_compliance_test_system.
The parameters of the support (i.e. $m_{\mu}$, $c_{\mu}$ and $k_{\mu}$) are chosen to match the vertical mode at $70\,\text{Hz}$ seen on the micro-station (Figure ref:fig:uniaxial_comp_frf_meas_model).
The transfer functions from $F$ to $L$ (i.e. control of the relative motion of the nano-hexapod) and from $L$ to $d$ (i.e. control of the position between the nano-hexapod and the fixed granite) can then be computed.
When the relative displacement of the nano-hexapod $L$ is to be controlled (dynamics shown in Figure ref:fig:uniaxial_effect_support_compliance_dynamics), having a stiff nano-hexapod (i.e. with a suspension mode at higher frequency than the mode of the support) makes the dynamics less affected by the limited support compliance (Figure ref:fig:uniaxial_effect_support_compliance_dynamics_stiff).
This is why it is very common to have stiff piezoelectric stages fixed at the very top of positioning stages.
In such case, the control of the piezoelectric stage using its integrated metrology (typically capacitive sensors) is quite simple as the plant is not much affected by the dynamics of the support on which is it fixed.
# TODO - Add references of such stations with piezo stages on top
If a soft nano-hexapod is used, the support dynamics appears in the dynamics between $F$ and $L$ (see Figure ref:fig:uniaxial_effect_support_compliance_dynamics_soft) which will impact the control robustness and performance.
#+begin_src matlab
%% Parameters of the support compliance
w0h = 2*pi*70; % [rad/s]
xih = 0.1; % [-]
mh = 20; % [kg]
kh = mh*w0h^2;
ch = xih*2*sqrt(kh*mh);
#+end_src
#+begin_src matlab :exports none
%% Compute the transfer functions from F to L and from F to d for considered Nano-Hexapods
% "Soft" Nano-Hexapod
G_soft = (mh*s^2 + ch*s + kh)/(m*s^2*(c_soft*s + k_soft) + (m*s^2 + c_soft*s + k_soft)*(mh*s^2 + ch*s + kh)); % d/F
G_soft_r = (1 - m*s^2*G_soft)/(c_soft*s + k_soft); % L/F
% "Mid" Nano-Hexapod
G_mid = (mh*s^2 + ch*s + kh)/(m*s^2*(c_mid*s + k_mid) + (m*s^2 + c_mid*s + k_mid)*(mh*s^2 + ch*s + kh)); % d/F
G_mid_r = (1 - m*s^2*G_mid)/(c_mid*s + k_mid); % L/F
% "Stiff" Nano-Hexapod
G_stiff = (mh*s^2 + ch*s + kh)/(m*s^2*(c_stiff*s + k_stiff) + (m*s^2 + c_stiff*s + k_stiff)*(mh*s^2 + ch*s + kh)); % d/F
G_stiff_r = (1 - m*s^2*G_stiff)/(c_stiff*s + k_stiff); % L/F
#+end_src
#+begin_src matlab :exports none :results none
%% Effect of the support compliance on the transfer functions from F to L and from F to d
freqs = logspace(0, 3, 1000);
figure;
hold on;
plot(freqs, abs(squeeze(freqresp(G_soft_a, freqs, 'Hz'))), '-', 'color', colors(1,:));
plot(freqs, abs(squeeze(freqresp(G_soft_r, freqs, 'Hz'))), '-', 'color', colors(2,:));
loglog(10.^(0.3*cos(0:0.01:2*pi)+log10(60)), ...
10.^(0.6*sin(0:0.01:2*pi)+log10(4e-7)), 'k--');
text(8, 3e-7, sprintf('Support\nDynamics'), 'horizontalalignment', 'center');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('Magnitude [m/N]');
xlim([freqs(1), freqs(end)]);
xticks([1e0, 1e1, 1e2]);
ylim([1e-9, 1e-4]);
yticks([1e-9, 1e-7, 1e-5]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_effect_support_compliance_dynamics_soft.pdf', 'width', 450, 'height', 350);
#+end_src
#+begin_src matlab :exports none :results none
figure;
hold on;
plot(freqs, abs(squeeze(freqresp(G_mid_a, freqs, 'Hz'))), '-', 'color', colors(1,:));
plot(freqs, abs(squeeze(freqresp(G_mid_r, freqs, 'Hz'))), '-', 'color', colors(2,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]');
set(gca, 'YTickLabel',[]);
xlim([freqs(1), freqs(end)]);
xticks([1e0, 1e1, 1e2]);
ylim([1e-9, 1e-4]);
yticks([1e-9, 1e-7, 1e-5]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_effect_support_compliance_dynamics_mid.pdf', 'width', 400, 'height', 350);
#+end_src
#+begin_src matlab :exports none :results none
figure;
hold on;
plot(freqs, abs(squeeze(freqresp(G_stiff_a, freqs, 'Hz'))), '-', 'color', colors(1,:), ...
'DisplayName', '$L^\prime/F$');
plot(freqs, abs(squeeze(freqresp(G_stiff_r, freqs, 'Hz'))), '-', 'color', colors(2,:), ...
'DisplayName', '$L/F$');
loglog(10.^(0.3*cos(0:0.01:2*pi)+log10(50)), ...
10.^(0.3*sin(0:0.01:2*pi)+log10(8e-9)), 'k--', 'HandleVisibility', 'off');
text(50, 3e-8, 'No effect', 'horizontalalignment', 'center');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); set(gca, 'YTickLabel',[]);
legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 1);
xlim([freqs(1), freqs(end)]);
xticks([1e0, 1e1, 1e2]);
ylim([1e-9, 1e-4]);
yticks([1e-9, 1e-7, 1e-5]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_effect_support_compliance_dynamics_stiff.pdf', 'width', 400, 'height', 350);
#+end_src
#+name: fig:uniaxial_effect_support_compliance_dynamics
#+caption: Effect of the support compliance on the transfer functions from $F$ to $L$
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_effect_support_compliance_dynamics_soft}$\omega_{n} \ll \omega_{\mu}$}
#+attr_latex: :options {0.37\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_effect_support_compliance_dynamics_soft.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_effect_support_compliance_dynamics_mid}$\omega_{n} = \omega_{\mu}$}
#+attr_latex: :options {0.31\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_effect_support_compliance_dynamics_mid.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_effect_support_compliance_dynamics_stiff}$\omega_{n} \gg \omega_{\mu}$}
#+attr_latex: :options {0.31\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_effect_support_compliance_dynamics_stiff.png]]
#+end_subfigure
#+end_figure
** Effect of support compliance on $d/F$
When the motion to be controlled is the relative displacement $d$ between the granite and the nano-hexapod's top platform (which is the case for the acrshort:nass), the effect of the support compliance on the plant dynamics is opposite to what was previously observed.
Indeed, using a "soft" nano-hexapod (i.e. with a suspension mode at lower frequency than the mode of the support) makes the dynamics less affected by the support dynamics (Figure ref:fig:uniaxial_effect_support_compliance_dynamics_d_soft).
On the contrary, if a "stiff" nano-hexapod is used, the support dynamics appears in the plant dynamics (Figure ref:fig:uniaxial_effect_support_compliance_dynamics_d_stiff).
#+begin_src matlab :exports none :results none
%% Effect of the support compliance on the transfer functions from F to L and from F to d
freqs = logspace(0, 3, 1000);
figure;
hold on;
plot(freqs, abs(squeeze(freqresp(G_soft_a, freqs, 'Hz'))), '-', 'color', colors(1,:));
plot(freqs, abs(squeeze(freqresp(G_soft, freqs, 'Hz'))), '-', 'color', colors(3,:));
loglog(10.^(0.3*cos(0:0.01:2*pi)+log10(60)), ...
10.^(0.6*sin(0:0.01:2*pi)+log10(4e-7)), 'k--');
text(8, 3e-7, 'No effect', 'horizontalalignment', 'center');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('Magnitude [m/N]');
xlim([freqs(1), freqs(end)]);
xticks([1e0, 1e1, 1e2]);
ylim([1e-9, 1e-4]);
yticks([1e-9, 1e-7, 1e-5]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_effect_support_compliance_dynamics_d_soft.pdf', 'width', 450, 'height', 350);
#+end_src
#+begin_src matlab :exports none :results none
figure;
hold on;
plot(freqs, abs(squeeze(freqresp(G_mid_a, freqs, 'Hz'))), '-', 'color', colors(1,:));
plot(freqs, abs(squeeze(freqresp(G_mid, freqs, 'Hz'))), '-', 'color', colors(3,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]');
set(gca, 'YTickLabel',[]);
xlim([freqs(1), freqs(end)]);
xticks([1e0, 1e1, 1e2]);
ylim([1e-9, 1e-4]);
yticks([1e-9, 1e-7, 1e-5]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_effect_support_compliance_dynamics_d_mid.pdf', 'width', 400, 'height', 350);
#+end_src
#+begin_src matlab :exports none :results none
figure;
hold on;
plot(freqs, abs(squeeze(freqresp(G_stiff_a, freqs, 'Hz'))), '-', 'color', colors(1,:), ...
'DisplayName', '$L^\prime/F$');
plot(freqs, abs(squeeze(freqresp(G_stiff, freqs, 'Hz'))), '-', 'color', colors(3,:), ...
'DisplayName', '$d/F$');
loglog(10.^(0.4*cos(0:0.01:2*pi)+log10(50)), ...
10.^(0.8*sin(0:0.01:2*pi)+log10(8e-9)), 'k--', 'HandleVisibility', 'off');
text(50, 2e-7, sprintf('Support\nDynamics'), 'horizontalalignment', 'center');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); set(gca, 'YTickLabel',[]);
legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 1);
xlim([freqs(1), freqs(end)]);
xticks([1e0, 1e1, 1e2]);
ylim([1e-9, 1e-4]);
yticks([1e-9, 1e-7, 1e-5]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_effect_support_compliance_dynamics_d_stiff.pdf', 'width', 400, 'height', 350);
#+end_src
#+name: fig:uniaxial_effect_support_compliance_dynamics_d
#+caption: Effect of the support compliance on the transfer functions from $F$ to $d$
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_effect_support_compliance_dynamics_d_soft}$\omega_{n} \ll \omega_{\mu}$}
#+attr_latex: :options {0.37\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_effect_support_compliance_dynamics_d_soft.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_effect_support_compliance_dynamics_d_mid}$\omega_{n} = \omega_{\mu}$}
#+attr_latex: :options {0.31\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_effect_support_compliance_dynamics_d_mid.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_effect_support_compliance_dynamics_d_stiff}$\omega_{n} \gg \omega_{\mu}$}
#+attr_latex: :options {0.31\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_effect_support_compliance_dynamics_d_stiff.png]]
#+end_subfigure
#+end_figure
** Conclusion
:PROPERTIES:
:UNNUMBERED: t
:END:
In order to study the impact of the support compliance on the plant dynamics, simple models shown in Figure ref:fig:uniaxial_support_compliance_models were used.
Depending on the quantity to be controlled ($L$ or $d$ in Figure ref:fig:uniaxial_support_compliance_test_system) and on the relative location of $\omega_\nu$ (suspension mode of the nano-hexapod) with respect to $\omega_\mu$ (modes of the support), the interaction between the support and the nano-hexapod dynamics can change drastically (observations made are summarized in Table ref:tab:uniaxial_effect_compliance).
For the acrfull:nass, having the suspension mode of the nano-hexapod at lower frequencies than the suspension modes of the micro-station would make the plant less dependent on the micro-station dynamics, and therefore easier to control.
Note that observations made in this section are also affected by the ratio between the support mass $m_{\mu}$ and the nano-hexapod mass $m_n$ (the effect is more pronounced when the ratio $m_n/m_{\mu}$ increases).
#+name: tab:uniaxial_effect_compliance
#+caption: Impact of the support dynamics on the plant dynamics
#+attr_latex: :environment tabularx :width 0.4\linewidth :align Xccc
#+attr_latex: :center t :booktabs t
| | $\omega_{\nu} \ll \omega_{\mu}$ | $\omega_{\nu} \approx \omega_{\mu}$ | $\omega_{\nu} \gg \omega_{\mu}$ |
|--------+---------------------------------+-------------------------------------+---------------------------------|
| $d/F$ | small | large | large |
| $L/F$ | large | large | small |
* Effect of Payload Dynamics
:PROPERTIES:
:HEADER-ARGS:matlab+: :tangle matlab/uniaxial_8_payload_dynamics.m
:END:
<<sec:uniaxial_payload_dynamics>>
** Introduction :ignore:
Up to this section, the sample was modelled as a mass rigidly fixed to the nano-hexapod (as shown in Figure ref:fig:uniaxial_paylaod_dynamics_rigid_schematic).
However, such sample may present internal dynamics and its fixation to the nano-hexapod may have limited stiffness.
To study the effect of the sample dynamics, models shown in Figure ref:fig:uniaxial_paylaod_dynamics_schematic are used.
#+begin_src latex :file uniaxial_paylaod_dynamics_rigid_schematic.pdf :results file raw silent
\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
% Granite
\draw[fill=white!70!black] (-1*\massw, -\massh) rectangle (\massw, 0) node[pos=0.5]{Granite};
\coordinate(origin) at (0,0);
% Nano Station
\begin{scope}[shift={(0, 0)}]
% Mass
\draw[draw=colorred,fill=colorred!10!white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5, color=colorred]{$m_{n}$};
% Spring, Damper, and Actuator
\draw[spring,draw=colorred] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1, color=colorred]{$k_{n}$};
\draw[damper={colorred}{}{}] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2, color=colorred]{$c_{n}$};
\draw[actuator={0.4}{0.2}{colorred}] ( 0.4*\massw, 0) -- (0.4*\massw, \spaceh) node[midway, left=0.1, color=colorred](F){$f$};
% Displacements
\draw[dashed] (0.5*\massw, \spaceh) -- coordinate[near end](dhigh) ++(1.2, 0);
% 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]{$\nu$-hexapod};
\end{scope}
% Sample
\begin{scope}[shift={(0, \spaceh+\massh)}]
% Mass
\draw[draw=colorblue,fill=colorblue!10!white] (-0.3*\massw, 0) rectangle (0.3*\massw, \massh) node[pos=0.5, color=colorblue]{$m_{s}$};
\end{scope}
\draw[<->, dashed] (dhigh) --node[midway, right]{$L$} (origin-|dhigh);
\end{tikzpicture}
#+end_src
#+begin_src latex :file uniaxial_paylaod_dynamics_schematic.pdf :results file raw silent
\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
% Granite
\draw[fill=white!70!black] (-1*\massw, -\massh) rectangle (\massw, 0) node[pos=0.5]{Granite};
\coordinate(origin) at (0,0);
% Nano Station
\begin{scope}[shift={(0, 0)}]
% Mass
\draw[draw=colorred,fill=colorred!10!white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5, color=colorred]{$m_{n}$};
% Spring, Damper, and Actuator
\draw[spring,draw=colorred] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1, color=colorred]{$k_{n}$};
\draw[damper={colorred}{}{}] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2, color=colorred]{$c_{n}$};
\draw[actuator={0.4}{0.2}{colorred}] ( 0.4*\massw, 0) -- (0.4*\massw, \spaceh) node[midway, left=0.1, color=colorred](F){$f$};
% Displacements
\draw[dashed] (0.5*\massw, \spaceh) -- coordinate[near end](dhigh) ++(1.2, 0);
% 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]{$\nu$-hexapod};
\end{scope}
% Sample
\begin{scope}[shift={(0, \spaceh+\massh)}]
% Mass
\draw[draw=colorblue,fill=colorblue!10!white] (-0.3*\massw, \spaceh) rectangle (0.3*\massw, \spaceh+\massh) node[pos=0.5, color=colorblue]{$m_{s}$};
% Spring, Damper, and Actuator
\draw[spring,draw=colorblue] (-0.2*\massw, 0) -- (-0.2*\massw, \spaceh) node[midway, left=0.1, color=colorblue]{$k_{s}$};
\draw[damper={colorblue}{}{}] ( 0.2*\massw, 0) -- ( 0.2*\massw, \spaceh) node[midway, left=0.2, color=colorblue]{$c_{s}$};
% 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]{Payload};
\end{scope}
\draw[<->, dashed] (dhigh) --node[midway, right]{$L^\prime$} (origin-|dhigh);
\end{tikzpicture}
#+end_src
#+name: fig:uniaxial_payload_dynamics_models
#+caption: Models used to study the effect of payload dynamics
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_paylaod_dynamics_rigid_schematic}Rigid payload}
#+attr_latex: :options {0.49\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_paylaod_dynamics_rigid_schematic.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_paylaod_dynamics_schematic}Payload with some flexibility}
#+attr_latex: :options {0.49\textwidth}
#+begin_subfigure
#+attr_latex: :scale 1
[[file:figs/uniaxial_paylaod_dynamics_schematic.png]]
#+end_subfigure
#+end_figure
** Matlab Init :noexport:ignore:
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
<<matlab-dir>>
#+end_src
#+begin_src matlab :exports none :results silent :noweb yes
<<matlab-init>>
#+end_src
#+begin_src matlab :tangle no :noweb yes
<<m-init-path>>
#+end_src
#+begin_src matlab :eval no :noweb yes
<<m-init-path-tangle>>
#+end_src
#+begin_src matlab :noweb yes
<<m-init-other>>
#+end_src
#+begin_src matlab
%% Uniaxial Simscape model name
mdl = 'nass_uniaxial_model';
#+end_src
#+begin_src matlab
%% Load the micro-station parameters
load('uniaxial_micro_station_parameters.mat')
#+end_src
#+begin_src matlab
%% Load the PSD of disturbances
load('uniaxial_disturbance_psd.mat', 'f', 'psd_ft', 'psd_xf');
#+end_src
#+begin_src matlab :exports none
%% Load Active Damping Controller
load('uniaxial_active_damping_controllers.mat', 'K_iff_vc', 'K_iff_md', 'K_iff_pz', ...
'K_rdc_vc', 'K_rdc_md', 'K_rdc_pz', ...
'K_dvf_vc', 'K_dvf_md', 'K_dvf_pz');
#+end_src
#+begin_src matlab
%% Load High Authority Controllers
load('uniaxial_high_authority_controllers.mat', 'K_hac_vc', 'K_hac_md', 'K_hac_pz');
#+end_src
#+begin_src matlab
%% Frequency Vector [Hz]
freqs = logspace(0, 3, 1000);
#+end_src
** Impact on the plant dynamics
<<ssec:uniaxial_payload_dynamics_effect_dynamics>>
To study the impact of the flexibility between the nano-hexapod and the payload, a first (reference) model with a rigid payload as shown in Figure ref:fig:uniaxial_paylaod_dynamics_rigid_schematic is used.
Then "flexible" payload whose model is shown in Figure ref:fig:uniaxial_paylaod_dynamics_schematic are considered.
The resonances of the payload are set at $\omega_s = 20\,\text{Hz}$ and at $\omega_s = 200\,\text{Hz}$ while its mass is either $m_s = 1\,\text{kg}$ or $m_s = 50\,\text{kg}$.
The transfer functions from the nano-hexapod force $f$ to the motion of the nano-hexapod top platform are computed for all the above configurations and are compared for a soft Nano-Hexapod ($k_n = 0.01\,N/\mu m$) in Figure ref:fig:uniaxial_payload_dynamics_soft_nano_hexapod.
It can be seen that the mode of the sample adds an anti-resonance followed by a resonance (zero/pole pattern).
The frequency of the anti-resonance corresponds to the "free" resonance of the sample $\omega_s = \sqrt{k_s/m_s}$.
The flexibility of the sample also changes the high frequency gain (the mass line is shifted from $\frac{1}{(m_n + m_s)s^2}$ to $\frac{1}{m_ns^2}$).
#+begin_src matlab :exports none
%% Soft Nano-Hexapod
% Light payload mass
mn = 15; % Nano-Hexapod mass [kg]
ms = 1; % Sample Mass [kg]
kn = 1e4; % Nano-Hexapod (soft) Stiffness [N/m]
cn = 2*0.01*sqrt((ms + mn)*kn); % Nano-Hexapod Damping [N/(m/s)]
% Rigid sample
G_vc_rigid_light = 1/((mn + ms)*s^2 + cn*s + kn);
% Soft Sample
ws = 2*pi*20;
ks = ms * ws^2;
cs = 2*0.01*sqrt(ms*ks);
G_vc_soft_light = (ms*s^2 + cs*s + ks)/((mn*s^2 + cn*s + kn)*(ms*s^2 + cs*s + ks) + ms*s^2*(cs*s + ks));
% Stiff Sample
ws = 2*pi*200;
ks = ms * ws^2;
cs = 2*0.01*sqrt(ms*ks);
G_vc_stiff_light = (ms*s^2 + cs*s + ks)/((mn*s^2 + cn*s + kn)*(ms*s^2 + cs*s + ks) + ms*s^2*(cs*s + ks));
% Heavy payload mass
mn = 15; % Nano-Hexapod mass [kg]
ms = 50; % Sample Mass [kg]
kn = 1e4; % Nano-Hexapod (soft) Stiffness [N/m]
cn = 2*0.01*sqrt((ms + mn)*kn); % Nano-Hexapod Damping [N/(m/s)]
% Rigid sample
G_vc_rigid_heavy = 1/((mn + ms)*s^2 + cn*s + kn);
% Soft Sample
ws = 2*pi*20;
ks = ms * ws^2;
cs = 2*0.01*sqrt(ms*ks);
G_vc_soft_heavy = (ms*s^2 + cs*s + ks)/((mn*s^2 + cn*s + kn)*(ms*s^2 + cs*s + ks) + ms*s^2*(cs*s + ks));
% Stiff Sample
ws = 2*pi*200;
ks = ms * ws^2;
cs = 2*0.01*sqrt(ms*ks);
G_vc_stiff_heavy = (ms*s^2 + cs*s + ks)/((mn*s^2 + cn*s + kn)*(ms*s^2 + cs*s + ks) + ms*s^2*(cs*s + ks));
#+end_src
#+begin_src matlab :exports none :results none
%% Effect of the payload dynamics on the soft Nano-Hexapod. Light sample on the right, and heavy sample on the left
figure;
tiledlayout(3, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
ax1 = nexttile([2,1]);
hold on;
plot(freqs, abs(squeeze(freqresp(G_vc_rigid_light, freqs, 'Hz'))), '-', 'color', colors(1,:), 'DisplayName', 'Rigid sample');
plot(freqs, abs(squeeze(freqresp(G_vc_stiff_light, freqs, 'Hz'))), '-', 'color', colors(2,:), 'DisplayName', '$\omega_s = 200\,Hz$');
plot(freqs, abs(squeeze(freqresp(G_vc_soft_light, freqs, 'Hz'))), '-', 'color', colors(3,:), 'DisplayName', '$\omega_s = 20\,Hz$');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
ylim([1e-10, 1e-2])
ax1b = nexttile();
hold on;
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_vc_rigid_light, freqs, 'Hz')))), '-', 'color', colors(1,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_vc_stiff_light, freqs, 'Hz')))), '-', 'color', colors(2,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_vc_soft_light, freqs, 'Hz')))), '-', 'color', colors(3,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
xticks([1e0, 1e1, 1e2]);
yticks(-360:90:360);
ylim([-200, 20]);
linkaxes([ax1,ax1b],'x');
xlim([1, 1000]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_payload_dynamics_soft_nano_hexapod_light.pdf', 'width', 'half', 'height', 600);
#+end_src
#+begin_src matlab :exports none :results none
figure;
tiledlayout(3, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
ax2 = nexttile([2,1]);
hold on;
plot(freqs, abs(squeeze(freqresp(G_vc_rigid_heavy, freqs, 'Hz'))), '-', 'color', colors(1,:), 'DisplayName', 'Rigid sample');
plot(freqs, abs(squeeze(freqresp(G_vc_stiff_heavy, freqs, 'Hz'))), '-', 'color', colors(2,:), 'DisplayName', '$\omega_s = 200\,Hz$');
plot(freqs, abs(squeeze(freqresp(G_vc_soft_heavy, freqs, 'Hz'))), '-', 'color', colors(3,:), 'DisplayName', '$\omega_s = 20\,Hz$');
plot(freqs, abs(squeeze(freqresp(1/(mn*s^2), freqs, 'Hz'))), '-', 'color', [0,0,0,0.5], 'DisplayName', '$\frac{1}{m_n s^2}$');
plot(freqs, abs(squeeze(freqresp(1/((mn + ms)*s^2), freqs, 'Hz'))), '--', 'color', [0,0,0,0.5], 'DisplayName', '$\frac{1}{(m_n + m_s) s^2}$');
text(2.2, 2e-3, '$\omega_n = \sqrt{\frac{k_n}{m_n + m_s}}$', 'horizontalalignment', 'left');
text(20, 1e-8, '$\omega_s = \sqrt{\frac{k_s}{m_s}}$', 'horizontalalignment', 'center');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
ldg = legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 1);
ldg.ItemTokenSize = [20, 1];
ylim([1e-10, 1e-2])
ax2b = nexttile();
hold on;
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_vc_rigid_heavy, freqs, 'Hz')))), '-', 'color', colors(1,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_vc_stiff_heavy, freqs, 'Hz')))), '-', 'color', colors(2,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_vc_soft_heavy, freqs, 'Hz')))), '-', 'color', colors(3,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
xticks([1e0, 1e1, 1e2]);
yticks(-360:90:360);
ylim([-200, 20]);
linkaxes([ax2,ax2b],'x');
xlim([1, 1000]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_payload_dynamics_soft_nano_hexapod_heavy.pdf', 'width', 'half', 'height', 600);
#+end_src
#+name: fig:uniaxial_payload_dynamics_soft_nano_hexapod
#+caption: Effect of the payload dynamics on the soft Nano-Hexapod. Light sample (\subref{fig:uniaxial_payload_dynamics_soft_nano_hexapod_light}), and heavy sample (\subref{fig:uniaxial_payload_dynamics_soft_nano_hexapod_heavy})
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_payload_dynamics_soft_nano_hexapod_light}$k_n = 0.01\,N/\mu m$, $m_s = 1\,kg$}
#+attr_latex: :options {0.49\textwidth}
#+begin_subfigure
#+attr_latex: :width \linewidth
[[file:figs/uniaxial_payload_dynamics_soft_nano_hexapod_light.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_payload_dynamics_soft_nano_hexapod_heavy}$k_n = 0.01\,N/\mu m$, $m_s = 50\,kg$}
#+attr_latex: :options {0.49\textwidth}
#+begin_subfigure
#+attr_latex: :width \linewidth
[[file:figs/uniaxial_payload_dynamics_soft_nano_hexapod_heavy.png]]
#+end_subfigure
#+end_figure
The same transfer functions are now compared when using a stiff nano-hexapod ($k_n = 100\,N/\mu m$) in Figure ref:fig:uniaxial_payload_dynamics_stiff_nano_hexapod.
In that case, the sample's resonance $\omega_s$ is smaller than the nano-hexapod resonance $\omega_n$.
This changes the zero/pole pattern to a pole/zero pattern (the frequency of the zero still being equal to $\omega_s$).
Even tough the added sample's flexibility still shifts the high frequency mass line as for the soft nano-hexapod, the dynamics below the nano-hexapod resonance is much less impacted, even when the sample mass is high and when the sample resonance is at low frequency (see yellow curve in Figure ref:fig:uniaxial_payload_dynamics_stiff_nano_hexapod_heavy).
#+begin_src matlab :exports none
%% Stiff Nano-Hexapod
% Light payload mass
mn = 15; % Nano-Hexapod mass [kg]
ms = 1; % Sample Mass [kg]
kn = 1e8; % Nano-Hexapod (soft) Stiffness [N/m]
cn = 2*0.01*sqrt((ms + mn)*kn); % Nano-Hexapod Damping [N/(m/s)]
% Rigid sample
G_pz_rigid_light = 1/((mn + ms)*s^2 + cn*s + kn);
% Soft Sample
ws = 2*pi*20;
ks = ms * ws^2;
cs = 2*0.01*sqrt(ms*ks);
G_pz_soft_light = (ms*s^2 + cs*s + ks)/((mn*s^2 + cn*s + kn)*(ms*s^2 + cs*s + ks) + ms*s^2*(cs*s + ks));
% Stiff Sample
ws = 2*pi*200;
ks = ms * ws^2;
cs = 2*0.01*sqrt(ms*ks);
G_pz_stiff_light = (ms*s^2 + cs*s + ks)/((mn*s^2 + cn*s + kn)*(ms*s^2 + cs*s + ks) + ms*s^2*(cs*s + ks));
% Heavy payload mass
mn = 15; % Nano-Hexapod mass [kg]
ms = 50; % Sample Mass [kg]
kn = 1e8; % Nano-Hexapod (soft) Stiffness [N/m]
cn = 2*0.01*sqrt((ms + mn)*kn); % Nano-Hexapod Damping [N/(m/s)]
% Rigid sample
G_pz_rigid_heavy = 1/((mn + ms)*s^2 + cn*s + kn);
% Soft Sample
ws = 2*pi*20;
ks = ms * ws^2;
cs = 2*0.01*sqrt(ms*ks);
G_pz_soft_heavy = (ms*s^2 + cs*s + ks)/((mn*s^2 + cn*s + kn)*(ms*s^2 + cs*s + ks) + ms*s^2*(cs*s + ks));
% Stiff Sample
ws = 2*pi*200;
ks = ms * ws^2;
cs = 2*0.01*sqrt(ms*ks);
G_pz_stiff_heavy = (ms*s^2 + cs*s + ks)/((mn*s^2 + cn*s + kn)*(ms*s^2 + cs*s + ks) + ms*s^2*(cs*s + ks));
#+end_src
#+begin_src matlab :exports none :results none
%% Effect of the payload dynamics on the stiff Nano-Hexapod. Light sample on the right, and heavy sample on the left
figure;
tiledlayout(3, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
ax1 = nexttile([2,1]);
hold on;
plot(freqs, abs(squeeze(freqresp(G_pz_rigid_light, freqs, 'Hz'))), '-', 'color', colors(1,:));
plot(freqs, abs(squeeze(freqresp(G_pz_stiff_light, freqs, 'Hz'))), '-', 'color', colors(2,:));
plot(freqs, abs(squeeze(freqresp(G_pz_soft_light, freqs, 'Hz'))), '-', 'color', colors(3,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
ylim([1e-10, 1e-6])
ax1b = nexttile();
hold on;
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_pz_rigid_light, freqs, 'Hz')))), '-', 'color', colors(1,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_pz_stiff_light, freqs, 'Hz')))), '-', 'color', colors(2,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_pz_soft_light, freqs, 'Hz')))), '-', 'color', colors(3,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
xticks([1e0, 1e1, 1e2]);
yticks(-360:90:360);
ylim([-200, 20]);
linkaxes([ax1,ax1b],'x');
xlim([1, 1000]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_payload_dynamics_stiff_nano_hexapod_light.pdf', 'width', 'half', 'height', 500);
#+end_src
#+begin_src matlab :exports none :results none
figure;
tiledlayout(3, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
ax2 = nexttile([2,1]);
hold on;
plot(freqs, abs(squeeze(freqresp(G_pz_rigid_heavy, freqs, 'Hz'))), '-', 'color', colors(1,:), 'DisplayName', 'Rigid sample');
plot(freqs, abs(squeeze(freqresp(G_pz_stiff_heavy, freqs, 'Hz'))), '-', 'color', colors(2,:), 'DisplayName', 'Stiff sample: $\omega_s = 200\,Hz$');
plot(freqs, abs(squeeze(freqresp(G_pz_soft_heavy, freqs, 'Hz'))), '-', 'color', colors(3,:), 'DisplayName', 'Soft sample: $\omega_s = 20\,Hz$');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
ylim([1e-10, 1e-6])
ldg = legend('location', 'northwest', 'FontSize', 8, 'NumColumns', 1);
ldg.ItemTokenSize = [20, 1];
ax2b = nexttile();
hold on;
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_pz_rigid_heavy, freqs, 'Hz')))), '-', 'color', colors(1,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_pz_stiff_heavy, freqs, 'Hz')))), '-', 'color', colors(2,:));
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_pz_soft_heavy, freqs, 'Hz')))), '-', 'color', colors(3,:));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
xticks([1e0, 1e1, 1e2]);
yticks(-360:90:360);
ylim([-200, 20]);
linkaxes([ax2,ax2b],'x');
xlim([1, 1000]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/uniaxial_payload_dynamics_stiff_nano_hexapod_heavy.pdf', 'width', 'half', 'height', 500);
#+end_src
#+name: fig:uniaxial_payload_dynamics_stiff_nano_hexapod
#+caption: Effect of the payload dynamics on the stiff Nano-Hexapod. Light sample (\subref{fig:uniaxial_payload_dynamics_stiff_nano_hexapod_light}), and heavy sample (\subref{fig:uniaxial_payload_dynamics_stiff_nano_hexapod_heavy})
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_payload_dynamics_stiff_nano_hexapod_light}$k_n = 100\,N/\mu m$, $m_s = 1\,kg$}
#+attr_latex: :options {0.49\textwidth}
#+begin_subfigure
#+attr_latex: :width \linewidth
[[file:figs/uniaxial_payload_dynamics_stiff_nano_hexapod_light.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_payload_dynamics_stiff_nano_hexapod_heavy}$k_n = 100\,N/\mu m$, $m_s = 50\,kg$}
#+attr_latex: :options {0.49\textwidth}
#+begin_subfigure
#+attr_latex: :width \linewidth
[[file:figs/uniaxial_payload_dynamics_stiff_nano_hexapod_heavy.png]]
#+end_subfigure
#+end_figure
** Impact on the close loop performances
<<ssec:uniaxial_payload_dynamics_effect_stability>>
Having a flexibility between the measured position (i.e. the top platform of the nano-hexapod) and the point-of-interest to be positioned relative to the x-ray may also impact the closed-loop performances (i.e. the remaining sample's vibration).
In order to estimate if the sample flexibility is critical for the closed-loop position stability of the sample, the model shown in Figure ref:fig:uniaxial_sample_flexibility_control is used.
This is the same model that was used in Section ref:sec:uniaxial_position_control but with an added flexibility between the nano-hexapod and the sample (considered sample modes are at $\omega_s = 20\,\text{Hz}$ and $\omega_n = 200\,\text{Hz}$).
In that case, the measured (i.e. controlled) distance $d$ is no longer equal to the real performance index (the distance $y$).
#+begin_src latex :file uniaxial_sample_flexibility_control.pdf
\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.4} % Width of the dashed line for the displacement
\def\disph{0.3} % Height of the arrow for the displacements
\def\bracs{0.05} % Brace spacing vertically
\def\brach{-12pt} % Brace shift horizontaly
\def\fsensh{0.2} % Height of the force sensor
\def\velsize{0.2} % Size of the velocity sensor
% Ground
\draw (-0.5*\massw, 0) -- (0.5*\massw, 0);
\draw[dashed] (0.5*\massw, 0) -- ++(\dispw, 0);
\draw[->, color=colorpurple] (0.5*\massw+0.5*\dispw, 0) -- ++(0, 2*\disph) node[right, color=colorpurple]{$x_{f}$};
% ====================
% Granite
\begin{scope}[shift={(0, 0)}]
% Mass
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m_{g}$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k_{g}$};
\draw[damper] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2]{$c_{g}$};
% 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]{Granite};
% Displacements
\draw[dashed] (0.5*\massw, \spaceh+\massh) -- ++(9.0*\dispw, 0) coordinate(xg);
\end{scope}
% ====================
% ====================
% Stages
\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_{t}$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k_{t}$};
\draw[damper] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2]{$c_{t}$};
\draw[actuator={0.45}{0.2}{colorpurple}] ( 0.3*\massw, 0) -- (0.3*\massw, \spaceh) node[midway, right=0.1, color=colorpurple](ft){$f_{t}$};
% 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]{$T_y$/$R_y$/$R_z$};
\end{scope}
% ====================
% ====================
% Hexapod
\begin{scope}[shift={(0, 2*(\spaceh+\massh))}]
% Mass
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m_h$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh) node[midway, left=0.1]{$k_h$};
\draw[damper] (0, 0) -- ( 0, \spaceh) node[midway, left=0.2]{$c_h$};
% 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]{$\mu\text{-hexa}$};
\end{scope}
% ====================
% ====================
% NASS
\begin{scope}[shift={(0, 3*(\spaceh+\massh))}]
% Mass
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5]{$m_{n}$};
% Force Sensor
\node[forcesensor={\massw}{\fsensh}{colorblue}] (fsensn) at (0, \spaceh-\fsensh){};
\node[right, color=colorblue] (fn) at (fsensn.east) {$f_n$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4*\massw, 0) -- (-0.4*\massw, \spaceh-\fsensh) node[midway, left=0.1]{$k_{n}$};
\draw[damper] (0, 0) -- ( 0, \spaceh-\fsensh) node[midway, left=0.2]{$c_{n}$};
\draw[actuator={0.4}{0.2}{black}] ( 0.3*\massw, 0) -- (0.3*\massw, \spaceh-\fsensh) node[midway, right=0.1](f){$f$};
% 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]{$\nu\text{-hexa}$};
% Displacements
\draw[dashed] (0.5*\massw, \spaceh+\massh) -- ++(7.5*\dispw, 0) coordinate(xnpos);
\end{scope}
% ====================
% ====================
% sample
\begin{scope}[shift={(0, 4*(\spaceh+\massh))}]
% Mass
\draw[fill=white] (-0.3*\massw, \spaceh) rectangle (0.3*\massw, \spaceh+\massh) coordinate[pos=0.5](poi);
% Spring, Damper, and Actuator
\draw[spring] (-0.2*\massw, 0) -- (-0.2*\massw, \spaceh) node[midway, left=0.1]{$k_{s}$};
\draw[damper] ( 0.2*\massw, 0) -- ( 0.2*\massw, \spaceh) node[midway, left=0.2]{$c_{s}$};
% 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]{Sample};
% X-ray
\draw[dashed, draw=red, -<-=.5] (poi)node[branch, color=red]{} -- node[near end, above]{x-ray} ++(2.5, 0);
% Displacements
\draw[dashed] (0.2*\massw, \spaceh)coordinate(a) -- (xg|-a) coordinate(xspos);
\end{scope}
% ====================
% Measured displacement
\draw[<->, dashed, draw=colorred] ($(xnpos)+(-0.1, 0)$)coordinate(a) -- node[left, color=colorred](d){$d$} (xg-|a);
\draw[<->, dashed] ($(xg)+(-0.1, 0)$) -- node[left]{$y$} ($(xspos)+(-0.1, 0)$);
% ====================
% IFF Control
\node[block={2em}{2em}, right=1.0 of fn, color=colorblue, fill=colorblue!10!white] (iff) {$K_{\textsc{IFF}}$};
\node[addb, right=0.5 of f.east] (ctrladd) {};
\node[block={2em}{2em}, color=colorred, fill=colorred!10!white] (Khac) at (ctrladd|-d) {$K_{\textsc{HAC}}$};
\draw[->, draw=colorblue] (fn.east) -- (iff.west);
\draw[->, draw=colorblue] (iff.south) |- (ctrladd.east);
\draw[->] (ctrladd.west) -- (f.east);
\draw[->, draw=colorred] (d.west) -- (Khac.east);
\draw[->, draw=colorred] (Khac.north) -- (ctrladd.south) node[below right, color=colorred]{$f^{\prime}$};
% ====================
\end{tikzpicture}
#+end_src
#+name: fig:uniaxial_sample_flexibility_control
#+caption: Uniaxial model considering a flexibility between the nano-hexapod top platform and the sample. In that case the measured and controlled distance $d$ is different from the distance $y$ which is the real performance index
#+RESULTS:
[[file:figs/uniaxial_sample_flexibility_control.png]]
The system dynamics is computed and IFF is applied using the same gains as the ones used in Section ref:sec:uniaxial_active_damping.
Thanks to the collocation between the nano-hexapod and the force sensor used for IFF, the damped plants are still stable and similar damping values are obtained than when considering a rigid sample.
The High Authority Controllers used in Section ref:sec:uniaxial_position_control are then implemented on the damped plants.
The obtained closed-loop systems are stable, indicating good robustness.
Finally, closed-loop noise budgeting is computed for the obtained the closed-loop system and the cumulative amplitude spectrum of $d$ and $y$ are shown in Figure ref:fig:uniaxial_sample_flexibility_noise_budget_y.
The cumulative amplitude spectrum of the measured distance $d$ (Figure ref:fig:uniaxial_sample_flexibility_noise_budget_d) shows that the added flexibility at the sample location have very little effect on the control performance.
However, the cumulative amplitude spectrum of the distance $y$ (Figure ref:fig:uniaxial_sample_flexibility_noise_budget_y) shows that the stability of $y$ is degraded when the sample flexibility is considered and is degraded as $\omega_s$ is lowered.
What happens is that above $\omega_s$, even though the motion $d$ can be controlled perfectly, the sample's mass is "isolated" from the motion of the nano-hexapod and the control on $y$ is not effective.
#+begin_src matlab :exports none
%% Nano-Hexpod model
model_config = struct();
model_config.controller = "open_loop";
mn = 15; % Nano-Hexapod mass [kg]
ms = 1; % Sample Mass [kg]
%% Identification
clear io; io_i = 1;
io(io_i) = linio([mdl, '/controller'], 1, 'openinput'); io_i = io_i + 1; % Actuator Force
io(io_i) = linio([mdl, '/micro_station/xf'], 1, 'openinput'); io_i = io_i + 1; % Floor Motion
io(io_i) = linio([mdl, '/micro_station/ft'], 1, 'openinput'); io_i = io_i + 1; % Stage vibrations
io(io_i) = linio([mdl, '/fs'], 1, 'openinput'); io_i = io_i + 1; % Direct sample forces
io(io_i) = linio([mdl, '/dL'], 1, 'openoutput'); io_i = io_i + 1; % Relative Motion Sensor
io(io_i) = linio([mdl, '/fm'], 1, 'openoutput'); io_i = io_i + 1; % Force Sensor
io(io_i) = linio([mdl, '/vn'] , 1, 'openoutput'); io_i = io_i + 1; % Geophone
io(io_i) = linio([mdl, '/d'] , 1, 'openoutput'); io_i = io_i + 1; % Metrology Output
io(io_i) = linio([mdl, '/y'] , 1, 'openoutput'); io_i = io_i + 1; % Sample's position
#+end_src
#+begin_src matlab :exports none
%% Soft Nano-Hexapod
% Light payload mass
kn = 1e4; % Nano-Hexapod (soft) Stiffness [N/m]
cn = 2*0.01*sqrt((ms + mn)*kn); % Nano-Hexapod Damping [N/(m/s)]
% Rigid Sample
model_config.nhexa = "1dof";
G_vc_light_rigid = linearize(mdl, io, 0.0);
G_vc_light_rigid.InputName = {'f', 'xf', 'ft', 'fs'};
G_vc_light_rigid.OutputName = {'dL', 'fm', 'vn', 'd', 'y'};
% Soft Sample
model_config.nhexa = "2dof";
ws = 2*pi*20;
ks = ms * ws^2;
cs = 2*0.01*sqrt(ms*ks);
G_vc_light_soft = linearize(mdl, io, 0.0);
G_vc_light_soft.InputName = {'f', 'xf', 'ft', 'fs'};
G_vc_light_soft.OutputName = {'dL', 'fm', 'vn', 'd', 'y'};
% Rigid Sample
model_config.nhexa = "2dof";
ws = 2*pi*200;
ks = ms * ws^2;
cs = 2*0.01*sqrt(ms*ks);
G_vc_light_stiff = linearize(mdl, io, 0.0);
G_vc_light_stiff.InputName = {'f', 'xf', 'ft', 'fs'};
G_vc_light_stiff.OutputName = {'dL', 'fm', 'vn', 'd', 'y'};
#+end_src
#+begin_src matlab :exports none
%% Stiff Nano-Hexapod
% Light payload mass
kn = 1e8; % Nano-Hexapod (soft) Stiffness [N/m]
cn = 2*0.01*sqrt((ms + mn)*kn); % Nano-Hexapod Damping [N/(m/s)]
% Rigid Sample
model_config.nhexa = "1dof";
G_pz_light_rigid = linearize(mdl, io, 0.0);
G_pz_light_rigid.InputName = {'f', 'xf', 'ft', 'fs'};
G_pz_light_rigid.OutputName = {'dL', 'fm', 'vn', 'd', 'y'};
% Soft Sample
model_config.nhexa = "2dof";
ws = 2*pi*20;
ks = ms * ws^2;
cs = 2*0.01*sqrt(ms*ks);
G_pz_light_soft = linearize(mdl, io, 0.0);
G_pz_light_soft.InputName = {'f', 'xf', 'ft', 'fs'};
G_pz_light_soft.OutputName = {'dL', 'fm', 'vn', 'd', 'y'};
% Rigid Sample
model_config.nhexa = "2dof";
ws = 2*pi*200;
ks = ms * ws^2;
cs = 2*0.01*sqrt(ms*ks);
G_pz_light_stiff = linearize(mdl, io, 0.0);
G_pz_light_stiff.InputName = {'f', 'xf', 'ft', 'fs'};
G_pz_light_stiff.OutputName = {'dL', 'fm', 'vn', 'd', 'y'};
#+end_src
#+begin_src matlab
%% Apply IFF and verify stability
% Soft Nano-Hexapod
G_iff_vc_light_rigid = feedback(G_vc_light_rigid, K_iff_vc, 'name', +1);
G_iff_vc_light_soft = feedback(G_vc_light_soft , K_iff_vc, 'name', +1);
G_iff_vc_light_stiff = feedback(G_vc_light_stiff, K_iff_vc, 'name', +1);
isstable(G_iff_vc_light_rigid)
isstable(G_iff_vc_light_soft)
isstable(G_iff_vc_light_stiff)
% Stiff Nano-Hexapod
G_iff_pz_light_rigid = feedback(G_pz_light_rigid, K_iff_pz, 'name', +1);
G_iff_pz_light_soft = feedback(G_pz_light_soft , K_iff_pz, 'name', +1);
G_iff_pz_light_stiff = feedback(G_pz_light_stiff, K_iff_pz, 'name', +1);
isstable(G_iff_pz_light_rigid)
isstable(G_iff_pz_light_soft)
isstable(G_iff_pz_light_stiff)
#+end_src
#+begin_src matlab
%% Compute closed-loop plants and verify stability
% Soft Nano-Hexapod
G_hac_iff_vc_light_rigid = feedback(G_iff_vc_light_rigid, K_hac_vc, 'name', -1);
G_hac_iff_vc_light_soft = feedback(G_iff_vc_light_soft , K_hac_vc, 'name', -1);
G_hac_iff_vc_light_stiff = feedback(G_iff_vc_light_stiff, K_hac_vc, 'name', -1);
isstable(G_hac_iff_vc_light_rigid)
isstable(G_hac_iff_vc_light_soft)
isstable(G_hac_iff_vc_light_stiff)
% Stiff Nano-Hexapod
G_hac_iff_pz_light_rigid = feedback(G_iff_pz_light_rigid, K_hac_pz, 'name', -1);
G_hac_iff_pz_light_soft = feedback(G_iff_pz_light_soft , K_hac_pz, 'name', -1);
G_hac_iff_pz_light_stiff = feedback(G_iff_pz_light_stiff, K_hac_pz, 'name', -1);
isstable(G_hac_iff_pz_light_rigid)
isstable(G_hac_iff_pz_light_soft)
isstable(G_hac_iff_pz_light_stiff)
#+end_src
#+begin_src matlab :exports none :results none
%% Cumulative Amplitude Spectrum of d - Effect of Sample's flexibility
figure;
hold on;
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_hac_iff_pz_light_rigid('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_hac_iff_pz_light_rigid('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'DisplayName', 'Rigid sample');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_hac_iff_pz_light_stiff('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_hac_iff_pz_light_stiff('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'DisplayName', '$\omega_s = 200\,$Hz');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_hac_iff_pz_light_soft('d', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_hac_iff_pz_light_soft('d', 'xf'), f, 'Hz'))).^2)))), '-', ...
'DisplayName', '$\omega_s = 20\,$Hz');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('CAS of $d$ [m]'); xlabel('Frequency [Hz]');
legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 1);
xlim([1, 500]);
xticks([1e0, 1e1, 1e2]);
ylim([2e-10, 2e-7])
#+end_src
#+begin_src matlab :tangle no :exports results :results file raw silent
exportFig('figs/uniaxial_sample_flexibility_noise_budget_d.pdf', 'width', 'half', 'height', 'normal');
#+end_src
#+begin_src matlab :exports none :results none
%% Cumulative Amplitude Spectrum - Effect of Sample's flexibility
figure;
hold on;
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_hac_iff_pz_light_rigid('y', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_hac_iff_pz_light_rigid('y', 'xf'), f, 'Hz'))).^2)))), '-', ...
'DisplayName', 'Rigid sample');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_hac_iff_pz_light_stiff('y', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_hac_iff_pz_light_stiff('y', 'xf'), f, 'Hz'))).^2)))), '-', ...
'DisplayName', '$\omega_s = 200\,$Hz');
plot(f, sqrt(flip(-cumtrapz(flip(f), flip(psd_ft.*abs(squeeze(freqresp(G_hac_iff_pz_light_soft('y', 'ft'), f, 'Hz'))).^2 + ...
psd_xf.*abs(squeeze(freqresp(G_hac_iff_pz_light_soft('y', 'xf'), f, 'Hz'))).^2)))), '-', ...
'DisplayName', '$\omega_s = 20\,$Hz');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('CAS of $y$ [m]'); xlabel('Frequency [Hz]');
legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 1);
xlim([1, 500]);
xticks([1e0, 1e1, 1e2]);
ylim([2e-10, 2e-7])
#+end_src
#+begin_src matlab :tangle no :exports results :results file raw silent
exportFig('figs/uniaxial_sample_flexibility_noise_budget_y.pdf', 'width', 'half', 'height', 'normal');
#+end_src
#+name: fig:uniaxial_sample_flexibility_noise_budget
#+caption: Cumulative Amplitude Spectrum of the distances $d$ and $y$. The effect of the sample's flexibility does not affects much $d$ but is detrimental to the stability of $y$. A sample mass $m_s = 1\,\text{kg}$ and a nano-hexapod stiffness of $100\,N/\mu m$ are used for the simulations.
#+attr_latex: :options [htbp]
#+begin_figure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_sample_flexibility_noise_budget_d}Cumulative Amplitude Spectrum of $d$}
#+attr_latex: :options {0.49\textwidth}
#+begin_subfigure
#+attr_latex: :width 0.95\linewidth
[[file:figs/uniaxial_sample_flexibility_noise_budget_d.png]]
#+end_subfigure
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_sample_flexibility_noise_budget_y}Cumulative Amplitude Spectrum of $y$}
#+attr_latex: :options {0.49\textwidth}
#+begin_subfigure
#+attr_latex: :width 0.95\linewidth
[[file:figs/uniaxial_sample_flexibility_noise_budget_y.png]]
#+end_subfigure
#+end_figure
** Conclusion
:PROPERTIES:
:UNNUMBERED: t
:END:
Payload dynamics is usually a major concern when designing a positioning system.
In this section, the impact of the sample dynamics on the plant was found to vary with the sample mass and the relative resonance frequency of the sample $\omega_s$ and of the nano-hexapod $\omega_n$.
The larger the sample mass, the larger the effect (i.e. change of high frequency gain, appearance of additional resonances and anti-resonances).
A zero/pole pattern is observed if $\omega_s > \omega_n$ and a pole/zero pattern if $\omega_s > \omega_n$.
Such additional dynamics can induce stability issues depending on their position relative to the wanted feedback bandwidth as explained in [[cite:&rankers98_machin Section 4.2]].
The general conclusion is that the stiffer the nano-hexapod, the less it is impacted by the payload's dynamics, which would make the feedback controller more robust to a change of payload.
This is why high-bandwidth soft positioning stages are usually restricted to constant and calibrated payloads (CD-player, lithography machines, isolation system for gravitational wave detectors, ...), while stiff positioning systems are usually used when the control must be robust to a change of payload's mass (stiff piezo nano-positioning stages for instance).
Having some flexibility between the measurement point and the point of interest (i.e. the sample point to be position on the x-ray) also degrades the position stability as shown in Section ref:ssec:uniaxial_payload_dynamics_effect_stability.
It will be therefore important to take special care when designing sampling environments, especially if a soft nano-hexapod is used.
* Conclusion
<<sec:uniaxial_conclusion>>
# Make a table summarizing the findings
In this study, a uniaxial model of the nano-active-stabilization-system has been tuned both from dynamical measurements (Section ref:sec:micro_station_model) and from disturbances measurements (Section ref:sec:uniaxial_disturbances).
It has been shown that three active damping techniques can be used to critically damp the nano-hexapod resonances (Section ref:sec:uniaxial_active_damping).
However, this model does not allows to determine which one is most suited to this application (a comparison of the three active damping techniques is done in Table ref:tab:comp_active_damping).
Position feedback controllers have been developed for three considered nano-hexapod stiffnesses (Section ref:sec:uniaxial_position_control).
These controllers were shown to be robust to the change of sample's masses, and to provide good rejection of disturbances.
It has been found that having a soft nano-hexapod makes the plant dynamics easier to control (because its dynamics is decoupled from the micro-station dynamics, see Section ref:sec:uniaxial_support_compliance) and requires less position feedback bandwidth to fulfill the requirements.
The moderately stiff nano-hexapod ($k_n = 1\,N/\mu m$) is requiring a higher feedback bandwidth, but is still giving acceptable results.
However, the stiff nano-hexapod is the most complex to control and gives the worst positioning performance.
* Bibliography :ignore:
#+latex: \printbibliography[heading=bibintoc,title={Bibliography}]
* Glossary :ignore:
[[printglossaries:]]
# #+latex: \printglossary[type=\acronymtype]
# #+latex: \printglossary[type=\glossarytype]
# #+latex: \printglossary
* Helping Functions :noexport:
** Initialize Path
#+NAME: m-init-path
#+BEGIN_SRC matlab
%% Path for functions, data and scripts
addpath('./matlab/mat/'); % Path for data
addpath('./matlab/'); % Path for scripts
#+END_SRC
#+NAME: m-init-path-tangle
#+BEGIN_SRC matlab
%% Path for functions, data and scripts
addpath('./mat/'); % Path for data
#+END_SRC
** Initialize other elements
#+NAME: m-init-other
#+BEGIN_SRC matlab
%% Colors for the figures
colors = colororder;
#+END_SRC
* Footnotes
[fn:3]DLPVA-100-B from Femto. Voltage input noise is $2.4\,nV/\sqrt{\text{Hz}}$
[fn:2]Mark Product L-22D geophones are used. Sensitivity is $88\,\frac{V}{m/s}$, natural frequency is $\approx 2\,\text{Hz}$
[fn:1]Mark Product L4-C geophones are used. Sensitivity is $171\,\frac{V}{m/s}$, natural frequency is $\approx 1\,\text{Hz}$