Model flexible nano-hexapod elements

This commit is contained in:
2020-11-03 09:45:50 +01:00
parent 184c755fb8
commit bd054638b2
23 changed files with 2872 additions and 2739 deletions

View File

@@ -534,10 +534,10 @@ We choose realistic values of the axial stiffness of the joints:
\[ K_a = 60\,[N/\mu m] \]
#+begin_src matlab
Kz_F = 60e6*ones(6,1); % [N/m]
Kz_M = 60e6*ones(6,1); % [N/m]
Cz_F = 1*ones(6,1); % [N/(m/s)]
Cz_M = 1*ones(6,1); % [N/(m/s)]
Ka_F = 60e6*ones(6,1); % [N/m]
Ka_M = 60e6*ones(6,1); % [N/m]
Ca_F = 1*ones(6,1); % [N/(m/s)]
Ca_M = 1*ones(6,1); % [N/(m/s)]
#+end_src
*** Initialization
@@ -591,10 +591,10 @@ The obtained dynamics are shown in Figure [[fig:flex_joint_trans_dvf]].
initializeNanoHexapod('k', k_opt, 'c', c_opt, ...
'type_F', 'universal_3dof', ...
'type_M', 'spherical_3dof', ...
'Kz_F', Kz_F, ...
'Kz_M', Kz_M, ...
'Cz_F', Cz_F, ...
'Cz_M', Cz_M);
'Ka_F', Ka_F, ...
'Ka_M', Ka_M, ...
'Ca_F', Ca_F, ...
'Ca_M', Ca_M);
G_dvf_3dof = linearize(mdl, io);
G_dvf_3dof.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
@@ -674,10 +674,10 @@ The dynamics is compare with and without the joint flexibility in Figure [[fig:f
initializeNanoHexapod('k', k_opt, 'c', c_opt, ...
'type_F', 'universal_3dof', ...
'type_M', 'spherical_3dof', ...
'Kz_F', Kz_F, ...
'Kz_M', Kz_M, ...
'Cz_F', Cz_F, ...
'Cz_M', Cz_M);
'Ka_F', Ka_F, ...
'Ka_M', Ka_M, ...
'Ca_F', Ca_F, ...
'Ca_M', Ca_M);
G = linearize(mdl, io);
G.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
@@ -759,7 +759,7 @@ We wish now to see what is the impact of the *axial* stiffness of the flexible j
Let's consider the following values for the axial stiffness:
#+begin_src matlab
Kzs = [1e4, 1e5, 1e6, 1e7, 1e8, 1e9]; % [N/m]
Kas = [1e4, 1e5, 1e6, 1e7, 1e8, 1e9]; % [N/m]
#+end_src
We also consider here a nano-hexapod with the identified optimal actuator stiffness ($k = 10^5\,[N/m]$).
@@ -788,16 +788,16 @@ It can be seen that very little active damping can be achieve for axial stiffnes
io(io_i) = linio([mdl, '/Controller'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Dnlm'); io_i = io_i + 1; % Force Sensors
G_dvf_3dof_s = {zeros(length(Kzs), 1)};
G_dvf_3dof_s = {zeros(length(Kas), 1)};
for i = 1:length(Kzs)
for i = 1:length(Kas)
initializeNanoHexapod('k', k_opt, 'c', c_opt, ...
'type_F', 'universal_3dof', ...
'type_M', 'spherical_3dof', ...
'Kz_F', Kzs(i), ...
'Kz_M', Kzs(i), ...
'Cz_F', 0.05*sqrt(Kzs(i)*10), ...
'Cz_M', 0.05*sqrt(Kzs(i)*10));
'Ka_F', Kas(i), ...
'Ka_M', Kas(i), ...
'Ca_F', 0.05*sqrt(Kas(i)*10), ...
'Ca_M', 0.05*sqrt(Kas(i)*10));
G = linearize(mdl, io);
G.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
@@ -814,7 +814,7 @@ It can be seen that very little active damping can be achieve for axial stiffnes
ax1 = subplot(2, 1, 1);
hold on;
for i = 1:length(Kzs)
for i = 1:length(Kas)
plot(freqs, abs(squeeze(freqresp(G_dvf_3dof_s{i}(1, 1), freqs, 'Hz'))));
end
plot(freqs, abs(squeeze(freqresp(G_dvf(1, 1), freqs, 'Hz'))), 'k--');
@@ -824,9 +824,9 @@ It can be seen that very little active damping can be achieve for axial stiffnes
ax2 = subplot(2, 1, 2);
hold on;
for i = 1:length(Kzs)
for i = 1:length(Kas)
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_dvf_3dof_s{i}(1, 1), freqs, 'Hz')))), ...
'DisplayName', sprintf('$k = %.0g$ [N/m]', Kzs(i)));
'DisplayName', sprintf('$k = %.0g$ [N/m]', Kas(i)));
end
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_dvf(1, 1), freqs, 'Hz')))), 'k--', ...
'DisplayName', 'Perfect Joint');
@@ -855,10 +855,10 @@ It can be seen that very little active damping can be achieve for axial stiffnes
gains = logspace(2, 5, 300);
hold on;
for i = 1:length(Kzs)
for i = 1:length(Kas)
set(gca,'ColorOrderIndex',i);
plot(real(pole(G_dvf_3dof_s{i})), imag(pole(G_dvf_3dof_s{i})), 'x', ...
'DisplayName', sprintf('$k = %.0g$ [N/m]', Kzs(i)));
'DisplayName', sprintf('$k = %.0g$ [N/m]', Kas(i)));
set(gca,'ColorOrderIndex',i);
plot(real(tzero(G_dvf_3dof_s{i})), imag(tzero(G_dvf_3dof_s{i})), 'o', ...
'HandleVisibility', 'off');
@@ -918,16 +918,16 @@ The dynamics from $\bm{\tau}^\prime$ to $\bm{\epsilon}_{\mathcal{X}_n}$ (for the
load('mat/stages.mat', 'nano_hexapod');
Gl_3dof_s = {zeros(length(Kzs), 1)};
Gl_3dof_s = {zeros(length(Kas), 1)};
for i = 1:length(Kzs)
for i = 1:length(Kas)
initializeNanoHexapod('k', k_opt, 'c', c_opt, ...
'type_F', 'universal_3dof', ...
'type_M', 'spherical_3dof', ...
'Kz_F', Kzs(i), ...
'Kz_M', Kzs(i), ...
'Cz_F', 0.05*sqrt(Kzs(i)*10), ...
'Cz_M', 0.05*sqrt(Kzs(i)*10));
'Ka_F', Kas(i), ...
'Ka_M', Kas(i), ...
'Ca_F', 0.05*sqrt(Kas(i)*10), ...
'Ca_M', 0.05*sqrt(Kas(i)*10));
G = linearize(mdl, io);
G.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
@@ -946,7 +946,7 @@ The dynamics from $\bm{\tau}^\prime$ to $\bm{\epsilon}_{\mathcal{X}_n}$ (for the
ax1 = subplot(2, 1, 1);
hold on;
for i = 1:length(Kzs)
for i = 1:length(Kas)
plot(freqs, abs(squeeze(freqresp(Gl_3dof_s{i}(1, 1), freqs, 'Hz'))));
end
hold off;
@@ -955,9 +955,9 @@ The dynamics from $\bm{\tau}^\prime$ to $\bm{\epsilon}_{\mathcal{X}_n}$ (for the
ax2 = subplot(2, 1, 2);
hold on;
for i = 1:length(Kzs)
for i = 1:length(Kas)
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(Gl_3dof_s{i}(1, 1), freqs, 'Hz')))), ...
'DisplayName', sprintf('$k = %.0g$ [N/m]', Kzs(i)));
'DisplayName', sprintf('$k = %.0g$ [N/m]', Kas(i)));
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
@@ -1012,3 +1012,262 @@ The dynamics from $\bm{\tau}^\prime$ to $\bm{\epsilon}_{\mathcal{X}_n}$ (for the
As there is generally a trade-off between bending stiffness and axial stiffness, it should be highlighted that the *axial* stiffness is the most important property of the flexible joints.
#+end_important
* Designed Flexible Joints
** 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>>
#+end_src
#+begin_src matlab :exports none :results silent :noweb yes
<<matlab-init>>
#+end_src
#+begin_src matlab :tangle no
simulinkproject('../');
#+end_src
#+begin_src matlab
load('mat/conf_simulink.mat');
open('nass_model.slx')
#+end_src
** Initialization
Let's initialize all the stages with default parameters.
#+begin_src matlab
initializeGround();
initializeGranite();
initializeTy();
initializeRy();
initializeRz();
initializeMicroHexapod();
initializeAxisc('type', 'none');
initializeMirror('type', 'none');
initializeMirror();
#+end_src
#+begin_src matlab :exports none
initializeSimscapeConfiguration();
initializeDisturbances('enable', false);
initializeLoggingConfiguration('log', 'none');
initializeController('type', 'hac-dvf');
#+end_src
Let's consider the heaviest mass which should we the most problematic with it comes to the flexible joints.
#+begin_src matlab
initializeSample('mass', 50, 'freq', 200*ones(6,1));
initializeReferences('Rz_type', 'rotating-not-filtered', 'Rz_period', 60);
#+end_src
#+begin_src matlab :exports none
K = tf(zeros(6));
Kdvf = tf(zeros(6));
#+end_src
#+begin_src matlab
flex_joint = load('./mat/flexor_025.mat', 'int_xyz', 'int_i', 'n_xyz', 'n_i', 'nodes', 'M', 'K');
apa = load('./mat/APA300ML_simplified_model.mat');
#+end_src
#+begin_src matlab
initializeNanoHexapod('actuator', 'amplified', ...
'ke', apa.ke, 'ka', apa.ka, 'k1', apa.k1, 'c1', apa.c1, 'F_gain', apa.F_gain, ...
'type_M', 'spherical_3dof', ...
'Kr_M', flex_joint.K(1,1)*ones(6,1), ...
'Ka_M', flex_joint.K(3,3)*ones(6,1), ...
'Kf_M', flex_joint.K(4,4)*ones(6,1), ...
'Kt_M', flex_joint.K(6,6)*ones(6,1), ...
'type_F', 'spherical_3dof', ...
'Kr_F', flex_joint.K(1,1)*ones(6,1), ...
'Ka_F', flex_joint.K(3,3)*ones(6,1), ...
'Kf_F', flex_joint.K(4,4)*ones(6,1), ...
'Kt_F', flex_joint.K(6,6)*ones(6,1));
#+end_src
#+begin_src matlab
initializeNanoHexapod();
#+end_src
** Direct Velocity Feedback
#+begin_src matlab :exports none
%% Name of the Simulink File
mdl = 'nass_model';
%% Input/Output definition
clear io; io_i = 1;
io(io_i) = linio([mdl, '/Controller'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Dnlm'); io_i = io_i + 1; % Force Sensors
#+end_src
#+begin_src matlab :exports none
G_dvf = linearize(mdl, io);
G_dvf.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
G_dvf.OutputName = {'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6'};
#+end_src
#+begin_src matlab :exports none
freqs = logspace(0, 4, 1000);
figure;
ax1 = subplot(2, 1, 1);
hold on;
plot(freqs, abs(squeeze(freqresp(G_dvf(1, 1), freqs, 'Hz'))));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
ax2 = subplot(2, 1, 2);
hold on;
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_dvf(1, 1), freqs, 'Hz')))), ...
'DisplayName', 'Designed Joints');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-270, 90]);
yticks([-360:90:360]);
legend('location', 'northeast');
linkaxes([ax1,ax2],'x');
#+end_src
#+begin_src matlab :exports none
K_iff = 1e6*s/(1 + s/2/pi/100)/(1 + s/2/pi/100);
freqs = logspace(0, 4, 1000);
figure;
ax1 = subplot(2, 1, 1);
hold on;
plot(freqs, abs(squeeze(freqresp(K_iff*G_dvf(1, 1), freqs, 'Hz'))));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
ax2 = subplot(2, 1, 2);
hold on;
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(K_iff*G_dvf(1, 1), freqs, 'Hz')))), ...
'DisplayName', 'Designed Joints');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-270, 90]);
yticks([-360:90:360]);
legend('location', 'northeast');
linkaxes([ax1,ax2],'x');
#+end_src
#+begin_src matlab :exports none
gains = logspace(0, 5, 100);
figure;
hold on;
plot(real(pole(G_dvf)), imag(pole(G_dvf)), 'x');
set(gca,'ColorOrderIndex',1);
plot(real(tzero(G_dvf)), imag(tzero(G_dvf)), 'o');
for i = 1:length(gains)
set(gca,'ColorOrderIndex',1);
cl_poles = pole(feedback(G_dvf, (gains(i)*s/(1+s/2/pi/100)^2)*eye(6)));
plot(real(cl_poles), imag(cl_poles), '.');
end
% ylim([0, 2*pi*500]);
% xlim([-2*pi*500,0]);
xlabel('Real Part')
ylabel('Imaginary Part')
axis square
#+end_src
** Integral Force Feedback
#+begin_src matlab :exports none
%% Name of the Simulink File
mdl = 'nass_model';
%% Input/Output definition
clear io; io_i = 1;
io(io_i) = linio([mdl, '/Controller'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Fnlm'); io_i = io_i + 1; % Force Sensors
#+end_src
#+begin_src matlab :exports none
G_iff = linearize(mdl, io);
G_iff.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
G_iff.OutputName = {'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6'};
#+end_src
#+begin_src matlab :exports none
freqs = logspace(0, 4, 1000);
figure;
ax1 = subplot(2, 1, 1);
hold on;
plot(freqs, abs(squeeze(freqresp(G_iff(1, 1), freqs, 'Hz'))));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [N/N]'); set(gca, 'XTickLabel',[]);
ax2 = subplot(2, 1, 2);
hold on;
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_iff(1, 1), freqs, 'Hz')))), ...
'DisplayName', 'Designed Joints');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-270, 90]);
yticks([-360:90:360]);
legend('location', 'northeast');
linkaxes([ax1,ax2],'x');
#+end_src
#+begin_src matlab :exports none
K_iff = -1e4/(s + 2*pi*5)*s/(s + 2*pi*5);
freqs = logspace(-1, 4, 1000);
figure;
ax1 = subplot(2, 1, 1);
hold on;
plot(freqs, abs(squeeze(freqresp(K_iff*G_iff(1, 1), freqs, 'Hz'))));
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Loop Gain'); set(gca, 'XTickLabel',[]);
ax2 = subplot(2, 1, 2);
hold on;
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(K_iff*G_iff(1, 1), freqs, 'Hz')))), ...
'DisplayName', 'Designed Joints');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-360:90:360]);
legend('location', 'northeast');
linkaxes([ax1,ax2],'x');
#+end_src
#+begin_src matlab :exports none
gains = logspace(0, 5, 100);
figure;
hold on;
plot(real(pole(G_iff)), imag(pole(G_iff)), 'x');
set(gca,'ColorOrderIndex',1);
plot(real(tzero(G_iff)), imag(tzero(G_iff)), 'o');
for i = 1:length(gains)
set(gca,'ColorOrderIndex',1);
cl_poles = pole(feedback(G_iff, -(gains(i)/(s + 2*pi*5)*s/(s + 2*pi*5))*eye(6)));
plot(real(cl_poles), imag(cl_poles), '.');
end
ylim([0, 2*pi*500]);
xlim([-2*pi*500,0]);
xlabel('Real Part')
ylabel('Imaginary Part')
axis square
#+end_src

