Rework analysis: encoders fixed to the plates

This commit is contained in:
Thomas Dehaeze 2021-07-02 14:56:02 +02:00
parent 4b260cdbe8
commit a86d9ea9fd
4 changed files with 392 additions and 356 deletions

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -208,7 +208,7 @@ i_lf = f < 250; % Points for low frequency excitation
i_hf = f > 250; % Points for high frequency excitation
#+end_src
*** DVF Plant
*** Transfer function from Actuator to Encoder
First, let's compute the coherence from the excitation voltage and the displacement as measured by the encoders (Figure [[fig:enc_struts_dvf_coh]]).
#+begin_src matlab
@ -321,7 +321,7 @@ exportFig('figs/enc_struts_dvf_frf.pdf', 'width', 'wide', 'height', 'tall');
#+RESULTS:
[[file:figs/enc_struts_dvf_frf.png]]
*** IFF Plant
*** Transfer function from Actuator to Force Sensor
First, let's compute the coherence from the excitation voltage and the displacement as measured by the encoders (Figure [[fig:enc_struts_iff_coh]]).
#+begin_src matlab
@ -2167,7 +2167,6 @@ exportFig('figs/comp_undamped_opt_iff_gain_diagonal.pdf', 'width', 'wide', 'heig
*** Experimental Results - Damped Plant with Optimal gain
<<sec:iff_struts_opt_gain>>
**** Introduction :ignore:
Let's now look at the $6 \times 6$ damped plant with the optimal gain $g = 400$.
@ -3126,15 +3125,17 @@ In this section, the encoders are fixed to the plates rather than to the struts
[[file:figs/IMG_20210625_083801.jpg]]
It is structured as follow:
- Section [[sec:enc_plates_plant_id]]: The dynamics of the nano-hexapod is identified
- Section [[sec:enc_plates_comp_simscape]]: The identified dynamics is compared with the Simscape model
- Section [[sec:enc_plates_iff]]: The Integral Force Feedback (IFF) control strategy is applied and the dynamics of the damped nano-hexapod is identified and compare with the Simscape model
- Section [[sec:hac_iff_struts]]: The High Authority Control (HAC) in the frame of the struts is developed
- Section [[sec:hac_iff_struts_ref_track]]: Some reference tracking tests are performed in order to experimentally validate the HAC-LAC control strategy.
- Section [[sec:enc_plates_plant_id]]: The dynamics of the nano-hexapod is identified.
- Section [[sec:enc_plates_comp_simscape]]: The identified dynamics is compared with the Simscape model.
- Section [[sec:enc_plates_iff]]: The Integral Force Feedback (IFF) control strategy is applied and the dynamics of the damped nano-hexapod is identified and compare with the Simscape model.
** Identification of the dynamics
<<sec:enc_plates_plant_id>>
*** Introduction :ignore:
In this section, the dynamics of the nano-hexapod with the encoders fixed to the plates is identified.
First, the measurement data are loaded in Section [[sec:enc_plates_plant_id_setup]], then the transfer function matrix from the actuators to the encoders are estimated in Section [[sec:enc_plates_plant_id_dvf]].
Finally, the transfer function matrix from the actuators to the force sensors is estimated in Section [[sec:enc_plates_plant_id_iff]].
*** Matlab Init :noexport:ignore:
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
@ -3156,7 +3157,11 @@ addpath('./mat/');
addpath('./src/');
#+end_src
*** Load Measurement Data
*** Data Loading and Spectral Analysis Setup
<<sec:enc_plates_plant_id_setup>>
The actuators are excited one by one using a low pass filtered white noise.
For each excitation, the 6 force sensors and 6 encoders are measured and saved.
#+begin_src matlab
%% Load Identification Data
meas_data_lf = {};
@ -3166,8 +3171,7 @@ for i = 1:6
end
#+end_src
*** Spectral Analysis - Setup
#+begin_src matlab
#+begin_src matlab :exports none
%% Setup useful variables
% Sampling Time [s]
Ts = (meas_data_lf{1}.t(end) - (meas_data_lf{1}.t(1)))/(length(meas_data_lf{1}.t)-1);
@ -3182,9 +3186,10 @@ win = hanning(ceil(1*Fs));
[~, f] = tfestimate(meas_data_lf{1}.Va, meas_data_lf{1}.de, win, [], [], 1/Ts);
#+end_src
*** DVF Plant
First, let's compute the coherence from the excitation voltage and the displacement as measured by the encoders (Figure [[fig:enc_plates_dvf_coh]]).
*** Transfer function from Actuator to Encoder
<<sec:enc_plates_plant_id_dvf>>
Let's compute the coherence from the excitation voltage $\bm{u}$ and the displacement $d\bm{\mathcal{L}}_m$ as measured by the encoders.
#+begin_src matlab
%% Coherence
coh_dvf = zeros(length(f), 6, 6);
@ -3194,6 +3199,8 @@ for i = 1:6
end
#+end_src
The obtained coherence shown in Figure [[fig:enc_plates_dvf_coh]] is quite good up to 400Hz.
#+begin_src matlab :exports none
%% Coherence for the transfer function from u to dLm
figure;
@ -3227,7 +3234,7 @@ exportFig('figs/enc_plates_dvf_coh.pdf', 'width', 'wide', 'height', 'normal');
#+RESULTS:
[[file:figs/enc_plates_dvf_coh.png]]
Then the 6x6 transfer function matrix is estimated (Figure [[fig:enc_plates_dvf_frf]]).
Then the 6x6 transfer function matrix is estimated.
#+begin_src matlab
%% DVF Plant (transfer function from u to dLm)
G_dvf = zeros(length(f), 6, 6);
@ -3237,6 +3244,7 @@ for i = 1:6
end
#+end_src
The diagonal and off-diagonal terms of this transfer function matrix are shown in Figure [[fig:enc_plates_dvf_frf]].
#+begin_src matlab :exports none
%% Bode plot for the transfer function from u to dLm
figure;
@ -3291,9 +3299,18 @@ exportFig('figs/enc_plates_dvf_frf.pdf', 'width', 'wide', 'height', 'tall');
#+RESULTS:
[[file:figs/enc_plates_dvf_frf.png]]
*** IFF Plant
First, let's compute the coherence from the excitation voltage and the displacement as measured by the encoders (Figure [[fig:enc_plates_iff_coh]]).
#+begin_important
From Figure [[fig:enc_plates_dvf_frf]], we can draw few conclusions on the transfer functions from $\bm{u}$ to $d\bm{\mathcal{L}}_m$ when the encoders are fixed to the plates:
- the decoupling is rather good at low frequency (below the first suspension mode).
The low frequency gain is constant for the off diagonal terms, whereas when the encoders where fixed to the struts, the low frequency gain of the off-diagonal terms were going to zero (Figure [[fig:enc_struts_dvf_frf]]).
- the flexible modes of the struts at 226Hz and 337Hz are indeed shown in the transfer functions, but their amplitudes are rather low.
- the diagonal terms have alternating poles and zeros up to at least 600Hz: the flexible modes of the struts are not affecting the alternating pole/zero pattern. This what not the case when the encoders were fixed to the struts (Figure [[fig:enc_struts_dvf_frf]]).
#+end_important
*** Transfer function from Actuator to Force Sensor
<<sec:enc_plates_plant_id_iff>>
Let's now compute the coherence from the excitation voltage $\bm{u}$ and the voltage $\bm{\tau}_m$ generated by the Force senors.
#+begin_src matlab
%% Coherence for the IFF plant
coh_iff = zeros(length(f), 6, 6);
@ -3303,6 +3320,7 @@ for i = 1:6
end
#+end_src
The coherence is shown in Figure [[fig:enc_plates_iff_coh]], and is very good for from 10Hz up to 2kHz.
#+begin_src matlab :exports none
%% Coherence of the IFF Plant (transfer function from u to taum)
figure;
@ -3336,7 +3354,7 @@ exportFig('figs/enc_plates_iff_coh.pdf', 'width', 'wide', 'height', 'normal');
#+RESULTS:
[[file:figs/enc_plates_iff_coh.png]]
Then the 6x6 transfer function matrix is estimated (Figure [[fig:enc_plates_iff_frf]]).
Then the 6x6 transfer function matrix is estimated.
#+begin_src matlab
%% IFF Plant
G_iff = zeros(length(f), 6, 6);
@ -3346,6 +3364,7 @@ for i = 1:6
end
#+end_src
The bode plot of the diagonal and off-diagonal terms are shown in Figure [[fig:enc_plates_iff_frf]].
#+begin_src matlab :exports none
%% Bode plot of the IFF Plant (transfer function from u to taum)
figure;
@ -3397,19 +3416,27 @@ exportFig('figs/enc_plates_iff_frf.pdf', 'width', 'wide', 'height', 'tall');
#+RESULTS:
[[file:figs/enc_plates_iff_frf.png]]
#+begin_important
It is shown in Figure [[fig:enc_plates_iff_comp_simscape_all]] that:
- The IFF plant has alternating poles and zeros
- The first flexible mode of the struts as 235Hz is appearing, and therefore is should be possible to add some damping to this mode using IFF
- The decoupling is quite good at low frequency (below the first model) as well as high frequency (above the last suspension mode, except near the flexible modes of the top plate)
#+end_important
*** Save Identified Plants
#+begin_src matlab :tangle no
The identified dynamics is saved for further use.
#+begin_src matlab :exports none :tangle no
save('matlab/mat/identified_plants_enc_plates.mat', 'f', 'Ts', 'G_iff', 'G_dvf')
#+end_src
#+begin_src matlab :exports none :eval no
#+begin_src matlab :eval no
save('mat/identified_plants_enc_plates.mat', 'f', 'Ts', 'G_iff', 'G_dvf')
#+end_src
** Comparison with the Simscape Model
<<sec:enc_plates_comp_simscape>>
*** Introduction :ignore:
In this section, the measured dynamics is compared with the dynamics estimated from the Simscape model.
In this section, the measured dynamics done in Section [[sec:enc_plates_plant_id]] is compared with the dynamics estimated from the Simscape model.
*** Matlab Init :noexport:ignore:
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
@ -3449,6 +3476,11 @@ addpath('nass-simscape/src/')
addpath('nass-simscape/mat/')
#+end_src
#+begin_src matlab
%% Load identification data
load('identified_plants_enc_plates.mat', 'f', 'Ts', 'G_iff', 'G_dvf')
#+end_src
#+begin_src matlab
%% Open Simulink Model
mdl = 'nano_hexapod_simscape';
@ -3461,13 +3493,8 @@ Rx = zeros(1, 7);
open(mdl)
#+end_src
*** Load measured FRF
#+begin_src matlab
%% Load data
load('identified_plants_enc_plates.mat', 'f', 'Ts', 'G_iff', 'G_dvf')
#+end_src
*** Dynamics from Actuator to Force Sensors
*** Identification Setup
The nano-hexapod is initialized with the APA taken as flexible models.
#+begin_src matlab
%% Initialize Nano-Hexapod
n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
@ -3476,6 +3503,8 @@ n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
'actuator_type', 'flexible');
#+end_src
*** Dynamics from Actuator to Force Sensors
Then the transfer function from $\bm{u}$ to $\bm{\tau}_m$ is identified using the Simscape model.
#+begin_src matlab
%% Identify the IFF Plant (transfer function from u to taum)
clear io; io_i = 1;
@ -3485,6 +3514,11 @@ io(io_i) = linio([mdl, '/dum'], 1, 'openoutput'); io_i = io_i + 1; % Force Sens
Giff = exp(-s*Ts)*linearize(mdl, io, 0.0, options);
#+end_src
The identified dynamics is compared with the measured FRF:
- Figure [[fig:enc_plates_iff_comp_simscape_all]]: the individual transfer function from $u_1$ (the DAC voltage for the first actuator) to the force sensors of all 6 struts are compared
- Figure [[fig:enc_plates_iff_comp_simscape]]: all the diagonal elements are compared
- Figure [[fig:enc_plates_iff_comp_offdiag_simscape]]: all the off-diagonal elements are compared
#+begin_src matlab :exports none
%% Comparison of the plants (encoder output) when tuning the misalignment
freqs = 2*logspace(1, 3, 1000);
@ -3663,14 +3697,7 @@ exportFig('figs/enc_plates_iff_comp_offdiag_simscape.pdf', 'width', 'wide', 'hei
[[file:figs/enc_plates_iff_comp_offdiag_simscape.png]]
*** Dynamics from Actuator to Encoder
#+begin_src matlab
%% Initialization of the Nano-Hexapod
n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
'flex_top_type', '4dof', ...
'motion_sensor_type', 'plates', ...
'actuator_type', 'flexible');
#+end_src
Now, the dynamics from the DAC voltage $\bm{u}$ to the encoders $d\bm{\mathcal{L}}_m$ is estimated using the Simscape model.
#+begin_src matlab
%% Identify the DVF Plant (transfer function from u to dLm)
clear io; io_i = 1;
@ -3680,6 +3707,11 @@ io(io_i) = linio([mdl, '/dL'], 1, 'openoutput'); io_i = io_i + 1; % Encoders
Gdvf = exp(-s*Ts)*linearize(mdl, io, 0.0, options);
#+end_src
The identified dynamics is compared with the measured FRF:
- Figure [[fig:enc_plates_dvf_comp_simscape_all]]: the individual transfer function from $u_3$ (the DAC voltage for the actuator number 3) to the six encoders
- Figure [[fig:enc_plates_dvf_comp_simscape]]: all the diagonal elements are compared
- Figure [[fig:enc_plates_dvf_comp_offdiag_simscape]]: all the off-diagonal elements are compared
#+begin_src matlab :exports none
%% Comparison of the plants (encoder output) when tuning the misalignment
freqs = 2*logspace(1, 3, 1000);
@ -3858,26 +3890,38 @@ exportFig('figs/enc_plates_dvf_comp_offdiag_simscape.pdf', 'width', 'wide', 'hei
#+RESULTS:
[[file:figs/enc_plates_dvf_comp_offdiag_simscape.png]]
*** Conclusion
#+begin_important
The Simscape model is quite accurate for the transfer function matrices from $\bm{u}$ to $\bm{\tau}_m$ and from $\bm{u}$ to $d\bm{\mathcal{L}}_m$ except at frequencies of the flexible modes of the top-plate.
The Simscape model can therefore be used to develop the control strategies.
#+end_important
** Integral Force Feedback
<<sec:enc_plates_iff>>
*** Introduction :ignore:
In this section, the Integral Force Feedback (IFF) control strategy is applied to the nano-hexapod in order to add damping to the suspension modes.
The control architecture is shown in Figure [[fig:control_architecture_iff]]:
- $\bm{\tau}_m$ is the measured voltage of the 6 force sensors
- $\bm{K}_{\text{IFF}}$ is the $6 \times 6$ diagonal controller
- $\bm{u}$ is the plant input (voltage generated by the 6 DACs)
- $\bm{u}^\prime$ is the new plant inputs with added damping
#+begin_src latex :file control_architecture_iff.pdf
\begin{tikzpicture}
% Blocs
\node[block={3.0cm}{3.0cm}] (P) {Plant};
\node[block={3.0cm}{2.0cm}] (P) {Plant};
\coordinate[] (inputF) at ($(P.south west)!0.5!(P.north west)$);
\coordinate[] (outputF) at ($(P.south east)!0.8!(P.north east)$);
\coordinate[] (outputX) at ($(P.south east)!0.5!(P.north east)$);
\coordinate[] (outputL) at ($(P.south east)!0.2!(P.north east)$);
\coordinate[] (outputF) at ($(P.south east)!0.7!(P.north east)$);
\coordinate[] (outputL) at ($(P.south east)!0.3!(P.north east)$);
\node[block, above=0.4 of P] (Kiff) {$\bm{K}_\text{IFF}$};
\node[addb={+}{}{-}{}{}, left= of inputF] (addF) {};
\node[addb, left= of inputF] (addF) {};
% Connections and labels
\draw[->] (outputF) -- ++(1, 0) node[below left]{$\bm{\tau}_m$};
\draw[->] (outputL) -- ++(1, 0) node[above left]{$d\bm{\mathcal{L}}$};
\draw[->] (outputX) -- ++(1, 0) node[above left]{$\bm{\mathcal{X}}$};
\draw[->] (outputL) -- ++(1, 0) node[below left]{$d\bm{\mathcal{L}}_m$};
\draw[->] ($(outputF) + (0.6, 0)$)node[branch]{} |- (Kiff.east);
\draw[->] (Kiff.west) -| (addF.north);
@ -3891,6 +3935,8 @@ exportFig('figs/enc_plates_dvf_comp_offdiag_simscape.pdf', 'width', 'wide', 'hei
#+RESULTS:
[[file:figs/control_architecture_iff.png]]
- Section [[sec:enc_struts_effect_iff_plant]]
*** 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>>
@ -3947,36 +3993,10 @@ Rx = zeros(1, 7);
colors = colororder;
#+end_src
*** Identification of the IFF Plant
#+begin_src matlab
%% Initialize Nano-Hexapod
n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
'flex_top_type', '4dof', ...
'motion_sensor_type', 'plates', ...
'actuator_type', '2dof');
#+end_src
#+begin_src matlab
%% Identify the IFF Plant (transfer function from u to taum)
clear io; io_i = 1;
io(io_i) = linio([mdl, '/du'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
io(io_i) = linio([mdl, '/Fm'], 1, 'openoutput'); io_i = io_i + 1; % Force Sensors
Giff = exp(-s*Ts)*linearize(mdl, io, 0.0, options);
#+end_src
*** Effect of IFF on the plant - Simscape Model
#+begin_src matlab
load('Kiff.mat', 'Kiff')
#+end_src
#+begin_src matlab
%% Identify the (damped) transfer function from u to dLm for different values of the IFF gain
clear io; io_i = 1;
io(io_i) = linio([mdl, '/du'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
io(io_i) = linio([mdl, '/dL'], 1, 'openoutput'); io_i = io_i + 1; % Plate Displacement (encoder)
#+end_src
<<sec:enc_struts_effect_iff_plant>>
The nano-hexapod is initialized with flexible APA and the encoders fixed to the struts.
#+begin_src matlab
%% Initialize the Simscape model in closed loop
n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
@ -3985,10 +4005,27 @@ n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
'actuator_type', 'flexible');
#+end_src
The same controller as the one developed when the encoder were fixed to the struts is used.
#+begin_src matlab
%% Optimal IFF controller
load('Kiff.mat', 'Kiff')
#+end_src
The transfer function from $\bm{u}^\prime$ to $d\bm{\mathcal{L}}_m$ is identified.
#+begin_src matlab
%% Identify the (damped) transfer function from u to dLm for different values of the IFF gain
clear io; io_i = 1;
io(io_i) = linio([mdl, '/du'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
io(io_i) = linio([mdl, '/dL'], 1, 'openoutput'); io_i = io_i + 1; % Plate Displacement (encoder)
#+end_src
First in Open-Loop:
#+begin_src matlab
%% Transfer function from u to dL (open-loop)
Gd_ol = exp(-s*Ts)*linearize(mdl, io, 0.0, options);
#+end_src
And then with the IFF controller:
#+begin_src matlab
%% Initialize the Simscape model in closed loop
n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
@ -3996,19 +4033,21 @@ n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
'motion_sensor_type', 'plates', ...
'actuator_type', 'flexible', ...
'controller_type', 'iff');
#+end_src
#+begin_src matlab
%% Transfer function from u to dL (IFF)
Gd_iff = exp(-s*Ts)*linearize(mdl, io, 0.0, options);
#+end_src
#+begin_src matlab :results value replace :exports results :tangle no
It is first verified that the system is stable:
#+begin_src matlab :results value replace :exports both :tangle no
isstable(Gd_iff)
#+end_src
#+RESULTS:
: 1
The diagonal and off-diagonal terms of the $6 \times 6$ transfer function matrices identified are compared in Figure [[fig:enc_plates_iff_gains_effect_dvf_plant]].
It is shown, as was the case when the encoders were fixed to the struts, that the IFF control strategy is very effective in damping the suspension modes of the nano-hexapod.
#+begin_src matlab :exports none
%% Bode plot of the transfer function from u to dLm for tested values of the IFF gain
freqs = 2*logspace(1, 3, 1000);
@ -4083,11 +4122,11 @@ exportFig('figs/enc_plates_iff_gains_effect_dvf_plant.pdf', 'width', 'wide', 'he
#+RESULTS:
[[file:figs/enc_plates_iff_gains_effect_dvf_plant.png]]
*** Experimental Results - Damped Plant with Optimal gain
**** Introduction :ignore:
Let's now look at the $6 \times 6$ damped plant with the optimal gain $g = 400$.
*** Effect of IFF on the plant - FRF
The IFF control strategy is experimentally implemented.
The (damped) transfer function from $\bm{u}^\prime$ to $d\bm{\mathcal{L}}_m$ is experimentally identified.
**** Load Data
The identification data are loaded:
#+begin_src matlab
%% Load Identification Data
meas_iff_plates = {};
@ -4097,15 +4136,11 @@ for i = 1:6
end
#+end_src
**** Spectral Analysis - Setup
And the parameters used for the transfer function estimation are defined below.
#+begin_src matlab
%% Setup useful variables
% Sampling Time [s]
Ts = (meas_iff_plates{1}.t(end) - (meas_iff_plates{1}.t(1)))/(length(meas_iff_plates{1}.t)-1);
% Sampling Frequency [Hz]
Fs = 1/Ts;
% Hannning Windows
win = hanning(ceil(1*Fs));
@ -4113,34 +4148,9 @@ win = hanning(ceil(1*Fs));
[~, f] = tfestimate(meas_iff_plates{1}.Va, meas_iff_plates{1}.de, win, [], [], 1/Ts);
#+end_src
**** Simscape Model
The estimation is performed using the =tfestimate= command.
#+begin_src matlab
load('Kiff.mat', 'Kiff')
#+end_src
#+begin_src matlab
%% Initialize the Simscape model in closed loop
n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
'flex_top_type', '4dof', ...
'motion_sensor_type', 'plates', ...
'actuator_type', 'flexible', ...
'controller_type', 'iff');
#+end_src
#+begin_src matlab
%% Identify the (damped) transfer function from u to dLm for different values of the IFF gain
clear io; io_i = 1;
io(io_i) = linio([mdl, '/du'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
io(io_i) = linio([mdl, '/dL'], 1, 'openoutput'); io_i = io_i + 1; % Plate Displacement (encoder)
#+end_src
#+begin_src matlab
Gd_iff_opt = exp(-s*Ts)*linearize(mdl, io, 0.0, options);
#+end_src
**** DVF Plant
#+begin_src matlab
%% IFF Plant
%% Estimation of the transfer function matrix from u to dL when IFF is applied
G_enc_iff_opt = zeros(length(f), 6, 6);
for i = 1:6
@ -4148,223 +4158,7 @@ for i = 1:6
end
#+end_src
#+begin_src matlab :exports none
%% Comparison of the plants (encoder output) when tuning the misalignment
freqs = 2*logspace(1, 3, 1000);
i_input = 1;
figure;
tiledlayout(2, 3, 'TileSpacing', 'Compact', 'Padding', 'None');
ax1 = nexttile();
hold on;
plot(f, abs(G_enc_iff_opt(:, 1, i_input)));
plot(freqs, abs(squeeze(freqresp(Gd_iff_opt(1, i_input), freqs, 'Hz'))));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
set(gca, 'XTickLabel',[]); ylabel('Amplitude [m/V]');
title(sprintf('$d\\tau_{m1}/u_{%i}$', i_input));
ax2 = nexttile();
hold on;
plot(f, abs(G_enc_iff_opt(:, 2, i_input)));
plot(freqs, abs(squeeze(freqresp(Gd_iff_opt(2, i_input), freqs, 'Hz'))));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
set(gca, 'XTickLabel',[]); set(gca, 'YTickLabel',[]);
title(sprintf('$d\\tau_{m2}/u_{%i}$', i_input));
ax3 = nexttile();
hold on;
plot(f, abs(G_enc_iff_opt(:, 3, i_input)), ...
'DisplayName', 'Meas.');
plot(freqs, abs(squeeze(freqresp(Gd_iff_opt(3, i_input), freqs, 'Hz'))), ...
'DisplayName', 'Model');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
set(gca, 'XTickLabel',[]); set(gca, 'YTickLabel',[]);
legend('location', 'southeast', 'FontSize', 8);
title(sprintf('$d\\tau_{m3}/u_{%i}$', i_input));
ax4 = nexttile();
hold on;
plot(f, abs(G_enc_iff_opt(:, 4, i_input)));
plot(freqs, abs(squeeze(freqresp(Gd_iff_opt(4, i_input), freqs, 'Hz'))));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('Amplitude [m/V]');
title(sprintf('$d\\tau_{m4}/u_{%i}$', i_input));
ax5 = nexttile();
hold on;
plot(f, abs(G_enc_iff_opt(:, 5, i_input)));
plot(freqs, abs(squeeze(freqresp(Gd_iff_opt(5, i_input), freqs, 'Hz'))));
hold off;
xlabel('Frequency [Hz]'); set(gca, 'YTickLabel',[]);
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
title(sprintf('$d\\tau_{m5}/u_{%i}$', i_input));
ax6 = nexttile();
hold on;
plot(f, abs(G_enc_iff_opt(:, 6, i_input)));
plot(freqs, abs(squeeze(freqresp(Gd_iff_opt(6, i_input), freqs, 'Hz'))));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); set(gca, 'YTickLabel',[]);
title(sprintf('$d\\tau_{m6}/u_{%i}$', i_input));
linkaxes([ax1,ax2,ax3,ax4,ax5,ax6],'xy');
xlim([20, 2e3]); ylim([1e-8, 1e-4]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/enc_plates_opt_iff_comp_simscape_all.pdf', 'width', 'full', 'height', 'tall');
#+end_src
#+name: fig:enc_plates_opt_iff_comp_simscape_all
#+caption: FRF from one actuator to all the encoders when the plant is damped using IFF
#+RESULTS:
[[file:figs/enc_plates_opt_iff_comp_simscape_all.png]]
#+begin_src matlab :exports none
%% Bode plot for the transfer function from u to dLm
freqs = 2*logspace(1, 3, 1000);
figure;
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
ax1 = nexttile([2,1]);
hold on;
% Diagonal Elements FRF
plot(f, abs(G_enc_iff_opt(:,1,1)), 'color', [colors(1,:), 0.2], ...
'DisplayName', '$d\mathcal{L}_{m,i}/u_i$ - FRF')
for i = 2:6
plot(f, abs(G_enc_iff_opt(:,i,i)), 'color', [colors(1,:), 0.2], ...
'HandleVisibility', 'off');
end
% Diagonal Elements Model
set(gca,'ColorOrderIndex',2)
plot(freqs, abs(squeeze(freqresp(Gd_iff_opt(1,1), freqs, 'Hz'))), '-', ...
'DisplayName', '$d\mathcal{L}_{m,i}/u_i$ - Model')
for i = 2:6
set(gca,'ColorOrderIndex',2)
plot(freqs, abs(squeeze(freqresp(Gd_iff_opt(i,i), freqs, 'Hz'))), '-', ...
'HandleVisibility', 'off');
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude $d_e/V_{exc}$ [m/V]'); set(gca, 'XTickLabel',[]);
ylim([1e-8, 1e-4]);
legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 3);
ax2 = nexttile;
hold on;
for i =1:6
plot(f, 180/pi*angle(G_enc_iff_opt(:,i,i)), 'color', [colors(1,:), 0.2]);
set(gca,'ColorOrderIndex',2)
plot(freqs, 180/pi*angle(squeeze(freqresp(Gd_iff_opt(i,i), freqs, 'Hz'))));
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
hold off;
yticks(-360:90:360);
ylim([-180, 180]);
linkaxes([ax1,ax2],'x');
xlim([20, 2e3]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/damped_iff_plates_plant_comp_diagonal.pdf', 'width', 'wide', 'height', 'tall');
#+end_src
#+name: fig:damped_iff_plates_plant_comp_diagonal
#+caption: Comparison of the diagonal elements of the transfer functions from $\bm{u}$ to $d\bm{\mathcal{L}}_m$ with active damping (IFF) applied with an optimal gain $g = 400$
#+RESULTS:
[[file:figs/damped_iff_plates_plant_comp_diagonal.png]]
#+begin_src matlab :exports none
%% Bode plot for the transfer function from u to dLm
freqs = 2*logspace(1, 3, 1000);
figure;
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
ax1 = nexttile([2,1]);
hold on;
% Off diagonal FRF
plot(f, abs(G_enc_iff_opt(:,1,2)), 'color', [colors(1,:), 0.2], ...
'DisplayName', '$d\mathcal{L}_{m,i}/u_j$ - FRF')
for i = 1:5
for j = i+1:6
plot(f, abs(G_enc_iff_opt(:,i,j)), 'color', [colors(1,:), 0.2], ...
'HandleVisibility', 'off');
end
end
% Off diagonal Model
set(gca,'ColorOrderIndex',2)
plot(freqs, abs(squeeze(freqresp(Gd_iff_opt(1,2), freqs, 'Hz'))), '-', ...
'DisplayName', '$d\mathcal{L}_{m,i}/u_j$ - Model')
for i = 1:5
for j = i+1:6
set(gca,'ColorOrderIndex',2)
plot(freqs, abs(squeeze(freqresp(Gd_iff_opt(i,j), freqs, 'Hz'))), ...
'HandleVisibility', 'off');
end
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude $d_e/V_{exc}$ [m/V]'); set(gca, 'XTickLabel',[]);
ylim([1e-8, 1e-4]);
legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 3);
ax2 = nexttile;
hold on;
% Off diagonal FRF
for i = 1:5
for j = i+1:6
plot(f, 180/pi*angle(G_enc_iff_opt(:,i,j)), 'color', [colors(1,:), 0.2]);
end
end
% Off diagonal Model
for i = 1:5
for j = i+1:6
set(gca,'ColorOrderIndex',2)
plot(freqs, 180/pi*angle(squeeze(freqresp(Gd_iff_opt(i,j), freqs, 'Hz'))));
end
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
hold off;
yticks(-360:90:360);
ylim([-180, 180]);
linkaxes([ax1,ax2],'x');
xlim([20, 2e3]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/damped_iff_plates_plant_comp_off_diagonal.pdf', 'width', 'wide', 'height', 'tall');
#+end_src
#+name: fig:damped_iff_plates_plant_comp_off_diagonal
#+caption: Comparison of the off-diagonal elements of the transfer functions from $\bm{u}$ to $d\bm{\mathcal{L}}_m$ with active damping (IFF) applied with an optimal gain $g = 400$
#+RESULTS:
[[file:figs/damped_iff_plates_plant_comp_off_diagonal.png]]
*** Effect of IFF on the plant - FRF
#+begin_src matlab :tangle no
load('identified_plants_enc_plates.mat', 'f', 'G_dvf');
#+end_src
The obtained diagonal and off-diagonal elements of the transfer function from $\bm{u}^\prime$ to $d\bm{\mathcal{L}}_m$ are shown in Figure [[fig:enc_plant_plates_effect_iff]] both without and with IFF.
#+begin_src matlab :exports none
%% Bode plot of the transfer function from u to dLm for tested values of the IFF gain
freqs = 2*logspace(1, 3, 1000);
@ -4437,17 +4231,259 @@ exportFig('figs/enc_plant_plates_effect_iff.pdf', 'width', 'wide', 'height', 'ta
#+RESULTS:
[[file:figs/enc_plant_plates_effect_iff.png]]
#+begin_important
As was predicted with the Simscape model, the IFF control strategy is very effective in damping the suspension modes of the nano-hexapod.
Little damping is also applied on the first flexible mode of the strut at 235Hz.
However, no damping is applied on other modes, such as the flexible modes of the top plate.
#+end_important
*** Comparison of the measured FRF and the Simscape model
Let's now compare the obtained damped plants obtained experimentally with the one extracted from Simscape:
- Figure [[fig:enc_plates_opt_iff_comp_simscape_all]]: the individual transfer function from $u_1^\prime$ to the six encoders are comapred
- Figure [[fig:damped_iff_plates_plant_comp_diagonal]]: all the diagonal elements are compared
- Figure [[fig:damped_iff_plates_plant_comp_off_diagonal]]: all the off-diagonal elements are compared
#+begin_src matlab :exports none
%% Comparison of the plants (encoder output) when tuning the misalignment
freqs = 2*logspace(1, 3, 1000);
i_input = 1;
figure;
tiledlayout(2, 3, 'TileSpacing', 'Compact', 'Padding', 'None');
ax1 = nexttile();
hold on;
plot(f, abs(G_enc_iff_opt(:, 1, i_input)));
plot(freqs, abs(squeeze(freqresp(Gd_iff(1, i_input), freqs, 'Hz'))));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
set(gca, 'XTickLabel',[]); ylabel('Amplitude [m/V]');
title(sprintf('$d\\tau_{m1}/u_{%i}$', i_input));
ax2 = nexttile();
hold on;
plot(f, abs(G_enc_iff_opt(:, 2, i_input)));
plot(freqs, abs(squeeze(freqresp(Gd_iff(2, i_input), freqs, 'Hz'))));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
set(gca, 'XTickLabel',[]); set(gca, 'YTickLabel',[]);
title(sprintf('$d\\tau_{m2}/u_{%i}$', i_input));
ax3 = nexttile();
hold on;
plot(f, abs(G_enc_iff_opt(:, 3, i_input)), ...
'DisplayName', 'Meas.');
plot(freqs, abs(squeeze(freqresp(Gd_iff(3, i_input), freqs, 'Hz'))), ...
'DisplayName', 'Model');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
set(gca, 'XTickLabel',[]); set(gca, 'YTickLabel',[]);
legend('location', 'southeast', 'FontSize', 8);
title(sprintf('$d\\tau_{m3}/u_{%i}$', i_input));
ax4 = nexttile();
hold on;
plot(f, abs(G_enc_iff_opt(:, 4, i_input)));
plot(freqs, abs(squeeze(freqresp(Gd_iff(4, i_input), freqs, 'Hz'))));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); ylabel('Amplitude [m/V]');
title(sprintf('$d\\tau_{m4}/u_{%i}$', i_input));
ax5 = nexttile();
hold on;
plot(f, abs(G_enc_iff_opt(:, 5, i_input)));
plot(freqs, abs(squeeze(freqresp(Gd_iff(5, i_input), freqs, 'Hz'))));
hold off;
xlabel('Frequency [Hz]'); set(gca, 'YTickLabel',[]);
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
title(sprintf('$d\\tau_{m5}/u_{%i}$', i_input));
ax6 = nexttile();
hold on;
plot(f, abs(G_enc_iff_opt(:, 6, i_input)));
plot(freqs, abs(squeeze(freqresp(Gd_iff(6, i_input), freqs, 'Hz'))));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
xlabel('Frequency [Hz]'); set(gca, 'YTickLabel',[]);
title(sprintf('$d\\tau_{m6}/u_{%i}$', i_input));
linkaxes([ax1,ax2,ax3,ax4,ax5,ax6],'xy');
xlim([20, 2e3]); ylim([1e-8, 1e-4]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/enc_plates_opt_iff_comp_simscape_all.pdf', 'width', 'full', 'height', 'tall');
#+end_src
#+name: fig:enc_plates_opt_iff_comp_simscape_all
#+caption: FRF from one actuator to all the encoders when the plant is damped using IFF
#+RESULTS:
[[file:figs/enc_plates_opt_iff_comp_simscape_all.png]]
#+begin_src matlab :exports none
%% Bode plot for the transfer function from u to dLm
freqs = 2*logspace(1, 3, 1000);
figure;
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
ax1 = nexttile([2,1]);
hold on;
% Diagonal Elements FRF
plot(f, abs(G_enc_iff_opt(:,1,1)), 'color', [colors(1,:), 0.2], ...
'DisplayName', '$d\mathcal{L}_{m,i}/u_i$ - FRF')
for i = 2:6
plot(f, abs(G_enc_iff_opt(:,i,i)), 'color', [colors(1,:), 0.2], ...
'HandleVisibility', 'off');
end
% Diagonal Elements Model
set(gca,'ColorOrderIndex',2)
plot(freqs, abs(squeeze(freqresp(Gd_iff(1,1), freqs, 'Hz'))), '-', ...
'DisplayName', '$d\mathcal{L}_{m,i}/u_i$ - Model')
for i = 2:6
set(gca,'ColorOrderIndex',2)
plot(freqs, abs(squeeze(freqresp(Gd_iff(i,i), freqs, 'Hz'))), '-', ...
'HandleVisibility', 'off');
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude $d_e/V_{exc}$ [m/V]'); set(gca, 'XTickLabel',[]);
ylim([1e-8, 1e-4]);
legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 3);
ax2 = nexttile;
hold on;
for i =1:6
plot(f, 180/pi*angle(G_enc_iff_opt(:,i,i)), 'color', [colors(1,:), 0.2]);
set(gca,'ColorOrderIndex',2)
plot(freqs, 180/pi*angle(squeeze(freqresp(Gd_iff(i,i), freqs, 'Hz'))));
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
hold off;
yticks(-360:90:360);
ylim([-180, 180]);
linkaxes([ax1,ax2],'x');
xlim([20, 2e3]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/damped_iff_plates_plant_comp_diagonal.pdf', 'width', 'wide', 'height', 'tall');
#+end_src
#+name: fig:damped_iff_plates_plant_comp_diagonal
#+caption: Comparison of the diagonal elements of the transfer functions from $\bm{u}$ to $d\bm{\mathcal{L}}_m$ with active damping (IFF) applied with an optimal gain $g = 400$
#+RESULTS:
[[file:figs/damped_iff_plates_plant_comp_diagonal.png]]
#+begin_src matlab :exports none
%% Bode plot for the transfer function from u to dLm
freqs = 2*logspace(1, 3, 1000);
figure;
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
ax1 = nexttile([2,1]);
hold on;
% Off diagonal FRF
plot(f, abs(G_enc_iff_opt(:,1,2)), 'color', [colors(1,:), 0.2], ...
'DisplayName', '$d\mathcal{L}_{m,i}/u_j$ - FRF')
for i = 1:5
for j = i+1:6
plot(f, abs(G_enc_iff_opt(:,i,j)), 'color', [colors(1,:), 0.2], ...
'HandleVisibility', 'off');
end
end
% Off diagonal Model
set(gca,'ColorOrderIndex',2)
plot(freqs, abs(squeeze(freqresp(Gd_iff(1,2), freqs, 'Hz'))), '-', ...
'DisplayName', '$d\mathcal{L}_{m,i}/u_j$ - Model')
for i = 1:5
for j = i+1:6
set(gca,'ColorOrderIndex',2)
plot(freqs, abs(squeeze(freqresp(Gd_iff(i,j), freqs, 'Hz'))), ...
'HandleVisibility', 'off');
end
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude $d_e/V_{exc}$ [m/V]'); set(gca, 'XTickLabel',[]);
ylim([1e-8, 1e-4]);
legend('location', 'southeast', 'FontSize', 8, 'NumColumns', 3);
ax2 = nexttile;
hold on;
% Off diagonal FRF
for i = 1:5
for j = i+1:6
plot(f, 180/pi*angle(G_enc_iff_opt(:,i,j)), 'color', [colors(1,:), 0.2]);
end
end
% Off diagonal Model
for i = 1:5
for j = i+1:6
set(gca,'ColorOrderIndex',2)
plot(freqs, 180/pi*angle(squeeze(freqresp(Gd_iff(i,j), freqs, 'Hz'))));
end
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
hold off;
yticks(-360:90:360);
ylim([-180, 180]);
linkaxes([ax1,ax2],'x');
xlim([20, 2e3]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/damped_iff_plates_plant_comp_off_diagonal.pdf', 'width', 'wide', 'height', 'tall');
#+end_src
#+name: fig:damped_iff_plates_plant_comp_off_diagonal
#+caption: Comparison of the off-diagonal elements of the transfer functions from $\bm{u}$ to $d\bm{\mathcal{L}}_m$ with active damping (IFF) applied with an optimal gain $g = 400$
#+RESULTS:
[[file:figs/damped_iff_plates_plant_comp_off_diagonal.png]]
#+begin_important
From Figures [[fig:damped_iff_plates_plant_comp_diagonal]] and [[fig:damped_iff_plates_plant_comp_off_diagonal]], it is clear that the Simscape model very well represents the dynamics of the nano-hexapod.
This is true to around 400Hz, then the dynamics depends on the flexible modes of the top plate which are not modelled.
#+end_important
*** Save Damped Plant
#+begin_src matlab :tangle no
The experimentally identified plant is saved for further use.
#+begin_src matlab :exports none:tangle no
save('matlab/mat/damped_plant_enc_plates.mat', 'f', 'Ts', 'G_enc_iff_opt')
#+end_src
#+begin_src matlab :exports none :eval no
#+begin_src matlab :eval no
save('mat/damped_plant_enc_plates.mat', 'f', 'Ts', 'G_enc_iff_opt')
#+end_src
** Conclusion
* HAC-IFF
#+begin_important
In this section, the dynamics of the nano-hexapod with the encoders fixed to the plates is studied.
It has been found that:
- The measured dynamics is in agreement with the dynamics of the simscape model, up to the flexible modes of the top plate.
See figures [[fig:enc_plates_iff_comp_simscape]] and [[fig:enc_plates_iff_comp_offdiag_simscape]] for the transfer function to the force sensors and Figures [[fig:enc_plates_dvf_comp_simscape]] and [[fig:enc_plates_dvf_comp_offdiag_simscape]]for the transfer functions to the encoders
- The Integral Force Feedback strategy is very effective in damping the suspension modes of the nano-hexapod (Figure [[fig:enc_plant_plates_effect_iff]]).
- The transfer function from $\bm{u}^\prime$ to $d\bm{\mathcal{L}}_m$ show nice dynamical properties and is a much better candidate for the high-authority-control than when the encoders were fixed to the struts.
At least up to the flexible modes of the top plate, the diagonal elements of the transfer function matrix have alternating poles and zeros, and the phase is moving smoothly.
Only the flexible modes of the top plates seems to be problematic for control.
#+end_important
* High Authority Control with Integral Force Feedback
<<sec:hac_iff>>
** Introduction :ignore: