Reworked all the section about the Gravimeter

This commit is contained in:
2020-11-25 09:17:11 +01:00
parent 87a0d98e01
commit e69e5a5d2b
32 changed files with 83245 additions and 1118 deletions

342
index.org
View File

@@ -44,10 +44,6 @@
:END:
** Introduction
#+name: fig:gravimeter_model
#+caption: Model of the gravimeter
[[file:figs/gravimeter_model.png]]
** Matlab Init :noexport:ignore:
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
<<matlab-dir>>
@@ -66,6 +62,10 @@
open('gravimeter.slx')
#+end_src
#+name: fig:gravimeter_model
#+caption: Model of the gravimeter
[[file:figs/gravimeter_model.png]]
Parameters
#+begin_src matlab
l = 1.0; % Length of the mass [m]
@@ -78,7 +78,7 @@ Parameters
I = 115; % Inertia [kg m^2]
k = 15e3; % Actuator Stiffness [N/m]
c = 0.03; % Actuator Damping [N/(m/s)]
c = 2e1; % Actuator Damping [N/(m/s)]
deq = 0.2; % Length of the actuators [m]
@@ -107,9 +107,18 @@ Parameters
The inputs and outputs of the plant are shown in Figure [[fig:gravimeter_plant_schematic]].
More precisely there are three inputs (the three actuator forces):
\begin{equation}
\bm{\tau} = \begin{bmatrix}\tau_1 \\ \tau_2 \\ \tau_2 \end{bmatrix}
\end{equation}
And 4 outputs (the two 2-DoF accelerometers):
\begin{equation}
\bm{a} = \begin{bmatrix} a_{1x} \\ a_{1z} \\ a_{2x} \\ a_{2z} \end{bmatrix}
\end{equation}
#+begin_src latex :file gravimeter_plant_schematic.pdf :tangle no :exports results
\begin{tikzpicture}
\node[block] (G) {$G$};
\node[block] (G) {$\bm{G}$};
% Connections and labels
\draw[<-] (G.west) -- ++(-2.0, 0) node[above right]{$\bm{\tau} = \begin{bmatrix}\tau_1 \\ \tau_2 \\ \tau_2 \end{bmatrix}$};
@@ -122,31 +131,20 @@ The inputs and outputs of the plant are shown in Figure [[fig:gravimeter_plant_s
#+RESULTS:
[[file:figs/gravimeter_plant_schematic.png]]
\begin{equation}
\bm{a} = \begin{bmatrix} a_{1x} \\ a_{1z} \\ a_{2x} \\ a_{2z} \end{bmatrix}
\end{equation}
\begin{equation}
\bm{\tau} = \begin{bmatrix}\tau_1 \\ \tau_2 \\ \tau_2 \end{bmatrix}
\end{equation}
We can check the poles of the plant:
#+begin_src matlab :results output replace :exports results
#+begin_src matlab :results value replace :exports results
pole(G)
#+end_src
#+RESULTS:
#+begin_example
-0.000183495485977108 + 13.546056874877i
-0.000183495485977108 - 13.546056874877i
-7.49842878906757e-05 + 8.65934902322567i
-7.49842878906757e-05 - 8.65934902322567i
-1.33171230256362e-05 + 3.64924169037897i
-1.33171230256362e-05 - 3.64924169037897i
#+end_example
| -0.12243+13.551i |
| -0.12243-13.551i |
| -0.05+8.6601i |
| -0.05-8.6601i |
| -0.0088785+3.6493i |
| -0.0088785-3.6493i |
The plant as 6 states as expected (2 translations + 1 rotation)
As expected, the plant as 6 states (2 translations + 1 rotation)
#+begin_src matlab :results output replace
size(G)
#+end_src
@@ -198,25 +196,32 @@ The bode plot of all elements of the plant are shown in Figure [[fig:open_loop_t
Consider the control architecture shown in Figure [[fig:gravimeter_decouple_jacobian]].
The Jacobian matrix $J_{\tau}$ is used to transform forces applied by the three actuators into forces/torques applied on the gravimeter at its center of mass.
The Jacobian matrix $J_{a}$ is used to compute the vertical acceleration, horizontal acceleration and rotational acceleration of the mass with respect to its center of mass.
The Jacobian matrix $J_{\tau}$ is used to transform forces applied by the three actuators into forces/torques applied on the gravimeter at its center of mass:
\begin{equation}
\begin{bmatrix} \tau_1 \\ \tau_2 \\ \tau_3 \end{bmatrix} = J_{\tau}^{-T} \begin{bmatrix} F_x \\ F_z \\ M_y \end{bmatrix}
\end{equation}
The Jacobian matrix $J_{a}$ is used to compute the vertical acceleration, horizontal acceleration and rotational acceleration of the mass with respect to its center of mass:
\begin{equation}
\begin{bmatrix} a_x \\ a_z \\ a_{R_y} \end{bmatrix} = J_{a}^{-1} \begin{bmatrix} a_{x1} \\ a_{z1} \\ a_{x2} \\ a_{z2} \end{bmatrix}
\end{equation}
We thus define a new plant as defined in Figure [[fig:gravimeter_decouple_jacobian]].
\[ G_x(s) = J_a G(s) J_{\tau}^{-T} \]
\[ \bm{G}_x(s) = J_a^{-1} \bm{G}(s) J_{\tau}^{-T} \]
$G_x(s)$ correspond to the transfer function from forces and torques applied to the gravimeter at its center of mass to the absolute acceleration of the gravimeter's center of mass.
$\bm{G}_x(s)$ correspond to the $3 \times 3$transfer function matrix from forces and torques applied to the gravimeter at its center of mass to the absolute acceleration of the gravimeter's center of mass (Figure [[fig:gravimeter_decouple_jacobian]]).
#+begin_src latex :file gravimeter_decouple_jacobian.pdf :tangle no :exports results
\begin{tikzpicture}
\node[block] (G) {$G$};
\node[block] (G) {$\bm{G}$};
\node[block, left=0.6 of G] (Jt) {$J_{\tau}^{-T}$};
\node[block, right=0.6 of G] (Ja) {$J_{a}$};
\node[block, right=0.6 of G] (Ja) {$J_{a}^{-1}$};
% Connections and labels
\draw[<-] (Jt.west) -- ++(-1.1, 0) node[above right]{$\bm{\mathcal{F}}$};
\draw[<-] (Jt.west) -- ++(-2.5, 0) node[above right]{$\bm{\mathcal{F}} = \begin{bmatrix}F_x \\ F_z \\ M_y \end{bmatrix}$};
\draw[->] (Jt.east) -- (G.west) node[above left]{$\bm{\tau}$};
\draw[->] (G.east) -- (Ja.west) node[above left]{$\bm{a}$};
\draw[->] (Ja.east) -- ++( 1.1, 0) node[above left]{$\bm{\mathcal{X}}$};
\draw[->] (Ja.east) -- ++( 2.6, 0) node[above left]{$\bm{\mathcal{A}} = \begin{bmatrix}a_x \\ a_z \\ a_{R_y} \end{bmatrix}$};
\begin{scope}[on background layer]
\node[fit={(Jt.south west) (Ja.north east)}, fill=black!10!white, draw, dashed, inner sep=14pt] (Gx) {};
@@ -230,7 +235,7 @@ $G_x(s)$ correspond to the transfer function from forces and torques applied to
#+RESULTS:
[[file:figs/gravimeter_decouple_jacobian.png]]
The jacobian corresponding to the sensors and actuators are defined below.
The Jacobian corresponding to the sensors and actuators are defined below:
#+begin_src matlab
Ja = [1 0 h/2
0 1 -l/2
@@ -242,12 +247,21 @@ The jacobian corresponding to the sensors and actuators are defined below.
0 1 la];
#+end_src
And the plant $\bm{G}_x$ is computed:
#+begin_src matlab
Gx = pinv(Ja)*G*pinv(Jt');
Gx.InputName = {'Fx', 'Fz', 'My'};
Gx.OutputName = {'Dx', 'Dz', 'Ry'};
#+end_src
#+begin_src matlab :results output replace :exports results
size(Gx)
#+end_src
#+RESULTS:
: size(Gx)
: State-space model with 3 outputs, 3 inputs, and 6 states.
The diagonal and off-diagonal elements of $G_x$ are shown in Figure [[fig:gravimeter_jacobian_plant]].
#+begin_src matlab :exports none
@@ -285,10 +299,13 @@ The diagonal and off-diagonal elements of $G_x$ are shown in Figure [[fig:gravim
#+RESULTS:
[[file:figs/gravimeter_jacobian_plant.png]]
** Real Approximation of $G$ at the decoupling frequency
<<sec:gravimeter_real_approx>>
** SVD Decoupling
<<sec:gravimeter_svd_decoupling>>
Let's compute a real approximation of the complex matrix $H_1$ which corresponds to the the transfer function $G_u(j\omega_c)$ from forces applied by the actuators to the measured acceleration of the top platform evaluated at the frequency $\omega_c$.
In order to decouple the plant using the SVD, first a real approximation of the plant transfer function matrix as the crossover frequency is required.
Let's compute a real approximation of the complex matrix $H_1$ which corresponds to the the transfer function $G(j\omega_c)$ from forces applied by the actuators to the measured acceleration of the top platform evaluated at the frequency $\omega_c$.
#+begin_src matlab
wc = 2*pi*10; % Decoupling frequency [rad/s]
@@ -298,7 +315,7 @@ Let's compute a real approximation of the complex matrix $H_1$ which corresponds
The real approximation is computed as follows:
#+begin_src matlab
D = pinv(real(H1'*H1));
H1 = inv(D*real(H1'*diag(exp(j*angle(diag(H1*D*H1.'))/2))));
H1 = pinv(D*real(H1'*diag(exp(j*angle(diag(H1*D*H1.'))/2))));
#+end_src
#+begin_src matlab :exports results :results value table replace :tangle no
@@ -307,25 +324,24 @@ The real approximation is computed as follows:
#+caption: Real approximate of $G$ at the decoupling frequency $\omega_c$
#+RESULTS:
| 0.0026 | -3.7e-05 | 3.7e-05 |
| 1.9e-10 | 0.0025 | 0.0025 |
| -0.0078 | 0.0045 | -0.0045 |
| 0.0092 | -0.0039 | 0.0039 |
| -0.0039 | 0.0048 | 0.00028 |
| -0.004 | 0.0038 | -0.0038 |
| 8.4e-09 | 0.0025 | 0.0025 |
** SVD Decoupling
<<sec:gravimeter_svd_decoupling>>
First, the Singular Value Decomposition of $H_1$ is performed:
Now, the Singular Value Decomposition of $H_1$ is performed:
\[ H_1 = U \Sigma V^H \]
#+begin_src matlab
[U,~,V] = svd(H1);
[U,S,V] = svd(H1);
#+end_src
The obtained matrices $U$ and $V$ are used to decouple the system as shown in Figure [[fig:gravimeter_decouple_svd]].
#+begin_src latex :file gravimeter_decouple_svd.pdf :tangle no :exports results
\begin{tikzpicture}
\node[block] (G) {$G_u$};
\node[block] (G) {$\bm{G}$};
\node[block, left=0.6 of G.west] (V) {$V^{-T}$};
\node[block, right=0.6 of G.east] (U) {$U^{-1}$};
@@ -349,14 +365,26 @@ The obtained matrices $U$ and $V$ are used to decouple the system as shown in Fi
[[file:figs/gravimeter_decouple_svd.png]]
The decoupled plant is then:
\[ G_{SVD}(s) = U^{-1} G_u(s) V^{-H} \]
\[ \bm{G}_{SVD}(s) = U^{-1} \bm{G}(s) V^{-H} \]
#+begin_src matlab
Gsvd = inv(U)*G*inv(V');
#+end_src
The diagonal and off-diagonal elements of the "SVD" plant are shown in Figure [[fig:gravimeter_svd_plant]].
#+begin_src matlab :results output replace :exports results
size(Gsvd)
#+end_src
#+RESULTS:
: size(Gsvd)
: State-space model with 4 outputs, 3 inputs, and 6 states.
The 4th output (corresponding to the null singular value) is discarded, and we only keep the $3 \times 3$ plant:
#+begin_src matlab
Gsvd = Gsvd(1:3, 1:3);
#+end_src
The diagonal and off-diagonal elements of the "SVD" plant are shown in Figure [[fig:gravimeter_svd_plant]].
#+begin_src matlab :exports none
freqs = logspace(-1, 2, 1000);
@@ -379,7 +407,7 @@ The diagonal and off-diagonal elements of the "SVD" plant are shown in Figure [[
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('Magnitude');
legend('location', 'southeast', 'FontSize', 8);
legend('location', 'southwest', 'FontSize', 8);
ylim([1e-8, 1e0]);
#+end_src
@@ -392,7 +420,7 @@ The diagonal and off-diagonal elements of the "SVD" plant are shown in Figure [[
#+RESULTS:
[[file:figs/gravimeter_svd_plant.png]]
** TODO Verification of the decoupling using the "Gershgorin Radii"
** Verification of the decoupling using the "Gershgorin Radii"
<<sec:comp_decoupling>>
The "Gershgorin Radii" is computed for the coupled plant $G(s)$, for the "Jacobian plant" $G_x(s)$ and the "SVD Decoupled Plant" $G_{SVD}(s)$:
@@ -407,9 +435,9 @@ This is computed over the following frequencies.
#+begin_src matlab :exports none
% Gershgorin Radii for the coupled plant:
Gr_coupled = zeros(length(freqs), size(Gu,2));
H = abs(squeeze(freqresp(Gu, freqs, 'Hz')));
for out_i = 1:size(Gu,2)
Gr_coupled = zeros(length(freqs), size(G,2));
H = abs(squeeze(freqresp(G, freqs, 'Hz')));
for out_i = 1:size(G,2)
Gr_coupled(:, out_i) = squeeze((sum(H(out_i,:,:)) - H(out_i,out_i,:))./H(out_i, out_i, :));
end
@@ -434,7 +462,7 @@ This is computed over the following frequencies.
plot(freqs, Gr_coupled(:,1), 'DisplayName', 'Coupled');
plot(freqs, Gr_decoupled(:,1), 'DisplayName', 'SVD');
plot(freqs, Gr_jacobian(:,1), 'DisplayName', 'Jacobian');
for in_i = 2:6
for in_i = 2:3
set(gca,'ColorOrderIndex',1)
plot(freqs, Gr_coupled(:,in_i), 'HandleVisibility', 'off');
set(gca,'ColorOrderIndex',2)
@@ -446,22 +474,22 @@ This is computed over the following frequencies.
hold off;
xlabel('Frequency (Hz)'); ylabel('Gershgorin Radii')
legend('location', 'northwest');
ylim([1e-3, 1e3]);
ylim([1e-4, 1e2]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/simscape_model_gershgorin_radii.pdf', 'eps', true, 'width', 'wide', 'height', 'normal');
exportFig('figs/gravimeter_gershgorin_radii.pdf', 'eps', true, 'width', 'wide', 'height', 'normal');
#+end_src
#+name: fig:simscape_model_gershgorin_radii
#+name: fig:gravimeter_gershgorin_radii
#+caption: Gershgorin Radii of the Coupled and Decoupled plants
#+RESULTS:
[[file:figs/simscape_model_gershgorin_radii.png]]
[[file:figs/gravimeter_gershgorin_radii.png]]
** TODO Obtained Decoupled Plants
** Obtained Decoupled Plants
<<sec:gravimeter_decoupled_plant>>
The bode plot of the diagonal and off-diagonal elements of $G_{SVD}$ are shown in Figure [[fig:simscape_model_decoupled_plant_svd]].
The bode plot of the diagonal and off-diagonal elements of $G_{SVD}$ are shown in Figure [[fig:gravimeter_decoupled_plant_svd]].
#+begin_src matlab :exports none
freqs = logspace(-1, 2, 1000);
@@ -472,8 +500,8 @@ The bode plot of the diagonal and off-diagonal elements of $G_{SVD}$ are shown i
% Magnitude
ax1 = nexttile([2, 1]);
hold on;
for i_in = 1:6
for i_out = [1:i_in-1, i_in+1:6]
for i_in = 1:3
for i_out = [1:i_in-1, i_in+1:3]
plot(freqs, abs(squeeze(freqresp(Gsvd(i_out, i_in), freqs, 'Hz'))), 'color', [0,0,0,0.2], ...
'HandleVisibility', 'off');
end
@@ -481,20 +509,20 @@ The bode plot of the diagonal and off-diagonal elements of $G_{SVD}$ are shown i
plot(freqs, abs(squeeze(freqresp(Gsvd(1, 2), freqs, 'Hz'))), 'color', [0,0,0,0.5], ...
'DisplayName', '$G_{SVD}(i,j),\ i \neq j$');
set(gca,'ColorOrderIndex',1)
for ch_i = 1:6
for ch_i = 1:3
plot(freqs, abs(squeeze(freqresp(Gsvd(ch_i, ch_i), freqs, 'Hz'))), ...
'DisplayName', sprintf('$G_{SVD}(%i,%i)$', ch_i, ch_i));
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Magnitude'); set(gca, 'XTickLabel',[]);
legend('location', 'northwest');
ylim([1e-1, 1e5])
legend('location', 'southwest');
ylim([1e-8, 1e0])
% Phase
ax2 = nexttile;
hold on;
for ch_i = 1:6
for ch_i = 1:3
plot(freqs, 180/pi*angle(squeeze(freqresp(Gsvd(ch_i, ch_i), freqs, 'Hz'))));
end
hold off;
@@ -507,15 +535,15 @@ The bode plot of the diagonal and off-diagonal elements of $G_{SVD}$ are shown i
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/simscape_model_decoupled_plant_svd.pdf', 'eps', true, 'width', 'wide', 'height', 'tall');
exportFig('figs/gravimeter_decoupled_plant_svd.pdf', 'eps', true, 'width', 'wide', 'height', 'tall');
#+end_src
#+name: fig:simscape_model_decoupled_plant_svd
#+name: fig:gravimeter_decoupled_plant_svd
#+caption: Decoupled Plant using SVD
#+RESULTS:
[[file:figs/simscape_model_decoupled_plant_svd.png]]
[[file:figs/gravimeter_decoupled_plant_svd.png]]
Similarly, the bode plots of the diagonal elements and off-diagonal elements of the decoupled plant $G_x(s)$ using the Jacobian are shown in Figure [[fig:simscape_model_decoupled_plant_jacobian]].
Similarly, the bode plots of the diagonal elements and off-diagonal elements of the decoupled plant $G_x(s)$ using the Jacobian are shown in Figure [[fig:gravimeter_decoupled_plant_jacobian]].
#+begin_src matlab :exports none
freqs = logspace(-1, 2, 1000);
@@ -526,8 +554,8 @@ Similarly, the bode plots of the diagonal elements and off-diagonal elements of
% Magnitude
ax1 = nexttile([2, 1]);
hold on;
for i_in = 1:6
for i_out = [1:i_in-1, i_in+1:6]
for i_in = 1:3
for i_out = [1:i_in-1, i_in+1:3]
plot(freqs, abs(squeeze(freqresp(Gx(i_out, i_in), freqs, 'Hz'))), 'color', [0,0,0,0.2], ...
'HandleVisibility', 'off');
end
@@ -535,106 +563,101 @@ Similarly, the bode plots of the diagonal elements and off-diagonal elements of
plot(freqs, abs(squeeze(freqresp(Gx(1, 2), freqs, 'Hz'))), 'color', [0,0,0,0.5], ...
'DisplayName', '$G_x(i,j),\ i \neq j$');
set(gca,'ColorOrderIndex',1)
plot(freqs, abs(squeeze(freqresp(Gx('Ax', 'Fx'), freqs, 'Hz'))), 'DisplayName', '$G_x(1,1) = A_x/F_x$');
plot(freqs, abs(squeeze(freqresp(Gx('Ay', 'Fy'), freqs, 'Hz'))), 'DisplayName', '$G_x(2,2) = A_y/F_y$');
plot(freqs, abs(squeeze(freqresp(Gx('Az', 'Fz'), freqs, 'Hz'))), 'DisplayName', '$G_x(3,3) = A_z/F_z$');
plot(freqs, abs(squeeze(freqresp(Gx('Arx', 'Mx'), freqs, 'Hz'))), 'DisplayName', '$G_x(4,4) = A_{R_x}/M_x$');
plot(freqs, abs(squeeze(freqresp(Gx('Ary', 'My'), freqs, 'Hz'))), 'DisplayName', '$G_x(5,5) = A_{R_y}/M_y$');
plot(freqs, abs(squeeze(freqresp(Gx('Arz', 'Mz'), freqs, 'Hz'))), 'DisplayName', '$G_x(6,6) = A_{R_z}/M_z$');
plot(freqs, abs(squeeze(freqresp(Gx(1, 1), freqs, 'Hz'))), 'DisplayName', '$G_x(1,1) = A_x/F_x$');
plot(freqs, abs(squeeze(freqresp(Gx(2, 2), freqs, 'Hz'))), 'DisplayName', '$G_x(2,2) = A_y/F_y$');
plot(freqs, abs(squeeze(freqresp(Gx(3, 3), freqs, 'Hz'))), 'DisplayName', '$G_x(3,3) = R_y/M_y$');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Magnitude'); set(gca, 'XTickLabel',[]);
legend('location', 'northwest');
ylim([1e-2, 2e6])
legend('location', 'southwest');
ylim([1e-8, 1e0])
% Phase
ax2 = nexttile;
hold on;
plot(freqs, 180/pi*angle(squeeze(freqresp(Gx('Ax', 'Fx'), freqs, 'Hz'))));
plot(freqs, 180/pi*angle(squeeze(freqresp(Gx('Ay', 'Fy'), freqs, 'Hz'))));
plot(freqs, 180/pi*angle(squeeze(freqresp(Gx('Az', 'Fz'), freqs, 'Hz'))));
plot(freqs, 180/pi*angle(squeeze(freqresp(Gx('Arx', 'Mx'), freqs, 'Hz'))));
plot(freqs, 180/pi*angle(squeeze(freqresp(Gx('Ary', 'My'), freqs, 'Hz'))));
plot(freqs, 180/pi*angle(squeeze(freqresp(Gx('Arz', 'Mz'), freqs, 'Hz'))));
plot(freqs, 180/pi*angle(squeeze(freqresp(Gx(1, 1), freqs, 'Hz'))));
plot(freqs, 180/pi*angle(squeeze(freqresp(Gx(2, 2), freqs, 'Hz'))));
plot(freqs, 180/pi*angle(squeeze(freqresp(Gx(3, 3), freqs, 'Hz'))));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([0, 180]);
ylim([-180, 180]);
yticks([0:45:360]);
linkaxes([ax1,ax2],'x');
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/simscape_model_decoupled_plant_jacobian.pdf', 'eps', true, 'width', 'wide', 'height', 'tall');
exportFig('figs/gravimeter_decoupled_plant_jacobian.pdf', 'eps', true, 'width', 'wide', 'height', 'tall');
#+end_src
#+name: fig:simscape_model_decoupled_plant_jacobian
#+name: fig:gravimeter_decoupled_plant_jacobian
#+caption: Gravimeter Platform Plant from forces (resp. torques) applied by the legs to the acceleration (resp. angular acceleration) of the platform as well as all the coupling terms between the two (non-diagonal terms of the transfer function matrix)
#+RESULTS:
[[file:figs/simscape_model_decoupled_plant_jacobian.png]]
[[file:figs/gravimeter_decoupled_plant_jacobian.png]]
** TODO Diagonal Controller
** Diagonal Controller
<<sec:gravimeter_diagonal_control>>
The control diagram for the centralized control is shown in Figure [[fig:centralized_control]].
The control diagram for the centralized control is shown in Figure [[fig:centralized_control_gravimeter]].
The controller $K_c$ is "working" in an cartesian frame.
The Jacobian is used to convert forces in the cartesian frame to forces applied by the actuators.
#+begin_src latex :file centralized_control.pdf :tangle no :exports results
#+begin_src latex :file centralized_control_gravimeter.pdf :tangle no :exports results
\begin{tikzpicture}
\node[block={2cm}{1.5cm}] (G) {$\begin{bmatrix}G_d\\G_u\end{bmatrix}$};
\node[above] at (G.north) {$\bm{G}$};
\node[block, below right=0.6 and -0.5 of G] (K) {$K_c$};
\node[block, below left= 0.6 and -0.5 of G] (J) {$J^{-T}$};
% Inputs of the controllers
\coordinate[] (inputd) at ($(G.south west)!0.75!(G.north west)$);
\coordinate[] (inputu) at ($(G.south west)!0.25!(G.north west)$);
\node[block] (G) {$\bm{G}$};
\node[block, left=0.6 of G] (Jt) {$J_{\tau}^{-T}$};
\node[block, right=0.6 of G] (Ja) {$J_{a}^{-1}$};
\node[block, left=1.2 of Jt] (K) {$K_c$};
% Connections and labels
\draw[<-] (inputd) -- ++(-0.8, 0) node[above right]{$D_w$};
\draw[->] (G.east) -- ++(2.0, 0) node[above left]{$a$};
\draw[->] ($(G.east)+(1.4, 0)$)node[branch]{} |- (K.east);
\draw[->] (K.west) -- (J.east) node[above right]{$\mathcal{F}$};
\draw[->] (J.west) -- ++(-0.6, 0) |- (inputu) node[above left]{$\tau$};
\draw[->] (Jt.east) -- (G.west) node[above left]{$\bm{\tau}$};
\draw[->] (G.east) -- (Ja.west) node[above left]{$\bm{a}$};
\draw[->] (Ja.east) -- ++(1.4, 0);
\draw[->] ($(Ja.east) + (0.8, 0)$) node[branch]{} node[above]{$\bm{\mathcal{A}}$} -- ++(0, -1.2) -| ($(K.west) + (-0.6, 0)$) -- (K.west);
\draw[->] (K.east) -- (Jt.west) node[above left]{$\bm{\mathcal{F}}$};
\begin{scope}[on background layer]
\node[fit={(Jt.south west) (Ja.north east)}, fill=black!10!white, draw, dashed, inner sep=14pt] (Gx) {};
\node[below right] at (Gx.north west) {$\bm{G}_x$};
\end{scope}
\end{tikzpicture}
#+end_src
#+name: fig:centralized_control
#+name: fig:centralized_control_gravimeter
#+caption: Control Diagram for the Centralized control
#+RESULTS:
[[file:figs/centralized_control.png]]
[[file:figs/centralized_control_gravimeter.png]]
The SVD control architecture is shown in Figure [[fig:svd_control]].
The SVD control architecture is shown in Figure [[fig:svd_control_gravimeter]].
The matrices $U$ and $V$ are used to decoupled the plant $G$.
#+begin_src latex :file svd_control.pdf :tangle no :exports results
#+begin_src latex :file svd_control_gravimeter.pdf :tangle no :exports results
\begin{tikzpicture}
\node[block={2cm}{1.5cm}] (G) {$\begin{bmatrix}G_d\\G_u\end{bmatrix}$};
\node[above] at (G.north) {$\bm{G}$};
\node[block, below right=0.6 and 0 of G] (U) {$U^{-1}$};
\node[block, below=0.6 of G] (K) {$K_{\text{SVD}}$};
\node[block, below left= 0.6 and 0 of G] (V) {$V^{-T}$};
\node[block] (G) {$\bm{G}$};
% Inputs of the controllers
\coordinate[] (inputd) at ($(G.south west)!0.75!(G.north west)$);
\coordinate[] (inputu) at ($(G.south west)!0.25!(G.north west)$);
\node[block, left=0.6 of G.west] (V) {$V^{-T}$};
\node[block, right=0.6 of G.east] (U) {$U^{-1}$};
\node[block, left=1.2 of V] (K) {$K_c$};
% Connections and labels
\draw[<-] (inputd) -- ++(-0.8, 0) node[above right]{$D_w$};
\draw[->] (G.east) -- ++(2.5, 0) node[above left]{$a$};
\draw[->] ($(G.east)+(2.0, 0)$) node[branch]{} |- (U.east);
\draw[->] (U.west) -- (K.east);
\draw[->] (K.west) -- (V.east);
\draw[->] (V.west) -- ++(-0.6, 0) |- (inputu) node[above left]{$\tau$};
\draw[->] (V.east) -- (G.west) node[above left]{$\tau$};
\draw[->] (G.east) -- (U.west) node[above left]{$a$};
\draw[->] (U.east) -- ++( 1.4, 0);
\draw[->] ($(U.east) + (0.8, 0)$) node[branch]{} node[above]{$y$} -- ++(0, -1.2) -| ($(K.west) + (-0.6, 0)$) -- (K.west);
\draw[->] (K.east) -- (V.west) node[above left]{$u$};
\begin{scope}[on background layer]
\node[fit={(V.south west) (G.north-|U.east)}, fill=black!10!white, draw, dashed, inner sep=14pt] (Gsvd) {};
\node[below right] at (Gsvd.north west) {$\bm{G}_{SVD}$};
\end{scope}
\end{tikzpicture}
#+end_src
#+name: fig:svd_control
#+name: fig:svd_control_gravimeter
#+caption: Control Diagram for the SVD control
#+RESULTS:
[[file:figs/svd_control.png]]
[[file:figs/svd_control_gravimeter.png]]
We choose the controller to be a low pass filter:
@@ -643,20 +666,21 @@ We choose the controller to be a low pass filter:
$G_0$ is tuned such that the crossover frequency corresponding to the diagonal terms of the loop gain is equal to $\omega_c$
#+begin_src matlab
wc = 2*pi*80; % Crossover Frequency [rad/s]
wc = 2*pi*10; % Crossover Frequency [rad/s]
w0 = 2*pi*0.1; % Controller Pole [rad/s]
#+end_src
#+begin_src matlab
K_cen = diag(1./diag(abs(evalfr(Gx, j*wc))))*(1/abs(evalfr(1/(1 + s/w0), j*wc)))/(1 + s/w0);
L_cen = K_cen*Gx;
G_cen = feedback(G, pinv(J')*K_cen, [7:12], [1:6]);
G_cen = feedback(G, pinv(Jt')*K_cen*pinv(Ja));
#+end_src
#+begin_src matlab
K_svd = diag(1./diag(abs(evalfr(Gsvd, j*wc))))*(1/abs(evalfr(1/(1 + s/w0), j*wc)))/(1 + s/w0);
L_svd = K_svd*Gsvd;
G_svd = feedback(G, inv(V')*K_svd*inv(U), [7:12], [1:6]);
U_inv = inv(U);
G_svd = feedback(G, inv(V')*K_svd*U_inv(1:3, :));
#+end_src
The obtained diagonal elements of the loop gains are shown in Figure [[fig:gravimeter_comp_loop_gain_diagonal]].
@@ -671,7 +695,7 @@ The obtained diagonal elements of the loop gains are shown in Figure [[fig:gravi
ax1 = nexttile([2, 1]);
hold on;
plot(freqs, abs(squeeze(freqresp(L_svd(1, 1), freqs, 'Hz'))), 'DisplayName', '$L_{SVD}(i,i)$');
for i_in_out = 2:6
for i_in_out = 2:3
set(gca,'ColorOrderIndex',1)
plot(freqs, abs(squeeze(freqresp(L_svd(i_in_out, i_in_out), freqs, 'Hz'))), 'HandleVisibility', 'off');
end
@@ -679,7 +703,7 @@ The obtained diagonal elements of the loop gains are shown in Figure [[fig:gravi
set(gca,'ColorOrderIndex',2)
plot(freqs, abs(squeeze(freqresp(L_cen(1, 1), freqs, 'Hz'))), ...
'DisplayName', '$L_{J}(i,i)$');
for i_in_out = 2:6
for i_in_out = 2:3
set(gca,'ColorOrderIndex',2)
plot(freqs, abs(squeeze(freqresp(L_cen(i_in_out, i_in_out), freqs, 'Hz'))), 'HandleVisibility', 'off');
end
@@ -692,12 +716,12 @@ The obtained diagonal elements of the loop gains are shown in Figure [[fig:gravi
% Phase
ax2 = nexttile;
hold on;
for i_in_out = 1:6
for i_in_out = 1:3
set(gca,'ColorOrderIndex',1)
plot(freqs, 180/pi*angle(squeeze(freqresp(L_svd(i_in_out, i_in_out), freqs, 'Hz'))));
end
set(gca,'ColorOrderIndex',2)
for i_in_out = 1:6
for i_in_out = 1:3
set(gca,'ColorOrderIndex',2)
plot(freqs, 180/pi*angle(squeeze(freqresp(L_cen(i_in_out, i_in_out), freqs, 'Hz'))));
end
@@ -719,7 +743,7 @@ The obtained diagonal elements of the loop gains are shown in Figure [[fig:gravi
#+RESULTS:
[[file:figs/gravimeter_comp_loop_gain_diagonal.png]]
** TODO Closed-Loop system Performances
** Closed-Loop system Performances
<<sec:gravimeter_closed_loop_results>>
Let's first verify the stability of the closed-loop systems:
@@ -747,56 +771,42 @@ The obtained transmissibility in Open-loop, for the centralized control as well
freqs = logspace(-2, 2, 1000);
figure;
tiledlayout(2, 2, 'TileSpacing', 'None', 'Padding', 'None');
tiledlayout(1, 3, 'TileSpacing', 'None', 'Padding', 'None');
ax1 = nexttile;
hold on;
plot(freqs, abs(squeeze(freqresp(G( 'Ax', 'Dwx')/s^2, freqs, 'Hz'))), 'DisplayName', 'Open-Loop');
plot(freqs, abs(squeeze(freqresp(G_cen('Ax', 'Dwx')/s^2, freqs, 'Hz'))), 'DisplayName', 'Centralized');
plot(freqs, abs(squeeze(freqresp(G_svd('Ax', 'Dwx')/s^2, freqs, 'Hz'))), '--', 'DisplayName', 'SVD');
set(gca,'ColorOrderIndex',1)
plot(freqs, abs(squeeze(freqresp(G( 'Ay', 'Dwy')/s^2, freqs, 'Hz'))), 'HandleVisibility', 'off');
plot(freqs, abs(squeeze(freqresp(G_cen('Ay', 'Dwy')/s^2, freqs, 'Hz'))), 'HandleVisibility', 'off');
plot(freqs, abs(squeeze(freqresp(G_svd('Ay', 'Dwy')/s^2, freqs, 'Hz'))), '--', 'HandleVisibility', 'off');
plot(freqs, abs(squeeze(freqresp(G( 1,1)/s^2, freqs, 'Hz'))), 'DisplayName', 'Open-Loop');
plot(freqs, abs(squeeze(freqresp(G_cen(1,1)/s^2, freqs, 'Hz'))), 'DisplayName', 'Centralized');
plot(freqs, abs(squeeze(freqresp(G_svd(1,1)/s^2, freqs, 'Hz'))), '--', 'DisplayName', 'SVD');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('$D_x/D_{w,x}$, $D_y/D_{w, y}$'); set(gca, 'XTickLabel',[]);
ylabel('Transmissibility'); xlabel('Frequency [Hz]');
title('$D_x/D_{w,x}$');
legend('location', 'southwest');
ax2 = nexttile;
hold on;
plot(freqs, abs(squeeze(freqresp(G( 'Az', 'Dwz')/s^2, freqs, 'Hz'))));
plot(freqs, abs(squeeze(freqresp(G_cen('Az', 'Dwz')/s^2, freqs, 'Hz'))));
plot(freqs, abs(squeeze(freqresp(G_svd('Az', 'Dwz')/s^2, freqs, 'Hz'))), '--');
plot(freqs, abs(squeeze(freqresp(G( 2,2)/s^2, freqs, 'Hz'))));
plot(freqs, abs(squeeze(freqresp(G_cen(2,2)/s^2, freqs, 'Hz'))));
plot(freqs, abs(squeeze(freqresp(G_svd(2,2)/s^2, freqs, 'Hz'))), '--');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('$D_z/D_{w,z}$'); set(gca, 'XTickLabel',[]);
set(gca, 'YTickLabel',[]); xlabel('Frequency [Hz]');
title('$D_z/D_{w,z}$');
ax3 = nexttile;
hold on;
plot(freqs, abs(squeeze(freqresp(G( 'Arx', 'Rwx')/s^2, freqs, 'Hz'))));
plot(freqs, abs(squeeze(freqresp(G_cen('Arx', 'Rwx')/s^2, freqs, 'Hz'))));
plot(freqs, abs(squeeze(freqresp(G_svd('Arx', 'Rwx')/s^2, freqs, 'Hz'))), '--');
set(gca,'ColorOrderIndex',1)
plot(freqs, abs(squeeze(freqresp(G( 'Ary', 'Rwy')/s^2, freqs, 'Hz'))));
plot(freqs, abs(squeeze(freqresp(G_cen('Ary', 'Rwy')/s^2, freqs, 'Hz'))));
plot(freqs, abs(squeeze(freqresp(G_svd('Ary', 'Rwy')/s^2, freqs, 'Hz'))), '--');
plot(freqs, abs(squeeze(freqresp(G( 3,3)/s^2, freqs, 'Hz'))));
plot(freqs, abs(squeeze(freqresp(G_cen(3,3)/s^2, freqs, 'Hz'))));
plot(freqs, abs(squeeze(freqresp(G_svd(3,3)/s^2, freqs, 'Hz'))), '--');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('$R_x/R_{w,x}$, $R_y/R_{w,y}$'); xlabel('Frequency [Hz]');
set(gca, 'YTickLabel',[]); xlabel('Frequency [Hz]');
title('$R_y/R_{w,y}$');
ax4 = nexttile;
hold on;
plot(freqs, abs(squeeze(freqresp(G( 'Arz', 'Rwz')/s^2, freqs, 'Hz'))));
plot(freqs, abs(squeeze(freqresp(G_cen('Arz', 'Rwz')/s^2, freqs, 'Hz'))));
plot(freqs, abs(squeeze(freqresp(G_svd('Arz', 'Rwz')/s^2, freqs, 'Hz'))), '--');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('$R_z/R_{w,z}$'); xlabel('Frequency [Hz]');
linkaxes([ax1,ax2,ax3,ax4],'xy');
linkaxes([ax1,ax2,ax3],'xy');
xlim([freqs(1), freqs(end)]);
ylim([1e-3, 1e2]);
ylim([1e-7, 1e-2]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace