Add some examples and comments about loop shaping

This commit is contained in:
Thomas Dehaeze 2020-11-27 23:13:29 +01:00
parent 1b8b824d9f
commit dbe2962ec0
17 changed files with 1823 additions and 496 deletions

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -103,38 +103,38 @@
<g id="surface1"> <g id="surface1">
<path style="fill-rule:nonzero;fill:rgb(79.998779%,79.998779%,79.998779%);fill-opacity:1;stroke-width:0.99628;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:2.98883,2.98883;stroke-miterlimit:10;" d="M -37.313154 -20.650957 L 74.164387 -20.650957 L 74.164387 58.966894 L -37.313154 58.966894 Z M -37.313154 -20.650957 " transform="matrix(0.996067,0,0,-0.996067,73.627327,59.727146)"/> <path style="fill-rule:nonzero;fill:rgb(79.998779%,79.998779%,79.998779%);fill-opacity:1;stroke-width:0.99628;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:2.98883,2.98883;stroke-miterlimit:10;" d="M -37.313154 -20.650957 L 74.164387 -20.650957 L 74.164387 58.966894 L -37.313154 58.966894 Z M -37.313154 -20.650957 " transform="matrix(0.996067,0,0,-0.996067,73.627327,59.727146)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> <g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="39.769028" y="11.744622"/> <use xlink:href="#glyph0-1" x="41.421503" y="11.744622"/>
<use xlink:href="#glyph0-2" x="47.555931" y="11.744622"/> <use xlink:href="#glyph0-2" x="49.208406" y="11.744622"/>
<use xlink:href="#glyph0-3" x="51.966889" y="11.744622"/> <use xlink:href="#glyph0-3" x="53.619363" y="11.744622"/>
<use xlink:href="#glyph0-2" x="57.480337" y="11.744622"/> <use xlink:href="#glyph0-2" x="59.132812" y="11.744622"/>
<use xlink:href="#glyph0-4" x="61.891295" y="11.744622"/> <use xlink:href="#glyph0-4" x="63.543769" y="11.744622"/>
<use xlink:href="#glyph0-5" x="65.778296" y="11.744622"/> <use xlink:href="#glyph0-5" x="67.430771" y="11.744622"/>
<use xlink:href="#glyph0-6" x="70.740003" y="11.744622"/> <use xlink:href="#glyph0-6" x="72.392477" y="11.744622"/>
<use xlink:href="#glyph0-7" x="73.496727" y="11.744622"/> <use xlink:href="#glyph0-7" x="75.149202" y="11.744622"/>
<use xlink:href="#glyph0-8" x="76.253452" y="11.744622"/> <use xlink:href="#glyph0-8" x="77.905926" y="11.744622"/>
<use xlink:href="#glyph0-2" x="80.664409" y="11.744622"/> <use xlink:href="#glyph0-2" x="82.316884" y="11.744622"/>
<use xlink:href="#glyph0-9" x="85.075366" y="11.744622"/> <use xlink:href="#glyph0-9" x="86.727841" y="11.744622"/>
</g> </g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> <g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-10" x="93.893312" y="11.744622"/> <use xlink:href="#glyph0-10" x="95.545786" y="11.744622"/>
<use xlink:href="#glyph0-6" x="100.647187" y="11.744622"/> <use xlink:href="#glyph0-6" x="102.299662" y="11.744622"/>
<use xlink:href="#glyph0-5" x="103.403912" y="11.744622"/> <use xlink:href="#glyph0-5" x="105.056386" y="11.744622"/>
<use xlink:href="#glyph0-3" x="108.365619" y="11.744622"/> <use xlink:href="#glyph0-3" x="110.018093" y="11.744622"/>
</g> </g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> <g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-11" x="113.601212" y="11.744622"/> <use xlink:href="#glyph0-11" x="115.253686" y="11.744622"/>
</g> </g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> <g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-1" x="120.76917" y="11.744622"/> <use xlink:href="#glyph1-1" x="122.420648" y="11.744622"/>
</g> </g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> <g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-12" x="128.518568" y="11.744622"/> <use xlink:href="#glyph0-12" x="130.170047" y="11.744622"/>
</g> </g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> <g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-2" x="132.377331" y="11.744622"/> <use xlink:href="#glyph1-2" x="134.029805" y="11.744622"/>
</g> </g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> <g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-13" x="137.028962" y="11.744622"/> <use xlink:href="#glyph0-13" x="138.681437" y="11.744622"/>
</g> </g>
<path style="fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.99628;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M -17.00672 -14.172349 L 17.009891 -14.172349 L 17.009891 14.17352 L -17.00672 14.17352 Z M -17.00672 -14.172349 " transform="matrix(0.996067,0,0,-0.996067,73.627327,59.727146)"/> <path style="fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.99628;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M -17.00672 -14.172349 L 17.009891 -14.172349 L 17.009891 14.17352 L -17.00672 14.17352 Z M -17.00672 -14.172349 " transform="matrix(0.996067,0,0,-0.996067,73.627327,59.727146)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> <g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
@ -199,7 +199,7 @@
<path style="fill:none;stroke-width:0.99628;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M -57.192126 41.060525 L 44.477305 41.060525 L 44.477305 14.597061 " transform="matrix(0.996067,0,0,-0.996067,73.627327,59.727146)"/> <path style="fill:none;stroke-width:0.99628;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M -57.192126 41.060525 L 44.477305 41.060525 L 44.477305 14.597061 " transform="matrix(0.996067,0,0,-0.996067,73.627327,59.727146)"/>
<path style="fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.99628;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 6.053553 0.000104966 L 1.610295 1.682504 L 3.088767 0.000104966 L 1.610295 -1.682294 Z M 6.053553 0.000104966 " transform="matrix(0,0.996067,0.996067,0,117.929583,42.360883)"/> <path style="fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.99628;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 6.053553 0.000104966 L 1.610295 1.682504 L 3.088767 0.000104966 L 1.610295 -1.682294 Z M 6.053553 0.000104966 " transform="matrix(0,0.996067,0.996067,0,117.929583,42.360883)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> <g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-8" x="3.983341" y="15.02467"/> <use xlink:href="#glyph1-8" x="3.984337" y="15.02467"/>
</g> </g>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;"> <g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-14" x="14.111347" y="15.02467"/> <use xlink:href="#glyph0-14" x="14.111347" y="15.02467"/>

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

