1235 lines
		
	
	
		
			47 KiB
		
	
	
	
		
			TeX
		
	
	
	
	
	
			
		
		
	
	
			1235 lines
		
	
	
		
			47 KiB
		
	
	
	
		
			TeX
		
	
	
	
	
	
| % Created 2020-11-11 mer. 16:50
 | |
| % Intended LaTeX compiler: pdflatex
 | |
| \documentclass[tocnp, secbreak, minted]{cleanreport}
 | |
| \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}
 | |
| \newcommand{\authorFirstName}{Thomas}
 | |
| \newcommand{\authorLastName}{Dehaeze}
 | |
| \newcommand{\authorEmail}{dehaeze.thomas@gmail.com}
 | |
| \usepackage[cache=false]{minted}
 | |
| \usemintedstyle{autumn}
 | |
| \setminted[matlab]{linenos=true, breaklines=true, tabsize=4, fontsize=\scriptsize, autogobble=true}
 | |
| \makeatletter
 | |
| \preto\Gin@extensions{png,}
 | |
| \DeclareGraphicsRule{.png}{pdf}{.pdf}{\noexpand\Gin@base.pdf}
 | |
| \makeatother
 | |
| \addbibresource{ref.bib}
 | |
| \author{Dehaeze Thomas}
 | |
| \date{\today}
 | |
| \title{Sensor Fusion - Test Bench}
 | |
| \hypersetup{
 | |
|  pdfauthor={Dehaeze Thomas},
 | |
|  pdftitle={Sensor Fusion - Test Bench},
 | |
|  pdfkeywords={},
 | |
|  pdfsubject={},
 | |
|  pdfcreator={Emacs 27.1 (Org mode 9.4)}, 
 | |
|  pdflang={English}}
 | |
| \begin{document}
 | |
| 
 | |
| \maketitle
 | |
| \setcounter{tocdepth}{2}
 | |
| \tableofcontents
 | |
| 
 | |
| 
 | |
| In this document, we wish the experimentally validate sensor fusion of inertial sensors.
 | |
| 
 | |
| This document is divided into the following sections:
 | |
| \begin{itemize}
 | |
| \item Section \ref{sec:experimental_setup}: the experimental setup is described
 | |
| \item Section \ref{sec:first_identification}: a first identification of the system dynamics is performed
 | |
| \item Section \ref{sec:integral_force_feedback}: the integral force feedback active damping technique is applied on the system
 | |
| \item Section \ref{sec:optimal_excitation}: the optimal excitation signal is determine in order to have the best possible system dynamics estimation
 | |
| \item Section \ref{sec:inertial_sensor_dynamics}: the inertial sensor dynamics are experimentally estimated
 | |
| \item Section \ref{sec:inertial_sensor_noise}: the inertial sensor noises are estimated and the \(\mathcal{H}_2\) synthesis of complementary filters is performed in order to yield a super sensor with minimal noise
 | |
| \item Section \ref{sec:inertial_sensor_uncertainty}: the dynamical uncertainty of the inertial sensors is estimated. Then the \(\mathcal{H}_\infty\) synthesis of complementary filters is performed in order to minimize the super sensor dynamical uncertainty
 | |
| \item Section \ref{sec:optimal_sensor_fusion}: Optimal sensor fusion is performed using the \(\mathcal{H}_2/\mathcal{H}_\infty\) synthesis
 | |
| \end{itemize}
 | |
| 
 | |
| \section{Experimental Setup}
 | |
| \label{sec:org1f25ae6}
 | |
| \label{sec:experimental_setup}
 | |
| 
 | |
| The goal of this experimental setup is to experimentally merge inertial sensors.
 | |
| To merge the sensors, optimal and robust complementary filters are designed.
 | |
| 
 | |
| A schematic of the test-bench used is shown in Figure \ref{fig:exp_setup_sensor_fusion} and a picture of it is shown in Figure \ref{fig:test-bench-sensor-fusion-picture}.
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/exp_setup_sensor_fusion.png}
 | |
| \caption{\label{fig:exp_setup_sensor_fusion}Schematic of the test-bench}
 | |
| \end{figure}
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/test-bench-sensor-fusion-picture.png}
 | |
| \caption{\label{fig:test-bench-sensor-fusion-picture}Picture of the test-bench}
 | |
| \end{figure}
 | |
| 
 | |
| 
 | |
| Two inertial sensors are used:
 | |
| \begin{itemize}
 | |
| \item An vertical accelerometer \emph{PCB 393B05} (\href{doc/TM-VIB-Seismic\_Lowres.pdf}{doc})
 | |
| \item A vertical geophone \emph{Mark Product L-22}
 | |
| \end{itemize}
 | |
| 
 | |
| Basic characteristics of both sensors are shown in Tables \ref{tab:393B05_spec} and \ref{tab:L22_spec}.
 | |
| 
 | |
| \begin{table}[htbp]
 | |
| \caption{\label{tab:393B05_spec}Accelerometer (393B05) Specifications}
 | |
| \centering
 | |
| \begin{tabular}{ll}
 | |
| \textbf{Specification} & \textbf{Value}\\
 | |
| \hline
 | |
| Sensitivity & 1.02 [V/(m/s2)]\\
 | |
| Resonant Frequency & > 2.5 [kHz]\\
 | |
| Resolution (1 to 10kHz) & 0.00004 [m/s2 rms]\\
 | |
| \end{tabular}
 | |
| \end{table}
 | |
| 
 | |
| \begin{table}[htbp]
 | |
| \caption{\label{tab:L22_spec}Geophone (L22) Specifications}
 | |
| \centering
 | |
| \begin{tabular}{ll}
 | |
| \textbf{Specification} & \textbf{Value}\\
 | |
| \hline
 | |
| Sensitivity & To be measured [V/(m/s)]\\
 | |
| Resonant Frequency & 2 [Hz]\\
 | |
| \end{tabular}
 | |
| \end{table}
 | |
| 
 | |
| The ADC used are the IO131 Speedgoat module (\href{https://www.speedgoat.com/products/io-connectivity-analog-io131}{link}) with a 16bit resolution over +/- 10V.
 | |
| 
 | |
| The geophone signals are amplified using a DLPVA-100-B-D voltage amplified from Femto (\href{doc/de-dlpva-100-b.pdf}{doc}).
 | |
| The force sensor signal is amplified using a Low Noise Voltage Preamplifier from Ametek (\href{doc/model\_5113.pdf}{doc}).
 | |
| 
 | |
| The excitation signal is amplified by a linear amplified from Cedrat (LA75B) with a gain equals to 20 (\href{doc/LA75B.pdf}{doc}).
 | |
| 
 | |
| Geophone electronics:
 | |
| \begin{itemize}
 | |
| \item gain: 10 (20dB)
 | |
| \item low pass filter: 1.5Hz
 | |
| \item hifh pass filter: 100kHz (2nd order)
 | |
| \end{itemize}
 | |
| 
 | |
| Force Sensor electronics:
 | |
| \begin{itemize}
 | |
| \item gain: 10 (20dB)
 | |
| \item low pass filter: 1st order at 3Hz
 | |
| \item high pass filter: 1st order at 30kHz
 | |
| \end{itemize}
 | |
| 
 | |
| \section{First identification of the system}
 | |
| \label{sec:orgfd3d380}
 | |
| \label{sec:first_identification}
 | |
| In this section, a first identification of each elements of the system is performed.
 | |
| This include the dynamics from the actuator to the force sensor, interferometer and inertial sensors.
 | |
| 
 | |
| Each of the dynamics is compared with the dynamics identified form a Simscape model.
 | |
| \subsection{Load Data}
 | |
| \label{sec:orge975c98}
 | |
| The data is loaded in the Matlab workspace.
 | |
| \begin{minted}[]{matlab}
 | |
| id_ol = load('identification_noise_bis.mat', 'd', 'acc_1', 'acc_2', 'geo_1', 'geo_2', 'f_meas', 'u', 't');
 | |
| \end{minted}
 | |
| 
 | |
| Then, any offset is removed.
 | |
| \begin{minted}[]{matlab}
 | |
| id_ol.d      = detrend(id_ol.d, 0);
 | |
| id_ol.acc_1  = detrend(id_ol.acc_1, 0);
 | |
| id_ol.acc_2  = detrend(id_ol.acc_2, 0);
 | |
| id_ol.geo_1  = detrend(id_ol.geo_1, 0);
 | |
| id_ol.geo_2  = detrend(id_ol.geo_2, 0);
 | |
| id_ol.f_meas = detrend(id_ol.f_meas, 0);
 | |
| id_ol.u      = detrend(id_ol.u, 0);
 | |
| \end{minted}
 | |
| 
 | |
| \subsection{Excitation Signal}
 | |
| \label{sec:org5e8f3ce}
 | |
| The generated voltage used to excite the system is a white noise and can be seen in Figure \ref{fig:excitation_signal_first_identification}.
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/excitation_signal_first_identification.png}
 | |
| \caption{\label{fig:excitation_signal_first_identification}Voltage excitation signal}
 | |
| \end{figure}
 | |
| 
 | |
| \subsection{Identified Plant}
 | |
| \label{sec:org326a4c0}
 | |
| The transfer function from the excitation voltage to the mass displacement and to the force sensor stack voltage are identified using the \texttt{tfestimate} command.
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| Ts = id_ol.t(2) - id_ol.t(1);
 | |
| win = hann(ceil(10/Ts));
 | |
| \end{minted}
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| [tf_fmeas_est, f] = tfestimate(id_ol.u, id_ol.f_meas, win, [], [], 1/Ts); % [V/V]
 | |
| [tf_G_ol_est,  ~] = tfestimate(id_ol.u, id_ol.d, win, [], [], 1/Ts); % [m/V]
 | |
| \end{minted}
 | |
| 
 | |
| The bode plots of the obtained dynamics are shown in Figures \ref{fig:force_sensor_bode_plot} and \ref{fig:displacement_sensor_bode_plot}.
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/force_sensor_bode_plot.png}
 | |
