Add example system

This commit is contained in:
tdehaeze committed 2020-11-27 18:26:06 +01:00
1 parent 178b273105
commit 1b8b824d9f
15 files changed
+1307 -63

No files matched your search

+352 -1
View File
@@ -38,6 +38,7 @@
#+PROPERTY: header-args:latex+ :post pdf2svg(file=*this*, ext="png")
:END:
* Introduction :ignore:
* 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>>
@@ -48,6 +49,7 @@
#+end_src
* Introduction to the Control Methodology - Model Based Control
** Control Methodology
The typical methodology when applying Model Based Control to a plant is schematically shown in Figure [[fig:control-procedure]].
It consists of three steps:
@@ -91,7 +93,7 @@ It consists of three steps:
In this document, we will mainly focus on steps 2 and 3.
* Some Background: From Classical Control to Robust Control
** Some Background: From Classical Control to Robust Control
Classical Control (1930)
- Tools:
@@ -136,6 +138,355 @@ Robust Control (1980)
- Requires the knowledge of specific tools
- Need a reasonably good model of the system
** Example System
Let's consider the test-system shown in Figure [[fig:mech_sys_1dof_inertial_contr]].
The notations used are listed in Table [[tab:example_notations]].
#+begin_src latex :file mech_sys_1dof_inertial_contr.pdf
\begin{tikzpicture}
% Parameters
\def\massw{3}
\def\massh{1}
\def\spaceh{1.8}
% Ground
\draw[] (-0.5*\massw, 0) -- (0.5*\massw, 0);
% Mass
\draw[fill=white] (-0.5*\massw, \spaceh) rectangle (0.5*\massw, \spaceh+\massh) node[pos=0.5](m){$m$};
% Spring, Damper, and Actuator
\draw[spring] (-0.3*\massw, 0) -- (-0.3*\massw, \spaceh) node[midway, left=0.1]{$k$};
\draw[damper] ( 0, 0) -- ( 0, \spaceh) node[midway, left=0.3]{$c$};
\draw[actuator] ( 0.3*\massw, 0) -- (0.3*\massw, \spaceh) node[midway](F){};
% Displacements
\draw[dashed] (0.5*\massw, 0) -- ++(0.5, 0);
\draw[->] (0.6*\massw, 0) -- ++(0, 0.5) node[below right]{$d$};
% Inertial Sensor
\node[inertialsensor] (inertials) at (0.5*\massw, \spaceh+\massh){};
\node[addb={+}{-}{}{}{}, right=0.8 of inertials] (subf) {};
\node[block, below=0.4 of subf] (K){$K(s)$};
\draw[->] (inertials.east) node[above right]{$y$} -- (subf.west);
\draw[->] (subf.south) -- (K.north) node[above right]{$\epsilon$};
\draw[<-] (subf.north) -- ++(0, 0.6) node[below right]{$r$};
\draw[->] (K.south) |- (F.east) node[above right]{$u$};
\end{tikzpicture}
#+end_src
#+name: fig:mech_sys_1dof_inertial_contr
#+caption: Test System consisting of a payload with a mass $m$ on top of an active system with a stiffness $k$, damping $c$ and an actuator. A feedback controller $K(s)$ is added to position / isolate the payload.
#+RESULTS:
[[file:figs/mech_sys_1dof_inertial_contr.png]]
#+name: tab:example_notations
#+caption: Example system variables
| *Notation* | *Description* | *Value* | *Unit* |
|--------------------+----------------------------------------------------------------+----------------+-----------|
| $m$ | Payload's mass to position / isolate | | [kg] |
| $k$ | Stiffness of the suspension system | | [N/m] |
| $c$ | Damping coefficient of the suspension system | | [N/(m/s)] |
| $y$ | Payload absolute displacement (measured by an inertial sensor) | | [m] |
| $d$ | Ground displacement, it acts as a disturbance | | [m] |
| $u$ | Actuator force | | [N] |
| $r$ | Wanted position of the mass (the reference) | | [m] |
| $\epsilon = r - y$ | Position error | | [m] |
| $K$ | Feedback controller | to be designed | [N/m] |
#+begin_exercice
Derive the following open-loop transfer functions:
\begin{align}
G(s) &= \frac{y}{u} \\
G_d(s) &= \frac{y}{d}
\end{align}
*Hint:* You can follow this generic procedure:
1. List all applied forces ot the mass: Actuator force, Stiffness force (Hooke's law), ...
2. Apply the Newton's Second Law on the payload
\[ m \ddot{y} = \Sigma F \]
3. Transform the differential equations into the Laplace domain:
\[ \frac{d\ \cdot}{dt} \Leftrightarrow \cdot \times s \]
4. Write $y(s)$ as a function of $u(s)$ and $w(s)$
#+end_exercice
Having obtained $G(s)$ and $G_d(s)$, we can transform the system shown in Figure [[fig:mech_sys_1dof_inertial_contr]] into a classical feedback form as shown in Figure [[fig:open_loop_shaping]].
#+begin_src latex :file classical_feedback_test_system.pdf
\begin{tikzpicture}
\node[addb={+}{}{}{}{-}] (addfb) at (0, 0){};
\node[block, right=0.8 of addfb] (K){$K(s)$};
\node[block, right=0.8 of K] (G){$G(s)$};
\node[addb={+}{}{}{}{}, right=0.8 of G] (addd){};
\node[block, above=0.5 of addd] (Gd){$G_d(s)$};
\draw[<-] (addfb.west) -- ++(-0.8, 0) node[above right]{$r$};
\draw[->] (addfb.east) -- (K.west) node[above left]{$\epsilon$};
\draw[->] (K.east) -- (G.west) node[above left]{$u$};
\draw[->] (G.east) -- (addd.west);
\draw[<-] (Gd.north) -- ++(0, 0.8) node[below right]{$d$};
\draw[->] (Gd.south) -- (addd.north);
\draw[->] (addd.east) -- ++(1.2, 0);
\draw[->] ($(addd.east) + (0.6, 0)$) node[branch]{} node[above]{$y$} -- ++(0, -1.0) -| (addfb.south);
\end{tikzpicture}
#+end_src
#+name: fig:classical_feedback_test_system
#+caption: Block diagram corresponding to the example system
#+RESULTS:
[[file:figs/classical_feedback_test_system.png]]
#+begin_src matlab
k = 1e6; % Stiffness [N/m]
c = 4e2; % Damping [N/(m/s)]
m = 16; % Mass [kg]
#+end_src
#+begin_src matlab
G = 1/(m*s^2 + c*s + k);
Gd = (c*s + k)/(m*s^2 + c*s + k);
#+end_src
* Classical Open Loop Shaping
** Introduction ot Open Loop Shaping
Usually, the controller $K(s)$ is designed such that the loop gain $L(s)$ has desirable shape.
This technique is called *Open Loop Shaping*.
*************** TODO Explain why the Loop gain si an important "value"
For instance example all the specifications can usually be explained in terms of the open loop gain.
*************** END
#+begin_src latex :file open_loop_shaping.pdf
\begin{tikzpicture}
\node[addb={+}{}{}{}{-}] (addsub) at (0, 0){};
\node[block, right=0.8 of addsub] (K) {$K(s)$};
\node[below] at (K.south) {Controller};
\node[block, right=0.8 of K] (G) {$G(s)$};
\node[below] at (G.south) {Plant};
\draw[<-] (addsub.west) -- ++(-0.8, 0) node[above right]{$r$};
\draw[->] (addsub) -- (K.west) node[above left]{$\epsilon$};
\draw[->] (K.east) -- (G.west) node[above left]{$u$};
\draw[->] (G.east) -- ++(0.8, 0) node[above left]{$y$};
\draw[] ($(G.east) + (0.5, 0)$) -- ++(0, -1.4);
\draw[->] ($(G.east) + (0.5, -1.4)$) -| (addsub.south);
\draw [decoration={brace, raise=5pt}, decorate] (K.north west) -- node[above=6pt]{$L(s)$} (G.north east);
\end{tikzpicture}
#+end_src
#+name: fig:open_loop_shaping
#+caption: Classical Feedback Architecture
#+RESULTS:
[[file:figs/open_loop_shaping.png]]
This is usually done manually has the loop gain $L(s)$ depends linearly of $K(s)$:
\begin{equation}
L(s) = G(s) K(s)
\end{equation}
- where $L(s)$ is called the *Loop Gain Transfer Function*
$K(s)$ then consists of a combination of leads, lags, notches, etc. such that its product with $G(s)$ has wanted shape.
** Example of Open Loop Shaping
#+begin_src matlab
k = 1e-6;
m = 10;
c = 10;
G =
#+end_src
#+begin_src matlab :exports none
freqs = logspace(1, 4, 1000);
figure;
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
ax1 = nexttile([2,1]);
hold on;
plot(freqs, abs(squeeze(freqresp(G, freqs, 'Hz'))));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Magnitude'); set(gca, 'XTickLabel',[]);
hold off;
ax2 = nexttile;
hold on;
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G, freqs, 'Hz')))));
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
yticks(-360:90:360); ylim([-270, 90]);
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
hold off;
linkaxes([ax1,ax2],'x');
xlim([freqs(1), freqs(end)]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/bode_plot_example_afm.pdf', 'width', 'wide', 'height', 'normal');
#+end_src
#+name: fig:bode_plot_example_afm
#+caption: Bode plot of the plant $G(s)$
#+RESULTS:
[[file:figs/bode_plot_example_afm.png]]
Specifications:
- *Performance*: Bandwidth of approximately 50Hz
- *Noise Attenuation*: Roll-off of -40dB/decade past 250Hz
- *Robustness*: Gain margin > 5dB and Phase margin > 40 deg
#+begin_exercice
Using =SISOTOOL=, design a controller that fulfill the specifications.
#+begin_src matlab :eval no
sisotool(G)
#+end_src
#+end_exercice
In order to have the wanted Roll-off, two integrators are used, a lead is also added to have sufficient phase margin.
The obtained controller is shown below, and the bode plot of the Loop Gain is shown in Figure [[fig:loop_gain_manual_afm]].
#+begin_src matlab
K = 6e4 * ... % Gain
1/(s^2) * ... % Double Integrator
(1 + s/111)/(1 + s/888); % Lead
#+end_src
#+begin_src matlab :exports none
freqs = logspace(1, 4, 1000);
figure;
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
ax1 = nexttile([2,1]);
hold on;
plot(freqs, abs(squeeze(freqresp(G*K, freqs, 'Hz'))));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Magnitude'); set(gca, 'XTickLabel',[]);
hold off;
ylim([1e-5, 1e1])
ax2 = nexttile;
hold on;
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G*K, freqs, 'Hz')))));
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
yticks(-360:90:360); ylim([-360, 0]);
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
hold off;
linkaxes([ax1,ax2],'x');
xlim([freqs(1), freqs(end)]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/loop_gain_manual_afm.pdf', 'width', 'wide', 'height', 'tall');
#+end_src
#+name: fig:loop_gain_manual_afm
#+caption: Bode Plot of the obtained Loop Gain $L(s) = G(s) K(s)$
#+RESULTS:
[[file:figs/loop_gain_manual_afm.png]]
And we can verify that we have the wanted stability margins:
#+begin_src matlab :results output replace
[Gm, Pm, ~, Wc] = margin(G*K)
#+end_src
#+begin_src matlab :exports results :results value table replace :tangle no :post addhdr(*this*)
data2orgtable([Gm; Pm; Wc/2/pi], {'Gain Margin [dB]', 'Phase Margin [deg]', 'Crossover [Hz]'}, {'Value'}, ' %.1f ');
#+end_src
#+RESULTS:
| | Value |
|--------------------+-------|
| Gain Margin [dB] | 7.2 |
| Phase Margin [deg] | 48.1 |
| Crossover [Hz] | 50.7 |
** $\mathcal{H}_\infty$ Loop Shaping Synthesis
The Open Loop Shaping synthesis can be performed using the $\mathcal{H}_\infty$ Synthesis.
Even though we will not go into details, we will provide one example.
Using Matlab, the $\mathcal{H}_\infty$ synthesis of a controller based on the wanted open loop shape can be performed using the =loopsyn= command:
#+begin_src matlab :eval no
K = loopsyn(G, Gd);
#+end_src
where:
- =G= is the (LTI) plant
- =Gd= is the wanted loop shape
- =K= is the synthesize controller
#+begin_seealso
Matlab documentation of =loopsyn= ([[https://www.mathworks.com/help/robust/ref/loopsyn.html][link]]).
#+end_seealso
** Example of the $\mathcal{H}_\infty$ Loop Shaping Synthesis
Let's re-use the previous plant.
Translate the specification into the wanted shape of the open loop gain.
#+begin_src matlab
G = tf(16,[1 0.16 16]);
Gd = 3.7e4*1/s*(1 + s/2/pi/20)/(1 + s/2/pi/220)*1/(s + s/2/pi/500);
#+end_src
#+begin_src matlab :exports none
bodeFig({Gd}, struct('phase', true))
#+end_src
#+begin_src matlab
[K,CL,GAM,INFO] = loopsyn(G, Gd);
#+end_src
#+begin_src matlab
bodeFig({K})
#+end_src
#+begin_src matlab :exports none
freqs = logspace(1, 4, 1000);
figure;
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
ax1 = nexttile([2,1]);
hold on;
plot(freqs, abs(squeeze(freqresp(G*K, freqs, 'Hz'))));
plot(freqs, abs(squeeze(freqresp(Gd, freqs, 'Hz'))), 'k--');
plot(freqs, abs(squeeze(freqresp(Gd, freqs, 'Hz')))*GAM, 'k-.');
plot(freqs, abs(squeeze(freqresp(Gd, freqs, 'Hz')))/GAM, 'k-.');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Magnitude'); set(gca, 'XTickLabel',[]);
hold off;
ylim([1e-5, 1e1])
ax2 = nexttile;
hold on;
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G*K, freqs, 'Hz')))));
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
yticks(-360:90:360); ylim([-360, 0]);
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
hold off;
linkaxes([ax1,ax2],'x');
xlim([freqs(1), freqs(end)]);
#+end_src
* The $\mathcal{H}_\infty$ Norm
#+begin_definition