phd-nass-flexible-joints/nass-flexible-joints.org

1440 lines
49 KiB
Org Mode
Raw Permalink Normal View History

2024-03-19 15:16:03 +01:00
#+TITLE: Nano-Hexapod - Flexible Joints Optimization
:DRAWER:
#+LANGUAGE: en
#+EMAIL: dehaeze.thomas@gmail.com
#+AUTHOR: Dehaeze Thomas
#+HTML_LINK_HOME: ../index.html
#+HTML_LINK_UP: ../index.html
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="https://research.tdehaeze.xyz/css/style.css"/>
#+HTML_HEAD: <script type="text/javascript" src="https://research.tdehaeze.xyz/js/script.js"></script>
#+BIND: org-latex-image-default-option "scale=1"
#+BIND: org-latex-image-default-width ""
#+LaTeX_CLASS: scrreprt
#+LaTeX_CLASS_OPTIONS: [a4paper, 10pt, DIV=12, parskip=full, bibliography=totoc]
#+LaTeX_HEADER_EXTRA: \input{preamble.tex}
#+LATEX_HEADER_EXTRA: \bibliography{nass-flexible-joints.bib}
#+BIND: org-latex-bib-compiler "biber"
#+PROPERTY: header-args:matlab :session *MATLAB*
#+PROPERTY: header-args:matlab+ :comments org
#+PROPERTY: header-args:matlab+ :exports none
#+PROPERTY: header-args:matlab+ :results none
#+PROPERTY: header-args:matlab+ :eval no-export
#+PROPERTY: header-args:matlab+ :noweb yes
#+PROPERTY: header-args:matlab+ :mkdirp yes
#+PROPERTY: header-args:matlab+ :output-dir figs
#+PROPERTY: header-args:matlab+ :tangle no
#+PROPERTY: header-args:latex :headers '("\\usepackage{tikz}" "\\usepackage{import}" "\\import{$HOME/Cloud/tikz/org/}{config.tex}")
#+PROPERTY: header-args:latex+ :imagemagick t :fit yes
#+PROPERTY: header-args:latex+ :iminoptions -scale 100% -density 150
#+PROPERTY: header-args:latex+ :imoutoptions -quality 100
#+PROPERTY: header-args:latex+ :results file raw replace
#+PROPERTY: header-args:latex+ :buffer no
#+PROPERTY: header-args:latex+ :tangle no
#+PROPERTY: header-args:latex+ :eval no-export
#+PROPERTY: header-args:latex+ :exports results
#+PROPERTY: header-args:latex+ :mkdirp yes
#+PROPERTY: header-args:latex+ :output-dir figs
#+PROPERTY: header-args:latex+ :post pdf2svg(file=*this*, ext="png")
:END:
#+begin_export html
<hr>
<p>This report is also available as a <a href="./nass-flexible-joints.pdf">pdf</a>.</p>
<hr>
#+end_export
#+latex: \clearpage
* Build :noexport:
#+NAME: startblock
#+BEGIN_SRC emacs-lisp :results none :tangle no
(add-to-list 'org-latex-classes
'("scrreprt"
"\\documentclass{scrreprt}"
("\\chapter{%s}" . "\\chapter*{%s}")
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\paragraph{%s}" . "\\paragraph*{%s}")
))
;; Remove automatic org heading labels
(defun my-latex-filter-removeOrgAutoLabels (text backend info)
"Org-mode automatically generates labels for headings despite explicit use of `#+LABEL`. This filter forcibly removes all automatically generated org-labels in headings."
(when (org-export-derived-backend-p backend 'latex)
(replace-regexp-in-string "\\\\label{sec:org[a-f0-9]+}\n" "" text)))
(add-to-list 'org-export-filter-headline-functions
'my-latex-filter-removeOrgAutoLabels)
;; Remove all org comments in the output LaTeX file
(defun delete-org-comments (backend)
(loop for comment in (reverse (org-element-map (org-element-parse-buffer)
'comment 'identity))
do
(setf (buffer-substring (org-element-property :begin comment)
(org-element-property :end comment))
"")))
(add-hook 'org-export-before-processing-hook 'delete-org-comments)
;; Use no package by default
(setq org-latex-packages-alist nil)
(setq org-latex-default-packages-alist nil)
;; Do not include the subtitle inside the title
(setq org-latex-subtitle-separate t)
(setq org-latex-subtitle-format "\\subtitle{%s}")
(setq org-export-before-parsing-hook '(org-ref-glossary-before-parsing
org-ref-acronyms-before-parsing))
#+END_SRC
* Notes :noexport:
- [ ] look at the conclusion of the 2020-report
- [ ] Convert this to a "standard report" in its own directory
- [ ] Add figs
- [ ] Add simscape files
Outline:
- Perfect flexible joint
- Imperfection of the flexible joint: Model
- Study of the effect of limited stiffness in constrain directions and non-null stiffness in other directions
- Obtained Specification
- Design optimisation (FEM)
- Implementation of flexible elements in the Simscape model: close to simplified model
*** Effect of flexible joint characteristics on obtained dynamics
- Based on Simscape model
- Effect of axial stiffness, bending stiffness, ...
- Obtained specifications (trade-off)
*** Flexible joint geometry optimization
- Chosen geometry
- Show different existing geometry for flexible joints used on hexapods
- Optimisation with Ansys
- Validation with Simscape model
*** Experimental identification
- Experimental validation, characterisation ([[file:~/Cloud/work-projects/ID31-NASS/matlab/test-bench-flexible-joints-adv/bending.org::+TITLE: Flexible Joint - Measurement of the Bending Stiffness][study]])
- Visual inspection
- Test bench
- Obtained results
* Introduction :ignore:
In this document is studied the effect of the mechanical behavior of the flexible joints that are located the extremities of each nano-hexapod's legs.
Ideally, we want the x and y rotations to be free and all the translations to be blocked.
However, this is never the case and be have to consider:
- Finite bending stiffnesses (Section [[sec:rot_stiffness]])
- Axial stiffness in the direction of the legs (Section [[sec:trans_stiffness]])
This may impose some limitations, also, the goal is to specify the required joints stiffnesses (summarized in Section [[sec:conclusion]]).
#+name: tab:nass_flexible_joints_section_matlab_code
#+caption: Report sections and corresponding Matlab files
#+attr_latex: :environment tabularx :width 0.6\linewidth :align lX
#+attr_latex: :center t :booktabs t
| *Sections* | *Matlab File* |
|-----------------------------------+----------------------|
| Section ref:sec:nass_flexible_joints_1_a | =nass_flexible_joints_1_.m= |
* Bending and Torsional Stiffness
<<sec:rot_stiffness>>
** Introduction :ignore:
In this section, we wish to study the effect of the rotation flexibility of the nano-hexapod 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();
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
** Realistic Bending Stiffness Values
*** Introduction :ignore:
Let's compare the ideal case (zero stiffness in rotation and infinite stiffness in translation) with a more realistic case:
- $K_{\theta, \phi} = 15\,[Nm/rad]$ stiffness in flexion
- $K_{\psi} = 20\,[Nm/rad]$ stiffness in torsion
#+begin_src matlab
Kf_M = 15*ones(6,1);
Kf_F = 15*ones(6,1);
Kt_M = 20*ones(6,1);
Kt_F = 20*ones(6,1);
#+end_src
The stiffness and damping of the nano-hexapod's legs are:
#+begin_src matlab
k_opt = 1e5; % [N/m]
c_opt = 2e2; % [N/(m/s)]
#+end_src
This corresponds to the optimal identified stiffness.
*** Direct Velocity Feedback
We identify the dynamics from actuators force $\tau_i$ to relative motion sensors $d\mathcal{L}_i$ with and without considering the flexible joint stiffness.
The obtained dynamics are shown in Figure [[fig:flex_joint_rot_dvf]].
It is shown that the adding of stiffness for the flexible joints does increase a little bit the frequencies of the mass suspension modes. It stiffen the structure.
#+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
initializeNanoHexapod('k', k_opt, 'c', c_opt, ...
'type_F', 'universal_p', ...
'type_M', 'spherical_p');
G_dvf_p = linearize(mdl, io);
G_dvf_p.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
G_dvf_p.OutputName = {'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6'};
#+end_src
#+begin_src matlab :exports none
initializeNanoHexapod('k', k_opt, 'c', c_opt, ...
'type_F', 'universal', ...
'type_M', 'spherical', ...
'Kf_M', Kf_M, ...
'Kt_M', Kt_M, ...
'Kf_F', Kf_F, ...
'Kt_F', Kt_F);
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(-1, 3, 1000);
figure;
ax1 = subplot(2, 1, 1);
hold on;
plot(freqs, abs(squeeze(freqresp(G_dvf(1, 1), freqs, 'Hz'))));
plot(freqs, abs(squeeze(freqresp(G_dvf_p(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', 'Flexible Joints');
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_dvf_p(1, 1), freqs, 'Hz')))), ...
'DisplayName', 'Perfect 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 :tangle no :exports results :results file replace
exportFig('figs/flex_joint_rot_dvf.pdf', 'width', 'full', 'height', 'full');
#+end_src
#+name: fig:flex_joint_rot_dvf
#+caption: Dynamics from actuators force $\tau_i$ to relative motion sensors $d\mathcal{L}_i$ with (blue) and without (red) considering the flexible joint stiffness
#+RESULTS:
[[file:figs/flex_joint_rot_dvf.png]]
*** Primary Plant
#+begin_src matlab :exports none
Kdvf = 5e3*s/(1+s/2/pi/1e3)*eye(6);
#+end_src
Let's now identify the dynamics from $\bm{\tau}^\prime$ to $\bm{\epsilon}_{\mathcal{X}_n}$ (for the primary controller designed in the frame of the legs).
The dynamics is compare with and without the joint flexibility in Figure [[fig:flex_joints_rot_primary_plant_L]].
The plant dynamics is not found to be changing significantly.
#+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, 'input'); io_i = io_i + 1; % Actuator Inputs
io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En'); io_i = io_i + 1; % Position Errror
load('mat/stages.mat', 'nano_hexapod');
#+end_src
#+begin_src matlab :exports none
initializeNanoHexapod('k', k_opt, 'c', c_opt, ...
'type_F', 'universal_p', ...
'type_M', 'spherical_p');
G = linearize(mdl, io);
G.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
G.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
Gl_p = -nano_hexapod.kinematics.J*G;
Gl_p.OutputName = {'E1', 'E2', 'E3', 'E4', 'E5', 'E6'};
#+end_src
#+begin_src matlab :exports none
initializeNanoHexapod('k', k_opt, 'c', c_opt, ...
'type_F', 'universal', ...
'type_M', 'spherical', ...
'Kf_M', Kf_M, ...
'Kt_M', Kt_M, ...
'Kf_F', Kf_F, ...
'Kt_F', Kt_F);
G = linearize(mdl, io);
G.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
G.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
Gl = -nano_hexapod.kinematics.J*G;
Gl.OutputName = {'E1', 'E2', 'E3', 'E4', 'E5', 'E6'};
#+end_src
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
ax1 = subplot(2, 1, 1);
hold on;
for j = 1:6
set(gca,'ColorOrderIndex',1);
plot(freqs, abs(squeeze(freqresp(Gl(j, j), freqs, 'Hz'))));
end
for j = 1:6
set(gca,'ColorOrderIndex',2);
plot(freqs, abs(squeeze(freqresp(Gl_p(j, j), freqs, 'Hz'))));
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
ax2 = subplot(2, 1, 2);
hold on;
for j = 1:6
set(gca,'ColorOrderIndex',1);
if j == 1
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(Gl(j, j), freqs, 'Hz')))), ...
'DisplayName', 'Flexible Joints');
else
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(Gl(j, j), freqs, 'Hz')))), ...
'HandleVisibility', 'off');
end
end
for j = 1:6
set(gca,'ColorOrderIndex',2);
if j == 1
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(Gl_p(j, j), freqs, 'Hz')))), ...
'DisplayName', 'Perfect Joints');
else
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(Gl_p(j, j), freqs, 'Hz')))), ...
'HandleVisibility', 'off');
end
end
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', 'southwest');
linkaxes([ax1,ax2],'x');
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/flex_joints_rot_primary_plant_L.pdf', 'width', 'full', 'height', 'full');
#+end_src
#+name: fig:flex_joints_rot_primary_plant_L
#+caption: Dynamics from $\bm{\tau}^\prime_i$ to $\bm{\epsilon}_{\mathcal{X}_n,i}$ with perfect joints and with flexible joints
#+RESULTS:
[[file:figs/flex_joints_rot_primary_plant_L.png]]
*** Conclusion
#+begin_important
Considering realistic flexible joint bending stiffness for the nano-hexapod does not seems to impose any limitation on the DVF control nor on the primary control.
It only increases a little bit the suspension modes of the sample on top of the nano-hexapod.
#+end_important
** Parametric Study
*** Introduction :ignore:
We wish now to see what is the impact of the rotation stiffness of the flexible joints on the dynamics.
This will help to determine the requirements on the joint's stiffness.
Let's consider the following bending stiffness of the flexible joints:
#+begin_src matlab
Ks = [1, 5, 10, 50, 100]; % [Nm/rad]
#+end_src
We also consider here a nano-hexapod with the identified optimal actuator stiffness.
#+begin_src matlab :exports none
K = tf(zeros(6));
Kdvf = tf(zeros(6));
#+end_src
*** Direct Velocity Feedback
The dynamics from the actuators to the relative displacement sensor in each leg is identified and shown in Figure [[fig:flex_joints_rot_study_dvf]].
The corresponding Root Locus plot is shown in Figure [[fig:flex_joints_rot_study_dvf_root_locus]].
It is shown that the bending stiffness of the flexible joints does indeed change a little the dynamics, but critical damping is stiff achievable with 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; % Relative Displacement Sensors
G_dvf_s = {zeros(length(Ks), 1)};
for i = 1:length(Ks)
initializeNanoHexapod('k', k_opt, 'c', c_opt, ...
'type_F', 'universal', ...
'type_M', 'spherical', ...
'Kf_M', Ks(i), ...
'Kt_M', Ks(i), ...
'Kf_F', Ks(i), ...
'Kt_F', Ks(i));
G = linearize(mdl, io);
G.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
G.OutputName = {'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6'};
G_dvf_s(i) = {G};
end
#+end_src
#+begin_src matlab :exports none
freqs = logspace(-1, 3, 1000);
figure;
ax1 = subplot(2, 1, 1);
hold on;
for i = 1:length(Ks)
plot(freqs, abs(squeeze(freqresp(G_dvf_s{i}(1, 1), freqs, 'Hz'))));
end
plot(freqs, abs(squeeze(freqresp(G_dvf_p(1, 1), freqs, 'Hz'))), 'k--');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
ax2 = subplot(2, 1, 2);
hold on;
for i = 1:length(Ks)
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_dvf_s{i}(1, 1), freqs, 'Hz')))), ...
'DisplayName', sprintf('$k = %.0f$ [Nm/rad]', Ks(i)));
end
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_dvf_p(1, 1), freqs, 'Hz')))), 'k--', ...
'DisplayName', 'Ideal Joint');
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', 'southwest');
linkaxes([ax1,ax2],'x');
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/flex_joints_rot_study_dvf.pdf', 'width', 'full', 'height', 'full');
#+end_src
#+name: fig:flex_joints_rot_study_dvf
#+caption: Dynamics from $\tau_i$ to $d\mathcal{L}_i$ for all the considered Rotation Stiffnesses
#+RESULTS:
[[file:figs/flex_joints_rot_study_dvf.png]]
#+begin_src matlab :exports none
figure;
gains = logspace(2, 5, 300);
hold on;
for i = 1:length(Ks)
set(gca,'ColorOrderIndex',i);
plot(real(pole(G_dvf_s{i})), imag(pole(G_dvf_s{i})), 'x', ...
'DisplayName', sprintf('$k = %.0f$ [Nm/rad]', Ks(i)));
set(gca,'ColorOrderIndex',i);
plot(real(tzero(G_dvf_s{i})), imag(tzero(G_dvf_s{i})), 'o', ...
'HandleVisibility', 'off');
for k = 1:length(gains)
set(gca,'ColorOrderIndex',i);
cl_poles = pole(feedback(G_dvf_s{i}, (gains(k)*s)*eye(6)));
plot(real(cl_poles), imag(cl_poles), '.', ...
'HandleVisibility', 'off');
end
end
hold off;
axis square;
xlim([-140, 10]); ylim([0, 150]);
xlabel('Real Part'); ylabel('Imaginary Part');
legend('location', 'northwest');
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/flex_joints_rot_study_dvf_root_locus.pdf', 'width', 'wide', 'height', 'tall');
#+end_src
#+name: fig:flex_joints_rot_study_dvf_root_locus
#+caption: Root Locus for all the considered Rotation Stiffnesses
#+RESULTS:
[[file:figs/flex_joints_rot_study_dvf_root_locus.png]]
*** Primary Control
The dynamics from $\bm{\tau}^\prime$ to $\bm{\epsilon}_{\mathcal{X}_n}$ (for the primary controller designed in the frame of the legs) is shown in Figure [[fig:flex_joints_rot_study_primary_plant]].
It is shown that the bending stiffness of the flexible joints have very little impact on the dynamics.
#+begin_src matlab :exports none
Kdvf = 5e3*s/(1+s/2/pi/1e3)*eye(6);
#+end_src
#+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, 'input'); io_i = io_i + 1; % Actuator Inputs
io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En'); io_i = io_i + 1; % Position Errror
load('mat/stages.mat', 'nano_hexapod');
Gl_s = {zeros(length(Ks), 1)};
for i = 1:length(Ks)
initializeNanoHexapod('k', k_opt, 'c', c_opt, ...
'type_F', 'universal', ...
'type_M', 'spherical', ...
'Kf_M', Ks(i), ...
'Kt_M', Ks(i), ...
'Kf_F', Ks(i), ...
'Kt_F', Ks(i));
G = linearize(mdl, io);
G.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
G.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
Gl = -nano_hexapod.kinematics.J*G;
Gl.OutputName = {'E1', 'E2', 'E3', 'E4', 'E5', 'E6'};
Gl_s(i) = {Gl};
end
#+end_src
#+begin_src matlab :exports none
freqs = logspace(-1, 3, 1000);
figure;
ax1 = subplot(2, 1, 1);
hold on;
for i = 1:length(Ks)
plot(freqs, abs(squeeze(freqresp(Gl_s{i}(1, 1), freqs, 'Hz'))));
end
plot(freqs, abs(squeeze(freqresp(Gl_p(1, 1), freqs, 'Hz'))), 'k--');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
ax2 = subplot(2, 1, 2);
hold on;
for i = 1:length(Ks)
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(Gl_s{i}(1, 1), freqs, 'Hz')))), ...
'DisplayName', sprintf('$k = %.0f$ [Nm/rad]', Ks(i)));
end
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(Gl_p(1, 1), freqs, 'Hz')))), 'k--', ...
'DisplayName', 'Ideal Joint');
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', 'southwest');
linkaxes([ax1,ax2],'x');
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/flex_joints_rot_study_primary_plant.pdf', 'width', 'full', 'height', 'full');
#+end_src
#+name: fig:flex_joints_rot_study_primary_plant
#+caption: Diagonal elements of the transfer function matrix from $\bm{\tau}^\prime$ to $\bm{\epsilon}_{\mathcal{X}_n}$ for the considered bending stiffnesses
#+RESULTS:
[[file:figs/flex_joints_rot_study_primary_plant.png]]
*** Conclusion
#+begin_important
The bending stiffness of the flexible joint does not significantly change the dynamics.
#+end_important
* Axial Stiffness
<<sec:trans_stiffness>>
** Introduction :ignore:
Let's know consider a flexibility in translation of the flexible joint, in the axis of the legs.
** 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
** Realistic Translation Stiffness Values
*** Introduction :ignore:
We choose realistic values of the axial stiffness of the joints:
\[ K_a = 60\,[N/\mu m] \]
#+begin_src matlab
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
Let's initialize all the stages with default parameters.
#+begin_src matlab
initializeGround();
initializeGranite();
initializeTy();
initializeRy();
initializeRz();
initializeMicroHexapod();
initializeAxisc();
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
*** Direct Velocity Feedback
The dynamics from actuators force $\tau_i$ to relative motion sensors $d\mathcal{L}_i$ with and without considering the flexible joint stiffness are identified.
The obtained dynamics are shown in Figure [[fig:flex_joint_trans_dvf]].
#+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
initializeNanoHexapod('k', k_opt, 'c', c_opt, ...
'type_F', 'universal_3dof', ...
'type_M', 'spherical_3dof', ...
'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'};
G_dvf_3dof.OutputName = {'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6'};
#+end_src
#+begin_src matlab :exports none
initializeNanoHexapod('k', k_opt, 'c', c_opt, ...
'type_F', 'universal', ...
'type_M', 'spherical');
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(-1, 3, 1000);
figure;
ax1 = subplot(2, 1, 1);
hold on;
plot(freqs, abs(squeeze(freqresp(G_dvf(1, 1), freqs, 'Hz'))));
plot(freqs, abs(squeeze(freqresp(G_dvf_3dof(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', '2dof Joints');
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_dvf_3dof(1, 1), freqs, 'Hz')))), ...
'DisplayName', '3dof 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 :tangle no :exports results :results file replace
exportFig('figs/flex_joint_trans_dvf.pdf', 'width', 'full', 'height', 'full');
#+end_src
#+name: fig:flex_joint_trans_dvf
#+caption: Dynamics from actuators force $\tau_i$ to relative motion sensors $d\mathcal{L}_i$ with (blue) and without (red) considering the flexible joint axis stiffness
#+RESULTS:
[[file:figs/flex_joint_trans_dvf.png]]
*** Primary Plant
#+begin_src matlab
Kdvf = 5e3*s/(1+s/2/pi/1e3)*eye(6);
#+end_src
Let's now identify the dynamics from $\bm{\tau}^\prime$ to $\bm{\epsilon}_{\mathcal{X}_n}$ (for the primary controller designed in the frame of the legs).
The dynamics is compare with and without the joint flexibility in Figure [[fig:flex_joints_trans_primary_plant_L]].
#+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, 'input'); io_i = io_i + 1; % Actuator Inputs
io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En'); io_i = io_i + 1; % Position Errror
load('mat/stages.mat', 'nano_hexapod');
#+end_src
#+begin_src matlab :exports none
initializeNanoHexapod('k', k_opt, 'c', c_opt, ...
'type_F', 'universal_3dof', ...
'type_M', 'spherical_3dof', ...
'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'};
G.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
Gl_3dof = -nano_hexapod.kinematics.J*G;
Gl_3dof.OutputName = {'E1', 'E2', 'E3', 'E4', 'E5', 'E6'};
#+end_src
#+begin_src matlab :exports none
initializeNanoHexapod('k', k_opt, 'c', c_opt, ...
'type_F', 'universal', ...
'type_M', 'spherical');
G = linearize(mdl, io);
G.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
G.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
Gl = -nano_hexapod.kinematics.J*G;
Gl.OutputName = {'E1', 'E2', 'E3', 'E4', 'E5', 'E6'};
#+end_src
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
ax1 = subplot(2, 1, 1);
hold on;
for j = 1:6
set(gca,'ColorOrderIndex',1);
plot(freqs, abs(squeeze(freqresp(Gl(j, j), freqs, 'Hz'))));
end
for j = 1:6
set(gca,'ColorOrderIndex',2);
plot(freqs, abs(squeeze(freqresp(Gl_3dof(j, j), freqs, 'Hz'))), '--');
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
title('Diagonal elements of the Plant');
ax2 = subplot(2, 1, 2);
hold on;
for j = 1:6
set(gca,'ColorOrderIndex',1);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(Gl(j, j), freqs, 'Hz')))));
end
for j = 1:6
set(gca,'ColorOrderIndex',2);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(Gl_3dof(j, j), freqs, 'Hz')))), '--');
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-270, 90]);
yticks([-360:90:360]);
linkaxes([ax1,ax2],'x');
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/flex_joints_trans_primary_plant_L.pdf', 'width', 'full', 'height', 'full');
#+end_src
#+name: fig:flex_joints_trans_primary_plant_L
#+caption: Dynamics from $\bm{\tau}^\prime_i$ to $\bm{\epsilon}_{\mathcal{X}_n,i}$ with infinite axis stiffnes (solid) and with realistic axial stiffness (dashed)
#+RESULTS:
[[file:figs/flex_joints_trans_primary_plant_L.png]]
*** Conclusion
#+begin_important
For the realistic value of the flexible joint axial stiffness, the dynamics is not much impact, and this should not be a problem for control.
#+end_important
** Parametric study
*** Introduction :ignore:
We wish now to see what is the impact of the *axial* stiffness of the flexible joints on the dynamics.
Let's consider the following values for the axial stiffness:
#+begin_src matlab
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]$).
#+begin_src matlab :exports none
K = tf(zeros(6));
Kdvf = tf(zeros(6));
#+end_src
*** Direct Velocity Feedback
The dynamics from the actuators to the relative displacement sensor in each leg is identified and shown in Figure [[fig:flex_joints_trans_study_dvf]].
It is shown that the axial stiffness of the flexible joints does have a huge impact on the dynamics.
If the axial stiffness of the flexible joints is $K_a > 10^7\,[N/m]$ (here $100$ times higher than the actuator stiffness), then the change of dynamics stays reasonably small.
This is more clear by looking at the root locus (Figures [[fig:flex_joints_trans_study_dvf_root_locus]] and [[fig:flex_joints_trans_study_root_locus_unzoom]]).
It can be seen that very little active damping can be achieve for axial stiffnesses below $10^7\,[N/m]$.
#+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
G_dvf_3dof_s = {zeros(length(Kas), 1)};
for i = 1:length(Kas)
initializeNanoHexapod('k', k_opt, 'c', c_opt, ...
'type_F', 'universal_3dof', ...
'type_M', 'spherical_3dof', ...
'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'};
G.OutputName = {'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6'};
G_dvf_3dof_s(i) = {G};
end
#+end_src
#+begin_src matlab :exports none
freqs = logspace(-1, 3, 1000);
figure;
ax1 = subplot(2, 1, 1);
hold on;
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--');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
ax2 = subplot(2, 1, 2);
hold on;
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]', Kas(i)));
end
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_dvf(1, 1), freqs, 'Hz')))), 'k--', ...
'DisplayName', 'Perfect Joint');
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', 'southwest');
linkaxes([ax1,ax2],'x');
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/flex_joints_trans_study_dvf.pdf', 'width', 'full', 'height', 'full');
#+end_src
#+name: fig:flex_joints_trans_study_dvf
#+caption: Dynamics from $\tau_i$ to $d\mathcal{L}_i$ for all the considered axis Stiffnesses
#+RESULTS:
[[file:figs/flex_joints_trans_study_dvf.png]]
#+begin_src matlab :exports none
figure;
gains = logspace(2, 5, 300);
hold on;
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]', Kas(i)));
set(gca,'ColorOrderIndex',i);
plot(real(tzero(G_dvf_3dof_s{i})), imag(tzero(G_dvf_3dof_s{i})), 'o', ...
'HandleVisibility', 'off');
for k = 1:length(gains)
set(gca,'ColorOrderIndex',i);
cl_poles = pole(feedback(G_dvf_3dof_s{i}, (gains(k)*s)*eye(6)));
plot(real(cl_poles), imag(cl_poles), '.', ...
'HandleVisibility', 'off');
end
end
hold off;
axis square;
xlim([-140, 10]); ylim([0, 150]);
xlabel('Real Part'); ylabel('Imaginary Part');
legend('location', 'northwest');
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/flex_joints_trans_study_dvf_root_locus.pdf', 'width', 'wide', 'height', 'tall');
#+end_src
#+name: fig:flex_joints_trans_study_dvf_root_locus
#+caption: Root Locus for all the considered axial Stiffnesses
#+RESULTS:
[[file:figs/flex_joints_trans_study_dvf_root_locus.png]]
#+begin_src matlab :exports none
xlim([-1e3, 0]);
ylim([0, 1e3]);
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/flex_joints_trans_study_root_locus_unzoom.pdf', 'width', 'wide', 'height', 'tall');
#+end_src
#+name: fig:flex_joints_trans_study_root_locus_unzoom
#+caption: Root Locus (unzoom) for all the considered axial Stiffnesses
#+RESULTS:
[[file:figs/flex_joints_trans_study_root_locus_unzoom.png]]
*** Primary Control
The dynamics from $\bm{\tau}^\prime$ to $\bm{\epsilon}_{\mathcal{X}_n}$ (for the primary controller designed in the frame of the legs) is shown in Figure [[fig:flex_joints_trans_study_primary_plant]].
#+begin_src matlab :exports none
Kdvf = 5e3*s/(1+s/2/pi/1e3)*eye(6);
#+end_src
#+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, 'input'); io_i = io_i + 1; % Actuator Inputs
io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En'); io_i = io_i + 1; % Position Errror
load('mat/stages.mat', 'nano_hexapod');
Gl_3dof_s = {zeros(length(Kas), 1)};
for i = 1:length(Kas)
initializeNanoHexapod('k', k_opt, 'c', c_opt, ...
'type_F', 'universal_3dof', ...
'type_M', 'spherical_3dof', ...
'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'};
G.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
Gl_3dof = -nano_hexapod.kinematics.J*G;
Gl_3dof.OutputName = {'E1', 'E2', 'E3', 'E4', 'E5', 'E6'};
Gl_3dof_s(i) = {Gl_3dof};
end
#+end_src
#+begin_src matlab :exports none
freqs = logspace(-1, 3, 1000);
figure;
ax1 = subplot(2, 1, 1);
hold on;
for i = 1:length(Kas)
plot(freqs, abs(squeeze(freqresp(Gl_3dof_s{i}(1, 1), freqs, 'Hz'))));
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
ax2 = subplot(2, 1, 2);
hold on;
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]', Kas(i)));
end
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 :tangle no :exports results :results file replace
exportFig('figs/flex_joints_trans_study_primary_plant.pdf', 'width', 'full', 'height', 'full');
#+end_src
#+name: fig:flex_joints_trans_study_primary_plant
#+caption: Diagonal elements of the transfer function matrix from $\bm{\tau}^\prime$ to $\bm{\epsilon}_{\mathcal{X}_n}$ for the considered axial stiffnesses
#+RESULTS:
[[file:figs/flex_joints_trans_study_primary_plant.png]]
** Conclusion
#+begin_important
The axial stiffness of the flexible joints should be maximized.
For the considered actuator stiffness $k = 10^5\,[N/m]$, the axial stiffness of the flexible joints should ideally be above $10^7\,[N/m]$.
This is a reasonable stiffness value for such joints.
We may interpolate the results and say that the axial joint stiffness should be 100 times higher than the actuator stiffness, but this should be confirmed with further analysis.
#+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
* Conclusion
<<sec:conclusion>>
#+begin_important
In this study we considered the bending, torsional and axial stiffnesses of the flexible joints used for the nano-hexapod.
The bending and torsional stiffnesses somehow adds a parasitic stiffness in parallel with the legs.
It is not found to be much problematic for the considered control architecture (it is however, if Integral Force Feedback is to be used).
As a consequence of the added stiffness, it could increase a little bit the required actuator force.
The axial stiffness of the flexible joints can be very problematic for control.
Small values of the axial stiffness are shown to limit the achievable damping with Direct Velocity Feedback.
The axial stiffness should therefore be maximized and taken into account in the model of the nano-hexapod.
For the identified optimal actuator stiffness $k = 10^5\,[N/m]$, the flexible joint should have the following stiffness properties:
- Axial Stiffness: $K_a > 10^7\,[N/m]$
- Bending Stiffness: $K_b < 50\,[Nm/rad]$
- Torsion Stiffness: $K_t < 50\,[Nm/rad]$
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
* Bibliography :ignore:
#+latex: \printbibliography[heading=bibintoc,title={Bibliography}]
* Helping Functions :noexport:
** Initialize Path
#+NAME: m-init-path
#+BEGIN_SRC matlab
%% Path for functions, data and scripts
addpath('./matlab/mat/'); % Path for data
addpath('./matlab/'); % Path for scripts
#+END_SRC
#+NAME: m-init-path-tangle
#+BEGIN_SRC matlab
%% Path for functions, data and scripts
addpath('./mat/'); % Path for data
#+END_SRC
** Initialize other elements
#+NAME: m-init-other
#+BEGIN_SRC matlab
%% Colors for the figures
colors = colororder;
#+END_SRC