| \caption{\label{fig:force_sensor_bode_plot}Bode plot of the dynamics from excitation voltage to measured force sensor stack voltage}
 | |
| \end{figure}
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/displacement_sensor_bode_plot.png}
 | |
| \caption{\label{fig:displacement_sensor_bode_plot}Bode plot of the dynamics from excitation voltage to displacement of the mass as measured by the interferometer}
 | |
| \end{figure}
 | |
| 
 | |
| \subsection{Simscape Model - Comparison}
 | |
| \label{sec:org8797fe4}
 | |
| A simscape model representing the test-bench has been developed.
 | |
| The same transfer functions as the one identified using the test-bench can be obtained thanks to the simscape model.
 | |
| 
 | |
| They are compared in Figure \ref{fig:simscape_comp_iff_plant} and \ref{fig:simscape_comp_disp_plant}.
 | |
| It is shown that there is a good agreement between the model and the experiment.
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| load('piezo_amplified_3d.mat', 'int_xyz', 'int_i', 'n_xyz', 'n_i', 'nodes', 'M', 'K');
 | |
| \end{minted}
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/simscape_comp_iff_plant.png}
 | |
| \caption{\label{fig:simscape_comp_iff_plant}Comparison of the dynamics from excitation voltage to measured force sensor stack voltage - Identified dynamics and Simscape Model}
 | |
| \end{figure}
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/simscape_comp_disp_plant.png}
 | |
| \caption{\label{fig:simscape_comp_disp_plant}Comparison of the dynamics from excitation voltage to measured mass displacement - Identified dynamics and Simscape Model}
 | |
| \end{figure}
 | |
| 
 | |
| \subsection{Integral Force Feedback}
 | |
| \label{sec:org985543a}
 | |
| The force sensor stack can be used to damp the system.
 | |
| This makes the system easier to excite properly without too much amplification near resonances.
 | |
| 
 | |
| This is done thanks to the integral force feedback control architecture.
 | |
| 
 | |
| The force sensor stack signal is integrated (or rather low pass filtered) and fed back to the force sensor stacks.
 | |
| 
 | |
| The low pass filter used as the controller is defined below:
 | |
| \begin{minted}[]{matlab}
 | |
| Kiff = 102/(s + 2*pi*2);
 | |
| \end{minted}
 | |
| 
 | |
| The integral force feedback control strategy is applied to the simscape model as well as to the real test bench.
 | |
| 
 | |
| The damped system is then identified again using a noise excitation.
 | |
| 
 | |
| The data is loaded into Matlab and any offset is removed.
 | |
| \begin{minted}[]{matlab}
 | |
| id_cl = load('identification_noise_iff_bis.mat', 'd', 'acc_1', 'acc_2', 'geo_1', 'geo_2', 'f_meas', 'u', 't');
 | |
| 
 | |
| id_cl.d      = detrend(id_cl.d, 0);
 | |
| id_cl.acc_1  = detrend(id_cl.acc_1, 0);
 | |
| id_cl.acc_2  = detrend(id_cl.acc_2, 0);
 | |
| id_cl.geo_1  = detrend(id_cl.geo_1, 0);
 | |
| id_cl.geo_2  = detrend(id_cl.geo_2, 0);
 | |
| id_cl.f_meas = detrend(id_cl.f_meas, 0);
 | |
| id_cl.u      = detrend(id_cl.u, 0);
 | |
| \end{minted}
 | |
| 
 | |
| The transfer functions are estimated using \texttt{tfestimate}.
 | |
| \begin{minted}[]{matlab}
 | |
| [tf_G_cl_est, ~] = tfestimate(id_cl.u, id_cl.d, win, [], [], 1/Ts);
 | |
| [co_G_cl_est, ~] = mscohere(  id_cl.u, id_cl.d, win, [], [], 1/Ts);
 | |
| \end{minted}
 | |
| 
 | |
| The dynamics from driving voltage to the measured displacement are compared both in the open-loop and IFF case, and for the test-bench experimental identification and for the Simscape model in Figure \ref{fig:iff_ol_cl_identified_simscape_comp}.
 | |
| This shows that the Integral Force Feedback architecture effectively damps the first resonance of the system.
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/iff_ol_cl_identified_simscape_comp.png}
 | |
| \caption{\label{fig:iff_ol_cl_identified_simscape_comp}Comparison of the open-loop and closed-loop (IFF) dynamics for both the real identification and the Simscape one}
 | |
| \end{figure}
 | |
| 
 | |
| \subsection{Inertial Sensors}
 | |
| \label{sec:orgcdb3347}
 | |
| In order to estimate the dynamics of the inertial sensor (the transfer function from the ``absolute'' displacement to the measured voltage), the following experiment can be performed:
 | |
| \begin{itemize}
 | |
| \item The mass is excited such that is relative displacement as measured by the interferometer is much larger that the ground ``absolute'' motion.
 | |
| \item The transfer function from the measured displacement by the interferometer to the measured voltage generated by the inertial sensors can be estimated.
 | |
| \end{itemize}
 | |
| 
 | |
| The first point is quite important in order to have a good coherence between the interferometer measurement and the inertial sensor measurement.
 | |
| 
 | |
| Here, a first identification is performed were the excitation signal is a white noise.
 | |
| 
 | |
| 
 | |
| As usual, the data is loaded and any offset is removed.
 | |
| \begin{minted}[]{matlab}
 | |
| id = load('identification_noise_opt_iff.mat', 'd', 'acc_1', 'acc_2', 'geo_1', 'geo_2', 'f_meas', 'u', 't');
 | |
| 
 | |
| id.d = detrend(id.d, 0);
 | |
| id.acc_1 = detrend(id.acc_1, 0);
 | |
| id.acc_2 = detrend(id.acc_2, 0);
 | |
| id.geo_1 = detrend(id.geo_1, 0);
 | |
| id.geo_2 = detrend(id.geo_2, 0);
 | |
| id.f_meas = detrend(id.f_meas, 0);
 | |
| \end{minted}
 | |
| 
 | |
| Then the transfer functions from the measured displacement by the interferometer to the generated voltage of the inertial sensors are computed..
 | |
| \begin{minted}[]{matlab}
 | |
| Ts = id.t(2) - id.t(1);
 | |
| win = hann(ceil(10/Ts));
 | |
| \end{minted}
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| [tf_acc1_est, f] = tfestimate(id.d, id.acc_1, win, [], [], 1/Ts);
 | |
| [co_acc1_est, ~] = mscohere(  id.d, id.acc_1, win, [], [], 1/Ts);
 | |
| [tf_acc2_est, ~] = tfestimate(id.d, id.acc_2, win, [], [], 1/Ts);
 | |
| [co_acc2_est, ~] = mscohere(  id.d, id.acc_2, win, [], [], 1/Ts);
 | |
| 
 | |
| [tf_geo1_est, ~] = tfestimate(id.d, id.geo_1, win, [], [], 1/Ts);
 | |
| [co_geo1_est, ~] = mscohere(  id.d, id.geo_1, win, [], [], 1/Ts);
 | |
| [tf_geo2_est, ~] = tfestimate(id.d, id.geo_2, win, [], [], 1/Ts);
 | |
| [co_geo2_est, ~] = mscohere(  id.d, id.geo_2, win, [], [], 1/Ts);
 | |
| \end{minted}
 | |
| 
 | |
| The same transfer functions are estimated using the Simscape model.
 | |
| 
 | |
| The obtained dynamics of the accelerometer are compared in Figure \ref{fig:comp_dynamics_accelerometer} while the one of the geophones are compared in Figure \ref{fig:comp_dynamics_geophone}.
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/comp_dynamics_accelerometer.png}
 | |
| \caption{\label{fig:comp_dynamics_accelerometer}Comparison of the measured accelerometer dynamics}
 | |
| \end{figure}
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/comp_dynamics_geophone.png}
 | |
| \caption{\label{fig:comp_dynamics_geophone}Comparison of the measured geophone dynamics}
 | |
| \end{figure}
 | |
| 
 | |
| \section{Optimal IFF Development}
 | |
| \label{sec:org2ad9f9e}
 | |
| \label{sec:integral_force_feedback}
 | |
| In this section, a proper identification of the transfer function from the force actuator to the force sensor is performed.
 | |
| Then, an optimal IFF controller is developed and applied experimentally.
 | |
| 
 | |
| The damped system is identified to verified the effectiveness of the added method.
 | |
| \subsection{Load Data}
 | |
| \label{sec:org648d21b}
 | |
| The experimental data is loaded and any offset is removed.
 | |
| \begin{minted}[]{matlab}
 | |
| id_ol = load('identification_noise_bis.mat', 'd', 'acc_1', 'acc_2', 'geo_1', 'geo_2', 'f_meas', 'u', 't');
 | |
| \end{minted}
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| id_ol.d = detrend(id_ol.d, 0);
 | |
| id_ol.acc_1 = detrend(id_ol.acc_1, 0);
 | |
| id_ol.acc_2 = detrend(id_ol.acc_2, 0);
 | |
| id_ol.geo_1 = detrend(id_ol.geo_1, 0);
 | |
| id_ol.geo_2 = detrend(id_ol.geo_2, 0);
 | |
| id_ol.f_meas = detrend(id_ol.f_meas, 0);
 | |
| id_ol.u = detrend(id_ol.u, 0);
 | |
| \end{minted}
 | |
| 
 | |
| \subsection{Experimental Data}
 | |
| \label{sec:org4151558}
 | |
| The transfer function from force actuator to force sensors is estimated.
 | |
| 
 | |
| The coherence shown in Figure \ref{fig:iff_identification_coh} shows that the excitation signal is good enough.
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| Ts = id_ol.t(2) - id_ol.t(1);
 | |
| win = hann(ceil(10/Ts));
 | |
| \end{minted}
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| [tf_fmeas_est, f] = tfestimate(id_ol.u, id_ol.f_meas, win, [], [], 1/Ts); % [V/m]
 | |
| [co_fmeas_est, ~] = mscohere(  id_ol.u, id_ol.f_meas, win, [], [], 1/Ts);
 | |
| \end{minted}
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/iff_identification_coh.png}
 | |
| \caption{\label{fig:iff_identification_coh}Coherence for the identification of the IFF plant}
 | |
| \end{figure}
 | |
| 
 | |
| The obtained dynamics is shown in Figure \ref{fig:iff_identification_bode_plot}.
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/iff_identification_bode_plot.png}
 | |
| \caption{\label{fig:iff_identification_bode_plot}Bode plot of the identified IFF plant}
 | |
| \end{figure}
 | |
| 
 | |
| \subsection{Model of the IFF Plant}
 | |
| \label{sec:org50bd8ad}
 | |
| In order to plot the root locus for the IFF control strategy, a model of the identified plant is developed.
 | |
| 
 | |
| It consists of several poles and zeros are shown below.
 | |
| \begin{minted}[]{matlab}
 | |
| wz = 2*pi*102;
 | |
| xi_z = 0.01;
 | |
| wp = 2*pi*239.4;
 | |
| xi_p = 0.015;
 | |
| 
 | |
| Giff = 2.2*(s^2 + 2*xi_z*s*wz + wz^2)/(s^2 + 2*xi_p*s*wp + wp^2) * ... % Dynamics
 | |
|        10*(s/3/pi/(1 + s/3/pi)) * ... % Low pass filter and gain of the voltage amplifier
 | |
|        exp(-Ts*s); % Time delay induced by ADC/DAC
 | |
| \end{minted}
 | |
| 
 | |
| The comparison of the identified dynamics and the developed model is done in Figure \ref{fig:iff_plant_model}.
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/iff_plant_model.png}
 | |
| \caption{\label{fig:iff_plant_model}IFF Plant + Model}
 | |
| \end{figure}
 | |
| 
 | |
| \subsection{Root Locus and optimal Controller}
 | |
| \label{sec:orgd2946d4}
 | |
| Now, the root locus for the Integral Force Feedback strategy is computed and shown in Figure \ref{fig:iff_root_locus}.
 | |
| 
 | |
| Note that the controller used is not a pure integrator but rather a first order low pass filter with a cut-off frequency set at 2Hz.
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/iff_root_locus.png}
 | |
| \caption{\label{fig:iff_root_locus}Root Locus for the IFF control}
 | |
| \end{figure}
 | |
| 
 | |
| The controller that yield maximum damping (shown by the red cross in Figure \ref{fig:iff_root_locus}) is:
 | |
| \begin{minted}[]{matlab}
 | |
| Kiff_opt = 102/(s + 2*pi*2);
 | |
| \end{minted}
 | |
| 
 | |
| \subsection{Verification of the achievable damping}
 | |
| \label{sec:org163da4b}
 | |
| A new identification is performed with the IFF control strategy applied to the system.
 | |
| 
 | |
| Data is loaded and offset removed.
 | |
| \begin{minted}[]{matlab}
 | |
| id_cl = load('identification_noise_iff_bis.mat', 'd', 'acc_1', 'acc_2', 'geo_1', 'geo_2', 'f_meas', 'u', 't');
 | |
| \end{minted}
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| id_cl.d      = detrend(id_cl.d, 0);
 | |
| id_cl.acc_1  = detrend(id_cl.acc_1, 0);
 | |
| id_cl.acc_2  = detrend(id_cl.acc_2, 0);
 | |
| id_cl.geo_1  = detrend(id_cl.geo_1, 0);
 | |
| id_cl.geo_2  = detrend(id_cl.geo_2, 0);
 | |
| id_cl.f_meas = detrend(id_cl.f_meas, 0);
 | |
| id_cl.u      = detrend(id_cl.u, 0);
 | |
| \end{minted}
 | |
| 
 | |
| The open-loop and closed-loop dynamics are estimated.
 | |
| \begin{minted}[]{matlab}
 | |
| [tf_G_ol_est, f] = tfestimate(id_ol.u, id_ol.d, win, [], [], 1/Ts);
 | |
| [co_G_ol_est, ~] = mscohere(  id_ol.u, id_ol.d, win, [], [], 1/Ts);
 | |
| [tf_G_cl_est, ~] = tfestimate(id_cl.u, id_cl.d, win, [], [], 1/Ts);
 | |
| [co_G_cl_est, ~] = mscohere(  id_cl.u, id_cl.d, win, [], [], 1/Ts);
 | |
| \end{minted}
 | |
| 
 | |
| The obtained coherence is shown in Figure \ref{fig:Gd_identification_iff_coherence} and the dynamics in Figure \ref{fig:Gd_identification_iff_bode_plot}.
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/Gd_identification_iff_coherence.png}
 | |
| \caption{\label{fig:Gd_identification_iff_coherence}Coherence for the transfer function from F to d, with and without IFF}
 | |
| \end{figure}
 | |
| 
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/Gd_identification_iff_bode_plot.png}
 | |
| \caption{\label{fig:Gd_identification_iff_bode_plot}Coherence for the transfer function from F to d, with and without IFF}
 | |
| \end{figure}
 | |
| 
 | |
| \section{Generate the excitation signal}
 | |
| \label{sec:orgad4b447}
 | |
| \label{sec:optimal_excitation}
 | |
| In order to properly estimate the dynamics of the inertial sensor, the excitation signal must be properly chosen.
 | |
| 
 | |
| The requirements on the excitation signal is:
 | |
| \begin{itemize}
 | |
| \item General much larger motion that the measured motion during the huddle test
 | |
| \item Don't damage the actuator
 | |
| \end{itemize}
 | |
| 
 | |
| To determine the perfect voltage signal to be generated, we need two things:
 | |
| \begin{itemize}
 | |
| \item the transfer function from voltage to mass displacement
 | |
| \item the PSD of the measured motion by the inertial sensors
 | |
| \item not saturate the sensor signals
 | |
| \item provide enough signal/noise ratio (good coherence) in the frequency band of interest (\textasciitilde{}0.5Hz to 3kHz)
 | |
| \end{itemize}
 | |
| \subsection{Transfer function from excitation signal to displacement}
 | |
| \label{sec:orgeb37755}
 | |
| Let's first estimate the transfer function from the excitation signal in [V] to the generated displacement in [m] as measured by the inteferometer.
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| id_cl = load('identification_noise_iff_bis.mat', 'd', 'acc_1', 'acc_2', 'geo_1', 'geo_2', 'f_meas', 'u', 't');
 | |
| \end{minted}
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| Ts = id_cl.t(2) - id_cl.t(1);
 | |
| win = hann(ceil(10/Ts));
 | |
| \end{minted}
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| [tf_G_cl_est, f] = tfestimate(id_cl.u, id_cl.d, win, [], [], 1/Ts);
 | |
| [co_G_cl_est, ~] = mscohere(  id_cl.u, id_cl.d, win, [], [], 1/Ts);
 | |
| \end{minted}
 | |
| 
 | |
| Approximate transfer function from voltage output to generated displacement when IFF is used, in [m/V].
 | |
| \begin{minted}[]{matlab}
 | |
| G_d_est = -5e-6*(2*pi*230)^2/(s^2 + 2*0.3*2*pi*240*s + (2*pi*240)^2);
 | |
| \end{minted}
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/Gd_plant_estimation.png}
 | |
| \caption{\label{fig:Gd_plant_estimation}Estimation of the transfer function from the excitation signal to the generated displacement}
 | |
| \end{figure}
 | |
| 
 | |
| \subsection{Motion measured during Huddle test}
 | |
| \label{sec:org2632bf6}
 | |
| We now compute the PSD of the measured motion by the inertial sensors during the huddle test.
 | |
| \begin{minted}[]{matlab}
 | |
| ht = load('huddle_test.mat', 'd', 'acc_1', 'acc_2', 'geo_1', 'geo_2', 'f_meas', 'u', 't');
 | |
| ht.d = detrend(ht.d, 0);
 | |
| ht.acc_1 = detrend(ht.acc_1, 0);
 | |
| ht.acc_2 = detrend(ht.acc_2, 0);
 | |
| ht.geo_1 = detrend(ht.geo_1, 0);
 | |
| ht.geo_2 = detrend(ht.geo_2, 0);
 | |
| \end{minted}
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| [p_d, f] = pwelch(ht.d, win, [], [], 1/Ts);
 | |
| [p_acc1, ~] = pwelch(ht.acc_1, win, [], [], 1/Ts);
 | |
| [p_acc2, ~] = pwelch(ht.acc_2, win, [], [], 1/Ts);
 | |
| [p_geo1, ~] = pwelch(ht.geo_1, win, [], [], 1/Ts);
 | |
| [p_geo2, ~] = pwelch(ht.geo_2, win, [], [], 1/Ts);
 | |
| \end{minted}
 | |
| 
 | |
| Using an estimated model of the sensor dynamics from the documentation of the sensors, we can compute the ASD of the motion in \(m/\sqrt{Hz}\) measured by the sensors.
 | |
| \begin{minted}[]{matlab}
 | |
| G_acc = 1/(1 + s/2/pi/2500); % [V/(m/s2)]
 | |
| G_geo = -120*s^2/(s^2 + 2*0.7*2*pi*2*s + (2*pi*2)^2); % [V/(m/s)]
 | |
| \end{minted}
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/huddle_test_psd_motion.png}
 | |
| \caption{\label{fig:huddle_test_psd_motion}ASD of the motion measured by the sensors}
 | |
| \end{figure}
 | |
| 
 | |
| From the ASD of the motion measured by the sensors, we can create an excitation signal that will generate much motion motion that the motion under no excitation.
 | |
| 
 | |
| We create \texttt{G\_exc} that corresponds to the wanted generated motion.
 | |
| \begin{minted}[]{matlab}
 | |
| G_exc = 0.2e-6/(1 + s/2/pi/2)/(1 + s/2/pi/50);
 | |
| \end{minted}
 | |
| 
 | |
| And we create a time domain signal \texttt{y\_d} that have the spectral density described by \texttt{G\_exc}.
 | |
| \begin{minted}[]{matlab}
 | |
| Fs = 1/Ts;
 | |
| t = 0:Ts:180; % Time Vector [s]
 | |
| u = sqrt(Fs/2)*randn(length(t), 1); % Signal with an ASD equal to one
 | |
| 
 | |
| y_d = lsim(G_exc, u, t);
 | |
| \end{minted}
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| [pxx, ~] = pwelch(y_d, win, 0, [], Fs);
 | |
| \end{minted}
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/comp_huddle_test_excited_motion_psd.png}
 | |
| \caption{\label{fig:comp_huddle_test_excited_motion_psd}Comparison of the ASD of the motion during Huddle and the wanted generated motion}
 | |
| \end{figure}
 | |
| 
 | |
| 
 | |
| We can now generate the voltage signal that will generate the wanted motion.
 | |
| \begin{minted}[]{matlab}
 | |
| y_v = lsim(G_exc * ... % from unit PSD to shaped PSD
 | |
|            (1 + s/2/pi/50) * ... % Inverse of pre-filter included in the Simulink file
 | |
|            1/G_d_est * ... % Wanted displacement => required voltage
 | |
|            1/(1 + s/2/pi/5e3), ... %  Add some high frequency filtering
 | |
|            u, t);
 | |
| \end{minted}
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/optimal_exc_signal_time.png}
 | |
| \caption{\label{fig:optimal_exc_signal_time}Generated excitation signal}
 | |
| \end{figure}
 | |
| 
 | |
| \section{Identification of the Inertial Sensors Dynamics}
 | |
| \label{sec:org15a1119}
 | |
| \label{sec:inertial_sensor_dynamics}
 | |
| Using the excitation signal generated in Section \ref{sec:optimal_excitation}, the dynamics of the inertial sensors are identified.
 | |
| \subsection{Load Data}
 | |
| \label{sec:org8165027}
 | |
| Both the measurement data during the identification test and during an ``huddle test'' are loaded.
 | |
| \begin{minted}[]{matlab}
 | |
| id = load('identification_noise_opt_iff.mat', 'd', 'acc_1', 'acc_2', 'geo_1', 'geo_2', 'f_meas', 'u', 't');
 | |
| ht = load('huddle_test.mat', 'd', 'acc_1', 'acc_2', 'geo_1', 'geo_2', 'f_meas', 'u', 't');
 | |
| \end{minted}
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| ht.d = detrend(ht.d, 0);
 | |
| ht.acc_1 = detrend(ht.acc_1, 0);
 | |
| ht.acc_2 = detrend(ht.acc_2, 0);
 | |
| ht.geo_1 = detrend(ht.geo_1, 0);
 | |
| ht.geo_2 = detrend(ht.geo_2, 0);
 | |
| ht.f_meas = detrend(ht.f_meas, 0);
 | |
| \end{minted}
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| id.d = detrend(id.d, 0);
 | |
| id.acc_1 = detrend(id.acc_1, 0);
 | |
| id.acc_2 = detrend(id.acc_2, 0);
 | |
| id.geo_1 = detrend(id.geo_1, 0);
 | |
| id.geo_2 = detrend(id.geo_2, 0);
 | |
| id.f_meas = detrend(id.f_meas, 0);
 | |
| \end{minted}
 | |
| 
 | |
| \subsection{Compare PSD during Huddle and and during identification}
 | |
| \label{sec:org6900214}
 | |
| The Power Spectral Density of the measured motion during the huddle test and during the identification test are compared in Figures \ref{fig:comp_psd_huddle_test_identification_acc} and \ref{fig:comp_psd_huddle_test_identification_geo}.
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| Ts = ht.t(2) - ht.t(1);
 | |
| win = hann(ceil(10/Ts));
 | |
| \end{minted}
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| [p_id_d, f] = pwelch(id.d, win, [], [], 1/Ts);
 | |
| [p_id_acc1, ~] = pwelch(id.acc_1, win, [], [], 1/Ts);
 | |
| [p_id_acc2, ~] = pwelch(id.acc_2, win, [], [], 1/Ts);
 | |
| [p_id_geo1, ~] = pwelch(id.geo_1, win, [], [], 1/Ts);
 | |
| [p_id_geo2, ~] = pwelch(id.geo_2, win, [], [], 1/Ts);
 | |
| \end{minted}
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| [p_ht_d, ~] = pwelch(ht.d, win, [], [], 1/Ts);
 | |
| [p_ht_acc1, ~] = pwelch(ht.acc_1, win, [], [], 1/Ts);
 | |