View File

@@ -278,6 +278,7 @@ The output =sample_pos= corresponds to the impact point of the X-ray.
args.x0 (1,1) double {mustBeNumeric} = 0 % Rest position of the Joint in the X direction [m]
args.y0 (1,1) double {mustBeNumeric} = 0 % Rest position of the Joint in the Y direction [m]
args.z0 (1,1) double {mustBeNumeric} = 0 % Rest position of the Joint in the Z direction [m]
args.sample_pos (1,1) double {mustBeNumeric} = 0.8 % Height of the measurment point [m]
end
#+end_src
@@ -322,7 +323,7 @@ Properties of the Material and link to the geometry of the granite.
Z-offset for the initial position of the sample with respect to the granite top surface.
#+begin_src matlab
granite.sample_pos = 0.8; % [m]
granite.sample_pos = args.sample_pos; % [m]
#+end_src
** Stiffness and Damping properties
@@ -1169,7 +1170,7 @@ We define the geometrical values.
#+begin_src matlab
mirror.h = 0.05; % Height of the mirror [m]
mirror.thickness = 0.025; % Thickness of the plate supporting the sample [m]
mirror.thickness = 0.02; % Thickness of the plate supporting the sample [m]
mirror.hole_rad = 0.125; % radius of the hole in the mirror [m]
@@ -1178,11 +1179,11 @@ We define the geometrical values.
% point of interest offset in z (above the top surfave) [m]
switch args.type
case 'none'
mirror.jacobian = 0.20;
mirror.jacobian = 0.205;
case 'rigid'
mirror.jacobian = 0.20 - mirror.h;
mirror.jacobian = 0.205 - mirror.h;
case 'flexible'
mirror.jacobian = 0.20 - mirror.h;
mirror.jacobian = 0.205 - mirror.h;
end
mirror.rad = 0.180; % radius of the mirror (at the bottom surface) [m]
@@ -1269,8 +1270,8 @@ The =mirror= structure is saved.
arguments
args.type char {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'init'})} = 'flexible'
% initializeFramesPositions
args.H (1,1) double {mustBeNumeric, mustBePositive} = 90e-3
args.MO_B (1,1) double {mustBeNumeric} = 175e-3
args.H (1,1) double {mustBeNumeric, mustBePositive} = 95e-3
args.MO_B (1,1) double {mustBeNumeric} = 170e-3
% generateGeneralConfiguration
args.FH (1,1) double {mustBeNumeric, mustBePositive} = 15e-3
args.FR (1,1) double {mustBeNumeric, mustBePositive} = 100e-3
@@ -1284,25 +1285,28 @@ The =mirror= structure is saved.
args.ke (1,1) double {mustBeNumeric} = 5e6
args.ka (1,1) double {mustBeNumeric} = 60e6
args.c1 (1,1) double {mustBeNumeric} = 10
args.ce (1,1) double {mustBeNumeric} = 10
args.ca (1,1) double {mustBeNumeric} = 10
args.F_gain (1,1) double {mustBeNumeric} = 1
args.k (1,1) double {mustBeNumeric} = -1
args.c (1,1) double {mustBeNumeric} = -1
% initializeJointDynamics
args.type_F char {mustBeMember(args.type_F,{'universal', 'spherical', 'universal_p', 'spherical_p', 'universal_3dof'})} = 'universal'
args.type_M char {mustBeMember(args.type_M,{'universal', 'spherical', 'universal_p', 'spherical_p', 'spherical_3dof'})} = 'spherical'
args.Kf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 15*ones(6,1)
args.type_F char {mustBeMember(args.type_F,{'universal', 'spherical', 'universal_p', 'spherical_p', 'universal_3dof', 'spherical_3dof', 'flexible'})} = 'universal'
args.type_M char {mustBeMember(args.type_M,{'universal', 'spherical', 'universal_p', 'spherical_p', 'universal_3dof', 'spherical_3dof', 'flexible'})} = 'spherical'
args.Ka_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.2e8*ones(6,1)
args.Ca_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
args.Kr_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.1e7*ones(6,1)
args.Cr_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
args.Kf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 33*ones(6,1)
args.Cf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1)
args.Kt_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 20*ones(6,1)
args.Kt_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 236*ones(6,1)
args.Ct_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1)
args.Kz_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 60e6*ones(6,1)
args.Cz_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e2*ones(6,1)
args.Kf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 15*ones(6,1)
args.Kf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 33*ones(6,1)
args.Cf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1)
args.Kt_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 20*ones(6,1)
args.Kt_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 236*ones(6,1)
args.Ct_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1)
args.Kz_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 60e6*ones(6,1)
args.Cz_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e2*ones(6,1)
args.Ka_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.2e8*ones(6,1)
args.Ca_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
args.Kr_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.1e7*ones(6,1)
args.Cr_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
% initializeCylindricalPlatforms
args.Fpm (1,1) double {mustBeNumeric, mustBePositive} = 1
args.Fph (1,1) double {mustBeNumeric, mustBePositive} = 10e-3
@@ -1355,9 +1359,8 @@ The =mirror= structure is saved.
'k1', args.k1*ones(6,1), ...
'c1', args.c1*ones(6,1), ...
'ka', args.ka*ones(6,1), ...
'ca', args.ca*ones(6,1), ...
'ke', args.ke*ones(6,1), ...
'ce', args.ce*ones(6,1));
'F_gain', args.F_gain*ones(6,1));
else
error('args.actuator should be piezo, lorentz or amplified');
end
@@ -1367,18 +1370,22 @@ The =mirror= structure is saved.
stewart = initializeJointDynamics(stewart, ...
'type_F', args.type_F, ...
'type_M', args.type_M, ...
'Kf_M' , args.Kf_M, ...
'Cf_M' , args.Cf_M, ...
'Kt_M' , args.Kt_M, ...
'Ct_M' , args.Ct_M, ...
'Kz_M' , args.Kz_M, ...
'Cz_M' , args.Cz_M, ...
'Kf_F' , args.Kf_F, ...
'Cf_F' , args.Cf_F, ...
'Kt_F' , args.Kt_F, ...
'Ct_F' , args.Ct_F, ...
'Kz_F' , args.Kz_F, ...
'Cz_F' , args.Cz_F);
'Kf_M', args.Kf_M, ...
'Cf_M', args.Cf_M, ...
'Kt_M', args.Kt_M, ...
'Ct_M', args.Ct_M, ...
'Kf_F', args.Kf_F, ...
'Cf_F', args.Cf_F, ...
'Kt_F', args.Kt_F, ...
'Ct_F', args.Ct_F, ...
'Ka_F', args.Ka_F, ...
'Ca_F', args.Ca_F, ...
'Kr_F', args.Kr_F, ...
'Cr_F', args.Cr_F, ...
'Ka_M', args.Ka_M, ...
'Ca_M', args.Ca_M, ...
'Kr_M', args.Kr_M, ...
'Cr_M', args.Cr_M);
#+end_src
#+begin_src matlab

View File

@@ -198,7 +198,7 @@ This Matlab function is accessible [[file:../src/generateGeneralConfiguration.m]
Joints are positions on a circle centered with the Z axis of {F} and {M} and at a chosen distance from {F} and {M}.
The radius of the circles can be chosen as well as the angles where the joints are located (see Figure [[fig:joint_position_general]]).
#+begin_src latex :file stewart_bottom_plate.pdf
#+begin_src latex :file stewart_bottom_plate.pdf :tangle no
\begin{tikzpicture}
% Internal and external limit
\draw[fill=white!80!black] (0, 0) circle [radius=3];
@@ -742,7 +742,7 @@ A simplistic model of such amplified actuator is shown in Figure [[fig:actuator_
- $v_{m}$ represents the absolute velocity of the top part of the actuator
- $d_{m}$ represents the total relative displacement of the actuator
#+begin_src latex :file actuator_model_simple.pdf
#+begin_src latex :file actuator_model_simple.pdf :tangle no
\begin{tikzpicture}
\draw (-1, 0) -- (1, 0);
@@ -801,14 +801,13 @@ A simplistic model of such amplified actuator is shown in Figure [[fig:actuator_
args.type char {mustBeMember(args.type,{'classical', 'amplified'})} = 'classical'
args.K (6,1) double {mustBeNumeric, mustBeNonnegative} = 20e6*ones(6,1)
args.C (6,1) double {mustBeNumeric, mustBeNonnegative} = 2e1*ones(6,1)
args.k1 (6,1) double {mustBeNumeric} = 1e6
args.ke (6,1) double {mustBeNumeric} = 5e6
args.ka (6,1) double {mustBeNumeric} = 60e6
args.c1 (6,1) double {mustBeNumeric} = 10
args.ce (6,1) double {mustBeNumeric} = 10
args.ca (6,1) double {mustBeNumeric} = 10
args.me (6,1) double {mustBeNumeric} = 0.05
args.ma (6,1) double {mustBeNumeric} = 0.05
args.k1 (6,1) double {mustBeNumeric} = 1e6*ones(6,1)
args.ke (6,1) double {mustBeNumeric} = 5e6*ones(6,1)
args.ka (6,1) double {mustBeNumeric} = 60e6*ones(6,1)
args.c1 (6,1) double {mustBeNumeric} = 10*ones(6,1)
args.F_gain (6,1) double {mustBeNumeric} = 1*ones(6,1)
args.me (6,1) double {mustBeNumeric} = 0.01*ones(6,1)
args.ma (6,1) double {mustBeNumeric} = 0.01*ones(6,1)
end
#+end_src
@@ -830,144 +829,14 @@ A simplistic model of such amplified actuator is shown in Figure [[fig:actuator_
stewart.actuators.c1 = args.c1;
stewart.actuators.ka = args.ka;
stewart.actuators.ca = args.ca;
stewart.actuators.ke = args.ke;
stewart.actuators.ce = args.ce;
stewart.actuators.F_gain = args.F_gain;
stewart.actuators.ma = args.ma;
stewart.actuators.me = args.me;
#+end_src
* =initializeAmplifiedStrutDynamics=: Add Stiffness and Damping properties of each strut for an amplified piezoelectric actuator
:PROPERTIES:
:header-args:matlab+: :tangle ../src/initializeAmplifiedStrutDynamics.m
:header-args:matlab+: :comments none :mkdirp yes :eval no
:END:
<<sec:initializeAmplifiedStrutDynamics>>
This Matlab function is accessible [[file:../src/initializeAmplifiedStrutDynamics.m][here]].
** Documentation
:PROPERTIES:
:UNNUMBERED: t
:END:
An amplified piezoelectric actuator is shown in Figure [[fig:cedrat_apa95ml]].
#+name: fig:cedrat_apa95ml
#+attr_html: :width 500px
#+caption: Example of an Amplified piezoelectric actuator with an integrated displacement sensor (Cedrat Technologies)
[[file:figs/amplified_piezo_with_displacement_sensor.jpg]]
A simplistic model of such amplified actuator is shown in Figure [[fig:amplified_piezo_model]] where:
- $K_{r}$ represent the vertical stiffness when the piezoelectric stack is removed
- $K_{a}$ is the vertical stiffness contribution of the piezoelectric stack
- $F_{i}$ represents the part of the piezoelectric stack that is used as a force actuator
- $F_{m,i}$ represents the remaining part of the piezoelectric stack that is used as a force sensor
- $v_{m,i}$ represents the absolute velocity of the top part of the actuator
- $d_{m,i}$ represents the total relative displacement of the actuator
#+begin_src latex :file iff_1dof.pdf
\begin{tikzpicture}
% Ground
\draw (-1.2, 0) -- (1, 0);
% Mass
\draw (-1.2, 1.4) -- ++(2.2, 0);
\node[forcesensor={0.4}{0.4}] (fsensn) at (0, 1){};
\draw[] (-0.4, 1) -- (0.4, 1);
\node[right] at (fsensn.east) {$F_{m}$};
% Spring, Damper, and Actuator
\draw[spring] (-0.4, 0) -- (-0.4, 1) node[midway, right=0.1]{$K_{a}$};
\draw[actuator={0.4}{0.2}] (0.4, 0) -- (0.4, 1) node[midway, right=0.1]{$F$};
\draw[spring] (-1, 0) -- (-1, 1.4) node[midway, left=0.1]{$K_{r}$};
\draw[dashed] (1, 0) -- ++(0.4, 0);
\draw[dashed] (1, 1.4) -- ++(0.4, 0);
\draw[->] (0, 1.4)node[]{$\bullet$} -- ++(0, 0.5) node[right]{$v_{m}$};
\draw[<->] (1.4, 0) -- ++(0, 1.4) node[midway, right]{$d_{m}$};
\end{tikzpicture}
#+end_src
#+name: fig:amplified_piezo_model
#+caption: Model of an amplified actuator
#+RESULTS:
[[file:figs/iff_1dof.png]]
** Function description
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
function [stewart] = initializeAmplifiedStrutDynamics(stewart, args)
% initializeAmplifiedStrutDynamics - Add Stiffness and Damping properties of each strut
%
% Syntax: [stewart] = initializeAmplifiedStrutDynamics(args)
%
% Inputs:
% - args - Structure with the following fields:
% - Ka [6x1] - Vertical stiffness contribution of the piezoelectric stack [N/m]
% - Ca [6x1] - Vertical damping contribution of the piezoelectric stack [N/(m/s)]
% - Kr [6x1] - Vertical (residual) stiffness when the piezoelectric stack is removed [N/m]
% - Cr [6x1] - Vertical (residual) damping when the piezoelectric stack is removed [N/(m/s)]
%
% Outputs:
% - stewart - updated Stewart structure with the added fields:
% - actuators.type = 2
% - actuators.K [6x1] - Total Stiffness of each strut [N/m]
% - actuators.C [6x1] - Total Damping of each strut [N/(m/s)]
% - actuators.Ka [6x1] - Vertical stiffness contribution of the piezoelectric stack [N/m]
% - actuators.Ca [6x1] - Vertical damping contribution of the piezoelectric stack [N/(m/s)]
% - actuators.Kr [6x1] - Vertical stiffness when the piezoelectric stack is removed [N/m]
% - actuators.Cr [6x1] - Vertical damping when the piezoelectric stack is removed [N/(m/s)]
#+end_src
** Optional Parameters
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
arguments
stewart
args.Kr (6,1) double {mustBeNumeric, mustBeNonnegative} = 5e6*ones(6,1)
args.Cr (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
args.Ka (6,1) double {mustBeNumeric, mustBeNonnegative} = 15e6*ones(6,1)
args.Ca (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
end
#+end_src
** Compute the total stiffness and damping
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
K = args.Ka + args.Kr;
C = args.Ca + args.Cr;
#+end_src
** Populate the =stewart= structure
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
stewart.actuators.type = 2;
stewart.actuators.Ka = args.Ka;
stewart.actuators.Ca = args.Ca;
stewart.actuators.Kr = args.Kr;
stewart.actuators.Cr = args.Cr;
stewart.actuators.K = K;
stewart.actuators.C = K;
#+end_src
* =initializeJointDynamics=: Add Stiffness and Damping properties for spherical joints
:PROPERTIES:
:header-args:matlab+: :tangle ../src/initializeJointDynamics.m
@@ -995,14 +864,10 @@ This Matlab function is accessible [[file:../src/initializeJointDynamics.m][here
% - Kt_M [6x1] - Torsion (Rz) Stiffness for each top joints [(N.m)/rad]
% - Cf_M [6x1] - Bending (Rx, Ry) Damping of each top joint [(N.m)/(rad/s)]
% - Ct_M [6x1] - Torsion (Rz) Damping of each top joint [(N.m)/(rad/s)]
% - Kz_M [6x1] - Translation (Tz) Stiffness for each top joints [N/m]
% - Cz_M [6x1] - Translation (Tz) Damping of each top joint [N/m]
% - Kf_F [6x1] - Bending (Rx, Ry) Stiffness for each bottom joints [(N.m)/rad]
% - Kt_F [6x1] - Torsion (Rz) Stiffness for each bottom joints [(N.m)/rad]
% - Cf_F [6x1] - Bending (Rx, Ry) Damping of each bottom joint [(N.m)/(rad/s)]
% - Cf_F [6x1] - Torsion (Rz) Damping of each bottom joint [(N.m)/(rad/s)]
% - Kz_F [6x1] - Translation (Tz) Stiffness for each bottom joints [N/m]
% - Cz_F [6x1] - Translation (Tz) Damping of each bottom joint [N/m]
%
% Outputs:
% - stewart - updated Stewart structure with the added fields:
@@ -1023,20 +888,34 @@ This Matlab function is accessible [[file:../src/initializeJointDynamics.m][here
#+begin_src matlab
arguments
stewart
args.type_F char {mustBeMember(args.type_F,{'universal', 'spherical', 'universal_p', 'spherical_p', 'universal_3dof'})} = 'universal'
args.type_M char {mustBeMember(args.type_M,{'universal', 'spherical', 'universal_p', 'spherical_p', 'spherical_3dof'})} = 'spherical'
args.Kf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 15*ones(6,1)
args.type_F char {mustBeMember(args.type_F,{'universal', 'spherical', 'universal_p', 'spherical_p', 'universal_3dof', 'spherical_3dof', 'flexible'})} = 'universal'
args.type_M char {mustBeMember(args.type_M,{'universal', 'spherical', 'universal_p', 'spherical_p', 'universal_3dof', 'spherical_3dof', 'flexible'})} = 'spherical'
args.Kf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 33*ones(6,1)
args.Cf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1)
args.Kt_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 20*ones(6,1)
args.Kt_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 236*ones(6,1)
args.Ct_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1)
args.Kz_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 60e6*ones(6,1)
args.Cz_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e2*ones(6,1)
args.Kf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 15*ones(6,1)
args.Kf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 33*ones(6,1)
args.Cf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1)
args.Kt_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 20*ones(6,1)
args.Kt_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 236*ones(6,1)
args.Ct_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1)
args.Kz_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 60e6*ones(6,1)
args.Cz_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e2*ones(6,1)
args.Ka_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.2e8*ones(6,1)
args.Ca_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
args.Kr_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.1e7*ones(6,1)
args.Cr_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
args.Ka_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.2e8*ones(6,1)
args.Ca_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
args.Kr_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.1e7*ones(6,1)
args.Cr_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
args.K_M double {mustBeNumeric} = zeros(6,6)
args.M_M double {mustBeNumeric} = zeros(6,6)
args.n_xyz_M double {mustBeNumeric} = zeros(2,3)
args.xi_M double {mustBeNumeric} = 0.1
args.step_file_M char {} = ''
args.K_F double {mustBeNumeric} = zeros(6,6)
args.M_F double {mustBeNumeric} = zeros(6,6)
args.n_xyz_F double {mustBeNumeric} = zeros(2,3)
args.xi_F double {mustBeNumeric} = 0.1
args.step_file_F char {} = ''
end
#+end_src
@@ -1051,11 +930,15 @@ This Matlab function is accessible [[file:../src/initializeJointDynamics.m][here
case 'spherical'
stewart.joints_F.type = 2;
case 'universal_p'
stewart.joints_F.type = 1;
stewart.joints_F.type = 3;
case 'spherical_p'
stewart.joints_F.type = 2;
case 'universal_3dof'
stewart.joints_F.type = 4;
case 'flexible'
stewart.joints_F.type = 5;
case 'universal_3dof'
stewart.joints_F.type = 6;
case 'spherical_3dof'
stewart.joints_F.type = 7;
end
switch args.type_M
@@ -1064,56 +947,38 @@ This Matlab function is accessible [[file:../src/initializeJointDynamics.m][here
case 'spherical'
stewart.joints_M.type = 2;
case 'universal_p'
stewart.joints_M.type = 1;
stewart.joints_M.type = 3;
case 'spherical_p'
stewart.joints_M.type = 2;
case 'spherical_3dof'
stewart.joints_M.type = 4;
case 'flexible'
stewart.joints_M.type = 5;
case 'universal_3dof'
stewart.joints_M.type = 6;
case 'spherical_3dof'
stewart.joints_M.type = 7;
end
#+end_src
** Initialize Stiffness
#+begin_src matlab
stewart.joints_M.Kx = zeros(6,1);
stewart.joints_M.Ky = zeros(6,1);
stewart.joints_M.Kz = zeros(6,1);
stewart.joints_F.Kx = zeros(6,1);
stewart.joints_F.Ky = zeros(6,1);
stewart.joints_F.Kz = zeros(6,1);
stewart.joints_M.Kf = zeros(6,1);
stewart.joints_M.Kt = zeros(6,1);
stewart.joints_F.Kf = zeros(6,1);
stewart.joints_F.Kt = zeros(6,1);
stewart.joints_M.Cx = zeros(6,1);
stewart.joints_M.Cy = zeros(6,1);
stewart.joints_M.Cz = zeros(6,1);
stewart.joints_F.Cx = zeros(6,1);
stewart.joints_F.Cy = zeros(6,1);
stewart.joints_F.Cz = zeros(6,1);
stewart.joints_M.Cf = zeros(6,1);
stewart.joints_M.Ct = zeros(6,1);
stewart.joints_F.Cf = zeros(6,1);
stewart.joints_F.Ct = zeros(6,1);
#+end_src
** Add Stiffness and Damping in Translation of each strut
:PROPERTIES:
:UNNUMBERED: t
:END:
Translation Stiffness
Axial and Radial (shear) Stiffness
#+begin_src matlab
if ~strcmp(args.type_M, 'universal_p') || ~strcmp(args.type_M, 'spherical_p')
stewart.joints_M.Kz = args.Kz_M;
stewart.joints_M.Cz = args.Cz_M;
end
stewart.joints_M.Ka = args.Ka_M;
stewart.joints_M.Kr = args.Kr_M;
if ~strcmp(args.type_F, 'universal_p') || ~strcmp(args.type_F, 'spherical_p')
stewart.joints_F.Kz = args.Kz_F;
stewart.joints_F.Cz = args.Cz_F;
end
stewart.joints_F.Ka = args.Ka_F;
stewart.joints_F.Kr = args.Kr_F;
#+end_src
Translation Damping
#+begin_src matlab
stewart.joints_M.Ca = args.Ca_M;
stewart.joints_M.Cr = args.Cr_M;
stewart.joints_F.Ca = args.Ca_F;
stewart.joints_F.Cr = args.Cr_F;
#+end_src
** Add Stiffness and Damping in Rotation of each strut
@@ -1122,21 +987,40 @@ Translation Stiffness
:END:
Rotational Stiffness
#+begin_src matlab
if ~strcmp(args.type_M, 'universal_p') || ~strcmp(args.type_M, 'spherical_p')
stewart.joints_M.Kf = args.Kf_M;
stewart.joints_M.Cf = args.Cf_M;
stewart.joints_M.Kf = args.Kf_M;
stewart.joints_M.Kt = args.Kt_M;
stewart.joints_M.Kt = args.Kt_M;
stewart.joints_M.Ct = args.Ct_M;
end
stewart.joints_F.Kf = args.Kf_F;
stewart.joints_F.Kt = args.Kt_F;
#+end_src
if ~strcmp(args.type_F, 'universal_p') || ~strcmp(args.type_F, 'spherical_p')
stewart.joints_F.Kf = args.Kf_F;
stewart.joints_F.Cf = args.Cf_F;
Rotational Damping
#+begin_src matlab
stewart.joints_M.Cf = args.Cf_M;
stewart.joints_M.Ct = args.Ct_M;
stewart.joints_F.Kt = args.Kt_F;
stewart.joints_F.Ct = args.Ct_F;
end
stewart.joints_F.Cf = args.Cf_F;
stewart.joints_F.Ct = args.Ct_F;
#+end_src
** Stiffness and Mass matrices for flexible joint
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
stewart.joints_F.M = args.M_F;
stewart.joints_F.K = args.K_F;
stewart.joints_F.n_xyz = args.n_xyz_F;
stewart.joints_F.xi = args.xi_F;
stewart.joints_F.xi = args.xi_F;
stewart.joints_F.step_file = args.step_file_F;
stewart.joints_M.M = args.M_M;
stewart.joints_M.K = args.K_M;
stewart.joints_M.n_xyz = args.n_xyz_M;
stewart.joints_M.xi = args.xi_M;
stewart.joints_M.step_file = args.step_file_M;
#+end_src
* =initializeInertialSensor=: Initialize the inertial sensor in each strut