File diff suppressed because it is too large Load Diff

482
index.org
View File

@ -38,7 +38,7 @@
#+PROPERTY: header-args:latex+ :post pdf2svg(file=*this*, ext="png") #+PROPERTY: header-args:latex+ :post pdf2svg(file=*this*, ext="png")
:END: :END:
* Introduction :ignore: * TODO Introduction :ignore:
* Matlab Init :noexport: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) #+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
<<matlab-dir>> <<matlab-dir>>
@ -95,53 +95,36 @@ 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) #+name: tab:comparison_control_methods
- Tools: #+caption: Table summurazing the main differences between classical, modern and robust control
- TF (input-output) | | *Classical Control* | *Modern Control* | *Robust Control* |
- Nyquist, Bode, Black, \ldots | <l> | <c> | <c> | <c> |
- P-PI-PID, Phase lead-lag, \ldots |-------------------------+------------------------------------+--------------------------------------+-------------------------------------------------------------------------|
- Advantages: | *Date* | 1930- | 1960- | 1980- |
- Stability |-------------------------+------------------------------------+--------------------------------------+-------------------------------------------------------------------------|
- Performances | *Tools* | Transfer Functions | State Space formulation | Systems and Signals Norms ($\mathcal{H}_\infty$, $\mathcal{H}_2$ Norms) |
- Robustness | | Nyquist Plots | Riccati Equations | Closed Loop Transfer Functions |
- Disadvantages: | | Bode Plots | | Open/Closed Loop Shaping |
- Manual Method | | Phase and Gain margins | | Weighting Functions |
- Only SISO | | | | Disk margin |
|-------------------------+------------------------------------+--------------------------------------+-------------------------------------------------------------------------|
Modern Control (1960) | *Control Architectures* | Proportional, Integral, Derivative | Full State Feedback | General Control Configuration |
- Tools: | | Leads, Lags | LQR, LQG | |
- State Space | | | Kalman Filters | |
- Optimal Command |-------------------------+------------------------------------+--------------------------------------+-------------------------------------------------------------------------|
- LQR, LQG | *Advantages* | Study Stability | Automatic Synthesis | Automatic Synthesis |
- Advantages: | | Simple | MIMO | MIMO |
- Automatic Synthesis | | Natural | Optimization Problem | Optimization Problem |
- MIMO | | | | Guaranteed Robustness |
- Optimisation problem | | | | Easy specification of performances |
- Disadvantages: |-------------------------+------------------------------------+--------------------------------------+-------------------------------------------------------------------------|
- Robustness | *Disadvantages* | Manual Method | No Guaranteed Robustness | Required knowledge of specific tools |
- Rejection of Perturbations | | Only SISO | Difficult Rejection of Perturbations | Need a reasonably good model of the system |
Robust Control (1980)
- Tools:
- Disk Margin
- Systems and Signals norms ($\mathcal{H}_\infty$ and $\mathcal{H}_2$ norms)
- Closed Loop Transfer Functions
- Loop Shaping
- Advantages:
- Stability
- Performances
- Robustness
- Automatic Synthesis
- MIMO
- Optimization Problem
- Disadvantages:
- Requires the knowledge of specific tools
- Need a reasonably good model of the system
** Example System ** Example System
Let's consider the test-system shown in Figure [[fig:mech_sys_1dof_inertial_contr]]. Let's consider the model shown in Figure [[fig:mech_sys_1dof_inertial_contr]].
It could represent a suspension system with a payload to position or isolate using an force actuator and an inertial sensor.
The notations used are listed in Table [[tab:example_notations]]. The notations used are listed in Table [[tab:example_notations]].
#+begin_src latex :file mech_sys_1dof_inertial_contr.pdf #+begin_src latex :file mech_sys_1dof_inertial_contr.pdf
@ -187,9 +170,9 @@ The notations used are listed in Table [[tab:example_notations]].
#+caption: Example system variables #+caption: Example system variables
| *Notation* | *Description* | *Value* | *Unit* | | *Notation* | *Description* | *Value* | *Unit* |
|--------------------+----------------------------------------------------------------+----------------+-----------| |--------------------+----------------------------------------------------------------+----------------+-----------|
| $m$ | Payload's mass to position / isolate | | [kg] | | $m$ | Payload's mass to position / isolate | $10$ | [kg] |
| $k$ | Stiffness of the suspension system | | [N/m] | | $k$ | Stiffness of the suspension system | $10^6$ | [N/m] |
| $c$ | Damping coefficient of the suspension system | | [N/(m/s)] | | $c$ | Damping coefficient of the suspension system | $400$ | [N/(m/s)] |
| $y$ | Payload absolute displacement (measured by an inertial sensor) | | [m] | | $y$ | Payload absolute displacement (measured by an inertial sensor) | | [m] |
| $d$ | Ground displacement, it acts as a disturbance | | [m] | | $d$ | Ground displacement, it acts as a disturbance | | [m] |
| $u$ | Actuator force | | [N] | | $u$ | Actuator force | | [N] |
@ -204,13 +187,22 @@ Derive the following open-loop transfer functions:
G_d(s) &= \frac{y}{d} G_d(s) &= \frac{y}{d}
\end{align} \end{align}
*Hint:* You can follow this generic procedure: #+HTML: <details><summary>Hint</summary>
You can follow this generic procedure:
1. List all applied forces ot the mass: Actuator force, Stiffness force (Hooke's law), ... 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 2. Apply the Newton's Second Law on the payload
\[ m \ddot{y} = \Sigma F \] \[ m \ddot{y} = \Sigma F \]
3. Transform the differential equations into the Laplace domain: 3. Transform the differential equations into the Laplace domain:
\[ \frac{d\ \cdot}{dt} \Leftrightarrow \cdot \times s \] \[ \frac{d\ \cdot}{dt} \Leftrightarrow \cdot \times s \]
4. Write $y(s)$ as a function of $u(s)$ and $w(s)$ 4. Write $y(s)$ as a function of $u(s)$ and $w(s)$
#+HTML: </details>
#+HTML: <details><summary>Results</summary>
\begin{align}
G(s) &= \frac{1}{m s^2 + cs + k} \\
G_d(s) &= \frac{cs + k}{m s^2 + cs + k}
\end{align}
#+HTML: </details>
#+end_exercice #+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]]. 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]].
@ -239,75 +231,22 @@ Having obtained $G(s)$ and $G_d(s)$, we can transform the system shown in Figure
#+RESULTS: #+RESULTS:
[[file:figs/classical_feedback_test_system.png]] [[file:figs/classical_feedback_test_system.png]]
#+begin_src matlab
Let's define the system parameters on Matlab.
#+begin_src matlab +n
k = 1e6; % Stiffness [N/m] k = 1e6; % Stiffness [N/m]
c = 4e2; % Damping [N/(m/s)] c = 4e2; % Damping [N/(m/s)]
m = 16; % Mass [kg] m = 10; % Mass [kg]
#+end_src #+end_src
#+begin_src matlab And now the system dynamics $G(s)$ and $G_d(s)$ (their bode plots are shown in Figures [[fig:bode_plot_example_afm]] and [[fig:bode_plot_example_Gd]]).
G = 1/(m*s^2 + c*s + k); #+begin_src matlab +n -r
Gd = (c*s + k)/(m*s^2 + c*s + k); G = 1/(m*s^2 + c*s + k); % Plant
Gd = (c*s + k)/(m*s^2 + c*s + k); % Disturbance
#+end_src #+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 #+begin_src matlab :exports none
freqs = logspace(1, 4, 1000); freqs = logspace(0, 3, 1000);
figure; figure;
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None'); tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
@ -340,10 +279,87 @@ $K(s)$ then consists of a combination of leads, lags, notches, etc. such that it
#+RESULTS: #+RESULTS:
[[file:figs/bode_plot_example_afm.png]] [[file:figs/bode_plot_example_afm.png]]
Specifications: #+begin_src matlab :exports none
- *Performance*: Bandwidth of approximately 50Hz freqs = logspace(0, 3, 1000);
- *Noise Attenuation*: Roll-off of -40dB/decade past 250Hz
- *Robustness*: Gain margin > 5dB and Phase margin > 40 deg figure;
hold on;
plot(freqs, abs(squeeze(freqresp(Gd, freqs, 'Hz'))));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('Magnitude');
hold off;
xlim([freqs(1), freqs(end)]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/bode_plot_example_Gd.pdf', 'width', 'wide', 'height', 'small');
#+end_src
#+name: fig:bode_plot_example_Gd
#+caption: Magnitude of the disturbance transfer function $G_d(s)$
#+RESULTS:
[[file:figs/bode_plot_example_Gd.png]]
* Classical Open Loop Shaping
** Introduction to Open Loop Shaping
#+begin_definition
The *Loop Gain* $L(s)$ usually refers to as the product of the controller and the plant (Figure [[fig:open_loop_shaping]]):
\begin{equation}
L(s) = G(s) \cdot K(s) \label{eq:loop_gain}
\end{equation}
#+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
[[file:figs/open_loop_shaping.png]]
#+end_definition
#+begin_definition
*Open Loop Shaping* refers to a control design technique where the controller $K(s)$ is designed such that the *Open Loop Gain* $L(s)$ has desirable shape.
#+end_definition
This synthesis method is widely used as many characteristics of the closed-loop system depend on the shape of the open loop gain $L(s)$:
- *Performance*: $L$ large
- *Good disturbance rejection*: $L$ large
- *Limitation of measurement noise on plant output*: $L$ small
- *Small magnitude of input signal*: $K$ and $L$ small
- *Nominal stability*: $L$ small (RHP zeros and time delays)
- *Robust stability*: $L$ small (neglected dynamics)
The Open Loop shape is usually done manually has the loop gain $L(s)$ depends linearly on $K(s)$ eqref:eq:loop_gain.
$K(s)$ then consists of a combination of leads, lags, notches, etc. such that $L(s)$ has the wanted shape.
** Example of Open Loop Shaping
#+begin_exampl
Let's take our example system and try to apply the Open-Loop shaping strategy to design a controller that fulfils the following specifications:
- *Performance*: Bandwidth of approximately 10Hz
- *Noise Attenuation*: Roll-off of -40dB/decade past 30Hz
- *Robustness*: Gain margin > 3dB and Phase margin > 30 deg
#+end_exampl
#+begin_exercice #+begin_exercice
Using =SISOTOOL=, design a controller that fulfill the specifications. Using =SISOTOOL=, design a controller that fulfill the specifications.
@ -357,13 +373,14 @@ In order to have the wanted Roll-off, two integrators are used, a lead is also a
The obtained controller is shown below, and the bode plot of the Loop Gain is shown in Figure [[fig:loop_gain_manual_afm]]. 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 #+begin_src matlab
K = 6e4 * ... % Gain K = 14e8 * ... % Gain
1/(s^2) * ... % Double Integrator 1/(s^2) * ... % Double Integrator
(1 + s/111)/(1 + s/888); % Lead 1/(1 + s/2/pi/40) * ... % Low Pass Filter
(1 + s/(2*pi*10/sqrt(8)))/(1 + s/(2*pi*10*sqrt(8))); % Lead
#+end_src #+end_src
#+begin_src matlab :exports none #+begin_src matlab :exports none
freqs = logspace(1, 4, 1000); freqs = logspace(0, 3, 1000);
figure; figure;
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None'); tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
@ -375,7 +392,7 @@ The obtained controller is shown below, and the bode plot of the Loop Gain is sh
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Magnitude'); set(gca, 'XTickLabel',[]); ylabel('Magnitude'); set(gca, 'XTickLabel',[]);
hold off; hold off;
ylim([1e-5, 1e1]) ylim([1e-4, 1e1])
ax2 = nexttile; ax2 = nexttile;
hold on; hold on;
@ -390,7 +407,7 @@ The obtained controller is shown below, and the bode plot of the Loop Gain is sh
#+end_src #+end_src
#+begin_src matlab :tangle no :exports results :results file replace #+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/loop_gain_manual_afm.pdf', 'width', 'wide', 'height', 'tall'); exportFig('figs/loop_gain_manual_afm.pdf', 'width', 'wide', 'height', 'normal');
#+end_src #+end_src
#+name: fig:loop_gain_manual_afm #+name: fig:loop_gain_manual_afm
@ -399,22 +416,23 @@ The obtained controller is shown below, and the bode plot of the Loop Gain is sh
[[file:figs/loop_gain_manual_afm.png]] [[file:figs/loop_gain_manual_afm.png]]
And we can verify that we have the wanted stability margins: And we can verify that we have the wanted stability margins:
#+begin_src matlab :results output replace #+begin_src matlab
[Gm, Pm, ~, Wc] = margin(G*K) [Gm, Pm, ~, Wc] = margin(G*K)
#+end_src #+end_src
#+begin_src matlab :exports results :results value table replace :tangle no :post addhdr(*this*) #+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 '); data2orgtable([Gm; Pm; Wc/2/pi], {'Gain Margin $> 3$ [dB]', 'Phase Margin $> 30$ [deg]', 'Crossover $\approx 10$ [Hz]'}, {'Manual Method'}, ' %.1f ');
#+end_src #+end_src
#+RESULTS: #+RESULTS:
| | Value | | | Manual Method |
|--------------------+-------| |-----------------------------+---------------|
| Gain Margin [dB] | 7.2 | | Gain Margin $> 3$ [dB] | 3.1 |
| Phase Margin [deg] | 48.1 | | Phase Margin $> 30$ [deg] | 35.4 |
| Crossover [Hz] | 50.7 | | Crossover $\approx 10$ [Hz] | 10.1 |
** $\mathcal{H}_\infty$ Loop Shaping Synthesis ** $\mathcal{H}_\infty$ Loop Shaping Synthesis
The Open Loop Shaping synthesis can be performed using the $\mathcal{H}_\infty$ 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. Even though we will not go into details, we will provide one example.
@ -434,45 +452,88 @@ where:
** Example of the $\mathcal{H}_\infty$ Loop Shaping Synthesis ** Example of the $\mathcal{H}_\infty$ Loop Shaping Synthesis
Let's re-use the previous plant. Let's reuse the previous plant.
Translate the specification into the wanted shape of the open loop gain. Translate the specification into the wanted shape of the open loop gain.
- *Performance*: Bandwidth of approximately 10Hz: $|L_w(j2 \pi 10)| = 1$
- *Noise Attenuation*: Roll-off of -40dB/decade past 30Hz
- *Robustness*: Gain margin > 3dB and Phase margin > 30 deg
#+begin_src matlab #+begin_src matlab
G = tf(16,[1 0.16 16]); Lw = 2.3e3 * ...
1/(s^2) * ... % Double Integrator
Gd = 3.7e4*1/s*(1 + s/2/pi/20)/(1 + s/2/pi/220)*1/(s + s/2/pi/500); (1 + s/(2*pi*10/sqrt(3)))/(1 + s/(2*pi*10*sqrt(3))); % Lead
#+end_src #+end_src
The $\mathcal{H}_\infty$ optimal open loop shaping is performed using the =loopsyn= command:
#+begin_src matlab
[K, ~, GAM] = loopsyn(G, Lw);
#+end_src
The Bode plot of the obtained controller is shown in Figure [[fig:open_loop_shaping_hinf_K]].
#+begin_important
It is always important to analyze the controller after the synthesis is performed.
In the end, a synthesize controller is just a combination of low pass filters, high pass filters, notches, leads, etc.
#+end_important
Let's briefly analyze this controller:
- two integrators are used at low frequency to have the wanted low frequency high gain
- a lead is added centered with the crossover frequency to increase the phase margin
- a notch is added at the resonance of the plant to increase the gain margin (this is very typical of $\mathcal{H}_\infty$ controllers, and can be an issue, more info on that latter)
#+begin_src matlab :exports none #+begin_src matlab :exports none
bodeFig({Gd}, struct('phase', true)) freqs = logspace(0, 3, 1000);
figure;
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
ax1 = nexttile([2,1]);
plot(freqs, abs(squeeze(freqresp(K, freqs, 'Hz'))));
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Magnitude'); set(gca, 'XTickLabel',[]);
hold off;
ax2 = nexttile;
plot(freqs, 180/pi*angle(squeeze(freqresp(K, freqs, 'Hz'))));
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
yticks(-360:90:360); ylim([-180, 90]);
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
linkaxes([ax1,ax2],'x');
xlim([freqs(1), freqs(end)]);
#+end_src #+end_src
#+begin_src matlab #+begin_src matlab :tangle no :exports results :results file replace
[K,CL,GAM,INFO] = loopsyn(G, Gd); exportFig('figs/open_loop_shaping_hinf_K.pdf', 'width', 'wide', 'height', 'normal');
#+end_src #+end_src
#+begin_src matlab #+name: fig:open_loop_shaping_hinf_K
bodeFig({K}) #+caption: Obtained controller $K$ using the open-loop $\mathcal{H}_\infty$ shaping
#+end_src #+RESULTS:
[[file:figs/open_loop_shaping_hinf_K.png]]
The obtained Loop Gain is shown in Figure [[fig:open_loop_shaping_hinf_L]].
#+begin_src matlab :exports none #+begin_src matlab :exports none
freqs = logspace(1, 4, 1000); freqs = logspace(0, 3, 1000);
figure; figure;
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None'); tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
ax1 = nexttile([2,1]); ax1 = nexttile([2,1]);
hold on; hold on;
plot(freqs, abs(squeeze(freqresp(G*K, freqs, 'Hz')))); plot(freqs, abs(squeeze(freqresp(G*K, freqs, 'Hz'))), 'DisplayName', '$L(s)$');
plot(freqs, abs(squeeze(freqresp(Gd, freqs, 'Hz'))), 'k--'); plot(freqs, abs(squeeze(freqresp(Lw, freqs, 'Hz'))), 'k--', 'DisplayName', '$L_w(s)$');
plot(freqs, abs(squeeze(freqresp(Gd, freqs, 'Hz')))*GAM, 'k-.'); plot(freqs, abs(squeeze(freqresp(Lw, freqs, 'Hz')))*GAM, 'k-.', 'DisplayName', '$L_w(s) / \gamma$, $L_w(s) \cdot \gamma$');
plot(freqs, abs(squeeze(freqresp(Gd, freqs, 'Hz')))/GAM, 'k-.'); plot(freqs, abs(squeeze(freqresp(Lw, freqs, 'Hz')))/GAM, 'k-.', 'HandleVisibility', 'off');
hold off; hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Magnitude'); set(gca, 'XTickLabel',[]); ylabel('Magnitude'); set(gca, 'XTickLabel',[]);
hold off; hold off;
ylim([1e-5, 1e1]) legend('location', 'northeast');
ylim([1e-4, 1e2]);
ax2 = nexttile; ax2 = nexttile;
hold on; hold on;
@ -486,8 +547,36 @@ Translate the specification into the wanted shape of the open loop gain.
xlim([freqs(1), freqs(end)]); xlim([freqs(1), freqs(end)]);
#+end_src #+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/open_loop_shaping_hinf_L.pdf', 'width', 'wide', 'height', 'tall');
#+end_src
* The $\mathcal{H}_\infty$ Norm #+name: fig:open_loop_shaping_hinf_L
#+caption: Obtained Open Loop Gain $L(s) = G(s) K(s)$ and comparison with the wanted Loop gain $L_w$
#+RESULTS:
[[file:figs/open_loop_shaping_hinf_L.png]]
Let's now compare the obtained stability margins of the $\mathcal{H}_\infty$ controller and of the manually developed controller in Table [[tab:open_loop_shaping_compare]].
#+begin_src matlab :exports none
[Gm_2, Pm_2, ~, Wc_2] = margin(G*K)
#+end_src
#+begin_src matlab :exports results :results value table replace :tangle no :post addhdr(*this*)
data2orgtable([Gm, Gm_2; Pm, Pm_2; Wc/2/pi, Wc_2/2/pi], {'Gain Margin $> 3$ [dB]', 'Phase Margin $> 30$ [deg]', 'Crossover $\approx 10$ [Hz]'}, {'Specifications', 'Manual Method', '$\mathcal{H}_\infty$ Method'}, ' %.1f ');
#+end_src
#+name: tab:open_loop_shaping_compare
#+caption: Comparison of the characteristics obtained with the two methods
#+RESULTS:
| Specifications | Manual Method | $\mathcal{H}_\infty$ Method |
|-----------------------------+---------------+-----------------------------|
| Gain Margin $> 3$ [dB] | 3.1 | 31.7 |
| Phase Margin $> 30$ [deg] | 35.4 | 54.7 |
| Crossover $\approx 10$ [Hz] | 10.1 | 9.9 |
* First Step in the $\mathcal{H}_\infty$ world
** The $\mathcal{H}_\infty$ Norm
#+begin_definition #+begin_definition
The $\mathcal{H}_\infty$ norm is defined as the peak of the maximum singular value of the frequency response The $\mathcal{H}_\infty$ norm is defined as the peak of the maximum singular value of the frequency response
@ -502,31 +591,24 @@ Translate the specification into the wanted shape of the open loop gain.
#+end_definition #+end_definition
#+begin_exampl #+begin_exampl
Let's define a plant dynamics:
#+begin_src matlab
w0 = 2*pi; k = 1e6; xi = 0.04;
G = 1/k/(s^2/w0^2 + 2*xi*s/w0 + 1);
#+end_src
And compute its $\mathcal{H}_\infty$ norm using the =hinfnorm= function: And compute its $\mathcal{H}_\infty$ norm using the =hinfnorm= function:
#+begin_src matlab :results value replace #+begin_src matlab :results value replace
hinfnorm(G) hinfnorm(G)
#+end_src #+end_src
#+RESULTS: #+RESULTS:
: 1.0013e-05 : 7.9216e-06
The magnitude $|G(j\omega)|$ of the plant $G(s)$ as a function of frequency is shown in Figure [[fig:hinfinity_norm_siso_bode]]. The magnitude $|G(j\omega)|$ of the plant $G(s)$ as a function of frequency is shown in Figure [[fig:hinfinity_norm_siso_bode]].
The maximum value of the magnitude over all frequencies does correspond to the $\mathcal{H}_\infty$ norm of $G(s)$ as Equation eqref:eq:hinf_norm_siso implies. The maximum value of the magnitude over all frequencies does correspond to the $\mathcal{H}_\infty$ norm of $G(s)$ as Equation eqref:eq:hinf_norm_siso implies.
#+begin_src matlab :exports none #+begin_src matlab :exports none
freqs = logspace(-1, 1, 1000); freqs = logspace(0, 3, 1000);
figure; figure;
hold on; hold on;
plot(freqs, abs(squeeze(freqresp(G, freqs, 'Hz'))), 'k-'); plot(freqs, abs(squeeze(freqresp(G, freqs, 'Hz'))), 'k-');
plot([0.5, 2], [hinfnorm(G) hinfnorm(G)], 'k--'); plot([20, 100], [hinfnorm(G) hinfnorm(G)], 'k--');
text(2, hinfnorm(G), '$\quad \|G\|_\infty$') text(100, hinfnorm(G), '$\quad \|G\|_\infty$')
hold off; hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('Magnitude $|G(j\omega)|$'); xlabel('Frequency [Hz]'); ylabel('Magnitude $|G(j\omega)|$');
@ -543,7 +625,7 @@ The maximum value of the magnitude over all frequencies does correspond to the $
[[file:figs/hinfinity_norm_siso_bode.png]] [[file:figs/hinfinity_norm_siso_bode.png]]
#+end_exampl #+end_exampl
* $\mathcal{H}_\infty$ Synthesis ** $\mathcal{H}_\infty$ Synthesis
*Optimization problem*: *Optimization problem*:
$\mathcal{H}_\infty$ synthesis is a method that uses an *algorithm* (LMI optimization, Riccati equation) to find a controller of the same order as the system so that the $\mathcal{H}_\infty$ norms of defined transfer functions are minimized. $\mathcal{H}_\infty$ synthesis is a method that uses an *algorithm* (LMI optimization, Riccati equation) to find a controller of the same order as the system so that the $\mathcal{H}_\infty$ norms of defined transfer functions are minimized.
@ -560,7 +642,7 @@ $\mathcal{H}_\infty$ synthesis is a method that uses an *algorithm* (LMI optimiz
- Fixed-Structure $\mathcal{H}_\infty$ Synthesis - Fixed-Structure $\mathcal{H}_\infty$ Synthesis
- Signal Based $\mathcal{H}_\infty$ Synthesis - Signal Based $\mathcal{H}_\infty$ Synthesis
* The Generalized Plant ** The Generalized Plant
#+begin_src latex :file general_plant.pdf #+begin_src latex :file general_plant.pdf
\begin{tikzpicture} \begin{tikzpicture}
\node[block={2.0cm}{2.0cm}] (P) {$P$}; \node[block={2.0cm}{2.0cm}] (P) {$P$};
@ -598,45 +680,7 @@ $\mathcal{H}_\infty$ synthesis is a method that uses an *algorithm* (LMI optimiz
\begin{bmatrix} z \\ v \end{bmatrix} = P \begin{bmatrix} w \\ u \end{bmatrix} = \begin{bmatrix} P_{11} & P_{12} \\ P_{21} & P_{22} \end{bmatrix} \begin{bmatrix} w \\ u \end{bmatrix} \begin{bmatrix} z \\ v \end{bmatrix} = P \begin{bmatrix} w \\ u \end{bmatrix} = \begin{bmatrix} P_{11} & P_{12} \\ P_{21} & P_{22} \end{bmatrix} \begin{bmatrix} w \\ u \end{bmatrix}
\end{equation} \end{equation}
* Problem Formulation ** From a Classical Feedback Architecture to a Generalized Plant
#+begin_important
The $\mathcal{H}_\infty$ Synthesis objective is to find all stabilizing controllers $K$ which minimize
\begin{equation}
\| F_l(P, K) \|_\infty = \max_{\omega} \overline{\sigma} \big( F_l(P, K)(j\omega) \big)
\end{equation}
#+end_important
#+begin_src latex :file general_control_names.pdf
\begin{tikzpicture}
% Blocs
\node[block={2.0cm}{2.0cm}] (P) {$P$};
\node[block={1.5cm}{1.5cm}, below=0.7 of P] (K) {$K$};
% Input and outputs coordinates
\coordinate[] (inputw) at ($(P.south west)!0.75!(P.north west)$);
\coordinate[] (inputu) at ($(P.south west)!0.25!(P.north west)$);
\coordinate[] (outputz) at ($(P.south east)!0.75!(P.north east)$);
\coordinate[] (outputv) at ($(P.south east)!0.25!(P.north east)$);
% Connections and labels
\draw[<-] (inputw) node[above left, align=right]{(weighted)\\exogenous inputs\\$w$} -- ++(-1.5, 0);
\draw[<-] (inputu) -- ++(-0.8, 0) |- node[left, near start, align=right]{control signals\\$u$} (K.west);
\draw[->] (outputz) node[above right, align=left]{(weighted)\\exogenous outputs\\$z$} -- ++(1.5, 0);
\draw[->] (outputv) -- ++(0.8, 0) |- node[right, near start, align=left]{sensed output\\$v$} (K.east);
\end{tikzpicture}
#+end_src
#+name: fig:general_control_names
#+caption: General Control Configuration
#+RESULTS:
[[file:figs/general_control_names.png]]
* Classical feedback control and closed loop transfer functions
#+begin_src latex :file classical_feedback.pdf #+begin_src latex :file classical_feedback.pdf
\begin{tikzpicture} \begin{tikzpicture}
@ -672,7 +716,6 @@ $\mathcal{H}_\infty$ synthesis is a method that uses an *algorithm* (LMI optimiz
| $d$ | Input Disturbance | | $d$ | Input Disturbance |
| $\epsilon$ | Tracking Error | | $\epsilon$ | Tracking Error |
* From a Classical Feedback Architecture to a Generalized Plant
The procedure is: The procedure is:
1. define signals of the generalized plant 1. define signals of the generalized plant
2. Remove $K$ and rearrange the inputs and outputs 2. Remove $K$ and rearrange the inputs and outputs
@ -716,12 +759,12 @@ The procedure is:
\begin{scope}[on background layer] \begin{scope}[on background layer]
\node[fit={(G.south-|start.west) ($(z1.north west)+(-0.4, 0)$)}, inner sep=6pt, draw, dashed, fill=black!20!white] (P) {}; \node[fit={(G.south-|start.west) ($(z1.north west)+(-0.4, 0)$)}, inner sep=6pt, draw, dashed, fill=black!20!white] (P) {};
\node[below right] at (P.north west) {Generalized Plant $P(s)$}; \node[below] at (P.north) {Generalized Plant $P(s)$};
\end{scope} \end{scope}
\end{tikzpicture} \end{tikzpicture}
#+end_src #+end_src
#+begin_exampl #+begin_exercice
Let's find the Generalized plant of corresponding to the tracking control architecture shown in Figure [[fig:classical_feedback_tracking]] Let's find the Generalized plant of corresponding to the tracking control architecture shown in Figure [[fig:classical_feedback_tracking]]
#+name: fig:classical_feedback_tracking #+name: fig:classical_feedback_tracking
@ -747,7 +790,46 @@ The procedure is:
0 1; 0 1;
1 -G] 1 -G]
#+end_src #+end_src
#+end_exampl #+end_exercice
** The General Synthesis Problem Formulation
#+begin_important
The $\mathcal{H}_\infty$ Synthesis objective is to find all stabilizing controllers $K$ which minimize
\begin{equation}
\| F_l(P, K) \|_\infty = \max_{\omega} \overline{\sigma} \big( F_l(P, K)(j\omega) \big)
\end{equation}
#+end_important
#+begin_src latex :file general_control_names.pdf
\begin{tikzpicture}
% Blocs
\node[block={2.0cm}{2.0cm}] (P) {$P$};
\node[block={1.5cm}{1.5cm}, below=0.7 of P] (K) {$K$};
% Input and outputs coordinates
\coordinate[] (inputw) at ($(P.south west)!0.75!(P.north west)$);
\coordinate[] (inputu) at ($(P.south west)!0.25!(P.north west)$);
\coordinate[] (outputz) at ($(P.south east)!0.75!(P.north east)$);
\coordinate[] (outputv) at ($(P.south east)!0.25!(P.north east)$);
% Connections and labels
\draw[<-] (inputw) node[above left, align=right]{(weighted)\\exogenous inputs\\$w$} -- ++(-1.5, 0);
\draw[<-] (inputu) -- ++(-0.8, 0) |- node[left, near start, align=right]{control signals\\$u$} (K.west);
\draw[->] (outputz) node[above right, align=left]{(weighted)\\exogenous outputs\\$z$} -- ++(1.5, 0);
\draw[->] (outputv) -- ++(0.8, 0) |- node[right, near start, align=left]{sensed output\\$v$} (K.east);
\end{tikzpicture}
#+end_src
#+name: fig:general_control_names
#+caption: General Control Configuration
#+RESULTS:
[[file:figs/general_control_names.png]]
* Modern Interpretation of the Control Specifications * Modern Interpretation of the Control Specifications
** Introduction ** Introduction