1992 lines
75 KiB
Org Mode
1992 lines
75 KiB
Org Mode
#+TITLE: NASS - Finite Element Models with Simscape
|
|
: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-fem.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-fem.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:
|
|
|
|
- [ ] Convert this into a standard report
|
|
- [ ] look at the [[file:~/Cloud/research/papers/published/brumund21_multib_simul_reduc_order_flexib_bodies_fea/paper/brumund21_multib_simul_reduc_order_flexib_bodies_fea.pdf][published paper]]
|
|
|
|
* Introduction :ignore:
|
|
|
|
In this document, Finite Element Models (FEM) of parts of the Nano-Hexapod are developed and integrated into Simscape for dynamical analysis.
|
|
|
|
It is divided in the following sections:
|
|
- Section [[sec:APA300ML]]:
|
|
A super-element of the Amplified Piezoelectric Actuator APA300ML used for the NASS is exported using Ansys and imported in Simscape.
|
|
The static and dynamical properties of the APA300ML are then estimated using the Simscape model.
|
|
- Section [[sec:flexor_ID16]]:
|
|
A first geometry of a Flexible joint is modelled and its characteristics are identified from the Stiffness matrix as well as from the Simscape model.
|
|
- Section [[sec:flexor_025]]:
|
|
An optimized flexible joint is developed for the Nano-Hexapod and is then imported in a Simscape model.
|
|
- Section [[sec:strut_encoder]]:
|
|
A super element of a complete strut is studied.
|
|
|
|
* APA300ML
|
|
:PROPERTIES:
|
|
:header-args:matlab+: :tangle matlab/APA300ML.m
|
|
:END:
|
|
<<sec:APA300ML>>
|
|
** Introduction :ignore:
|
|
|
|
In this section, the Amplified Piezoelectric Actuator APA300ML ([[file:doc/APA300ML.pdf][doc]]) is modeled using a Finite Element Software.
|
|
Then a /super element/ is exported and imported in Simscape where its dynamic is studied.
|
|
|
|
A 3D view of the Amplified Piezoelectric Actuator (APA300ML) is shown in Figure [[fig:apa300ml_ansys]].
|
|
The remote point used are also shown in this figure.
|
|
|
|
#+name: fig:apa300ml_ansys
|
|
#+caption: Ansys FEM of the APA300ML
|
|
#+attr_latex: :width 0.7\linewidth
|
|
[[file:figs/apa300ml_ansys.jpg]]
|
|
|
|
** 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
|
|
addpath('matlab/');
|
|
addpath('matlab/APA300ML/');
|
|
#+end_src
|
|
|
|
#+begin_src matlab :eval no
|
|
addpath('APA300ML/');
|
|
#+end_src
|
|
|
|
#+begin_src matlab
|
|
% open('APA300ML.slx');
|
|
#+end_src
|
|
|
|
** Import Mass Matrix, Stiffness Matrix, and Interface Nodes Coordinates
|
|
We first extract the stiffness and mass matrices.
|
|
#+begin_src matlab
|
|
K = readmatrix('APA300ML_mat_K.CSV');
|
|
M = readmatrix('APA300ML_mat_M.CSV');
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports results :results value table replace :tangle no
|
|
data2orgtable(K(1:10, 1:10), {}, {}, ' %.1g ');
|
|
#+end_src
|
|
|
|
#+name: tab:APA300ML_mat_K
|
|
#+caption: First 10x10 elements of the Stiffness matrix
|
|
#+attr_latex: :environment tabularx :width \linewidth :align XXXXXXXXXX
|
|
#+attr_latex: :center t :booktabs t :font \tiny
|
|
#+RESULTS:
|
|
| 200000000 | 30000 | -20000 | -70 | 300000 | 40 | 10000000 | 10000 | -6000 | 30 |
|
|
| 30000 | 30000000 | 2000 | -200000 | 60 | -10 | 4000 | 2000000 | -500 | 9000 |
|
|
| -20000 | 2000 | 7000000 | -10 | -30 | 10 | 6000 | 900 | -500000 | 3 |
|
|
| -70 | -200000 | -10 | 1000 | -0.1 | 08 | -20 | -9000 | 3 | -30 |
|
|
| 300000 | 60 | -30 | -0.1 | 900 | 0.1 | 30000 | 20 | -10 | 06 |
|
|
| 40 | -10 | 10 | 08 | 0.1 | 10000 | 20 | 9 | -5 | 03 |
|
|
| 10000000 | 4000 | 6000 | -20 | 30000 | 20 | 200000000 | 10000 | 9000 | 50 |
|
|
| 10000 | 2000000 | 900 | -9000 | 20 | 9 | 10000 | 30000000 | -500 | 200000 |
|
|
| -6000 | -500 | -500000 | 3 | -10 | -5 | 9000 | -500 | 7000000 | -2 |
|
|
| 30 | 9000 | 3 | -30 | 06 | 03 | 50 | 200000 | -2 | 1000 |
|
|
|
|
|
|
#+begin_src matlab :exports results :results value table replace :tangle no
|
|
data2orgtable(M(1:10, 1:10), {}, {}, ' %.1g ');
|
|
#+end_src
|
|
|
|
#+name: tab:APA300ML_mat_M
|
|
#+caption: First 10x10 elements of the Mass matrix
|
|
#+attr_latex: :environment tabularx :width \linewidth :align XXXXXXXXXX
|
|
#+attr_latex: :center t :booktabs t :font \tiny
|
|
#+RESULTS:
|
|
| 0.01 | -2e-06 | 1e-06 | 6e-09 | 5e-05 | -5e-09 | -0.0005 | -7e-07 | 6e-07 | -3e-09 |
|
|
| -2e-06 | 0.01 | 8e-07 | -2e-05 | -8e-09 | 2e-09 | -9e-07 | -0.0002 | 1e-08 | -9e-07 |
|
|
| 1e-06 | 8e-07 | 0.009 | 5e-10 | 1e-09 | -1e-09 | -5e-07 | 3e-08 | 6e-05 | 1e-10 |
|
|
| 6e-09 | -2e-05 | 5e-10 | 3e-07 | 2e-11 | -3e-12 | 3e-09 | 9e-07 | -4e-10 | 3e-09 |
|
|
| 5e-05 | -8e-09 | 1e-09 | 2e-11 | 6e-07 | -4e-11 | -1e-06 | -2e-09 | 1e-09 | -8e-12 |
|
|
| -5e-09 | 2e-09 | -1e-09 | -3e-12 | -4e-11 | 1e-07 | -2e-09 | -1e-09 | -4e-10 | -5e-12 |
|
|
| -0.0005 | -9e-07 | -5e-07 | 3e-09 | -1e-06 | -2e-09 | 0.01 | 1e-07 | -3e-07 | -2e-08 |
|
|
| -7e-07 | -0.0002 | 3e-08 | 9e-07 | -2e-09 | -1e-09 | 1e-07 | 0.01 | -4e-07 | 2e-05 |
|
|
| 6e-07 | 1e-08 | 6e-05 | -4e-10 | 1e-09 | -4e-10 | -3e-07 | -4e-07 | 0.009 | -2e-10 |
|
|
| -3e-09 | -9e-07 | 1e-10 | 3e-09 | -8e-12 | -5e-12 | -2e-08 | 2e-05 | -2e-10 | 3e-07 |
|
|
|
|
|
|
Then, we extract the coordinates of the interface nodes.
|
|
#+begin_src matlab
|
|
[int_xyz, int_i, n_xyz, n_i, nodes] = extractNodes('APA300ML_out_nodes_3D.txt');
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports results :results value table replace :tangle no :post addhdr(*this*)
|
|
data2orgtable([[1:length(int_i)]', int_i, int_xyz], {}, {'Node i', 'Node Number', 'x [m]', 'y [m]', 'z [m]'}, ' %f ');
|
|
#+end_src
|
|
|
|
#+name: tab:coordinate_nodes
|
|
#+caption: Coordinates of the interface nodes
|
|
#+attr_latex: :environment tabularx :width 0.6\linewidth :align ccccc
|
|
#+attr_latex: :center t :booktabs t
|
|
#+RESULTS:
|
|
| Node i | Node Number | x [m] | y [m] | z [m] |
|
|
|--------+-------------+---------+-------+--------|
|
|
| 1.0 | 697783 | 0.0 | 0.0 | -0.015 |
|
|
| 2.0 | 697784 | 0.0 | 0.0 | 0.015 |
|
|
| 3.0 | 697785 | -0.0325 | 0.0 | 0.0 |
|
|
| 4.0 | 697786 | -0.0125 | 0.0 | 0.0 |
|
|
| 5.0 | 697787 | -0.0075 | 0.0 | 0.0 |
|
|
| 6.0 | 697788 | 0.0125 | 0.0 | 0.0 |
|
|
| 7.0 | 697789 | 0.0325 | 0.0 | 0.0 |
|
|
|
|
#+begin_src matlab :exports results :results value table replace :tangle no
|
|
data2orgtable([length(n_i); length(int_i); size(M,1) - 6*length(int_i); size(M,1)], {'Total number of Nodes', 'Number of interface Nodes', 'Number of Modes', 'Size of M and K matrices'}, {}, ' %.0f ');
|
|
#+end_src
|
|
|
|
#+name: tab:parameters_fem
|
|
#+caption: Some extracted parameters of the FEM
|
|
#+attr_latex: :environment tabularx :width 0.4\linewidth :align lc
|
|
#+attr_latex: :center t :booktabs t
|
|
#+RESULTS:
|
|
| Total number of Nodes | 7 |
|
|
| Number of interface Nodes | 7 |
|
|
| Number of Modes | 120 |
|
|
| Size of M and K matrices | 162 |
|
|
|
|
Using =K=, =M= and =int_xyz=, we can now use the =Reduced Order Flexible Solid= simscape block.
|
|
|
|
** Piezoelectric parameters
|
|
In order to make the conversion from applied voltage to generated force or from the strain to the generated voltage, we need to defined some parameters corresponding to the piezoelectric material:
|
|
#+begin_src matlab
|
|
d33 = 600e-12; % Strain constant [m/V]
|
|
n = 80; % Number of layers per stack
|
|
eT = 1.6e-8; % Permittivity under constant stress [F/m]
|
|
sD = 1e-11; % Compliance under constant electric displacement [m2/N]
|
|
ka = 235e6; % Stack stiffness [N/m]
|
|
C = 5e-6; % Stack capactiance [F]
|
|
#+end_src
|
|
|
|
PZT-4
|
|
#+begin_src matlab
|
|
d33 = 300e-12; % Strain constant [m/V]
|
|
n = 80; % Number of layers per stack
|
|
eT = 5.3e-9; % Permittivity under constant stress [F/m]
|
|
sD = 1e-11; % Compliance under constant electric displacement [m2/N]
|
|
ka = 235e6; % Stack stiffness [N/m]
|
|
C = 5e-6; % Stack capactiance [F]
|
|
#+end_src
|
|
|
|
The ratio of the developed force to applied voltage is:
|
|
#+name: eq:piezo_voltage_to_force
|
|
\begin{equation}
|
|
F_a = g_a V_a, \quad g_a = d_{33} n k_a
|
|
\end{equation}
|
|
where:
|
|
- $F_a$: developed force in [N]
|
|
- $n$: number of layers of the actuator stack
|
|
- $d_{33}$: strain constant in [m/V]
|
|
- $k_a$: actuator stack stiffness in [N/m]
|
|
- $V_a$: applied voltage in [V]
|
|
|
|
If we take the numerical values, we obtain:
|
|
#+begin_src matlab :results replace value
|
|
d33*n*ka % [N/V]
|
|
#+end_src
|
|
|
|
#+RESULTS:
|
|
: 5.64
|
|
|
|
From [[cite:&fleming14_desig_model_contr_nanop_system]] (page 123), the relation between relative displacement of the sensor stack and generated voltage is:
|
|
#+name: eq:piezo_strain_to_voltage
|
|
\begin{equation}
|
|
V_s = \frac{d_{33}}{\epsilon^T s^D n} \Delta h
|
|
\end{equation}
|
|
where:
|
|
- $V_s$: measured voltage in [V]
|
|
- $d_{33}$: strain constant in [m/V]
|
|
- $\epsilon^T$: permittivity under constant stress in [F/m]
|
|
- $s^D$: elastic compliance under constant electric displacement in [m^2/N]
|
|
- $n$: number of layers of the sensor stack
|
|
- $\Delta h$: relative displacement in [m]
|
|
|
|
If we take the numerical values, we obtain:
|
|
#+begin_src matlab :results replace value
|
|
1e-6*d33/(eT*sD*n) % [V/um]
|
|
#+end_src
|
|
|
|
#+RESULTS:
|
|
: 23.438
|
|
|
|
** Simscape Model
|
|
The flexible element is imported using the =Reduced Order Flexible Solid= simscape block.
|
|
|
|
Let's say we use two stacks as a force sensor and one stack as an actuator:
|
|
- A =Relative Motion Sensor= block is added between the nodes A and C
|
|
- An =Internal Force= block is added between the remote points E and B
|
|
|
|
The interface nodes are shown in Figure [[fig:apa300ml_ansys]].
|
|
|
|
One mass is fixed at one end of the piezo-electric stack actuator (remove point F), the other end is fixed to the world frame (remote point G).
|
|
|
|
** Identification of the APA Characteristics
|
|
*** Stiffness
|
|
#+begin_src matlab :exports none
|
|
m = 0.0001;
|
|
#+end_src
|
|
|
|
The transfer function from vertical external force to the relative vertical displacement is identified.
|
|
|
|
#+begin_src matlab :exports none
|
|
%% Name of the Simulink File
|
|
mdl = 'APA300ML';
|
|
|
|
%% Input/Output definition
|
|
clear io; io_i = 1;
|
|
io(io_i) = linio([mdl, '/Fd'], 1, 'openinput'); io_i = io_i + 1;
|
|
io(io_i) = linio([mdl, '/z'], 1, 'openoutput'); io_i = io_i + 1;
|
|
|
|
G = linearize(mdl, io);
|
|
#+end_src
|
|
|
|
The inverse of its DC gain is the axial stiffness of the APA:
|
|
#+begin_src matlab :results replace value
|
|
1e-6/dcgain(G) % [N/um]
|
|
#+end_src
|
|
|
|
#+RESULTS:
|
|
: 1.753
|
|
|
|
The specified stiffness in the datasheet is $k = 1.8\, [N/\mu m]$.
|
|
|
|
*** Resonance Frequency
|
|
The resonance frequency is specified to be between 650Hz and 840Hz.
|
|
This is also the case for the FEM model (Figure [[fig:apa300ml_resonance]]).
|
|
|
|
#+begin_src matlab :exports none
|
|
freqs = logspace(2, 4, 5000);
|
|
|
|
figure;
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G, freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
xlabel('Frequency [Hz]'); ylabel('Amplitude');
|
|
hold off;
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/apa300ml_resonance.pdf', 'width', 'wide', 'height', 'normal');
|
|
#+end_src
|
|
|
|
#+name: fig:apa300ml_resonance
|
|
#+caption: First resonance is around 800Hz
|
|
#+RESULTS:
|
|
[[file:figs/apa300ml_resonance.png]]
|
|
|
|
*** Amplification factor
|
|
The amplification factor is the ratio of the vertical displacement to the stack displacement.
|
|
|
|
#+begin_src matlab :exports none
|
|
%% Name of the Simulink File
|
|
mdl = 'APA300ML';
|
|
|
|
%% Input/Output definition
|
|
clear io; io_i = 1;
|
|
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1;
|
|
io(io_i) = linio([mdl, '/z'], 1, 'openoutput'); io_i = io_i + 1;
|
|
io(io_i) = linio([mdl, '/d'], 1, 'openoutput'); io_i = io_i + 1;
|
|
|
|
G = linearize(mdl, io);
|
|
#+end_src
|
|
|
|
The ratio of the two displacement is computed from the FEM model.
|
|
#+begin_src matlab :results replace value
|
|
abs(dcgain(G(1,1))./dcgain(G(2,1)))
|
|
#+end_src
|
|
|
|
#+RESULTS:
|
|
: 5.0749
|
|
|
|
This is actually correct and approximately corresponds to the ratio of the piezo height and length:
|
|
#+begin_src matlab :results replace value
|
|
75/15
|
|
#+end_src
|
|
|
|
#+RESULTS:
|
|
: 5
|
|
|
|
*** Stroke
|
|
|
|
Estimation of the actuator stroke:
|
|
\[ \Delta H = A n \Delta L \]
|
|
with:
|
|
- $\Delta H$ Axial Stroke of the APA
|
|
- $A$ Amplification factor (5 for the APA300ML)
|
|
- $n$ Number of stack used
|
|
- $\Delta L$ Stroke of the stack (0.1% of its length)
|
|
|
|
#+begin_src matlab :results replace value
|
|
1e6 * 5 * 3 * 20e-3 * 0.1e-2
|
|
#+end_src
|
|
|
|
#+RESULTS:
|
|
: 300
|
|
|
|
This is exactly the specified stroke in the data-sheet.
|
|
|
|
*** TODO Stroke BIS
|
|
- [ ] Identified the stroke form the transfer function from V to z
|
|
|
|
#+begin_src matlab :exports none
|
|
%% Name of the Simulink File
|
|
mdl = 'APA300ML';
|
|
|
|
%% Input/Output definition
|
|
clear io; io_i = 1;
|
|
io(io_i) = linio([mdl, '/V'], 1, 'openinput'); io_i = io_i + 1;
|
|
io(io_i) = linio([mdl, '/d'], 1, 'openoutput'); io_i = io_i + 1;
|
|
|
|
G = linearize(mdl, io);
|
|
|
|
1e6*170*abs(dcgain(G))
|
|
#+end_src
|
|
|
|
** Identification of the Dynamics from actuator to replace displacement
|
|
We first set the mass to be approximately zero.
|
|
#+begin_src matlab :exports none
|
|
m = 0.01;
|
|
#+end_src
|
|
|
|
The dynamics is identified from the applied force to the measured relative displacement.
|
|
#+begin_src matlab :exports none
|
|
%% Name of the Simulink File
|
|
mdl = 'APA300ML';
|
|
|
|
%% Input/Output definition
|
|
clear io; io_i = 1;
|
|
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1;
|
|
io(io_i) = linio([mdl, '/z'], 1, 'openoutput'); io_i = io_i + 1;
|
|
|
|
Gh = -linearize(mdl, io);
|
|
#+end_src
|
|
|
|
The same dynamics is identified for a payload mass of 10Kg.
|
|
#+begin_src matlab
|
|
m = 10;
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none
|
|
%% Name of the Simulink File
|
|
mdl = 'APA300ML';
|
|
|
|
%% Input/Output definition
|
|
clear io; io_i = 1;
|
|
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1;
|
|
io(io_i) = linio([mdl, '/z'], 1, 'openoutput'); io_i = io_i + 1;
|
|
|
|
Ghm = -linearize(mdl, io);
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none
|
|
freqs = logspace(0, 4, 5000);
|
|
|
|
figure;
|
|
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
|
|
|
|
ax1 = nexttile([2,1]);
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(Gh, freqs, 'Hz'))), '-');
|
|
plot(freqs, abs(squeeze(freqresp(Ghm, freqs, 'Hz'))), '-');
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
ylabel('Amplitude'); set(gca, 'XTickLabel',[]);
|
|
hold off;
|
|
|
|
ax2 = nexttile;
|
|
hold on;
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(Gh, freqs, 'Hz')))), '-', ...
|
|
'DisplayName', '$m = 0kg$');
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(Ghm, freqs, 'Hz')))), '-', ...
|
|
'DisplayName', '$m = 10kg$');
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
|
|
yticks(-360:90:360);
|
|
ylim([-360 0]);
|
|
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
|
|
hold off;
|
|
linkaxes([ax1,ax2],'x');
|
|
xlim([freqs(1), freqs(end)]);
|
|
legend('location', 'southwest');
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/apa300ml_plant_dynamics.pdf', 'width', 'wide', 'height', 'tall');
|
|
#+end_src
|
|
|
|
#+name: fig:apa300ml_plant_dynamics
|
|
#+caption: Transfer function from forces applied by the stack to the axial displacement of the APA
|
|
#+RESULTS:
|
|
[[file:figs/apa300ml_plant_dynamics.png]]
|
|
|
|
The root locus corresponding to Direct Velocity Feedback with a mass of 10kg is shown in Figure [[fig:apa300ml_dvf_root_locus]].
|
|
#+begin_src matlab :exports none
|
|
figure;
|
|
|
|
gains = logspace(0, 5, 500);
|
|
|
|
hold on;
|
|
plot(real(pole(Ghm)), imag(pole(G)), 'kx');
|
|
plot(real(tzero(Ghm)), imag(tzero(G)), 'ko');
|
|
for k = 1:length(gains)
|
|
cl_poles = pole(feedback(Ghm, gains(k)*s));
|
|
plot(real(cl_poles), imag(cl_poles), 'k.');
|
|
end
|
|
hold off;
|
|
axis square;
|
|
xlim([-500, 10]); ylim([0, 510]);
|
|
|
|
xlabel('Real Part'); ylabel('Imaginary Part');
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/apa300ml_dvf_root_locus.pdf', 'width', 'wide', 'height', 'tall');
|
|
#+end_src
|
|
|
|
#+name: fig:apa300ml_dvf_root_locus
|
|
#+caption: Root Locus for Direct Velocity Feedback
|
|
#+RESULTS:
|
|
[[file:figs/apa300ml_dvf_root_locus.png]]
|
|
|
|
** Identification of the Dynamics from actuator to force sensor
|
|
Let's use 2 stacks as a force sensor and 1 stack as force actuator.
|
|
|
|
The transfer function from actuator voltage to sensor voltage is identified and shown in Figure [[fig:apa300ml_iff_plant]].
|
|
#+begin_src matlab :exports none
|
|
m = 10;
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none
|
|
%% Name of the Simulink File
|
|
mdl = 'APA300ML';
|
|
|
|
%% Input/Output definition
|
|
clear io; io_i = 1;
|
|
io(io_i) = linio([mdl, '/Va'], 1, 'openinput'); io_i = io_i + 1;
|
|
io(io_i) = linio([mdl, '/Vs'], 1, 'openoutput'); io_i = io_i + 1;
|
|
|
|
Giff = -linearize(mdl, io);
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none
|
|
freqs = logspace(0, 4, 5000);
|
|
|
|
figure;
|
|
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
|
|
|
|
ax1 = nexttile([2,1]);
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(Giff, freqs, 'Hz'))), '-');
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
ylabel('Amplitude'); set(gca, 'XTickLabel',[]);
|
|
hold off;
|
|
|
|
ax2 = nexttile;
|
|
hold on;
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(Giff, freqs, 'Hz')))), '-');
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
|
|
yticks(-360:90:360);
|
|
ylim([-180 180]);
|
|
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
|
|
hold off;
|
|
linkaxes([ax1,ax2],'x');
|
|
xlim([freqs(1), freqs(end)]);
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/apa300ml_iff_plant.pdf', 'width', 'wide', 'height', 'tall');
|
|
#+end_src
|
|
|
|
#+name: fig:apa300ml_iff_plant
|
|
#+caption: Transfer function from actuator to force sensor
|
|
#+RESULTS:
|
|
[[file:figs/apa300ml_iff_plant.png]]
|
|
|
|
For root locus corresponding to IFF is shown in Figure [[fig:apa300ml_iff_root_locus]].
|
|
#+begin_src matlab :exports none
|
|
figure;
|
|
|
|
gains = logspace(0, 5, 500);
|
|
|
|
hold on;
|
|
plot(real(pole(Giff)), imag(pole(Giff)), 'kx');
|
|
plot(real(tzero(Giff)), imag(tzero(Giff)), 'ko');
|
|
for k = 1:length(gains)
|
|
cl_poles = pole(feedback(Giff, gains(k)/s));
|
|
plot(real(cl_poles), imag(cl_poles), 'k.');
|
|
end
|
|
hold off;
|
|
axis square;
|
|
xlim([-500, 10]); ylim([0, 510]);
|
|
|
|
xlabel('Real Part'); ylabel('Imaginary Part');
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/apa300ml_iff_root_locus.pdf', 'width', 'wide', 'height', 'tall');
|
|
#+end_src
|
|
|
|
#+name: fig:apa300ml_iff_root_locus
|
|
#+caption: Root Locus for IFF
|
|
#+RESULTS:
|
|
[[file:figs/apa300ml_iff_root_locus.png]]
|
|
|
|
** Identification for a simpler model
|
|
The goal in this section is to identify the parameters of a simple APA model from the FEM.
|
|
This can be useful is a lower order model is to be used for simulations.
|
|
|
|
The presented model is based on cite:souleille18_concep_activ_mount_space_applic.
|
|
|
|
The model represents the Amplified Piezo Actuator (APA) from Cedrat-Technologies (Figure [[fig:souleille18_model_piezo]]).
|
|
The parameters are shown in the table below.
|
|
|
|
#+name: fig:souleille18_model_piezo
|
|
#+caption: Picture of an APA100M from Cedrat Technologies. Simplified model of a one DoF payload mounted on such isolator
|
|
#+attr_latex: :width 0.7\linewidth
|
|
[[file:./figs/souleille18_model_piezo.png]]
|
|
|
|
#+name: tab:parameters_apa100m
|
|
#+caption:Parameters used for the model of the APA 100M
|
|
#+attr_latex: :environment tabularx :width 0.8\linewidth :align cl
|
|
#+attr_latex: :center t :booktabs t
|
|
| | Meaning |
|
|
|-------+----------------------------------------------------------------|
|
|
| $k_e$ | Stiffness used to adjust the pole of the isolator |
|
|
| $k_1$ | Stiffness of the metallic suspension when the stack is removed |
|
|
| $k_a$ | Stiffness of the actuator |
|
|
| $c_1$ | Added viscous damping |
|
|
|
|
The goal is to determine $k_e$, $k_a$ and $k_1$ so that the simplified model fits the FEM model.
|
|
|
|
\[ \alpha = \frac{x_1}{f}(\omega=0) = \frac{\frac{k_e}{k_e + k_a}}{k_1 + \frac{k_e k_a}{k_e + k_a}} \]
|
|
\[ \beta = \frac{x_1}{F}(\omega=0) = \frac{1}{k_1 + \frac{k_e k_a}{k_e + k_a}} \]
|
|
|
|
If we can fix $k_a$, we can determine $k_e$ and $k_1$ with:
|
|
\[ k_e = \frac{k_a}{\frac{\beta}{\alpha} - 1} \]
|
|
\[ k_1 = \frac{1}{\beta} - \frac{k_e k_a}{k_e + k_a} \]
|
|
|
|
#+begin_src matlab :exports none
|
|
m = 10;
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none
|
|
%% Name of the Simulink File
|
|
mdl = 'APA300ML';
|
|
|
|
%% Input/Output definition
|
|
clear io; io_i = 1;
|
|
io(io_i) = linio([mdl, '/Fd'], 1, 'openinput'); io_i = io_i + 1; % External Vertical Force [N]
|
|
io(io_i) = linio([mdl, '/w'], 1, 'openinput'); io_i = io_i + 1; % Base Motion [m]
|
|
io(io_i) = linio([mdl, '/Fa'], 1, 'openinput'); io_i = io_i + 1; % Actuator Force [N]
|
|
io(io_i) = linio([mdl, '/z'], 1, 'openoutput'); io_i = io_i + 1; % Vertical Displacement [m]
|
|
io(io_i) = linio([mdl, '/Vs'], 1, 'openoutput'); io_i = io_i + 1; % Force Sensor [V]
|
|
io(io_i) = linio([mdl, '/d'], 1, 'openoutput'); io_i = io_i + 1; % Stack Displacement [m]
|
|
|
|
G = linearize(mdl, io);
|
|
|
|
G.InputName = {'Fd', 'w', 'Fa'};
|
|
G.OutputName = {'y', 'Fs', 'd'};
|
|
#+end_src
|
|
|
|
From the identified dynamics, compute $\alpha$ and $\beta$
|
|
#+begin_src matlab
|
|
alpha = abs(dcgain(G('y', 'Fa')));
|
|
beta = abs(dcgain(G('y', 'Fd')));
|
|
#+end_src
|
|
|
|
$k_a$ is estimated using the following formula:
|
|
#+begin_src matlab
|
|
ka = 0.8/abs(dcgain(G('y', 'Fa')));
|
|
#+end_src
|
|
The factor can be adjusted to better match the curves.
|
|
|
|
Then $k_e$ and $k_1$ are computed.
|
|
#+begin_src matlab
|
|
ke = ka/(beta/alpha - 1);
|
|
k1 = 1/beta - ke*ka/(ke + ka);
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports results :results value table replace :tangle no :post addhdr(*this*)
|
|
data2orgtable(1e-6*[ka; ke; k1], {'=ka=', '=ke=', '=k1='}, {'Value [N/um]'}, ' %.1f ');
|
|
#+end_src
|
|
|
|
#+name: tab:stiffnesses_apa100m
|
|
#+caption:Obtained stiffnesses of the APA 100M
|
|
#+attr_latex: :environment tabularx :width 0.3\linewidth :align cl
|
|
#+attr_latex: :center t :booktabs t
|
|
#+RESULTS:
|
|
| | Value [N/um] |
|
|
|----+--------------|
|
|
| ka | 40.5 |
|
|
| ke | 1.5 |
|
|
| k1 | 0.4 |
|
|
|
|
The damping in the system is adjusted to match the FEM model if necessary.
|
|
#+begin_src matlab
|
|
c1 = 1e2;
|
|
#+end_src
|
|
|
|
The analytical model of the simpler system is defined below:
|
|
#+begin_src matlab
|
|
Ga = 1/(m*s^2 + k1 + c1*s + ke*ka/(ke + ka)) * ...
|
|
[ 1 , k1 + c1*s + ke*ka/(ke + ka) , ke/(ke + ka) ;
|
|
-ke*ka/(ke + ka), ke*ka/(ke + ka)*m*s^2 , -ke/(ke + ka)*(m*s^2 + c1*s + k1)];
|
|
|
|
Ga.InputName = {'Fd', 'w', 'Fa'};
|
|
Ga.OutputName = {'y', 'Fs'};
|
|
#+end_src
|
|
|
|
And the DC gain is adjusted for the force sensor:
|
|
#+begin_src matlab
|
|
F_gain = dcgain(G('Fs', 'Fd'))/dcgain(Ga('Fs', 'Fd'));
|
|
#+end_src
|
|
|
|
The dynamics of the FEM model and the simpler model are compared in Figure [[fig:apa300ml_comp_simpler_model]].
|
|
|
|
#+begin_src matlab :exports none
|
|
freqs = logspace(0, 5, 1000);
|
|
|
|
figure;
|
|
tiledlayout(2, 3, 'TileSpacing', 'None', 'Padding', 'None');
|
|
|
|
ax1 = nexttile;
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G( 'y', 'w'), freqs, 'Hz'))));
|
|
plot(freqs, abs(squeeze(freqresp(Ga('y', 'w'), freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
set(gca, 'XTickLabel',[]);
|
|
ylabel('$x_1/w$ [m/m]');
|
|
ylim([1e-6, 1e2]);
|
|
|
|
ax2 = nexttile;
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G( 'y', 'Fa'), freqs, 'Hz'))));
|
|
plot(freqs, abs(squeeze(freqresp(Ga('y', 'Fa'), freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
set(gca, 'XTickLabel',[]);
|
|
ylabel('$x_1/f$ [m/N]');
|
|
ylim([1e-14, 1e-6]);
|
|
|
|
ax3 = nexttile;
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G( 'y', 'Fd'), freqs, 'Hz'))));
|
|
plot(freqs, abs(squeeze(freqresp(Ga('y', 'Fd'), freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
set(gca, 'XTickLabel',[]);
|
|
ylabel('$x_1/F$ [m/N]');
|
|
ylim([1e-14, 1e-4]);
|
|
|
|
ax4 = nexttile;
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G( 'Fs', 'w'), freqs, 'Hz'))));
|
|
plot(freqs, abs(squeeze(freqresp(F_gain*Ga('Fs', 'w'), freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
xlabel('Frequency [Hz]');
|
|
ylabel('$F_s/w$ [m/m]');
|
|
ylim([1e2, 1e8]);
|
|
|
|
ax5 = nexttile;
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G( 'Fs', 'Fa'), freqs, 'Hz'))));
|
|
plot(freqs, abs(squeeze(freqresp(F_gain*Ga('Fs', 'Fa'), freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
xlabel('Frequency [Hz]');
|
|
ylabel('$F_s/f$ [m/N]');
|
|
ylim([1e-4, 1e1]);
|
|
|
|
ax6 = nexttile;
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G( 'Fs', 'Fd'), freqs, 'Hz'))));
|
|
plot(freqs, abs(squeeze(freqresp(F_gain*Ga('Fs', 'Fd'), freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
xlabel('Frequency [Hz]');
|
|
ylabel('$F_s/F$ [m/N]');
|
|
ylim([1e-7, 1e2]);
|
|
|
|
linkaxes([ax1,ax2,ax3,ax4,ax5,ax6],'x');
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/apa300ml_comp_simpler_model.pdf', 'width', 'full', 'height', 'full');
|
|
#+end_src
|
|
|
|
#+name: fig:apa300ml_comp_simpler_model
|
|
#+caption: Comparison of the Dynamics between the FEM model and the simplified one
|
|
#+attr_latex: :width 1.0\linewidth
|
|
#+RESULTS:
|
|
[[file:figs/apa300ml_comp_simpler_model.png]]
|
|
|
|
The simplified model has also been implemented in Simscape.
|
|
|
|
The dynamics of the Simscape simplified model is identified and compared with the FEM one in Figure [[fig:apa300ml_comp_simpler_simscape]].
|
|
#+begin_src matlab :exports none
|
|
%% Name of the Simulink File
|
|
mdl = 'APA300ML_simplified';
|
|
|
|
%% Input/Output definition
|
|
clear io; io_i = 1;
|
|
io(io_i) = linio([mdl, '/Fd'], 1, 'openinput'); io_i = io_i + 1; % External Vertical Force [N]
|
|
io(io_i) = linio([mdl, '/w'], 1, 'openinput'); io_i = io_i + 1; % Base Motion [m]
|
|
io(io_i) = linio([mdl, '/Fa'], 1, 'openinput'); io_i = io_i + 1; % Actuator Force [N]
|
|
io(io_i) = linio([mdl, '/y'], 1, 'openoutput'); io_i = io_i + 1; % Vertical Displacement [m]
|
|
io(io_i) = linio([mdl, '/Fs'], 1, 'openoutput'); io_i = io_i + 1; % Force Sensor [V]
|
|
|
|
Gs = linearize(mdl, io);
|
|
|
|
Gs.InputName = {'Fd', 'w', 'Fa'};
|
|
Gs.OutputName = {'y', 'Fs'};
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none
|
|
freqs = logspace(0, 5, 1000);
|
|
|
|
figure;
|
|
tiledlayout(2, 3, 'TileSpacing', 'None', 'Padding', 'None');
|
|
|
|
ax1 = nexttile;
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G( 'y', 'w'), freqs, 'Hz'))));
|
|
plot(freqs, abs(squeeze(freqresp(Gs('y', 'w'), freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
set(gca, 'XTickLabel',[]);
|
|
ylabel('$x_1/w$ [m/m]');
|
|
ylim([1e-6, 1e2]);
|
|
|
|
ax2 = nexttile;
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G( 'y', 'Fa'), freqs, 'Hz'))));
|
|
plot(freqs, abs(squeeze(freqresp(Gs('y', 'Fa'), freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
set(gca, 'XTickLabel',[]);
|
|
ylabel('$x_1/f$ [m/N]');
|
|
ylim([1e-14, 1e-6]);
|
|
|
|
ax3 = nexttile;
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G( 'y', 'Fd'), freqs, 'Hz'))));
|
|
plot(freqs, abs(squeeze(freqresp(Gs('y', 'Fd'), freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
set(gca, 'XTickLabel',[]);
|
|
ylabel('$x_1/F$ [m/N]');
|
|
ylim([1e-14, 1e-4]);
|
|
|
|
ax4 = nexttile;
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G( 'Fs', 'w'), freqs, 'Hz'))));
|
|
plot(freqs, abs(squeeze(freqresp(F_gain*Gs('Fs', 'w'), freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
xlabel('Frequency [Hz]');
|
|
ylabel('$F_s/w$ [m/m]');
|
|
ylim([1e2, 1e8]);
|
|
|
|
ax5 = nexttile;
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G( 'Fs', 'Fa'), freqs, 'Hz'))));
|
|
plot(freqs, abs(squeeze(freqresp(F_gain*Gs('Fs', 'Fa'), freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
xlabel('Frequency [Hz]');
|
|
ylabel('$F_s/f$ [m/N]');
|
|
ylim([1e-4, 1e1]);
|
|
|
|
ax6 = nexttile;
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G( 'Fs', 'Fd'), freqs, 'Hz'))));
|
|
plot(freqs, abs(squeeze(freqresp(F_gain*Gs('Fs', 'Fd'), freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
xlabel('Frequency [Hz]');
|
|
ylabel('$F_s/F$ [m/N]');
|
|
ylim([1e-7, 1e2]);
|
|
|
|
linkaxes([ax1,ax2,ax3,ax4,ax5,ax6],'x');
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/apa300ml_comp_simpler_simscape.pdf', 'width', 'full', 'height', 'full');
|
|
#+end_src
|
|
|
|
#+name: fig:apa300ml_comp_simpler_simscape
|
|
#+caption: Comparison of the Dynamics between the FEM model and the simplified simscape model
|
|
#+RESULTS:
|
|
[[file:figs/apa300ml_comp_simpler_simscape.png]]
|
|
|
|
** Integral Force Feedback
|
|
In this section, Integral Force Feedback control architecture is applied on the APA300ML.
|
|
|
|
First, the plant (dynamics from voltage actuator to voltage sensor is identified).
|
|
#+begin_src matlab :exports none
|
|
Kiff = tf(0);
|
|
#+end_src
|
|
|
|
The payload mass is set to 10kg.
|
|
#+begin_src matlab
|
|
m = 10;
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none
|
|
%% Name of the Simulink File
|
|
mdl = 'APA300ML_IFF';
|
|
|
|
%% Input/Output definition
|
|
clear io; io_i = 1;
|
|
io(io_i) = linio([mdl, '/w'], 1, 'openinput'); io_i = io_i + 1;
|
|
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1;
|
|
io(io_i) = linio([mdl, '/Fd'], 1, 'openinput'); io_i = io_i + 1;
|
|
io(io_i) = linio([mdl, '/z'], 1, 'openoutput'); io_i = io_i + 1;
|
|
io(io_i) = linio([mdl, '/APA300ML'], 1, 'openoutput'); io_i = io_i + 1;
|
|
|
|
G_ol = linearize(mdl, io);
|
|
G_ol.InputName = {'w', 'f', 'F'};
|
|
G_ol.OutputName = {'x1', 'Fs'};
|
|
|
|
G = G_ol({'Fs'}, {'f'});
|
|
#+end_src
|
|
|
|
The obtained dynamics is shown in Figure [[fig:piezo_amplified_iff_plant]].
|
|
|
|
#+begin_src matlab :exports none
|
|
freqs = logspace(1, 5, 1000);
|
|
|
|
figure;
|
|
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
|
|
|
|
ax1 = nexttile([2,1]);
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G, freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
ylabel('Amplitude'); set(gca, 'XTickLabel',[]);
|
|
hold off;
|
|
|
|
ax2 = nexttile;
|
|
hold on;
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G, freqs, 'Hz')))));
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
|
|
yticks(-360:90:360);
|
|
ylim([-390 30]);
|
|
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
|
|
hold off;
|
|
linkaxes([ax1,ax2],'x');
|
|
xlim([freqs(1), freqs(end)]);
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/piezo_amplified_iff_plant.pdf', 'width', 'wide', 'height', 'tall');
|
|
#+end_src
|
|
|
|
#+name: fig:piezo_amplified_iff_plant
|
|
#+caption: IFF Plant
|
|
#+RESULTS:
|
|
[[file:figs/piezo_amplified_iff_plant.png]]
|
|
|
|
The controller is defined below and the loop gain is shown in Figure [[fig:piezo_amplified_iff_loop_gain]].
|
|
#+begin_src matlab
|
|
Kiff = -1e3/s;
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none
|
|
freqs = logspace(1, 5, 1000);
|
|
|
|
figure;
|
|
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
|
|
|
|
ax1 = nexttile([2,1]);
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G*Kiff, freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
ylabel('Amplitude'); set(gca, 'XTickLabel',[]);
|
|
hold off;
|
|
|
|
ax2 = nexttile;
|
|
hold on;
|
|
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G*Kiff, freqs, 'Hz')))));
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
|
|
yticks(-360:90:360);
|
|
ylim([-180 180]);
|
|
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
|
|
hold off;
|
|
linkaxes([ax1,ax2],'x');
|
|
xlim([freqs(1), freqs(end)]);
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/piezo_amplified_iff_loop_gain.pdf', 'width', 'wide', 'height', 'tall');
|
|
#+end_src
|
|
|
|
#+name: fig:piezo_amplified_iff_loop_gain
|
|
#+caption: IFF Loop Gain
|
|
#+RESULTS:
|
|
[[file:figs/piezo_amplified_iff_loop_gain.png]]
|
|
|
|
Now the closed-loop system is identified again and compare with the open loop system in Figure [[fig:piezo_amplified_iff_comp]].
|
|
|
|
It is the expected behavior as shown in the Figure [[fig:souleille18_results]] (from cite:souleille18_concep_activ_mount_space_applic).
|
|
|
|
#+begin_src matlab :exports none
|
|
clear io; io_i = 1;
|
|
io(io_i) = linio([mdl, '/w'], 1, 'openinput'); io_i = io_i + 1;
|
|
io(io_i) = linio([mdl, '/F'], 1, 'openinput'); io_i = io_i + 1;
|
|
io(io_i) = linio([mdl, '/Fd'], 1, 'openinput'); io_i = io_i + 1;
|
|
io(io_i) = linio([mdl, '/z'], 1, 'openoutput'); io_i = io_i + 1;
|
|
io(io_i) = linio([mdl, '/APA300ML'], 1, 'output'); io_i = io_i + 1;
|
|
|
|
Giff = linearize(mdl, io);
|
|
Giff.InputName = {'w', 'f', 'F'};
|
|
Giff.OutputName = {'x1', 'Fs'};
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none
|
|
freqs = logspace(0, 3, 1000);
|
|
|
|
figure;
|
|
tiledlayout(2, 3, 'TileSpacing', 'None', 'Padding', 'None');
|
|
|
|
ax1 = nexttile;
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G_ol('x1', 'w'), freqs, 'Hz'))));
|
|
plot(freqs, abs(squeeze(freqresp(Giff('x1', 'w'), freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
set(gca, 'XTickLabel',[]); ylabel('$x_1/w$ [m/m]')
|
|
|
|
ax2 = nexttile;
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G_ol('x1', 'f'), freqs, 'Hz'))));
|
|
plot(freqs, abs(squeeze(freqresp(Giff('x1', 'f'), freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
set(gca, 'XTickLabel',[]); ylabel('$x_1/f$ [m/N]');
|
|
|
|
ax3 = nexttile;
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G_ol('x1', 'F'), freqs, 'Hz'))));
|
|
plot(freqs, abs(squeeze(freqresp(Giff('x1', 'F'), freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
set(gca, 'XTickLabel',[]); ylabel('$x_1/F$ [m/N]');
|
|
|
|
ax4 = nexttile;
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G_ol('Fs', 'w'), freqs, 'Hz'))));
|
|
plot(freqs, abs(squeeze(freqresp(Giff('Fs', 'w'), freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
xlabel('Frequency [Hz]'); ylabel('$F_s/w$ [N/m]');
|
|
|
|
ax5 = nexttile;
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G_ol('Fs', 'f'), freqs, 'Hz'))));
|
|
plot(freqs, abs(squeeze(freqresp(Giff('Fs', 'f'), freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
xlabel('Frequency [Hz]'); ylabel('$F_s/f$ [N/N]');
|
|
|
|
ax6 = nexttile;
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G_ol('Fs', 'F'), freqs, 'Hz'))));
|
|
plot(freqs, abs(squeeze(freqresp(Giff('Fs', 'F'), freqs, 'Hz'))));
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
xlabel('Frequency [Hz]'); ylabel('$F_s/F$ [N/N]');
|
|
|
|
linkaxes([ax1,ax2,ax3,ax4,ax5,ax6],'x');
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/piezo_amplified_iff_comp.pdf', 'width', 'full', 'height', 'full');
|
|
#+end_src
|
|
|
|
#+name: fig:piezo_amplified_iff_comp
|
|
#+caption: OL and CL transfer functions
|
|
#+RESULTS:
|
|
[[file:figs/piezo_amplified_iff_comp.png]]
|
|
|
|
#+name: fig:souleille18_results
|
|
#+caption: Results obtained in cite:souleille18_concep_activ_mount_space_applic
|
|
#+attr_latex: :width 1.0\linewidth
|
|
[[file:figs/souleille18_results.png]]
|
|
|
|
|
|
* First Flexible Joint Geometry
|
|
:PROPERTIES:
|
|
:header-args:matlab+: :tangle matlab/flexor_ID16.m
|
|
:END:
|
|
<<sec:flexor_ID16>>
|
|
** Introduction :ignore:
|
|
The studied flexor is shown in Figure [[fig:flexor_id16_screenshot]].
|
|
|
|
The stiffness and mass matrices representing the dynamics of the flexor are exported from a FEM.
|
|
It is then imported into Simscape.
|
|
|
|
A simplified model of the flexor is then developped.
|
|
|
|
#+name: fig:flexor_id16_screenshot
|
|
#+caption: Flexor studied
|
|
#+attr_latex: :width 0.3\linewidth
|
|
[[file:figs/flexor_id16_screenshot.png]]
|
|
|
|
** 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
|
|
addpath('matlab/');
|
|
addpath('matlab/flexor_ID16/');
|
|
#+end_src
|
|
|
|
#+begin_src matlab :eval no
|
|
addpath('flexor_ID16/');
|
|
#+end_src
|
|
|
|
#+begin_src matlab
|
|
open('flexor_ID16.slx');
|
|
#+end_src
|
|
|
|
** Import Mass Matrix, Stiffness Matrix, and Interface Nodes Coordinates
|
|
We first extract the stiffness and mass matrices.
|
|
#+begin_src matlab
|
|
K = extractMatrix('mat_K_6modes_2MDoF.matrix');
|
|
M = extractMatrix('mat_M_6modes_2MDoF.matrix');
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports results :results value table replace :tangle no
|
|
data2orgtable(K(1:10, 1:10), {}, {}, ' %.2e ');
|
|
#+end_src
|
|
|
|
#+name: tab:APA300ML_mat_K_2MDoF
|
|
#+caption: First 10x10 elements of the Stiffness matrix
|
|
#+attr_latex: :environment tabularx :width \linewidth :align XXXXXXXXXX
|
|
#+attr_latex: :center t :booktabs t :font \tiny
|
|
#+RESULTS:
|
|
| 11200000 | 195 | 2220 | -0.719 | -265 | 1.59 | -11200000 | -213 | -2220 | 0.147 | | 195 | 11400000 | 1290 | -148 | -0.188 | 2.41 | -212 | -11400000 | -1290 | 148 |
|
|
| 2220 | 1290 | 119000000 | 1.31 | 1.49 | 1.79 | -2220 | -1290 | -119000000 | -1.31 | | | | | | | | | | | |
|
|
| -0.719 | -148 | 1.31 | 33 | 000488 | -000977 | 0.141 | 148 | -1.31 | -33 | | | | | | | | | | | |
|
|
| -265 | -0.188 | 1.49 | 000488 | 33 | 00293 | 266 | 0.154 | -1.49 | 00026 | | | | | | | | | | | |
|
|
| 1.59 | 2.41 | 1.79 | -000977 | 00293 | 236 | -1.32 | -2.55 | -1.79 | 000379 | | | | | | | | | | | |
|
|
| -11200000 | -212 | -2220 | 0.141 | 266 | -1.32 | 11400000 | 24600 | 1640 | 120 | | | | | | | | | | | |
|
|
| -213 | -11400000 | -1290 | 148 | 0.154 | -2.55 | 24600 | 11400000 | 1290 | -72 | | | | | | | | | | | |
|
|
| -2220 | -1290 | -119000000 | -1.31 | -1.49 | -1.79 | 1640 | 1290 | 119000000 | 1.32 | | | | | | | | | | | |
|
|
| 0.147 | 148 | -1.31 | -33 | 00026 | 000379 | 120 | -72 | 1.32 | 34.7 | | | | | | | | | | | |
|
|
|
|
#+begin_src matlab :exports results :results value table replace :tangle no
|
|
data2orgtable(M(1:10, 1:10), {}, {}, ' %.1g ');
|
|
#+end_src
|
|
|
|
#+name: tab:APA300ML_mat_M_2MDoF
|
|
#+caption: First 10x10 elements of the Mass matrix
|
|
#+attr_latex: :environment tabularx :width \linewidth :align XXXXXXXXXX
|
|
#+attr_latex: :center t :booktabs t :font \tiny
|
|
#+RESULTS:
|
|
| 0.02 | 1e-09 | -4e-08 | -1e-10 | 0.0002 | -3e-11 | 0.004 | 5e-08 | 7e-08 | 1e-10 |
|
|
| 1e-09 | 0.02 | -3e-07 | -0.0002 | -1e-10 | -2e-09 | 2e-08 | 0.004 | 3e-07 | 1e-05 |
|
|
| -4e-08 | -3e-07 | 0.02 | 7e-10 | -2e-09 | 1e-09 | 3e-07 | 7e-08 | 0.003 | 1e-09 |
|
|
| -1e-10 | -0.0002 | 7e-10 | 4e-06 | -1e-12 | -6e-13 | 2e-10 | -7e-06 | -8e-10 | -1e-09 |
|
|
| 0.0002 | -1e-10 | -2e-09 | -1e-12 | 3e-06 | 2e-13 | 9e-06 | 4e-11 | 2e-09 | -3e-13 |
|
|
| -3e-11 | -2e-09 | 1e-09 | -6e-13 | 2e-13 | 4e-07 | 8e-11 | 9e-10 | -1e-09 | 2e-12 |
|
|
| 0.004 | 2e-08 | 3e-07 | 2e-10 | 9e-06 | 8e-11 | 0.02 | -7e-08 | -3e-07 | -2e-10 |
|
|
| 5e-08 | 0.004 | 7e-08 | -7e-06 | 4e-11 | 9e-10 | -7e-08 | 0.01 | -4e-08 | 0.0002 |
|
|
| 7e-08 | 3e-07 | 0.003 | -8e-10 | 2e-09 | -1e-09 | -3e-07 | -4e-08 | 0.02 | -1e-09 |
|
|
| 1e-10 | 1e-05 | 1e-09 | -1e-09 | -3e-13 | 2e-12 | -2e-10 | 0.0002 | -1e-09 | 2e-06 |
|
|
|
|
#+begin_src matlab :exports results :results value table replace :tangle no
|
|
data2orgtable([length(n_i); length(int_i); size(M,1) - 6*length(int_i); size(M,1)], {'Total number of Nodes', 'Number of interface Nodes', 'Number of Modes', 'Size of M and K matrices'}, {}, ' %.0f ');
|
|
#+end_src
|
|
|
|
#+name: tab:parameters_fem_2MDoF
|
|
#+caption: Some extracted parameters of the FEM
|
|
#+attr_latex: :environment tabularx :width 0.4\linewidth :align lc
|
|
#+attr_latex: :center t :booktabs t
|
|
#+RESULTS:
|
|
| Total number of Nodes | 2 |
|
|
| Number of interface Nodes | 2 |
|
|
| Number of Modes | 6 |
|
|
| Size of M and K matrices | 18 |
|
|
|
|
Then, we extract the coordinates of the interface nodes.
|
|
#+begin_src matlab
|
|
[int_xyz, int_i, n_xyz, n_i, nodes] = extractNodes('out_nodes_3D.txt');
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports results :results value table replace :tangle no :post addhdr(*this*)
|
|
data2orgtable([[1:length(int_i)]', int_i, int_xyz], {}, {'Node i', 'Node Number', 'x [m]', 'y [m]', 'z [m]'}, ' %f ');
|
|
#+end_src
|
|
|
|
#+name: tab:coordinate_nodes_2MDoF
|
|
#+caption: Coordinates of the interface nodes
|
|
#+attr_latex: :environment tabularx :width 0.6\linewidth :align ccccc
|
|
#+attr_latex: :center t :booktabs t
|
|
#+RESULTS:
|
|
| Node i | Node Number | x [m] | y [m] | z [m] |
|
|
|--------+-------------+-------+-------+-------|
|
|
| 1.0 | 181278.0 | 0.0 | 0.0 | 0.0 |
|
|
| 2.0 | 181279.0 | 0.0 | 0.0 | -0.0 |
|
|
|
|
Using =K=, =M= and =int_xyz=, we can use the =Reduced Order Flexible Solid= simscape block.
|
|
|
|
** Identification of the parameters using Simscape and looking at the Stiffness Matrix
|
|
The flexor is now imported into Simscape and its parameters are estimated using an identification.
|
|
|
|
#+begin_src matlab :exports none
|
|
m = 1;
|
|
#+end_src
|
|
|
|
The dynamics is identified from the applied force/torque to the measured displacement/rotation of the flexor.
|
|
#+begin_src matlab :exports none
|
|
%% Name of the Simulink File
|
|
mdl = 'flexor_ID16';
|
|
|
|
%% Input/Output definition
|
|
clear io; io_i = 1;
|
|
io(io_i) = linio([mdl, '/T'], 1, 'openinput'); io_i = io_i + 1;
|
|
io(io_i) = linio([mdl, '/D'], 1, 'openoutput'); io_i = io_i + 1;
|
|
|
|
G = linearize(mdl, io);
|
|
#+end_src
|
|
|
|
And we find the same parameters as the one estimated from the Stiffness matrix.
|
|
|
|
#+begin_src matlab :exports results :results value table replace :tangle no :post addhdr(*this*)
|
|
data2orgtable([1e-6*K(3,3), K(4,4), K(5,5), K(6,6) ; 1e-6./dcgain(G(3,3)), 1./dcgain(G(4,4)), 1./dcgain(G(5,5)), 1./dcgain(G(6,6))]', {'Axial Stiffness Dz [N/um]', 'Bending Stiffness Rx [Nm/rad]', 'Bending Stiffness Ry [Nm/rad]', 'Torsion Stiffness Rz [Nm/rad]'}, {'*Characteristic*', '*Value*', '*Identification*'}, ' %0.f ');
|
|
#+end_src
|
|
|
|
#+name: tab:comp_identified_stiffnesses
|
|
#+caption: Comparison of identified and FEM stiffnesses
|
|
#+attr_latex: :environment tabularx :width 0.7\linewidth :align lcc
|
|
#+attr_latex: :center t :booktabs t
|
|
#+RESULTS:
|
|
| *Characteristic* | *Value* | *Identification* |
|
|
|-------------------------------+---------+------------------|
|
|
| Axial Stiffness Dz [N/um] | 119 | 119 |
|
|
| Bending Stiffness Rx [Nm/rad] | 33 | 33 |
|
|
| Bending Stiffness Ry [Nm/rad] | 33 | 33 |
|
|
| Torsion Stiffness Rz [Nm/rad] | 236 | 236 |
|
|
|
|
** Simpler Model
|
|
Let's now model the flexible joint with a "perfect" Bushing joint as shown in Figure [[fig:flexible_joint_simscape]].
|
|
|
|
#+name: fig:flexible_joint_simscape
|
|
#+caption: Bushing Joint used to model the flexible joint
|
|
#+attr_latex: :width 0.3\linewidth
|
|
[[file:figs/flexible_joint_simscape.png]]
|
|
|
|
The parameters of the Bushing joint (stiffnesses) are estimated from the Stiffness matrix that was computed from the FEM.
|
|
#+begin_src matlab
|
|
Kx = K(1,1); % [N/m]
|
|
Ky = K(2,2); % [N/m]
|
|
Kz = K(3,3); % [N/m]
|
|
Krx = K(4,4); % [Nm/rad]
|
|
Kry = K(5,5); % [Nm/rad]
|
|
Krz = K(6,6); % [Nm/rad]
|
|
#+end_src
|
|
|
|
The dynamics from the applied force/torque to the measured displacement/rotation of the flexor is identified again for this simpler model.
|
|
#+begin_src matlab :exports none
|
|
%% Name of the Simulink File
|
|
mdl = 'flexor_ID16_simplified';
|
|
|
|
%% Input/Output definition
|
|
clear io; io_i = 1;
|
|
io(io_i) = linio([mdl, '/T'], 1, 'openinput'); io_i = io_i + 1;
|
|
io(io_i) = linio([mdl, '/D'], 1, 'openoutput'); io_i = io_i + 1;
|
|
|
|
Gs = linearize(mdl, io);
|
|
#+end_src
|
|
|
|
The two obtained dynamics are compared in Figure
|
|
|
|
#+begin_src matlab :exports none
|
|
freqs = logspace(0, 5, 1000);
|
|
|
|
figure;
|
|
tiledlayout(1, 2, 'TileSpacing', 'None', 'Padding', 'None');
|
|
|
|
ax1 = nexttile;
|
|
hold on;
|
|
set(gca,'ColorOrderIndex',1)
|
|
plot(freqs, abs(squeeze(freqresp(G(1,1), freqs, 'Hz'))), '-', 'DisplayName', '$D_x/F_x$');
|
|
set(gca,'ColorOrderIndex',1)
|
|
plot(freqs, abs(squeeze(freqresp(Gs(1,1), freqs, 'Hz'))), '--', 'HandleVisibility', 'off');
|
|
set(gca,'ColorOrderIndex',2)
|
|
plot(freqs, abs(squeeze(freqresp(G(2,2), freqs, 'Hz'))), '-', 'DisplayName', '$D_y/F_y$');
|
|
set(gca,'ColorOrderIndex',2)
|
|
plot(freqs, abs(squeeze(freqresp(Gs(2,2), freqs, 'Hz'))), '--', 'HandleVisibility', 'off');
|
|
set(gca,'ColorOrderIndex',3)
|
|
plot(freqs, abs(squeeze(freqresp(G(3,3), freqs, 'Hz'))), '-', 'DisplayName', '$D_z/F_z$');
|
|
set(gca,'ColorOrderIndex',3)
|
|
plot(freqs, abs(squeeze(freqresp(Gs(3,3), freqs, 'Hz'))), '--', 'HandleVisibility', 'off');
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
xlabel('Frequency [Hz]'); ylabel('Amplitude [m/N]');
|
|
hold off;
|
|
legend('location', 'southwest');
|
|
|
|
ax2 = nexttile;
|
|
hold on;
|
|
set(gca,'ColorOrderIndex',1)
|
|
plot(freqs, abs(squeeze(freqresp(G(4,4), freqs, 'Hz'))), '-', 'DisplayName', '$R_x/M_x$');
|
|
set(gca,'ColorOrderIndex',1)
|
|
plot(freqs, abs(squeeze(freqresp(Gs(4,4), freqs, 'Hz'))), '--', 'HandleVisibility', 'off');
|
|
set(gca,'ColorOrderIndex',2)
|
|
plot(freqs, abs(squeeze(freqresp(G(5,5), freqs, 'Hz'))), '-', 'DisplayName', '$R_y/M_y$');
|
|
set(gca,'ColorOrderIndex',2)
|
|
plot(freqs, abs(squeeze(freqresp(Gs(5,5), freqs, 'Hz'))), '--', 'HandleVisibility', 'off');
|
|
set(gca,'ColorOrderIndex',3)
|
|
plot(freqs, abs(squeeze(freqresp(G(6,6), freqs, 'Hz'))), '-', 'DisplayName', '$R_z/M_z$');
|
|
set(gca,'ColorOrderIndex',3)
|
|
plot(freqs, abs(squeeze(freqresp(Gs(6,6), freqs, 'Hz'))), '--', 'HandleVisibility', 'off');
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
xlabel('Frequency [Hz]'); ylabel('Amplitude [rad/Nm]');
|
|
hold off;
|
|
legend('location', 'southwest');
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/flexor_ID16_compare_bushing_joint.pdf', 'width', 'wide', 'height', 'normal');
|
|
#+end_src
|
|
|
|
#+name: fig:flexor_ID16_compare_bushing_joint
|
|
#+caption: Comparison of the Joint compliance between the FEM model and the simpler model
|
|
#+RESULTS:
|
|
[[file:figs/flexor_ID16_compare_bushing_joint.png]]
|
|
|
|
* Optimized Flexible Joint
|
|
:PROPERTIES:
|
|
:header-args:matlab+: :tangle matlab/flexor_025.m
|
|
:END:
|
|
<<sec:flexor_025>>
|
|
** Introduction :ignore:
|
|
|
|
The joint geometry has been optimized using Ansys to have lower bending stiffness while keeping a large axial stiffness.
|
|
|
|
The obtained geometry is shown in Figure [[fig:optimal_flexor]].
|
|
|
|
#+name: fig:optimal_flexor
|
|
#+caption: Flexor studied
|
|
#+attr_latex: :width 1.0\linewidth
|
|
[[file:figs/flexor_025_MDoF.jpg]]
|
|
|
|
** 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
|
|
addpath('matlab/');
|
|
addpath('matlab/flexor_025/');
|
|
#+end_src
|
|
|
|
#+begin_src matlab :eval no
|
|
addpath('flexor_025/');
|
|
#+end_src
|
|
|
|
#+begin_src matlab
|
|
open('flexor_025.slx');
|
|
#+end_src
|
|
|
|
** Import Mass Matrix, Stiffness Matrix, and Interface Nodes Coordinates
|
|
We first extract the stiffness and mass matrices.
|
|
#+begin_src matlab
|
|
K = readmatrix('flex025_mat_K.CSV');
|
|
M = readmatrix('flex025_mat_M.CSV');
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports results :results value table replace :tangle no
|
|
data2orgtable(K(1:10, 1:10), {}, {}, ' %.2e ');
|
|
#+end_src
|
|
|
|
#+name: tab:flex_mat_K
|
|
#+caption: First 10x10 elements of the Stiffness matrix
|
|
#+attr_latex: :environment tabularx :width \linewidth :align XXXXXXXXXX
|
|
#+attr_latex: :center t :booktabs t :font \tiny
|
|
#+RESULTS:
|
|
| 12700000 | -18.5 | -26.8 | 00162 | -4.63 | 64 | -12700000 | 18.3 | 26.7 | 00234 |
|
|
| -18.5 | 12700000 | -499 | -132 | 00414 | -0.495 | 18.4 | -12700000 | 499 | 132 |
|
|
| -26.8 | -499 | 94000000 | -470 | 00771 | -0.855 | 26.8 | 498 | -94000000 | 470 |
|
|
| 00162 | -132 | -470 | 4.83 | 2.61e-07 | 000123 | -00163 | 132 | 470 | -4.83 |
|
|
| -4.63 | 00414 | 00771 | 2.61e-07 | 4.83 | 4.43e-05 | 4.63 | -00413 | -00772 | -4.3e-07 |
|
|
| 64 | -0.495 | -0.855 | 000123 | 4.43e-05 | 260 | -64 | 0.495 | 0.855 | -000124 |
|
|
| -12700000 | 18.4 | 26.8 | -00163 | 4.63 | -64 | 12700000 | -18.2 | -26.7 | -00234 |
|
|
| 18.3 | -12700000 | 498 | 132 | -00413 | 0.495 | -18.2 | 12700000 | -498 | -132 |
|
|
| 26.7 | 499 | -94000000 | 470 | -00772 | 0.855 | -26.7 | -498 | 94000000 | -470 |
|
|
| 00234 | 132 | 470 | -4.83 | -4.3e-07 | -000124 | -00234 | -132 | -470 | 4.83 |
|
|
|
|
|
|
#+begin_src matlab :exports results :results value table replace :tangle no
|
|
data2orgtable(M(1:10, 1:10), {}, {}, ' %.1g ');
|
|
#+end_src
|
|
|
|
#+name: tab:flex_mat_M
|
|
#+caption: First 10x10 elements of the Mass matrix
|
|
#+attr_latex: :environment tabularx :width \linewidth :align XXXXXXXXXX
|
|
#+attr_latex: :center t :booktabs t :font \tiny
|
|
#+RESULTS:
|
|
| 0.006 | 8e-09 | -2e-08 | -1e-10 | 3e-05 | 3e-08 | 0.003 | -3e-09 | 9e-09 | 2e-12 |
|
|
| 8e-09 | 0.02 | 1e-07 | -3e-05 | 1e-11 | 6e-10 | 1e-08 | 0.003 | -5e-08 | 3e-09 |
|
|
| -2e-08 | 1e-07 | 0.01 | -6e-08 | -6e-11 | -8e-12 | -1e-07 | 1e-08 | 0.003 | -1e-08 |
|
|
| -1e-10 | -3e-05 | -6e-08 | 1e-06 | 7e-14 | 6e-13 | 1e-10 | 1e-06 | -1e-08 | 3e-10 |
|
|
| 3e-05 | 1e-11 | -6e-11 | 7e-14 | 2e-07 | 1e-10 | 3e-08 | -7e-12 | 6e-11 | -6e-16 |
|
|
| 3e-08 | 6e-10 | -8e-12 | 6e-13 | 1e-10 | 5e-07 | 1e-08 | -5e-10 | -1e-11 | 1e-13 |
|
|
| 0.003 | 1e-08 | -1e-07 | 1e-10 | 3e-08 | 1e-08 | 0.02 | -2e-08 | 1e-07 | -4e-12 |
|
|
| -3e-09 | 0.003 | 1e-08 | 1e-06 | -7e-12 | -5e-10 | -2e-08 | 0.006 | -8e-08 | 3e-05 |
|
|
| 9e-09 | -5e-08 | 0.003 | -1e-08 | 6e-11 | -1e-11 | 1e-07 | -8e-08 | 0.01 | -6e-08 |
|
|
| 2e-12 | 3e-09 | -1e-08 | 3e-10 | -6e-16 | 1e-13 | -4e-12 | 3e-05 | -6e-08 | 2e-07 |
|
|
|
|
|
|
Then, we extract the coordinates of the interface nodes.
|
|
#+begin_src matlab
|
|
[int_xyz, int_i, n_xyz, n_i, nodes] = extractNodes('flex025_out_nodes_3D.txt');
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports results :results value table replace :tangle no
|
|
data2orgtable([length(n_i); length(int_i); size(M,1) - 6*length(int_i); size(M,1)], {'Total number of Nodes', 'Number of interface Nodes', 'Number of Modes', 'Size of M and K matrices'}, {}, ' %.0f ');
|
|
#+end_src
|
|
|
|
#+name: tab:coordinate_nodes_flex
|
|
#+caption: Coordinates of the interface nodes for Flexible Joint
|
|
#+attr_latex: :environment tabularx :width 0.6\linewidth :align ccccc
|
|
#+attr_latex: :center t :booktabs t
|
|
#+RESULTS:
|
|
| Total number of Nodes | 2 |
|
|
| Number of interface Nodes | 2 |
|
|
| Number of Modes | 6 |
|
|
| Size of M and K matrices | 18 |
|
|
|
|
#+begin_src matlab :exports results :results value table replace :tangle no :post addhdr(*this*)
|
|
data2orgtable([[1:length(int_i)]', int_i, int_xyz], {}, {'Node i', 'Node Number', 'x [m]', 'y [m]', 'z [m]'}, ' %f ');
|
|
#+end_src
|
|
|
|
#+name: tab:coordinate_interface_nodes_flex
|
|
#+caption: Coordinates of the interface nodes
|
|
#+attr_latex: :environment tabularx :width 0.6\linewidth :align ccccc
|
|
#+attr_latex: :center t :booktabs t
|
|
#+RESULTS:
|
|
| Node i | Node Number | x [m] | y [m] | z [m] |
|
|
|--------+-------------+-------+-------+-------|
|
|
| 1.0 | 528875.0 | 0.0 | 0.0 | 0.0 |
|
|
| 2.0 | 528876.0 | 0.0 | 0.0 | -0.0 |
|
|
|
|
Using =K=, =M= and =int_xyz=, we can use the =Reduced Order Flexible Solid= simscape block.
|
|
|
|
** Identification of the parameters using Simscape
|
|
The flexor is now imported into Simscape and its parameters are estimated using an identification.
|
|
|
|
#+begin_src matlab :exports none
|
|
m = 1;
|
|
#+end_src
|
|
|
|
The dynamics is identified from the applied force/torque to the measured displacement/rotation of the flexor.
|
|
#+begin_src matlab :exports none
|
|
%% Name of the Simulink File
|
|
mdl = 'flexor_025';
|
|
|
|
%% Input/Output definition
|
|
clear io; io_i = 1;
|
|
io(io_i) = linio([mdl, '/T'], 1, 'openinput'); io_i = io_i + 1;
|
|
io(io_i) = linio([mdl, '/D'], 1, 'openoutput'); io_i = io_i + 1;
|
|
|
|
G = linearize(mdl, io);
|
|
#+end_src
|
|
|
|
And we find the same parameters as the one estimated from the Stiffness matrix.
|
|
|
|
#+begin_src matlab :exports results :results value table replace :tangle no :post addhdr(*this*)
|
|
data2orgtable([1e-6*K(3,3), K(4,4), K(5,5), K(6,6) ; 1e-6./dcgain(G(3,3)), 1./dcgain(G(4,4)), 1./dcgain(G(5,5)), 1./dcgain(G(6,6))]', {'Axial Stiffness Dz [N/um]', 'Bending Stiffness Rx [Nm/rad]', 'Bending Stiffness Ry [Nm/rad]', 'Torsion Stiffness Rz [Nm/rad]'}, {'*Caracteristic*', '*Value*', '*Identification*'}, ' %.1f ');
|
|
#+end_src
|
|
|
|
#+name: tab:comp_identified_stiffnesses_flex
|
|
#+caption: Comparison of identified and FEM stiffnesses
|
|
#+attr_latex: :environment tabularx :width 0.7\linewidth :align lcc
|
|
#+attr_latex: :center t :booktabs t
|
|
#+RESULTS:
|
|
| *Caracteristic* | *Value* | *Identification* |
|
|
|-------------------------------+---------+------------------|
|
|
| Axial Stiffness Dz [N/um] | 94.0 | 93.9 |
|
|
| Bending Stiffness Rx [Nm/rad] | 4.8 | 4.8 |
|
|
| Bending Stiffness Ry [Nm/rad] | 4.8 | 4.8 |
|
|
| Torsion Stiffness Rz [Nm/rad] | 260.2 | 260.2 |
|
|
|
|
** Simpler Model
|
|
Let's now model the flexible joint with a "perfect" Bushing joint as shown in Figure [[fig:flexible_joint_simscape]].
|
|
|
|
The parameters of the Bushing joint (stiffnesses) are estimated from the Stiffness matrix that was computed from the FEM.
|
|
#+begin_src matlab
|
|
Kx = K(1,1); % [N/m]
|
|
Ky = K(2,2); % [N/m]
|
|
Kz = K(3,3); % [N/m]
|
|
Krx = K(4,4); % [Nm/rad]
|
|
Kry = K(5,5); % [Nm/rad]
|
|
Krz = K(6,6); % [Nm/rad]
|
|
#+end_src
|
|
|
|
The dynamics from the applied force/torque to the measured displacement/rotation of the flexor is identified again for this simpler model.
|
|
#+begin_src matlab :exports none
|
|
%% Name of the Simulink File
|
|
mdl = 'flexor_025_simplified';
|
|
|
|
%% Input/Output definition
|
|
clear io; io_i = 1;
|
|
io(io_i) = linio([mdl, '/T'], 1, 'openinput'); io_i = io_i + 1;
|
|
io(io_i) = linio([mdl, '/D'], 1, 'openoutput'); io_i = io_i + 1;
|
|
|
|
Gs = linearize(mdl, io);
|
|
#+end_src
|
|
|
|
The two obtained dynamics are compared in Figure
|
|
|
|
#+begin_src matlab :exports none
|
|
freqs = logspace(0, 5, 1000);
|
|
|
|
figure;
|
|
tiledlayout(1, 2, 'TileSpacing', 'None', 'Padding', 'None');
|
|
|
|
ax1 = nexttile;
|
|
hold on;
|
|
set(gca,'ColorOrderIndex',1)
|
|
plot(freqs, abs(squeeze(freqresp(G(1,1), freqs, 'Hz'))), '-', 'DisplayName', '$D_x/F_x$');
|
|
set(gca,'ColorOrderIndex',1)
|
|
plot(freqs, abs(squeeze(freqresp(Gs(1,1), freqs, 'Hz'))), '--', 'HandleVisibility', 'off');
|
|
set(gca,'ColorOrderIndex',2)
|
|
plot(freqs, abs(squeeze(freqresp(G(2,2), freqs, 'Hz'))), '-', 'DisplayName', '$D_y/F_y$');
|
|
set(gca,'ColorOrderIndex',2)
|
|
plot(freqs, abs(squeeze(freqresp(Gs(2,2), freqs, 'Hz'))), '--', 'HandleVisibility', 'off');
|
|
set(gca,'ColorOrderIndex',3)
|
|
plot(freqs, abs(squeeze(freqresp(G(3,3), freqs, 'Hz'))), '-', 'DisplayName', '$D_z/F_z$');
|
|
set(gca,'ColorOrderIndex',3)
|
|
plot(freqs, abs(squeeze(freqresp(Gs(3,3), freqs, 'Hz'))), '--', 'HandleVisibility', 'off');
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
xlabel('Frequency [Hz]'); ylabel('Amplitude [m/N]');
|
|
hold off;
|
|
legend('location', 'southwest');
|
|
|
|
ax2 = nexttile;
|
|
hold on;
|
|
set(gca,'ColorOrderIndex',1)
|
|
plot(freqs, abs(squeeze(freqresp(G(4,4), freqs, 'Hz'))), '-', 'DisplayName', '$R_x/M_x$');
|
|
set(gca,'ColorOrderIndex',1)
|
|
plot(freqs, abs(squeeze(freqresp(Gs(4,4), freqs, 'Hz'))), '--', 'HandleVisibility', 'off');
|
|
set(gca,'ColorOrderIndex',2)
|
|
plot(freqs, abs(squeeze(freqresp(G(5,5), freqs, 'Hz'))), '-', 'DisplayName', '$R_y/M_y$');
|
|
set(gca,'ColorOrderIndex',2)
|
|
plot(freqs, abs(squeeze(freqresp(Gs(5,5), freqs, 'Hz'))), '--', 'HandleVisibility', 'off');
|
|
set(gca,'ColorOrderIndex',3)
|
|
plot(freqs, abs(squeeze(freqresp(G(6,6), freqs, 'Hz'))), '-', 'DisplayName', '$R_z/M_z$');
|
|
set(gca,'ColorOrderIndex',3)
|
|
plot(freqs, abs(squeeze(freqresp(Gs(6,6), freqs, 'Hz'))), '--', 'HandleVisibility', 'off');
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
xlabel('Frequency [Hz]'); ylabel('Amplitude [rad/Nm]');
|
|
hold off;
|
|
legend('location', 'southwest');
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/flexor_ID16_compare_bushing_joint_optimized.pdf', 'width', 'wide', 'height', 'normal');
|
|
#+end_src
|
|
|
|
#+name: fig:flexor_ID16_compare_bushing_joint_optimized
|
|
#+caption: Comparison of the Joint compliance between the FEM model and the simpler model
|
|
#+RESULTS:
|
|
[[file:figs/flexor_ID16_compare_bushing_joint_optimized.png]]
|
|
|
|
** Comparison with a stiffer Flexible Joint
|
|
The stiffness matrix with the flexible joint with a "hinge" size of 0.50mm is loaded.
|
|
#+begin_src matlab
|
|
K_050 = readmatrix('flex050_mat_K.CSV');
|
|
#+end_src
|
|
|
|
Its parameters are compared with the Flexible Joint with a size of 0.25mm in the table below.
|
|
|
|
#+begin_src matlab :exports results :results value table replace :tangle no :post addhdr(*this*)
|
|
data2orgtable([1e-6*K(3,3), 1e-6*K(2,2), K(4,4), K(5,5), K(6,6) ; 1e-6*K_050(3,3), 1e-6*K_050(2,2), K_050(4,4), K_050(5,5), K_050(6,6)]', {'Axial Stiffness Dz [N/um]', 'Shear Stiffness [N/um]', 'Bending Stiffness Rx [Nm/rad]', 'Bending Stiffness Ry [Nm/rad]', 'Torsion Stiffness Rz [Nm/rad]'}, {'*Caracteristic*', '*0.25 mm*', '*0.50 mm*'}, ' %.1f ');
|
|
#+end_src
|
|
|
|
#+name: tab:comp_stiffnesses_flex_size
|
|
#+caption: Comparison of flexible joint stiffnesses for 0.25 and 0.5mm
|
|
#+attr_latex: :environment tabularx :width 0.7\linewidth :align lcc
|
|
#+attr_latex: :center t :booktabs t
|
|
#+RESULTS:
|
|
| *Caracteristic* | *0.25 mm* | *0.50 mm* |
|
|
|-------------------------------+-----------+-----------|
|
|
| Axial Stiffness Dz [N/um] | 94.0 | 124.7 |
|
|
| Shear Stiffness [N/um] | 12.7 | 25.8 |
|
|
| Bending Stiffness Rx [Nm/rad] | 4.8 | 26.0 |
|
|
| Bending Stiffness Ry [Nm/rad] | 4.8 | 26.0 |
|
|
| Torsion Stiffness Rz [Nm/rad] | 260.2 | 538.0 |
|
|
|
|
* Complete Strut with Encoder
|
|
:PROPERTIES:
|
|
:header-args:matlab+: :tangle matlab/strut_encoder.m
|
|
:END:
|
|
<<sec:strut_encoder>>
|
|
** Introduction
|
|
|
|
Now, the full nano-hexapod strut is modelled using Ansys.
|
|
|
|
The 3D as well as the interface nodes are shown in Figure [[fig:strut_encoder_points3]].
|
|
|
|
#+name: fig:strut_encoder_points3
|
|
#+caption: Interface points
|
|
#+attr_latex: :width 1.0\linewidth
|
|
[[file:figs/strut_fem_nodes.jpg]]
|
|
|
|
A side view is shown in Figure [[fig:strut_encoder_nodes_side]].
|
|
|
|
#+name: fig:strut_encoder_nodes_side
|
|
#+caption: Interface points - Side view
|
|
#+attr_latex: :width 1.0\linewidth
|
|
[[file:figs/strut_fem_nodes_side.jpg]]
|
|
|
|
The flexible joints used have a 0.25mm width size.
|
|
|
|
** 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
|
|
addpath('matlab/');
|
|
addpath('matlab/strut_encoder/');
|
|
#+end_src
|
|
|
|
#+begin_src matlab :eval no
|
|
addpath('strut_encoder/');
|
|
#+end_src
|
|
|
|
#+begin_src matlab
|
|
open('strut_encoder.slx');
|
|
#+end_src
|
|
|
|
** Import Mass Matrix, Stiffness Matrix, and Interface Nodes Coordinates
|
|
We first extract the stiffness and mass matrices.
|
|
#+begin_src matlab
|
|
K = readmatrix('strut_encoder_mat_K.CSV');
|
|
M = readmatrix('strut_encoder_mat_M.CSV');
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports results :results value table replace :tangle no
|
|
data2orgtable(K(1:10, 1:10), {}, {}, ' %.1g ');
|
|
#+end_src
|
|
|
|
#+name: tab:strut_mat_K
|
|
#+caption: First 10x10 elements of the Stiffness matrix
|
|
#+attr_latex: :environment tabularx :width \linewidth :align XXXXXXXXXX
|
|
#+attr_latex: :center t :booktabs t :font \tiny
|
|
#+RESULTS:
|
|
| 2000000 | 1000000 | -3000000 | -400 | 300 | 200 | -30 | 2000 | -10000 | 0.3 |
|
|
| 1000000 | 4000000 | -8000000 | -900 | 400 | -50 | -6000 | 10000 | -20000 | 3 |
|
|
| -3000000 | -8000000 | 20000000 | 2000 | -900 | 200 | -10000 | 20000 | -300000 | 7 |
|
|
| -400 | -900 | 2000 | 5 | -0.1 | 05 | 1 | -3 | 6 | -0007 |
|
|
| 300 | 400 | -900 | -0.1 | 5 | 04 | -0.1 | 0.5 | -3 | 0001 |
|
|
| 200 | -50 | 200 | 05 | 04 | 300 | 4 | -01 | -1 | 3e-05 |
|
|
| -30 | -6000 | -10000 | 1 | -0.1 | 4 | 3000000 | -1000000 | -2000000 | -300 |
|
|
| 2000 | 10000 | 20000 | -3 | 0.5 | -01 | -1000000 | 6000000 | 7000000 | 1000 |
|
|
| -10000 | -20000 | -300000 | 6 | -3 | -1 | -2000000 | 7000000 | 20000000 | 2000 |
|
|
| 0.3 | 3 | 7 | -0007 | 0001 | 3e-05 | -300 | 1000 | 2000 | 5 |
|
|
|
|
|
|
#+begin_src matlab :exports results :results value table replace :tangle no
|
|
data2orgtable(M(1:10, 1:10), {}, {}, ' %.1g ');
|
|
#+end_src
|
|
|
|
#+name: tab:strut_mat_M
|
|
#+caption: First 10x10 elements of the Mass matrix
|
|
#+attr_latex: :environment tabularx :width \linewidth :align XXXXXXXXXX
|
|
#+attr_latex: :center t :booktabs t :font \tiny
|
|
#+RESULTS:
|
|
| 0.04 | -0.005 | 0.007 | 2e-06 | 0.0001 | -5e-07 | -1e-05 | -9e-07 | 8e-05 | -5e-10 |
|
|
| -0.005 | 0.03 | 0.02 | -0.0001 | 1e-06 | -3e-07 | 3e-05 | -0.0001 | 8e-05 | -3e-08 |
|
|
| 0.007 | 0.02 | 0.08 | -6e-06 | -5e-06 | -7e-07 | 4e-05 | -0.0001 | 0.0005 | -3e-08 |
|
|
| 2e-06 | -0.0001 | -6e-06 | 2e-06 | -4e-10 | 2e-11 | -8e-09 | 3e-08 | -2e-08 | 6e-12 |
|
|
| 0.0001 | 1e-06 | -5e-06 | -4e-10 | 3e-06 | 2e-10 | -3e-09 | 3e-09 | -7e-09 | 6e-13 |
|
|
| -5e-07 | -3e-07 | -7e-07 | 2e-11 | 2e-10 | 5e-07 | -2e-08 | 5e-09 | -5e-09 | 1e-12 |
|
|
| -1e-05 | 3e-05 | 4e-05 | -8e-09 | -3e-09 | -2e-08 | 0.04 | 0.004 | 0.003 | 1e-06 |
|
|
| -9e-07 | -0.0001 | -0.0001 | 3e-08 | 3e-09 | 5e-09 | 0.004 | 0.02 | -0.02 | 0.0001 |
|
|
| 8e-05 | 8e-05 | 0.0005 | -2e-08 | -7e-09 | -5e-09 | 0.003 | -0.02 | 0.08 | -5e-06 |
|
|
| -5e-10 | -3e-08 | -3e-08 | 6e-12 | 6e-13 | 1e-12 | 1e-06 | 0.0001 | -5e-06 | 2e-06 |
|
|
|
|
|
|
Then, we extract the coordinates of the interface nodes.
|
|
#+begin_src matlab
|
|
[int_xyz, int_i, n_xyz, n_i, nodes] = extractNodes('strut_encoder_out_nodes_3D.txt');
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports results :results value table replace :tangle no
|
|
data2orgtable([length(n_i); length(int_i); size(M,1) - 6*length(int_i); size(M,1)], {'Total number of Nodes', 'Number of interface Nodes', 'Number of Modes', 'Size of M and K matrices'}, {}, ' %.0f ');
|
|
#+end_src
|
|
|
|
#+name: tab:parameters_fem_strut
|
|
#+caption: Some extracted parameters of the FEM
|
|
#+attr_latex: :environment tabularx :width 0.4\linewidth :align lc
|
|
#+attr_latex: :center t :booktabs t
|
|
#+RESULTS:
|
|
| Total number of Nodes | 8 |
|
|
| Number of interface Nodes | 8 |
|
|
| Number of Modes | 6 |
|
|
| Size of M and K matrices | 54 |
|
|
|
|
#+begin_src matlab :exports results :results value table replace :tangle no :post addhdr(*this*)
|
|
data2orgtable([[1:length(int_i)]', int_i, int_xyz], {}, {'Node i', 'Node Number', 'x [m]', 'y [m]', 'z [m]'}, ' %f ');
|
|
#+end_src
|
|
|
|
#+name: tab:coordinate_nodes_strut
|
|
#+caption: Coordinates of the interface nodes
|
|
#+attr_latex: :environment tabularx :width 0.6\linewidth :align ccccc
|
|
#+attr_latex: :center t :booktabs t
|
|
#+RESULTS:
|
|
| Node i | Node Number | x [m] | y [m] | z [m] |
|
|
|--------+-------------+---------+--------+----------|
|
|
| 1.0 | 504411.0 | 0.0 | 0.0 | 0.0405 |
|
|
| 2.0 | 504412.0 | 0.0 | 0.0 | -0.0405 |
|
|
| 3.0 | 504413.0 | -0.0325 | 0.0 | 0.0 |
|
|
| 4.0 | 504414.0 | -0.0125 | 0.0 | 0.0 |
|
|
| 5.0 | 504415.0 | -0.0075 | 0.0 | 0.0 |
|
|
| 6.0 | 504416.0 | 0.0325 | 0.0 | 0.0 |
|
|
| 7.0 | 504417.0 | 0.004 | 0.0145 | -0.00175 |
|
|
| 8.0 | 504418.0 | 0.004 | 0.0166 | -0.00175 |
|
|
|
|
Using =K=, =M= and =int_xyz=, we can use the =Reduced Order Flexible Solid= simscape block.
|
|
|
|
** Piezoelectric parameters
|
|
Parameters for the APA300ML:
|
|
|
|
#+begin_src matlab
|
|
d33 = 300e-12; % Strain constant [m/V]
|
|
n = 80; % Number of layers per stack
|
|
eT = 1.6e-8; % Permittivity under constant stress [F/m]
|
|
sD = 1e-11; % Compliance under constant electric displacement [m2/N]
|
|
ka = 235e6; % Stack stiffness [N/m]
|
|
C = 5e-6; % Stack capactiance [F]
|
|
#+end_src
|
|
|
|
#+begin_src matlab
|
|
na = 2; % Number of stacks used as actuator
|
|
ns = 1; % Number of stacks used as force sensor
|
|
#+end_src
|
|
|
|
** Identification of the Dynamics
|
|
#+begin_src matlab :exports none
|
|
m = 0.01;
|
|
#+end_src
|
|
|
|
The dynamics is identified from the applied force to the measured relative displacement.
|
|
#+begin_src matlab :exports none
|
|
%% Name of the Simulink File
|
|
mdl = 'strut_encoder';
|
|
|
|
%% Input/Output definition
|
|
clear io; io_i = 1;
|
|
io(io_i) = linio([mdl, '/Fa'], 1, 'openinput'); io_i = io_i + 1;
|
|
io(io_i) = linio([mdl, '/L'], 1, 'openoutput'); io_i = io_i + 1;
|
|
|
|
Gh = -linearize(mdl, io);
|
|
#+end_src
|
|
|
|
The same dynamics is identified for a payload mass of 10Kg.
|
|
#+begin_src matlab
|
|
m = 10;
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none
|
|
Ghm = -linearize(mdl, io);
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none
|
|
freqs = logspace(0, 4, 5000);
|
|
|
|
figure;
|
|
tiledlayout(3, 1, 'TileSpacing', 'None', 'Padding', 'None');
|
|
|
|
ax1 = nexttile([2,1]);
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(Gh, freqs, 'Hz'))), '-');
|
|
plot(freqs, abs(squeeze(freqresp(Ghm, freqs, 'Hz'))), '-');
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
ylabel('Amplitude'); set(gca, 'XTickLabel',[]);
|
|
axis padded 'auto x'
|
|
hold off;
|
|
|
|
ax2 = nexttile;
|
|
hold on;
|
|
plot(freqs, 180/pi*angle(squeeze(freqresp(Gh, freqs, 'Hz'))), '-', ...
|
|
'DisplayName', '$m = 0kg$');
|
|
plot(freqs, 180/pi*angle(squeeze(freqresp(Ghm, freqs, 'Hz'))), '-', ...
|
|
'DisplayName', '$m = 10kg$');
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
|
|
yticks(-360:90:360);
|
|
ylim([-180 180]);
|
|
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
|
|
hold off;
|
|
axis padded 'auto x'
|
|
#+end_src
|
|
|
|
#+begin_src matlab :tangle no :exports results :results file replace
|
|
exportFig('figs/dynamics_encoder_full_strut.pdf', 'width', 'wide', 'height', 'tall');
|
|
#+end_src
|
|
|
|
#+name: fig:dynamics_encoder_full_strut
|
|
#+caption: Dynamics from the force actuator to the measured motion by the encoder
|
|
#+RESULTS:
|
|
[[file:figs/dynamics_encoder_full_strut.png]]
|
|
|
|
* To Order :noexport:
|
|
:PROPERTIES:
|
|
:header-args:matlab+: :tangle no
|
|
:END:
|
|
** TODO Identification of the stiffness properties of the APA300ML
|
|
*** APA Alone
|
|
#+begin_src matlab :exports none
|
|
m = 10;
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none
|
|
%% Name of the Simulink File
|
|
mdl = 'APA300ML_characterisation';
|
|
|
|
%% Input/Output definition
|
|
clear io; io_i = 1;
|
|
io(io_i) = linio([mdl, '/Fd'], 1, 'openinput'); io_i = io_i + 1; % External Vertical Force [N]
|
|
io(io_i) = linio([mdl, '/D'], 1, 'openoutput'); io_i = io_i + 1; % Displacement/Rotation [m]
|
|
|
|
G = linearize(mdl, io);
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports results :results value table replace :tangle no :post addhdr(*this*)
|
|
data2orgtable([1e-6./dcgain(G(1,1)), 1e-6./dcgain(G(2,2)), 1e-6./dcgain(G(3,3)), 1./dcgain(G(4,4)), 1./dcgain(G(5,5)), 1./dcgain(G(6,6))]', {'Kx [N/um]', 'Ky [N/um]', 'Kz [N/um]', 'Rx [Nm/rad]', 'Ry [Nm/rad]', 'Rz [Nm/rad]'}, {'*Caracteristics*', '*Value*'}, ' %.1f ');
|
|
#+end_src
|
|
|
|
#+RESULTS:
|
|
| *Caracteristics* | *Value* |
|
|
|------------------+---------|
|
|
| Kx [N/um] | 0.8 |
|
|
| Ky [N/um] | 1.6 |
|
|
| Kz [N/um] | 1.8 |
|
|
| Rx [Nm/rad] | 71.4 |
|
|
| Ry [Nm/rad] | 148.2 |
|
|
| Rz [Nm/rad] | 4241.8 |
|
|
|
|
*** See how the global stiffness is changing with the flexible joints
|
|
#+begin_src matlab
|
|
flex = load('./mat/flexor_ID16.mat', 'int_xyz', 'int_i', 'n_xyz', 'n_i', 'nodes', 'M', 'K');
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none
|
|
%% Name of the Simulink File
|
|
mdl = 'APA300ML_characterisation_with_joints';
|
|
|
|
%% Input/Output definition
|
|
clear io; io_i = 1;
|
|
io(io_i) = linio([mdl, '/Fd'], 1, 'openinput'); io_i = io_i + 1; % External Vertical Force [N]
|
|
io(io_i) = linio([mdl, '/D'], 1, 'openoutput'); io_i = io_i + 1; % Displacement/Rotation [m]
|
|
|
|
Gf = linearize(mdl, io);
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports results :results value table replace :tangle no :post addhdr(*this*)
|
|
data2orgtable([1e-6./dcgain(Gf(1,1)), 1e-6./dcgain(Gf(2,2)), 1e-6./dcgain(Gf(3,3)), 1./dcgain(Gf(4,4)), 1./dcgain(Gf(5,5)), 1./dcgain(Gf(6,6))]', {'Kx [N/um]', 'Ky [N/um]', 'Kz [N/um]', 'Rx [Nm/rad]', 'Ry [Nm/rad]', 'Rz [Nm/rad]'}, {'*Caracteristic*', '*Value*'}, ' %.1f ');
|
|
#+end_src
|
|
|
|
#+RESULTS:
|
|
| *Caracteristic* | *Value* |
|
|
|-----------------+---------|
|
|
| Kx [N/um] | 0.0 |
|
|
| Ky [N/um] | 0.0 |
|
|
| Kz [N/um] | 1.8 |
|
|
| Rx [Nm/rad] | 722.9 |
|
|
| Ry [Nm/rad] | 129.6 |
|
|
| Rz [Nm/rad] | 115.3 |
|
|
|
|
|
|
#+begin_src matlab
|
|
freqs = logspace(-2, 5, 1000);
|
|
|
|
figure;
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G(2,2), freqs, 'Hz'))), '-', 'DisplayName', 'APA');
|
|
plot(freqs, abs(squeeze(freqresp(Gf(2,2), freqs, 'Hz'))), '-', 'DisplayName', 'Flex');
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
xlabel('Frequency [Hz]'); ylabel('Amplitude [m/N]');
|
|
hold off;
|
|
legend('location', 'northeast');
|
|
#+end_src
|
|
|
|
#+begin_src matlab
|
|
freqs = logspace(-2, 5, 1000);
|
|
|
|
figure;
|
|
hold on;
|
|
plot(freqs, abs(squeeze(freqresp(G(3,3), freqs, 'Hz'))), '-', 'DisplayName', 'APA');
|
|
plot(freqs, abs(squeeze(freqresp(Gf(3,3), freqs, 'Hz'))), '-', 'DisplayName', 'Flex');
|
|
hold off;
|
|
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
|
|
xlabel('Frequency [Hz]'); ylabel('Amplitude [m/N]');
|
|
hold off;
|
|
legend('location', 'northeast');
|
|
#+end_src
|
|
|
|
** TODO Effect of APA300ML in the flexibility of the leg
|
|
#+begin_src matlab :exports none
|
|
m = 10;
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none
|
|
%% Name of the Simulink File
|
|
mdl = 'APA300ML_flex_joints';
|
|
|
|
%% Input/Output definition
|
|
clear io; io_i = 1;
|
|
io(io_i) = linio([mdl, '/Fd'], 1, 'openinput'); io_i = io_i + 1; % External Vertical Force [N]
|
|
io(io_i) = linio([mdl, '/D'], 1, 'openoutput'); io_i = io_i + 1; % Displacement/Rotation [m]
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none
|
|
G = linearize(mdl, io);
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none
|
|
Gf = linearize(mdl, io);
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports results :results value table replace :tangle no :post addhdr(*this*)
|
|
data2orgtable([[1e-6./dcgain(G(1,1)), 1e-6./dcgain(G(2,2)), 1e-6./dcgain(G(3,3)), 1./dcgain(G(4,4)), 1./dcgain(G(5,5)), 1./dcgain(G(6,6))]', [1e-6./dcgain(Gf(1,1)), 1e-6./dcgain(Gf(2,2)), 1e-6./dcgain(Gf(3,3)), 1./dcgain(Gf(4,4)), 1./dcgain(Gf(5,5)), 1./dcgain(Gf(6,6))]'], {'Kx [N/um]', 'Ky [N/um]', 'Kz [N/um]', 'Rx [Nm/rad]', 'Ry [Nm/rad]', 'Rz [Nm/rad]'}, {'*Caracteristic*', '*Rigid APA*', '*Flexible APA*'}, ' %.3f ');
|
|
#+end_src
|
|
|
|
|
|
#+RESULTS:
|
|
| *Caracteristic* | *Rigid APA* | *Flexible APA* |
|
|
|-----------------+-------------+----------------|
|
|
| Kx [N/um] | 0.018 | 0.019 |
|
|
| Ky [N/um] | 0.018 | 0.018 |
|
|
| Kz [N/um] | 60.0 | 2.647 |
|
|
| Rx [Nm/rad] | 16.705 | 557.682 |
|
|
| Ry [Nm/rad] | 16.535 | 185.939 |
|
|
| Rz [Nm/rad] | 118.0 | 114.803 |
|
|
|
|
* Bibliography :ignore:
|
|
#+latex: \printbibliography[heading=bibintoc,title={Bibliography}]
|