Add analysis on the DVF complex conjugate zero
Before Width: | Height: | Size: 185 KiB After Width: | Height: | Size: 166 KiB |
BIN
docs/figs/nano_hexapod_cartesian_plant_perfect_joints.pdf
Normal file
BIN
docs/figs/nano_hexapod_cartesian_plant_perfect_joints.png
Normal file
After Width: | Height: | Size: 136 KiB |
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 125 KiB |
Before Width: | Height: | Size: 163 KiB After Width: | Height: | Size: 146 KiB |
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 116 KiB |
@ -44,6 +44,15 @@ addpath('matlab/nano_hexapod');
|
|||||||
open('matlab/nano_hexapod/nano_hexapod.slx')
|
open('matlab/nano_hexapod/nano_hexapod.slx')
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src matlab
|
||||||
|
%% Options for Linearized
|
||||||
|
options = linearizeOptions;
|
||||||
|
options.SampleTime = 0;
|
||||||
|
|
||||||
|
%% Name of the Simulink File
|
||||||
|
mdl = 'nano_hexapod';
|
||||||
|
#+end_src
|
||||||
|
|
||||||
** Nano Hexapod - Configuration
|
** Nano Hexapod - Configuration
|
||||||
<<sec:nano_hexapod_conf>>
|
<<sec:nano_hexapod_conf>>
|
||||||
*** Introduction :ignore:
|
*** Introduction :ignore:
|
||||||
@ -169,13 +178,6 @@ We here wish to compare the plant from actuators to the encoders when the encode
|
|||||||
|
|
||||||
We initialize the identification parameters.
|
We initialize the identification parameters.
|
||||||
#+begin_src matlab
|
#+begin_src matlab
|
||||||
%% Options for Linearized
|
|
||||||
options = linearizeOptions;
|
|
||||||
options.SampleTime = 0;
|
|
||||||
|
|
||||||
%% Name of the Simulink File
|
|
||||||
mdl = 'nano_hexapod';
|
|
||||||
|
|
||||||
%% Input/Output definition
|
%% Input/Output definition
|
||||||
clear io; io_i = 1;
|
clear io; io_i = 1;
|
||||||
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
||||||
@ -185,7 +187,7 @@ io(io_i) = linio([mdl, '/D'], 1, 'openoutput'); io_i = io_i + 1; % Relative Mot
|
|||||||
Identify the plant when the encoders are on the struts:
|
Identify the plant when the encoders are on the struts:
|
||||||
#+begin_src matlab
|
#+begin_src matlab
|
||||||
n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
|
n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
|
||||||
'flex_top_type', '3dof', ...
|
'flex_top_type', '4dof', ...
|
||||||
'motion_sensor_type', 'struts', ...
|
'motion_sensor_type', 'struts', ...
|
||||||
'actuator_type', '2dof');
|
'actuator_type', '2dof');
|
||||||
|
|
||||||
@ -197,7 +199,7 @@ Gs.OutputName = {'D1', 'D2', 'D3', 'D4', 'D5', 'D6'};
|
|||||||
And identify the plant when the encoders are fixed on the plates:
|
And identify the plant when the encoders are fixed on the plates:
|
||||||
#+begin_src matlab
|
#+begin_src matlab
|
||||||
n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
|
n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
|
||||||
'flex_top_type', '3dof', ...
|
'flex_top_type', '4dof', ...
|
||||||
'motion_sensor_type', 'plates', ...
|
'motion_sensor_type', 'plates', ...
|
||||||
'actuator_type', '2dof');
|
'actuator_type', '2dof');
|
||||||
|
|
||||||
@ -265,8 +267,9 @@ exportFig('figs/nano_hexapod_effect_encoder.pdf', 'width', 'full', 'height', 'ta
|
|||||||
[[file:figs/nano_hexapod_effect_encoder.png]]
|
[[file:figs/nano_hexapod_effect_encoder.png]]
|
||||||
|
|
||||||
#+begin_important
|
#+begin_important
|
||||||
The zeros at 400Hz and 800Hz should corresponds to resonances of the system when one of the APA is blocked.
|
The zeros at 280Hz should corresponds to resonances of the system when one of the APA is blocked.
|
||||||
It is linked to the axial stiffness of the flexible joints: increasing the axial stiffness of the joints will increase the frequency of the zeros.
|
It is linked to the axial stiffness of the flexible joints: increasing the axial stiffness of the joints will increase the frequency of the zeros.
|
||||||
|
This will be verified in
|
||||||
#+end_important
|
#+end_important
|
||||||
|
|
||||||
** Effect of APA flexibility
|
** Effect of APA flexibility
|
||||||
@ -453,20 +456,13 @@ Depending on the physical effects we want to model, we therefore know how many s
|
|||||||
|
|
||||||
The transfer function from actuator forces $\tau_i$ to the encoder measurements $\mathcal{L}_i$ is now identified both when the encoders are fixed to the struts.
|
The transfer function from actuator forces $\tau_i$ to the encoder measurements $\mathcal{L}_i$ is now identified both when the encoders are fixed to the struts.
|
||||||
#+begin_src matlab
|
#+begin_src matlab
|
||||||
%% Options for Linearized
|
|
||||||
options = linearizeOptions;
|
|
||||||
options.SampleTime = 0;
|
|
||||||
|
|
||||||
%% Name of the Simulink File
|
|
||||||
mdl = 'nano_hexapod';
|
|
||||||
|
|
||||||
%% Input/Output definition
|
%% Input/Output definition
|
||||||
clear io; io_i = 1;
|
clear io; io_i = 1;
|
||||||
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs [N]
|
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs [N]
|
||||||
io(io_i) = linio([mdl, '/D'], 1, 'openoutput'); io_i = io_i + 1; % Relative displacements [m]
|
io(io_i) = linio([mdl, '/D'], 1, 'openoutput'); io_i = io_i + 1; % Relative displacements [m]
|
||||||
|
|
||||||
n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
|
n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
|
||||||
'flex_top_type', '3dof', ...
|
'flex_top_type', '4dof', ...
|
||||||
'motion_sensor_type', 'struts', ...
|
'motion_sensor_type', 'struts', ...
|
||||||
'actuator_type', '2dof');
|
'actuator_type', '2dof');
|
||||||
|
|
||||||
@ -560,28 +556,49 @@ exportFig('figs/nano_hexapod_struts_2dof_dvf_plant.pdf', 'width', 'full', 'heigh
|
|||||||
<<sec:iff_plant>>
|
<<sec:iff_plant>>
|
||||||
|
|
||||||
The transfer function from actuators to force sensors is identified.
|
The transfer function from actuators to force sensors is identified.
|
||||||
|
It corresponds to the plant for the Integral Force Feedback (IFF) control strategy.
|
||||||
#+begin_src matlab
|
#+begin_src matlab
|
||||||
%% Options for Linearized
|
|
||||||
options = linearizeOptions;
|
|
||||||
options.SampleTime = 0;
|
|
||||||
|
|
||||||
%% Name of the Simulink File
|
|
||||||
mdl = 'nano_hexapod';
|
|
||||||
|
|
||||||
%% Input/Output definition
|
%% Input/Output definition
|
||||||
clear io; io_i = 1;
|
clear io; io_i = 1;
|
||||||
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
||||||
io(io_i) = linio([mdl, '/Fm'], 1, 'openoutput'); io_i = io_i + 1; % Force Sensors
|
io(io_i) = linio([mdl, '/Fm'], 1, 'openoutput'); io_i = io_i + 1; % Force Sensors
|
||||||
|
|
||||||
n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
|
n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
|
||||||
'flex_top_type', '3dof', ...
|
'flex_top_type', '4dof', ...
|
||||||
'motion_sensor_type', 'struts', ...
|
'motion_sensor_type', 'struts', ...
|
||||||
'actuator_type', '2dof');
|
'actuator_type', '2dof');
|
||||||
|
|
||||||
Giff = linearize(mdl, io, 0.0, options);
|
Giff = linearize(mdl, io, 0.0, options);
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
This is corresponding to the dynamics for the Integral Force Feedback (IFF) control strategy.
|
The DC gain from actuator to the force sensor should be equal to (for the 2dof APA):
|
||||||
|
\[ \frac{k_e k_1}{k_1 k_e + k_a k_1 + k_e k_a} \]
|
||||||
|
|
||||||
|
Which is equal to:
|
||||||
|
#+begin_src matlab :results value replace :exports results :tangle no
|
||||||
|
sprintf('DCgain = %.2e [m/N]', n_hexapod.actuator.ke(1)*n_hexapod.actuator.k(1)/(n_hexapod.actuator.k(1)*n_hexapod.actuator.ke(1) + n_hexapod.actuator.ka(1)*n_hexapod.actuator.k(1) + n_hexapod.actuator.ke(1)*n_hexapod.actuator.ka(1)))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
: DCgain = 6.56e-03 [m/N]
|
||||||
|
|
||||||
|
This is indeed close to what we see on DC gain of the $6 \times 6$ IFF plant in Table [[tab:iff_dc_gain]].
|
||||||
|
Also, the off diagonal terms are quite small compared to the diagonal terms.
|
||||||
|
#+begin_src matlab :exports results :results value table replace :tangle no
|
||||||
|
data2orgtable(dcgain(Giff), {}, {}, ' %.4f ');
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+name: tab:iff_dc_gain
|
||||||
|
#+caption: DC gain of the IFF plant
|
||||||
|
#+attr_latex: :environment tabularx :width 0.8\linewidth :align cccccc
|
||||||
|
#+attr_latex: :center t :booktabs t :float t
|
||||||
|
#+RESULTS:
|
||||||
|
| 0.0068 | 0.0002 | -0.0002 | -0.0 | 0.0002 | -0.0001 |
|
||||||
|
| 0.0003 | 0.0068 | 0.0001 | -0.0001 | -0.0001 | 0.0002 |
|
||||||
|
| 0.0001 | 0.0 | 0.0068 | -0.0001 | -0.0001 | 0.0001 |
|
||||||
|
| -0.0002 | -0.0003 | 0.0001 | 0.0068 | -0.0002 | -0.0 |
|
||||||
|
| -0.0001 | -0.0003 | -0.0 | 0.0001 | 0.0065 | 0.0 |
|
||||||
|
| 0.0001 | 0.0001 | -0.0002 | -0.0 | 0.0002 | 0.0066 |
|
||||||
|
|
||||||
The bode plot is shown in Figure [[fig:nano_hexapod_struts_2dof_iff_plant]].
|
The bode plot is shown in Figure [[fig:nano_hexapod_struts_2dof_iff_plant]].
|
||||||
#+begin_src matlab :exports none
|
#+begin_src matlab :exports none
|
||||||
@ -677,13 +694,6 @@ The "perfect" sensor output $\mathcal{X}$ is used to verify that the sensor Jaco
|
|||||||
|
|
||||||
Let's then identify the plant for both configuration, and compare the transfer functions from $\mathcal{F}$ to $d\mathcal{X}$ and to $\mathcal{X}$.
|
Let's then identify the plant for both configuration, and compare the transfer functions from $\mathcal{F}$ to $d\mathcal{X}$ and to $\mathcal{X}$.
|
||||||
#+begin_src matlab
|
#+begin_src matlab
|
||||||
%% Options for Linearized
|
|
||||||
options = linearizeOptions;
|
|
||||||
options.SampleTime = 0;
|
|
||||||
|
|
||||||
%% Name of the Simulink File
|
|
||||||
mdl = 'nano_hexapod';
|
|
||||||
|
|
||||||
%% Input/Output definition
|
%% Input/Output definition
|
||||||
clear io; io_i = 1;
|
clear io; io_i = 1;
|
||||||
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
||||||
@ -694,7 +704,7 @@ io(io_i) = linio([mdl, '/X'], 1, 'openoutput'); io_i = io_i + 1; % Relative Mot
|
|||||||
Start when the encoders are fixed on the struts.
|
Start when the encoders are fixed on the struts.
|
||||||
#+begin_src matlab
|
#+begin_src matlab
|
||||||
n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
|
n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
|
||||||
'flex_top_type', '3dof', ...
|
'flex_top_type', '4dof', ...
|
||||||
'motion_sensor_type', 'struts', ...
|
'motion_sensor_type', 'struts', ...
|
||||||
'actuator_type', '2dof', ...
|
'actuator_type', '2dof', ...
|
||||||
'MO_B', 150e-3);
|
'MO_B', 150e-3);
|
||||||
@ -767,7 +777,7 @@ exportFig('figs/nano_hexapod_comp_cartesian_plants_struts.pdf', 'width', 'wide',
|
|||||||
The same if performed when the encoders are fixed to the plates.
|
The same if performed when the encoders are fixed to the plates.
|
||||||
#+begin_src matlab
|
#+begin_src matlab
|
||||||
n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
|
n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
|
||||||
'flex_top_type', '3dof', ...
|
'flex_top_type', '4dof', ...
|
||||||
'motion_sensor_type', 'plates', ...
|
'motion_sensor_type', 'plates', ...
|
||||||
'actuator_type', '2dof', ...
|
'actuator_type', '2dof', ...
|
||||||
'MO_B', 150e-3);
|
'MO_B', 150e-3);
|
||||||
@ -900,6 +910,141 @@ exportFig('figs/nano_hexapod_cartesian_plant_encoder_comp.pdf', 'width', 'full',
|
|||||||
#+RESULTS:
|
#+RESULTS:
|
||||||
[[file:figs/nano_hexapod_cartesian_plant_encoder_comp.png]]
|
[[file:figs/nano_hexapod_cartesian_plant_encoder_comp.png]]
|
||||||
|
|
||||||
|
#+begin_question
|
||||||
|
Is the complex conjugate zeros on Figure [[fig:nano_hexapod_cartesian_plant_encoder_comp]] could be due to the axial stiffness of the joints?
|
||||||
|
Let's find out by using a model with no axial flexibility on the joints and see if we still have this zero.
|
||||||
|
#+end_question
|
||||||
|
|
||||||
|
*** Perfect axial stiffness of the joints
|
||||||
|
Let's initialize the Nano-Hexapod with perfect joints (no axial stiffness):
|
||||||
|
#+begin_src matlab
|
||||||
|
n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '3dof', ...
|
||||||
|
'flex_top_type', '2dof', ...
|
||||||
|
'motion_sensor_type', 'struts', ...
|
||||||
|
'actuator_type', '2dof', ...
|
||||||
|
'MO_B', 150e-3);
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Identify its dynamics.
|
||||||
|
#+begin_src matlab
|
||||||
|
G = linearize(mdl, io, 0.0, options);
|
||||||
|
G.InputName = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
|
||||||
|
G.OutputName = {'D1', 'D2', 'D3', 'D4', 'D5', 'D6', ...
|
||||||
|
'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
And compute the transfer function in the cartesian frame.
|
||||||
|
#+begin_src matlab
|
||||||
|
G = inv(n_hexapod.geometry.Js)*G({'D1', 'D2', 'D3', 'D4', 'D5', 'D6'}, {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'})*inv(n_hexapod.geometry.J)';
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
The obtained dynamics is shown in Figure [[fig:nano_hexapod_cartesian_plant_perfect_joints]].
|
||||||
|
It is shown that there are no zeros at high frequency.
|
||||||
|
#+begin_src matlab :exports none
|
||||||
|
freqs = 5*logspace(0, 2, 1000);
|
||||||
|
|
||||||
|
labels = {'$D_x/\mathcal{F}_x$', '$D_y/\mathcal{F}_y$', '$D_z/\mathcal{F}_z$', ...
|
||||||
|
'$R_x/\mathcal{M}_x$', '$R_y/\mathcal{M}_y$', '$R_z/\mathcal{M}_z$'};
|
||||||
|
|
||||||
|
figure;
|
||||||
|
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
|
||||||
|
|
||||||
|
ax1 = nexttile([2,1]);
|
||||||
|
hold on;
|
||||||
|
for i = 1:6
|
||||||
|
plot(freqs, abs(squeeze(freqresp(G(i,i), freqs, 'Hz'))), '-', ...
|
||||||
|
'DisplayName', labels{i});
|
||||||
|
end
|
||||||
|
hold off;
|
||||||
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
||||||
|
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
|
||||||
|
legend('location', 'southwest');
|
||||||
|
ylim([1e-11, 1e-4]);
|
||||||
|
|
||||||
|
ax2 = nexttile;
|
||||||
|
hold on;
|
||||||
|
for i = 1:6
|
||||||
|
plot(freqs, 180/pi*angle(squeeze(freqresp(G(i,i), freqs, 'Hz'))), '-');
|
||||||
|
end
|
||||||
|
hold off;
|
||||||
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
|
||||||
|
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
|
||||||
|
ylim([-180, 180]);
|
||||||
|
yticks([-180, -90, 0, 90, 180]);
|
||||||
|
|
||||||
|
linkaxes([ax1,ax2],'x');
|
||||||
|
xlim([freqs(1), freqs(end)]);
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src matlab :tangle no :exports results :results file replace
|
||||||
|
exportFig('figs/nano_hexapod_cartesian_plant_perfect_joints.pdf', 'width', 'full', 'height', 'tall');
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+name: fig:nano_hexapod_cartesian_plant_perfect_joints
|
||||||
|
#+caption: Bode plot of the "cartesian" plant (transfer function from $\mathcal{F}$ to $d\mathcal{X}$) when the encoders are fixed on the struts and with perfect joints (infinite axial stiffness)
|
||||||
|
#+RESULTS:
|
||||||
|
[[file:figs/nano_hexapod_cartesian_plant_perfect_joints.png]]
|
||||||
|
|
||||||
|
#+begin_important
|
||||||
|
The zeros appearing between 100Hz and 500Hz are due to the axial stiffness of the flexible joints.
|
||||||
|
They appear when the relative motion sensors are fixed to the struts.
|
||||||
|
They basically correspond to the resonance frequency where the APA are infinitively stiff.
|
||||||
|
#+end_important
|
||||||
|
|
||||||
|
*** Frequency of the zeros
|
||||||
|
Let's verify this last affirmation by generating a nano-hexapod with very stiff APA.
|
||||||
|
#+begin_src matlab
|
||||||
|
n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
|
||||||
|
'flex_top_type', '4dof', ...
|
||||||
|
'motion_sensor_type', 'struts', ...
|
||||||
|
'actuator_type', '2dof', ...
|
||||||
|
'actuator_k', 1e9*ones(6,1));
|
||||||
|
Gs = linearize(mdl, io, 0.0, options);
|
||||||
|
Gs.InputName = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
|
||||||
|
Gs.OutputName = {'D1', 'D2', 'D3', 'D4', 'D5', 'D6'};
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src matlab
|
||||||
|
Gs_p = imag(pole(Gs))/2/pi;
|
||||||
|
sort(Gs_p(Gs_p > 0))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src matlab :exports none
|
||||||
|
freqs = 5*logspace(0, 2, 1000);
|
||||||
|
|
||||||
|
labels = {'$D_x/\mathcal{F}_x$', '$D_y/\mathcal{F}_y$', '$D_z/\mathcal{F}_z$', ...
|
||||||
|
'$R_x/\mathcal{M}_x$', '$R_y/\mathcal{M}_y$', '$R_z/\mathcal{M}_z$'};
|
||||||
|
|
||||||
|
figure;
|
||||||
|
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
|
||||||
|
|
||||||
|
ax1 = nexttile([2,1]);
|
||||||
|
hold on;
|
||||||
|
for i = 1:6
|
||||||
|
plot(freqs, abs(squeeze(freqresp(Gsc(i,i), freqs, 'Hz'))), '-', ...
|
||||||
|
'DisplayName', labels{i});
|
||||||
|
end
|
||||||
|
hold off;
|
||||||
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
||||||
|
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
|
||||||
|
legend('location', 'southwest');
|
||||||
|
% ylim([1e-11, 1e-4]);
|
||||||
|
|
||||||
|
ax2 = nexttile;
|
||||||
|
hold on;
|
||||||
|
for i = 1:6
|
||||||
|
plot(freqs, 180/pi*angle(squeeze(freqresp(Gsc(i,i), freqs, 'Hz'))), '-');
|
||||||
|
end
|
||||||
|
hold off;
|
||||||
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
|
||||||
|
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
|
||||||
|
ylim([-180, 180]);
|
||||||
|
yticks([-180, -90, 0, 90, 180]);
|
||||||
|
|
||||||
|
linkaxes([ax1,ax2],'x');
|
||||||
|
xlim([freqs(1), freqs(end)]);
|
||||||
|
#+end_src
|
||||||
|
|
||||||
** Decentralized Plant - Decoupling at the Center of Stiffness
|
** Decentralized Plant - Decoupling at the Center of Stiffness
|
||||||
<<sec:decoupled_plant_cok>>
|
<<sec:decoupled_plant_cok>>
|
||||||
|
|
||||||
@ -971,13 +1116,6 @@ And we indeed obtain a diagonal stiffness matrix.
|
|||||||
*** Obtained plant
|
*** Obtained plant
|
||||||
Let's identify the transfer function from $\tau$ to $d\mathcal{L}$ and from $\tau$ to $\mathcal{X}$.
|
Let's identify the transfer function from $\tau$ to $d\mathcal{L}$ and from $\tau$ to $\mathcal{X}$.
|
||||||
#+begin_src matlab
|
#+begin_src matlab
|
||||||
%% Options for Linearized
|
|
||||||
options = linearizeOptions;
|
|
||||||
options.SampleTime = 0;
|
|
||||||
|
|
||||||
%% Name of the Simulink File
|
|
||||||
mdl = 'nano_hexapod';
|
|
||||||
|
|
||||||
%% Input/Output definition
|
%% Input/Output definition
|
||||||
clear io; io_i = 1;
|
clear io; io_i = 1;
|
||||||
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
||||||
@ -1068,14 +1206,14 @@ The location of the applied force/torque and the expressed displacement/rotation
|
|||||||
Such location (or frame) is then used for the computation of the Jacobian which in turns is used to compute the stiffness matrix.
|
Such location (or frame) is then used for the computation of the Jacobian which in turns is used to compute the stiffness matrix.
|
||||||
|
|
||||||
*** Compute the theoretical stiffness of the nano-hexapod
|
*** Compute the theoretical stiffness of the nano-hexapod
|
||||||
Neglecting stiffness of the joints, we have:
|
Neglecting the torsional/bending stiffness of the joints, we have:
|
||||||
\[ K = J^t \mathcal{K} J \]
|
\[ K = J^t \mathcal{K} J \]
|
||||||
where $\mathcal{K}$ is a diagonal 6x6 matrix with axial stiffness of the struts on the diagonal.
|
where $\mathcal{K}$ is a diagonal 6x6 matrix with the axial stiffness of the struts on the diagonal.
|
||||||
|
|
||||||
Let's note the axial stiffness of the APA:
|
Let's note the axial stiffness of the APA:
|
||||||
\[ k_{\text{APA}} = k + \frac{k_e k_a}{k_e + k_a} \]
|
\[ k_{\text{APA}} = k + \frac{k_e k_a}{k_e + k_a} \]
|
||||||
|
|
||||||
Them axial stiffness of the struts $k_s$:
|
The axial stiffness of the struts $k_s$ is then:
|
||||||
\[ k_s = \frac{k_z k_{\text{APA}}}{k_z + 2 k_{\text{APA}}} \]
|
\[ k_s = \frac{k_z k_{\text{APA}}}{k_z + 2 k_{\text{APA}}} \]
|
||||||
with $k_z$ the axial stiffness of the flexible joints.
|
with $k_z$ the axial stiffness of the flexible joints.
|
||||||
|
|
||||||
@ -1087,32 +1225,18 @@ n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
|
|||||||
'actuator_type', '2dof');
|
'actuator_type', '2dof');
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
The axial stiffness of the joints and stiffnesses of the 2-DoF actuators are defined below.
|
|
||||||
#+begin_src matlab
|
|
||||||
k = n_hexapod.actuator.k(1);
|
|
||||||
ke = n_hexapod.actuator.ke(1);
|
|
||||||
ka = n_hexapod.actuator.ka(1);
|
|
||||||
kz = n_hexapod.flex_top.kz(1); % Joint's axial stiffness [m/N]
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
The total axial stiffness of the APA is:
|
The total axial stiffness of the APA is:
|
||||||
#+begin_src matlab
|
|
||||||
kAPA = k + ke*ka/(ke + ka);
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab :results value replace :exports results :tangle no
|
#+begin_src matlab :results value replace :exports results :tangle no
|
||||||
sprintf('kAPA = %.3e [N/m]', kAPA)
|
kAPA = n_hexapod.actuator.k(1) + n_hexapod.actuator.ke(1)*n_hexapod.actuator.ka(1)/(n_hexapod.actuator.ke(1) + n_hexapod.actuator.ka(1));
|
||||||
|
sprintf('kAPA = %.3e [N/m]', kAPA);
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+RESULTS:
|
#+RESULTS:
|
||||||
: kAPA = 1.799e+06 [N/m]
|
: kAPA = 1.799e+06 [N/m]
|
||||||
|
|
||||||
And the total axial stiffness of the struts is:
|
And the total axial stiffness of the struts is:
|
||||||
#+begin_src matlab
|
|
||||||
ks = kz*kAPA/(kz + 2*kAPA);
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+begin_src matlab :results value replace :exports results :tangle no
|
#+begin_src matlab :results value replace :exports results :tangle no
|
||||||
|
ks = n_hexapod.flex_top.kz(1)*kAPA/(n_hexapod.flex_top.kz(1) + 2*kAPA);
|
||||||
sprintf('ks = %.3e [N/m]', ks)
|
sprintf('ks = %.3e [N/m]', ks)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
@ -1120,7 +1244,7 @@ sprintf('ks = %.3e [N/m]', ks)
|
|||||||
: ks = 1.737e+06 [N/m]
|
: ks = 1.737e+06 [N/m]
|
||||||
|
|
||||||
#+begin_important
|
#+begin_important
|
||||||
We can see that the axial stiffness of the flexible joint as little impact on the total axial stiffness of the struts.
|
We can see that the axial stiffness of the flexible joint as little impact on the total axial stiffness of the struts as it is much stiffer than the APA.
|
||||||
#+end_important
|
#+end_important
|
||||||
|
|
||||||
Let's now compute the stiffness matrix corresponding to an hexapod with perfect joints and the above computed axial strut stiffness:
|
Let's now compute the stiffness matrix corresponding to an hexapod with perfect joints and the above computed axial strut stiffness:
|
||||||
@ -1153,13 +1277,6 @@ ans = C
|
|||||||
*** Comparison with Simscape Model
|
*** Comparison with Simscape Model
|
||||||
Let's now identify the compliance matrix using Simscape.
|
Let's now identify the compliance matrix using Simscape.
|
||||||
#+begin_src matlab
|
#+begin_src matlab
|
||||||
%% Options for Linearized
|
|
||||||
options = linearizeOptions;
|
|
||||||
options.SampleTime = 0;
|
|
||||||
|
|
||||||
%% Name of the Simulink File
|
|
||||||
mdl = 'nano_hexapod';
|
|
||||||
|
|
||||||
%% Input/Output definition
|
%% Input/Output definition
|
||||||
clear io; io_i = 1;
|
clear io; io_i = 1;
|
||||||
io(io_i) = linio([mdl, '/Fe'], 1, 'openinput'); io_i = io_i + 1; % External forces [N, Nm/rad]
|
io(io_i) = linio([mdl, '/Fe'], 1, 'openinput'); io_i = io_i + 1; % External forces [N, Nm/rad]
|
||||||
@ -1189,10 +1306,27 @@ dcgain(G)
|
|||||||
| 8.7375e-06 | 9.9165e-08 | 8.135e-09 | -2.5208e-07 | 4.5331e-05 | 3.0602e-09 |
|
| 8.7375e-06 | 9.9165e-08 | 8.135e-09 | -2.5208e-07 | 4.5331e-05 | 3.0602e-09 |
|
||||||
| 6.1611e-09 | 6.1733e-09 | 2.6778e-09 | -3.3188e-08 | 3.3887e-08 | 1.3212e-05 |
|
| 6.1611e-09 | 6.1733e-09 | 2.6778e-09 | -3.3188e-08 | 3.3887e-08 | 1.3212e-05 |
|
||||||
|
|
||||||
#+begin_important
|
Let's compare the two obtained compliance matrices.
|
||||||
The bending and torsional stiffness of the flexible joints induces a lot of coupling between forces/torques applied to the to platform to its displacement/rotation.
|
The results are shown in Table [[tab:compliance_matrices_compare]].
|
||||||
It can be seen by comparison the compliance matrices in Tables [[tab:compliance_matrix_perfect_joints]] and [[tab:compliance_matrix_simscape_joints]].
|
The diagonal terms are matching quite good, as well as the 1/4 and 2/5 of diagonal terms that are the most important ones.
|
||||||
#+end_important
|
|
||||||
|
All the other terms are zero in the ideal case (Table [[tab:compliance_matrix_perfect_joints]]).
|
||||||
|
There are not zero when considering the bending/torsional stiffness of the joints (Table [[tab:compliance_matrix_simscape_joints]]), however they are still small as compared to the diagonal terms.
|
||||||
|
#+begin_src matlab :results value replace :exports both :tangle no
|
||||||
|
C./dcgain(G)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+name: tab:compliance_matrices_compare
|
||||||
|
#+caption: Compliance Matrices - Comparison
|
||||||
|
#+attr_latex: :environment tabularx :width 0.85\linewidth :align cccccc
|
||||||
|
#+attr_latex: :center t :booktabs t :float t
|
||||||
|
#+RESULTS:
|
||||||
|
| 1.0037 | -9.3741e-15 | 1.4613e-14 | -1.5751e-14 | 1.0069 | 0.090379 |
|
||||||
|
| 8.6313e-15 | 1.014 | -0.0029656 | 1.0204 | 2.4404e-15 | 1.7641e-20 |
|
||||||
|
| -1.8807e-14 | -0.024917 | 1.0028 | -0.020701 | -3.4857e-14 | 4.3304e-18 |
|
||||||
|
| 6.6502e-15 | 1.0157 | -0.0029943 | 1.0193 | 2.3673e-15 | 1.9265e-20 |
|
||||||
|
| 1.0061 | -1.0288e-14 | 2.1354e-14 | -1.7844e-14 | 1.0085 | 0.032102 |
|
||||||
|
| 0.0048048 | -3.1201e-14 | -6.5769e-19 | -2.5589e-14 | 0.002899 | 1.005 |
|
||||||
|
|
||||||
* Active Damping using Integral Force Feedback
|
* Active Damping using Integral Force Feedback
|
||||||
<<sec:integral_force_feedback>>
|
<<sec:integral_force_feedback>>
|
||||||
@ -1228,6 +1362,15 @@ addpath('matlab/nano_hexapod');
|
|||||||
open('matlab/nano_hexapod/nano_hexapod.slx')
|
open('matlab/nano_hexapod/nano_hexapod.slx')
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src matlab
|
||||||
|
%% Options for Linearized
|
||||||
|
options = linearizeOptions;
|
||||||
|
options.SampleTime = 0;
|
||||||
|
|
||||||
|
%% Name of the Simulink File
|
||||||
|
mdl = 'nano_hexapod';
|
||||||
|
#+end_src
|
||||||
|
|
||||||
** Plant Identification
|
** Plant Identification
|
||||||
<<sec:iff_identification>>
|
<<sec:iff_identification>>
|
||||||
|
|
||||||
@ -1241,13 +1384,6 @@ n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
|
|||||||
|
|
||||||
The transfer function from actuator inputs to force sensors outputs is identified.
|
The transfer function from actuator inputs to force sensors outputs is identified.
|
||||||
#+begin_src matlab
|
#+begin_src matlab
|
||||||
%% Options for Linearized
|
|
||||||
options = linearizeOptions;
|
|
||||||
options.SampleTime = 0;
|
|
||||||
|
|
||||||
%% Name of the Simulink File
|
|
||||||
mdl = 'nano_hexapod';
|
|
||||||
|
|
||||||
%% Input/Output definition
|
%% Input/Output definition
|
||||||
clear io; io_i = 1;
|
clear io; io_i = 1;
|
||||||
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
||||||
@ -1422,13 +1558,6 @@ exportFig('figs/nano_hexapod_iff_loop_gain.pdf', 'width', 'wide', 'height', 'tal
|
|||||||
|
|
||||||
Let's now see how the IFF control strategy effectively damps the plant and how it affects the transfer functions from the actuator forces to the relative motion sensors (encoders).
|
Let's now see how the IFF control strategy effectively damps the plant and how it affects the transfer functions from the actuator forces to the relative motion sensors (encoders).
|
||||||
#+begin_src matlab :exports none
|
#+begin_src matlab :exports none
|
||||||
%% Options for Linearized
|
|
||||||
options = linearizeOptions;
|
|
||||||
options.SampleTime = 0;
|
|
||||||
|
|
||||||
%% Name of the Simulink File
|
|
||||||
mdl = 'nano_hexapod';
|
|
||||||
|
|
||||||
%% Input/Output definition
|
%% Input/Output definition
|
||||||
clear io; io_i = 1;
|
clear io; io_i = 1;
|
||||||
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
||||||
@ -1538,13 +1667,6 @@ The Integral Force Feedback Strategy is very effective to damp the 6 suspension
|
|||||||
The IFF strategy has the well known drawback of degrading the compliance (transfer function from external forces/torques applied to the top platform to the motion of the top platform), especially at low frequency where the control gain is large.
|
The IFF strategy has the well known drawback of degrading the compliance (transfer function from external forces/torques applied to the top platform to the motion of the top platform), especially at low frequency where the control gain is large.
|
||||||
Let's quantify that for the nano-hexapod.
|
Let's quantify that for the nano-hexapod.
|
||||||
#+begin_src matlab :exports none
|
#+begin_src matlab :exports none
|
||||||
%% Options for Linearized
|
|
||||||
options = linearizeOptions;
|
|
||||||
options.SampleTime = 0;
|
|
||||||
|
|
||||||
%% Name of the Simulink File
|
|
||||||
mdl = 'nano_hexapod';
|
|
||||||
|
|
||||||
%% Input/Output definition
|
%% Input/Output definition
|
||||||
clear io; io_i = 1;
|
clear io; io_i = 1;
|
||||||
io(io_i) = linio([mdl, '/Fe'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
io(io_i) = linio([mdl, '/Fe'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
||||||
@ -1650,6 +1772,15 @@ addpath('matlab/nano_hexapod');
|
|||||||
open('matlab/nano_hexapod/nano_hexapod.slx')
|
open('matlab/nano_hexapod/nano_hexapod.slx')
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src matlab
|
||||||
|
%% Options for Linearized
|
||||||
|
options = linearizeOptions;
|
||||||
|
options.SampleTime = 0;
|
||||||
|
|
||||||
|
%% Name of the Simulink File
|
||||||
|
mdl = 'nano_hexapod';
|
||||||
|
#+end_src
|
||||||
|
|
||||||
** Plant Identification
|
** Plant Identification
|
||||||
<<sec:dvf_identification_struts>>
|
<<sec:dvf_identification_struts>>
|
||||||
|
|
||||||
@ -1663,13 +1794,6 @@ n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
|
|||||||
|
|
||||||
The transfer function from actuator inputs to force sensors outputs is identified.
|
The transfer function from actuator inputs to force sensors outputs is identified.
|
||||||
#+begin_src matlab
|
#+begin_src matlab
|
||||||
%% Options for Linearized
|
|
||||||
options = linearizeOptions;
|
|
||||||
options.SampleTime = 0;
|
|
||||||
|
|
||||||
%% Name of the Simulink File
|
|
||||||
mdl = 'nano_hexapod';
|
|
||||||
|
|
||||||
%% Input/Output definition
|
%% Input/Output definition
|
||||||
clear io; io_i = 1;
|
clear io; io_i = 1;
|
||||||
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
||||||
@ -1843,13 +1967,6 @@ exportFig('figs/nano_hexapod_dvf_loop_gain_struts.pdf', 'width', 'wide', 'height
|
|||||||
|
|
||||||
Let's now see how the DVF control strategy effectively damps the plant and how it affects the transfer functions from the actuator forces to the relative motion sensors (encoders).
|
Let's now see how the DVF control strategy effectively damps the plant and how it affects the transfer functions from the actuator forces to the relative motion sensors (encoders).
|
||||||
#+begin_src matlab :exports none
|
#+begin_src matlab :exports none
|
||||||
%% Options for Linearized
|
|
||||||
options = linearizeOptions;
|
|
||||||
options.SampleTime = 0;
|
|
||||||
|
|
||||||
%% Name of the Simulink File
|
|
||||||
mdl = 'nano_hexapod';
|
|
||||||
|
|
||||||
%% Input/Output definition
|
%% Input/Output definition
|
||||||
clear io; io_i = 1;
|
clear io; io_i = 1;
|
||||||
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
||||||
@ -1959,13 +2076,6 @@ The Direct Velocity Feedback Strategy is very effective to damp the 6 suspension
|
|||||||
The DVF strategy has the well known drawback of degrading the compliance (transfer function from external forces/torques applied to the top platform to the motion of the top platform), especially at low frequency where the control gain is large.
|
The DVF strategy has the well known drawback of degrading the compliance (transfer function from external forces/torques applied to the top platform to the motion of the top platform), especially at low frequency where the control gain is large.
|
||||||
Let's quantify that for the nano-hexapod.
|
Let's quantify that for the nano-hexapod.
|
||||||
#+begin_src matlab :exports none
|
#+begin_src matlab :exports none
|
||||||
%% Options for Linearized
|
|
||||||
options = linearizeOptions;
|
|
||||||
options.SampleTime = 0;
|
|
||||||
|
|
||||||
%% Name of the Simulink File
|
|
||||||
mdl = 'nano_hexapod';
|
|
||||||
|
|
||||||
%% Input/Output definition
|
%% Input/Output definition
|
||||||
clear io; io_i = 1;
|
clear io; io_i = 1;
|
||||||
io(io_i) = linio([mdl, '/Fe'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
io(io_i) = linio([mdl, '/Fe'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
||||||
@ -2065,6 +2175,15 @@ addpath('matlab/nano_hexapod');
|
|||||||
open('matlab/nano_hexapod/nano_hexapod.slx')
|
open('matlab/nano_hexapod/nano_hexapod.slx')
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
#+begin_src matlab
|
||||||
|
%% Options for Linearized
|
||||||
|
options = linearizeOptions;
|
||||||
|
options.SampleTime = 0;
|
||||||
|
|
||||||
|
%% Name of the Simulink File
|
||||||
|
mdl = 'nano_hexapod';
|
||||||
|
#+end_src
|
||||||
|
|
||||||
** Plant Identification
|
** Plant Identification
|
||||||
<<sec:dvf_identification_plates>>
|
<<sec:dvf_identification_plates>>
|
||||||
|
|
||||||
@ -2078,13 +2197,6 @@ n_hexapod = initializeNanoHexapodFinal('flex_bot_type', '4dof', ...
|
|||||||
|
|
||||||
The transfer function from actuator inputs to force sensors outputs is identified.
|
The transfer function from actuator inputs to force sensors outputs is identified.
|
||||||
#+begin_src matlab
|
#+begin_src matlab
|
||||||
%% Options for Linearized
|
|
||||||
options = linearizeOptions;
|
|
||||||
options.SampleTime = 0;
|
|
||||||
|
|
||||||
%% Name of the Simulink File
|
|
||||||
mdl = 'nano_hexapod';
|
|
||||||
|
|
||||||
%% Input/Output definition
|
%% Input/Output definition
|
||||||
clear io; io_i = 1;
|
clear io; io_i = 1;
|
||||||
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
||||||
@ -2258,13 +2370,6 @@ exportFig('figs/nano_hexapod_dvf_loop_gain_plates.pdf', 'width', 'wide', 'height
|
|||||||
|
|
||||||
Let's now see how the DVF control strategy effectively damps the plant and how it affects the transfer functions from the actuator forces to the relative motion sensors (encoders).
|
Let's now see how the DVF control strategy effectively damps the plant and how it affects the transfer functions from the actuator forces to the relative motion sensors (encoders).
|
||||||
#+begin_src matlab :exports none
|
#+begin_src matlab :exports none
|
||||||
%% Options for Linearized
|
|
||||||
options = linearizeOptions;
|
|
||||||
options.SampleTime = 0;
|
|
||||||
|
|
||||||
%% Name of the Simulink File
|
|
||||||
mdl = 'nano_hexapod';
|
|
||||||
|
|
||||||
%% Input/Output definition
|
%% Input/Output definition
|
||||||
clear io; io_i = 1;
|
clear io; io_i = 1;
|
||||||
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
||||||
@ -2374,13 +2479,6 @@ The Direct Velocity Feedback Strategy is very effective in damping the 6 suspens
|
|||||||
The DVF strategy has the well known drawback of degrading the compliance (transfer function from external forces/torques applied to the top platform to the motion of the top platform), especially at low frequency where the control gain is large.
|
The DVF strategy has the well known drawback of degrading the compliance (transfer function from external forces/torques applied to the top platform to the motion of the top platform), especially at low frequency where the control gain is large.
|
||||||
Let's quantify that for the nano-hexapod.
|
Let's quantify that for the nano-hexapod.
|
||||||
#+begin_src matlab :exports none
|
#+begin_src matlab :exports none
|
||||||
%% Options for Linearized
|
|
||||||
options = linearizeOptions;
|
|
||||||
options.SampleTime = 0;
|
|
||||||
|
|
||||||
%% Name of the Simulink File
|
|
||||||
mdl = 'nano_hexapod';
|
|
||||||
|
|
||||||
%% Input/Output definition
|
%% Input/Output definition
|
||||||
clear io; io_i = 1;
|
clear io; io_i = 1;
|
||||||
io(io_i) = linio([mdl, '/Fe'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
io(io_i) = linio([mdl, '/Fe'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
|
||||||
|