dehaeze20_virtu_senso_fusio/matlab/index.html

1092 lines
66 KiB
HTML
Raw Normal View History

2020-10-08 10:52:20 +02:00
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<!-- 2019-08-21 mer. 16:03 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Sensor Fusion Paper - Computation with Matlab</title>
<meta name="generator" content="Org mode" />
<meta name="author" content="Thomas Dehaeze" />
<style type="text/css">
<!--/*--><![CDATA[/*><!--*/
.title { text-align: center;
margin-bottom: .2em; }
.subtitle { text-align: center;
font-size: medium;
font-weight: bold;
margin-top:0; }
.todo { font-family: monospace; color: red; }
.done { font-family: monospace; color: green; }
.priority { font-family: monospace; color: orange; }
.tag { background-color: #eee; font-family: monospace;
padding: 2px; font-size: 80%; font-weight: normal; }
.timestamp { color: #bebebe; }
.timestamp-kwd { color: #5f9ea0; }
.org-right { margin-left: auto; margin-right: 0px; text-align: right; }
.org-left { margin-left: 0px; margin-right: auto; text-align: left; }
.org-center { margin-left: auto; margin-right: auto; text-align: center; }
.underline { text-decoration: underline; }
#postamble p, #preamble p { font-size: 90%; margin: .2em; }
p.verse { margin-left: 3%; }
pre {
border: 1px solid #ccc;
box-shadow: 3px 3px 3px #eee;
padding: 8pt;
font-family: monospace;
overflow: auto;
margin: 1.2em;
}
pre.src {
position: relative;
overflow: visible;
padding-top: 1.2em;
}
pre.src:before {
display: none;
position: absolute;
background-color: white;
top: -10px;
right: 10px;
padding: 3px;
border: 1px solid black;
}
pre.src:hover:before { display: inline;}
/* Languages per Org manual */
pre.src-asymptote:before { content: 'Asymptote'; }
pre.src-awk:before { content: 'Awk'; }
pre.src-C:before { content: 'C'; }
/* pre.src-C++ doesn't work in CSS */
pre.src-clojure:before { content: 'Clojure'; }
pre.src-css:before { content: 'CSS'; }
pre.src-D:before { content: 'D'; }
pre.src-ditaa:before { content: 'ditaa'; }
pre.src-dot:before { content: 'Graphviz'; }
pre.src-calc:before { content: 'Emacs Calc'; }
pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
pre.src-fortran:before { content: 'Fortran'; }
pre.src-gnuplot:before { content: 'gnuplot'; }
pre.src-haskell:before { content: 'Haskell'; }
pre.src-hledger:before { content: 'hledger'; }
pre.src-java:before { content: 'Java'; }
pre.src-js:before { content: 'Javascript'; }
pre.src-latex:before { content: 'LaTeX'; }
pre.src-ledger:before { content: 'Ledger'; }
pre.src-lisp:before { content: 'Lisp'; }
pre.src-lilypond:before { content: 'Lilypond'; }
pre.src-lua:before { content: 'Lua'; }
pre.src-matlab:before { content: 'MATLAB'; }
pre.src-mscgen:before { content: 'Mscgen'; }
pre.src-ocaml:before { content: 'Objective Caml'; }
pre.src-octave:before { content: 'Octave'; }
pre.src-org:before { content: 'Org mode'; }
pre.src-oz:before { content: 'OZ'; }
pre.src-plantuml:before { content: 'Plantuml'; }
pre.src-processing:before { content: 'Processing.js'; }
pre.src-python:before { content: 'Python'; }
pre.src-R:before { content: 'R'; }
pre.src-ruby:before { content: 'Ruby'; }
pre.src-sass:before { content: 'Sass'; }
pre.src-scheme:before { content: 'Scheme'; }
pre.src-screen:before { content: 'Gnu Screen'; }
pre.src-sed:before { content: 'Sed'; }
pre.src-sh:before { content: 'shell'; }
pre.src-sql:before { content: 'SQL'; }
pre.src-sqlite:before { content: 'SQLite'; }
/* additional languages in org.el's org-babel-load-languages alist */
pre.src-forth:before { content: 'Forth'; }
pre.src-io:before { content: 'IO'; }
pre.src-J:before { content: 'J'; }
pre.src-makefile:before { content: 'Makefile'; }
pre.src-maxima:before { content: 'Maxima'; }
pre.src-perl:before { content: 'Perl'; }
pre.src-picolisp:before { content: 'Pico Lisp'; }
pre.src-scala:before { content: 'Scala'; }
pre.src-shell:before { content: 'Shell Script'; }
pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
/* additional language identifiers per "defun org-babel-execute"
in ob-*.el */
pre.src-cpp:before { content: 'C++'; }
pre.src-abc:before { content: 'ABC'; }
pre.src-coq:before { content: 'Coq'; }
pre.src-groovy:before { content: 'Groovy'; }
/* additional language identifiers from org-babel-shell-names in
ob-shell.el: ob-shell is the only babel language using a lambda to put
the execution function name together. */
pre.src-bash:before { content: 'bash'; }
pre.src-csh:before { content: 'csh'; }
pre.src-ash:before { content: 'ash'; }
pre.src-dash:before { content: 'dash'; }
pre.src-ksh:before { content: 'ksh'; }
pre.src-mksh:before { content: 'mksh'; }
pre.src-posh:before { content: 'posh'; }
/* Additional Emacs modes also supported by the LaTeX listings package */
pre.src-ada:before { content: 'Ada'; }
pre.src-asm:before { content: 'Assembler'; }
pre.src-caml:before { content: 'Caml'; }
pre.src-delphi:before { content: 'Delphi'; }
pre.src-html:before { content: 'HTML'; }
pre.src-idl:before { content: 'IDL'; }
pre.src-mercury:before { content: 'Mercury'; }
pre.src-metapost:before { content: 'MetaPost'; }
pre.src-modula-2:before { content: 'Modula-2'; }
pre.src-pascal:before { content: 'Pascal'; }
pre.src-ps:before { content: 'PostScript'; }
pre.src-prolog:before { content: 'Prolog'; }
pre.src-simula:before { content: 'Simula'; }
pre.src-tcl:before { content: 'tcl'; }
pre.src-tex:before { content: 'TeX'; }
pre.src-plain-tex:before { content: 'Plain TeX'; }
pre.src-verilog:before { content: 'Verilog'; }
pre.src-vhdl:before { content: 'VHDL'; }
pre.src-xml:before { content: 'XML'; }
pre.src-nxml:before { content: 'XML'; }
/* add a generic configuration mode; LaTeX export needs an additional
(add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
pre.src-conf:before { content: 'Configuration File'; }
table { border-collapse:collapse; }
caption.t-above { caption-side: top; }
caption.t-bottom { caption-side: bottom; }
td, th { vertical-align:top; }
th.org-right { text-align: center; }
th.org-left { text-align: center; }
th.org-center { text-align: center; }
td.org-right { text-align: right; }
td.org-left { text-align: left; }
td.org-center { text-align: center; }
dt { font-weight: bold; }
.footpara { display: inline; }
.footdef { margin-bottom: 1em; }
.figure { padding: 1em; }
.figure p { text-align: center; }
.equation-container {
display: table;
text-align: center;
width: 100%;
}
.equation {
vertical-align: middle;
}
.equation-label {
display: table-cell;
text-align: right;
vertical-align: middle;
}
.inlinetask {
padding: 10px;
border: 2px solid gray;
margin: 10px;
background: #ffffcc;
}
#org-div-home-and-up
{ text-align: right; font-size: 70%; white-space: nowrap; }
textarea { overflow-x: auto; }
.linenr { font-size: smaller }
.code-highlighted { background-color: #ffff00; }
.org-info-js_info-navigation { border-style: none; }
#org-info-js_console-label
{ font-size: 10px; font-weight: bold; white-space: nowrap; }
.org-info-js_search-highlight
{ background-color: #ffff00; color: #000000; font-weight: bold; }
.org-svg { width: 90%; }
/*]]>*/-->
</style>
<link rel="stylesheet" type="text/css" href="../css/htmlize.css"/>
<link rel="stylesheet" type="text/css" href="../css/readtheorg.css"/>
<script src="../js/jquery.min.js"></script>
<script src="../js/bootstrap.min.js"></script>
<script src="../js/jquery.stickytableheaders.min.js"></script>
<script src="../js/readtheorg.js"></script>
<script type="text/javascript">
/*
@licstart The following is the entire license notice for the
JavaScript code in this tag.
Copyright (C) 2012-2019 Free Software Foundation, Inc.
The JavaScript code in this tag is free software: you can
redistribute it and/or modify it under the terms of the GNU
General Public License (GNU GPL) as published by the Free Software
Foundation, either version 3 of the License, or (at your option)
any later version. The code is distributed WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
As additional permission under GNU GPL version 3 section 7, you
may distribute non-source (e.g., minimized or compacted) forms of
that code without the copy of the GNU GPL normally required by
section 4, provided you include this license notice and a URL
through which recipients can access the Corresponding Source.
@licend The above is the entire license notice
for the JavaScript code in this tag.
*/
<!--/*--><![CDATA[/*><!--*/
function CodeHighlightOn(elem, id)
{
var target = document.getElementById(id);
if(null != target) {
elem.cacheClassElem = elem.className;
elem.cacheClassTarget = target.className;
target.className = "code-highlighted";
elem.className = "code-highlighted";
}
}
function CodeHighlightOff(elem, id)
{
var target = document.getElementById(id);
if(elem.cacheClassElem)
elem.className = elem.cacheClassElem;
if(elem.cacheClassTarget)
target.className = elem.cacheClassTarget;
}
/*]]>*///-->
</script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
displayAlign: "center",
displayIndent: "0em",
"HTML-CSS": { scale: 100,
linebreaks: { automatic: "false" },
webFont: "TeX"
},
SVG: {scale: 100,
linebreaks: { automatic: "false" },
font: "TeX"},
NativeMML: {scale: 100},
TeX: { equationNumbers: {autoNumber: "AMS"},
MultLineWidth: "85%",
TagSide: "right",
TagIndent: ".8em"
}
});
</script>
<script type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body>
<div id="content">
<h1 class="title">Sensor Fusion Paper - Computation with Matlab</h1>
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#org4b54548">1. Definition of the plant</a></li>
<li><a href="#org6285b61">2. Multiplicative input uncertainty</a></li>
<li><a href="#org32f1884">3. Specifications and performance weights</a></li>
<li><a href="#org1448df0">4. Upper bounds on the norm of the complementary filters for NP, RS and RP</a></li>
<li><a href="#orgea7006d">5. H-Infinity synthesis of complementary filters</a></li>
<li><a href="#org7c5a65a">6. Complementary filters using analytical formula</a></li>
<li><a href="#orgab961ea">7. Comparison of complementary filters</a></li>
<li><a href="#org57cec62">8. Controller Analysis</a></li>
<li><a href="#org8ce1c24">9. Nominal Stability and Nominal Performance</a></li>
<li><a href="#orgaba2090">10. Robust Stability and Robust Performance</a></li>
<li><a href="#org81d9b1e">11. Pre-filter</a></li>
<li><a href="#org83dc39a">12. Controller using classical techniques</a></li>
</ul>
</div>
</div>
<p>
The control architecture studied here is shown on figure <a href="#orgb5609b0">1</a> where:
</p>
<ul class="org-ul">
<li>\(G^{\prime}\) is the plant to control</li>
<li>\(K = G^{-1} H_L^{-1}\) is the controller used with \(G\) a model of the plant</li>
<li>\(H_L\) and \(H_H\) are complementary filters (\(H_L + H_H = 1\))</li>
<li>\(K_r\) is a pre-filter that can be added</li>
</ul>
<div id="orgb5609b0" class="figure">
<p><img src="figs-tikz/sf_arch_class_prefilter.png" alt="sf_arch_class_prefilter.png" />
</p>
<p><span class="figure-number">Figure 1: </span>Control Architecture</p>
</div>
<p>
Here is the outline of the <code>matlab</code> analysis for this control architecture:
</p>
<ul class="org-ul">
<li>Section <a href="#orgcfacece">1</a>: the plant model \(G\) is defined</li>
<li>Section <a href="#org4b0f635">2</a>: the plant uncertainty set \(\Pi_I\) is defined using the multiplicative input uncertainty: \(\Pi_I: \ G^\prime = G (1 + w_I \Delta)\). Thus the weight \(w_I\) is defined such that the true system dynamics is included in the set \(\Pi_I\)</li>
<li>Section <a href="#org5848fdb">3</a>: From the specifications on performance that are expressed in terms of upper bounds of \(S\) and \(T\), performance weights \(w_S\) and \(w_T\) are derived such that the goal is to obtain \(|S| < \frac{1}{|w_S|}\) and \(|T| < \frac{1}{|w_T|}, \ \forall \omega\)</li>
<li>Section <a href="#orgd23fb55">4</a>: upper bounds on the magnitude of the complementary filters \(|H_L|\) and \(|H_H|\) are defined in order to ensure Nominal Performance (NP), Robust Stability (RS) and Robust Performance (RP)</li>
<li>Then, \(H_L\) and \(H_H\) are synthesize such that \(|H_L|\) and \(|H_H|\) are within the specified bounds and such that \(H_L + H_H = 1\) (complementary property). This is done using two techniques, first \(\mathcal{H}_\infty\) (section <a href="#org7687a72">5</a>) and then analytical formulas (section <a href="#org1a2b8b9">6</a>). Resulting complementary filters for both methods are compared in section <a href="#org9738366">7</a>.</li>
<li>Section <a href="#org895d8ed">8</a>: the obtain controller \(K = G^{-1} H_H^{-1}\) is analyzed</li>
<li>Section <a href="#org2d6dce4">9</a>: the Nominal Stability (NS) and Nominal Performance conditions are verified</li>
<li>Section <a href="#org888f329">10</a>: robust Stability and Robust Performance conditions are studied</li>
<li>Section <a href="#org567dd40">11</a>: a pre-filter that is used to limit the input usage due to the change of the reference is added</li>
<li>Section <a href="#orgdc38108">12</a>: a controller is designed using <code>SISOTOOL</code> and then compared with the previously generated controller</li>
</ul>
<div class="note">
<p>
All the files (data and Matlab scripts) are accessible <a href="data/sensor_fusion.zip">here</a>.
</p>
</div>
<div id="outline-container-org4b54548" class="outline-2">
<h2 id="org4b54548"><span class="section-number-2">1</span> Definition of the plant</h2>
<div class="outline-text-2" id="text-1">
<p>
<a id="orgcfacece"></a>
</p>
<p>
The studied system consists of a solid positioned on top of a motorized uni-axial soft suspension.
</p>
<p>
The absolute position \(x\) of the solid is measured using an inertial sensor and a force \(F\) can be applied to the mass using a voice coil actuator.
</p>
<p>
The model of the system is represented on figure <a href="#org96b8d22">2</a> where the mass of the solid is \(m = 20\ [kg]\), the stiffness of the suspension is \(k = 10^4\ [N/m]\) and the damping of the system is \(c = 10^2\ [N/(m/s)]\).
</p>
<div id="org96b8d22" class="figure">
<p><img src="figs-tikz/mech_sys_alone.png" alt="mech_sys_alone.png" />
</p>
<p><span class="figure-number">Figure 2: </span>One degree of freedom system</p>
</div>
<p>
The plant \(G\) is defined on matlab and its bode plot is shown on figure <a href="#org5df8edf">3</a>.
</p>
<div class="org-src-container">
<pre class="src src-matlab">m = <span class="org-highlight-numbers-number">20</span>; <span class="org-comment">% [kg]</span>
k = <span class="org-highlight-numbers-number">1e4</span>; <span class="org-comment">% [N/m]</span>
c = <span class="org-highlight-numbers-number">1e2</span>; <span class="org-comment">% [N/(m/s)]</span>
G = <span class="org-highlight-numbers-number">1</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-1">(</span>m<span class="org-type">*</span>s<span class="org-type">^</span><span class="org-highlight-numbers-number">2</span> <span class="org-type">+</span> c<span class="org-type">*</span>s <span class="org-type">+</span> k<span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<div id="org5df8edf" class="figure">
<p><img src="figs/bode_plot_mech_sys.png" alt="bode_plot_mech_sys.png" />
</p>
<p><span class="figure-number">Figure 3: </span>Bode plot of \(G\) (<a href="./figs/bode_plot_mech_sys.png">png</a>, <a href="./figs/bode_plot_mech_sys.pdf">pdf</a>)</p>
</div>
</div>
</div>
<div id="outline-container-org6285b61" class="outline-2">
<h2 id="org6285b61"><span class="section-number-2">2</span> Multiplicative input uncertainty</h2>
<div class="outline-text-2" id="text-2">
<p>
<a id="org4b0f635"></a>
We choose to use the multiplicative input uncertainty to model the plant uncertainty:
\[ \Pi_I: \ G^\prime(s) = G(s) (1 + w_I(s) \Delta(s)),\text{ with } |\Delta(j\omega)| < 1 \ \forall \omega \]
</p>
<p>
The uncertainty weight \(w_I\) has the following form:
\[ w_I(s) = \frac{\tau s + r_0}{(\tau/r_\infty) s + 1} \]
where \(r_0=0.1\) is the relative uncertainty at steady-state, \(1/\tau=80\text{Hz}\) is the frequency at which the relative uncertainty reaches 100%, and \(r_\infty=10\) is the magnitude of the weight at high frequency.
</p>
<p>
We defined the uncertainty weight on matlab. Its bode plot is shown on figure <a href="#org3758d61">4</a>.
</p>
<div class="org-src-container">
<pre class="src src-matlab">r0 = <span class="org-highlight-numbers-number">0</span>.<span class="org-highlight-numbers-number">1</span>;
rinf = <span class="org-highlight-numbers-number">10</span>;
tau = <span class="org-highlight-numbers-number">1</span><span class="org-type">/</span><span class="org-highlight-numbers-number">2</span><span class="org-type">/</span><span class="org-constant">pi</span><span class="org-type">/</span><span class="org-highlight-numbers-number">80</span>;
wI = <span class="org-rainbow-delimiters-depth-1">(</span>tau<span class="org-type">*</span>s <span class="org-type">+</span> r0<span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-rainbow-delimiters-depth-2">(</span>tau<span class="org-type">/</span>rinf<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span>s<span class="org-type">+</span><span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<div id="org3758d61" class="figure">
<p><img src="figs/bode_wi.png" alt="bode_wi.png" />
</p>
<p><span class="figure-number">Figure 4: </span>Bode plot of \(w_I\) (<a href="./figs/bode_wi.png">png</a>, <a href="./figs/bode_wi.pdf">pdf</a>)</p>
</div>
<p>
The uncertain model is created with the <code>ultidyn</code> function. Elements in the uncertainty set \(\Pi_I\) are computed and their bode plot is shown on figure <a href="#orgd0dde8c">5</a>.
</p>
<div class="org-src-container">
<pre class="src src-matlab">Delta = ultidyn<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-string">'Delta'</span>, <span class="org-rainbow-delimiters-depth-2">[</span><span class="org-highlight-numbers-number">1</span> <span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-2">]</span><span class="org-rainbow-delimiters-depth-1">)</span>;
Gd = G<span class="org-type">*</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-highlight-numbers-number">1</span><span class="org-type">+</span>wI<span class="org-type">*</span>Delta<span class="org-rainbow-delimiters-depth-1">)</span>;
Gds = usample<span class="org-rainbow-delimiters-depth-1">(</span>Gd, <span class="org-highlight-numbers-number">20</span><span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<div id="orgd0dde8c" class="figure">
<p><img src="figs/plant_uncertainty_bode_plot.png" alt="plant_uncertainty_bode_plot.png" />
</p>
<p><span class="figure-number">Figure 5: </span>Some elements in the uncertainty set \(\Pi_I\) (<a href="./figs/plant_uncertainty_bode_plot.png">png</a>, <a href="./figs/plant_uncertainty_bode_plot.pdf">pdf</a>)</p>
</div>
</div>
</div>
<div id="outline-container-org32f1884" class="outline-2">
<h2 id="org32f1884"><span class="section-number-2">3</span> Specifications and performance weights</h2>
<div class="outline-text-2" id="text-3">
<p>
<a id="org5848fdb"></a>
</p>
<p>
The control objective is to isolate the displacement \(x\) of the mass from the ground motion \(w\).
</p>
<p>
The specifications are described below:
</p>
<ul class="org-ul">
<li>at least a factor \(10\) of disturbance rejection at \(2\ \text{Hz}\) and with a slope of \(2\) below \(2\ \text{Hz}\) until a rejection of \(10^3\)</li>
<li>the noise attenuation should be at least \(10\) above \(100\ \text{Hz}\) and with a slope of \(-2\) above</li>
</ul>
<p>
These specifications can be represented as upper bounds on the closed loop transfer functions \(S\) and \(T\) (see figure <a href="#orgbee58e5">6</a>).
</p>
<div id="orgbee58e5" class="figure">
<p><img src="figs/bode_requirements.png" alt="bode_requirements.png" />
</p>
<p><span class="figure-number">Figure 6: </span>Upper bounds on \(S\) and \(T\) (<a href="./figs/bode_requirements.png">png</a>, <a href="./figs/bode_requirements.pdf">pdf</a>)</p>
</div>
<p>
We now define two weights, \(w_S(s)\) and \(w_T(s)\) such that \(1/|w_S|\) and \(1/|w_T|\) are lower than the previously defined upper bounds.
Then, the performance specifications are satisfied if the following condition is valid:
\[ \big|S(j\omega)\big| < \frac{1}{|w_S(j\omega)|} ; \quad \big|T(j\omega)\big| < \frac{1}{|w_T(j\omega)|}, \quad \forall \omega \]
</p>
<p>
The weights are defined as follow. They magnitude is compared with the upper bounds on \(S\) and \(T\) on figure <a href="#orgcb06128">7</a>.
</p>
<div class="org-src-container">
<pre class="src src-matlab">wS = <span class="org-highlight-numbers-number">1600</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-1">(</span>s<span class="org-type">+</span><span class="org-highlight-numbers-number">0</span>.<span class="org-highlight-numbers-number">13</span><span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">2</span>;
wT = <span class="org-highlight-numbers-number">1000</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-rainbow-delimiters-depth-2">(</span>s<span class="org-type">/</span><span class="org-rainbow-delimiters-depth-3">(</span><span class="org-highlight-numbers-number">2</span><span class="org-type">*</span><span class="org-constant">pi</span><span class="org-type">*</span><span class="org-highlight-numbers-number">1000</span><span class="org-rainbow-delimiters-depth-3">)</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">2</span>;
</pre>
</div>
<div id="orgcb06128" class="figure">
<p><img src="figs/compare_weights_upper_bounds_S_T.png" alt="compare_weights_upper_bounds_S_T.png" />
</p>
<p><span class="figure-number">Figure 7: </span>Weights \(w_S\) and \(w_T\) with the upper bounds on \(S\) and \(T\) obtained from the specifications (<a href="./figs/compare_weights_upper_bounds_S_T.png">png</a>, <a href="./figs/compare_weights_upper_bounds_S_T.pdf">pdf</a>)</p>
</div>
</div>
</div>
<div id="outline-container-org1448df0" class="outline-2">
<h2 id="org1448df0"><span class="section-number-2">4</span> Upper bounds on the norm of the complementary filters for NP, RS and RP</h2>
<div class="outline-text-2" id="text-4">
<p>
<a id="orgd23fb55"></a>
</p>
<p>
Now that we have defined \(w_I\), \(w_S\) and \(w_T\), we can derive conditions for Nominal Performance, Robust Stability and Robust Performance (\(j\omega\) is omitted here for readability):
</p>
\begin{align*}
\text{NP} &\Leftrightarrow |H_H| < \frac{1}{|w_S|} \text{ and } |H_L| < \frac{1}{|w_T|} \quad \forall \omega \\
\text{RS} &\Leftrightarrow |H_L| < \frac{1}{|w_I| (2 + |w_I|)} \quad \forall \omega \\
\text{RP for } S &\Leftarrow |H_H| < \frac{1 + |w_I|}{|w_S| (2 + |w_I|)} \quad \forall \omega \\
\text{RP for } T &\Leftrightarrow |H_L| < \frac{1}{|w_T| (1 + |w_I|) + |w_I|} \quad \forall \omega
\end{align*}
<p>
These conditions are upper bounds on the complementary filters used for control.
</p>
<p>
We plot these conditions on figure <a href="#org852b4a8">8</a>.
</p>
<div id="org852b4a8" class="figure">
<p><img src="figs/weights_NP_RS_RP.png" alt="weights_NP_RS_RP.png" />
</p>
<p><span class="figure-number">Figure 8: </span>Upper bounds on the norm of the complementary filters for NP, RS and RP (<a href="./figs/weights_NP_RS_RP.png">png</a>, <a href="./figs/weights_NP_RS_RP.pdf">pdf</a>)</p>
</div>
</div>
</div>
<div id="outline-container-orgea7006d" class="outline-2">
<h2 id="orgea7006d"><span class="section-number-2">5</span> H-Infinity synthesis of complementary filters</h2>
<div class="outline-text-2" id="text-5">
<p>
<a id="org7687a72"></a>
</p>
<p>
We here synthesize the complementary filters using the \(\mathcal{H}_\infty\) synthesis.
The goal is to specify upper bounds on the norms of \(H_L\) and \(H_H\) while ensuring their complementary property (\(H_L + H_H = 1\)).
</p>
<p>
In order to do so, we use the generalized plant shown on figure <a href="#org5d15350">9</a> where \(w_L\) and \(w_H\) weighting transfer functions that will be used to shape \(H_L\) and \(H_H\) respectively.
</p>
<div id="org5d15350" class="figure">
<p><img src="figs-tikz/sf_hinf_filters_plant_b.png" alt="sf_hinf_filters_plant_b.png" />
</p>
<p><span class="figure-number">Figure 9: </span>Generalized plant used for the \(\mathcal{H}_\infty\) synthesis of the complementary filters</p>
</div>
<p>
The \(\mathcal{H}_\infty\) synthesis applied on this generalized plant will give a transfer function \(H_L\) (figure <a href="#orgf04293d">10</a>) such that the \(\mathcal{H}_\infty\) norm of the transfer function from \(w\) to \([z_H,\ z_L]\) is less than one:
\[ \left\| \begin{array}{c} H_L w_L \\ (1 - H_L) w_H \end{array} \right\|_\infty < 1 \]
</p>
<p>
Thus, if the above condition is verified, we can define \(H_H = 1 - H_L\) and we have that:
\[ \left\| \begin{array}{c} H_L w_L \\ H_H w_H \end{array} \right\|_\infty < 1 \]
Which is almost (with an maximum error of \(\sqrt{2}\)) equivalent to:
</p>
\begin{align*}
|H_L| &< \frac{1}{|w_L|}, \quad \forall \omega \\
|H_H| &< \frac{1}{|w_H|}, \quad \forall \omega
\end{align*}
<p>
We then see that \(w_L\) and \(w_H\) can be used to shape both \(H_L\) and \(H_H\) while ensuring (by definition of \(H_H = 1 - H_L\)) their complementary property.
</p>
<div id="orgf04293d" class="figure">
<p><img src="figs-tikz/sf_hinf_filters_b.png" alt="sf_hinf_filters_b.png" />
</p>
<p><span class="figure-number">Figure 10: </span>\(\mathcal{H}_\infty\) synthesis of the complementary filters</p>
</div>
<p>
Thus, if we choose \(w_L\) and \(w_H\) such that \(1/|w_L|\) and \(1/|w_H|\) lie below the upper bounds of figure <a href="#org852b4a8">8</a>, we will ensure the NP, RS and RP of the controlled system.
</p>
<p>
Depending if we are interested only in NP, RS or RP, we can adjust the weights \(w_L\) and \(w_H\).
</p>
<div class="org-src-container">
<pre class="src src-matlab">omegab = <span class="org-highlight-numbers-number">2</span><span class="org-type">*</span><span class="org-constant">pi</span><span class="org-type">*</span><span class="org-highlight-numbers-number">9</span>;
wH = <span class="org-rainbow-delimiters-depth-1">(</span>omegab<span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">2</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-1">(</span>s <span class="org-type">+</span> omegab<span class="org-type">*</span>sqrt<span class="org-rainbow-delimiters-depth-2">(</span><span class="org-highlight-numbers-number">1e</span><span class="org-type">-</span><span class="org-highlight-numbers-number">5</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">2</span>;
omegab = <span class="org-highlight-numbers-number">2</span><span class="org-type">*</span><span class="org-constant">pi</span><span class="org-type">*</span><span class="org-highlight-numbers-number">28</span>;
wL = <span class="org-rainbow-delimiters-depth-1">(</span>s <span class="org-type">+</span> omegab<span class="org-type">/</span><span class="org-rainbow-delimiters-depth-2">(</span><span class="org-highlight-numbers-number">4</span>.<span class="org-highlight-numbers-number">5</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">^</span><span class="org-rainbow-delimiters-depth-2">(</span><span class="org-highlight-numbers-number">1</span><span class="org-type">/</span><span class="org-highlight-numbers-number">3</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">3</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-1">(</span>s<span class="org-type">*</span><span class="org-rainbow-delimiters-depth-2">(</span><span class="org-highlight-numbers-number">1e</span><span class="org-type">-</span><span class="org-highlight-numbers-number">4</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">^</span><span class="org-rainbow-delimiters-depth-2">(</span><span class="org-highlight-numbers-number">1</span><span class="org-type">/</span><span class="org-highlight-numbers-number">3</span><span class="org-rainbow-delimiters-depth-2">)</span> <span class="org-type">+</span> omegab<span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">3</span>;
</pre>
</div>
<div id="org0dbd288" class="figure">
<p><img src="figs/weights_wl_wh.png" alt="weights_wl_wh.png" />
</p>
<p><span class="figure-number">Figure 11: </span>Weights on the complementary filters \(w_L\) and \(w_H\) and the associated performance weights (<a href="./figs/weights_wl_wh.png">png</a>, <a href="./figs/weights_wl_wh.pdf">pdf</a>)</p>
</div>
<p>
We define the generalized plant \(P\) on matlab.
</p>
<div class="org-src-container">
<pre class="src src-matlab">P = <span class="org-rainbow-delimiters-depth-1">[</span><span class="org-highlight-numbers-number">0</span> wL;
wH <span class="org-type">-</span>wH;
<span class="org-highlight-numbers-number">1</span> <span class="org-highlight-numbers-number">0</span><span class="org-rainbow-delimiters-depth-1">]</span>;
</pre>
</div>
<p>
And we do the \(\mathcal{H}_\infty\) synthesis using the <code>hinfsyn</code> command.
</p>
<div class="org-src-container">
<pre class="src src-matlab"><span class="org-rainbow-delimiters-depth-1">[</span>Hl_hinf, <span class="org-type">~</span>, gamma, <span class="org-type">~</span><span class="org-rainbow-delimiters-depth-1">]</span> = hinfsyn<span class="org-rainbow-delimiters-depth-1">(</span>P, <span class="org-highlight-numbers-number">1</span>, <span class="org-highlight-numbers-number">1</span>,'TOLGAM', <span class="org-highlight-numbers-number">0</span>.<span class="org-highlight-numbers-number">001</span>, 'METHOD', 'ric', 'DISPLAY', 'on'<span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<pre class="example">
[Hl_hinf, ~, gamma, ~] = hinfsyn(P, 1, 1,'TOLGAM', 0.001, 'METHOD', 'ric', 'DISPLAY', 'on');
Test bounds: 0.0000 &lt; gamma &lt;= 1.7285
gamma hamx_eig xinf_eig hamy_eig yinf_eig nrho_xy p/f
1.729 4.1e+01 8.4e-12 1.8e-01 0.0e+00 0.0000 p
0.864 3.9e+01 -5.8e-02# 1.8e-01 0.0e+00 0.0000 f
1.296 4.0e+01 8.4e-12 1.8e-01 0.0e+00 0.0000 p
1.080 4.0e+01 8.5e-12 1.8e-01 0.0e+00 0.0000 p
0.972 3.9e+01 -4.2e-01# 1.8e-01 0.0e+00 0.0000 f
1.026 4.0e+01 8.5e-12 1.8e-01 0.0e+00 0.0000 p
0.999 3.9e+01 8.5e-12 1.8e-01 0.0e+00 0.0000 p
0.986 3.9e+01 -1.2e+00# 1.8e-01 0.0e+00 0.0000 f
0.993 3.9e+01 -8.2e+00# 1.8e-01 0.0e+00 0.0000 f
0.996 3.9e+01 8.5e-12 1.8e-01 0.0e+00 0.0000 p
0.994 3.9e+01 8.5e-12 1.8e-01 0.0e+00 0.0000 p
0.993 3.9e+01 -3.2e+01# 1.8e-01 0.0e+00 0.0000 f
Gamma value achieved: 0.9942
</pre>
<p>
We then define the high pass filter \(H_H = 1 - H_L\). The bode plot of both \(H_L\) and \(H_H\) is shown on figure <a href="#org4ed86b3">12</a>.
</p>
<div class="org-src-container">
<pre class="src src-matlab">Hh_hinf = <span class="org-highlight-numbers-number">1</span> <span class="org-type">-</span> Hl_hinf;
</pre>
</div>
<div id="org4ed86b3" class="figure">
<p><img src="figs/hinf_filters_results.png" alt="hinf_filters_results.png" />
</p>
<p><span class="figure-number">Figure 12: </span>Obtained complementary filters using \(\mathcal{H}_\infty\) synthesis (<a href="./figs/hinf_filters_results.png">png</a>, <a href="./figs/hinf_filters_results.pdf">pdf</a>)</p>
</div>
</div>
</div>
<div id="outline-container-org7c5a65a" class="outline-2">
<h2 id="org7c5a65a"><span class="section-number-2">6</span> Complementary filters using analytical formula</h2>
<div class="outline-text-2" id="text-6">
<p>
<a id="org1a2b8b9"></a>
</p>
<p>
We here use analytical formula for the complementary filters \(H_L\) and \(H_H\).
</p>
<p>
The first two formulas that are used to generate complementary filters are:
</p>
\begin{align*}
H_L(s) &= \frac{(1+\alpha) (\frac{s}{\omega_0})+1}{\left((\frac{s}{\omega_0})+1\right) \left((\frac{s}{\omega_0})^2 + \alpha (\frac{s}{\omega_0}) + 1\right)}\\
H_H(s) &= \frac{(\frac{s}{\omega_0})^2 \left((\frac{s}{\omega_0})+1+\alpha\right)}{\left((\frac{s}{\omega_0})+1\right) \left((\frac{s}{\omega_0})^2 + \alpha (\frac{s}{\omega_0}) + 1\right)}
\end{align*}
<p>
where:
</p>
<ul class="org-ul">
<li>\(\omega_0\) is the blending frequency in rad/s.</li>
<li>\(\alpha\) is used to change the shape of the filters:
<ul class="org-ul">
<li>Small values for \(\alpha\) will produce high magnitude of the filters \(|H_L(j\omega)|\) and \(|H_H(j\omega)|\) near \(\omega_0\) but smaller value for \(|H_L(j\omega)|\) above \(\approx 1.5 \omega_0\) and for \(|H_H(j\omega)|\) below \(\approx 0.7 \omega_0\)</li>
<li>A large \(\alpha\) will do the opposite</li>
</ul></li>
</ul>
<p>
This is illustrated on figure <a href="#org593c318">13</a>.
As it is usually wanted to have the \(\| S \|_\infty < 2\), \(\alpha\) between \(0.5\) and \(1\) gives a good trade-off between the performance and the robustness.
The slope of those filters at high and low frequencies is \(-2\) and \(2\) respectively for \(H_L\) and \(H_H\).
</p>
<div id="org593c318" class="figure">
<p><img src="figs/comp_filters_param_alpha.png" alt="comp_filters_param_alpha.png" />
</p>
<p><span class="figure-number">Figure 13: </span>Effect of the parameter \(\alpha\) on the shape of the generated second order complementary filters (<a href="./figs/comp_filters_param_alpha.png">png</a>, <a href="./figs/comp_filters_param_alpha.pdf">pdf</a>)</p>
</div>
<p>
The parameters \(\alpha\) and \(\omega_0\) are chosen in order to have that the complementary filters stay below the defined upper bounds.
</p>
<p>
The obtained complementary filters are shown on figure <a href="#orgb89687e">14</a>.
The Robust Performance is not fulfilled for \(T\), and we see that the RP condition as a slop of \(-3\). We thus have to use different formula for the complementary filters here.
</p>
<div class="org-src-container">
<pre class="src src-matlab">w0 = <span class="org-highlight-numbers-number">2</span><span class="org-type">*</span><span class="org-constant">pi</span><span class="org-type">*</span><span class="org-highlight-numbers-number">13</span>;
alpha = <span class="org-highlight-numbers-number">0</span>.<span class="org-highlight-numbers-number">8</span>;
Hh2_ana = <span class="org-rainbow-delimiters-depth-1">(</span>s<span class="org-type">/</span>w0<span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">2</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-rainbow-delimiters-depth-2">(</span>s<span class="org-type">/</span>w0<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">+</span><span class="org-highlight-numbers-number">1</span><span class="org-type">+</span>alpha<span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-rainbow-delimiters-depth-2">(</span><span class="org-rainbow-delimiters-depth-3">(</span>s<span class="org-type">/</span>w0<span class="org-rainbow-delimiters-depth-3">)</span><span class="org-type">+</span><span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-2">(</span><span class="org-rainbow-delimiters-depth-3">(</span>s<span class="org-type">/</span>w0<span class="org-rainbow-delimiters-depth-3">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">2</span> <span class="org-type">+</span> alpha<span class="org-type">*</span><span class="org-rainbow-delimiters-depth-3">(</span>s<span class="org-type">/</span>w0<span class="org-rainbow-delimiters-depth-3">)</span> <span class="org-type">+</span> <span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span>;
Hl2_ana = <span class="org-rainbow-delimiters-depth-1">(</span><span class="org-rainbow-delimiters-depth-2">(</span><span class="org-highlight-numbers-number">1</span><span class="org-type">+</span>alpha<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-2">(</span>s<span class="org-type">/</span>w0<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">+</span><span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-rainbow-delimiters-depth-2">(</span><span class="org-rainbow-delimiters-depth-3">(</span>s<span class="org-type">/</span>w0<span class="org-rainbow-delimiters-depth-3">)</span><span class="org-type">+</span><span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-2">(</span><span class="org-rainbow-delimiters-depth-3">(</span>s<span class="org-type">/</span>w0<span class="org-rainbow-delimiters-depth-3">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">2</span> <span class="org-type">+</span> alpha<span class="org-type">*</span><span class="org-rainbow-delimiters-depth-3">(</span>s<span class="org-type">/</span>w0<span class="org-rainbow-delimiters-depth-3">)</span> <span class="org-type">+</span> <span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<div id="orgb89687e" class="figure">
<p><img src="figs/complementary_filters_second_order.png" alt="complementary_filters_second_order.png" />
</p>
<p><span class="figure-number">Figure 14: </span>Second order complementary filters using the analytical formula (<a href="./figs/complementary_filters_second_order.png">png</a>, <a href="./figs/complementary_filters_second_order.pdf">pdf</a>)</p>
</div>
<p>
The following formula gives complementary filters with slopes of \(-3\) and \(3\):
</p>
\begin{align*}
H_L(s) &= \frac{\left(1+(\alpha+1)(\beta+1)\right) (\frac{s}{\omega_0})^2 + (1+\alpha+\beta)(\frac{s}{\omega_0}) + 1}{\left(\frac{s}{\omega_0} + 1\right) \left( (\frac{s}{\omega_0})^2 + \alpha (\frac{s}{\omega_0}) + 1 \right) \left( (\frac{s}{\omega_0})^2 + \beta (\frac{s}{\omega_0}) + 1 \right)}\\
H_H(s) &= \frac{(\frac{s}{\omega_0})^3 \left( (\frac{s}{\omega_0})^2 + (1+\alpha+\beta) (\frac{s}{\omega_0}) + (1+(\alpha+1)(\beta+1)) \right)}{\left(\frac{s}{\omega_0} + 1\right) \left( (\frac{s}{\omega_0})^2 + \alpha (\frac{s}{\omega_0}) + 1 \right) \left( (\frac{s}{\omega_0})^2 + \beta (\frac{s}{\omega_0}) + 1 \right)}
\end{align*}
<p>
The parameters are:
</p>
<ul class="org-ul">
<li>\(\omega_0\) is the blending frequency in rad/s</li>
<li>\(\alpha\) and \(\beta\) that are used to change the shape of the filters similarly to the parameter \(\alpha\) for the second order complementary filters</li>
</ul>
<p>
The filters are defined below and the result is shown on figure <a href="#orgfa59961">15</a> where we can see that the complementary filters are below the defined upper bounds.
</p>
<div class="org-src-container">
<pre class="src src-matlab">alpha = <span class="org-highlight-numbers-number">1</span>;
beta = <span class="org-highlight-numbers-number">10</span>;
w0 = <span class="org-highlight-numbers-number">2</span><span class="org-type">*</span><span class="org-constant">pi</span><span class="org-type">*</span><span class="org-highlight-numbers-number">14</span>;
Hh3_ana = <span class="org-rainbow-delimiters-depth-1">(</span>s<span class="org-type">/</span>w0<span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">3</span> <span class="org-type">*</span> <span class="org-rainbow-delimiters-depth-1">(</span><span class="org-rainbow-delimiters-depth-2">(</span>s<span class="org-type">/</span>w0<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">2</span> <span class="org-type">+</span> <span class="org-rainbow-delimiters-depth-2">(</span><span class="org-highlight-numbers-number">1</span><span class="org-type">+</span>alpha<span class="org-type">+</span>beta<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-2">(</span>s<span class="org-type">/</span>w0<span class="org-rainbow-delimiters-depth-2">)</span> <span class="org-type">+</span> <span class="org-rainbow-delimiters-depth-2">(</span><span class="org-highlight-numbers-number">1</span><span class="org-type">+</span><span class="org-rainbow-delimiters-depth-3">(</span>alpha<span class="org-type">+</span><span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-3">)</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-3">(</span>beta<span class="org-type">+</span><span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-3">)</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-rainbow-delimiters-depth-2">(</span>s<span class="org-type">/</span>w0 <span class="org-type">+</span> <span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-2">(</span><span class="org-rainbow-delimiters-depth-3">(</span>s<span class="org-type">/</span>w0<span class="org-rainbow-delimiters-depth-3">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">2</span><span class="org-type">+</span>alpha<span class="org-type">*</span><span class="org-rainbow-delimiters-depth-3">(</span>s<span class="org-type">/</span>w0<span class="org-rainbow-delimiters-depth-3">)</span><span class="org-type">+</span><span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-2">(</span><span class="org-rainbow-delimiters-depth-3">(</span>s<span class="org-type">/</span>w0<span class="org-rainbow-delimiters-depth-3">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">2</span><span class="org-type">+</span>beta<span class="org-type">*</span><span class="org-rainbow-delimiters-depth-3">(</span>s<span class="org-type">/</span>w0<span class="org-rainbow-delimiters-depth-3">)</span><span class="org-type">+</span><span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span>;
Hl3_ana = <span class="org-rainbow-delimiters-depth-1">(</span><span class="org-rainbow-delimiters-depth-2">(</span><span class="org-highlight-numbers-number">1</span><span class="org-type">+</span><span class="org-rainbow-delimiters-depth-3">(</span>alpha<span class="org-type">+</span><span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-3">)</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-3">(</span>beta<span class="org-type">+</span><span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-3">)</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-2">(</span>s<span class="org-type">/</span>w0<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">2</span> <span class="org-type">+</span> <span class="org-rainbow-delimiters-depth-2">(</span><span class="org-highlight-numbers-number">1</span><span class="org-type">+</span>alpha<span class="org-type">+</span>beta<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-2">(</span>s<span class="org-type">/</span>w0<span class="org-rainbow-delimiters-depth-2">)</span> <span class="org-type">+</span> <span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-rainbow-delimiters-depth-2">(</span>s<span class="org-type">/</span>w0 <span class="org-type">+</span> <span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-2">(</span><span class="org-rainbow-delimiters-depth-3">(</span>s<span class="org-type">/</span>w0<span class="org-rainbow-delimiters-depth-3">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">2</span><span class="org-type">+</span>alpha<span class="org-type">*</span><span class="org-rainbow-delimiters-depth-3">(</span>s<span class="org-type">/</span>w0<span class="org-rainbow-delimiters-depth-3">)</span><span class="org-type">+</span><span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-2">(</span><span class="org-rainbow-delimiters-depth-3">(</span>s<span class="org-type">/</span>w0<span class="org-rainbow-delimiters-depth-3">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">2</span><span class="org-type">+</span>beta<span class="org-type">*</span><span class="org-rainbow-delimiters-depth-3">(</span>s<span class="org-type">/</span>w0<span class="org-rainbow-delimiters-depth-3">)</span><span class="org-type">+</span><span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<div id="orgfa59961" class="figure">
<p><img src="figs/complementary_filters_third_order.png" alt="complementary_filters_third_order.png" />
</p>
<p><span class="figure-number">Figure 15: </span>Third order complementary filters using the analytical formula (<a href="./figs/complementary_filters_third_order.png">png</a>, <a href="./figs/complementary_filters_third_order.pdf">pdf</a>)</p>
</div>
</div>
</div>
<div id="outline-container-orgab961ea" class="outline-2">
<h2 id="orgab961ea"><span class="section-number-2">7</span> Comparison of complementary filters</h2>
<div class="outline-text-2" id="text-7">
<p>
<a id="org9738366"></a>
The generated complementary filters using \(\mathcal{H}_\infty\) and the analytical formulas are compared on figure <a href="#org4505579">16</a>.
</p>
<p>
Although they are very close to each other, there is some difference to note here:
</p>
<ul class="org-ul">
<li>the analytical formula provides a very simple way to generate the complementary filters (and thus the controller), they could even be used to tune the controller online using the parameters \(\alpha\) and \(\omega_0\). However, these formula have the property that \(|H_H|\) and \(|H_L|\) are symmetrical with the frequency \(\omega_0\) which may not be desirable.</li>
<li>while the \(\mathcal{H}_\infty\) synthesis of the complementary filters is not as straightforward as using the analytical formula, it provides a more optimized procedure to obtain the complementary filters</li>
</ul>
<p>
The complementary filters obtained with the \(\mathcal{H}_\infty\) will be used for further analysis.
</p>
<div id="org4505579" class="figure">
<p><img src="figs/comp_hinf_analytical.png" alt="comp_hinf_analytical.png" />
</p>
<p><span class="figure-number">Figure 16: </span>Comparison of the complementary filters obtained with \(\mathcal{H}_\infty\) synthesis and with the analytical formula (<a href="./figs/comp_hinf_analytical.png">png</a>, <a href="./figs/comp_hinf_analytical.pdf">pdf</a>)</p>
</div>
</div>
</div>
<div id="outline-container-org57cec62" class="outline-2">
<h2 id="org57cec62"><span class="section-number-2">8</span> Controller Analysis</h2>
<div class="outline-text-2" id="text-8">
<p>
<a id="org895d8ed"></a>
</p>
<p>
The controller \(K\) is computed from the plant model \(G\) and the low pass filter \(H_H\):
\[ K = G^{-1} H_H^{-1} \]
</p>
<p>
As this is not proper and thus realizable, a second order low pass filter is added with a crossover frequency much larger than the control bandwidth.
</p>
<div class="org-src-container">
<pre class="src src-matlab">omega = <span class="org-highlight-numbers-number">2</span><span class="org-type">*</span><span class="org-constant">pi</span><span class="org-type">*</span><span class="org-highlight-numbers-number">1000</span>;
K = <span class="org-highlight-numbers-number">1</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-1">(</span>Hh_hinf<span class="org-type">*</span>G<span class="org-rainbow-delimiters-depth-1">)</span> <span class="org-type">*</span> <span class="org-highlight-numbers-number">1</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-rainbow-delimiters-depth-2">(</span><span class="org-highlight-numbers-number">1</span><span class="org-type">+</span>s<span class="org-type">/</span>omega<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-2">(</span><span class="org-highlight-numbers-number">1</span><span class="org-type">+</span>s<span class="org-type">/</span>omega<span class="org-type">+</span><span class="org-rainbow-delimiters-depth-3">(</span>s<span class="org-type">/</span>omega<span class="org-rainbow-delimiters-depth-3">)</span><span class="org-type">^</span><span class="org-highlight-numbers-number">2</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<pre class="example">
zpk(K)
ans =
4.961e12 (s+9.915e04) (s^2 + 5s + 500) (s^2 + 284.6s + 2.135e04) (s^2 + 130.5s + 9887)
--------------------------------------------------------------------------------------------------
(s+9.914e04) (s+6283) (s^2 + 0.3576s + 0.03198) (s^2 + 413.8s + 6.398e04) (s^2 + 6283s + 3.948e07)
Continuous-time zero/pole/gain model.
</pre>
<p>
The bode plot of the controller is shown on figure <a href="#orgf7c7488">17</a>:
</p>
<ul class="org-ul">
<li>two integrator are present at low frequency</li>
<li>the resonance of the plant at \(3.5\ \text{Hz}\) is inverted (notched)</li>
<li>a lead is added at \(10\ \text{Hz}\)</li>
</ul>
<div id="orgf7c7488" class="figure">
<p><img src="figs/bode_plot_controller.png" alt="bode_plot_controller.png" />
</p>
<p><span class="figure-number">Figure 17: </span>Bode plot of the obtained controller \(K\) (<a href="./figs/bode_plot_controller.png">png</a>, <a href="./figs/bode_plot_controller.pdf">pdf</a>)</p>
</div>
</div>
</div>
<div id="outline-container-org8ce1c24" class="outline-2">
<h2 id="org8ce1c24"><span class="section-number-2">9</span> Nominal Stability and Nominal Performance</h2>
<div class="outline-text-2" id="text-9">
<p>
<a id="org2d6dce4"></a>
</p>
<p>
The nominal stability of the system is first checked with the <code>allmargin</code> matlab command.
</p>
<div class="org-src-container">
<pre class="src src-matlab">allmargin<span class="org-rainbow-delimiters-depth-1">(</span>K<span class="org-type">*</span>G<span class="org-type">*</span>Hl_hinf<span class="org-rainbow-delimiters-depth-1">)</span>
</pre>
</div>
<pre class="example">
allmargin(K*G*Hl_hinf)
ans =
struct with fields:
GainMargin: 4.46426896164391
GMFrequency: 243.854595348016
PhaseMargin: 35.7045152899792
PMFrequency: 88.3664383511655
DelayMargin: 0.00705201387841809
DMFrequency: 88.3664383511655
Stable: 1
</pre>
<p>
The system is stable and the stability margins are good.
</p>
<p>
The bode plot of the loop gain \(L = K*G*H_L\) is shown on figure <a href="#org7bc5e27">18</a>.
</p>
<div id="org7bc5e27" class="figure">
<p><img src="figs/bode_plot_loop_gain.png" alt="bode_plot_loop_gain.png" />
</p>
<p><span class="figure-number">Figure 18: </span>Bode Plot of the Loop Gain \(L = K G H_L\) (<a href="./figs/bode_plot_loop_gain.png">png</a>, <a href="./figs/bode_plot_loop_gain.pdf">pdf</a>)</p>
</div>
<p>
In order to check the Nominal Performance of the system, we compute the sensibility and the complementary sensibility transfer functions.
</p>
<div class="org-src-container">
<pre class="src src-matlab">S = <span class="org-highlight-numbers-number">1</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-1">(</span>K<span class="org-type">*</span>G<span class="org-type">*</span>Hl_hinf <span class="org-type">+</span> <span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-1">)</span>;
T = K<span class="org-type">*</span>G<span class="org-type">*</span>Hl_hinf<span class="org-type">/</span><span class="org-rainbow-delimiters-depth-1">(</span>K<span class="org-type">*</span>G<span class="org-type">*</span>Hl_hinf <span class="org-type">+</span> <span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<p>
We then compare their norms with the upper bounds on the performance of the system (figure <a href="#org126d73c">19</a>).
As expected, we guarantee the Nominal Performance of the system.
</p>
<div id="org126d73c" class="figure">
<p><img src="figs/verification_NP.png" alt="verification_NP.png" />
</p>
<p><span class="figure-number">Figure 19: </span>Bode plot of \(S\) and \(T\) in order to verify the nominal performance of the system (<a href="./figs/verification_NP.png">png</a>, <a href="./figs/verification_NP.pdf">pdf</a>)</p>
</div>
</div>
</div>
<div id="outline-container-orgaba2090" class="outline-2">
<h2 id="orgaba2090"><span class="section-number-2">10</span> Robust Stability and Robust Performance</h2>
<div class="outline-text-2" id="text-10">
<p>
<a id="org888f329"></a>
In order to verify the Robust stability of the system, we can use the following equivalence:
\[ \text{RS} \Leftrightarrow \left| w_I T \right| < 1 \quad \forall \omega \]
</p>
<p>
This is shown on figure <a href="#org30bf482">20</a>.
</p>
<div id="org30bf482" class="figure">
<p><img src="figs-tikz/robust_stability.png" alt="robust_stability.png" />
</p>
<p><span class="figure-number">Figure 20: </span>Robust Stability Check: \(|w_I T| < 1, \quad \forall \omega\) (<a href="./figs/robust_stability.png">png</a>, <a href="./figs/robust_stability.pdf">pdf</a>)</p>
</div>
<p>
To check Robust Stability, we can also look at the loop gain of the uncertain system (figure <a href="#org9d9304c">21</a>) or the Nyquist plot (figure <a href="#org7fafa9d">22</a>).
</p>
<div id="org9d9304c" class="figure">
<p><img src="figs/loop_gain_robustness.png" alt="loop_gain_robustness.png" />
</p>
<p><span class="figure-number">Figure 21: </span>Loop Gain of the uncertain system (<a href="./figs/loop_gain_robustness.png">png</a>, <a href="./figs/loop_gain_robustness.pdf">pdf</a>)</p>
</div>
<div id="org7fafa9d" class="figure">
<p><img src="figs/nyquist_robustness.png" alt="nyquist_robustness.png" />
</p>
<p><span class="figure-number">Figure 22: </span>Nyquist plot of the uncertain system (<a href="./figs/nyquist_robustness.png">png</a>, <a href="./figs/nyquist_robustness.pdf">pdf</a>)</p>
</div>
<p>
The Robust Performance is verified by plotting \(|S|\) and \(|T|\) for the uncertain system along side the upper bounds defined for performance.
This is shown on figure <a href="#org01125b1">23</a> and we can indeed confirmed that the robust performance property of the system is valid.
</p>
<div id="org01125b1" class="figure">
<p><img src="figs/robust_performance_result.png" alt="robust_performance_result.png" />
</p>
<p><span class="figure-number">Figure 23: </span>Verification of the Robust Performance (<a href="./figs/robust_performance_result.png">png</a>, <a href="./figs/robust_performance_result.pdf">pdf</a>)</p>
</div>
</div>
</div>
<div id="outline-container-org81d9b1e" class="outline-2">
<h2 id="org81d9b1e"><span class="section-number-2">11</span> Pre-filter</h2>
<div class="outline-text-2" id="text-11">
<p>
<a id="org567dd40"></a>
</p>
<p>
For now, we have not specified any performance requirements on the input usage due to change of reference.
Do limit the input usage due to change of reference, we can use a pre-filter \(K_r\) as shown on figure <a href="#orgb5609b0">1</a>.
</p>
<p>
If we want a response time of 0.01 second, we can choose a first order low pass filter with a crossover frequency at \(1/0.01 = 100\ \text{Hz}\) as defined below.
</p>
<div class="org-src-container">
<pre class="src src-matlab">Kr = <span class="org-highlight-numbers-number">1</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-1">(</span><span class="org-highlight-numbers-number">1</span><span class="org-type">+</span>s<span class="org-type">/</span><span class="org-highlight-numbers-number">2</span><span class="org-type">/</span><span class="org-constant">pi</span><span class="org-type">/</span><span class="org-highlight-numbers-number">100</span><span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<p>
We then run a simulation for a step of \(1\mu m\) for the system without and with the pre-filter \(K_r\) (figure <a href="#orga9e3e93">24</a>).
This confirms that a pre-filter can be used to limit the input usage due to change of reference using this architecture.
</p>
<div class="org-src-container">
<pre class="src src-matlab">t = linspace<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-highlight-numbers-number">0</span>, <span class="org-highlight-numbers-number">0</span>.<span class="org-highlight-numbers-number">02</span>, <span class="org-highlight-numbers-number">1000</span><span class="org-rainbow-delimiters-depth-1">)</span>;
opts = stepDataOptions;
opts.StepAmplitude = <span class="org-highlight-numbers-number">1e</span><span class="org-type">-</span><span class="org-highlight-numbers-number">6</span>;
u = step<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-rainbow-delimiters-depth-2">(</span>K<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-2">(</span><span class="org-highlight-numbers-number">1</span><span class="org-type">+</span>G<span class="org-type">*</span>K<span class="org-type">*</span>Hl_hinf<span class="org-rainbow-delimiters-depth-2">)</span>, t, opts<span class="org-rainbow-delimiters-depth-1">)</span>;
uf = step<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-rainbow-delimiters-depth-2">(</span>Kr<span class="org-type">*</span>K<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-2">(</span><span class="org-highlight-numbers-number">1</span><span class="org-type">+</span>G<span class="org-type">*</span>K<span class="org-type">*</span>Hl_hinf<span class="org-rainbow-delimiters-depth-2">)</span>, t, opts<span class="org-rainbow-delimiters-depth-1">)</span>;
y = step<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-rainbow-delimiters-depth-2">(</span>K<span class="org-type">*</span>G<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-2">(</span><span class="org-highlight-numbers-number">1</span><span class="org-type">+</span>G<span class="org-type">*</span>K<span class="org-type">*</span>Hl_hinf<span class="org-rainbow-delimiters-depth-2">)</span>, t, opts<span class="org-rainbow-delimiters-depth-1">)</span>;
yf = step<span class="org-rainbow-delimiters-depth-1">(</span><span class="org-rainbow-delimiters-depth-2">(</span>Kr<span class="org-type">*</span>G<span class="org-type">*</span>K<span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-2">(</span><span class="org-highlight-numbers-number">1</span><span class="org-type">+</span>G<span class="org-type">*</span>K<span class="org-type">*</span>Hl_hinf<span class="org-rainbow-delimiters-depth-2">)</span>, t, opts<span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<div id="orga9e3e93" class="figure">
<p><img src="figs/u_and_y_with_Kr.png" alt="u_and_y_with_Kr.png" />
</p>
<p><span class="figure-number">Figure 24: </span>Input usage and response due to a step change of reference when using a pre-filter \(K_r\) (<a href="./figs/u_and_y_with_Kr.png">png</a>, <a href="./figs/u_and_y_with_Kr.pdf">pdf</a>)</p>
</div>
</div>
</div>
<div id="outline-container-org83dc39a" class="outline-2">
<h2 id="org83dc39a"><span class="section-number-2">12</span> Controller using classical techniques</h2>
<div class="outline-text-2" id="text-12">
<p>
<a id="orgdc38108"></a>
A controller is designed using <code>SISOTOOL</code> with a bandwidth of approximately \(20\ \text{Hz}\) and with two integrator.
</p>
<p>
The obtained controller is shown below.
</p>
<div class="org-src-container">
<pre class="src src-matlab">Kf = <span class="org-highlight-numbers-number">1</span>.<span class="org-highlight-numbers-number">1814e12</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-1">(</span>s<span class="org-type">+</span><span class="org-highlight-numbers-number">10</span>.<span class="org-highlight-numbers-number">15</span><span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-1">(</span>s<span class="org-type">+</span><span class="org-highlight-numbers-number">9</span>.<span class="org-highlight-numbers-number">036</span><span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-1">(</span>s<span class="org-type">+</span><span class="org-highlight-numbers-number">53</span>.<span class="org-highlight-numbers-number">8</span><span class="org-rainbow-delimiters-depth-1">)</span><span class="org-type">/</span><span class="org-rainbow-delimiters-depth-1">(</span>s<span class="org-type">^</span><span class="org-highlight-numbers-number">2</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-2">(</span>s<span class="org-type">+</span><span class="org-highlight-numbers-number">216</span>.<span class="org-highlight-numbers-number">1</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-2">(</span>s<span class="org-type">+</span><span class="org-highlight-numbers-number">1200</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-type">*</span><span class="org-rainbow-delimiters-depth-2">(</span>s<span class="org-type">+</span><span class="org-highlight-numbers-number">1864</span><span class="org-rainbow-delimiters-depth-2">)</span><span class="org-rainbow-delimiters-depth-1">)</span>;
</pre>
</div>
<div class="org-src-container">
<pre class="src src-matlab">zpk<span class="org-rainbow-delimiters-depth-1">(</span>Kf<span class="org-rainbow-delimiters-depth-1">)</span>
</pre>
</div>
<pre class="example">
zpk(Kf)
ans =
1.1814e12 (s+10.15) (s+9.036) (s+53.8)
--------------------------------------
s^2 (s+216.1) (s+1200) (s+1864)
Continuous-time zero/pole/gain model.
</pre>
<p>
The loop gain for both cases are compared on figure <a href="#org7cdee61">25</a>.
</p>
<div id="org7cdee61" class="figure">
<p><img src="figs/loop_gain_compare.png" alt="loop_gain_compare.png" />
</p>
<p><span class="figure-number">Figure 25: </span>Comparison of the Loop Gains (<a href="./figs/loop_gain_compare.png">png</a>, <a href="./figs/loop_gain_compare.pdf">pdf</a>)</p>
</div>
<p>
The Robust Stability of the system is verified using the Nyquist plot on figure <a href="#orgea02419">26</a>.
</p>
<div id="orgea02419" class="figure">
<p><img src="figs/nyquist_plot_sisotool_controller.png" alt="nyquist_plot_sisotool_controller.png" />
</p>
<p><span class="figure-number">Figure 26: </span>Nyquist Plot of the uncertain system (<a href="./figs/nyquist_plot_sisotool_controller.png">png</a>, <a href="./figs/nyquist_plot_sisotool_controller.pdf">pdf</a>)</p>
</div>
<p>
The closed loop sensitivity and complementary sensitivity transfer functions are computed.
And finally, the Robust Performance of both systems are compared on figure <a href="#orgcb82444">27</a>.
</p>
<div id="orgcb82444" class="figure">
<p><img src="figs/robust_performance_compare.png" alt="robust_performance_compare.png" />
</p>
<p><span class="figure-number">Figure 27: </span>Comparison of the Robust Performance for both controllers (<a href="./figs/robust_performance_compare.png">png</a>, <a href="./figs/robust_performance_compare.pdf">pdf</a>)</p>
</div>
</div>
</div>
</div>
<div id="postamble" class="status">
<p class="author">Author: Thomas Dehaeze</p>
<p class="date">Created: 2019-08-21 mer. 16:03</p>
<p class="validation"><a href="http://validator.w3.org/check?uri=referer">Validate</a></p>
</div>
</body>
</html>