1440 lines
49 KiB
Org Mode
1440 lines
49 KiB
Org Mode
#+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
|