1405 lines
52 KiB
TeX
1405 lines
52 KiB
TeX
% Created 2021-09-02 jeu. 10:03
|
|
% 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}
|
|
\title{Designing Complementary filters for sensor fusion using \(\mathcal{H}_\infty\) synthesis - Matlab Computation}
|
|
\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
|
|
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);
|
|
|
|
%% 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
|
|
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);
|
|
|
|
%% 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
|
|
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);
|
|
|
|
%% 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');
|
|
|
|
%% Synthesized H2 and H3 filters
|
|
H2 = tf(H(1));
|
|
H3 = tf(H(2));
|
|
|
|
%% H1 is defined as the complementary filter of H2 and H3
|
|
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}
|
|
|
|
\printbibliography
|
|
\end{document}
|