-
+
Sensor Fusion - Test Bench
-
-
-
-
-
-
+
+
-#+HTML_HEAD:
-#+HTML_HEAD:
+#+HTML_HEAD:
+#+HTML_HEAD:
#+PROPERTY: header-args:latex :headers '("\\usepackage{tikz}" "\\usepackage{import}" "\\import{$HOME/Cloud/tikz/org/}{config.tex}")
#+PROPERTY: header-args:latex+ :imagemagick t :fit yes
diff --git a/index.tex b/index.tex
deleted file mode 100644
index 05bdd75..0000000
--- a/index.tex
+++ /dev/null
@@ -1,1234 +0,0 @@
-% 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}
diff --git a/js/bootstrap.min.js b/js/bootstrap.min.js
deleted file mode 100644
index c8f82e5..0000000
--- a/js/bootstrap.min.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/*!
- * Bootstrap v3.3.4 (http://getbootstrap.com)
- * Copyright 2011-2015 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- */
-if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.4",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.4",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active"));a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.4",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.4",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=c(d),f={relatedTarget:this};e.hasClass("open")&&(e.trigger(b=a.Event("hide.bs.dropdown",f)),b.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f)))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.4",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('').insertAfter(a(this)).on("click",b);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(b){if(/(38|40|27|32)/.test(b.which)&&!/input|textarea/i.test(b.target.tagName)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var e=c(d),g=e.hasClass("open");if(!g&&27!=b.which||g&&27==b.which)return 27==b.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find('[role="menu"]'+h+', [role="listbox"]'+h);if(i.length){var j=i.index(b.target);38==b.which&&j>0&&j--,40==b.which&&j').appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.adjustDialog()},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(this.options.viewport.selector||this.options.viewport),this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c&&c.$tip&&c.$tip.is(":visible")?void(c.hoverState="in"):(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.options.container?a(this.options.container):this.$element.parent(),p=this.getPosition(o);h="bottom"==h&&k.bottom+m>p.bottom?"top":"top"==h&&k.top-mp.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.width&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type)})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.4",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'