| [p_ht_acc2, ~] = pwelch(ht.acc_2, win, [], [], 1/Ts);
 | |
| [p_ht_geo1, ~] = pwelch(ht.geo_1, win, [], [], 1/Ts);
 | |
| [p_ht_geo2, ~] = pwelch(ht.geo_2, win, [], [], 1/Ts);
 | |
| [p_ht_fmeas, ~] = pwelch(ht.f_meas, win, [], [], 1/Ts);
 | |
| \end{minted}
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/comp_psd_huddle_test_identification_acc.png}
 | |
| \caption{\label{fig:comp_psd_huddle_test_identification_acc}Comparison of the PSD of the measured motion during the Huddle test and during the identification}
 | |
| \end{figure}
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/comp_psd_huddle_test_identification_geo.png}
 | |
| \caption{\label{fig:comp_psd_huddle_test_identification_geo}Comparison of the PSD of the measured motion during the Huddle test and during the identification}
 | |
| \end{figure}
 | |
| 
 | |
| \subsection{Compute transfer functions}
 | |
| \label{sec:orgb24ac36}
 | |
| The transfer functions from the motion as measured by the interferometer (and that should represent the absolute motion of the mass) to the inertial sensors are estimated:
 | |
| \begin{minted}[]{matlab}
 | |
| [tf_acc1_est, f] = tfestimate(id.d, id.acc_1, win, [], [], 1/Ts);
 | |
| [co_acc1_est, ~] = mscohere(  id.d, id.acc_1, win, [], [], 1/Ts);
 | |
| [tf_acc2_est, ~] = tfestimate(id.d, id.acc_2, win, [], [], 1/Ts);
 | |
| [co_acc2_est, ~] = mscohere(  id.d, id.acc_2, win, [], [], 1/Ts);
 | |
| 
 | |
| [tf_geo1_est, ~] = tfestimate(id.d, id.geo_1, win, [], [], 1/Ts);
 | |
| [co_geo1_est, ~] = mscohere(  id.d, id.geo_1, win, [], [], 1/Ts);
 | |
| [tf_geo2_est, ~] = tfestimate(id.d, id.geo_2, win, [], [], 1/Ts);
 | |
| [co_geo2_est, ~] = mscohere(  id.d, id.geo_2, win, [], [], 1/Ts);
 | |
| \end{minted}
 | |
| 
 | |
| The obtained coherence are shown in Figure \ref{fig:id_sensor_dynamics_coherence}.
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/id_sensor_dynamics_coherence.png}
 | |
| \caption{\label{fig:id_sensor_dynamics_coherence}Coherence for the estimation of the sensor dynamics}
 | |
| \end{figure}
 | |
| 
 | |
| We also make a simplified model of the inertial sensors to be compared with the identified dynamics.
 | |
| \begin{minted}[]{matlab}
 | |
| G_acc = 1/(1 + s/2/pi/2500); % [V/(m/s2)]
 | |
| G_geo = -1200*s^2/(s^2 + 2*0.7*2*pi*2*s + (2*pi*2)^2); % [[V/(m/s)]
 | |
| \end{minted}
 | |
| 
 | |
| The model and identified dynamics show good agreement (Figures \ref{fig:id_sensor_dynamics_accelerometers} and \ref{fig:id_sensor_dynamics_geophones}.)
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/id_sensor_dynamics_accelerometers.png}
 | |
| \caption{\label{fig:id_sensor_dynamics_accelerometers}Identified dynamics of the accelerometers}
 | |
| \end{figure}
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/id_sensor_dynamics_geophones.png}
 | |
| \caption{\label{fig:id_sensor_dynamics_geophones}Identified dynamics of the geophones}
 | |
| \end{figure}
 | |
| 
 | |
| \section{Inertial Sensor Noise and the \(\mathcal{H}_2\) Synthesis of complementary filters}
 | |
| \label{sec:orgba1dbbc}
 | |
| \label{sec:inertial_sensor_noise}
 | |
| In this section, the noise of the inertial sensors (geophones and accelerometers) is estimated.
 | |
| \subsection{Load Data}
 | |
| \label{sec:orga473e53}
 | |
| As before, the identification data is loaded and any offset if removed.
 | |
| \begin{minted}[]{matlab}
 | |
| id = load('identification_noise_opt_iff.mat', 'd', 'acc_1', 'acc_2', 'geo_1', 'geo_2', 'f_meas', 'u', 't');
 | |
| \end{minted}
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| id.d = detrend(id.d, 0);
 | |
| id.acc_1 = detrend(id.acc_1, 0);
 | |
| id.acc_2 = detrend(id.acc_2, 0);
 | |
| id.geo_1 = detrend(id.geo_1, 0);
 | |
| id.geo_2 = detrend(id.geo_2, 0);
 | |
| id.f_meas = detrend(id.f_meas, 0);
 | |
| \end{minted}
 | |
| 
 | |
| \subsection{ASD of the Measured displacement}
 | |
| \label{sec:orga1e0863}
 | |
| The Power Spectral Density of the displacement as measured by the interferometer and the inertial sensors is computed.
 | |
| \begin{minted}[]{matlab}
 | |
| Ts = id.t(2) - id.t(1);
 | |
| win = hann(ceil(10/Ts));
 | |
| \end{minted}
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| [p_id_d,     f] = pwelch(id.d,      win, [], [], 1/Ts);
 | |
| [p_id_acc1,  ~] = pwelch(id.acc_1,  win, [], [], 1/Ts);
 | |
| [p_id_acc2,  ~] = pwelch(id.acc_2,  win, [], [], 1/Ts);
 | |
| [p_id_geo1,  ~] = pwelch(id.geo_1,  win, [], [], 1/Ts);
 | |
| [p_id_geo2,  ~] = pwelch(id.geo_2,  win, [], [], 1/Ts);
 | |
| \end{minted}
 | |
| 
 | |
| Let's use a model of the accelerometer and geophone to compute the motion from the measured voltage.
 | |
| \begin{minted}[]{matlab}
 | |
| G_acc = 1/(1 + s/2/pi/2500); % [V/(m/s2)]
 | |
| G_geo = -1200*s^2/(s^2 + 2*0.7*2*pi*2*s + (2*pi*2)^2); % [[V/(m/s)]
 | |
| \end{minted}
 | |
| 
 | |
| The obtained ASD in \(m/\sqrt{Hz}\) is shown in Figure \ref{fig:measure_displacement_all_sensors}.
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/measure_displacement_all_sensors.png}
 | |
| \caption{\label{fig:measure_displacement_all_sensors}ASD of the measured displacement as measured by all the sensors}
 | |
| \end{figure}
 | |
| 
 | |
| \subsection{ASD of the Sensor Noise}
 | |
| \label{sec:org642e324}
 | |
| The noise of a sensor can be estimated using two identical sensors by computing:
 | |
| \begin{itemize}
 | |
| \item the Power Spectral Density of the measured motion by the two sensors
 | |
| \item the Cross Spectral Density between the two sensors (coherence)
 | |
| \end{itemize}
 | |
| 
 | |
| This technique to estimate the sensor noise is described in \cite{barzilai98_techn_measur_noise_sensor_presen}.
 | |
| 
 | |
| The Power Spectral Density of the sensor noise can be estimated using the following equation:
 | |
| \begin{equation}
 | |
|   |S_n(\omega)| = |S_{x_1}(\omega)| \Big( 1 - \gamma_{x_1 x_2}(\omega) \Big)
 | |
| \end{equation}
 | |
| with \(S_{x_1}\) the PSD of one of the sensor and \(\gamma_{x_1 x_2}\) the coherence between the two sensors.
 | |
| 
 | |
| The coherence between the two accelerometers and between the two geophones is computed.
 | |
| \begin{minted}[]{matlab}
 | |
| [coh_acc, ~] = mscohere(id.acc_1, id.acc_2, win, [], [], 1/Ts);
 | |
| [coh_geo, ~] = mscohere(id.geo_1, id.geo_2, win, [], [], 1/Ts);
 | |
| \end{minted}
 | |
| 
 | |
| Finally, the Power Spectral Density of the sensors is computed and converted in \([m^2/Hz]\).
 | |
| \begin{minted}[]{matlab}
 | |
| pN_acc = p_id_acc1.*(1 - coh_acc) .* ... % [V^2/Hz]
 | |
|          1./abs(squeeze(freqresp(G_acc*s^2, f, 'Hz'))).^2; % [(m/V)^2]
 | |
| pN_geo = p_id_geo1.*(1 - coh_geo) .* ... % [V^2/Hz]
 | |
|          1./abs(squeeze(freqresp(G_geo*s, f, 'Hz'))).^2; % [(m/V)^2]
 | |
