4194 lines
199 KiB
Org Mode
4194 lines
199 KiB
Org Mode
#+TITLE: NASS - 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]
|
|
#+LaTeX_HEADER_EXTRA: \input{preamble.tex}
|
|
|
|
#+PROPERTY: header-args:matlab :session *MATLAB*
|
|
#+PROPERTY: header-args:matlab+ :comments org
|
|
#+PROPERTY: header-args:matlab+ :exports both
|
|
#+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: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
|
|
|
|
* Introduction :ignore:
|
|
|
|
In this report, a uniaxial model of the Nano Active Stabilization System (NASS) is developed and used to have a first idea of the challenges involved in this complex system.
|
|
Note that in this document, only the vertical direction is considered (which is the most stiff), but other directions were considered as well and yields 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 NASS that will be used for further analysis (Section ref:sec:nano_station_model).
|
|
|
|
The disturbances affecting the position accuracy 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, there nano-hexapod stiffnesses are considered to better understand the trade-offs and to find the most adequate stiffness.
|
|
Three sample masses are also considered to verify the robustness of the applied control strategies to a change of sample.
|
|
|
|
Three active damping techniques are then applied on the nano-hexapod.
|
|
This helps to reduce the effect of disturbances as well as render the system easier to control afterwards (Section ref:sec:uniaxial_active_damping).
|
|
|
|
Once the system is well damped, a feedback position controller is applied, and the obtained performances are compared (Section ref:sec:uniaxial_position_control).
|
|
|
|
Conclusion remarks are given in Section ref:sec: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=colorred,fill=colorred!10!white] (-0.3*\massw, 0) rectangle (0.3*\massw, \massh) node[pos=0.5,color=colorred]{$m_{s}$};
|
|
|
|
% External Force
|
|
\draw[->, color=coloryellow] (0, \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 and sample 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) and Position control in purple (Section ref:sec:uniaxial_position_control)
|
|
#+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:micro_station_first_meas_dynamics where several geophones 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:micro_station_first_meas_dynamics
|
|
#+caption: Experimental Setup for the first dynamical measurements on the Micro-Station. Geophones are fixed to the micro-station, and the granite as well as the micro-hexapod's top platform are impact with an instrumented hammer
|
|
#+attr_latex: :width \linewidth
|
|
[[file:figs/micro_station_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:micro_station_meas_dynamics_schematic where:
|
|
- Two hammer hits are performed, one on the Granite (force $F_g$), and one on the micro-hexapod's top platform (force $F_h$)
|
|
- The inertial motion of the granite $x_g$ and the micro-hexapod's top platform $x_h$ are measured using geophones.
|
|
|
|
From the forces applied by the instrumented hammer and the responses of the geophones, the following frequency response functions can be computed:
|
|
- from $F_h$ to $d_h$ (i.e. the compliance of the micro-station)
|
|
- from $F_g$ to $d_h$ (or from $F_h$ to $d_g$)
|
|
- from $F_g$ to $d_g$
|
|
|
|
#+begin_src latex :file micro_station_meas_dynamics_schematic.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}
|
|
|
|
% 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_meas_dynamics_schematic
|
|
#+caption: Measurement setup - Schematic
|
|
#+RESULTS:
|
|
[[file:figs/micro_station_meas_dynamics_schematic.png]]
|
|
|
|
Due to the bad coherence at low frequency, the frequency response functions are only shown between 20 and 200Hz (Figure ref:fig:uniaxial_measured_frf_vertical).
|
|
|
|
#+begin_src matlab
|
|
%% Load measured FRF
|
|
load('meas_microstation_frf.mat');
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none :results none
|
|
%% Measured Frequency Response Functions in the vertical direction
|
|
figure;
|
|
tiledlayout(3, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
|
|
|
|
ax1 = nexttile([2,1]);
|
|
hold on;
|
|
plot(f(f>20), abs(frf_Fhx_to_Dhx(f>20)), ...
|
|
'DisplayName', '$D_{h}/F_{h}$');
|
|
plot(f(f>20), abs(frf_Fgx_to_Dhx(f>20)), ...
|
|
'DisplayName', '$D_{h}/F_{g}$');
|
|
plot(f(f>20), abs(frf_Fgx_to_Dgx(f>20)), ...
|
|
'DisplayName', '$D_{g}/F_{g}$');
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
|
|
ylim([1e-10, 2e-6]);
|
|
legend('location', 'northwest', 'FontSize', 8, 'NumColumns', 1);
|
|
|
|
ax2 = nexttile;
|
|
hold on;
|
|
plot(f(f>20), 180/pi*unwrap(angle(frf_Fhx_to_Dhx(f>20))));
|
|
plot(f(f>30), 180/pi*unwrap(angle(frf_Fgx_to_Dhx(f>30))));
|
|
plot(f(f>20), 180/pi*unwrap(angle(frf_Fgx_to_Dgx(f>20))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
|
|
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
|
|
hold off;
|
|
yticks(-360:90:360);
|
|
ylim([-360, 10]);
|
|
|
|
linkaxes([ax1,ax2],'x');
|
|
xlim([1, 500]);
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/uniaxial_measured_frf_vertical.pdf', 'width', 'wide', 'height', 'tall');
|
|
#+end_src
|
|
|
|
#+name: fig:uniaxial_measured_frf_vertical
|
|
#+caption: Measured Frequency Response Functions in the vertical direction
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_measured_frf_vertical.png]]
|
|
|
|
** Uniaxial Model
|
|
The uni-axial model of the micro-station is shown in Figure ref:fig:uniaxial_comp_frf_meas_model, with:
|
|
- Disturbances:
|
|
- $x_f$: Floor motion
|
|
- $f_t$: Stage vibrations
|
|
- Hammer impacts: $F_h$ and $F_g$.
|
|
- Geophones: $x_h$ and $x_g$
|
|
|
|
#+begin_src latex :file uniaxial_model_micro_station.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.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
|
|
|
|
#+name: fig:uniaxial_model_micro_station
|
|
#+caption: Uniaxial model of the micro-station
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_model_micro_station.png]]
|
|
|
|
Masses are estimated from the CAD.
|
|
#+BEGIN_SRC matlab
|
|
%% Parameters - Mass
|
|
mh = 15; % Micro Hexapod [kg]
|
|
mt = 1200; % Ty + Ry + Rz [kg]
|
|
mg = 2500; % Granite [kg]
|
|
#+END_SRC
|
|
|
|
And stiffnesses from the data-sheet of stage manufacturers.
|
|
#+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
|
|
|
|
The damping coefficients are tuned to match the identified damping from the measurements.
|
|
#+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 comparison between the measurements and the model is done in Figure ref:fig:uniaxial_comp_frf_meas_model.
|
|
|
|
As the model is simplistic, the goal is not to match exactly the measurement 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', '$D_{h,z}/F_{h,z}$');
|
|
plot(f(f>20), abs(frf_Fgz_to_Dhz(f>20)), '-', 'color', colors(2,:), 'DisplayName', '$D_{h,z}/F_{g,z}$');
|
|
plot(f(f>20), abs(frf_Fgz_to_Dgz(f>20)), '-', 'color', colors(3,:), 'DisplayName', '$D_{g,z}/F_{g,z}$');
|
|
plot(freqs, abs(squeeze(freqresp(G_id('Dh', 'Fh'), freqs, 'Hz'))), '--', 'color', colors(1,:), 'DisplayName', '$D_{h,z}/F_{h,z}$ (model)');
|
|
plot(freqs, abs(squeeze(freqresp(G_id('Dh', 'Fg'), freqs, 'Hz'))), '--', 'color', colors(2,:), 'DisplayName', '$D_{h,z}/F_{g,z}$ (model)');
|
|
plot(freqs, abs(squeeze(freqresp(G_id('Dg', 'Fg'), freqs, 'Hz'))), '--', 'color', colors(3,:), 'DisplayName', '$D_{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:
|
|
- $f_s$: direct forces applied to the sample (for instance cable forces)
|
|
- $f_t$: disturbances coming from the imperfect stage scanning performances
|
|
- $x_f$: 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 further analysis.
|
|
|
|
#+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
|
|
#+caption: Uni-axial model of the micro-station with added nano-hexapod (represented in blue) and sample (represented in green)
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_model_micro_station-nass.png]]
|
|
|
|
** 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 parameters for the nano-hexapod and sample are:
|
|
- $m_s$ the sample mass that can vary from 1kg up to 50kg
|
|
- $m_n$ the nano-hexapod mass which is set to 15kg
|
|
- $k_n$ the nano-hexapod stiffness, which can vary depending on the chosen architecture/technology
|
|
|
|
As a first example, let's choose a nano-hexapod stiffness of $10\,N/\mu m$ and a sample mass of 10kg.
|
|
|
|
#+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 Dynamics
|
|
The sensitivity to disturbances (i.e. $x_f$, $f_t$ and $f_s$) 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 are 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
|
|
figure;
|
|
tiledlayout(1, 3, 'TileSpacing', 'Compact', 'Padding', 'None');
|
|
|
|
ax1 = nexttile();
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G_ol('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]);
|
|
|
|
ax2 = nexttile();
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G_ol('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]);
|
|
|
|
ax3 = nexttile();
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G_ol('d', 'xf'), freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
ylabel('Amplitude $d/x_{f}$ [m/m]'); xlabel('Frequency [Hz]');
|
|
xticks([1e0, 1e1, 1e2]);
|
|
|
|
linkaxes([ax1,ax2,ax3],'x');
|
|
xlim([1, 500]);
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/uniaxial_sensitivity_dist_first_params.pdf', 'width', 'full', 'height', 'normal');
|
|
#+end_src
|
|
|
|
#+name: fig:uniaxial_sensitivity_dist_first_params
|
|
#+caption: Sensitivity to disturbances
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_sensitivity_dist_first_params.png]]
|
|
|
|
#+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 replace
|
|
exportFig('figs/uniaxial_plant_first_params.pdf', 'width', 'normal', 'height', 600);
|
|
#+end_src
|
|
|
|
#+name: fig:uniaxial_plant_first_params
|
|
#+caption: Bode Plot of the transfer function from actuator forces to measured displacement by the metrology
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_plant_first_params.png]]
|
|
|
|
** 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 measure disturbances, two geophones are used, on located on the floor and on on the micro-hexapod's top platform (see Figure ref:fig:micro_station_meas_disturbances).
|
|
|
|
The geophone on the floor is used to measured the floor motion $x_f$ while the geophone on the micro-hexapod is used to measure vibrations introduced by scanning of the $T_y$ stage and $R_z$ stage.
|
|
|
|
#+begin_src latex :file micro_station_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:micro_station_meas_disturbances
|
|
#+caption: Disturbance measurement setup - Schematic
|
|
#+RESULTS:
|
|
[[file:figs/micro_station_meas_disturbances.png]]
|
|
|
|
#+name: fig:micro_station_dynamical_id_setup
|
|
#+caption: Two geophones are used to measure the micro-station vibrations induced by the scanning of the $T_y$ and $R_z$ stages
|
|
#+attr_latex: :width 0.6\linewidth
|
|
[[file:figs/micro_station_dynamical_id_setup.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
|
|
|
|
#+begin_src matlab
|
|
%% Load the micro-station parameters
|
|
load('uniaxial_micro_station_parameters.mat');
|
|
#+end_src
|
|
|
|
** Ground Motion
|
|
The geophone fixed to the floor to measure the floor motion.
|
|
|
|
#+begin_src matlab
|
|
%% 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');
|
|
#+end_src
|
|
|
|
The voltage generated by each geophone is amplified using a voltage amplifier (gain of 60dB) before going to the ADC.
|
|
The sensitivity of the geophone as well as the gain of the voltage amplifier are then taken into account to reconstruct the floor displacement.
|
|
#+begin_src matlab
|
|
%% Sensitivity of the geophone
|
|
S0 = 88; % Sensitivity [V/(m/s)]
|
|
f0 = 2; % Cut-off frequency [Hz]
|
|
|
|
S = S0*(s/2/pi/f0)/(1+s/2/pi/f0); % Geophone's transfer function [V/(m/s)]
|
|
|
|
%% Gain of the voltage amplifier
|
|
G0_db = 60; % [dB]
|
|
G0 = 10^(G0_db/20); % [abs]
|
|
|
|
%% Transfer function from measured voltage to displacement
|
|
G_geo = 1/S/G0/s; % [m/V]
|
|
#+end_src
|
|
|
|
The PSD $S_{V_f}$ of the measured voltage $V_f$ is computed.
|
|
#+begin_src matlab
|
|
%% Compute measured voltage PSD
|
|
Fs = 1/(t(2)-t(1)); % Sampling Frequency [Hz]
|
|
win = hanning(ceil(2*Fs)); % Hanning window
|
|
|
|
[psd_V, f] = pwelch(V, win, [], [], Fs); % [V^2/Hz]
|
|
#+end_src
|
|
|
|
The PSD of the corresponding displacement can be computed as follows:
|
|
\begin{equation}
|
|
S_{x_f}(\omega) = \frac{S_{V_f}(\omega)}{|S_{\text{geo}}(j\omega)| \cdot G_{\text{amp}} \cdot \omega}
|
|
\end{equation}
|
|
with:
|
|
- $S_{\text{geo}}$ the sensitivity of the Geophone in $[Vs/m]$
|
|
- $G_{\text{amp}}$ the gain of the voltage amplifier
|
|
- $\omega$ is here to integrate and have the displacement instead of the velocity
|
|
|
|
#+begin_src matlab
|
|
%% Ground Motion ASD
|
|
psd_xf = psd_V.*abs(squeeze(freqresp(G_geo, f, 'Hz'))).^2; % [m^2/Hz]
|
|
#+end_src
|
|
|
|
The amplitude spectral density $\Gamma_{x_f}$ of the measured displacement $x_f$ is shown in Figure ref:fig:asd_floor_motion_id31.
|
|
|
|
#+begin_src matlab :exports none :results none
|
|
%% Measured Amplitude Spectral Density of the Floor motion on ID31
|
|
figure;
|
|
hold on;
|
|
plot(f, sqrt(psd_xf), 'DisplayName', '$\Gamma_{x_{f}}$');
|
|
hold off;
|
|
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
|
|
xlabel('Frequency [Hz]'); ylabel('Ampl. Spectral Density $\left[\frac{m}{\sqrt{Hz}}\right]$')
|
|
xlim([1, 500]);
|
|
legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 1);
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/asd_floor_motion_id31.pdf', 'width', 'wide', 'height', 'normal');
|
|
#+end_src
|
|
|
|
#+name: fig:asd_floor_motion_id31
|
|
#+caption: Measured Amplitude Spectral Density of the Floor motion on ID31
|
|
#+RESULTS:
|
|
[[file:figs/asd_floor_motion_id31.png]]
|
|
|
|
** Stage Vibration
|
|
During Spindle rotation (here at 6rpm), the granite velocity and micro-hexapod's top platform velocity are measured with the geophones.
|
|
|
|
#+begin_src matlab
|
|
%% 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
|
|
#+end_src
|
|
|
|
The Power Spectral Density of the relative velocity between the hexapod and the granite is computed.
|
|
#+begin_src matlab
|
|
%% 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]
|
|
#+end_src
|
|
|
|
It is then integrated to obtain the Amplitude Spectral Density of the relative motion which is compared with a non-rotating case (Figure ref:fig:asd_vibration_spindle_rotation).
|
|
It is shown that the spindle rotation induces vibrations in a wide frequency spectrum.
|
|
|
|
#+begin_src matlab :exports none :results none
|
|
%% Measured Amplitude Spectral Density of the relative motion 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/asd_vibration_spindle_rotation.pdf', 'width', 'wide', 'height', 'normal');
|
|
#+end_src
|
|
|
|
#+name: fig:asd_vibration_spindle_rotation
|
|
#+caption: Measured Amplitude Spectral Density of the relative motion between the granite and the micro-hexapod's top platform during Spindle rotating
|
|
#+RESULTS:
|
|
[[file:figs/asd_vibration_spindle_rotation.png]]
|
|
|
|
In order to compute the equivalent disturbance force $f_t$ that induces such motion, the transfer function from $f_t$ to the relative motion of the hexapod's top platform and the granite is extracted from the model.
|
|
#+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/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'};
|
|
#+end_src
|
|
|
|
The power spectral density $\Gamma_{f_{t}}$ of the disturbance force can be computed as follows:
|
|
\begin{equation}
|
|
\Gamma_{f_{t}}(\omega) = \frac{\Gamma_{v_{t}}(\omega)}{|G_{\text{model}}(j\omega)|^2}
|
|
\end{equation}
|
|
with:
|
|
- $\Gamma_{v_{t}}$ the measured power spectral density of the relative motion between the micro-hexapod's top platform and the granite during the spindle's rotation
|
|
- $G_{\text{model}}$ the transfer function (extracted from the uniaxial model) from $f_t$ to the relative motion between the micro-hexapod's top platform and the granite
|
|
|
|
#+begin_src matlab :exports none
|
|
%% Power Spectral Density of the equivalent force ft
|
|
psd_ft = (psd_vft./(2*pi*f).^2)./abs(squeeze(freqresp(G('Dh', 'ft') - G('Dg', 'ft'), f, 'Hz'))).^2;
|
|
#+end_src
|
|
|
|
The obtained amplitude spectral density of the disturbance force $f_t$ is shown in Figure ref:fig:asd_disturbance_force.
|
|
#+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 replace
|
|
exportFig('figs/asd_disturbance_force.pdf', 'width', 'wide', 'height', 'normal');
|
|
#+end_src
|
|
|
|
#+name: fig:asd_disturbance_force
|
|
#+caption: Estimated disturbance force ft from measurement and uniaxial model
|
|
#+RESULTS:
|
|
[[file:figs/asd_disturbance_force.png]]
|
|
|
|
The vibrations induced by the $T_y$ stage are not considered here as:
|
|
- the induced vibrations have less amplitude than the vibrations induced by the $R_z$ stage
|
|
- it can be scanned at lower velocities if the induced vibrations are an issue
|
|
|
|
#+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 we have a model of the NASS and an estimation of the power spectral density of the disturbances, it is possible to perform an /open-loop dynamic noise budgeting/.
|
|
|
|
** 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
|
|
From the Uni-axial model, 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 light sample (same conclusions can be drawn with the heavy one).
|
|
|
|
#+begin_important
|
|
From Figure ref:fig:uniaxial_sensitivity_disturbances_nano_hexapod_stiffnesses, following can be concluded for the *soft nano-hexapod*:
|
|
- It is more sensitive to forces applied on the sample (cable forces for instance), which is expected due to the lower stiffness
|
|
- Between the suspension mode of the nano-hexapod (here at 5Hz) and the first mode of the micro-station (here at 70Hz), the disturbances induced by the stage vibrations are filtered out.
|
|
- Above the suspension mode of the nano-hexapod, the sample's motion is unaffected by the floor motion, and therefore the sensitivity to floor motion is almost $1$.
|
|
#+end_important
|
|
|
|
#+begin_src matlab :exports none :results none
|
|
%% Sensitivity to disturbances for three different nano-hexpod stiffnesses
|
|
figure;
|
|
tiledlayout(1, 3, 'TileSpacing', 'Compact', 'Padding', 'None');
|
|
|
|
ax1 = nexttile();
|
|
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]);
|
|
|
|
ax2 = nexttile();
|
|
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]);
|
|
|
|
ax3 = nexttile();
|
|
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]);
|
|
legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 1);
|
|
|
|
linkaxes([ax1,ax2,ax3],'x');
|
|
xlim([1, 500]);
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/uniaxial_sensitivity_disturbances_nano_hexapod_stiffnesses.pdf', 'width', 'full', 'height', 'normal');
|
|
#+end_src
|
|
|
|
#+name: fig:uniaxial_sensitivity_disturbances_nano_hexapod_stiffnesses
|
|
#+caption: Sensitivity to disturbances for three different nano-hexpod stiffnesses
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_sensitivity_disturbances_nano_hexapod_stiffnesses.png]]
|
|
|
|
** Open-Loop Dynamic Noise Budgeting
|
|
Now, the power spectral density of the disturbances is taken into account to estimate the residual motion $d$ in each case.
|
|
|
|
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 stage vibrations, except for the soft nano-hexapod below 5Hz.
|
|
|
|
#+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;
|
|
tiledlayout(1, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
|
|
|
|
ax1 = nexttile();
|
|
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('Cumulative Ampl. Spectrum [m]'); xlabel('Frequency [Hz]');
|
|
legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 2);
|
|
|
|
xlim([1, 500]);
|
|
ylim([1e-12, 1e-6])
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/uniaxial_cas_d_disturbances_stiffnesses.pdf', 'width', 'wide', 'height', 'normal');
|
|
#+end_src
|
|
|
|
#+name: fig:uniaxial_cas_d_disturbances_stiffnesses
|
|
#+caption: Cumulative Amplitude Spectrum of the relative motion d, due to both the floor motion and the stage vibrations (light sample)
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_cas_d_disturbances_stiffnesses.png]]
|
|
|
|
The total cumulative amplitude spectrum 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 all disturbances, for two sample masses
|
|
figure;
|
|
tiledlayout(1, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
|
|
|
|
ax1 = nexttile();
|
|
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$');
|
|
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$');
|
|
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$');
|
|
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$)');
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
ylabel('Cumulative Ampl. Spectrum [m]'); xlabel('Frequency [Hz]');
|
|
legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 2);
|
|
|
|
xlim([1, 500]);
|
|
ylim([1e-11, 3e-6])
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/uniaxial_cas_d_disturbances_payload_masses.pdf', 'width', 'wide', 'height', 'normal');
|
|
#+end_src
|
|
|
|
#+name: fig:uniaxial_cas_d_disturbances_payload_masses
|
|
#+caption: Cumulative Amplitude Spectrum of the relative motion d due to all disturbances, for two sample masses
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_cas_d_disturbances_payload_masses.png]]
|
|
|
|
** Conclusion
|
|
#+begin_important
|
|
The conclusion is that in order to have a closed-loop residual vibration $d \approx 20\,nm\text{ rms}$, if a simple feedback controller is used, the required closed-loop bandwidth would be:
|
|
- $\approx 10\,\text{Hz}$ 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$)
|
|
- $\approx 100\,\text{Hz}$ for the stiff nano-hexapod ($k_n = 100\,N/\mu m$)
|
|
|
|
This can be explain by the fact that above the suspension mode of the nano-hexapod, the stage vibrations are filtered out (see Figure ref:fig:uniaxial_sensitivity_disturbances_nano_hexapod_stiffnesses).
|
|
|
|
This gives a first advantage to having a soft nano-hexapod.
|
|
#+end_important
|
|
|
|
* 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 are applied on the nano-hexapod (see Figure ref:fig:uniaxial_active_damping_strategies): Integral Force Feedback (IFF), Relative Damping Control (RDC) and Direct Velocity Feedback (DVF).
|
|
|
|
These active damping techniques are compared in terms of:
|
|
- Reduction of the effect of disturbances (i.e. $x_f$, $f_t$ and $f_s$) on the displacement $d$
|
|
- Achievable damping
|
|
- Robustness to a change of sample's mass
|
|
|
|
#+begin_src latex :file uniaxial_active_damping_strategies.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
|
|
\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}
|
|
|
|
|
|
\begin{scope}[shift={(5,0)}]
|
|
% ====================
|
|
% 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}
|
|
|
|
\begin{scope}[shift={(10,0)}]
|
|
% ====================
|
|
% 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 (IFF) using a force sensor, Relative Damping Control (RDC) using a relative displacement sensor, and Direct Velocity Feedback (DVF) using a geophone
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_active_damping_strategies.png]]
|
|
|
|
** 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
|
|
|
|
The Integral Force Feedback strategy consists of using a force sensor in series with the actuator (see Figure ref:fig:uniaxial_active_damping_iff_equiv, left).
|
|
|
|
The control strategy consists of integrating the measured force and feeding it back to the actuator:
|
|
\begin{equation}
|
|
K_{\text{IFF}}(s) = \frac{g}{s}
|
|
\end{equation}
|
|
|
|
The mechanical equivalent of this strategy is to add 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, right).
|
|
|
|
#+begin_src latex :file uniaxial_active_damping_iff_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$};
|
|
\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}
|
|
|
|
\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_equiv
|
|
#+caption: Integral Force Feedback is equivalent as to add a damper in series with the stiffness (the initial damping is here neglected for simplicity)
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_active_damping_iff_equiv.png]]
|
|
|
|
|
|
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_equiv, left).
|
|
|
|
The derivative of this relative motion is used for the feedback signal:
|
|
\begin{equation}
|
|
K_{\text{RDC}}(s) = - g \cdot s
|
|
\end{equation}
|
|
|
|
The mechanical equivalent is to add 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, right).
|
|
|
|
#+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[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}
|
|
|
|
\begin{scope}[shift={(6, 0)}]
|
|
% ====================
|
|
% 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_equiv
|
|
#+caption: Relative Damping Control is equivalent as adding a damper in parallel with the actuator/relative motion sensor
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_active_damping_rdc_equiv.png]]
|
|
|
|
Finally, the Direct Velocity Feedback strategy consists of using an inertial sensor (usually a geophone), that measured the "absolute" velocity of the body fixed on top of the actuator (se Figure ref:fig:uniaxial_active_damping_dvf_equiv, left).
|
|
|
|
The measured velocity is then fed back to the actuator:
|
|
\begin{equation}
|
|
K_{\text{DVF}}(s) = - g
|
|
\end{equation}
|
|
|
|
This is equivalent as to fix a dashpot (with a damping coefficient equal to the controller gain $g$) between the body (one which the inertial sensor is fixed) and an inertial reference frame (see Figure ref:fig:uniaxial_active_damping_dvf_equiv, right).
|
|
This is usually refers to as "/sky hook damper/".
|
|
|
|
#+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[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}
|
|
|
|
\begin{scope}[shift={(6, 0)}]
|
|
% ====================
|
|
% 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_equiv
|
|
#+caption: Direct velocity Feedback using an inertial sensor is equivalent to a "sky hook damper"
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_active_damping_dvf_equiv.png]]
|
|
|
|
** Plant Dynamics for Active Damping
|
|
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 is bounded to $\pm 90\,\text{deg}$ which makes the controller very robust.
|
|
|
|
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 transfer functions from IFF and DVF.
|
|
|
|
For the stiff nano-hexapod, 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
|
|
figure;
|
|
tiledlayout(3, 3, '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',[]);
|
|
title('IFF: $f_m/f$');
|
|
ldg = legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 1);
|
|
ldg.ItemTokenSize = [20, 1];
|
|
|
|
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',[]);
|
|
title('RDC: $d\mathcal{L}/f$');
|
|
|
|
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',[]);
|
|
title('DVF: $v_n/f$');
|
|
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]);
|
|
|
|
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]);
|
|
|
|
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([ax1,ax2,ax3,ax1b,ax2b,ax3b],'x');
|
|
xlim([1, 1000]);
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/uniaxial_plant_active_damping_techniques.pdf', 'width', 'full', 'height', 'tall');
|
|
#+end_src
|
|
|
|
#+name: fig:uniaxial_plant_active_damping_techniques
|
|
#+caption: Plant dynamics for the three active damping techniques (IFF: right, RDC: middle, DVF: left), 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).
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_plant_active_damping_techniques.png]]
|
|
|
|
** Achievable Damping - Root Locus
|
|
The Root Locus are computed for the three nano-hexapod stiffnesses and for the three active damping techniques.
|
|
They 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.
|
|
|
|
There is even a little bit of authority on micro-station modes with IFF and DVF applied on the stiff nano-hexapod (Figure ref:fig:uniaxial_root_locus_damping_techniques, right) and with RDC for a soft nano-hexapod (Figure ref:fig:uniaxial_root_locus_damping_techniques_micro_station_mode).
|
|
This can be explained by the fact that above the suspension mode of the soft nano-hexapod, the relative motion sensor acts as an inertial sensor for the micro-station top platform. Therefore, it is like DVF was applied (the nano-hexapod acts as a geophone!).
|
|
|
|
#+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
|
|
figure;
|
|
tiledlayout(1, 3, 'TileSpacing', 'Compact', 'Padding', 'None');
|
|
|
|
%% Soft Nano-Hexapod
|
|
ax1 = nexttile();
|
|
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');
|
|
title('$k_n = 0.01\,N/\mu m$')
|
|
ldg = legend('location', 'northwest', 'FontSize', 8, 'NumColumns', 1);
|
|
ldg.ItemTokenSize = [10, 1];
|
|
xlim([-30, 0]); ylim([0, 30]);
|
|
|
|
%% Medium-Stiff Nano-Hexapod
|
|
ax2 = nexttile();
|
|
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');
|
|
title('$k_n = 1\,N/\mu m$')
|
|
xlim([-300, 0]); ylim([0, 300]);
|
|
|
|
%% Stiff Nano-Hexapod
|
|
ax3 = nexttile();
|
|
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');
|
|
title('$k_n = 100\,N/\mu m$')
|
|
xlim([-4000, 0]); ylim([0, 4000]);
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/uniaxial_root_locus_damping_techniques.pdf', 'width', 'full', '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.
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_root_locus_damping_techniques.png]]
|
|
|
|
#+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');
|
|
for g = logspace(2,5,500)
|
|
clpoles = pole(feedback(G_md_mid('dL', 'f'), -g*s, +1));
|
|
plot(real(clpoles), imag(clpoles), '.', 'color', colors(2,:), ...
|
|
'HandleVisibility', 'off');
|
|
end
|
|
|
|
% 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. 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]]
|
|
|
|
** 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 Active Damping Controllers
|
|
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 Active Damping Controller
|
|
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
|
|
|
|
** Change of sensitivity to disturbances
|
|
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$.
|
|
|
|
#+begin_important
|
|
Conclusions from Figure ref:fig:uniaxial_sensitivity_dist_active_damping are:
|
|
- IFF degrades the sensitivity to direct forces on the sample (i.e. the compliance) below the resonance of the nano-hexapod
|
|
- RDC degrades the sensitivity to stage vibrations around the nano-hexapod's resonance as compared to the other two methods
|
|
- both IFF and DVF degrades the sensitivity to floor motion below the resonance of the nano-hexapod
|
|
#+end_important
|
|
|
|
#+begin_src matlab :exports none :results none
|
|
%% Change of sensitivity to disturbance with all three active damping strategies
|
|
figure;
|
|
tiledlayout(1, 3, 'TileSpacing', 'Compact', 'Padding', 'None');
|
|
|
|
ax1 = nexttile();
|
|
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]);
|
|
|
|
ax2 = nexttile();
|
|
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]);
|
|
|
|
ax3 = nexttile();
|
|
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);
|
|
|
|
linkaxes([ax1,ax2,ax3],'x');
|
|
xlim([1, 500]);
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/uniaxial_sensitivity_dist_active_damping.pdf', 'width', 'full', 'height', 'normal');
|
|
#+end_src
|
|
|
|
#+name: fig:uniaxial_sensitivity_dist_active_damping
|
|
#+caption: Change of sensitivity to disturbance with all three active damping strategies
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_sensitivity_dist_active_damping.png]]
|
|
|
|
** Noise Budgeting after Active Damping
|
|
Cumulative Amplitude Spectrum of the distance $d$ with all three active damping techniques are compared in Figure ref:fig:uniaxial_cas_active_damping.
|
|
All three active damping methods are giving similar results (except the RDC which is a little bit worse for the stiff nano-hexapod).
|
|
|
|
Compare to the open-loop case, the active damping helps to lower the vibrations induced by the nano-hexapod resonance.
|
|
|
|
#+begin_src matlab :exports none :results none
|
|
%% Cumulative Amplitude Spectrum of the distance d with all three active damping techniques
|
|
figure;
|
|
tiledlayout(1, 3, 'TileSpacing', 'Compact', 'Padding', 'None');
|
|
|
|
ax1 = nexttile();
|
|
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]);
|
|
title('$k_n = 0.01\,N/\mu m$')
|
|
|
|
ax2 = nexttile();
|
|
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]);
|
|
title('$k_n = 1\,N/\mu m$')
|
|
|
|
ax3 = nexttile();
|
|
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]);
|
|
title('$k_n = 100\,N/\mu m$')
|
|
legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 1);
|
|
|
|
linkaxes([ax1,ax2,ax3], 'xy')
|
|
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.pdf', 'width', 'full', '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).
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_cas_active_damping.png]]
|
|
|
|
** Obtained Damped Plant
|
|
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_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',[]);
|
|
legend('location', 'northwest', 'FontSize', 8, 'NumColumns', 1);
|
|
|
|
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]);
|
|
|
|
linkaxes([ax1,ax2],'x');
|
|
xlim([1, 500]);
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/uniaxial_damped_plant_three_active_damping_techniques.pdf', 'width', 'wide', 'height', 'tall');
|
|
#+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
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_damped_plant_three_active_damping_techniques.png]]
|
|
|
|
The damped plants are shown in Figure ref:fig:uniaxial_damped_plant_change_sample_mass for all three techniques, with the three considered nano-hexapod stiffnesses and sample's masses.
|
|
#+begin_src matlab :exports none :results none
|
|
%% Damped plant - Robustness to change of sample's mass
|
|
figure;
|
|
tiledlayout(3, 3, 'TileSpacing', 'Compact', 'Padding', 'None');
|
|
|
|
ax1 = nexttile([2,1]);
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G_vc_mid('d', 'f'), freqs, 'Hz'))), '-', 'color', [0, 0, 0, 0.5], 'HandleVisibility', 'off');
|
|
plot(freqs, abs(squeeze(freqresp(G_md_mid('d', 'f'), freqs, 'Hz'))), '-', 'color', [0, 0, 0, 0.5], 'HandleVisibility', 'off');
|
|
plot(freqs, abs(squeeze(freqresp(G_pz_mid('d', 'f'), freqs, 'Hz'))), '-', 'color', [0, 0, 0, 0.5], 'HandleVisibility', 'off');
|
|
plot(freqs, abs(squeeze(freqresp(G_iff_vc_light('d', 'f'), freqs, 'Hz'))), '-', 'color', colors(1,:), 'DisplayName', '$k_n = 0.01\,N/\mu m$');
|
|
plot(freqs, abs(squeeze(freqresp(G_iff_vc_mid( 'd', 'f'), freqs, 'Hz'))), '-.', 'color', colors(1,:), 'HandleVisibility', 'off');
|
|
plot(freqs, abs(squeeze(freqresp(G_iff_vc_heavy('d', 'f'), freqs, 'Hz'))), '--', 'color', colors(1,:), 'HandleVisibility', 'off');
|
|
plot(freqs, abs(squeeze(freqresp(G_iff_md_light('d', 'f'), freqs, 'Hz'))), '-', 'color', colors(2,:), 'DisplayName', '$k_n = 1\,N/\mu m$');
|
|
plot(freqs, abs(squeeze(freqresp(G_iff_md_mid( 'd', 'f'), freqs, 'Hz'))), '-.', 'color', colors(2,:), 'HandleVisibility', 'off');
|
|
plot(freqs, abs(squeeze(freqresp(G_iff_md_heavy('d', 'f'), freqs, 'Hz'))), '--', 'color', colors(2,:), 'HandleVisibility', 'off');
|
|
plot(freqs, abs(squeeze(freqresp(G_iff_pz_light('d', 'f'), freqs, 'Hz'))), '-', 'color', colors(3,:), 'DisplayName', '$k_n = 100\,N/\mu m$');
|
|
plot(freqs, abs(squeeze(freqresp(G_iff_pz_mid( 'd', 'f'), freqs, 'Hz'))), '-.', 'color', colors(3,:), 'HandleVisibility', 'off');
|
|
plot(freqs, abs(squeeze(freqresp(G_iff_pz_heavy('d', 'f'), freqs, 'Hz'))), '--', 'color', colors(3,:), 'HandleVisibility', 'off');
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
|
|
title('IFF');
|
|
ylim([5e-10, 1e-3]);
|
|
ldg = legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 1);
|
|
ldg.ItemTokenSize = [20, 1];
|
|
|
|
ax2 = nexttile([2,1]);
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G_vc_mid('d', 'f'), freqs, 'Hz'))), '-', 'color', [0, 0, 0, 0.5]);
|
|
plot(freqs, abs(squeeze(freqresp(G_md_mid('d', 'f'), freqs, 'Hz'))), '-', 'color', [0, 0, 0, 0.5]);
|
|
plot(freqs, abs(squeeze(freqresp(G_pz_mid('d', 'f'), freqs, 'Hz'))), '-', 'color', [0, 0, 0, 0.5]);
|
|
plot(freqs, abs(squeeze(freqresp(G_rdc_vc_light('d', 'f'), freqs, 'Hz'))), '-', 'color', colors(1,:));
|
|
plot(freqs, abs(squeeze(freqresp(G_rdc_vc_mid( 'd', 'f'), freqs, 'Hz'))), '-.', 'color', colors(1,:));
|
|
plot(freqs, abs(squeeze(freqresp(G_rdc_vc_heavy('d', 'f'), freqs, 'Hz'))), '--', 'color', colors(1,:));
|
|
plot(freqs, abs(squeeze(freqresp(G_rdc_md_light('d', 'f'), freqs, 'Hz'))), '-', 'color', colors(2,:));
|
|
plot(freqs, abs(squeeze(freqresp(G_rdc_md_mid( 'd', 'f'), freqs, 'Hz'))), '-.', 'color', colors(2,:));
|
|
plot(freqs, abs(squeeze(freqresp(G_rdc_md_heavy('d', 'f'), freqs, 'Hz'))), '--', 'color', colors(2,:));
|
|
plot(freqs, abs(squeeze(freqresp(G_rdc_pz_light('d', 'f'), freqs, 'Hz'))), '-', 'color', colors(3,:));
|
|
plot(freqs, abs(squeeze(freqresp(G_rdc_pz_mid( 'd', 'f'), freqs, 'Hz'))), '-.', 'color', colors(3,:));
|
|
plot(freqs, abs(squeeze(freqresp(G_rdc_pz_heavy('d', 'f'), freqs, 'Hz'))), '--', 'color', colors(3,:));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
set(gca, 'XTickLabel',[]); set(gca, 'YTickLabel',[]);
|
|
title('RDC');
|
|
ylim([5e-10, 1e-3]);
|
|
|
|
ax3 = nexttile([2,1]);
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G_vc_mid('d', 'f'), freqs, 'Hz'))), '-', 'color', [0, 0, 0, 0.5], 'HandleVisibility', 'off');
|
|
plot(freqs, abs(squeeze(freqresp(G_md_mid('d', 'f'), freqs, 'Hz'))), '-', 'color', [0, 0, 0, 0.5], 'HandleVisibility', 'off');
|
|
plot(freqs, abs(squeeze(freqresp(G_pz_mid('d', 'f'), freqs, 'Hz'))), '-', 'color', [0, 0, 0, 0.5], 'HandleVisibility', 'off');
|
|
plot(freqs, abs(squeeze(freqresp(G_dvf_vc_light('d', 'f'), freqs, 'Hz'))), '-', 'color', colors(1,:), 'DisplayName', '$m_s = 1\,kg$');
|
|
plot(freqs, abs(squeeze(freqresp(G_dvf_vc_mid( 'd', 'f'), freqs, 'Hz'))), '-.', 'color', colors(1,:), 'DisplayName', '$m_s = 25\,kg$');
|
|
plot(freqs, abs(squeeze(freqresp(G_dvf_vc_heavy('d', 'f'), freqs, 'Hz'))), '--', 'color', colors(1,:), 'DisplayName', '$m_s = 50\,kg$');
|
|
plot(freqs, abs(squeeze(freqresp(G_dvf_md_light('d', 'f'), freqs, 'Hz'))), '-', 'color', colors(2,:), 'HandleVisibility', 'off');
|
|
plot(freqs, abs(squeeze(freqresp(G_dvf_md_mid( 'd', 'f'), freqs, 'Hz'))), '-.', 'color', colors(2,:), 'HandleVisibility', 'off');
|
|
plot(freqs, abs(squeeze(freqresp(G_dvf_md_heavy('d', 'f'), freqs, 'Hz'))), '--', 'color', colors(2,:), 'HandleVisibility', 'off');
|
|
plot(freqs, abs(squeeze(freqresp(G_dvf_pz_light('d', 'f'), freqs, 'Hz'))), '-', 'color', colors(3,:), 'HandleVisibility', 'off');
|
|
plot(freqs, abs(squeeze(freqresp(G_dvf_pz_mid( 'd', 'f'), freqs, 'Hz'))), '-.', 'color', colors(3,:), 'HandleVisibility', 'off');
|
|
plot(freqs, abs(squeeze(freqresp(G_dvf_pz_heavy('d', 'f'), freqs, 'Hz'))), '--', 'color', colors(3,:), 'HandleVisibility', 'off');
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
set(gca, 'XTickLabel',[]); set(gca, 'YTickLabel',[]);
|
|
title('DVF');
|
|
ylim([5e-10, 1e-3]);
|
|
ldg = legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 1);
|
|
ldg.ItemTokenSize = [20, 1];
|
|
|
|
ax1b = nexttile();
|
|
hold on;
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_vc_mid('d', 'f'), freqs, 'Hz')))), '-', 'color', [0, 0, 0, 0.5]);
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_md_mid('d', 'f'), freqs, 'Hz')))), '-', 'color', [0, 0, 0, 0.5]);
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_pz_mid('d', 'f'), freqs, 'Hz')))), '-', 'color', [0, 0, 0, 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(1,:));
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_iff_vc_heavy('d', 'f'), freqs, 'Hz')))), '--', 'color', colors(1,:));
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_iff_md_light('d', 'f'), freqs, 'Hz')))), '-', 'color', colors(2,:));
|
|
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(2,:));
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_iff_pz_light('d', 'f'), freqs, 'Hz')))), '-', 'color', colors(3,:));
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_iff_pz_mid( 'd', 'f'), freqs, 'Hz')))), '-.', 'color', colors(3,:));
|
|
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');
|
|
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
|
|
xticks([1e0, 1e1, 1e2]);
|
|
yticks(-360:90:360);
|
|
ylim([-200, 20]);
|
|
|
|
ax2b = nexttile();
|
|
hold on;
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_vc_mid('d', 'f'), freqs, 'Hz')))), '-', 'color', [0, 0, 0, 0.5]);
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_md_mid('d', 'f'), freqs, 'Hz')))), '-', 'color', [0, 0, 0, 0.5]);
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_pz_mid('d', 'f'), freqs, 'Hz')))), '-', 'color', [0, 0, 0, 0.5]);
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_rdc_vc_light('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(1,:));
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_rdc_vc_heavy('d', 'f'), freqs, 'Hz')))), '--', 'color', colors(1,:));
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_rdc_md_light('d', 'f'), freqs, 'Hz')))), '-', 'color', colors(2,:));
|
|
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_rdc_md_heavy('d', 'f'), freqs, 'Hz')))), '--', 'color', colors(2,:));
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_rdc_pz_light('d', 'f'), freqs, 'Hz')))), '-', 'color', colors(3,:));
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_rdc_pz_mid( 'd', 'f'), freqs, 'Hz')))), '-.', 'color', colors(3,:));
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_rdc_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]);
|
|
|
|
ax3b = nexttile();
|
|
hold on;
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_vc_mid('d', 'f'), freqs, 'Hz')))), '-', 'color', [0, 0, 0, 0.5]);
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_md_mid('d', 'f'), freqs, 'Hz')))), '-', 'color', [0, 0, 0, 0.5]);
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_pz_mid('d', 'f'), freqs, 'Hz')))), '-', 'color', [0, 0, 0, 0.5]);
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_dvf_vc_light('d', 'f'), freqs, 'Hz')))), '-', 'color', colors(1,:));
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_dvf_vc_mid( 'd', 'f'), freqs, 'Hz')))), '-.', 'color', colors(1,:));
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_dvf_vc_heavy('d', 'f'), freqs, 'Hz')))), '--', 'color', colors(1,:));
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_dvf_md_light('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(2,:));
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_dvf_md_heavy('d', 'f'), freqs, 'Hz')))), '--', 'color', colors(2,:));
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_dvf_pz_light('d', 'f'), freqs, 'Hz')))), '-', 'color', colors(3,:));
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_dvf_pz_mid( 'd', 'f'), freqs, 'Hz')))), '-.', 'color', colors(3,:));
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_dvf_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([ax1,ax2,ax3,ax1b,ax2b,ax3b],'x');
|
|
xlim([1, 1e3]);
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/uniaxial_damped_plant_change_sample_mass.pdf', 'width', 'full', 'height', 'tall');
|
|
#+end_src
|
|
|
|
#+name: fig:uniaxial_damped_plant_change_sample_mass
|
|
#+caption: Damped plant $d/f$ - Robustness to change of sample's mass for all three active damping techniques. Grey curves are the open-loop (i.e. undamped) plants.
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_damped_plant_change_sample_mass.png]]
|
|
|
|
** Robustness to change of payload's mass
|
|
The Root Locus for the three damping techniques are shown in Figure ref:fig:uniaxial_active_damping_robustness_mass_root_locus for three sample's mass (1kg, 25kg and 50kg).
|
|
The closed-loop poles are shown by the squares for a specific gain.
|
|
|
|
We can see that having heavier samples yields larger damping for IFF and smaller damping for RDC and DVF.
|
|
|
|
#+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
|
|
figure;
|
|
tiledlayout(1, 3, 'TileSpacing', 'Compact', 'Padding', 'None');
|
|
|
|
%% Integral Force Feedback
|
|
ax1 = nexttile();
|
|
hold on;
|
|
% Light Sample
|
|
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(1,4,100)
|
|
clpoles = pole(feedback(G_md_light('fm', 'f'), g/s, +1));
|
|
plot(real(clpoles), imag(clpoles), '.', 'color', colors(1,:), ...
|
|
'HandleVisibility', 'off');
|
|
end
|
|
clpoles = pole(feedback(G_md_light('fm', 'f'), K_iff_md, +1));
|
|
plot(real(clpoles), imag(clpoles), 'square', 'color', colors(1,:), ...
|
|
'DisplayName', '$m_s = 1\,kg$');
|
|
|
|
% Mid Sample
|
|
plot(real(pole(G_md_mid('fm', 'f'))), imag(pole(G_md_mid('fm', 'f'))), 'x', 'color', colors(2,:), ...
|
|
'HandleVisibility', 'off');
|
|
plot(real(zero(G_md_mid('fm', 'f'))), imag(zero(G_md_mid('fm', 'f'))), 'o', 'color', colors(2,:), ...
|
|
'HandleVisibility', 'off');
|
|
for g = logspace(1,4,100)
|
|
clpoles = pole(feedback(G_md_mid('fm', 'f'), g/s, +1));
|
|
plot(real(clpoles), imag(clpoles), '.', 'color', colors(2,:), ...
|
|
'HandleVisibility', 'off');
|
|
end
|
|
clpoles = pole(feedback(G_md_mid('fm', 'f'), K_iff_md, +1));
|
|
plot(real(clpoles), imag(clpoles), 'square', 'color', colors(2,:), ...
|
|
'DisplayName', '$m_s = 25\,kg$');
|
|
|
|
% Heavy Sample
|
|
plot(real(pole(G_md_heavy('fm', 'f'))), imag(pole(G_md_heavy('fm', 'f'))), 'x', 'color', colors(3,:), ...
|
|
'HandleVisibility', 'off');
|
|
plot(real(zero(G_md_heavy('fm', 'f'))), imag(zero(G_md_heavy('fm', 'f'))), 'o', 'color', colors(3,:), ...
|
|
'HandleVisibility', 'off');
|
|
for g = logspace(1,4,100)
|
|
clpoles = pole(feedback(G_md_heavy('fm', 'f'), g/s, +1));
|
|
plot(real(clpoles), imag(clpoles), '.', 'color', colors(3,:), ...
|
|
'HandleVisibility', 'off');
|
|
end
|
|
clpoles = pole(feedback(G_md_heavy('fm', 'f'), K_iff_md, +1));
|
|
plot(real(clpoles), imag(clpoles), 'square', 'color', colors(3,:), ...
|
|
'DisplayName', '$m_s = 50\,kg$');
|
|
hold off;
|
|
axis square;
|
|
xlabel('Real Part'); ylabel('Imaginary Part');
|
|
title('IFF')
|
|
ldg = legend('location', 'northwest', 'FontSize', 8, 'NumColumns', 1);
|
|
ldg.ItemTokenSize = [10, 1];
|
|
|
|
%% Relative Damping Control
|
|
ax2 = nexttile();
|
|
hold on;
|
|
% Light Sample
|
|
plot(real(pole(G_md_light('dL', 'f'))), imag(pole(G_md_light('dL', 'f'))), 'x', 'color', colors(1,:), ...
|
|
'DisplayName', '$m_s = 1\,kg$');
|
|
plot(real(zero(G_md_light('dL', 'f'))), imag(zero(G_md_light('dL', 'f'))), 'o', 'color', colors(1,:), ...
|
|
'HandleVisibility', 'off');
|
|
for g = logspace(2,5,100)
|
|
clpoles = pole(feedback(G_md_light('dL', 'f'), -g*s, +1));
|
|
plot(real(clpoles), imag(clpoles), '.', 'color', colors(1,:), ...
|
|
'HandleVisibility', 'off');
|
|
end
|
|
clpoles = pole(feedback(G_md_light('dL', 'f'), K_rdc_md, +1));
|
|
plot(real(clpoles), imag(clpoles), 'square', 'color', colors(1,:), ...
|
|
'HandleVisibility', 'off');
|
|
|
|
% Mid Sample
|
|
plot(real(pole(G_md_mid('dL', 'f'))), imag(pole(G_md_mid('dL', 'f'))), 'x', 'color', colors(2,:), ...
|
|
'DisplayName', '$m_s = 25\,kg$');
|
|
plot(real(zero(G_md_mid('dL', 'f'))), imag(zero(G_md_mid('dL', 'f'))), 'o', 'color', colors(2,:), ...
|
|
'HandleVisibility', 'off');
|
|
for g = logspace(2,5,100)
|
|
clpoles = pole(feedback(G_md_mid('dL', 'f'), -g*s, +1));
|
|
plot(real(clpoles), imag(clpoles), '.', 'color', colors(2,:), ...
|
|
'HandleVisibility', 'off');
|
|
end
|
|
clpoles = pole(feedback(G_md_mid('dL', 'f'), K_rdc_md, +1));
|
|
plot(real(clpoles), imag(clpoles), 'square', 'color', colors(2,:), ...
|
|
'HandleVisibility', 'off');
|
|
|
|
% Heavy Sample
|
|
plot(real(pole(G_md_heavy('dL', 'f'))), imag(pole(G_md_heavy('dL', 'f'))), 'x', 'color', colors(3,:), ...
|
|
'DisplayName', '$m_s = 50\,kg$');
|
|
plot(real(zero(G_md_heavy('dL', 'f'))), imag(zero(G_md_heavy('dL', 'f'))), 'o', 'color', colors(3,:), ...
|
|
'HandleVisibility', 'off');
|
|
for g = logspace(2,5,100)
|
|
clpoles = pole(feedback(G_md_heavy('dL', 'f'), -g*s, +1));
|
|
plot(real(clpoles), imag(clpoles), '.', 'color', colors(3,:), ...
|
|
'HandleVisibility', 'off');
|
|
end
|
|
clpoles = pole(feedback(G_md_heavy('dL', 'f'), K_rdc_md, +1));
|
|
plot(real(clpoles), imag(clpoles), 'square', 'color', colors(3,:), ...
|
|
'HandleVisibility', 'off');
|
|
hold off;
|
|
axis square;
|
|
xlabel('Real Part'); ylabel('Imaginary Part');
|
|
title('RDC');
|
|
|
|
%% Direct Velocity Feedback
|
|
ax3 = nexttile();
|
|
hold on;
|
|
% Light Sample
|
|
plot(real(pole(G_md_light('vn', 'f'))), imag(pole(G_md_light('vn', 'f'))), 'x', 'color', colors(1,:), ...
|
|
'DisplayName', '$m_s = 1\,kg$');
|
|
plot(real(zero(G_md_light('vn', 'f'))), imag(zero(G_md_light('vn', 'f'))), 'o', 'color', colors(1,:), ...
|
|
'HandleVisibility', 'off');
|
|
for g = logspace(2,5,100)
|
|
clpoles = pole(feedback(G_md_light('vn', 'f'), -g, +1));
|
|
plot(real(clpoles), imag(clpoles), '.', 'color', colors(1,:), ...
|
|
'HandleVisibility', 'off');
|
|
end
|
|
clpoles = pole(feedback(G_md_light('vn', 'f'), K_dvf_md, +1));
|
|
plot(real(clpoles), imag(clpoles), 'square', 'color', colors(1,:), ...
|
|
'HandleVisibility', 'off');
|
|
|
|
% Mid Sample
|
|
plot(real(pole(G_md_mid('vn', 'f'))), imag(pole(G_md_mid('vn', 'f'))), 'x', 'color', colors(2,:), ...
|
|
'DisplayName', '$m_s = 25\,kg$');
|
|
plot(real(zero(G_md_mid('vn', 'f'))), imag(zero(G_md_mid('vn', 'f'))), 'o', 'color', colors(2,:), ...
|
|
'HandleVisibility', 'off');
|
|
for g = logspace(2,5,100)
|
|
clpoles = pole(feedback(G_md_mid('vn', 'f'), -g, +1));
|
|
plot(real(clpoles), imag(clpoles), '.', 'color', colors(2,:), ...
|
|
'HandleVisibility', 'off');
|
|
end
|
|
clpoles = pole(feedback(G_md_mid('vn', 'f'), K_dvf_md, +1));
|
|
plot(real(clpoles), imag(clpoles), 'square', 'color', colors(2,:), ...
|
|
'HandleVisibility', 'off');
|
|
|
|
% Heavy Sample
|
|
plot(real(pole(G_md_heavy('vn', 'f'))), imag(pole(G_md_heavy('vn', 'f'))), 'x', 'color', colors(3,:), ...
|
|
'DisplayName', '$m_s = 50\,kg$');
|
|
plot(real(zero(G_md_heavy('vn', 'f'))), imag(zero(G_md_heavy('vn', 'f'))), 'o', 'color', colors(3,:), ...
|
|
'HandleVisibility', 'off');
|
|
for g = logspace(2,5,100)
|
|
clpoles = pole(feedback(G_md_heavy('vn', 'f'), -g, +1));
|
|
plot(real(clpoles), imag(clpoles), '.', 'color', colors(3,:), ...
|
|
'HandleVisibility', 'off');
|
|
end
|
|
clpoles = pole(feedback(G_md_heavy('vn', 'f'), K_dvf_md, +1));
|
|
plot(real(clpoles), imag(clpoles), 'square', 'color', colors(3,:), ...
|
|
'HandleVisibility', 'off');
|
|
hold off;
|
|
axis square;
|
|
xlabel('Real Part'); ylabel('Imaginary Part');
|
|
title('DVF');
|
|
|
|
linkaxes([ax1,ax2,ax3],'xy');
|
|
xlim([-300, 0]); ylim([0, 300]);
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/uniaxial_active_damping_robustness_mass_root_locus.pdf', 'width', 'full', 'height', 'normal');
|
|
#+end_src
|
|
|
|
#+name: fig:uniaxial_active_damping_robustness_mass_root_locus
|
|
#+caption: Active Damping Robustness to change of sample's mass - Root Locus for all three damping techniques with 3 different sample's masses
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_active_damping_robustness_mass_root_locus.png]]
|
|
|
|
** Conclusion
|
|
|
|
#+begin_important
|
|
Conclusions for Active Damping:
|
|
- All three active damping techniques yields good damping (Figure ref:fig:uniaxial_root_locus_damping_techniques) and similar remaining vibrations (Figure ref:fig:uniaxial_cas_active_damping)
|
|
- The obtained damped plants (Figure ref:fig:uniaxial_damped_plant_change_sample_mass) are equivalent for the three active damping techniques
|
|
- Which one to be used will be determined with the use of more accurate models and will depend on which is the easiest to implement in practice
|
|
#+end_important
|
|
|
|
#+name: tab:comp_active_damping
|
|
#+caption: Comparison of active damping strategies
|
|
#+attr_latex: :environment tabularx :width \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 High Authority Control - Low Authority Control (HAC-LAC) 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$).
|
|
- Then, a position controller $\bm{K}_{\textsc{HAC}}$ is implemented.
|
|
|
|
#+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
|
|
|
|
Combined with the uniaxial model, it is shown in Figure ref:fig:uniaxial_hac_lac_model.
|
|
|
|
#+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: High Authority Control - Low Authority Control (HAC-LAC)
|
|
#+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: :options {0.45\textwidth}
|
|
#+attr_latex: :caption \subcaption{\label{fig:uniaxial_hac_lac_model}Uniaxial model with HAC-LAC strategy}
|
|
#+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
|
|
As was shown in Section ref:sec:uniaxial_active_damping, all three proposed active damping techniques yield similar damping plants.
|
|
Therefore, /Integral Force Feedback/ will be used in this section to study the HAC-LAC performances.
|
|
|
|
The obtained damped plants for the three nano-hexapod stiffnesses are shown in Figure ref:fig:uniaxial_hac_iff_damped_plants_masses.
|
|
|
|
#+begin_src matlab :exports none :results none
|
|
%% Damped plant - Robustness to change of sample's mass
|
|
figure;
|
|
tiledlayout(3, 3, 'TileSpacing', 'Compact', 'Padding', 'None');
|
|
|
|
ax1 = nexttile([2,1]);
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G_iff_vc_light('d', 'f'), freqs, 'Hz'))), '-', 'DisplayName', '$m_s = 1\,kg$');
|
|
plot(freqs, abs(squeeze(freqresp(G_iff_vc_mid( 'd', 'f'), freqs, 'Hz'))), '-', 'DisplayName', '$m_s = 25\,kg$');
|
|
plot(freqs, abs(squeeze(freqresp(G_iff_vc_heavy('d', 'f'), freqs, 'Hz'))), '-', 'DisplayName', '$m_s = 50\,kg$');
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
|
|
title('$k_n = 0.01\,N/\mu m$');
|
|
ylim([5e-10, 1e-3]);
|
|
ldg = legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 1);
|
|
ldg.ItemTokenSize = [20, 1];
|
|
|
|
ax2 = nexttile([2,1]);
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G_iff_md_light('d', 'f'), freqs, 'Hz'))));
|
|
plot(freqs, abs(squeeze(freqresp(G_iff_md_mid( 'd', 'f'), freqs, 'Hz'))));
|
|
plot(freqs, abs(squeeze(freqresp(G_iff_md_heavy('d', 'f'), freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
set(gca, 'XTickLabel',[]); set(gca, 'YTickLabel',[]);
|
|
title('$k_n = 1\,N/\mu m$');
|
|
ylim([5e-10, 1e-3]);
|
|
|
|
ax3 = nexttile([2,1]);
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G_iff_pz_light('d', 'f'), freqs, 'Hz'))));
|
|
plot(freqs, abs(squeeze(freqresp(G_iff_pz_mid( 'd', 'f'), freqs, 'Hz'))));
|
|
plot(freqs, abs(squeeze(freqresp(G_iff_pz_heavy('d', 'f'), freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
set(gca, 'XTickLabel',[]); set(gca, 'YTickLabel',[]);
|
|
title('$k_n = 100\,N/\mu m$');
|
|
ylim([5e-10, 1e-3]);
|
|
|
|
ax1b = nexttile();
|
|
hold on;
|
|
plot(freqs, unwrap(180/pi*angle(squeeze(freqresp(G_iff_vc_light('d', 'f'), freqs, 'Hz')))));
|
|
plot(freqs, unwrap(180/pi*angle(squeeze(freqresp(G_iff_vc_mid( 'd', 'f'), freqs, 'Hz')))));
|
|
plot(freqs, unwrap(180/pi*angle(squeeze(freqresp(G_iff_vc_heavy('d', 'f'), freqs, 'Hz')))));
|
|
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]);
|
|
|
|
ax2b = nexttile();
|
|
hold on;
|
|
plot(freqs, unwrap(180/pi*angle(squeeze(freqresp(G_iff_md_light('d', 'f'), freqs, 'Hz')))));
|
|
plot(freqs, unwrap(180/pi*angle(squeeze(freqresp(G_iff_md_mid( 'd', 'f'), freqs, 'Hz')))));
|
|
plot(freqs, unwrap(180/pi*angle(squeeze(freqresp(G_iff_md_heavy('d', 'f'), freqs, 'Hz')))));
|
|
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]);
|
|
|
|
ax3b = nexttile();
|
|
hold on;
|
|
plot(freqs, unwrap(180/pi*angle(squeeze(freqresp(G_iff_pz_light('d', 'f'), freqs, 'Hz')))));
|
|
plot(freqs, unwrap(180/pi*angle(squeeze(freqresp(G_iff_pz_mid( 'd', 'f'), freqs, 'Hz')))));
|
|
plot(freqs, unwrap(180/pi*angle(squeeze(freqresp(G_iff_pz_heavy('d', 'f'), freqs, 'Hz')))));
|
|
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([ax1,ax2,ax3,ax1b,ax2b,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.pdf', 'width', 'full', '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
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_hac_iff_damped_plants_masses.png]]
|
|
|
|
** Position Feedback Controller
|
|
The objective now is to design a position feedback controller for each of the three nano-hexapods that are robust to the change of sample's mass.
|
|
|
|
The required feedback bandwidth was approximately determined un Section ref:sec:uniaxial_noise_budgeting:
|
|
- $\approx 10\,\text{Hz}$ for the soft nano-hexapod ($k_n = 0.01\,N/\mu m$).
|
|
Near this frequency, the plants are equivalent to a mass line.
|
|
The gain of the mass line can vary up to a fact $\approx 5$ (suspended mass from $16\,kg$ up to $65\,kg$).
|
|
This mean 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.
|
|
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.
|
|
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).
|
|
These high authority controllers are generally composed of a two integrators 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 loop gains 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, 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.
|
|
- for the stiff nano-hexapod, the obtained crossover frequency is not at high as what was estimated necessary.
|
|
The crossover frequency in that case is close to the stiffness line of the plant, which makes the robust design of the controller easier.
|
|
|
|
Note that these controller were quickly tuned by hand and not designed using any optimization methods.
|
|
The goal is just to have a first estimation of the attainable performances.
|
|
|
|
#+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)));
|
|
|
|
% Low Pass filter to increase robustness
|
|
H_lpf = 1/(1 + s/2/pi/200);
|
|
|
|
% Added integrator at low frequency
|
|
H_int = (s + 2*pi*5)/(s + 2*pi*0.01);
|
|
|
|
% High Authority Controller
|
|
K_hac_vc = 4e5 * ... % Gain
|
|
H_lead * ... % Lead
|
|
H_int * ... % Integrator
|
|
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
|
|
% Integrator as low frequency
|
|
H_int = (s + 2*pi*10)/(s + 2*pi*0.01) * (s + 2*pi*20)/(s + 2*pi*0.01);
|
|
|
|
% 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)));
|
|
|
|
% 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_lpf * ... % Low Pass Filter
|
|
H_int; % Integrator
|
|
K_hac_md.InputName = {'d'};
|
|
K_hac_md.OutputName = {'f'};
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none
|
|
%% High Authority Controller - Stiff Nano-Hexapod
|
|
% Integrator as low frequency
|
|
H_int = 1/(s + 2*pi*0.01) * 1/(s + 2*pi*0.01);
|
|
|
|
% 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)));
|
|
|
|
% Low Pass filter to increase robustness
|
|
H_lpf = 1/(1 + s/2/pi/500);
|
|
|
|
% High Authority Controller
|
|
K_hac_pz = 6e12 * ... % Gain
|
|
H_lead^2 * ... % Lead
|
|
H_lpf * ... % Low Pass Filter
|
|
H_int; % Integrator
|
|
K_hac_pz.InputName = {'d'};
|
|
K_hac_pz.OutputName = {'f'};
|
|
#+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 :tangle no :exports results :results file replace
|
|
exportFig('figs/uniaxial_nyquist_hac.pdf', 'width', 'wide', 'height', 'tall');
|
|
#+end_src
|
|
|
|
#+name: fig:uniaxial_nyquist_hac
|
|
#+caption: Nyquist Plot - Hight Authority Controller for all three nano-hexapod stiffnesses (soft one in blue, moderately stiff in red and very stiff in yellow) and all sample masses (corresponding to the three curves of each color)
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_nyquist_hac.png]]
|
|
|
|
#+begin_src matlab :exports none :results none
|
|
%% Loop Gain - High Authority Controller for all three nano-hexapod stiffnesses and all sample masses
|
|
figure;
|
|
tiledlayout(3, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
|
|
|
|
ax1 = nexttile([2,1]);
|
|
hold on;
|
|
plot(freqs, abs(L_vc_light), 'color', [colors(1,:), 0.5], 'DisplayName', '$k_n = 0.01\,N/\mu m$');
|
|
plot(freqs, abs(L_vc_mid), 'color', [colors(1,:), 0.5], 'HandleVisibility', 'off');
|
|
plot(freqs, abs(L_vc_heavy), 'color', [colors(1,:), 0.5], 'HandleVisibility', 'off');
|
|
plot(freqs, abs(L_md_light), 'color', [colors(2,:), 0.5], 'DisplayName', '$k_n = 1\,N/\mu m$');
|
|
plot(freqs, abs(L_md_mid), 'color', [colors(2,:), 0.5], 'HandleVisibility', 'off');
|
|
plot(freqs, abs(L_md_heavy), 'color', [colors(2,:), 0.5], 'HandleVisibility', 'off');
|
|
plot(freqs, abs(L_pz_light), 'color', [colors(3,:), 0.5], 'DisplayName', '$k_n = 100\,N/\mu m$');
|
|
plot(freqs, abs(L_pz_mid), 'color', [colors(3,:), 0.5], 'HandleVisibility', 'off');
|
|
plot(freqs, abs(L_pz_heavy), 'color', [colors(3,:), 0.5], 'HandleVisibility', 'off');
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
ylabel('Loop Gain'); set(gca, 'XTickLabel',[]);
|
|
ylim([1e-3, 1e3]);
|
|
legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 1);
|
|
|
|
ax2 = nexttile;
|
|
hold on;
|
|
plot(freqs, 180/pi*unwrap(angle(L_vc_light)), 'color', [colors(1,:), 0.5]);
|
|
plot(freqs, 180/pi*unwrap(angle(L_vc_mid )), 'color', [colors(1,:), 0.5]);
|
|
plot(freqs, 180/pi*unwrap(angle(L_vc_heavy)), 'color', [colors(1,:), 0.5]);
|
|
plot(freqs, 180/pi*unwrap(angle(L_md_light)), 'color', [colors(2,:), 0.5]);
|
|
plot(freqs, 180/pi*unwrap(angle(L_md_mid )), 'color', [colors(2,:), 0.5]);
|
|
plot(freqs, 180/pi*unwrap(angle(L_md_heavy)), 'color', [colors(2,:), 0.5]);
|
|
plot(freqs, 180/pi*unwrap(angle(L_pz_light)), 'color', [colors(3,:), 0.5]);
|
|
plot(freqs, 180/pi*unwrap(angle(L_pz_mid )), 'color', [colors(3,:), 0.5]);
|
|
plot(freqs, 180/pi*unwrap(angle(L_pz_heavy)), 'color', [colors(3,:), 0.5]);
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
|
|
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
|
|
hold off;
|
|
yticks(-360:90:360);
|
|
ylim([-270, 0]);
|
|
|
|
linkaxes([ax1,ax2],'x');
|
|
xlim([1, 500]);
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/uniaxial_loop_gain_hac.pdf', 'width', 'wide', 'height', 'tall');
|
|
#+end_src
|
|
|
|
#+name: fig:uniaxial_loop_gain_hac
|
|
#+caption: Loop Gain - High Authority Controller for all three nano-hexapod stiffnesses (soft one in blue, moderately stiff in red and very stiff in yellow) and all sample masses (corresponding to the three curves of each color)
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_loop_gain_hac.png]]
|
|
|
|
** Closed-Loop Noise Budgeting
|
|
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;
|
|
tiledlayout(1, 3, 'TileSpacing', 'Compact', 'Padding', 'None');
|
|
|
|
ax1 = nexttile();
|
|
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]');
|
|
|
|
ax2 = nexttile();
|
|
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]');
|
|
|
|
ax3 = nexttile();
|
|
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);
|
|
|
|
linkaxes([ax1,ax2,ax3],'x');
|
|
xlim([1, 500]);
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/uniaxial_sensitivity_dist_hac_lac.pdf', 'width', 'full', 'height', 'normal');
|
|
#+end_src
|
|
|
|
#+name: fig:uniaxial_sensitivity_dist_hac_lac
|
|
#+caption: Change of sensitivity to disturbances with LAC and with HAC-LAC
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_sensitivity_dist_hac_lac.png]]
|
|
|
|
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;
|
|
tiledlayout(1, 3, 'TileSpacing', 'Compact', 'Padding', 'None');
|
|
|
|
ax1 = nexttile();
|
|
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);
|
|
title('$k_n = 0.01\,N/\mu m$');
|
|
|
|
ax2 = nexttile();
|
|
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',[]);
|
|
title('$k_n = 1\,N/\mu m$');
|
|
|
|
ax3 = nexttile();
|
|
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',[]);
|
|
title('$k_n = 100\,N/\mu m$');
|
|
|
|
linkaxes([ax1,ax2,ax3],'xy');
|
|
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.pdf', 'width', 'full', '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 HAC-LAC cases
|
|
#+RESULTS:
|
|
[[file:figs/uniaxial_cas_hac_lac.png]]
|
|
|
|
* Conclusion
|
|
<<sec:conclusion>>
|
|
|
|
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.
|
|
|
|
Finally, position feedback controllers have been developed for three considered nano-hexapod stiffnesses.
|
|
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 decoupled from the micro-station dynamics) and requires less position feedback bandwidth to fulfill the requirements.
|
|
The moderately stiff nano-hexapod ($k_n = 1\,N/\mu m$) is requiring a bit more position feedback bandwidth, but it still seems to give acceptable results.
|
|
However, the stiff nano-hexapod is the most complex to control and gives the worst positioning performances.
|
|
|
|
* 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/src/'); % Path for functions
|
|
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
|
|
addpath('./src/'); % Path for functions
|
|
#+END_SRC
|
|
|
|
** Initialize other elements
|
|
#+NAME: m-init-other
|
|
#+BEGIN_SRC matlab
|
|
%% Colors for the figures
|
|
colors = colororder;
|
|
#+END_SRC
|