2021-09-02 10:04:16 +02:00
% Created 2021-09-02 jeu. 10:03
2021-09-01 15:00:04 +02:00
% Intended LaTeX compiler: pdflatex
\documentclass [a4paper, 10pt, DIV=12, parskip=full] { scrreprt}
\usepackage [utf8] { inputenc}
\usepackage [T1] { fontenc}
\usepackage { graphicx}
\usepackage { grffile}
\usepackage { longtable}
\usepackage { wrapfig}
\usepackage { rotating}
\usepackage [normalem] { ulem}
\usepackage { amsmath}
\usepackage { textcomp}
\usepackage { amssymb}
\usepackage { capt-of}
\usepackage { hyperref}
\usepackage [most] { tcolorbox}
\usepackage { bm}
\usepackage { booktabs}
\usepackage { tabularx}
\usepackage { array}
\usepackage { siunitx}
\input { preamble.tex}
\addbibresource { ref.bib}
\author { Dehaeze Thomas}
\date { \today }
2021-09-02 10:04:16 +02:00
\title { Designing Complementary filters for sensor fusion using \( \mathcal { H } _ \infty \) synthesis - Matlab Computation}
2021-09-01 15:00:04 +02:00
\begin { document}
\maketitle
\tableofcontents
\clearpage
The present document is a companion file for the journal paper \cite { dehaeze21_ new_ method_ desig_ compl_ filter} .
All the Matlab \cite { matlab20} scripts used in the paper are here shared and explained.
This document is divided into the following sections also corresponding to the paper sections:
\begin { itemize}
\item Section \ref { sec:h_ inf_ synthesis_ complementary_ filters} : the shaping of complementary filters is written as an \( \mathcal { H } _ \infty \) optimization problem using weighting functions. The weighting function design is discussed and the method is applied for the design of a set of simple complementary filters.
\item Section \ref { sec:comp_ filters_ ligo} : the effectiveness of the proposed complementary filter synthesis strategy is demonstrated by designing complex complementary filters used in the first isolation stage at the LIGO
\item Section \ref { sec:closed_ loop_ complementary_ filters} : complementary filters are designed using the classical feedback loop
\item Section \ref { sec:three_ comp_ filters} : the proposed design method is generalized for the design of a set of three complementary filters
\item Section \ref { sec:matlab_ scripts} : complete Matlab scripts and functions developed are listed
\end { itemize}
\chapter { H-Infinity synthesis of complementary filters}
\label { sec:h_ inf_ synthesis_ complementary_ filters}
\section { Synthesis Architecture}
In order to generate two complementary filters with a wanted shape, the generalized plant of Figure \ref { fig:h_ infinity_ robust_ fusion_ plant} can be used.
The included weights \( W _ 1 ( s ) \) and \( W _ 2 ( s ) \) are used to specify the upper bounds of the complementary filters being generated.
\begin { figure} [htbp]
\centering
\includegraphics [scale=1] { figs-journal/h_ infinity_ robust_ fusion_ plant.png}
\caption { \label { fig:h_ infinity_ robust_ fusion_ plant} Generalized plant used for the \( \mathcal { H } _ \infty \) synthesis of a set of two complementary fiters}
\end { figure}
Applied the standard \( \mathcal { H } _ \infty \) synthesis on this generalized plant will give a transfer function \( H _ 2 ( s ) \) (see Figure \ref { fig:h_ infinity_ robust_ fusion_ fb} ) such that the \( \mathcal { H } _ \infty \) norm of the transfer function from \( w \) to \( [ z _ 1 , \ z _ 2 ] \) is less than one \eqref { eq:h_ inf_ objective} .
\begin { figure} [htbp]
\centering
\includegraphics [scale=1] { figs-journal/h_ infinity_ robust_ fusion_ fb.png}
\caption { \label { fig:h_ infinity_ robust_ fusion_ fb} Generalized plant with the synthesized filter obtained after the \( \mathcal { H } _ \infty \) synthesis}
\end { figure}
\begin { equation}
\left \| \begin { array} { c} (1 - H_ 2(s)) W_ 1(s) \\ H_ 2(s) W_ 2(s) \end { array} \right \| _ \infty < 1 \label { eq:h_ inf_ objective}
\end { equation}
Thus, if the synthesis is successful and the above condition is verified, we can define \( H _ 1 ( s ) \) to be the complementary of \( H _ 2 ( s ) \) \eqref { eq:H1_ complementary_ of_ H2} and we have condition \eqref { eq:shaping_ comp_ filters} verified.
\begin { equation}
H_ 1(s) = 1 - H_ 2(s) \label { eq:H1_ complementary_ of_ H2}
\end { equation}
\begin { equation}
\left \| \begin { array} { c} H_ 1(s) W_ 1(s) \\ H_ 2(s) W_ 2(s) \end { array} \right \| _ \infty < 1
\quad \Longrightarrow \quad
\left \{
\begin { array} { c}
|H_ 1(j\omega )| < \frac { 1} { |W_ 1(j\omega )|} , \quad \forall \omega \\
|H_ 2(j\omega )| < \frac { 1} { |W_ 2(j\omega )|} , \quad \forall \omega
\end { array}
\right . \label { eq:shaping_ comp_ filters}
\end { equation}
We then see that \( W _ 1 ( s ) \) and \( W _ 2 ( s ) \) can be used to set the wanted upper bounds of the magnitudes of both \( H _ 1 ( s ) \) and \( H _ 2 ( s ) \) .
The presented synthesis method therefore allows to shape two filters \( H _ 1 ( s ) \) and \( H _ 2 ( s ) \) \eqref { eq:shaping_ comp_ filters} while ensuring their complementary property \eqref { eq:H1_ complementary_ of_ H2} .
The complete Matlab script for this part is given in Section \ref { sec:1_ synthesis_ complementary_ filters} .
\section { Design of Weighting Function - Proposed formula}
A formula is proposed to help the design of the weighting functions:
\begin { equation}
W(s) = \left ( \frac {
\frac { 1} { \omega _ 0} \sqrt { \frac { 1 - \left (\frac { G_ 0} { G_ c} \right )^ { \frac { 2} { n} } } { 1 - \left (\frac { G_ c} { G_ \infty } \right )^ { \frac { 2} { n} } } } s + \left (\frac { G_ 0} { G_ c} \right )^ { \frac { 1} { n} }
} {
\left (\frac { 1} { G_ \infty } \right )^ { \frac { 1} { n} } \frac { 1} { \omega _ 0} \sqrt { \frac { 1 - \left (\frac { G_ 0} { G_ c} \right )^ { \frac { 2} { n} } } { 1 - \left (\frac { G_ c} { G_ \infty } \right )^ { \frac { 2} { n} } } } s + \left (\frac { 1} { G_ c} \right )^ { \frac { 1} { n} }
} \right )^ n \label { eq:weighting_ function_ formula}
\end { equation}
The parameters permits to specify:
\begin { itemize}
\item the low frequency gain: \( G _ 0 = lim _ { \omega \to 0 } |W ( j \omega ) | \)
\item the high frequency gain: \( G _ \infty = lim _ { \omega \to \infty } |W ( j \omega ) | \)
\item the absolute gain at \( \omega _ 0 \) : \( G _ c = |W ( j \omega _ 0 ) | \)
\item the absolute slope between high and low frequency: \( n \)
\end { itemize}
The general shape of a weighting function generated using the formula is shown in figure \ref { fig:weight_ formula} .
\begin { figure} [htbp]
\centering
\includegraphics [scale=1] { figs/weight_ formula.png}
\caption { \label { fig:weight_ formula} Magnitude of the weighting function generated using formula \eqref { eq:weighting_ function_ formula} }
\end { figure}
\section { Weighting functions for the design of two complementary filters}
\label { sec:weighting_ functions_ example}
The weighting function formula \eqref { eq:weighting_ function_ formula} is used to generate the upper bounds of two complementary filters that we wish to design.
The matlab function \texttt { generateWF} is described in Section \ref { sec:generateWF} .
\begin { minted} []{ matlab}
%% Design of the Weighting Functions
W1 = generateWF('n', 3, 'w0', 2*pi*10, 'G0', 1000, 'Ginf', 1/10, 'Gc', 0.45);
W2 = generateWF('n', 2, 'w0', 2*pi*10, 'G0', 1/10, 'Ginf', 1000, 'Gc', 0.45);
\end { minted}
The inverse magnitude of these two weighting functions are shown in Figure \ref { fig:weights_ W1_ W2} .
\begin { figure} [htbp]
\centering
\includegraphics [scale=1] { figs/weights_ W1_ W2.png}
\caption { \label { fig:weights_ W1_ W2} Inverse magnitude of the design weighting functions}
\end { figure}
\section { Synthesis of the complementary filters}
The generalized plant of Figure \ref { fig:h_ infinity_ robust_ fusion_ plant} is defined as follows:
\begin { minted} []{ matlab}
%% Generalized Plant
P = [W1 -W1;
0 W2;
1 0];
\end { minted}
And the \( \mathcal { H } _ \infty \) synthesis is performed using the \texttt { hinfsyn} command.
\begin { minted} []{ matlab}
%% H-Infinity Synthesis
[H2, ~, gamma, ~] = hinfsyn(P, 1, 1,'TOLGAM', 0.001, 'METHOD', 'ric', 'DISPLAY', 'on');
\end { minted}
\begin { verbatim}
[H2, ~, gamma, ~] = hinfsyn(P, 1, 1,'TOLGAM', 0.001, 'METHOD', 'ric', 'DISPLAY', 'on');
Test bounds: 0.3223 <= gamma <= 1000
gamma X>=0 Y>=0 rho(XY)<1 p/f
1.795e+01 1.4e-07 0.0e+00 1.481e-16 p
2.406e+00 1.4e-07 0.0e+00 3.604e-15 p
8.806e-01 -3.1e+02 # -1.4e-16 7.370e-19 f
1.456e+00 1.4e-07 0.0e+00 1.499e-18 p
1.132e+00 1.4e-07 0.0e+00 8.587e-15 p
9.985e-01 1.4e-07 0.0e+00 2.331e-13 p
9.377e-01 -7.7e+02 # -6.6e-17 3.744e-14 f
9.676e-01 -2.0e+03 # -5.7e-17 1.046e-13 f
9.829e-01 -6.6e+03 # -1.1e-16 2.949e-13 f
9.907e-01 1.4e-07 0.0e+00 2.374e-19 p
9.868e-01 -1.6e+04 # -6.4e-17 5.331e-14 f
9.887e-01 -5.1e+04 # -1.5e-17 2.703e-19 f
9.897e-01 1.4e-07 0.0e+00 1.583e-11 p
Limiting gains...
9.897e-01 1.5e-07 0.0e+00 1.183e-12 p
9.897e-01 6.9e-07 0.0e+00 1.365e-12 p
Best performance (actual): 0.9897
\end { verbatim}
As shown above, the obtained \( \mathcal { H } _ \infty \) norm of the transfer function from \( w \) to \( [ z _ 1 , \ z _ 2 ] \) is found to be less than one meaning the synthesis is successful.
We then define the filter \( H _ 1 ( s ) \) to be the complementary of \( H _ 2 ( s ) \) \eqref { eq:H1_ complementary_ of_ H2} .
\begin { minted} []{ matlab}
%% Define H1 to be the complementary of H2
H1 = 1 - H2;
\end { minted}
The function \texttt { generateCF} can also be used to synthesize the complementary filters.
This function is described in Section \ref { sec:generateCF} .
\begin { minted} []{ matlab}
[H1, H2] = generateCF(W1, W2);
\end { minted}
\section { Obtained Complementary Filters}
The obtained complementary filters are shown below and are found to be of order 5.
Their bode plots are shown in figure \ref { fig:hinf_ filters_ results} and compare with the defined upper bounds.
\begin { verbatim}
zpk(H1)
ans =
(s+1.289e05) (s+153.6) (s+3.842)^ 3
-------------------------------------------------------
(s+1.29e05) (s^ 2 + 102.1s + 2733) (s^ 2 + 69.45s + 3272)
zpk(H2)
ans =
125.61 (s+3358)^ 2 (s^ 2 + 46.61s + 813.8)
-------------------------------------------------------
(s+1.29e05) (s^ 2 + 102.1s + 2733) (s^ 2 + 69.45s + 3272)
\end { verbatim}
\begin { figure} [htbp]
\centering
\includegraphics [scale=1] { figs/hinf_ filters_ results.png}
\caption { \label { fig:hinf_ filters_ results} Obtained complementary filters using \( \mathcal { H } _ \infty \) synthesis}
\end { figure}
\chapter { Design of complementary filters used in the Active Vibration Isolation System at the LIGO}
\label { sec:comp_ filters_ ligo}
In this section, the proposed method for the design of complementary filters is validated for the design of a set of two complex complementary filters used for the first isolation stage at the LIGO \cite { hua04_ low_ ligo} .
The complete Matlab script for this part is given in Section \ref { sec:2_ ligo_ complementary_ filters} .
\section { Specifications}
The specifications for the set of complementary filters (\( L _ 1 ,H _ 1 \) ) used at the LIGO are summarized below (for further details, refer to \cite { hua04_ polyp_ fir_ compl_ filter_ contr_ system} ):
\begin { itemize}
\item From 0 to 0.008 Hz, the magnitude \( |L _ 1 ( j \omega ) | \) should be less or equal to \( 8 \times 10 ^ { - 4 } \)
\item Between 0.008 Hz to 0.04 Hz, the filter \( L _ 1 ( s ) \) should attenuate the input signal proportional to frequency cubed
\item Between 0.04 Hz to 0.1 Hz, the magnitude \( |L _ 1 ( j \omega ) | \) should be less than \( 3 \)
\item Above 0.1 Hz, the magnitude \( |H _ 1 ( j \omega ) | \) should be less than \( 0 . 045 \)
\end { itemize}
The specifications are translated into upper bounds of the complementary filters and are shown in Figure \ref { fig:ligo_ specifications} .
\begin { figure} [htbp]
\centering
\includegraphics [scale=1] { figs/ligo_ specifications.png}
\caption { \label { fig:ligo_ specifications} Specification for the LIGO complementary filters}
\end { figure}
\section { FIR Filter}
To replicated the complementary filters developed in \cite { hua04_ low_ ligo} , the CVX Matlab toolbox \cite { grant14_ cvx} is used.
The CVX toolbox is initialized and the \texttt { SeDuMi} solver \cite { sturm99_ using_ sedum} is used.
\begin { minted} []{ matlab}
%% Initialized CVX
cvx_ startup;
cvx_ solver sedumi;
\end { minted}
We define the frequency vectors on which we will constrain the norm of the FIR filter.
\begin { minted} []{ matlab}
%% Frequency vectors
w1 = 0:4.06e-4:0.008;
w2 = 0.008:4.06e-4:0.04;
w3 = 0.04:8.12e-4:0.1;
w4 = 0.1:8.12e-4:0.83;
\end { minted}
The order \( n \) of the FIR filter is defined.
\begin { minted} []{ matlab}
%% Filter order
n = 512;
\end { minted}
\begin { minted} []{ matlab}
%% Initialization of filter responses
A1 = [ones(length(w1),1), cos(kron(w1'.*(2*pi),[1:n-1]))];
A2 = [ones(length(w2),1), cos(kron(w2'.*(2*pi),[1:n-1]))];
A3 = [ones(length(w3),1), cos(kron(w3'.*(2*pi),[1:n-1]))];
A4 = [ones(length(w4),1), cos(kron(w4'.*(2*pi),[1:n-1]))];
B1 = [zeros(length(w1),1), sin(kron(w1'.*(2*pi),[1:n-1]))];
B2 = [zeros(length(w2),1), sin(kron(w2'.*(2*pi),[1:n-1]))];
B3 = [zeros(length(w3),1), sin(kron(w3'.*(2*pi),[1:n-1]))];
B4 = [zeros(length(w4),1), sin(kron(w4'.*(2*pi),[1:n-1]))];
\end { minted}
And the convex optimization is run.
\begin { minted} []{ matlab}
%% Convex optimization
cvx_ begin
variable y(n+1,1)
% t
maximize(-y(1))
for i = 1:length(w1)
norm([0 A1(i,:); 0 B1(i,:)]*y) <= 8e-3;
end
for i = 1:length(w2)
norm([0 A2(i,:); 0 B2(i,:)]*y) <= 8e-3*(2*pi*w2(i)/(0.008*2*pi))^ 3;
end
for i = 1:length(w3)
norm([0 A3(i,:); 0 B3(i,:)]*y) <= 3;
end
for i = 1:length(w4)
norm([[1 0]'- [0 A4(i,:); 0 B4(i,:)]*y]) <= y(1);
end
cvx_ end
h = y(2:end);
\end { minted}
\begin { verbatim}
cvx_ begin
variable y(n+1,1)
% t
maximize(-y(1))
for i = 1:length(w1)
norm([0 A1(i,:); 0 B1(i,:)]*y) <= 8e-3;
end
for i = 1:length(w2)
norm([0 A2(i,:); 0 B2(i,:)]*y) <= 8e-3*(2*pi*w2(i)/(0.008*2*pi))^ 3;
end
for i = 1:length(w3)
norm([0 A3(i,:); 0 B3(i,:)]*y) <= 3;
end
for i = 1:length(w4)
norm([[1 0]'- [0 A4(i,:); 0 B4(i,:)]*y]) <= y(1);
end
cvx_ end
Calling SeDuMi 1.34: 4291 variables, 1586 equality constraints
For improved efficiency, SeDuMi is solving the dual problem.
------------------------------------------------------------
SeDuMi 1.34 (beta) by AdvOL, 2005-2008 and Jos F. Sturm, 1998-2003.
Alg = 2: xz-corrector, Adaptive Step-Differentiation, theta = 0.250, beta = 0.500
eqs m = 1586, order n = 3220, dim = 4292, blocks = 1073
nnz(A) = 1100727 + 0, nnz(ADA) = 1364794, nnz(L) = 683190
it : b*y gap delta rate t/tP* t/tD* feas cg cg prec
0 : 4.11E+02 0.000
1 : -2.58E+00 1.25E+02 0.000 0.3049 0.9000 0.9000 4.87 1 1 3.0E+02
2 : -2.36E+00 3.90E+01 0.000 0.3118 0.9000 0.9000 1.83 1 1 6.6E+01
3 : -1.69E+00 1.31E+01 0.000 0.3354 0.9000 0.9000 1.76 1 1 1.5E+01
4 : -8.60E-01 7.10E+00 0.000 0.5424 0.9000 0.9000 2.48 1 1 4.8E+00
5 : -4.91E-01 5.44E+00 0.000 0.7661 0.9000 0.9000 3.12 1 1 2.5E+00
6 : -2.96E-01 3.88E+00 0.000 0.7140 0.9000 0.9000 2.62 1 1 1.4E+00
7 : -1.98E-01 2.82E+00 0.000 0.7271 0.9000 0.9000 2.14 1 1 8.5E-01
8 : -1.39E-01 2.00E+00 0.000 0.7092 0.9000 0.9000 1.78 1 1 5.4E-01
9 : -9.99E-02 1.30E+00 0.000 0.6494 0.9000 0.9000 1.51 1 1 3.3E-01
10 : -7.57E-02 8.03E-01 0.000 0.6175 0.9000 0.9000 1.31 1 1 2.0E-01
11 : -5.99E-02 4.22E-01 0.000 0.5257 0.9000 0.9000 1.17 1 1 1.0E-01
12 : -5.28E-02 2.45E-01 0.000 0.5808 0.9000 0.9000 1.08 1 1 5.9E-02
13 : -4.82E-02 1.28E-01 0.000 0.5218 0.9000 0.9000 1.05 1 1 3.1E-02
14 : -4.56E-02 5.65E-02 0.000 0.4417 0.9045 0.9000 1.02 1 1 1.4E-02
15 : -4.43E-02 2.41E-02 0.000 0.4265 0.9004 0.9000 1.01 1 1 6.0E-03
16 : -4.37E-02 8.90E-03 0.000 0.3690 0.9070 0.9000 1.00 1 1 2.3E-03
17 : -4.35E-02 3.24E-03 0.000 0.3641 0.9164 0.9000 1.00 1 1 9.5E-04
18 : -4.34E-02 1.55E-03 0.000 0.4788 0.9086 0.9000 1.00 1 1 4.7E-04
19 : -4.34E-02 8.77E-04 0.000 0.5653 0.9169 0.9000 1.00 1 1 2.8E-04
20 : -4.34E-02 5.05E-04 0.000 0.5754 0.9034 0.9000 1.00 1 1 1.6E-04
21 : -4.34E-02 2.94E-04 0.000 0.5829 0.9136 0.9000 1.00 1 1 9.9E-05
22 : -4.34E-02 1.63E-04 0.015 0.5548 0.9000 0.0000 1.00 1 1 6.6E-05
23 : -4.33E-02 9.42E-05 0.000 0.5774 0.9053 0.9000 1.00 1 1 3.9E-05
24 : -4.33E-02 6.27E-05 0.000 0.6658 0.9148 0.9000 1.00 1 1 2.6E-05
25 : -4.33E-02 3.75E-05 0.000 0.5972 0.9187 0.9000 1.00 1 1 1.6E-05
26 : -4.33E-02 1.89E-05 0.000 0.5041 0.9117 0.9000 1.00 1 1 8.6E-06
27 : -4.33E-02 9.72E-06 0.000 0.5149 0.9050 0.9000 1.00 1 1 4.5E-06
28 : -4.33E-02 2.94E-06 0.000 0.3021 0.9194 0.9000 1.00 1 1 1.5E-06
29 : -4.33E-02 9.73E-07 0.000 0.3312 0.9189 0.9000 1.00 2 2 5.3E-07
30 : -4.33E-02 2.82E-07 0.000 0.2895 0.9063 0.9000 1.00 2 2 1.6E-07
31 : -4.33E-02 8.05E-08 0.000 0.2859 0.9049 0.9000 1.00 2 2 4.7E-08
32 : -4.33E-02 1.43E-08 0.000 0.1772 0.9059 0.9000 1.00 2 2 8.8E-09
iter seconds digits c*x b*y
32 49.4 6.8 -4.3334083581e-02 -4.3334090214e-02
|Ax-b| = 3.7e-09, [Ay-c]_ + = 1.1E-10, |x|= 1.0e+00, |y|= 2.6e+00
Detailed timing (sec)
Pre IPM Post
3.902E+00 4.576E+01 1.035E-02
Max-norms: ||b||=1, ||c|| = 3,
Cholesky |add|=0, |skip| = 0, ||L.L|| = 4.26267.
------------------------------------------------------------
Status: Solved
Optimal value (cvx_ optval): -0.0433341
h = y(2:end);
\end { verbatim}
Finally, the filter response is computed over the frequency vector defined and the result is shown on figure \ref { fig:fir_ filter_ ligo} which is very close to the filters obtain in \cite { hua04_ low_ ligo} .
\begin { minted} []{ matlab}
%% Combine the frequency vectors to form the obtained filter
w = [w1 w2 w3 w4];
H = [exp(-j*kron(w'.*2*pi,[0:n-1]))]*h;
\end { minted}
\begin { figure} [htbp]
\centering
\includegraphics [scale=1] { figs/fir_ filter_ ligo.png}
\caption { \label { fig:fir_ filter_ ligo} FIR Complementary filters obtain after convex optimization}
\end { figure}
\section { Weighting function design}
The weightings function that will be used for the \( \mathcal { H } _ \infty \) synthesis of the complementary filters are now designed.
These weights will determine the order of the obtained filters.
Here are the requirements on the filters:
\begin { itemize}
\item reasonable order
\item to be as close as possible to the specified upper bounds
\item stable and minimum phase
\end { itemize}
The weighting function for the High Pass filter is defined as follows:
\begin { minted} []{ matlab}
%% Design of the weight for the high pass filter
w1 = 2*pi*0.008; x1 = 0.35;
w2 = 2*pi*0.04; x2 = 0.5;
w3 = 2*pi*0.05; x3 = 0.5;
% Slope of +3 from w1
wH = 0.008*(s^ 2/w1^ 2 + 2*x1/w1*s + 1)*(s/w1 + 1);
% Little bump from w2 to w3
wH = wH*(s^ 2/w2^ 2 + 2*x2/w2*s + 1)/(s^ 2/w3^ 2 + 2*x3/w3*s + 1);
% No Slope at high frequencies
wH = wH/(s^ 2/w3^ 2 + 2*x3/w3*s + 1)/(s/w3 + 1);
% Little bump between w2 and w3
w0 = 2*pi*0.045; xi = 0.1; A = 2; n = 1;
wH = wH*((s^ 2 + 2*w0*xi*A^ (1/n)*s + w0^ 2)/(s^ 2 + 2*w0*xi*s + w0^ 2))^ n;
wH = 1/wH;
wH = minreal(ss(wH));
\end { minted}
And the weighting function for the Low pass filter is taken as a Chebyshev Type I filter.
\begin { minted} []{ matlab}
%% Design of the weight for the low pass filter
n = 20; % Filter order
Rp = 1; % Peak to peak passband ripple
Wp = 2*pi*0.102; % Edge frequency
% Chebyshev Type I filter design
[b,a] = cheby1(n, Rp, Wp, 'high', 's');
wL = 0.04*tf(a, b);
wL = 1/wL;
wL = minreal(ss(wL));
\end { minted}
The inverse magnitude of the weighting functions are shown in Figure \ref { fig:ligo_ weights} .
\begin { figure} [htbp]
\centering
\includegraphics [scale=1] { figs/ligo_ weights.png}
\caption { \label { fig:ligo_ weights} Weights for the \( \mathcal { H } _ \infty \) synthesis}
\end { figure}
\section { Synthesis of the complementary filters}
The generalized plant of figure \ref { fig:h_ infinity_ robust_ fusion_ plant} is defined.
\begin { minted} []{ matlab}
%% Generalized plant for the H-infinity Synthesis
P = [0 wL;
wH -wH;
1 0];
\end { minted}
And the standard \( \mathcal { H } _ \infty \) synthesis using the \texttt { hinfsyn} command is performed.
\begin { minted} []{ matlab}
%% Standard H-Infinity synthesis
[Hl, ~, gamma, ~] = hinfsyn(P, 1, 1,'TOLGAM', 0.001, 'METHOD', 'ric', 'DISPLAY', 'on');
\end { minted}
\begin { verbatim}
[Hl, ~, gamma, ~] = hinfsyn(P, 1, 1,'TOLGAM', 0.001, 'METHOD', 'ric', 'DISPLAY', 'on');
Resetting value of Gamma min based on D_ 11, D_ 12, D_ 21 terms
Test bounds: 0.3276 < gamma <= 1.8063
gamma hamx_ eig xinf_ eig hamy_ eig yinf_ eig nrho_ xy p/f
1.806 1.4e-02 -1.7e-16 3.6e-03 -4.8e-12 0.0000 p
1.067 1.3e-02 -4.2e-14 3.6e-03 -1.9e-12 0.0000 p
0.697 1.3e-02 -3.0e-01# 3.6e-03 -3.5e-11 0.0000 f
0.882 1.3e-02 -9.5e-01# 3.6e-03 -1.2e-34 0.0000 f
0.975 1.3e-02 -2.7e+00# 3.6e-03 -1.6e-12 0.0000 f
1.021 1.3e-02 -8.7e+00# 3.6e-03 -4.5e-16 0.0000 f
1.044 1.3e-02 -6.5e-14 3.6e-03 -3.0e-15 0.0000 p
1.032 1.3e-02 -1.8e+01# 3.6e-03 0.0e+00 0.0000 f
1.038 1.3e-02 -3.8e+01# 3.6e-03 0.0e+00 0.0000 f
1.041 1.3e-02 -8.3e+01# 3.6e-03 -2.9e-33 0.0000 f
1.042 1.3e-02 -1.9e+02# 3.6e-03 -3.4e-11 0.0000 f
1.043 1.3e-02 -5.3e+02# 3.6e-03 -7.5e-13 0.0000 f
Gamma value achieved: 1.0439
\end { verbatim}
The obtained \( \mathcal { H } _ \infty \) norm is found to be close than one meaning the synthesis is successful.
The high pass filter \( H _ H ( s ) \) is defined to be the complementary of the synthesized low pass filter \( H _ L ( s ) \) :
\begin { equation}
H_ H(s) = 1 - H_ L(s)
\end { equation}
\begin { minted} []{ matlab}
%% High pass filter as the complementary of the low pass filter
Hh = 1 - Hl;
\end { minted}
The size of the filters is shown to be equal to the sum of the weighting functions orders.
\begin { verbatim}
size(Hh), size(Hl)
State-space model with 1 outputs, 1 inputs, and 27 states.
State-space model with 1 outputs, 1 inputs, and 27 states.
\end { verbatim}
The magnitude of the obtained filters as well as the requirements are shown in Figure \ref { fig:hinf_ synthesis_ ligo_ results} .
\begin { figure} [htbp]
\centering
\includegraphics [scale=1] { figs/hinf_ synthesis_ ligo_ results.png}
\caption { \label { fig:hinf_ synthesis_ ligo_ results} Obtained complementary filters using the \( \mathcal { H } _ \infty \) synthesis}
\end { figure}
\section { Comparison of the FIR filters and synthesized filters}
Let's now compare the FIR filters designed in \cite { hua04_ low_ ligo} with the with complementary filters obtained with the \( \mathcal { H } _ \infty \) synthesis.
This is done in Figure \ref { fig:comp_ fir_ ligo_ hinf} , and both set of filters are found to be very close to each other.
\begin { figure} [htbp]
\centering
\includegraphics [scale=1] { figs/comp_ fir_ ligo_ hinf.png}
\caption { \label { fig:comp_ fir_ ligo_ hinf} Comparison between the FIR filters developped for LIGO and the \( \mathcal { H } _ \infty \) complementary filters}
\end { figure}
\chapter { ``Closed-Loop'' complementary filters}
\label { sec:closed_ loop_ complementary_ filters}
In this section, the classical feedback architecture shown in Figure \ref { fig:feedback_ sensor_ fusion} is used for the design of complementary filters.
\begin { figure} [htbp]
\centering
\includegraphics [scale=1] { figs-journal/feedback_ sensor_ fusion.png}
\caption { \label { fig:feedback_ sensor_ fusion} ``Closed-Loop'' complementary filters}
\end { figure}
The complete Matlab script for this part is given in Section \ref { sec:3_ closed_ loop_ complementary_ filters} .
\section { Weighting Function design}
Weighting functions using the \texttt { generateWF} Matlab function are designed to specify the upper bounds of the complementary filters to be designed.
These weighting functions are the same as the ones used in Section \ref { sec:weighting_ functions_ example} .
\begin { minted} []{ matlab}
%% Design of the Weighting Functions
W1 = generateWF('n', 3, 'w0', 2*pi*10, 'G0', 1000, 'Ginf', 1/10, 'Gc', 0.45);
W2 = generateWF('n', 2, 'w0', 2*pi*10, 'G0', 1/10, 'Ginf', 1000, 'Gc', 0.45);
\end { minted}
\section { Generalized plant}
The generalized plant of Figure \ref { fig:feedback_ synthesis_ architecture_ generalized_ plant} is defined below:
\begin { minted} []{ matlab}
%% Generalized plant for "closed-loop" complementary filter synthesis
P = [ W1 0 1;
-W1 W2 -1];
\end { minted}
\begin { figure} [htbp]
\centering
\includegraphics [scale=1] { figs-journal/feedback_ synthesis_ architecture_ generalized_ plant.png}
\caption { \label { fig:feedback_ synthesis_ architecture_ generalized_ plant} Generalized plant used for the \( \mathcal { H } _ \infty \) synthesis of ``closed-loop'' complementary filters}
\end { figure}
\section { Synthesis of the closed-loop complementary filters}
And the standard \( \mathcal { H } _ \infty \) synthesis is performed.
\begin { minted} []{ matlab}
%% Standard H-Infinity Synthesis
[L, ~, gamma, ~] = hinfsyn(P, 1, 1,'TOLGAM', 0.001, 'METHOD', 'ric', 'DISPLAY', 'on');
\end { minted}
\begin { verbatim}
Test bounds: 0.3191 <= gamma <= 1.669
gamma X>=0 Y>=0 rho(XY)<1 p/f
7.299e-01 -1.5e-19 -2.4e+01 # 1.555e-18 f
1.104e+00 0.0e+00 1.6e-07 2.037e-19 p
8.976e-01 -3.2e-16 -1.4e+02 # 5.561e-16 f
9.954e-01 0.0e+00 1.6e-07 1.041e-15 p
9.452e-01 -1.1e-15 -3.8e+02 # 4.267e-15 f
9.700e-01 -6.5e-16 -1.6e+03 # 9.876e-15 f
9.826e-01 0.0e+00 1.6e-07 8.775e-39 p
9.763e-01 -5.0e-16 -6.2e+03 # 3.519e-14 f
9.795e-01 0.0e+00 1.6e-07 6.971e-20 p
9.779e-01 -1.9e-31 -2.2e+04 # 5.600e-18 f
9.787e-01 0.0e+00 1.6e-07 5.546e-19 p
Limiting gains...
9.789e-01 0.0e+00 1.6e-07 1.084e-13 p
9.789e-01 0.0e+00 9.7e-07 1.137e-13 p
Best performance (actual): 0.9789
\end { verbatim}
\section { Synthesized filters}
The obtained filter \( L ( s ) \) can then be included in the feedback architecture shown in Figure \ref { fig:hinf_ filters_ results_ mixed_ sensitivity} .
The closed-loop transfer functions from \( \hat { x } _ 1 \) to \( \hat { x } \) and from \( \hat { x } _ 2 \) to \( \hat { x } \) corresponding respectively to the sensitivity and complementary sensitivity transfer functions are defined below:
\begin { minted} []{ matlab}
%% Complementary filters
H1 = inv(1 + L);
H2 = 1 - H1;
\end { minted}
\begin { verbatim}
zpk(H1) =
(s+3.842)^ 3 (s+153.6) (s+1.289e05)
-------------------------------------------------------
(s+1.29e05) (s^ 2 + 102.1s + 2733) (s^ 2 + 69.45s + 3272)
zpk(H2) =
125.61 (s+3358)^ 2 (s^ 2 + 46.61s + 813.8)
-------------------------------------------------------
(s+1.29e05) (s^ 2 + 102.1s + 2733) (s^ 2 + 69.45s + 3272)
\end { verbatim}
The bode plots of the synthesized complementary filters are compared with the upper bounds in Figure \ref { fig:hinf_ filters_ results_ mixed_ sensitivity} .
\begin { figure} [htbp]
\centering
\includegraphics [scale=1] { figs/hinf_ filters_ results_ mixed_ sensitivity.png}
\caption { \label { fig:hinf_ filters_ results_ mixed_ sensitivity} Bode plot of the obtained complementary filters}
\end { figure}
\chapter { Synthesis of three complementary filters}
\label { sec:three_ comp_ filters}
In this section, the proposed synthesis method of complementary filters is generalized for the synthesis of a set of three complementary filters.
The complete Matlab script for this part is given in Section \ref { sec:4_ three_ complementary_ filters} .
\section { Synthesis Architecture}
The synthesis objective is to shape three filters that are complementary.
This corresponds to the conditions \eqref { eq:obj_ three_ cf} where \( W _ 1 ( s ) \) , \( W _ 2 ( s ) \) and \( W _ 3 ( s ) \) are weighting functions used to specify the maximum wanted magnitude of the three complementary filters.
\begin { equation}
\begin { aligned}
& |H_ 1(j\omega )| < \frac { 1} { |W_ 1(j\omega )|} , \quad \forall \omega \\
& |H_ 2(j\omega )| < \frac { 1} { |W_ 2(j\omega )|} , \quad \forall \omega \\
& |H_ 3(j\omega )| < \frac { 1} { |W_ 3(j\omega )|} , \quad \forall \omega \\
& H_ 1(s) + H_ 2(s) + H_ 3(s) = 1
\end { aligned} \label { eq:obj_ three_ cf}
\end { equation}
This synthesis can be done by performing the standard \( \mathcal { H } _ \infty \) synthesis with on the generalized plant in Figure \ref { fig:comp_ filter_ three_ hinf} .
\begin { figure} [htbp]
\centering
\includegraphics [scale=1] { figs-journal/comp_ filter_ three_ hinf_ fb.png}
\caption { \label { fig:comp_ filter_ three_ hinf} Generalized architecture for generating 3 complementary filters}
\end { figure}
After synthesis, filter \( H _ 2 ( s ) \) and \( H _ 3 ( s ) \) are obtained as shown in Figure \ref { fig:comp_ filter_ three_ hinf} .
The last filter \( H _ 1 ( s ) \) is defined as the complementary of the two others as in \eqref { eq:H1_ complementary_ of_ H2_ H3} .
\begin { equation}
H_ 1(s) = 1 - H_ 2(s) - H_ 3(s) \label { eq:H1_ complementary_ of_ H2_ H3}
\end { equation}
\section { Weights}
The three weighting functions are defined as shown below.
\begin { minted} []{ matlab}
%% Design of the Weighting Functions
W1 = generateWF('n', 2, 'w0', 2*pi*1, 'G0', 1/10, 'Ginf', 1000, 'Gc', 0.5);
W2 = 0.22*(1 + s/2/pi/1)^ 2/(sqrt(1e-4) + s/2/pi/1)^ 2*(1 + s/2/pi/10)^ 2/(1 + s/2/pi/1000)^ 2;
W3 = generateWF('n', 3, 'w0', 2*pi*10, 'G0', 1000, 'Ginf', 1/10, 'Gc', 0.5);
\end { minted}
Their inverse magnitudes are displayed in Figure \ref { fig:three_ weighting_ functions} .
\begin { figure} [htbp]
\centering
\includegraphics [scale=1] { figs/three_ weighting_ functions.png}
\caption { \label { fig:three_ weighting_ functions} Three weighting functions used for the \( \mathcal { H } _ \infty \) synthesis of the complementary filters}
\end { figure}
\section { H-Infinity Synthesis}
The generalized plant in Figure \ref { fig:comp_ filter_ three_ hinf} containing the weighting functions is defined below.
\begin { minted} []{ matlab}
%% Generalized plant for the synthesis of 3 complementary filters
P = [W1 -W1 -W1;
0 W2 0 ;
0 0 W3;
1 0 0];
\end { minted}
And the standard \( \mathcal { H } _ \infty \) synthesis using the \texttt { hinfsyn} command is performed.
\begin { minted} []{ matlab}
%% Standard H-Infinity Synthesis
[H, ~, gamma, ~] = hinfsyn(P, 1, 2,'TOLGAM', 0.001, 'METHOD', 'ric', 'DISPLAY', 'on');
\end { minted}
\begin { verbatim}
Resetting value of Gamma min based on D_ 11, D_ 12, D_ 21 terms
Test bounds: 0.1000 < gamma <= 1050.0000
gamma hamx_ eig xinf_ eig hamy_ eig yinf_ eig nrho_ xy p/f
1.050e+03 3.2e+00 4.5e-13 6.3e-02 -1.2e-11 0.0000 p
525.050 3.2e+00 1.3e-13 6.3e-02 0.0e+00 0.0000 p
262.575 3.2e+00 2.1e-12 6.3e-02 -1.5e-13 0.0000 p
131.337 3.2e+00 1.1e-12 6.3e-02 -7.2e-29 0.0000 p
65.719 3.2e+00 2.0e-12 6.3e-02 0.0e+00 0.0000 p
32.909 3.2e+00 7.4e-13 6.3e-02 -5.9e-13 0.0000 p
16.505 3.2e+00 1.4e-12 6.3e-02 0.0e+00 0.0000 p
8.302 3.2e+00 1.6e-12 6.3e-02 0.0e+00 0.0000 p
4.201 3.2e+00 1.6e-12 6.3e-02 0.0e+00 0.0000 p
2.151 3.2e+00 1.6e-12 6.3e-02 0.0e+00 0.0000 p
1.125 3.2e+00 2.8e-12 6.3e-02 0.0e+00 0.0000 p
0.613 3.0e+00 -2.5e+03# 6.3e-02 0.0e+00 0.0000 f
0.869 3.1e+00 -2.9e+01# 6.3e-02 0.0e+00 0.0000 f
0.997 3.2e+00 1.9e-12 6.3e-02 0.0e+00 0.0000 p
0.933 3.1e+00 -6.9e+02# 6.3e-02 0.0e+00 0.0000 f
0.965 3.1e+00 -3.0e+03# 6.3e-02 0.0e+00 0.0000 f
0.981 3.1e+00 -8.6e+03# 6.3e-02 0.0e+00 0.0000 f
0.989 3.2e+00 -2.7e+04# 6.3e-02 0.0e+00 0.0000 f
0.993 3.2e+00 -5.7e+05# 6.3e-02 0.0e+00 0.0000 f
0.995 3.2e+00 2.2e-12 6.3e-02 0.0e+00 0.0000 p
0.994 3.2e+00 1.6e-12 6.3e-02 0.0e+00 0.0000 p
0.994 3.2e+00 1.0e-12 6.3e-02 0.0e+00 0.0000 p
Gamma value achieved: 0.9936
\end { verbatim}
The two synthesized filters \( H _ 2 ( s ) \) and \( H _ 3 ( s ) \) are defined below:
And the third filter \( H _ 1 ( s ) \) is defined using \eqref { eq:H1_ complementary_ of_ H2_ H3} .
\begin { minted} []{ matlab}
%% H1 is defined as the complementary filter of H2 and H3
H1 = 1 - H2 - H3;
\end { minted}
The bode plots of the three obtained complementary filters are shown in Figure \ref { fig:three_ complementary_ filters_ results} .
\begin { figure} [htbp]
\centering
\includegraphics [scale=1] { figs/three_ complementary_ filters_ results.png}
\caption { \label { fig:three_ complementary_ filters_ results} The three complementary filters obtained after \( \mathcal { H } _ \infty \) synthesis}
\end { figure}
\chapter { Matlab Scripts}
\label { sec:matlab_ scripts}
\section { \texttt { 1\_ synthesis\_ complementary\_ filters.m} }
\label { sec:1_ synthesis_ complementary_ filters}
This scripts corresponds to section 3 of \cite { dehaeze21_ new_ method_ desig_ compl_ filter} .
\begin { minted} [linenos,firstnumber=1]{ matlab}
%% Clear Workspace and Close figures
clear; close all; clc;
%% Intialize Laplace variable
s = zpk('s');
%% Initialize Frequency Vector
freqs = logspace(-1, 3, 1000);
%% Weighting Function Design
% Parameters
n = 3; w0 = 2*pi*10; G0 = 1e-3; G1 = 1e1; Gc = 2;
% Formulas
W = (((1/w0)*sqrt((1-(G0/Gc)^ (2/n))/(1-(Gc/G1)^ (2/n)))*s + (G0/Gc)^ (1/n))/((1/G1)^ (1/n)*(1/w0)*sqrt((1-(G0/Gc)^ (2/n))/(1-(Gc/G1)^ (2/n)))*s + (1/Gc)^ (1/n)))^ n;
%% Magnitude of the weighting function with parameters
figure;
hold on;
plot(freqs, abs(squeeze(freqresp(W, freqs, 'Hz'))), 'k-');
plot([1e-3 1e0], [G0 G0], 'k--', 'LineWidth', 1)
text(1e0, G0, '$ \quad G _ 0 $ ')
plot([1e1 1e3], [G1 G1], 'k--', 'LineWidth', 1)
text(1e1,G1,'$ G _ { \infty } \quad $ ','HorizontalAlignment', 'right')
plot([w0/2/pi w0/2/pi], [1 2*Gc], 'k--', 'LineWidth', 1)
text(w0/2/pi,1,'$ \omega _ c $ ','VerticalAlignment', 'top', 'HorizontalAlignment', 'center')
plot([w0/2/pi/2 2*w0/2/pi], [Gc Gc], 'k--', 'LineWidth', 1)
text(w0/2/pi/2, Gc, '$ G _ c \quad $ ','HorizontalAlignment', 'right')
text(w0/5/pi/2, abs(evalfr(W, j*w0/5)), 'Slope: $ n \quad $ ', 'HorizontalAlignment', 'right')
text(w0/2/pi, abs(evalfr(W, j*w0)), '$ \bullet $ ', 'HorizontalAlignment', 'center')
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('Magnitude');
hold off;
xlim([freqs(1), freqs(end)]);
ylim([5e-4, 20]);
yticks([1e-4, 1e-3, 1e-2, 1e-1, 1, 1e1]);
%% Design of the Weighting Functions
2021-09-01 17:00:12 +02:00
W1 = generateWF('n', 3, 'w0', 2*pi*10, 'G0', 1000, 'Ginf', 1/10, 'Gc', 0.45);
W2 = generateWF('n', 2, 'w0', 2*pi*10, 'G0', 1/10, 'Ginf', 1000, 'Gc', 0.45);
2021-09-01 15:00:04 +02:00
%% Plot of the Weighting function magnitude
figure;
tiledlayout(1, 1, 'TileSpacing', 'None', 'Padding', 'None');
ax1 = nexttile();
hold on;
set(gca,'ColorOrderIndex',1)
plot(freqs, 1./abs(squeeze(freqresp(W1, freqs, 'Hz'))), '--', 'DisplayName', '$ |W _ 1 | ^ { - 1 } $ ');
set(gca,'ColorOrderIndex',2)
plot(freqs, 1./abs(squeeze(freqresp(W2, freqs, 'Hz'))), '--', 'DisplayName', '$ |W _ 2 | ^ { - 1 } $ ');
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]', 'FontSize', 10); ylabel('Magnitude', 'FontSize', 10);
hold off;
xlim([freqs(1), freqs(end)]);
xticks([0.1, 1, 10, 100, 1000]);
ylim([8e-4, 20]);
yticks([1e-3, 1e-2, 1e-1, 1, 1e1]);
yticklabels({ '', '$ 10 ^ { - 2 } $ ', '', '$ 10 ^ 0 $ ', ''} );
ax1.FontSize = 9;
leg = legend('location', 'south', 'FontSize', 8);
leg.ItemTokenSize(1) = 18;
%% Generalized Plant
P = [W1 -W1;
0 W2;
1 0];
%% H-Infinity Synthesis
[H2, ~, gamma, ~] = hinfsyn(P, 1, 1,'TOLGAM', 0.001, 'METHOD', 'ric', 'DISPLAY', 'on');
%% Define H1 to be the complementary of H2
H1 = 1 - H2;
%% Bode plot of the complementary filters
figure;
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
% Magnitude
ax1 = nexttile([2, 1]);
hold on;
set(gca,'ColorOrderIndex',1)
plot(freqs, 1./abs(squeeze(freqresp(W1, freqs, 'Hz'))), '--', 'DisplayName', '$ |W _ 1 | ^ { - 1 } $ ');
set(gca,'ColorOrderIndex',2)
plot(freqs, 1./abs(squeeze(freqresp(W2, freqs, 'Hz'))), '--', 'DisplayName', '$ |W _ 2 | ^ { - 1 } $ ');
set(gca,'ColorOrderIndex',1)
plot(freqs, abs(squeeze(freqresp(H1, freqs, 'Hz'))), '-', 'DisplayName', '$ H _ 1 $ ');
set(gca,'ColorOrderIndex',2)
plot(freqs, abs(squeeze(freqresp(H2, freqs, 'Hz'))), '-', 'DisplayName', '$ H _ 2 $ ');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
set(gca, 'XTickLabel',[]); ylabel('Magnitude');
ylim([8e-4, 20]);
yticks([1e-3, 1e-2, 1e-1, 1, 1e1]);
yticklabels({ '', '$ 10 ^ { - 2 } $ ', '', '$ 10 ^ 0 $ ', ''} )
leg = legend('location', 'south', 'FontSize', 8, 'NumColumns', 2);
leg.ItemTokenSize(1) = 18;
% Phase
ax2 = nexttile;
hold on;
set(gca,'ColorOrderIndex',1)
plot(freqs, 180/pi*phase(squeeze(freqresp(H1, freqs, 'Hz'))), '-');
set(gca,'ColorOrderIndex',2)
plot(freqs, 180/pi*phase(squeeze(freqresp(H2, freqs, 'Hz'))), '-');
hold off;
set(gca, 'XScale', 'log');
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
yticks([-180:90:180]);
ylim([-180, 200])
yticklabels({ '-180', '', '0', '', '180'} )
linkaxes([ax1,ax2],'x');
xlim([freqs(1), freqs(end)]);
\end { minted}
\section { \texttt { 2\_ ligo\_ complementary\_ filters.m} }
\label { sec:2_ ligo_ complementary_ filters}
This scripts corresponds to section 4 of \cite { dehaeze21_ new_ method_ desig_ compl_ filter} .
\begin { minted} [linenos,firstnumber=1]{ matlab}
%% Clear Workspace and Close figures
clear; close all; clc;
%% Intialize Laplace variable
s = zpk('s');
%% Initialize Frequency Vector
freqs = logspace(-3, 0, 1000);
%% Upper bounds for the complementary filters
figure;
hold on;
set(gca,'ColorOrderIndex',1)
plot([0.0001, 0.008], [8e-3, 8e-3], ':', 'DisplayName', 'Spec. on $ H _ H $ ');
set(gca,'ColorOrderIndex',1)
plot([0.008 0.04], [8e-3, 1], ':', 'HandleVisibility', 'off');
set(gca,'ColorOrderIndex',1)
plot([0.04 0.1], [3, 3], ':', 'HandleVisibility', 'off');
set(gca,'ColorOrderIndex',2)
plot([0.1, 10], [0.045, 0.045], ':', 'DisplayName', 'Spec. on $ H _ L $ ');
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('Magnitude');
hold off;
xlim([freqs(1), freqs(end)]);
ylim([1e-4, 10]);
leg = legend('location', 'southeast', 'FontSize', 8);
leg.ItemTokenSize(1) = 18;
%% Initialized CVX
cvx_ startup;
cvx_ solver sedumi;
%% Frequency vectors
w1 = 0:4.06e-4:0.008;
w2 = 0.008:4.06e-4:0.04;
w3 = 0.04:8.12e-4:0.1;
w4 = 0.1:8.12e-4:0.83;
%% Filter order
n = 512;
%% Initialization of filter responses
A1 = [ones(length(w1),1), cos(kron(w1'.*(2*pi),[1:n-1]))];
A2 = [ones(length(w2),1), cos(kron(w2'.*(2*pi),[1:n-1]))];
A3 = [ones(length(w3),1), cos(kron(w3'.*(2*pi),[1:n-1]))];
A4 = [ones(length(w4),1), cos(kron(w4'.*(2*pi),[1:n-1]))];
B1 = [zeros(length(w1),1), sin(kron(w1'.*(2*pi),[1:n-1]))];
B2 = [zeros(length(w2),1), sin(kron(w2'.*(2*pi),[1:n-1]))];
B3 = [zeros(length(w3),1), sin(kron(w3'.*(2*pi),[1:n-1]))];
B4 = [zeros(length(w4),1), sin(kron(w4'.*(2*pi),[1:n-1]))];
%% Convex optimization
cvx_ begin
variable y(n+1,1)
% t
maximize(-y(1))
for i = 1:length(w1)
norm([0 A1(i,:); 0 B1(i,:)]*y) <= 8e-3;
end
for i = 1:length(w2)
norm([0 A2(i,:); 0 B2(i,:)]*y) <= 8e-3*(2*pi*w2(i)/(0.008*2*pi))^ 3;
end
for i = 1:length(w3)
norm([0 A3(i,:); 0 B3(i,:)]*y) <= 3;
end
for i = 1:length(w4)
norm([[1 0]'- [0 A4(i,:); 0 B4(i,:)]*y]) <= y(1);
end
cvx_ end
h = y(2:end);
%% Combine the frequency vectors to form the obtained filter
w = [w1 w2 w3 w4];
H = [exp(-j*kron(w'.*2*pi,[0:n-1]))]*h;
%% Bode plot of the obtained complementary filters
figure;
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
% Magnitude
ax1 = nexttile([2, 1]);
hold on;
set(gca,'ColorOrderIndex',1)
plot(w, abs(1-H), '-', 'DisplayName', '$ L _ 1 $ ');
plot([0.1, 10], [0.045, 0.045], 'k:', 'DisplayName', 'Spec. on $ L _ 1 $ ');
set(gca,'ColorOrderIndex',2)
plot(w, abs(H), '-', 'DisplayName', '$ H _ 1 $ ');
plot([0.0001, 0.008], [8e-3, 8e-3], 'k--', 'DisplayName', 'Spec. on $ H _ 1 $ ');
plot([0.008 0.04], [8e-3, 1], 'k--', 'HandleVisibility', 'off');
plot([0.04 0.1], [3, 3], 'k--', 'HandleVisibility', 'off');
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
set(gca, 'XTickLabel',[]); ylabel('Magnitude');
hold off;
ylim([5e-3, 10]);
leg = legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 2);
leg.ItemTokenSize(1) = 16;
% Phase
ax2 = nexttile;
hold on;
plot(w, 180/pi*unwrap(angle(1-H)), '-');
plot(w, 180/pi*unwrap(angle(H)), '-');
hold off;
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
set(gca, 'XScale', 'log');
yticks([-360:180:180]); ylim([-380, 200]);
linkaxes([ax1,ax2],'x');
xlim([1e-3, 1]);
%% Design of the weight for the high pass filter
w1 = 2*pi*0.008; x1 = 0.35;
w2 = 2*pi*0.04; x2 = 0.5;
w3 = 2*pi*0.05; x3 = 0.5;
% Slope of +3 from w1
wH = 0.008*(s^ 2/w1^ 2 + 2*x1/w1*s + 1)*(s/w1 + 1);
% Little bump from w2 to w3
wH = wH*(s^ 2/w2^ 2 + 2*x2/w2*s + 1)/(s^ 2/w3^ 2 + 2*x3/w3*s + 1);
% No Slope at high frequencies
wH = wH/(s^ 2/w3^ 2 + 2*x3/w3*s + 1)/(s/w3 + 1);
% Little bump between w2 and w3
w0 = 2*pi*0.045; xi = 0.1; A = 2; n = 1;
wH = wH*((s^ 2 + 2*w0*xi*A^ (1/n)*s + w0^ 2)/(s^ 2 + 2*w0*xi*s + w0^ 2))^ n;
wH = 1/wH;
wH = minreal(ss(wH));
%% Design of the weight for the low pass filter
n = 20; % Filter order
Rp = 1; % Peak to peak passband ripple
Wp = 2*pi*0.102; % Edge frequency
% Chebyshev Type I filter design
[b,a] = cheby1(n, Rp, Wp, 'high', 's');
wL = 0.04*tf(a, b);
wL = 1/wL;
wL = minreal(ss(wL));
%% Magnitude of the designed Weights and initial specifications
figure;
hold on;
set(gca,'ColorOrderIndex',1);
plot(freqs, abs(squeeze(freqresp(inv(wL), freqs, 'Hz'))), '-', 'DisplayName', '$ |W _ L| ^ { - 1 } $ ');
plot([0.1, 10], [0.045, 0.045], 'k:', 'DisplayName', 'Spec. on $ L _ 1 $ ');
set(gca,'ColorOrderIndex',2);
plot(freqs, abs(squeeze(freqresp(inv(wH), freqs, 'Hz'))), '-', 'DisplayName', '$ |W _ H| ^ { - 1 } $ ');
plot([0.0001, 0.008], [8e-3, 8e-3], 'k--', 'DisplayName', 'Spec. on $ H _ 1 $ ');
plot([0.008 0.04], [8e-3, 1], 'k--', 'HandleVisibility', 'off');
plot([0.04 0.1], [3, 3], 'k--', 'HandleVisibility', 'off');
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('Magnitude');
hold off;
xlim([freqs(1), freqs(end)]);
ylim([5e-3, 10]);
leg = legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 2);
leg.ItemTokenSize(1) = 16;
%% Generalized plant for the H-infinity Synthesis
P = [0 wL;
wH -wH;
1 0];
%% Standard H-Infinity synthesis
[Hl, ~, gamma, ~] = hinfsyn(P, 1, 1,'TOLGAM', 0.001, 'METHOD', 'ric', 'DISPLAY', 'on');
%% High pass filter as the complementary of the low pass filter
Hh = 1 - Hl;
%% Minimum realization of the filters
Hh = minreal(Hh);
Hl = minreal(Hl);
%% Bode plot of the obtained filters and comparison with the upper bounds
figure;
hold on;
set(gca,'ColorOrderIndex',1);
plot(freqs, abs(squeeze(freqresp(Hl, freqs, 'Hz'))), '-', 'DisplayName', '$ L _ 1 ^ \prime $ ');
plot([0.1, 10], [0.045, 0.045], 'k:', 'DisplayName', 'Spec. on $ L _ 1 $ ');
set(gca,'ColorOrderIndex',2);
plot(freqs, abs(squeeze(freqresp(Hh, freqs, 'Hz'))), '-', 'DisplayName', '$ H _ 1 ^ \prime $ ');
plot([0.0001, 0.008], [8e-3, 8e-3], 'k--', 'DisplayName', 'Spec. on $ H _ 1 $ ');
plot([0.008 0.04], [8e-3, 1], 'k--', 'HandleVisibility', 'off');
plot([0.04 0.1], [3, 3], 'k--', 'HandleVisibility', 'off');
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('Magnitude');
hold off;
xlim([freqs(1), freqs(end)]);
ylim([5e-3, 10]);
leg = legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 2);
leg.ItemTokenSize(1) = 16;
%% Comparison of the complementary filters obtained with H-infinity and with CVX
figure;
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
% Magnitude
ax1 = nexttile([2, 1]);
hold on;
set(gca,'ColorOrderIndex',1);
plot(freqs, abs(squeeze(freqresp(Hl, freqs, 'Hz'))), '-', ...
'DisplayName', '$ L _ 1 ( s ) $ - $ \mathcal { H } _ \infty $ ');
set(gca,'ColorOrderIndex',2);
plot(freqs, abs(squeeze(freqresp(Hh, freqs, 'Hz'))), '-', ...
'DisplayName', '$ H _ 1 ( s ) $ - $ \mathcal { H } _ \infty $ ');
set(gca,'ColorOrderIndex',1);
plot(w, abs(1-H), '--', ...
'DisplayName', '$ L _ 1 ( s ) $ - FIR');
set(gca,'ColorOrderIndex',2);
plot(w, abs(H), '--', ...
'DisplayName', '$ H _ 1 ( s ) $ - FIR');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Magnitude');
set(gca, 'XTickLabel',[]);
ylim([5e-3, 10]);
leg = legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 2);
leg.ItemTokenSize(1) = 16;
% Phase
ax2 = nexttile;
hold on;
set(gca,'ColorOrderIndex',1);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(Hl, freqs, 'Hz')))), '-');
set(gca,'ColorOrderIndex',2);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(Hh, freqs, 'Hz')))), '-');
set(gca,'ColorOrderIndex',1);
plot(w, 180/pi*unwrap(angle(1-H)), '--');
set(gca,'ColorOrderIndex',2);
plot(w, 180/pi*unwrap(angle(H)), '--');
set(gca, 'XScale', 'log');
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
hold off;
yticks([-360:180:180]); ylim([-380, 200]);
linkaxes([ax1,ax2],'x');
xlim([freqs(1), freqs(end)]);
\end { minted}
\section { \texttt { 3\_ closed\_ loop\_ complementary\_ filters.m} }
\label { sec:3_ closed_ loop_ complementary_ filters}
This scripts corresponds to section 5.1 of \cite { dehaeze21_ new_ method_ desig_ compl_ filter} .
\begin { minted} [linenos,firstnumber=1]{ matlab}
%% Clear Workspace and Close figures
clear; close all; clc;
%% Intialize Laplace variable
s = zpk('s');
%% Initialize Frequency Vector
freqs = logspace(-1, 3, 1000);
%% Design of the Weighting Functions
2021-09-01 17:00:12 +02:00
W1 = generateWF('n', 3, 'w0', 2*pi*10, 'G0', 1000, 'Ginf', 1/10, 'Gc', 0.45);
W2 = generateWF('n', 2, 'w0', 2*pi*10, 'G0', 1/10, 'Ginf', 1000, 'Gc', 0.45);
2021-09-01 15:00:04 +02:00
%% Generalized plant for "closed-loop" complementary filter synthesis
P = [ W1 0 1;
-W1 W2 -1];
%% Standard H-Infinity Synthesis
[L, ~, gamma, ~] = hinfsyn(P, 1, 1,'TOLGAM', 0.001, 'METHOD', 'ric', 'DISPLAY', 'on');
%% Complementary filters
H1 = inv(1 + L);
H2 = 1 - H1;
%% Bode plot of the obtained Complementary filters with upper-bounds
freqs = logspace(-1, 3, 1000);
figure;
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
% Magnitude
ax1 = nexttile([2, 1]);
hold on;
set(gca,'ColorOrderIndex',1)
plot(freqs, 1./abs(squeeze(freqresp(W1, freqs, 'Hz'))), '--', 'DisplayName', '$ |W _ 1 | ^ { - 1 } $ ');
set(gca,'ColorOrderIndex',2)
plot(freqs, 1./abs(squeeze(freqresp(W2, freqs, 'Hz'))), '--', 'DisplayName', '$ |W _ 2 | ^ { - 1 } $ ');
set(gca,'ColorOrderIndex',1)
plot(freqs, abs(squeeze(freqresp(H1, freqs, 'Hz'))), '-', 'DisplayName', '$ H _ 1 $ ');
set(gca,'ColorOrderIndex',2)
plot(freqs, abs(squeeze(freqresp(H2, freqs, 'Hz'))), '-', 'DisplayName', '$ H _ 2 $ ');
plot(freqs, abs(squeeze(freqresp(L, freqs, 'Hz'))), 'k--', 'DisplayName', '$ |L| $ ');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
set(gca, 'XTickLabel',[]); ylabel('Magnitude');
ylim([1e-3, 1e3]);
yticks([1e-3, 1e-2, 1e-1, 1, 1e1, 1e2, 1e3]);
yticklabels({ '', '$ 10 ^ { - 2 } $ ', '', '$ 10 ^ 0 $ ', '', '$ 10 ^ 2 $ ', ''} );
leg = legend('location', 'northeast', 'FontSize', 8, 'NumColumns', 3);
leg.ItemTokenSize(1) = 18;
% Phase
ax2 = nexttile;
hold on;
set(gca,'ColorOrderIndex',1)
plot(freqs, 180/pi*phase(squeeze(freqresp(H1, freqs, 'Hz'))), '-');
set(gca,'ColorOrderIndex',2)
plot(freqs, 180/pi*phase(squeeze(freqresp(H2, freqs, 'Hz'))), '-');
hold off;
set(gca, 'XScale', 'log');
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
yticks([-180:90:180]);
ylim([-180, 200])
yticklabels({ '-180', '', '0', '', '180'} )
linkaxes([ax1,ax2],'x');
xlim([freqs(1), freqs(end)]);
\end { minted}
\section { \texttt { 4\_ three\_ complementary\_ filters.m} }
\label { sec:4_ three_ complementary_ filters}
This scripts corresponds to section 5.2 of \cite { dehaeze21_ new_ method_ desig_ compl_ filter} .
\begin { minted} [linenos,firstnumber=1]{ matlab}
%% Clear Workspace and Close figures
clear; close all; clc;
%% Intialize Laplace variable
s = zpk('s');
freqs = logspace(-2, 3, 1000);
%% Design of the Weighting Functions
2021-09-01 17:00:12 +02:00
W1 = generateWF('n', 2, 'w0', 2*pi*1, 'G0', 1/10, 'Ginf', 1000, 'Gc', 0.5);
2021-09-01 15:00:04 +02:00
W2 = 0.22*(1 + s/2/pi/1)^ 2/(sqrt(1e-4) + s/2/pi/1)^ 2*(1 + s/2/pi/10)^ 2/(1 + s/2/pi/1000)^ 2;
2021-09-01 17:00:12 +02:00
W3 = generateWF('n', 3, 'w0', 2*pi*10, 'G0', 1000, 'Ginf', 1/10, 'Gc', 0.5);
2021-09-01 15:00:04 +02:00
%% Inverse magnitude of the weighting functions
figure;
hold on;
set(gca,'ColorOrderIndex',1)
plot(freqs, 1./abs(squeeze(freqresp(W1, freqs, 'Hz'))), '--', 'DisplayName', '$ |W _ 1 | ^ { - 1 } $ ');
set(gca,'ColorOrderIndex',2)
plot(freqs, 1./abs(squeeze(freqresp(W2, freqs, 'Hz'))), '--', 'DisplayName', '$ |W _ 2 | ^ { - 1 } $ ');
set(gca,'ColorOrderIndex',3)
plot(freqs, 1./abs(squeeze(freqresp(W3, freqs, 'Hz'))), '--', 'DisplayName', '$ |W _ 3 | ^ { - 1 } $ ');
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('Magnitude');
hold off;
xlim([freqs(1), freqs(end)]); ylim([2e-4, 1.3e1])
leg = legend('location', 'northeast', 'FontSize', 8);
leg.ItemTokenSize(1) = 18;
%% Generalized plant for the synthesis of 3 complementary filters
P = [W1 -W1 -W1;
0 W2 0 ;
0 0 W3;
1 0 0];
%% Standard H-Infinity Synthesis
[H, ~, gamma, ~] = hinfsyn(P, 1, 2,'TOLGAM', 0.001, 'METHOD', 'ric', 'DISPLAY', 'on');
2021-09-01 17:00:12 +02:00
%% Synthesized H2 and H3 filters
2021-09-01 15:00:04 +02:00
H2 = tf(H(1));
H3 = tf(H(2));
2021-09-01 17:00:12 +02:00
%% H1 is defined as the complementary filter of H2 and H3
2021-09-01 15:00:04 +02:00
H1 = 1 - H2 - H3;
%% Bode plot of the obtained complementary filters
figure;
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
% Magnitude
ax1 = nexttile([2, 1]);
hold on;
set(gca,'ColorOrderIndex',1)
plot(freqs, 1./abs(squeeze(freqresp(W1, freqs, 'Hz'))), '--', 'DisplayName', '$ |W _ 1 | ^ { - 1 } $ ');
set(gca,'ColorOrderIndex',2)
plot(freqs, 1./abs(squeeze(freqresp(W2, freqs, 'Hz'))), '--', 'DisplayName', '$ |W _ 2 | ^ { - 1 } $ ');
set(gca,'ColorOrderIndex',3)
plot(freqs, 1./abs(squeeze(freqresp(W3, freqs, 'Hz'))), '--', 'DisplayName', '$ |W _ 3 | ^ { - 1 } $ ');
set(gca,'ColorOrderIndex',1)
plot(freqs, abs(squeeze(freqresp(H1, freqs, 'Hz'))), '-', 'DisplayName', '$ H _ 1 $ ');
set(gca,'ColorOrderIndex',2)
plot(freqs, abs(squeeze(freqresp(H2, freqs, 'Hz'))), '-', 'DisplayName', '$ H _ 2 $ ');
set(gca,'ColorOrderIndex',3)
plot(freqs, abs(squeeze(freqresp(H3, freqs, 'Hz'))), '-', 'DisplayName', '$ H _ 3 $ ');
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Magnitude');
set(gca, 'XTickLabel',[]);
ylim([1e-4, 20]);
leg = legend('location', 'northeast', 'FontSize', 8);
leg.ItemTokenSize(1) = 18;
% Phase
ax2 = nexttile;
hold on;
set(gca,'ColorOrderIndex',1)
plot(freqs, 180/pi*phase(squeeze(freqresp(H1, freqs, 'Hz'))));
set(gca,'ColorOrderIndex',2)
plot(freqs, 180/pi*phase(squeeze(freqresp(H2, freqs, 'Hz'))));
set(gca,'ColorOrderIndex',3)
plot(freqs, 180/pi*phase(squeeze(freqresp(H3, freqs, 'Hz'))));
hold off;
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
set(gca, 'XScale', 'log');
yticks([-180:90:180]); ylim([-220, 220]);
linkaxes([ax1,ax2],'x');
xlim([freqs(1), freqs(end)]);
\end { minted}
\section { \texttt { generateWF} : Generate Weighting Functions}
\label { sec:generateWF}
This function is used to easily generate weighting functions from classical requirements.
\begin { minted} []{ matlab}
function [W] = generateWF(args)
% createWeight -
%
% Syntax: [W] = generateWeight(args)
%
% Inputs:
% - n - Weight Order (integer)
% - G0 - Low frequency Gain
% - G1 - High frequency Gain
% - Gc - Gain of the weight at frequency w0
% - w0 - Frequency at which |W(j w0)| = Gc [rad/s]
%
% Outputs:
% - W - Generated Weighting Function
%% Argument validation
arguments
args.n (1,1) double { mustBeInteger, mustBePositive} = 1
args.G0 (1,1) double { mustBeNumeric, mustBePositive} = 0.1
args.Ginf (1,1) double { mustBeNumeric, mustBePositive} = 10
args.Gc (1,1) double { mustBeNumeric, mustBePositive} = 1
args.w0 (1,1) double { mustBeNumeric, mustBePositive} = 1
end
% Verification of correct relation between G0, Gc and Ginf
mustBeBetween(args.G0, args.Gc, args.Ginf);
%% Initialize the Laplace variable
s = zpk('s');
%% Create the weighting function according to formula
W = (((1/args.w0)*sqrt((1-(args.G0/args.Gc)^ (2/args.n))/(1-(args.Gc/args.Ginf)^ (2/args.n)))*s + ...
(args.G0/args.Gc)^ (1/args.n))/...
((1/args.Ginf)^ (1/args.n)*(1/args.w0)*sqrt((1-(args.G0/args.Gc)^ (2/args.n))/(1-(args.Gc/args.Ginf)^ (2/args.n)))*s + ...
(1/args.Gc)^ (1/args.n)))^ args.n;
%% Custom validation function
function mustBeBetween(a,b,c)
if ~((a > b & & b > c) || (c > b & & b > a))
eid = 'createWeight:inputError';
msg = 'Gc should be between G0 and Ginf.';
throwAsCaller(MException(eid,msg))
end
\end { minted}
\section { \texttt { generateCF} : Generate Complementary Filters}
\label { sec:generateCF}
This function is used to easily synthesize a set of two complementary filters using the \( \mathcal { H } _ \infty \) synthesis.
\begin { minted} []{ matlab}
function [H1, H2] = generateCF(W1, W2, args)
% createWeight -
%
% Syntax: [H1, H2] = generateCF(W1, W2, args)
%
% Inputs:
% - W1 - Weighting Function for H1
% - W2 - Weighting Function for H2
% - args:
% - method - H-Infinity solver ('lmi' or 'ric')
% - display - Display synthesis results ('on' or 'off')
%
% Outputs:
% - H1 - Generated H1 Filter
% - H2 - Generated H2 Filter
%% Argument validation
arguments
W1
W2
args.method char { mustBeMember(args.method,{ 'lmi', 'ric'} )} = 'ric'
args.display char { mustBeMember(args.display,{ 'on', 'off'} )} = 'on'
end
%% The generalized plant is defined
P = [W1 -W1;
0 W2;
1 0];
%% The standard H-infinity synthesis is performed
[H2, ~, gamma, ~] = hinfsyn(P, 1, 1,'TOLGAM', 0.001, 'METHOD', args.method, 'DISPLAY', args.display);
%% H1 is defined as the complementary of H2
H1 = 1 - H2;
\end { minted}
2021-09-01 17:00:12 +02:00
2021-09-01 15:00:04 +02:00
\printbibliography
\end { document}