| \end{minted}
 | |
| 
 | |
| The ASD of obtained noises are compared with the ASD of the measured signals in Figure \ref{fig:noise_inertial_sensors_comparison}.
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/noise_inertial_sensors_comparison.png}
 | |
| \caption{\label{fig:noise_inertial_sensors_comparison}Comparison of the computed ASD of the noise of the two inertial sensors}
 | |
| \end{figure}
 | |
| 
 | |
| \subsection{Noise Model}
 | |
| \label{sec:org162c1bf}
 | |
| Transfer functions are adjusted in order to fit the ASD of the sensor noises (expressed in \([m/s/\sqrt{Hz}]\) for more easy fitting).
 | |
| 
 | |
| These transfer functions are defined below and compared with the measured ASD in Figure \ref{fig:noise_models_velocity}.
 | |
| \begin{minted}[]{matlab}
 | |
| N_acc = 1*(s/(2*pi*2000) + 1)^2/(s + 0.1*2*pi)/(s + 1e3*2*pi); % [m/sqrt(Hz)]
 | |
| N_geo = 4e-4*(s/(2*pi*200) + 1)/(s + 1e3*2*pi); % [m/sqrt(Hz)]
 | |
| \end{minted}
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/noise_models_velocity.png}
 | |
| \caption{\label{fig:noise_models_velocity}ASD of the velocity noise measured by the sensors and the noise models}
 | |
| \end{figure}
 | |
| 
 | |
| \subsection{\(\mathcal{H}_2\) Synthesis of the Complementary Filters}
 | |
| \label{sec:org2d65000}
 | |
| We now wish to synthesize two complementary filters to merge the geophone and the accelerometer signal in such a way that the fused signal has the lowest possible RMS noise.
 | |
| 
 | |
| To do so, we use the \(\mathcal{H}_2\) synthesis where the transfer functions representing the noise density of both sensors are used as weights.
 | |
| 
 | |
| The generalized plant used for the synthesis is defined below.
 | |
| \begin{minted}[]{matlab}
 | |
| P = [0      N_acc  1;
 | |
|      N_geo -N_acc  0];
 | |
| \end{minted}
 | |
| 
 | |
| And the \(\mathcal{H}_2\) synthesis is done using the \texttt{h2syn} command.
 | |
| \begin{minted}[]{matlab}
 | |
| [H_geo, ~, gamma] = h2syn(P, 1, 1);
 | |
| H_acc = 1 - H_geo;
 | |
| \end{minted}
 | |
| 
 | |
| The obtained complementary filters are shown in Figure \ref{fig:complementary_filters_velocity_H2}.
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/complementary_filters_velocity_H2.png}
 | |
| \caption{\label{fig:complementary_filters_velocity_H2}Obtained Complementary Filters}
 | |
| \end{figure}
 | |
| 
 | |
| \subsection{Results}
 | |
| \label{sec:orgef78a56}
 | |
| Finally, the signals of both sensors are merged using the complementary filters and the super sensor noise is estimated and compared with the individual sensor noises in Figure \ref{fig:super_sensor_noise_asd_velocity}.
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/super_sensor_noise_asd_velocity.png}
 | |
| \caption{\label{fig:super_sensor_noise_asd_velocity}ASD of the super sensor noise (velocity)}
 | |
| \end{figure}
 | |
| 
 | |
| Finally, the Cumulative Power Spectrum is computed and compared in Figure \ref{fig:super_sensor_noise_cas_velocity}.
 | |
| \begin{minted}[]{matlab}
 | |
| [~, i_1Hz] = min(abs(f - 1));
 | |
| \end{minted}
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| CPS_acc = 1/pi*flip(-cumtrapz(2*pi*flip(f), flip((pN_acc.*(2*pi*f)).^2)));
 | |
| CPS_geo = 1/pi*flip(-cumtrapz(2*pi*flip(f), flip((pN_geo.*(2*pi*f)).^2)));
 | |
| CPS_SS  = 1/pi*flip(-cumtrapz(2*pi*flip(f), flip((pN_acc.*(2*pi*f)).^2.*abs(squeeze(freqresp(H_acc, f, 'Hz'))).^2 + (pN_geo.*(2*pi*f)).^2.*abs(squeeze(freqresp(H_geo, f, 'Hz'))).^2)));
 | |
| \end{minted}
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/super_sensor_noise_cas_velocity.png}
 | |
| \caption{\label{fig:super_sensor_noise_cas_velocity}Cumulative Power Spectrum of the Sensor Noise (velocity)}
 | |
| \end{figure}
 | |
| 
 | |
| \section{Inertial Sensor Dynamics Uncertainty and the \(\mathcal{H}_\infty\) Synthesis of complementary filters}
 | |
| \label{sec:org4c06165}
 | |
| \label{sec:inertial_sensor_uncertainty}
 | |
| When merging two sensors, it is important to be sure that we correctly know the sensor dynamics near the merging frequency.
 | |
| Thus, identifying the uncertainty on the sensor dynamics is quite important to perform a robust merging.
 | |
| \subsection{Load Data}
 | |
| \label{sec:orgdc287f4}
 | |
| Data is loaded and offset is removed.
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| id = load('identification_noise_opt_iff.mat', 'd', 'acc_1', 'acc_2', 'geo_1', 'geo_2', 'f_meas', 'u', 't');
 | |
| \end{minted}
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| id.d = detrend(id.d, 0);
 | |
| id.acc_1 = detrend(id.acc_1, 0);
 | |
| id.acc_2 = detrend(id.acc_2, 0);
 | |
| id.geo_1 = detrend(id.geo_1, 0);
 | |
| id.geo_2 = detrend(id.geo_2, 0);
 | |
| id.f_meas = detrend(id.f_meas, 0);
 | |
| \end{minted}
 | |
| 
 | |
| \subsection{Compute the dynamics of both sensors}
 | |
| \label{sec:org000ee7e}
 | |
| The dynamics of inertial sensors are estimated (in \([V/m]\)).
 | |
| \begin{minted}[]{matlab}
 | |
| Ts = id.t(2) - id.t(1);
 | |
| win = hann(ceil(10/Ts));
 | |
| \end{minted}
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| [tf_acc1_est, f] = tfestimate(id.d, id.acc_1, win, [], [], 1/Ts);
 | |
| [co_acc1_est, ~] = mscohere(  id.d, id.acc_1, win, [], [], 1/Ts);
 | |
| [tf_acc2_est, ~] = tfestimate(id.d, id.acc_2, win, [], [], 1/Ts);
 | |
| [co_acc2_est, ~] = mscohere(  id.d, id.acc_2, win, [], [], 1/Ts);
 | |
| 
 | |
| [tf_geo1_est, ~] = tfestimate(id.d, id.geo_1, win, [], [], 1/Ts);
 | |
| [co_geo1_est, ~] = mscohere(  id.d, id.geo_1, win, [], [], 1/Ts);
 | |
| [tf_geo2_est, ~] = tfestimate(id.d, id.geo_2, win, [], [], 1/Ts);
 | |
| [co_geo2_est, ~] = mscohere(  id.d, id.geo_2, win, [], [], 1/Ts);
 | |
| \end{minted}
 | |
| 
 | |
| The (nominal) models of the inertial sensors from the absolute displacement to the generated voltage are defined below:
 | |
| \begin{minted}[]{matlab}
 | |
| G_acc = 1/(1 + s/2/pi/2000)
 | |
| G_geo = -1200*s^2/(s^2 + 2*0.7*2*pi*2*s + (2*pi*2)^2);
 | |
| \end{minted}
 | |
| 
 | |
| These models are very simplistic models, and we then take into account the un-modelled dynamics with dynamical uncertainty.
 | |
| 
 | |
| \subsection{Dynamics uncertainty estimation}
 | |
| \label{sec:org3425338}
 | |
| Weights representing the dynamical uncertainty of the sensors are defined below.
 | |
| \begin{minted}[]{matlab}
 | |
| w_acc = createWeight('n', 2, 'G0', 10,  'G1', 0.2,    'Gc', 1,     'w0', 6*2*pi) * ...
 | |
|         createWeight('n', 2, 'G0', 1,   'G1', 5/0.2,  'Gc', 1/0.2, 'w0', 1300*2*pi);
 | |
| 
 | |
| w_geo = createWeight('n', 2, 'G0', 0.6, 'G1', 0.2,    'Gc', 0.3,   'w0', 3*2*pi) * ...
 | |
|         createWeight('n', 2, 'G0', 1,   'G1', 10/0.2, 'Gc', 1/0.2, 'w0', 800*2*pi);
 | |
| \end{minted}
 | |
| 
 | |
| The measured dynamics are compared with the modelled one as well as the modelled uncertainty in Figure \ref{fig:dyn_uncertainty_acc} for the accelerometers and in Figure \ref{fig:dyn_uncertainty_geo} for the geophones.
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/dyn_uncertainty_acc.png}
 | |
| \caption{\label{fig:dyn_uncertainty_acc}Modeled dynamical uncertainty and meaured dynamics of the accelerometers}
 | |
| \end{figure}
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/dyn_uncertainty_geo.png}
 | |
| \caption{\label{fig:dyn_uncertainty_geo}Modeled dynamical uncertainty and meaured dynamics of the geophones}
 | |
| \end{figure}
 | |
| 
 | |
| \subsection{\(\mathcal{H}_\infty\) Synthesis of Complementary Filters}
 | |
| \label{sec:org496909d}
 | |
| A last weight is now defined that represents the maximum dynamical uncertainty that is allowed for the super sensor.
 | |
| \begin{minted}[]{matlab}
 | |
| wu = inv(createWeight('n', 2, 'G0', 0.7, 'G1', 0.3,   'Gc', 0.4,   'w0', 3*2*pi) * ...
 | |
|          createWeight('n', 2, 'G0', 1,   'G1', 6/0.3, 'Gc', 1/0.3, 'w0', 1200*2*pi));
 | |
| \end{minted}
 | |
| 
 | |
| This dynamical uncertainty is compared with the two sensor uncertainties in Figure \ref{fig:uncertainty_weight_and_sensor_uncertainties}.
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/uncertainty_weight_and_sensor_uncertainties.png}
 | |
| \caption{\label{fig:uncertainty_weight_and_sensor_uncertainties}Individual sensor uncertainty (normalized by their dynamics) and the wanted maximum super sensor noise uncertainty}
 | |
| \end{figure}
 | |
| 
 | |
| The generalized plant used for the synthesis is defined:
 | |
| \begin{minted}[]{matlab}
 | |
| P = [wu*w_acc -wu*w_acc;
 | |
|      0         wu*w_geo;
 | |
|      1         0];
 | |
| \end{minted}
 | |
| 
 | |
| And the \(\mathcal{H}_\infty\) synthesis using the \texttt{hinfsyn} command is performed.
 | |
| \begin{minted}[]{matlab}
 | |
| [H_geo, ~, gamma, ~] = hinfsyn(P, 1, 1,'TOLGAM', 0.001, 'METHOD', 'ric', 'DISPLAY', 'on');
 | |
| \end{minted}
 | |
| 
 | |
| \begin{verbatim}
 | |
| Test bounds:  0.8556 <=  gamma  <=  1.34
 | |
| 
 | |
|   gamma        X>=0        Y>=0       rho(XY)<1    p/f
 | |
| 1.071e+00     0.0e+00     0.0e+00     0.000e+00     p
 | |
| 9.571e-01     0.0e+00     0.0e+00     9.436e-16     p
 | |
| 9.049e-01     0.0e+00     0.0e+00     1.084e-15     p
 | |
| 8.799e-01     0.0e+00     0.0e+00     1.191e-16     p
 | |
| 8.677e-01     0.0e+00     0.0e+00     6.905e-15     p
 | |
| 8.616e-01     0.0e+00     0.0e+00     0.000e+00     p
 | |
| 8.586e-01     1.1e-17     0.0e+00     6.917e-16     p
 | |
| 8.571e-01     0.0e+00     0.0e+00     6.991e-17     p
 | |
| 8.564e-01     0.0e+00     0.0e+00     1.492e-16     p
 | |
| 
 | |
| Best performance (actual): 0.8563
 | |
| \end{verbatim}
 | |
| 
 | |
| The complementary filter is defined as follows:
 | |
| \begin{minted}[]{matlab}
 | |
| H_acc = 1 - H_geo;
 | |
| \end{minted}
 | |
| 
 | |
| The bode plot of the obtained complementary filters is shown in Figure
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/h_infinity_obtained_complementary_filters.png}
 | |
| \caption{\label{fig:h_infinity_obtained_complementary_filters}Bode plot of the obtained complementary filters using the \(\mathcal{H}_\infty\) synthesis}
 | |
| \end{figure}
 | |
| 
 | |
| \subsection{Obtained Super Sensor Dynamical Uncertainty}
 | |
| \label{sec:org8114f7c}
 | |
| The obtained super sensor dynamical uncertainty is shown in Figure \ref{fig:super_sensor_uncertainty_h_infinity}.
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/super_sensor_uncertainty_h_infinity.png}
 | |
| \caption{\label{fig:super_sensor_uncertainty_h_infinity}Obtained Super sensor dynamics uncertainty}
 | |
| \end{figure}
 | |
| 
 | |
| \section{Optimal and Robust sensor fusion using the \(\mathcal{H}_2/\mathcal{H}_\infty\) synthesis}
 | |
| \label{sec:orgcd8e27b}
 | |
| \label{sec:optimal_sensor_fusion}
 | |
| \subsection{Noise and Dynamical uncertainty weights}
 | |
| \label{sec:org55c0ded}
 | |
| \begin{minted}[]{matlab}
 | |
| N_acc = (s/(2*pi*2000) + 1)^2/(s + 0.1*2*pi)/(s + 1e3*2*pi)/(1 + s/2/pi/1e3); % [m/sqrt(Hz)]
 | |
| N_geo = 4e-4*((s + 2*pi)/(2*pi*200) + 1)/(s + 1e3*2*pi)/(1 + s/2/pi/1e3); % [m/sqrt(Hz)]
 | |
| \end{minted}
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| w_acc = createWeight('n', 2, 'G0', 10,  'G1', 0.2,    'Gc', 1,     'w0', 6*2*pi) * ...
 | |
|         createWeight('n', 2, 'G0', 1,   'G1', 5/0.2,  'Gc', 1/0.2, 'w0', 1300*2*pi);
 | |
| 
 | |
| w_geo = createWeight('n', 2, 'G0', 0.6, 'G1', 0.2,    'Gc', 0.3,   'w0', 3*2*pi) * ...
 | |
|         createWeight('n', 2, 'G0', 1,   'G1', 10/0.2, 'Gc', 1/0.2, 'w0', 800*2*pi);
 | |
| \end{minted}
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| wu = inv(createWeight('n', 2, 'G0', 0.7, 'G1', 0.3,   'Gc', 0.4,   'w0', 3*2*pi) * ...
 | |
|          createWeight('n', 2, 'G0', 1,   'G1', 6/0.3, 'Gc', 1/0.3, 'w0', 1200*2*pi));
 | |
| \end{minted}
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| P = [wu*w_acc -wu*w_acc;
 | |
|      0         wu*w_geo;
 | |
|      N_acc    -N_acc;
 | |
|      0         N_geo;
 | |
|      1         0];
 | |
| \end{minted}
 | |
| 
 | |
| And the mixed \(\mathcal{H}_2/\mathcal{H}_\infty\) synthesis is performed.
 | |
| \begin{minted}[]{matlab}
 | |
| [H_geo, ~] = h2hinfsyn(ss(P), 1, 1, 2, [0, 1], 'HINFMAX', 1, 'H2MAX', Inf, 'DKMAX', 100, 'TOL', 1e-3, 'DISPLAY', 'on');
 | |
| \end{minted}
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| H_acc = 1 - H_geo;
 | |
| \end{minted}
 | |
| 
 | |
| \subsection{Obtained Super Sensor Noise}
 | |
| \label{sec:org925fb2f}
 | |
| \begin{minted}[]{matlab}
 | |
| freqs = logspace(0, 4, 1000);
 | |
| PSD_Sgeo = abs(squeeze(freqresp(N_geo, freqs, 'Hz'))).^2;
 | |
| PSD_Sacc = abs(squeeze(freqresp(N_acc, freqs, 'Hz'))).^2;
 | |
| PSD_Hss  = abs(squeeze(freqresp(N_acc*H_acc, freqs, 'Hz'))).^2 + ...
 | |
|            abs(squeeze(freqresp(N_geo*H_geo, freqs, 'Hz'))).^2;
 | |
| \end{minted}
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/psd_sensors_htwo_hinf_synthesis.png}
 | |
| \caption{\label{fig:psd_sensors_htwo_hinf_synthesis}Power Spectral Density of the Super Sensor obtained with the mixed \(\mathcal{H}_2/\mathcal{H}_\infty\) synthesis}
 | |
| \end{figure}
 | |
| 
 | |
| \subsection{Obtained Super Sensor Dynamical Uncertainty}
 | |
| \label{sec:org3ca6152}
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/super_sensor_dynamical_uncertainty_Htwo_Hinf.png}
 | |
| \caption{\label{fig:super_sensor_dynamical_uncertainty_Htwo_Hinf}Super sensor dynamical uncertainty (solid curve) when using the mixed \(\mathcal{H}_2/\mathcal{H}_\infty\) Synthesis}
 | |
| \end{figure}
 | |
| 
 | |
| \subsection{Experimental Super Sensor Dynamical Uncertainty}
 | |
| \label{sec:org9ea8a83}
 | |
| The super sensor dynamics is shown in Figure \ref{fig:super_sensor_optimal_uncertainty}.
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/super_sensor_optimal_uncertainty.png}
 | |
| \caption{\label{fig:super_sensor_optimal_uncertainty}Inertial Sensor dynamics as well as the super sensor dynamics}
 | |
| \end{figure}
 | |
| 
 | |
| \subsection{Experimental Super Sensor Noise}
 | |
| \label{sec:orgfacb28c}
 | |
| The obtained super sensor noise is shown in Figure \ref{fig:super_sensor_optimal_noise}.
 | |
| 
 | |
| \begin{figure}[htbp]
 | |
| \centering
 | |
| \includegraphics[scale=1]{figs/super_sensor_optimal_noise.png}
 | |
| \caption{\label{fig:super_sensor_optimal_noise}ASD of the super sensor obtained using the \(\mathcal{H}_2/\mathcal{H}_\infty\) synthesis}
 | |
| \end{figure}
 | |
| 
 | |
| \section{Matlab Functions}
 | |
| \label{sec:org95268dc}
 | |
| \label{sec:matlab_functions}
 | |
| \subsection{\texttt{createWeight}}
 | |
| \label{sec:org5453f8d}
 | |
| \label{sec:createWeight}
 | |
| 
 | |
| This Matlab function is accessible \href{src/createWeight.m}{here}.
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| function [W] = createWeight(args)
 | |
| % createWeight -
 | |
| %
 | |
| % Syntax: [in_data] = createWeight(in_data)
 | |
| %
 | |
| % Inputs:
 | |
| %    - n  - Weight Order
 | |
| %    - G0 - Low frequency Gain
 | |
| %    - G1 - High frequency Gain
 | |
| %    - Gc - Gain of W at frequency w0
 | |
| %    - w0 - Frequency at which |W(j w0)| = Gc
 | |
| %
 | |
| % Outputs:
 | |
| %    - W - Generated Weight
 | |
| 
 | |
|     arguments
 | |
|         args.n  (1,1) double {mustBeInteger, mustBePositive} = 1
 | |
|         args.G0 (1,1) double {mustBeNumeric, mustBePositive} = 0.1
 | |
|         args.G1 (1,1) double {mustBeNumeric, mustBePositive} = 10
 | |
|         args.Gc (1,1) double {mustBeNumeric, mustBePositive} = 1
 | |
|         args.w0 (1,1) double {mustBeNumeric, mustBePositive} = 1
 | |
|     end
 | |
| 
 | |
|   mustBeBetween(args.G0, args.Gc, args.G1);
 | |
| 
 | |
|   s = tf('s');
 | |
| 
 | |
|   W = (((1/args.w0)*sqrt((1-(args.G0/args.Gc)^(2/args.n))/(1-(args.Gc/args.G1)^(2/args.n)))*s + (args.G0/args.Gc)^(1/args.n))/((1/args.G1)^(1/args.n)*(1/args.w0)*sqrt((1-(args.G0/args.Gc)^(2/args.n))/(1-(args.Gc/args.G1)^(2/args.n)))*s + (1/args.Gc)^(1/args.n)))^args.n;
 | |
| 
 | |
|   end
 | |
| 
 | |
|   % 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 G1.';
 | |
|           throwAsCaller(MException(eid,msg))
 | |
|       end
 | |
|   end
 | |
| \end{minted}
 | |
| 
 | |
| \subsection{\texttt{plotMagUncertainty}}
 | |
| \label{sec:orgc63fba3}
 | |
| \label{sec:plotMagUncertainty}
 | |
| 
 | |
| This Matlab function is accessible \href{src/plotMagUncertainty.m}{here}.
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| function [p] = plotMagUncertainty(W, freqs, args)
 | |
| % plotMagUncertainty -
 | |
| %
 | |
| % Syntax: [p] = plotMagUncertainty(W, freqs, args)
 | |
| %
 | |
| % Inputs:
 | |
| %    - W     - Multiplicative Uncertainty Weight
 | |
| %    - freqs - Frequency Vector [Hz]
 | |
| %    - args  - Optional Arguments:
 | |
| %      - G
 | |
| %      - color_i
 | |
| %      - opacity
 | |
| %
 | |
| % Outputs:
 | |
| %    - p - Plot Handle
 | |
| 
 | |
| arguments
 | |
|     W
 | |
|     freqs double {mustBeNumeric, mustBeNonnegative}
 | |
|     args.G = tf(1)
 | |
|     args.color_i (1,1) double {mustBeInteger, mustBePositive} = 1
 | |
|     args.opacity (1,1) double {mustBeNumeric, mustBeNonnegative} = 0.3
 | |
|     args.DisplayName char = ''
 | |
| end
 | |
| 
 | |
| % Get defaults colors
 | |
| colors = get(groot, 'defaultAxesColorOrder');
 | |
| 
 | |
| p = patch([freqs flip(freqs)], ...
 | |
|           [abs(squeeze(freqresp(args.G, freqs, 'Hz'))).*(1 + abs(squeeze(freqresp(W, freqs, 'Hz')))); ...
 | |
|            flip(abs(squeeze(freqresp(args.G, freqs, 'Hz'))).*max(1 - abs(squeeze(freqresp(W, freqs, 'Hz'))), 1e-6))], 'w', ...
 | |
|           'DisplayName', args.DisplayName);
 | |
| 
 | |
| p.FaceColor = colors(args.color_i, :);
 | |
| p.EdgeColor = 'none';
 | |
| p.FaceAlpha = args.opacity;
 | |
| 
 | |
| end
 | |
| \end{minted}
 | |
| 
 | |
| \subsection{\texttt{plotPhaseUncertainty}}
 | |
| \label{sec:orga4018d2}
 | |
| \label{sec:plotPhaseUncertainty}
 | |
| 
 | |
| This Matlab function is accessible \href{src/plotPhaseUncertainty.m}{here}.
 | |
| 
 | |
| \begin{minted}[]{matlab}
 | |
| function [p] = plotPhaseUncertainty(W, freqs, args)
 | |
| % plotPhaseUncertainty -
 | |
| %
 | |
| % Syntax: [p] = plotPhaseUncertainty(W, freqs, args)
 | |
| %
 | |
| % Inputs:
 | |
| %    - W     - Multiplicative Uncertainty Weight
 | |
| %    - freqs - Frequency Vector [Hz]
 | |
| %    - args  - Optional Arguments:
 | |
| %      - G
 | |
| %      - color_i
 | |
| %      - opacity
 | |
| %
 | |
| % Outputs:
 | |
| %    - p - Plot Handle
 | |
| 
 | |
| arguments
 | |
|     W
 | |
|     freqs double {mustBeNumeric, mustBeNonnegative}
 | |
|     args.G = tf(1)
 | |
|     args.color_i (1,1) double {mustBeInteger, mustBePositive} = 1
 | |
|     args.opacity (1,1) double {mustBeNumeric, mustBePositive} = 0.3
 | |
|     args.DisplayName char = ''
 | |
| end
 | |
| 
 | |
| % Get defaults colors
 | |
| colors = get(groot, 'defaultAxesColorOrder');
 | |
| 
 | |
| % Compute Phase Uncertainty
 | |
| Dphi = 180/pi*asin(abs(squeeze(freqresp(W, freqs, 'Hz'))));
 | |
| Dphi(abs(squeeze(freqresp(W, freqs, 'Hz'))) > 1) = 360;
 | |
| 
 | |
| % Compute Plant Phase
 | |
| G_ang = 180/pi*angle(squeeze(freqresp(args.G, freqs, 'Hz')));
 | |
| 
 | |
| p = patch([freqs flip(freqs)], [G_ang+Dphi; flip(G_ang-Dphi)], 'w', ...
 | |
|           'DisplayName', args.DisplayName);
 | |
| 
 | |
| p.FaceColor = colors(args.color_i, :);
 | |
| p.EdgeColor = 'none';
 | |
| p.FaceAlpha = args.opacity;
 | |
| 
 | |
| end
 | |
| \end{minted}
 | |
| 
 | |
| \bibliography{ref}
 | |
| 
 | |
| \printbibliography
 | |
| \end{document}
 |