nass-simscape/docs/nano_hexapod.html

2788 lines
123 KiB
HTML

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<!-- 2021-05-06 jeu. 18:10 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>Nano-Hexapod</title>
<meta name="author" content="Dehaeze Thomas" />
<meta name="generator" content="Org Mode" />
<link rel="stylesheet" type="text/css" href="https://research.tdehaeze.xyz/css/style.css"/>
<script type="text/javascript" src="https://research.tdehaeze.xyz/js/script.js"></script>
<script>
MathJax = {
svg: {
scale: 1,
fontCache: "global"
},
tex: {
tags: "ams",
multlineWidth: "%MULTLINEWIDTH",
tagSide: "right",
macros: {bm: ["\\boldsymbol{#1}",1],},
tagIndent: ".8em"
}
};
</script>
<script id="MathJax-script" async
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"></script>
</head>
<body>
<div id="org-div-home-and-up">
<a accesskey="h" href="./index.html"> UP </a>
|
<a accesskey="H" href="../../index.html"> HOME </a>
</div><div id="content">
<h1 class="title">Nano-Hexapod</h1>
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#org3cc44d5">1. Nano-Hexapod</a>
<ul>
<li><a href="#org17a9502">1.1. Nano Hexapod - Configuration</a>
<ul>
<li><a href="#orgd406621">1.1.1. Flexible Joints</a></li>
<li><a href="#org38f71cc">1.1.2. Amplified Piezoelectric Actuators</a></li>
<li><a href="#orgad18643">1.1.3. Encoders</a></li>
<li><a href="#org37ecf7a">1.1.4. Jacobians</a></li>
</ul>
</li>
<li><a href="#orgf279891">1.2. Effect of encoders on the decentralized plant</a></li>
<li><a href="#orgbea8fbc">1.3. Effect of APA flexibility</a></li>
<li><a href="#orgb2e1d3b">1.4. Nano Hexapod - Number of DoF</a></li>
<li><a href="#orgcd30976">1.5. Direct Velocity Feedback Plant</a></li>
<li><a href="#orgdefb22f">1.6. Integral Force Feedback Plant</a></li>
<li><a href="#orgde9c23b">1.7. Decentralized Plant - Cartesian coordinates</a>
<ul>
<li><a href="#org435b7fd">1.7.1. Verification of the Sensor Jacobian</a></li>
<li><a href="#org664eab9">1.7.2. Comparison of the decentralized plants</a></li>
<li><a href="#orged8dc85">1.7.3. Perfect axial stiffness of the joints</a></li>
<li><a href="#orga4e05f4">1.7.4. Frequency of the zeros</a></li>
</ul>
</li>
<li><a href="#org6cf8089">1.8. Decentralized Plant - Decoupling at the Center of Stiffness</a>
<ul>
<li><a href="#org8c0186d">1.8.1. Center of Stiffness</a></li>
<li><a href="#org58e2a5b">1.8.2. Obtained plant</a></li>
</ul>
</li>
<li><a href="#orgd60e2b2">1.9. Stiffness matrix</a>
<ul>
<li><a href="#org97c57ea">1.9.1. Compute the theoretical stiffness of the nano-hexapod</a></li>
<li><a href="#orgc388f2b">1.9.2. Comparison with Simscape Model</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#org2fc54dd">2. Active Damping using Integral Force Feedback</a>
<ul>
<li><a href="#org9b12068">2.1. Plant Identification</a></li>
<li><a href="#org174c317">2.2. Root Locus</a></li>
<li><a href="#org78de4b8">2.3. Effect of IFF on the plant</a></li>
<li><a href="#org8db31cb">2.4. Effect of IFF on the compliance</a></li>
</ul>
</li>
<li><a href="#org605df2e">3. Active Damping using Direct Velocity Feedback - Encoders on the struts</a>
<ul>
<li><a href="#org2776d31">3.1. Plant Identification</a></li>
<li><a href="#org452cf4e">3.2. Root Locus</a></li>
<li><a href="#org059c247">3.3. Effect of DVF on the plant</a></li>
<li><a href="#org1627645">3.4. Effect of DVF on the compliance</a></li>
</ul>
</li>
<li><a href="#orgac5a0fc">4. Active Damping using Direct Velocity Feedback - Encoders on the plates</a>
<ul>
<li><a href="#org8a655d0">4.1. Plant Identification</a></li>
<li><a href="#orgb09a05b">4.2. Root Locus</a></li>
<li><a href="#orgc0b7c71">4.3. Effect of DVF on the plant</a></li>
<li><a href="#org221db88">4.4. Effect of DVF on the compliance</a></li>
</ul>
</li>
<li><a href="#org8862f6b">5. Function - Initialize Nano Hexapod</a>
<ul>
<li><a href="#org438f7d8">Function description</a></li>
<li><a href="#org49bef56">Optional Parameters</a></li>
<li><a href="#org33f6631">Nano Hexapod Object</a></li>
<li><a href="#orgdc3de74">Flexible Joints - Bot</a></li>
<li><a href="#org7d4d003">Flexible Joints - Top</a></li>
<li><a href="#org3744992">Relative Motion Sensor</a></li>
<li><a href="#orgdaa740a">Amplified Piezoelectric Actuator</a></li>
<li><a href="#org8d598c9">Geometry</a></li>
<li><a href="#org8d741d2">Jacobian for Actuators</a></li>
<li><a href="#orgea27820">Jacobian for Sensors</a></li>
<li><a href="#org90b9ac2">Controller</a></li>
<li><a href="#org8187b3b">Save the Structure</a></li>
</ul>
</li>
</ul>
</div>
</div>
<hr>
<p>This report is also available as a <a href="./nano_hexapod.pdf">pdf</a>.</p>
<hr>
<p>
In this document, a Simscape model of the nano-hexapod is developed and studied.
</p>
<p>
It is structured as follows:
</p>
<ul class="org-ul">
<li>Section <a href="#orge6be60c">1</a>: the simscape model of the nano-hexapod is presented. Few of its elements can be configured as wanted. The effect of the configuration on the obtained dynamics is studied.</li>
<li>Section <a href="#orge63ed81">2</a>: Direct Velocity Feedback is applied and the obtained damping is derived.</li>
<li>Section <a href="#orgdbb1c33">3</a>: the encoders are fixed to the struts, and Integral Force Feedback is applied. The obtained damping is computed.</li>
<li>Section <a href="#org19f552a">4</a>: the same is done when the encoders are fixed on the plates</li>
</ul>
<div id="outline-container-org3cc44d5" class="outline-2">
<h2 id="org3cc44d5"><span class="section-number-2">1</span> Nano-Hexapod</h2>
<div class="outline-text-2" id="text-1">
<p>
<a id="orge6be60c"></a>
</p>
</div>
<div id="outline-container-org17a9502" class="outline-3">
<h3 id="org17a9502"><span class="section-number-3">1.1</span> Nano Hexapod - Configuration</h3>
<div class="outline-text-3" id="text-1-1">
<p>
<a id="org31671ff"></a>
</p>
<p>
The nano-hexapod can be initialized and configured using the <code>initializeNanoHexapodFinal</code> function (<a href="#orga13249f">link</a>).
</p>
<p>
The following code would produce the model shown in Figure <a href="#orgf7ac248">1</a>.
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'3dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'struts'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>, ...
<span class="org-string">'MO_B'</span>, 150e<span class="org-type">-</span>3);
</pre>
</div>
<div id="orgf7ac248" class="figure">
<p><img src="figs/nano_hexapod_simscape_encoder_struts.png" alt="nano_hexapod_simscape_encoder_struts.png" />
</p>
<p><span class="figure-number">Figure 1: </span>3D view of the Sismcape model for the Nano-Hexapod</p>
</div>
<p>
Several elements on the nano-hexapod can be configured:
</p>
<ul class="org-ul">
<li>The flexible joints (Section <a href="#orgf2036e7">1.1.1</a>)</li>
<li>The amplified piezoelectric actuators (Section <a href="#orgec78e6b">1.1.2</a>)</li>
<li>The encoders (Section <a href="#org53c6b1c">1.1.3</a>)</li>
<li>The Jacobian matrices (Section <a href="#org435c1ab">1.1.4</a>)</li>
</ul>
</div>
<div id="outline-container-orgd406621" class="outline-4">
<h4 id="orgd406621"><span class="section-number-4">1.1.1</span> Flexible Joints</h4>
<div class="outline-text-4" id="text-1-1-1">
<p>
<a id="orgf2036e7"></a>
</p>
<p>
The model of the flexible joint is composed of 3 solid bodies as shown in Figure <a href="#org6751c1a">2</a> which are connected by joints representing the flexibility of the joint.
</p>
<p>
We can represent:
</p>
<ul class="org-ul">
<li>the bending flexibility \(k_{R_x}\), \(k_{R_y}\)</li>
<li>the torsional flexibility \(k_{R_z}\)</li>
<li>the axial flexibility \(k_z\)</li>
</ul>
<p>
The configurations and the represented flexibilities are summarized in Table <a href="#org0aecd94">1</a>.
</p>
<table id="org0aecd94" border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<caption class="t-above"><span class="table-number">Table 1:</span> Flexible joint&rsquo;s configuration and associated represented flexibility</caption>
<colgroup>
<col class="org-left" />
<col class="org-left" />
<col class="org-left" />
<col class="org-left" />
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left"><code>flex_type</code></th>
<th scope="col" class="org-left">Bending</th>
<th scope="col" class="org-left">Torsional</th>
<th scope="col" class="org-left">Axial</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left"><code>2dof</code></td>
<td class="org-left">x</td>
<td class="org-left">&#xa0;</td>
<td class="org-left">&#xa0;</td>
</tr>
<tr>
<td class="org-left"><code>3dof</code></td>
<td class="org-left">x</td>
<td class="org-left">x</td>
<td class="org-left">&#xa0;</td>
</tr>
<tr>
<td class="org-left"><code>4dof</code></td>
<td class="org-left">x</td>
<td class="org-left">x</td>
<td class="org-left">x</td>
</tr>
</tbody>
</table>
<p>
Of course, adding more DoF for the flexible joint will induce an addition of many states for the nano-hexapod simscape model.
</p>
<div id="org6751c1a" class="figure">
<p><img src="figs/simscape_model_flexible_joint.png" alt="simscape_model_flexible_joint.png" />
</p>
<p><span class="figure-number">Figure 2: </span>3D view of the Sismcape model for the Flexible joint (4DoF configuration)</p>
</div>
</div>
</div>
<div id="outline-container-org38f71cc" class="outline-4">
<h4 id="org38f71cc"><span class="section-number-4">1.1.2</span> Amplified Piezoelectric Actuators</h4>
<div class="outline-text-4" id="text-1-1-2">
<p>
<a id="orgec78e6b"></a>
</p>
<p>
The nano-hexapod&rsquo;s struts are containing one amplified piezoelectric actuator (APA300ML from Cedrat Technologies).
</p>
<p>
The APA can be modeled in different ways which can be configured with the <code>actuator_type</code> argument.
</p>
<p>
The simplest model is a 2-DoF system shown in Figure <a href="#orgc656438">3</a>.
</p>
<div id="orgc656438" class="figure">
<p><img src="figs/2dof_apa_model.png" alt="2dof_apa_model.png" />
</p>
<p><span class="figure-number">Figure 3: </span>Schematic of the 2DoF model for the Amplified Piezoelectric Actuator</p>
</div>
<p>
Then, a more complex model based on a Finite Element Model can be used.
</p>
</div>
</div>
<div id="outline-container-orgad18643" class="outline-4">
<h4 id="orgad18643"><span class="section-number-4">1.1.3</span> Encoders</h4>
<div class="outline-text-4" id="text-1-1-3">
<p>
<a id="org53c6b1c"></a>
</p>
<p>
The encoders can be either fixed directly on the struts (Figure <a href="#orgb0013b0">4</a>) or on the two plates (Figure <a href="#orgf95b7ad">5</a>).
</p>
<p>
This can be configured with the <code>motion_sensor_type</code> parameters which can be equal to <code>'struts'</code> or <code>'plates'</code>.
</p>
<div id="orgb0013b0" class="figure">
<p><img src="figs/encoder_struts.png" alt="encoder_struts.png" />
</p>
<p><span class="figure-number">Figure 4: </span>3D view of the Encoders fixed on the struts</p>
</div>
<div id="orgf95b7ad" class="figure">
<p><img src="figs/encoders_plates_with_apa.png" alt="encoders_plates_with_apa.png" />
</p>
<p><span class="figure-number">Figure 5: </span>3D view of the Encoders fixed on the plates</p>
</div>
<p>
A complete view of the nano-hexapod with encoders fixed to the struts is shown in Figure <a href="#orgf7ac248">1</a> while it is shown in Figure <a href="#orga9ba62b">6</a> when the encoders are fixed to the plates.
</p>
<div id="orga9ba62b" class="figure">
<p><img src="figs/nano_hexapod_simscape_encoder_plates.png" alt="nano_hexapod_simscape_encoder_plates.png" />
</p>
<p><span class="figure-number">Figure 6: </span>Nano-Hexapod with encoders fixed to the plates</p>
</div>
<p>
The encoder model is schematically represented in Figure <a href="#orgca7e9a4">7</a>:
</p>
<ul class="org-ul">
<li>a frame {B}, fixed to the ruler is positioned on its top surface</li>
<li>a frame {F}, rigidly fixed to the encoder is initially positioned such that its origin is aligned with the x axis of frame {B}</li>
</ul>
<p>
The output measurement is then the x displacement of the origin of the frame {F} expressed in frame {B}.
</p>
<div id="orgca7e9a4" class="figure">
<p><img src="figs/simscape_encoder_model.png" alt="simscape_encoder_model.png" />
</p>
<p><span class="figure-number">Figure 7: </span>Schematic of the encoder model</p>
</div>
<p>
If the encoder is experiencing some tilt, it is then &ldquo;converted&rdquo; into a measured displacement as shown in Figure <a href="#org460734a">8</a>.
</p>
<div id="org460734a" class="figure">
<p><img src="figs/simscape_encoder_model_disp.png" alt="simscape_encoder_model_disp.png" />
</p>
<p><span class="figure-number">Figure 8: </span>Schematic of the encoder model</p>
</div>
</div>
</div>
<div id="outline-container-org37ecf7a" class="outline-4">
<h4 id="org37ecf7a"><span class="section-number-4">1.1.4</span> Jacobians</h4>
<div class="outline-text-4" id="text-1-1-4">
<p>
<a id="org435c1ab"></a>
</p>
<p>
While the Jacobian configuration will not change the physical system, it is still quite an important part of the model.
</p>
<p>
This configuration consists on defining the location of the frame {B} in which the Jacobian will be computed.
This Jacobian is then used to transform the actuator forces to forces/torques applied on the payload and expressed in frame {B}.
Same thing can be done for the measured encoder displacements.
</p>
</div>
</div>
</div>
<div id="outline-container-orgf279891" class="outline-3">
<h3 id="orgf279891"><span class="section-number-3">1.2</span> Effect of encoders on the decentralized plant</h3>
<div class="outline-text-3" id="text-1-2">
<p>
<a id="org5a34350"></a>
</p>
<p>
We here wish to compare the plant from actuators to the encoders when the encoders are either fixed on the struts or on the plates.
</p>
<p>
We initialize the identification parameters.
</p>
<div class="org-src-container">
<pre class="src src-matlab"><span class="org-matlab-cellbreak"><span class="org-comment">%% Input/Output definition</span></span>
clear io; io_i = 1;
io(io_i) = linio([mdl, <span class="org-string">'/F'</span>], 1, <span class="org-string">'openinput'</span>); io_i = io_i <span class="org-type">+</span> 1; <span class="org-comment">% Actuator Inputs</span>
io(io_i) = linio([mdl, <span class="org-string">'/D'</span>], 1, <span class="org-string">'openoutput'</span>); io_i = io_i <span class="org-type">+</span> 1; <span class="org-comment">% Relative Motion Outputs</span>
</pre>
</div>
<p>
Identify the plant when the encoders are on the struts:
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'struts'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>);
Gs = linearize(mdl, io, 0.0, options);
Gs.InputName = {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>};
Gs.OutputName = {<span class="org-string">'D1'</span>, <span class="org-string">'D2'</span>, <span class="org-string">'D3'</span>, <span class="org-string">'D4'</span>, <span class="org-string">'D5'</span>, <span class="org-string">'D6'</span>};
</pre>
</div>
<p>
And identify the plant when the encoders are fixed on the plates:
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'plates'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>);
Gp = linearize(mdl, io, 0.0, options);
Gp.InputName = {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>};
Gp.OutputName = {<span class="org-string">'D1'</span>, <span class="org-string">'D2'</span>, <span class="org-string">'D3'</span>, <span class="org-string">'D4'</span>, <span class="org-string">'D5'</span>, <span class="org-string">'D6'</span>};
</pre>
</div>
<p>
The obtained plants are compared in Figure <a href="#orgdc23a85">9</a>.
</p>
<div id="orgdc23a85" class="figure">
<p><img src="figs/nano_hexapod_effect_encoder.png" alt="nano_hexapod_effect_encoder.png" />
</p>
<p><span class="figure-number">Figure 9: </span>Comparison of the plants from actuator to associated encoder when the encoders are either fixed to the struts or to the plates</p>
</div>
<div class="important" id="org18add26">
<p>
The zeros at 280Hz should corresponds to resonances of the system when one of the APA is blocked.
It is linked to the axial stiffness of the flexible joints: increasing the axial stiffness of the joints will increase the frequency of the zeros.
This will be verified in
</p>
</div>
</div>
</div>
<div id="outline-container-orgbea8fbc" class="outline-3">
<h3 id="orgbea8fbc"><span class="section-number-3">1.3</span> Effect of APA flexibility</h3>
<div class="outline-text-3" id="text-1-3">
<p>
<a id="org7ba60ef"></a>
</p>
<p>
First identify the plant for APA represented by 2DoF system:
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'3dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'struts'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>, ...
<span class="org-string">'actuator_Ga'</span>, 2);
Gs = linearize(mdl, io, 0.0, options);
Gs.InputName = {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>};
Gs.OutputName = {<span class="org-string">'D1'</span>, <span class="org-string">'D2'</span>, <span class="org-string">'D3'</span>, <span class="org-string">'D4'</span>, <span class="org-string">'D5'</span>, <span class="org-string">'D6'</span>};
</pre>
</div>
<p>
First identify the plant for APA represented by a flexible element:
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'3dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'struts'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'flexible'</span>);
Gf = linearize(mdl, io, 0.0, options);
Gf.InputName = {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>};
Gf.OutputName = {<span class="org-string">'D1'</span>, <span class="org-string">'D2'</span>, <span class="org-string">'D3'</span>, <span class="org-string">'D4'</span>, <span class="org-string">'D5'</span>, <span class="org-string">'D6'</span>};
</pre>
</div>
<div id="orgc16cea4" class="figure">
<p><img src="figs/nano_hexapod_effect_flexible_apa.png" alt="nano_hexapod_effect_flexible_apa.png" />
</p>
<p><span class="figure-number">Figure 10: </span>Comparison of the plants from actuator to associated strut encoder when the APA are modelled with a 2DoF system of with a flexible one</p>
</div>
<div class="question" id="orgea1d25a">
<p>
The first resonance is strange when using the flexible APA model (Figure <a href="#orgc16cea4">10</a>).
Moreover the system is unstable.
Otherwise, the 2DoF model matches quite well the flexible model considering its simplicity.
</p>
</div>
</div>
</div>
<div id="outline-container-orgb2e1d3b" class="outline-3">
<h3 id="orgb2e1d3b"><span class="section-number-3">1.4</span> Nano Hexapod - Number of DoF</h3>
<div class="outline-text-3" id="text-1-4">
<p>
<a id="org7000a9b"></a>
</p>
<p>
In this section, we wish to see how the configuration of each element changes the number of the states of the obtained system.
</p>
<p>
The most minimalist model is the following:
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'3dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'2dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'struts'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>);
G = linearize(mdl, io, 0.0, options);
</pre>
</div>
<pre class="example">
There are 24 states.
</pre>
<p>
These states are summarized on table <a href="#org72f8200">2</a>.
</p>
<table id="org72f8200" border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<caption class="t-above"><span class="table-number">Table 2:</span> Number of states for the minimalist model</caption>
<colgroup>
<col class="org-left" />
<col class="org-right" />
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Element</th>
<th scope="col" class="org-right">States</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">Struts</td>
<td class="org-right">2*6</td>
</tr>
<tr>
<td class="org-left">Top Plate</td>
<td class="org-right">12</td>
</tr>
</tbody>
<tbody>
<tr>
<td class="org-left">Total:</td>
<td class="org-right">24</td>
</tr>
</tbody>
</table>
<p>
If we add axial stiffness on the top joints, we should add 2 states for each struts.
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'2dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'struts'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>);
G = linearize(mdl, io, 0.0, options);
</pre>
</div>
<pre class="example">
There are 36 states.
</pre>
<p>
If we add torsional stiffness on the bottom joints, we should again add 2 states for each struts.
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'3dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'struts'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>);
G = linearize(mdl, io, 0.0, options);
</pre>
</div>
<pre class="example">
There are 48 states.
</pre>
<p>
Finally, if we add axial stiffness on the bottom joint, we should add 2 states for each struts.
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'struts'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>);
G = linearize(mdl, io, 0.0, options);
</pre>
</div>
<pre class="example">
There are 60 states.
</pre>
<div class="important" id="org8b31f2f">
<p>
Obtained number of states is very comprehensible.
Depending on the physical effects we want to model, we therefore know how many states are added when configuring the model.
</p>
</div>
</div>
</div>
<div id="outline-container-orgcd30976" class="outline-3">
<h3 id="orgcd30976"><span class="section-number-3">1.5</span> Direct Velocity Feedback Plant</h3>
<div class="outline-text-3" id="text-1-5">
<p>
<a id="orgcd47ec8"></a>
</p>
<p>
The transfer function from actuator forces \(\tau_i\) to the encoder measurements \(\mathcal{L}_i\) is now identified both when the encoders are fixed to the struts.
</p>
<div class="org-src-container">
<pre class="src src-matlab"><span class="org-matlab-cellbreak"><span class="org-comment">%% Input/Output definition</span></span>
clear io; io_i = 1;
io(io_i) = linio([mdl, <span class="org-string">'/F'</span>], 1, <span class="org-string">'openinput'</span>); io_i = io_i <span class="org-type">+</span> 1; <span class="org-comment">% Actuator Inputs [N]</span>
io(io_i) = linio([mdl, <span class="org-string">'/D'</span>], 1, <span class="org-string">'openoutput'</span>); io_i = io_i <span class="org-type">+</span> 1; <span class="org-comment">% Relative displacements [m]</span>
n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'struts'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>);
Gdvf = linearize(mdl, io, 0.0, options);
</pre>
</div>
<p>
The DC gain from actuator to relative motion sensor should be equal to (for the 2dof APA):
\[ \frac{1}{k + k_a + kk_a/k_e} \]
</p>
<p>
Which is equal to:
</p>
<pre class="example">
DCgain = 1.87e-08 [m/N]
</pre>
<p>
Let&rsquo;s verify that by looking at the DC gain of the \(6 \times 6\) DVF plant in Table <a href="#org099b380">3</a>.
</p>
<table id="org099b380" border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<caption class="t-above"><span class="table-number">Table 3:</span> DC gain of the DVF plant</caption>
<colgroup>
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
</colgroup>
<tbody>
<tr>
<td class="org-right">1.8617e-08</td>
<td class="org-right">-1.0408e-10</td>
<td class="org-right">1.3034e-10</td>
<td class="org-right">3.2559e-11</td>
<td class="org-right">-1.1188e-10</td>
<td class="org-right">9.0385e-11</td>
</tr>
<tr>
<td class="org-right">-5.1839e-11</td>
<td class="org-right">1.8593e-08</td>
<td class="org-right">-4.4868e-11</td>
<td class="org-right">8.016e-11</td>
<td class="org-right">4.3558e-11</td>
<td class="org-right">-1.1164e-10</td>
</tr>
<tr>
<td class="org-right">5.1963e-12</td>
<td class="org-right">-6.9001e-12</td>
<td class="org-right">1.8564e-08</td>
<td class="org-right">3.0844e-11</td>
<td class="org-right">4.0097e-11</td>
<td class="org-right">-3.4387e-11</td>
</tr>
<tr>
<td class="org-right">1.9359e-11</td>
<td class="org-right">1.7432e-10</td>
<td class="org-right">-5.0928e-11</td>
<td class="org-right">1.855e-08</td>
<td class="org-right">1.6406e-10</td>
<td class="org-right">4.5757e-12</td>
</tr>
<tr>
<td class="org-right">-2.1185e-11</td>
<td class="org-right">2.1724e-10</td>
<td class="org-right">1.5333e-12</td>
<td class="org-right">-8.802e-11</td>
<td class="org-right">1.8803e-08</td>
<td class="org-right">-4.6946e-11</td>
</tr>
<tr>
<td class="org-right">-1.1728e-11</td>
<td class="org-right">-5.7682e-11</td>
<td class="org-right">1.6213e-10</td>
<td class="org-right">2.1934e-12</td>
<td class="org-right">-1.6237e-10</td>
<td class="org-right">1.8715e-08</td>
</tr>
</tbody>
</table>
<p>
And the bode plot of the DVF plant is shown in Figure <a href="#orgd71b655">11</a>.
</p>
<div id="orgd71b655" class="figure">
<p><img src="figs/nano_hexapod_struts_2dof_dvf_plant.png" alt="nano_hexapod_struts_2dof_dvf_plant.png" />
</p>
<p><span class="figure-number">Figure 11: </span>Bode plot of the transfer functions from actuator forces \(\tau_i\) to relative motion sensors attached to the struts \(\mathcal{L}_i\). Diagonal terms are shown in blue, and off-diagonal terms in black.</p>
</div>
</div>
</div>
<div id="outline-container-orgdefb22f" class="outline-3">
<h3 id="orgdefb22f"><span class="section-number-3">1.6</span> Integral Force Feedback Plant</h3>
<div class="outline-text-3" id="text-1-6">
<p>
<a id="org4921e6d"></a>
</p>
<p>
The transfer function from actuators to force sensors is identified.
It corresponds to the plant for the Integral Force Feedback (IFF) control strategy.
</p>
<div class="org-src-container">
<pre class="src src-matlab"><span class="org-matlab-cellbreak"><span class="org-comment">%% Input/Output definition</span></span>
clear io; io_i = 1;
io(io_i) = linio([mdl, <span class="org-string">'/F'</span>], 1, <span class="org-string">'openinput'</span>); io_i = io_i <span class="org-type">+</span> 1; <span class="org-comment">% Actuator Inputs</span>
io(io_i) = linio([mdl, <span class="org-string">'/Fm'</span>], 1, <span class="org-string">'openoutput'</span>); io_i = io_i <span class="org-type">+</span> 1; <span class="org-comment">% Force Sensors</span>
n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'struts'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>);
Giff = linearize(mdl, io, 0.0, options);
</pre>
</div>
<p>
The DC gain from actuator to the force sensor should be equal to (for the 2dof APA):
\[ \frac{k_e k_1}{k_1 k_e + k_a k_1 + k_e k_a} \]
</p>
<p>
Which is equal to:
</p>
<pre class="example">
DCgain = 6.56e-03 [m/N]
</pre>
<p>
This is indeed close to what we see on DC gain of the \(6 \times 6\) IFF plant in Table <a href="#orgaa4cdee">4</a>.
Also, the off diagonal terms are quite small compared to the diagonal terms.
</p>
<table id="orgaa4cdee" border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<caption class="t-above"><span class="table-number">Table 4:</span> DC gain of the IFF plant</caption>
<colgroup>
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
</colgroup>
<tbody>
<tr>
<td class="org-right">0.0068</td>
<td class="org-right">0.0002</td>
<td class="org-right">-0.0002</td>
<td class="org-right">-0.0</td>
<td class="org-right">0.0002</td>
<td class="org-right">-0.0001</td>
</tr>
<tr>
<td class="org-right">0.0003</td>
<td class="org-right">0.0068</td>
<td class="org-right">0.0001</td>
<td class="org-right">-0.0001</td>
<td class="org-right">-0.0001</td>
<td class="org-right">0.0002</td>
</tr>
<tr>
<td class="org-right">0.0001</td>
<td class="org-right">0.0</td>
<td class="org-right">0.0068</td>
<td class="org-right">-0.0001</td>
<td class="org-right">-0.0001</td>
<td class="org-right">0.0001</td>
</tr>
<tr>
<td class="org-right">-0.0002</td>
<td class="org-right">-0.0003</td>
<td class="org-right">0.0001</td>
<td class="org-right">0.0068</td>
<td class="org-right">-0.0002</td>
<td class="org-right">-0.0</td>
</tr>
<tr>
<td class="org-right">-0.0001</td>
<td class="org-right">-0.0003</td>
<td class="org-right">-0.0</td>
<td class="org-right">0.0001</td>
<td class="org-right">0.0065</td>
<td class="org-right">0.0</td>
</tr>
<tr>
<td class="org-right">0.0001</td>
<td class="org-right">0.0001</td>
<td class="org-right">-0.0002</td>
<td class="org-right">-0.0</td>
<td class="org-right">0.0002</td>
<td class="org-right">0.0066</td>
</tr>
</tbody>
</table>
<p>
The bode plot is shown in Figure <a href="#org50de635">12</a>.
</p>
<div id="org50de635" class="figure">
<p><img src="figs/nano_hexapod_struts_2dof_iff_plant.png" alt="nano_hexapod_struts_2dof_iff_plant.png" />
</p>
<p><span class="figure-number">Figure 12: </span>Bode plot of the transfer functions from actuator forces \(\tau_i\) to force sensors \(F_{m,i}\). Diagonal terms are shown in blue, and off-diagonal terms in black.</p>
</div>
</div>
</div>
<div id="outline-container-orgde9c23b" class="outline-3">
<h3 id="orgde9c23b"><span class="section-number-3">1.7</span> Decentralized Plant - Cartesian coordinates</h3>
<div class="outline-text-3" id="text-1-7">
<p>
<a id="orgdf28609"></a>
</p>
<p>
Consider the plant shown in Figure <a href="#org0eaa805">13</a> with:
</p>
<ul class="org-ul">
<li>\(\tau\) the 6 input forces (APA)</li>
<li>\(d\mathcal{L}\) the relative motion sensor outputs (encoders)</li>
<li>\(\mathcal{X}\) the motion of the top platform measured with &ldquo;perfect&rdquo; 6-dof sensor</li>
<li>\(J_a\) and \(J_s\) the Jacobians for the actuators and sensors</li>
</ul>
<div id="org0eaa805" class="figure">
<p><img src="figs/nano_hexapod_decentralized_schematic.png" alt="nano_hexapod_decentralized_schematic.png" />
</p>
<p><span class="figure-number">Figure 13: </span>Plant in the cartesian Frame</p>
</div>
</div>
<div id="outline-container-org435b7fd" class="outline-4">
<h4 id="org435b7fd"><span class="section-number-4">1.7.1</span> Verification of the Sensor Jacobian</h4>
<div class="outline-text-4" id="text-1-7-1">
<p>
The &ldquo;perfect&rdquo; sensor output \(\mathcal{X}\) is used to verify that the sensor Jacobian is working correctly both when the encoders are fixed to the struts and to the plates.
</p>
<p>
Let&rsquo;s then identify the plant for both configuration, and compare the transfer functions from \(\mathcal{F}\) to \(d\mathcal{X}\) and to \(\mathcal{X}\).
</p>
<div class="org-src-container">
<pre class="src src-matlab"><span class="org-matlab-cellbreak"><span class="org-comment">%% Input/Output definition</span></span>
clear io; io_i = 1;
io(io_i) = linio([mdl, <span class="org-string">'/F'</span>], 1, <span class="org-string">'openinput'</span>); io_i = io_i <span class="org-type">+</span> 1; <span class="org-comment">% Actuator Inputs</span>
io(io_i) = linio([mdl, <span class="org-string">'/D'</span>], 1, <span class="org-string">'openoutput'</span>); io_i = io_i <span class="org-type">+</span> 1; <span class="org-comment">% Relative Motion Outputs</span>
io(io_i) = linio([mdl, <span class="org-string">'/X'</span>], 1, <span class="org-string">'openoutput'</span>); io_i = io_i <span class="org-type">+</span> 1; <span class="org-comment">% Relative Motion Outputs</span>
</pre>
</div>
<p>
Start when the encoders are fixed on the struts.
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'struts'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>, ...
<span class="org-string">'MO_B'</span>, 150e<span class="org-type">-</span>3);
Gs = linearize(mdl, io, 0.0, options);
Gs.InputName = {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>};
Gs.OutputName = {<span class="org-string">'D1'</span>, <span class="org-string">'D2'</span>, <span class="org-string">'D3'</span>, <span class="org-string">'D4'</span>, <span class="org-string">'D5'</span>, <span class="org-string">'D6'</span>, ...
<span class="org-string">'Dx'</span>, <span class="org-string">'Dy'</span>, <span class="org-string">'Dz'</span>, <span class="org-string">'Rx'</span>, <span class="org-string">'Ry'</span>, <span class="org-string">'Rz'</span>};
<span class="org-comment">% Cartesian plant using the Jacobians</span>
Gsc = inv(n_hexapod.geometry.Js)<span class="org-type">*</span>Gs({<span class="org-string">'D1'</span>, <span class="org-string">'D2'</span>, <span class="org-string">'D3'</span>, <span class="org-string">'D4'</span>, <span class="org-string">'D5'</span>, <span class="org-string">'D6'</span>}, {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>})<span class="org-type">*</span>inv(n_hexapod.geometry.J)<span class="org-type">'</span>;
<span class="org-comment">% Cartesian plant using the perfect sensor</span>
Gsp = <span class="org-type">-</span>Gs({<span class="org-string">'Dx'</span>, <span class="org-string">'Dy'</span>, <span class="org-string">'Dz'</span>, <span class="org-string">'Rx'</span>, <span class="org-string">'Ry'</span>, <span class="org-string">'Rz'</span>}, {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>})<span class="org-type">*</span>inv(n_hexapod.geometry.J)<span class="org-type">'</span>;
</pre>
</div>
<p>
The diagonal elements of the plant are shown in Figure <a href="#orge5b87a7">14</a>.
</p>
<div id="orge5b87a7" class="figure">
<p><img src="figs/nano_hexapod_comp_cartesian_plants_struts.png" alt="nano_hexapod_comp_cartesian_plants_struts.png" />
</p>
<p><span class="figure-number">Figure 14: </span>Bode plot of the diagonal elements of the decentralized (cartesian) plant when using the sensor Jacobian (solid) and when using &ldquo;perfect&rdquo; 6dof sensor (dashed). The encoders are fixed on the struts.</p>
</div>
<p>
The same if performed when the encoders are fixed to the plates.
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'plates'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>, ...
<span class="org-string">'MO_B'</span>, 150e<span class="org-type">-</span>3);
Gp = linearize(mdl, io, 0.0, options);
Gp.InputName = {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>};
Gp.OutputName = {<span class="org-string">'D1'</span>, <span class="org-string">'D2'</span>, <span class="org-string">'D3'</span>, <span class="org-string">'D4'</span>, <span class="org-string">'D5'</span>, <span class="org-string">'D6'</span>, ...
<span class="org-string">'Dx'</span>, <span class="org-string">'Dy'</span>, <span class="org-string">'Dz'</span>, <span class="org-string">'Rx'</span>, <span class="org-string">'Ry'</span>, <span class="org-string">'Rz'</span>};
<span class="org-comment">% Cartesian plant using the Jacobians</span>
Gpc = inv(n_hexapod.geometry.Js)<span class="org-type">*</span>Gp({<span class="org-string">'D1'</span>, <span class="org-string">'D2'</span>, <span class="org-string">'D3'</span>, <span class="org-string">'D4'</span>, <span class="org-string">'D5'</span>, <span class="org-string">'D6'</span>}, {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>})<span class="org-type">*</span>inv(n_hexapod.geometry.J)<span class="org-type">'</span>;
<span class="org-comment">% Cartesian plant using the perfect sensor</span>
Gpp = <span class="org-type">-</span>Gp({<span class="org-string">'Dx'</span>, <span class="org-string">'Dy'</span>, <span class="org-string">'Dz'</span>, <span class="org-string">'Rx'</span>, <span class="org-string">'Ry'</span>, <span class="org-string">'Rz'</span>}, {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>})<span class="org-type">*</span>inv(n_hexapod.geometry.J)<span class="org-type">'</span>;
</pre>
</div>
<p>
The obtained bode plots are shown in Figure <a href="#org4e450ca">15</a>.
</p>
<div id="org4e450ca" class="figure">
<p><img src="figs/nano_hexapod_comp_cartesian_plants_plates.png" alt="nano_hexapod_comp_cartesian_plants_plates.png" />
</p>
<p><span class="figure-number">Figure 15: </span>Bode plot of the diagonal elements of the decentralized (cartesian) plant when using the sensor Jacobian (solid) and when using &ldquo;perfect&rdquo; 6dof sensor (dashed). The encoders are fixed on the plates.</p>
</div>
<div class="important" id="org43430ac">
<p>
The Jacobian for the encoders is working properly both when the encoders are fixed to the plates or to the struts.
</p>
<p>
However, then the encoders are fixed to the struts, there is a mismatch between the estimated motion and the measured motion above 100Hz due to a complex conjugate zero.
</p>
</div>
</div>
</div>
<div id="outline-container-org664eab9" class="outline-4">
<h4 id="org664eab9"><span class="section-number-4">1.7.2</span> Comparison of the decentralized plants</h4>
<div class="outline-text-4" id="text-1-7-2">
<p>
The decentralized plants are now compared whether the encoders are fixed on the struts or on the plates in Figure <a href="#orgde1d043">16</a>.
</p>
<div id="orgde1d043" class="figure">
<p><img src="figs/nano_hexapod_cartesian_plant_encoder_comp.png" alt="nano_hexapod_cartesian_plant_encoder_comp.png" />
</p>
<p><span class="figure-number">Figure 16: </span>Bode plot of the &ldquo;cartesian&rdquo; plant (transfer function from \(\mathcal{F}\) to \(d\mathcal{X}\)) when the encoders are fixed on the struts (solid) and on the plates (dashed)</p>
</div>
<div class="question" id="org9eb073a">
<p>
Is the complex conjugate zeros on Figure <a href="#orgde1d043">16</a> could be due to the axial stiffness of the joints?
Let&rsquo;s find out by using a model with no axial flexibility on the joints and see if we still have this zero.
</p>
</div>
</div>
</div>
<div id="outline-container-orged8dc85" class="outline-4">
<h4 id="orged8dc85"><span class="section-number-4">1.7.3</span> Perfect axial stiffness of the joints</h4>
<div class="outline-text-4" id="text-1-7-3">
<p>
Let&rsquo;s initialize the Nano-Hexapod with perfect joints (no axial stiffness):
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'3dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'2dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'struts'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>, ...
<span class="org-string">'MO_B'</span>, 150e<span class="org-type">-</span>3);
</pre>
</div>
<p>
Identify its dynamics.
</p>
<div class="org-src-container">
<pre class="src src-matlab">G = linearize(mdl, io, 0.0, options);
G.InputName = {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>};
G.OutputName = {<span class="org-string">'D1'</span>, <span class="org-string">'D2'</span>, <span class="org-string">'D3'</span>, <span class="org-string">'D4'</span>, <span class="org-string">'D5'</span>, <span class="org-string">'D6'</span>, ...
<span class="org-string">'Dx'</span>, <span class="org-string">'Dy'</span>, <span class="org-string">'Dz'</span>, <span class="org-string">'Rx'</span>, <span class="org-string">'Ry'</span>, <span class="org-string">'Rz'</span>};
</pre>
</div>
<p>
And compute the transfer function in the cartesian frame.
</p>
<div class="org-src-container">
<pre class="src src-matlab">G = inv(n_hexapod.geometry.Js)<span class="org-type">*</span>G({<span class="org-string">'D1'</span>, <span class="org-string">'D2'</span>, <span class="org-string">'D3'</span>, <span class="org-string">'D4'</span>, <span class="org-string">'D5'</span>, <span class="org-string">'D6'</span>}, {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>})<span class="org-type">*</span>inv(n_hexapod.geometry.J)<span class="org-type">'</span>;
</pre>
</div>
<p>
The obtained dynamics is shown in Figure <a href="#org480cdaf">17</a>.
It is shown that there are no zeros at high frequency.
</p>
<div id="org480cdaf" class="figure">
<p><img src="figs/nano_hexapod_cartesian_plant_perfect_joints.png" alt="nano_hexapod_cartesian_plant_perfect_joints.png" />
</p>
<p><span class="figure-number">Figure 17: </span>Bode plot of the &ldquo;cartesian&rdquo; plant (transfer function from \(\mathcal{F}\) to \(d\mathcal{X}\)) when the encoders are fixed on the struts and with perfect joints (infinite axial stiffness)</p>
</div>
<div class="important" id="org17fa32d">
<p>
The zeros appearing between 100Hz and 500Hz are due to the axial stiffness of the flexible joints.
They appear when the relative motion sensors are fixed to the struts.
They basically correspond to the resonance frequency where the APA are infinitively stiff.
</p>
</div>
</div>
</div>
<div id="outline-container-orga4e05f4" class="outline-4">
<h4 id="orga4e05f4"><span class="section-number-4">1.7.4</span> Frequency of the zeros</h4>
<div class="outline-text-4" id="text-1-7-4">
<p>
Let&rsquo;s verify this last affirmation by generating a nano-hexapod with very stiff APA.
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'struts'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>, ...
<span class="org-string">'actuator_k'</span>, 1e9<span class="org-type">*</span>ones(6,1));
Gs = linearize(mdl, io, 0.0, options);
Gs.InputName = {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>};
Gs.OutputName = {<span class="org-string">'D1'</span>, <span class="org-string">'D2'</span>, <span class="org-string">'D3'</span>, <span class="org-string">'D4'</span>, <span class="org-string">'D5'</span>, <span class="org-string">'D6'</span>};
</pre>
</div>
<div class="org-src-container">
<pre class="src src-matlab">Gs_p = imag(pole(Gs))<span class="org-type">/</span>2<span class="org-type">/</span><span class="org-constant">pi</span>;
sort(Gs_p(Gs_p <span class="org-type">&gt;</span> 0))
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-org6cf8089" class="outline-3">
<h3 id="org6cf8089"><span class="section-number-3">1.8</span> Decentralized Plant - Decoupling at the Center of Stiffness</h3>
<div class="outline-text-3" id="text-1-8">
<p>
<a id="org07c3977"></a>
</p>
</div>
<div id="outline-container-org8c0186d" class="outline-4">
<h4 id="org8c0186d"><span class="section-number-4">1.8.1</span> Center of Stiffness</h4>
<div class="outline-text-4" id="text-1-8-1">
<p>
<a id="org7b98b12"></a>
</p>
<p>
Let&rsquo;s define some parameters that will be used for the computation of the stiffness matrix:
</p>
<div class="org-src-container">
<pre class="src src-matlab">si = n_hexapod.geometry.si; <span class="org-comment">% Orientation of struts</span>
bi = n_hexapod.geometry.Fb; <span class="org-comment">% Location of bi w.r.t. {F}</span>
ki = ones(1,6); <span class="org-comment">% Normalized strut stiffness</span>
</pre>
</div>
<p>
In order to find is the Center of Stiffness (CoK) exists, we have to verify is the following is diagonal:
</p>
<div class="org-src-container">
<pre class="src src-matlab">ki<span class="org-type">.*</span>si<span class="org-type">*</span>si<span class="org-type">'</span>
</pre>
</div>
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<colgroup>
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
</colgroup>
<tbody>
<tr>
<td class="org-right">1.8977</td>
<td class="org-right">2.4659e-17</td>
<td class="org-right">5.1838e-19</td>
</tr>
<tr>
<td class="org-right">2.4659e-17</td>
<td class="org-right">1.8977</td>
<td class="org-right">-2.3143e-05</td>
</tr>
<tr>
<td class="org-right">5.1838e-19</td>
<td class="org-right">-2.3143e-05</td>
<td class="org-right">2.2046</td>
</tr>
</tbody>
</table>
<p>
And we can find the location of the CoK with respect to {F}:
</p>
<div class="org-src-container">
<pre class="src src-matlab">OkX = (ki<span class="org-type">.*</span>cross(bi, si)<span class="org-type">*</span>si<span class="org-type">'</span>)<span class="org-type">/</span>(ki<span class="org-type">.*</span>si<span class="org-type">*</span>si<span class="org-type">'</span>);
Ok = [OkX(3,2);OkX(1,3);OkX(2,1)]
</pre>
</div>
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<colgroup>
<col class="org-right" />
</colgroup>
<tbody>
<tr>
<td class="org-right">-1.7444e-18</td>
</tr>
<tr>
<td class="org-right">2.1511e-06</td>
</tr>
<tr>
<td class="org-right">0.052707</td>
</tr>
</tbody>
</table>
<p>
The &ldquo;center of stiffness&rdquo; is therefore 52.7mm above the bottom platform {F} frame.
</p>
<p>
Let&rsquo;s initialize the hexapod with frame {A} and {B} at the CoK:
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'3dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'struts'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>, ...
<span class="org-string">'MO_B'</span>, Ok(3)<span class="org-type">-</span>95e<span class="org-type">-</span>3);
</pre>
</div>
<p>
And the (normalized) stiffness matrix is computed as follows:
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod.geometry.J<span class="org-type">'*</span>diag(ki)<span class="org-type">*</span>n_hexapod.geometry.J
</pre>
</div>
<table id="orgf9c4f48" border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<caption class="t-above"><span class="table-number">Table 5:</span> Normalized Stiffness Matrix - Center of Stiffness</caption>
<colgroup>
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
</colgroup>
<tbody>
<tr>
<td class="org-right">1.8977</td>
<td class="org-right">0</td>
<td class="org-right">0</td>
<td class="org-right">0</td>
<td class="org-right">-2.0817e-17</td>
<td class="org-right">-1.5311e-06</td>
</tr>
<tr>
<td class="org-right">0</td>
<td class="org-right">1.8977</td>
<td class="org-right">-2.3143e-05</td>
<td class="org-right">4.175e-06</td>
<td class="org-right">0</td>
<td class="org-right">0</td>
</tr>
<tr>
<td class="org-right">0</td>
<td class="org-right">-2.3143e-05</td>
<td class="org-right">2.2046</td>
<td class="org-right">4.7422e-06</td>
<td class="org-right">0</td>
<td class="org-right">0</td>
</tr>
<tr>
<td class="org-right">0</td>
<td class="org-right">4.175e-06</td>
<td class="org-right">4.7422e-06</td>
<td class="org-right">0.012594</td>
<td class="org-right">2.1684e-19</td>
<td class="org-right">-8.6736e-19</td>
</tr>
<tr>
<td class="org-right">-1.8521e-17</td>
<td class="org-right">0</td>
<td class="org-right">0</td>
<td class="org-right">0</td>
<td class="org-right">0.012594</td>
<td class="org-right">-9.3183e-08</td>
</tr>
<tr>
<td class="org-right">-1.5311e-06</td>
<td class="org-right">-6.9389e-18</td>
<td class="org-right">2.7756e-17</td>
<td class="org-right">-8.6736e-19</td>
<td class="org-right">-9.3183e-08</td>
<td class="org-right">0.043362</td>
</tr>
</tbody>
</table>
<p>
And we indeed obtain a diagonal stiffness matrix.
</p>
</div>
</div>
<div id="outline-container-org58e2a5b" class="outline-4">
<h4 id="org58e2a5b"><span class="section-number-4">1.8.2</span> Obtained plant</h4>
<div class="outline-text-4" id="text-1-8-2">
<p>
Let&rsquo;s identify the transfer function from \(\tau\) to \(d\mathcal{L}\) and from \(\tau\) to \(\mathcal{X}\).
</p>
<div class="org-src-container">
<pre class="src src-matlab"><span class="org-matlab-cellbreak"><span class="org-comment">%% Input/Output definition</span></span>
clear io; io_i = 1;
io(io_i) = linio([mdl, <span class="org-string">'/F'</span>], 1, <span class="org-string">'openinput'</span>); io_i = io_i <span class="org-type">+</span> 1; <span class="org-comment">% Actuator Inputs</span>
io(io_i) = linio([mdl, <span class="org-string">'/D'</span>], 1, <span class="org-string">'openoutput'</span>); io_i = io_i <span class="org-type">+</span> 1; <span class="org-comment">% Relative Motion Outputs</span>
io(io_i) = linio([mdl, <span class="org-string">'/X'</span>], 1, <span class="org-string">'openoutput'</span>); io_i = io_i <span class="org-type">+</span> 1; <span class="org-comment">% 6DoF perfect measurement</span>
G = linearize(mdl, io, 0.0, options);
G.InputName = {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>};
G.OutputName = {<span class="org-string">'D1'</span>, <span class="org-string">'D2'</span>, <span class="org-string">'D3'</span>, <span class="org-string">'D4'</span>, <span class="org-string">'D5'</span>, <span class="org-string">'D6'</span>, ...
<span class="org-string">'Dx'</span>, <span class="org-string">'Dy'</span>, <span class="org-string">'Dz'</span>, <span class="org-string">'Rx'</span>, <span class="org-string">'Ry'</span>, <span class="org-string">'Rz'</span>};
</pre>
</div>
<p>
Then use the Jacobian matrices to obtain the &ldquo;cartesian&rdquo; centralized plant.
</p>
<div class="org-src-container">
<pre class="src src-matlab">Gc = inv(n_hexapod.geometry.J)<span class="org-type">*</span>...
G({<span class="org-string">'D1'</span>, <span class="org-string">'D2'</span>, <span class="org-string">'D3'</span>, <span class="org-string">'D4'</span>, <span class="org-string">'D5'</span>, <span class="org-string">'D6'</span>}, {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>})<span class="org-type">*</span>...
inv(n_hexapod.geometry.J<span class="org-type">'</span>);
</pre>
</div>
<p>
The DC gain of the obtained plant is shown in Table <a href="#orgcad75ab">6</a>.
</p>
<table id="orgcad75ab" border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<caption class="t-above"><span class="table-number">Table 6:</span> DC gain of the centralized plant at the center of stiffness</caption>
<colgroup>
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
</colgroup>
<tbody>
<tr>
<td class="org-right">9.8602e-09</td>
<td class="org-right">7.8692e-11</td>
<td class="org-right">1.4426e-11</td>
<td class="org-right">-2.663e-10</td>
<td class="org-right">2.8e-10</td>
<td class="org-right">-4.7559e-11</td>
</tr>
<tr>
<td class="org-right">8.457e-11</td>
<td class="org-right">9.8788e-09</td>
<td class="org-right">-2.4002e-11</td>
<td class="org-right">-2.9502e-11</td>
<td class="org-right">-1.3262e-10</td>
<td class="org-right">-8.7346e-11</td>
</tr>
<tr>
<td class="org-right">-4.3244e-11</td>
<td class="org-right">2.4075e-13</td>
<td class="org-right">8.4775e-09</td>
<td class="org-right">1.1442e-11</td>
<td class="org-right">-2.5809e-10</td>
<td class="org-right">2.8796e-11</td>
</tr>
<tr>
<td class="org-right">-1.8326e-09</td>
<td class="org-right">-9.318e-10</td>
<td class="org-right">6.8188e-10</td>
<td class="org-right">1.4697e-06</td>
<td class="org-right">5.5936e-09</td>
<td class="org-right">8.7632e-10</td>
</tr>
<tr>
<td class="org-right">4.6906e-10</td>
<td class="org-right">1.5911e-09</td>
<td class="org-right">1.6989e-10</td>
<td class="org-right">-5.223e-09</td>
<td class="org-right">1.4729e-06</td>
<td class="org-right">-2.6059e-10</td>
</tr>
<tr>
<td class="org-right">-6.5754e-11</td>
<td class="org-right">-3.0408e-12</td>
<td class="org-right">5.394e-11</td>
<td class="org-right">-1.0917e-10</td>
<td class="org-right">6.9479e-10</td>
<td class="org-right">4.2979e-07</td>
</tr>
</tbody>
</table>
<p>
As the rotations and translations have very different gains, we normalize each motion to one.
</p>
<div class="org-src-container">
<pre class="src src-matlab">Gc = diag(1<span class="org-type">./</span>diag(dcgain(Gc)))<span class="org-type">*</span>Gc;
</pre>
</div>
<p>
The diagonal and off-diagonal elements are shown in Figure <a href="#org497e3a3">18</a>, and we can see good decoupling at low frequency.
</p>
<div id="org497e3a3" class="figure">
<p><img src="figs/nano_hexapod_diagonal_plant_cok.png" alt="nano_hexapod_diagonal_plant_cok.png" />
</p>
<p><span class="figure-number">Figure 18: </span>Diagonal and off-diagonal elements of the (normalized) decentralized plant with the Jacobians estimated at the &ldquo;center of stiffness&rdquo;</p>
</div>
<div class="important" id="org421c0b1">
<p>
The Jacobian matrices can be used to decoupled the plant at low frequency.
</p>
</div>
</div>
</div>
</div>
<div id="outline-container-orgd60e2b2" class="outline-3">
<h3 id="orgd60e2b2"><span class="section-number-3">1.9</span> Stiffness matrix</h3>
<div class="outline-text-3" id="text-1-9">
<p>
<a id="org694793c"></a>
</p>
<p>
The stiffness matrix of the nano-hexapod describes its induced static displacement/rotation when a force/torque is applied on its top platform.
The location of the applied force/torque and the expressed displacement/rotation can be defined as wanted.
Such location (or frame) is then used for the computation of the Jacobian which in turns is used to compute the stiffness matrix.
</p>
</div>
<div id="outline-container-org97c57ea" class="outline-4">
<h4 id="org97c57ea"><span class="section-number-4">1.9.1</span> Compute the theoretical stiffness of the nano-hexapod</h4>
<div class="outline-text-4" id="text-1-9-1">
<p>
Neglecting the torsional/bending stiffness of the joints, we have:
\[ K = J^t \mathcal{K} J \]
where \(\mathcal{K}\) is a diagonal 6x6 matrix with the axial stiffness of the struts on the diagonal.
</p>
<p>
Let&rsquo;s note the axial stiffness of the APA:
\[ k_{\text{APA}} = k + \frac{k_e k_a}{k_e + k_a} \]
</p>
<p>
The axial stiffness of the struts \(k_s\) is then:
\[ k_s = \frac{k_z k_{\text{APA}}}{k_z + 2 k_{\text{APA}}} \]
with \(k_z\) the axial stiffness of the flexible joints.
</p>
<p>
Let&rsquo;s initialize the nano-hexapod.
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'struts'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>);
</pre>
</div>
<p>
The total axial stiffness of the APA is:
</p>
<pre class="example">
kAPA = 1.799e+06 [N/m]
</pre>
<p>
And the total axial stiffness of the struts is:
</p>
<pre class="example">
ks = 1.737e+06 [N/m]
</pre>
<div class="important" id="org4c77c5f">
<p>
We can see that the axial stiffness of the flexible joint as little impact on the total axial stiffness of the struts as it is much stiffer than the APA.
</p>
</div>
<p>
Let&rsquo;s now compute the stiffness matrix corresponding to an hexapod with perfect joints and the above computed axial strut stiffness:
</p>
<div class="org-src-container">
<pre class="src src-matlab">Ks = n_hexapod.geometry.J<span class="org-type">'*</span>(ks<span class="org-type">*</span>eye(6))<span class="org-type">*</span>n_hexapod.geometry.J;
</pre>
</div>
<p>
And the compliance matrix can be computed as the inverse of the stiffness matrix.
</p>
<div class="org-src-container">
<pre class="src src-matlab">C = inv(Ks);
</pre>
</div>
<p>
The obtained compliance matrix is shown in Table <a href="#org426afb9">7</a>.
</p>
<table id="org426afb9" border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<caption class="t-above"><span class="table-number">Table 7:</span> Compliance Matrix - Perfect Joints</caption>
<colgroup>
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
</colgroup>
<tbody>
<tr>
<td class="org-right">1.9938e-06</td>
<td class="org-right">-2.3138e-22</td>
<td class="org-right">3.3403e-23</td>
<td class="org-right">1.0202e-21</td>
<td class="org-right">8.7906e-06</td>
<td class="org-right">2.9603e-11</td>
</tr>
<tr>
<td class="org-right">-3.1875e-23</td>
<td class="org-right">1.9938e-06</td>
<td class="org-right">2.2094e-11</td>
<td class="org-right">-8.7909e-06</td>
<td class="org-right">-1.6576e-22</td>
<td class="org-right">-3.5622e-28</td>
</tr>
<tr>
<td class="org-right">6.6811e-23</td>
<td class="org-right">2.2094e-11</td>
<td class="org-right">2.6115e-07</td>
<td class="org-right">-9.8337e-11</td>
<td class="org-right">3.4744e-22</td>
<td class="org-right">7.4663e-28</td>
</tr>
<tr>
<td class="org-right">1.4054e-22</td>
<td class="org-right">-8.7909e-06</td>
<td class="org-right">-9.8337e-11</td>
<td class="org-right">4.5715e-05</td>
<td class="org-right">7.3086e-22</td>
<td class="org-right">1.5706e-27</td>
</tr>
<tr>
<td class="org-right">8.7906e-06</td>
<td class="org-right">-1.0202e-21</td>
<td class="org-right">1.7371e-22</td>
<td class="org-right">4.498e-21</td>
<td class="org-right">4.5714e-05</td>
<td class="org-right">9.8237e-11</td>
</tr>
<tr>
<td class="org-right">2.9603e-11</td>
<td class="org-right">-1.9261e-22</td>
<td class="org-right">-1.7611e-27</td>
<td class="org-right">8.4925e-22</td>
<td class="org-right">9.8237e-11</td>
<td class="org-right">1.3277e-05</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="outline-container-orgc388f2b" class="outline-4">
<h4 id="orgc388f2b"><span class="section-number-4">1.9.2</span> Comparison with Simscape Model</h4>
<div class="outline-text-4" id="text-1-9-2">
<p>
Let&rsquo;s now identify the compliance matrix using Simscape.
</p>
<div class="org-src-container">
<pre class="src src-matlab"><span class="org-matlab-cellbreak"><span class="org-comment">%% Input/Output definition</span></span>
clear io; io_i = 1;
io(io_i) = linio([mdl, <span class="org-string">'/Fe'</span>], 1, <span class="org-string">'openinput'</span>); io_i = io_i <span class="org-type">+</span> 1; <span class="org-comment">% External forces [N, Nm/rad]</span>
io(io_i) = linio([mdl, <span class="org-string">'/X'</span>], 1, <span class="org-string">'openoutput'</span>); io_i = io_i <span class="org-type">+</span> 1; <span class="org-comment">% Induced motion [m, rad]</span>
G = linearize(mdl, io, 0.0, options);
</pre>
</div>
<p>
The DC gain of the identified plant is therefore the compliance matrix of the nano-hexapod.
It takes into account the bending and torsional stiffness of the flexible joints.
</p>
<p>
The obtained compliance matrix is shown in Table <a href="#org6e78afc">8</a>.
</p>
<table id="org6e78afc" border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<caption class="t-above"><span class="table-number">Table 8:</span> Compliance Matrix - Estimated from Simscape</caption>
<colgroup>
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
</colgroup>
<tbody>
<tr>
<td class="org-right">1.9863e-06</td>
<td class="org-right">2.4683e-08</td>
<td class="org-right">2.2859e-09</td>
<td class="org-right">-6.4768e-08</td>
<td class="org-right">8.7307e-06</td>
<td class="org-right">3.2754e-10</td>
</tr>
<tr>
<td class="org-right">-3.693e-09</td>
<td class="org-right">1.9663e-06</td>
<td class="org-right">-7.4503e-09</td>
<td class="org-right">-8.615e-06</td>
<td class="org-right">-6.7926e-08</td>
<td class="org-right">-2.0193e-08</td>
</tr>
<tr>
<td class="org-right">-3.5525e-09</td>
<td class="org-right">-8.8671e-10</td>
<td class="org-right">2.6042e-07</td>
<td class="org-right">4.7504e-09</td>
<td class="org-right">-9.9677e-09</td>
<td class="org-right">1.7242e-10</td>
</tr>
<tr>
<td class="org-right">2.1133e-08</td>
<td class="org-right">-8.6554e-06</td>
<td class="org-right">3.2841e-08</td>
<td class="org-right">4.4849e-05</td>
<td class="org-right">3.0873e-07</td>
<td class="org-right">8.1525e-08</td>
</tr>
<tr>
<td class="org-right">8.7375e-06</td>
<td class="org-right">9.9165e-08</td>
<td class="org-right">8.135e-09</td>
<td class="org-right">-2.5208e-07</td>
<td class="org-right">4.5331e-05</td>
<td class="org-right">3.0602e-09</td>
</tr>
<tr>
<td class="org-right">6.1611e-09</td>
<td class="org-right">6.1733e-09</td>
<td class="org-right">2.6778e-09</td>
<td class="org-right">-3.3188e-08</td>
<td class="org-right">3.3887e-08</td>
<td class="org-right">1.3212e-05</td>
</tr>
</tbody>
</table>
<p>
Let&rsquo;s compare the two obtained compliance matrices.
The results are shown in Table <a href="#org71532aa">9</a>.
The diagonal terms are matching quite good, as well as the 1/4 and 2/5 of diagonal terms that are the most important ones.
</p>
<p>
All the other terms are zero in the ideal case (Table <a href="#org426afb9">7</a>).
There are not zero when considering the bending/torsional stiffness of the joints (Table <a href="#org6e78afc">8</a>), however they are still small as compared to the diagonal terms.
</p>
<div class="org-src-container">
<pre class="src src-matlab">C<span class="org-type">./</span>dcgain(G)
</pre>
</div>
<table id="org71532aa" border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<caption class="t-above"><span class="table-number">Table 9:</span> Compliance Matrices - Comparison</caption>
<colgroup>
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
<col class="org-right" />
</colgroup>
<tbody>
<tr>
<td class="org-right">1.0037</td>
<td class="org-right">-9.3741e-15</td>
<td class="org-right">1.4613e-14</td>
<td class="org-right">-1.5751e-14</td>
<td class="org-right">1.0069</td>
<td class="org-right">0.090379</td>
</tr>
<tr>
<td class="org-right">8.6313e-15</td>
<td class="org-right">1.014</td>
<td class="org-right">-0.0029656</td>
<td class="org-right">1.0204</td>
<td class="org-right">2.4404e-15</td>
<td class="org-right">1.7641e-20</td>
</tr>
<tr>
<td class="org-right">-1.8807e-14</td>
<td class="org-right">-0.024917</td>
<td class="org-right">1.0028</td>
<td class="org-right">-0.020701</td>
<td class="org-right">-3.4857e-14</td>
<td class="org-right">4.3304e-18</td>
</tr>
<tr>
<td class="org-right">6.6502e-15</td>
<td class="org-right">1.0157</td>
<td class="org-right">-0.0029943</td>
<td class="org-right">1.0193</td>
<td class="org-right">2.3673e-15</td>
<td class="org-right">1.9265e-20</td>
</tr>
<tr>
<td class="org-right">1.0061</td>
<td class="org-right">-1.0288e-14</td>
<td class="org-right">2.1354e-14</td>
<td class="org-right">-1.7844e-14</td>
<td class="org-right">1.0085</td>
<td class="org-right">0.032102</td>
</tr>
<tr>
<td class="org-right">0.0048048</td>
<td class="org-right">-3.1201e-14</td>
<td class="org-right">-6.5769e-19</td>
<td class="org-right">-2.5589e-14</td>
<td class="org-right">0.002899</td>
<td class="org-right">1.005</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div id="outline-container-org2fc54dd" class="outline-2">
<h2 id="org2fc54dd"><span class="section-number-2">2</span> Active Damping using Integral Force Feedback</h2>
<div class="outline-text-2" id="text-2">
<p>
<a id="orge63ed81"></a>
</p>
<p>
In this section <b>Integral Force Feedback</b> (IFF) strategy is used to damp the nano-hexapod resonances.
</p>
<p>
It is structured as follows:
</p>
<ul class="org-ul">
<li>Section <a href="#orge3d108b">2.1</a>: the IFF plant is identified</li>
<li>Section <a href="#orgd1d36e0">2.2</a>: the optimal control gain is identified using the Root Locus plot</li>
<li>Section <a href="#org0a3be79">2.3</a>: the IFF is applied, and the effect on the damped plant is identified and compared with the un-damped one</li>
<li>Section <a href="#orgd966765">2.4</a>: the IFF is applied, and the effect on the compliance is identified</li>
</ul>
</div>
<div id="outline-container-org9b12068" class="outline-3">
<h3 id="org9b12068"><span class="section-number-3">2.1</span> Plant Identification</h3>
<div class="outline-text-3" id="text-2-1">
<p>
<a id="orge3d108b"></a>
</p>
<p>
The nano-hexapod is initialized as usual.
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'struts'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>);
</pre>
</div>
<p>
The transfer function from actuator inputs to force sensors outputs is identified.
</p>
<div class="org-src-container">
<pre class="src src-matlab"><span class="org-matlab-cellbreak"><span class="org-comment">%% Input/Output definition</span></span>
clear io; io_i = 1;
io(io_i) = linio([mdl, <span class="org-string">'/F'</span>], 1, <span class="org-string">'openinput'</span>); io_i = io_i <span class="org-type">+</span> 1; <span class="org-comment">% Actuator Inputs</span>
io(io_i) = linio([mdl, <span class="org-string">'/Fm'</span>], 1, <span class="org-string">'openoutput'</span>); io_i = io_i <span class="org-type">+</span> 1; <span class="org-comment">% Force Sensors</span>
Giff = linearize(mdl, io, 0.0, options);
Giff.InputName = {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>};
Giff.OutputName = {<span class="org-string">'Fm1'</span>, <span class="org-string">'Fm2'</span>, <span class="org-string">'Fm3'</span>, <span class="org-string">'Fm4'</span>, <span class="org-string">'Fm5'</span>, <span class="org-string">'Fm6'</span>};
</pre>
</div>
<p>
Its bode plot is shown in Figure
</p>
<div id="org00136be" class="figure">
<p><img src="figs/nano_hexapod_iff_plant_bode_plot.png" alt="nano_hexapod_iff_plant_bode_plot.png" />
</p>
<p><span class="figure-number">Figure 19: </span>Integral Force Feedback plant</p>
</div>
</div>
</div>
<div id="outline-container-org174c317" class="outline-3">
<h3 id="org174c317"><span class="section-number-3">2.2</span> Root Locus</h3>
<div class="outline-text-3" id="text-2-2">
<p>
<a id="orgd1d36e0"></a>
</p>
<p>
The controller is a diagonal (i.e. decentralized) controller with simple low pass filters (i.e. pseudo integrators) on the diagonal:
</p>
\begin{equation}
K_{\text{IFF}} = \frac{g}{s + \omega_c} \bm{I}_{6 \times 6}
\end{equation}
<p>
The value of \(\omega_c\) has quite a large impact both on the attainable damping and on the compliance degradation at low frequency.
</p>
<p>
It is here chosen to have quite a large \(\omega_c\) in order to not modify the plant at low frequency.
</p>
<div class="org-src-container">
<pre class="src src-matlab">wc = 2<span class="org-type">*</span><span class="org-constant">pi</span><span class="org-type">*</span>20;
</pre>
</div>
<p>
The obtained Root Locus is shown in Figure <a href="#org9be0d42">20</a>.
The control gain chosen for future plots is shown by the red crosses.
</p>
<div id="org9be0d42" class="figure">
<p><img src="figs/nano_hexapod_iff_root_locus.png" alt="nano_hexapod_iff_root_locus.png" />
</p>
<p><span class="figure-number">Figure 20: </span>Root locus for the decentralized IFF control strategy</p>
</div>
<p>
The obtained controller is then:
</p>
<div class="org-src-container">
<pre class="src src-matlab">Kiff = 1.5e4<span class="org-type">/</span>(s <span class="org-type">+</span> 2<span class="org-type">*</span><span class="org-constant">pi</span><span class="org-type">*</span>20)<span class="org-type">*</span>eye(6); <span class="org-comment">% IFF Controller</span>
</pre>
</div>
<p>
The corresponding loop gain of the diagonal terms are shown in Figure <a href="#org1a85ae7">21</a>.
It is shown that the loop gain is quite large around resonances (which allows to add lots of damping) and less than one at low frequency thanks to the large value of \(\omega_c\).
</p>
<div id="org1a85ae7" class="figure">
<p><img src="figs/nano_hexapod_iff_loop_gain.png" alt="nano_hexapod_iff_loop_gain.png" />
</p>
<p><span class="figure-number">Figure 21: </span>Loop gain of the diagonal terms \(G(i,i) \cdot K_{\text{IFF}}(i,i)\)</p>
</div>
</div>
</div>
<div id="outline-container-org78de4b8" class="outline-3">
<h3 id="org78de4b8"><span class="section-number-3">2.3</span> Effect of IFF on the plant</h3>
<div class="outline-text-3" id="text-2-3">
<p>
<a id="org0a3be79"></a>
</p>
<p>
Let&rsquo;s now see how the IFF control strategy effectively damps the plant and how it affects the transfer functions from the actuator forces to the relative motion sensors (encoders).
First identify the plant in open-loop.
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'3dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'struts'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>, ...
<span class="org-string">'controller_type'</span>, <span class="org-string">'none'</span>);
Gol = linearize(mdl, io, 0.0, options);
Gol.InputName = {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>};
Gol.OutputName = {<span class="org-string">'D1'</span>, <span class="org-string">'D2'</span>, <span class="org-string">'D3'</span>, <span class="org-string">'D4'</span>, <span class="org-string">'D5'</span>, <span class="org-string">'D6'</span>};
</pre>
</div>
<p>
And then with the IFF controller.
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'3dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'struts'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>, ...
<span class="org-string">'controller_type'</span>, <span class="org-string">'iff'</span>);
Giff = linearize(mdl, io, 0.0, options);
Giff.InputName = {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>};
Giff.OutputName = {<span class="org-string">'D1'</span>, <span class="org-string">'D2'</span>, <span class="org-string">'D3'</span>, <span class="org-string">'D4'</span>, <span class="org-string">'D5'</span>, <span class="org-string">'D6'</span>};
</pre>
</div>
<p>
The obtained plants are compared in Figure <a href="#org533526b">22</a>.
</p>
<div id="org533526b" class="figure">
<p><img src="figs/nano_hexapod_effect_iff_plant.png" alt="nano_hexapod_effect_iff_plant.png" />
</p>
<p><span class="figure-number">Figure 22: </span>Bode plots of the transfer functions from actuator forces \(\tau_i\) to relative motion sensors \(\mathcal{L}_i\) with and without the IFF controller.</p>
</div>
<div class="important" id="org76cb80b">
<p>
The Integral Force Feedback Strategy is very effective to damp the 6 suspension modes of the nano-hexapod.
</p>
</div>
</div>
</div>
<div id="outline-container-org8db31cb" class="outline-3">
<h3 id="org8db31cb"><span class="section-number-3">2.4</span> Effect of IFF on the compliance</h3>
<div class="outline-text-3" id="text-2-4">
<p>
<a id="orgd966765"></a>
</p>
<p>
The IFF strategy has the well known drawback of degrading the compliance (transfer function from external forces/torques applied to the top platform to the motion of the top platform), especially at low frequency where the control gain is large.
Let&rsquo;s quantify that for the nano-hexapod.
The obtained compliances are compared in Figure
</p>
<div id="org1b1b668" class="figure">
<p><img src="figs/nano_hexapod_iff_compare_compliance.png" alt="nano_hexapod_iff_compare_compliance.png" />
</p>
<p><span class="figure-number">Figure 23: </span>Comparison of the compliances in Open Loop and with Integral Force Feedback controller</p>
</div>
<div class="important" id="orge799d29">
<p>
The use of IFF induces a degradation of the compliance.
This degradation is limited due to the use of a pseudo integrator (instead of a pure integrator).
Also, it should not be a major problem for the NASS, as no direct forces should be applied to the top platform.
</p>
</div>
</div>
</div>
</div>
<div id="outline-container-org605df2e" class="outline-2">
<h2 id="org605df2e"><span class="section-number-2">3</span> Active Damping using Direct Velocity Feedback - Encoders on the struts</h2>
<div class="outline-text-2" id="text-3">
<p>
<a id="orgdbb1c33"></a>
</p>
<p>
In this section, the <b>Direct Velocity Feedback</b> (DVF) strategy is used to damp the nano-hexapod resonances.
</p>
<p>
It is structured as follows:
</p>
<ul class="org-ul">
<li>Section <a href="#orgc54bc4f">3.1</a>: the DVF plant is identified</li>
<li>Section <a href="#org87793e7">3.2</a>: the optimal control gain is identified using the Root Locus plot</li>
<li>Section <a href="#org3da8521">3.3</a>: the DVF is applied, and the effect on the damped plant is identified and compared with the un-damped one</li>
<li>Section <a href="#org149779e">3.4</a>: the DVF is applied, and the effect on the compliance is identified</li>
</ul>
</div>
<div id="outline-container-org2776d31" class="outline-3">
<h3 id="org2776d31"><span class="section-number-3">3.1</span> Plant Identification</h3>
<div class="outline-text-3" id="text-3-1">
<p>
<a id="orgc54bc4f"></a>
</p>
<p>
The nano-hexapod is initialized as usual.
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'struts'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>);
</pre>
</div>
<p>
The transfer function from actuator inputs to force sensors outputs is identified.
</p>
<div class="org-src-container">
<pre class="src src-matlab"><span class="org-matlab-cellbreak"><span class="org-comment">%% Input/Output definition</span></span>
clear io; io_i = 1;
io(io_i) = linio([mdl, <span class="org-string">'/F'</span>], 1, <span class="org-string">'openinput'</span>); io_i = io_i <span class="org-type">+</span> 1; <span class="org-comment">% Actuator Inputs</span>
io(io_i) = linio([mdl, <span class="org-string">'/D'</span>], 1, <span class="org-string">'openoutput'</span>); io_i = io_i <span class="org-type">+</span> 1; <span class="org-comment">% Relative Motion Outputs</span>
Gdvf = linearize(mdl, io, 0.0, options);
Gdvf.InputName = {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>};
Gdvf.OutputName = {<span class="org-string">'D1'</span>, <span class="org-string">'D2'</span>, <span class="org-string">'D3'</span>, <span class="org-string">'D4'</span>, <span class="org-string">'D5'</span>, <span class="org-string">'D6'</span>};
</pre>
</div>
<p>
Its bode plot is shown in Figure <a href="#orgd1aee5f">24</a>.
</p>
<div id="orgd1aee5f" class="figure">
<p><img src="figs/nano_hexapod_dvf_plant_bode_plot_struts.png" alt="nano_hexapod_dvf_plant_bode_plot_struts.png" />
</p>
<p><span class="figure-number">Figure 24: </span>Direct Velocity Feedback plant</p>
</div>
</div>
</div>
<div id="outline-container-org452cf4e" class="outline-3">
<h3 id="org452cf4e"><span class="section-number-3">3.2</span> Root Locus</h3>
<div class="outline-text-3" id="text-3-2">
<p>
<a id="org87793e7"></a>
</p>
<p>
The controller is a diagonal (i.e. decentralized) controller with simple high pass filters (i.e. pseudo derivators) on the diagonal:
</p>
\begin{equation}
K_{\text{DVF}} = g \frac{s}{s + \omega_d} \bm{I}_{6 \times 6}
\end{equation}
<p>
The value of \(\omega_d\) sets the frequency above high the derivative action is stopped.
</p>
<div class="org-src-container">
<pre class="src src-matlab">wd = 2<span class="org-type">*</span><span class="org-constant">pi</span><span class="org-type">*</span>150;
</pre>
</div>
<p>
The obtained Root Locus is shown in Figure <a href="#org35252b3">25</a>.
The control gain chosen for future plots is shown by the red crosses.
</p>
<div id="org35252b3" class="figure">
<p><img src="figs/nano_hexapod_dvf_root_locus_struts.png" alt="nano_hexapod_dvf_root_locus_struts.png" />
</p>
<p><span class="figure-number">Figure 25: </span>Root locus for the decentralized DVF control strategy</p>
</div>
<p>
The obtained controller is then:
</p>
<div class="org-src-container">
<pre class="src src-matlab">Kdvf = 5e8<span class="org-type">*</span>s<span class="org-type">/</span>(s <span class="org-type">+</span> wd)<span class="org-type">*</span>eye(6); <span class="org-comment">% DVF Controller</span>
</pre>
</div>
<p>
The corresponding loop gain of the diagonal terms are shown in Figure <a href="#orgb793b05">26</a>.
It is shown that the loop gain is quite large around resonances (which allows to add lots of damping) and less than one at low frequency thanks to the large value of \(\omega_c\).
</p>
<div id="orgb793b05" class="figure">
<p><img src="figs/nano_hexapod_dvf_loop_gain_struts.png" alt="nano_hexapod_dvf_loop_gain_struts.png" />
</p>
<p><span class="figure-number">Figure 26: </span>Loop gain of the diagonal terms \(G(i,i) \cdot K_{\text{DVF}}(i,i)\)</p>
</div>
</div>
</div>
<div id="outline-container-org059c247" class="outline-3">
<h3 id="org059c247"><span class="section-number-3">3.3</span> Effect of DVF on the plant</h3>
<div class="outline-text-3" id="text-3-3">
<p>
<a id="org3da8521"></a>
</p>
<p>
Let&rsquo;s now see how the DVF control strategy effectively damps the plant and how it affects the transfer functions from the actuator forces to the relative motion sensors (encoders).
First identify the plant in open-loop.
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'struts'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>, ...
<span class="org-string">'controller_type'</span>, <span class="org-string">'none'</span>);
Gol = linearize(mdl, io, 0.0, options);
Gol.InputName = {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>};
Gol.OutputName = {<span class="org-string">'D1'</span>, <span class="org-string">'D2'</span>, <span class="org-string">'D3'</span>, <span class="org-string">'D4'</span>, <span class="org-string">'D5'</span>, <span class="org-string">'D6'</span>};
</pre>
</div>
<p>
And then with the DVF controller.
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'struts'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>, ...
<span class="org-string">'controller_type'</span>, <span class="org-string">'dvf'</span>);
Gdvf = linearize(mdl, io, 0.0, options);
Gdvf.InputName = {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>};
Gdvf.OutputName = {<span class="org-string">'D1'</span>, <span class="org-string">'D2'</span>, <span class="org-string">'D3'</span>, <span class="org-string">'D4'</span>, <span class="org-string">'D5'</span>, <span class="org-string">'D6'</span>};
</pre>
</div>
<p>
The obtained plants are compared in Figure <a href="#orgefe8cee">27</a>.
</p>
<div id="orgefe8cee" class="figure">
<p><img src="figs/nano_hexapod_effect_dvf_plant_struts.png" alt="nano_hexapod_effect_dvf_plant_struts.png" />
</p>
<p><span class="figure-number">Figure 27: </span>Bode plots of the transfer functions from actuator forces \(\tau_i\) to relative motion sensors \(\mathcal{L}_i\) with and without the DVF controller.</p>
</div>
<div class="important" id="orga37e758">
<p>
The Direct Velocity Feedback Strategy is very effective to damp the 6 suspension modes of the nano-hexapod.
</p>
</div>
</div>
</div>
<div id="outline-container-org1627645" class="outline-3">
<h3 id="org1627645"><span class="section-number-3">3.4</span> Effect of DVF on the compliance</h3>
<div class="outline-text-3" id="text-3-4">
<p>
<a id="org149779e"></a>
</p>
<p>
The DVF strategy has the well known drawback of degrading the compliance (transfer function from external forces/torques applied to the top platform to the motion of the top platform), especially at low frequency where the control gain is large.
Let&rsquo;s quantify that for the nano-hexapod.
The obtained compliances are compared in Figure <a href="#orge66651f">28</a>.
</p>
<div id="orge66651f" class="figure">
<p><img src="figs/nano_hexapod_dvf_compare_compliance_struts.png" alt="nano_hexapod_dvf_compare_compliance_struts.png" />
</p>
<p><span class="figure-number">Figure 28: </span>Comparison of the compliances in Open Loop and with Direct Velocity Feedback controller</p>
</div>
</div>
</div>
</div>
<div id="outline-container-orgac5a0fc" class="outline-2">
<h2 id="orgac5a0fc"><span class="section-number-2">4</span> Active Damping using Direct Velocity Feedback - Encoders on the plates</h2>
<div class="outline-text-2" id="text-4">
<p>
<a id="org19f552a"></a>
</p>
<p>
In this section, the <b>Direct Velocity Feedback</b> (DVF) strategy is used to damp the nano-hexapod resonances.
</p>
<p>
It is structured as follows:
</p>
<ul class="org-ul">
<li>Section <a href="#orgd60528b">4.1</a>: the DVF plant is identified</li>
<li>Section <a href="#org7a12ece">4.2</a>: the optimal control gain is identified using the Root Locus plot</li>
<li>Section <a href="#orgd28d5bd">4.3</a>: the DVF is applied, and the effect on the damped plant is identified and compared with the un-damped one</li>
<li>Section <a href="#org23d3f72">4.4</a>: the DVF is applied, and the effect on the compliance is identified</li>
</ul>
</div>
<div id="outline-container-org8a655d0" class="outline-3">
<h3 id="org8a655d0"><span class="section-number-3">4.1</span> Plant Identification</h3>
<div class="outline-text-3" id="text-4-1">
<p>
<a id="orgd60528b"></a>
</p>
<p>
The nano-hexapod is initialized as usual.
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'plates'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>);
</pre>
</div>
<p>
The transfer function from actuator inputs to force sensors outputs is identified.
</p>
<div class="org-src-container">
<pre class="src src-matlab"><span class="org-matlab-cellbreak"><span class="org-comment">%% Input/Output definition</span></span>
clear io; io_i = 1;
io(io_i) = linio([mdl, <span class="org-string">'/F'</span>], 1, <span class="org-string">'openinput'</span>); io_i = io_i <span class="org-type">+</span> 1; <span class="org-comment">% Actuator Inputs</span>
io(io_i) = linio([mdl, <span class="org-string">'/D'</span>], 1, <span class="org-string">'openoutput'</span>); io_i = io_i <span class="org-type">+</span> 1; <span class="org-comment">% Relative Motion Outputs</span>
Gdvf = linearize(mdl, io, 0.0, options);
Gdvf.InputName = {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>};
Gdvf.OutputName = {<span class="org-string">'D1'</span>, <span class="org-string">'D2'</span>, <span class="org-string">'D3'</span>, <span class="org-string">'D4'</span>, <span class="org-string">'D5'</span>, <span class="org-string">'D6'</span>};
</pre>
</div>
<p>
Its bode plot is shown in Figure <a href="#orgc7b14d5">29</a>.
</p>
<div id="orgc7b14d5" class="figure">
<p><img src="figs/nano_hexapod_dvf_plant_bode_plot_plates.png" alt="nano_hexapod_dvf_plant_bode_plot_plates.png" />
</p>
<p><span class="figure-number">Figure 29: </span>Direct Velocity Feedback plant</p>
</div>
</div>
</div>
<div id="outline-container-orgb09a05b" class="outline-3">
<h3 id="orgb09a05b"><span class="section-number-3">4.2</span> Root Locus</h3>
<div class="outline-text-3" id="text-4-2">
<p>
<a id="org7a12ece"></a>
</p>
<p>
The controller is a diagonal (i.e. decentralized) controller with simple high pass filters (i.e. pseudo derivators) on the diagonal:
</p>
\begin{equation}
K_{\text{DVF}} = g \frac{s}{s + \omega_d} \bm{I}_{6 \times 6}
\end{equation}
<p>
The value of \(\omega_d\) sets the frequency above high the derivative action is stopped.
</p>
<div class="org-src-container">
<pre class="src src-matlab">wd = 2<span class="org-type">*</span><span class="org-constant">pi</span><span class="org-type">*</span>150;
</pre>
</div>
<p>
The obtained Root Locus is shown in Figure <a href="#org4c5834a">30</a>.
The control gain chosen for future plots is shown by the red crosses.
</p>
<div id="org4c5834a" class="figure">
<p><img src="figs/nano_hexapod_dvf_root_locus_plates.png" alt="nano_hexapod_dvf_root_locus_plates.png" />
</p>
<p><span class="figure-number">Figure 30: </span>Root locus for the decentralized DVF control strategy</p>
</div>
<p>
The obtained controller is then:
</p>
<div class="org-src-container">
<pre class="src src-matlab">Kdvf = 2e8<span class="org-type">*</span>s<span class="org-type">/</span>(s <span class="org-type">+</span> wd)<span class="org-type">*</span>eye(6); <span class="org-comment">% DVF Controller</span>
</pre>
</div>
<p>
The corresponding loop gain of the diagonal terms are shown in Figure <a href="#orgfb70997">31</a>.
It is shown that the loop gain is quite large around resonances (which allows to add lots of damping).
</p>
<div id="orgfb70997" class="figure">
<p><img src="figs/nano_hexapod_dvf_loop_gain_plates.png" alt="nano_hexapod_dvf_loop_gain_plates.png" />
</p>
<p><span class="figure-number">Figure 31: </span>Loop gain of the diagonal terms \(G(i,i) \cdot K_{\text{DVF}}(i,i)\)</p>
</div>
</div>
</div>
<div id="outline-container-orgc0b7c71" class="outline-3">
<h3 id="orgc0b7c71"><span class="section-number-3">4.3</span> Effect of DVF on the plant</h3>
<div class="outline-text-3" id="text-4-3">
<p>
<a id="orgd28d5bd"></a>
</p>
<p>
Let&rsquo;s now see how the DVF control strategy effectively damps the plant and how it affects the transfer functions from the actuator forces to the relative motion sensors (encoders).
First identify the plant in open-loop.
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'plates'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>, ...
<span class="org-string">'controller_type'</span>, <span class="org-string">'none'</span>);
Gol = linearize(mdl, io, 0.0, options);
Gol.InputName = {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>};
Gol.OutputName = {<span class="org-string">'D1'</span>, <span class="org-string">'D2'</span>, <span class="org-string">'D3'</span>, <span class="org-string">'D4'</span>, <span class="org-string">'D5'</span>, <span class="org-string">'D6'</span>};
</pre>
</div>
<p>
And then with the DVF controller.
</p>
<div class="org-src-container">
<pre class="src src-matlab">n_hexapod = initializeNanoHexapodFinal(<span class="org-string">'flex_bot_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'flex_top_type'</span>, <span class="org-string">'4dof'</span>, ...
<span class="org-string">'motion_sensor_type'</span>, <span class="org-string">'plates'</span>, ...
<span class="org-string">'actuator_type'</span>, <span class="org-string">'2dof'</span>, ...
<span class="org-string">'controller_type'</span>, <span class="org-string">'dvf'</span>);
Gdvf = linearize(mdl, io, 0.0, options);
Gdvf.InputName = {<span class="org-string">'F1'</span>, <span class="org-string">'F2'</span>, <span class="org-string">'F3'</span>, <span class="org-string">'F4'</span>, <span class="org-string">'F5'</span>, <span class="org-string">'F6'</span>};
Gdvf.OutputName = {<span class="org-string">'D1'</span>, <span class="org-string">'D2'</span>, <span class="org-string">'D3'</span>, <span class="org-string">'D4'</span>, <span class="org-string">'D5'</span>, <span class="org-string">'D6'</span>};
</pre>
</div>
<p>
The obtained plants are compared in Figure <a href="#org2b1e854">32</a>.
</p>
<div id="org2b1e854" class="figure">
<p><img src="figs/nano_hexapod_effect_dvf_plant_plates.png" alt="nano_hexapod_effect_dvf_plant_plates.png" />
</p>
<p><span class="figure-number">Figure 32: </span>Bode plots of the transfer functions from actuator forces \(\tau_i\) to relative motion sensors \(\mathcal{L}_i\) with and without the DVF controller.</p>
</div>
<div class="important" id="org331e7e2">
<p>
The Direct Velocity Feedback Strategy is very effective in damping the 6 suspension modes of the nano-hexapod.
</p>
</div>
</div>
</div>
<div id="outline-container-org221db88" class="outline-3">
<h3 id="org221db88"><span class="section-number-3">4.4</span> Effect of DVF on the compliance</h3>
<div class="outline-text-3" id="text-4-4">
<p>
<a id="org23d3f72"></a>
</p>
<p>
The DVF strategy has the well known drawback of degrading the compliance (transfer function from external forces/torques applied to the top platform to the motion of the top platform), especially at low frequency where the control gain is large.
Let&rsquo;s quantify that for the nano-hexapod.
The obtained compliances are compared in Figure <a href="#org4403cf5">33</a>.
</p>
<div id="org4403cf5" class="figure">
<p><img src="figs/nano_hexapod_dvf_compare_compliance_plates.png" alt="nano_hexapod_dvf_compare_compliance_plates.png" />
</p>
<p><span class="figure-number">Figure 33: </span>Comparison of the compliances in Open Loop and with Direct Velocity Feedback controller</p>
</div>
</div>
</div>
</div>
<div id="outline-container-org8862f6b" class="outline-2">
<h2 id="org8862f6b"><span class="section-number-2">5</span> Function - Initialize Nano Hexapod</h2>
<div class="outline-text-2" id="text-5">
<p>
<a id="orga13249f"></a>
</p>
</div>
<div id="outline-container-org438f7d8" class="outline-3">
<h3 id="org438f7d8">Function description</h3>
<div class="outline-text-3" id="text-org438f7d8">
<div class="org-src-container">
<pre class="src src-matlab"><span class="org-keyword">function</span> <span class="org-variable-name">[nano_hexapod]</span> = <span class="org-function-name">initializeNanoHexapodFinal</span>(<span class="org-variable-name">args</span>)
</pre>
</div>
</div>
</div>
<div id="outline-container-org49bef56" class="outline-3">
<h3 id="org49bef56">Optional Parameters</h3>
<div class="outline-text-3" id="text-org49bef56">
<div class="org-src-container">
<pre class="src src-matlab"><span class="org-keyword">arguments</span>
<span class="org-matlab-cellbreak"><span class="org-comment">%% Bottom Flexible Joints</span></span>
<span class="org-variable-name">args</span>.flex_bot_type char {mustBeMember(args.flex_bot_type,{<span class="org-string">'2dof'</span>, <span class="org-string">'3dof'</span>, <span class="org-string">'4dof'</span>, <span class="org-string">'flexible'</span>})} = <span class="org-string">'4dof'</span>
<span class="org-variable-name">args</span>.flex_bot_kRx (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>5 <span class="org-comment">% X bending stiffness [Nm/rad]</span>
<span class="org-variable-name">args</span>.flex_bot_kRy (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>5 <span class="org-comment">% Y bending stiffness [Nm/rad]</span>
<span class="org-variable-name">args</span>.flex_bot_kRz (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>260 <span class="org-comment">% Torsionnal stiffness [Nm/rad]</span>
<span class="org-variable-name">args</span>.flex_bot_kz (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>1e8 <span class="org-comment">% Axial Stiffness [N/m]</span>
<span class="org-variable-name">args</span>.flex_bot_cRx (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>0.1 <span class="org-comment">% X bending Damping [Nm/(rad/s)]</span>
<span class="org-variable-name">args</span>.flex_bot_cRy (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>0.1 <span class="org-comment">% Y bending Damping [Nm/(rad/s)]</span>
<span class="org-variable-name">args</span>.flex_bot_cRz (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>0.1 <span class="org-comment">% Torsionnal Damping [Nm/(rad/s)]</span>
<span class="org-variable-name">args</span>.flex_bot_cz (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>1e2 <span class="org-comment">% Axial Damping [N/(m/s)]</span>
<span class="org-matlab-cellbreak"><span class="org-comment">%% Top Flexible Joints</span></span>
<span class="org-variable-name">args</span>.flex_top_type char {mustBeMember(args.flex_top_type,{<span class="org-string">'2dof'</span>, <span class="org-string">'3dof'</span>, <span class="org-string">'4dof'</span>, <span class="org-string">'flexible'</span>})} = <span class="org-string">'4dof'</span>
<span class="org-variable-name">args</span>.flex_top_kRx (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>5 <span class="org-comment">% X bending stiffness [Nm/rad]</span>
<span class="org-variable-name">args</span>.flex_top_kRy (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>5 <span class="org-comment">% Y bending stiffness [Nm/rad]</span>
<span class="org-variable-name">args</span>.flex_top_kRz (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>260 <span class="org-comment">% Torsionnal stiffness [Nm/rad]</span>
<span class="org-variable-name">args</span>.flex_top_kz (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>1e8 <span class="org-comment">% Axial Stiffness [N/m]</span>
<span class="org-variable-name">args</span>.flex_top_cRx (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>0.1 <span class="org-comment">% X bending Damping [Nm/(rad/s)]</span>
<span class="org-variable-name">args</span>.flex_top_cRy (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>0.1 <span class="org-comment">% Y bending Damping [Nm/(rad/s)]</span>
<span class="org-variable-name">args</span>.flex_top_cRz (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>0.1 <span class="org-comment">% Torsionnal Damping [Nm/(rad/s)]</span>
<span class="org-variable-name">args</span>.flex_top_cz (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>1e2 <span class="org-comment">% Axial Damping [N/(m/s)]</span>
<span class="org-matlab-cellbreak"><span class="org-comment">%% Jacobian - Location of frame {A} and {B}</span></span>
<span class="org-variable-name">args</span>.MO_B (1,1) double {mustBeNumeric} = 150e<span class="org-type">-</span>3 <span class="org-comment">% Height of {B} w.r.t. {M} [m]</span>
<span class="org-matlab-cellbreak"><span class="org-comment">%% Relative Motion Sensor</span></span>
<span class="org-variable-name">args</span>.motion_sensor_type char {mustBeMember(args.motion_sensor_type,{<span class="org-string">'struts'</span>, <span class="org-string">'plates'</span>})} = <span class="org-string">'struts'</span>
<span class="org-matlab-cellbreak"><span class="org-comment">%% Actuators</span></span>
<span class="org-variable-name">args</span>.actuator_type char {mustBeMember(args.actuator_type,{<span class="org-string">'2dof'</span>, <span class="org-string">'flexible frame'</span>, <span class="org-string">'flexible'</span>})} = <span class="org-string">'flexible'</span>
<span class="org-variable-name">args</span>.actuator_Ga (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>1 <span class="org-comment">% Actuator gain [N/V]</span>
<span class="org-variable-name">args</span>.actuator_Gs (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>1 <span class="org-comment">% Sensor gain [V/m]</span>
<span class="org-comment">% For 2DoF</span>
<span class="org-variable-name">args</span>.actuator_k (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>0.35e6 <span class="org-comment">% [N/m]</span>
<span class="org-variable-name">args</span>.actuator_ke (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>1.5e6 <span class="org-comment">% [N/m]</span>
<span class="org-variable-name">args</span>.actuator_ka (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>43e6 <span class="org-comment">% [N/m]</span>
<span class="org-variable-name">args</span>.actuator_c (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>3e1 <span class="org-comment">% [N/(m/s)]</span>
<span class="org-variable-name">args</span>.actuator_ce (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>1e1 <span class="org-comment">% [N/(m/s)]</span>
<span class="org-variable-name">args</span>.actuator_ca (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>1e1 <span class="org-comment">% [N/(m/s)]</span>
<span class="org-variable-name">args</span>.actuator_Leq (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>0.056 <span class="org-comment">% [m]</span>
<span class="org-comment">% For Flexible Frame</span>
<span class="org-variable-name">args</span>.actuator_ks (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>235e6 <span class="org-comment">% Stiffness of one stack [N/m]</span>
<span class="org-variable-name">args</span>.actuator_cs (6,1) double {mustBeNumeric} = ones(6,1)<span class="org-type">*</span>1e1 <span class="org-comment">% Stiffness of one stack [N/m]</span>
<span class="org-variable-name">args</span>.actuator_xi (1,1) double {mustBeNumeric} = 0.01 <span class="org-comment">% Damping Ratio</span>
<span class="org-matlab-cellbreak"><span class="org-comment">%% Controller</span></span>
<span class="org-variable-name">args</span>.controller_type char {mustBeMember(args.controller_type,{<span class="org-string">'none'</span>, <span class="org-string">'iff'</span>, <span class="org-string">'dvf'</span>})} = <span class="org-string">'none'</span>
<span class="org-keyword">end</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-org33f6631" class="outline-3">
<h3 id="org33f6631">Nano Hexapod Object</h3>
<div class="outline-text-3" id="text-org33f6631">
<div class="org-src-container">
<pre class="src src-matlab">nano_hexapod = struct();
</pre>
</div>
</div>
</div>
<div id="outline-container-orgdc3de74" class="outline-3">
<h3 id="orgdc3de74">Flexible Joints - Bot</h3>
<div class="outline-text-3" id="text-orgdc3de74">
<div class="org-src-container">
<pre class="src src-matlab">nano_hexapod.flex_bot = struct();
<span class="org-keyword">switch</span> <span class="org-constant">args.flex_bot_type</span>
<span class="org-keyword">case</span> <span class="org-string">'2dof'</span>
nano_hexapod.flex_bot.type = 1;
<span class="org-keyword">case</span> <span class="org-string">'3dof'</span>
nano_hexapod.flex_bot.type = 2;
<span class="org-keyword">case</span> <span class="org-string">'4dof'</span>
nano_hexapod.flex_bot.type = 3;
<span class="org-keyword">case</span> <span class="org-string">'flexible'</span>
nano_hexapod.flex_bot.type = 4;
<span class="org-keyword">end</span>
nano_hexapod.flex_bot.kRx = args.flex_bot_kRx; <span class="org-comment">% X bending stiffness [Nm/rad]</span>
nano_hexapod.flex_bot.kRy = args.flex_bot_kRy; <span class="org-comment">% Y bending stiffness [Nm/rad]</span>
nano_hexapod.flex_bot.kRz = args.flex_bot_kRz; <span class="org-comment">% Torsionnal stiffness [Nm/rad]</span>
nano_hexapod.flex_bot.kz = args.flex_bot_kz; <span class="org-comment">% Axial stiffness [N/m]</span>
nano_hexapod.flex_bot.cRx = args.flex_bot_cRx; <span class="org-comment">% [Nm/(rad/s)]</span>
nano_hexapod.flex_bot.cRy = args.flex_bot_cRy; <span class="org-comment">% [Nm/(rad/s)]</span>
nano_hexapod.flex_bot.cRz = args.flex_bot_cRz; <span class="org-comment">% [Nm/(rad/s)]</span>
nano_hexapod.flex_bot.cz = args.flex_bot_cz; <span class="org-comment">%[N/(m/s)]</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-org7d4d003" class="outline-3">
<h3 id="org7d4d003">Flexible Joints - Top</h3>
<div class="outline-text-3" id="text-org7d4d003">
<div class="org-src-container">
<pre class="src src-matlab">nano_hexapod.flex_top = struct();
<span class="org-keyword">switch</span> <span class="org-constant">args.flex_top_type</span>
<span class="org-keyword">case</span> <span class="org-string">'2dof'</span>
nano_hexapod.flex_top.type = 1;
<span class="org-keyword">case</span> <span class="org-string">'3dof'</span>
nano_hexapod.flex_top.type = 2;
<span class="org-keyword">case</span> <span class="org-string">'4dof'</span>
nano_hexapod.flex_top.type = 3;
<span class="org-keyword">case</span> <span class="org-string">'flexible'</span>
nano_hexapod.flex_top.type = 4;
<span class="org-keyword">end</span>
nano_hexapod.flex_top.kRx = args.flex_top_kRx; <span class="org-comment">% X bending stiffness [Nm/rad]</span>
nano_hexapod.flex_top.kRy = args.flex_top_kRy; <span class="org-comment">% Y bending stiffness [Nm/rad]</span>
nano_hexapod.flex_top.kRz = args.flex_top_kRz; <span class="org-comment">% Torsionnal stiffness [Nm/rad]</span>
nano_hexapod.flex_top.kz = args.flex_top_kz; <span class="org-comment">% Axial stiffness [N/m]</span>
nano_hexapod.flex_top.cRx = args.flex_top_cRx; <span class="org-comment">% [Nm/(rad/s)]</span>
nano_hexapod.flex_top.cRy = args.flex_top_cRy; <span class="org-comment">% [Nm/(rad/s)]</span>
nano_hexapod.flex_top.cRz = args.flex_top_cRz; <span class="org-comment">% [Nm/(rad/s)]</span>
nano_hexapod.flex_top.cz = args.flex_top_cz; <span class="org-comment">%[N/(m/s)]</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-org3744992" class="outline-3">
<h3 id="org3744992">Relative Motion Sensor</h3>
<div class="outline-text-3" id="text-org3744992">
<div class="org-src-container">
<pre class="src src-matlab">nano_hexapod.motion_sensor = struct();
<span class="org-keyword">switch</span> <span class="org-constant">args.motion_sensor_type</span>
<span class="org-keyword">case</span> <span class="org-string">'struts'</span>
nano_hexapod.motion_sensor.type = 1;
<span class="org-keyword">case</span> <span class="org-string">'plates'</span>
nano_hexapod.motion_sensor.type = 2;
<span class="org-keyword">end</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-orgdaa740a" class="outline-3">
<h3 id="orgdaa740a">Amplified Piezoelectric Actuator</h3>
<div class="outline-text-3" id="text-orgdaa740a">
<div class="org-src-container">
<pre class="src src-matlab">nano_hexapod.actuator = struct();
<span class="org-keyword">switch</span> <span class="org-constant">args.actuator_type</span>
<span class="org-keyword">case</span> <span class="org-string">'2dof'</span>
nano_hexapod.actuator.type = 1;
<span class="org-keyword">case</span> <span class="org-string">'flexible frame'</span>
nano_hexapod.actuator.type = 2;
<span class="org-keyword">case</span> <span class="org-string">'flexible'</span>
nano_hexapod.actuator.type = 3;
<span class="org-keyword">end</span>
</pre>
</div>
<div class="org-src-container">
<pre class="src src-matlab">nano_hexapod.actuator.Ga = args.actuator_Ga; <span class="org-comment">% Actuator gain [N/V]</span>
nano_hexapod.actuator.Gs = args.actuator_Gs; <span class="org-comment">% Sensor gain [V/m]</span>
</pre>
</div>
<p>
2dof
</p>
<div class="org-src-container">
<pre class="src src-matlab">nano_hexapod.actuator.k = args.actuator_k; <span class="org-comment">% [N/m]</span>
nano_hexapod.actuator.ke = args.actuator_ke; <span class="org-comment">% [N/m]</span>
nano_hexapod.actuator.ka = args.actuator_ka; <span class="org-comment">% [N/m]</span>
nano_hexapod.actuator.c = args.actuator_c; <span class="org-comment">% [N/(m/s)]</span>
nano_hexapod.actuator.ce = args.actuator_ce; <span class="org-comment">% [N/(m/s)]</span>
nano_hexapod.actuator.ca = args.actuator_ca; <span class="org-comment">% [N/(m/s)]</span>
nano_hexapod.actuator.Leq = args.actuator_Leq; <span class="org-comment">% [m]</span>
</pre>
</div>
<p>
Flexible frame and fully flexible
</p>
<div class="org-src-container">
<pre class="src src-matlab"><span class="org-keyword">switch</span> <span class="org-constant">args.actuator_type</span>
<span class="org-keyword">case</span> <span class="org-string">'flexible frame'</span>
nano_hexapod.actuator.K = readmatrix(<span class="org-string">'APA300ML_b_mat_K.CSV'</span>); <span class="org-comment">% Stiffness Matrix</span>
nano_hexapod.actuator.M = readmatrix(<span class="org-string">'APA300ML_b_mat_M.CSV'</span>); <span class="org-comment">% Mass Matrix</span>
nano_hexapod.actuator.P = extractNodes(<span class="org-string">'APA300ML_b_out_nodes_3D.txt'</span>); <span class="org-comment">% Node coordinates [m]</span>
<span class="org-keyword">case</span> <span class="org-string">'flexible'</span>
nano_hexapod.actuator.K = readmatrix(<span class="org-string">'full_APA300ML_K.CSV'</span>); <span class="org-comment">% Stiffness Matrix</span>
nano_hexapod.actuator.M = readmatrix(<span class="org-string">'full_APA300ML_M.CSV'</span>); <span class="org-comment">% Mass Matrix</span>
nano_hexapod.actuator.P = extractNodes(<span class="org-string">'full_APA300ML_out_nodes_3D.txt'</span>); <span class="org-comment">% Node coordiantes [m]</span>
<span class="org-keyword">end</span>
nano_hexapod.actuator.xi = args.actuator_xi; <span class="org-comment">% Damping ratio</span>
nano_hexapod.actuator.ks = args.actuator_ks; <span class="org-comment">% Stiffness of one stack [N/m]</span>
nano_hexapod.actuator.cs = args.actuator_cs; <span class="org-comment">% Damping of one stack [N/m]</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-org8d598c9" class="outline-3">
<h3 id="org8d598c9">Geometry</h3>
<div class="outline-text-3" id="text-org8d598c9">
<div class="org-src-container">
<pre class="src src-matlab">nano_hexapod.geometry = struct();
</pre>
</div>
<p>
Center of joints \(a_i\) with respect to {F}:
</p>
<div class="org-src-container">
<pre class="src src-matlab">Fa = [[<span class="org-type">-</span>86.05, <span class="org-type">-</span>74.78, 22.49],
[ 86.05, <span class="org-type">-</span>74.78, 22.49],
[ 107.79, <span class="org-type">-</span>37.13, 22.49],
[ 21.74, 111.91, 22.49],
[<span class="org-type">-</span>21.74, 111.91, 22.49],
[<span class="org-type">-</span>107.79, <span class="org-type">-</span>37.13, 22.49]]<span class="org-type">'*</span>1e<span class="org-type">-</span>3; <span class="org-comment">% Ai w.r.t. {F} [m]</span>
</pre>
</div>
<p>
Center of joints \(b_i\) with respect to {M}:
</p>
<div class="org-src-container">
<pre class="src src-matlab">Mb = [[<span class="org-type">-</span>28.47, <span class="org-type">-</span>106.25, <span class="org-type">-</span>22.50],
[ 28.47, <span class="org-type">-</span>106.25, <span class="org-type">-</span>22.50],
[ 106.25, 28.47, <span class="org-type">-</span>22.50],
[ 77.78, 77.78, <span class="org-type">-</span>22.50],
[<span class="org-type">-</span>77.78, 77.78, <span class="org-type">-</span>22.50],
[<span class="org-type">-</span>106.25, 28.47, <span class="org-type">-</span>22.50]]<span class="org-type">'*</span>1e<span class="org-type">-</span>3; <span class="org-comment">% Bi w.r.t. {M} [m]</span>
</pre>
</div>
<p>
Now compute the positions \(b_i\) with respect to {F}:
</p>
<div class="org-src-container">
<pre class="src src-matlab">Fb = Mb <span class="org-type">+</span> [0; 0; 95e<span class="org-type">-</span>3]; <span class="org-comment">% Bi w.r.t. {F} [m]</span>
</pre>
</div>
<p>
The unit vector representing the orientation of the struts can then be computed:
</p>
<div class="org-src-container">
<pre class="src src-matlab">si = Fb <span class="org-type">-</span> Fa;
si = si<span class="org-type">./</span>vecnorm(si); <span class="org-comment">% Normalize</span>
</pre>
</div>
<p>
Location of encoder measurement points when fixed on the plates:
</p>
<div class="org-src-container">
<pre class="src src-matlab">Fc = [[<span class="org-type">-</span>29.362, <span class="org-type">-</span>105.765, 52.605]
[ 29.362, <span class="org-type">-</span>105.765, 52.605]
[ 106.276, 27.454, 52.605]
[ 76.914, 78.31, 52.605]
[<span class="org-type">-</span>76.914, 78.31, 52.605]
[<span class="org-type">-</span>106.276, 27.454, 52.605]]<span class="org-type">'*</span>1e<span class="org-type">-</span>3; <span class="org-comment">% Meas pos w.r.t. {F}</span>
Mc = Fc <span class="org-type">-</span> [0; 0; 95e<span class="org-type">-</span>3]; <span class="org-comment">% Meas pos w.r.t. {M}</span>
</pre>
</div>
<div class="org-src-container">
<pre class="src src-matlab">nano_hexapod.geometry.Fa = Fa;
nano_hexapod.geometry.Fb = Fb;
nano_hexapod.geometry.Fc = Fc;
nano_hexapod.geometry.Mb = Mb;
nano_hexapod.geometry.Mc = Mc;
nano_hexapod.geometry.si = si;
nano_hexapod.geometry.MO_B = args.MO_B;
</pre>
</div>
</div>
</div>
<div id="outline-container-org8d741d2" class="outline-3">
<h3 id="org8d741d2">Jacobian for Actuators</h3>
<div class="outline-text-3" id="text-org8d741d2">
<div class="org-src-container">
<pre class="src src-matlab">Bb = Mb <span class="org-type">-</span> [0; 0; args.MO_B];
nano_hexapod.geometry.J = [nano_hexapod.geometry.si<span class="org-type">'</span>, cross(Bb, nano_hexapod.geometry.si)<span class="org-type">'</span>];
</pre>
</div>
</div>
</div>
<div id="outline-container-orgea27820" class="outline-3">
<h3 id="orgea27820">Jacobian for Sensors</h3>
<div class="outline-text-3" id="text-orgea27820">
<div class="org-src-container">
<pre class="src src-matlab"><span class="org-keyword">switch</span> <span class="org-constant">args.motion_sensor_type</span>
<span class="org-keyword">case</span> <span class="org-string">'struts'</span>
nano_hexapod.geometry.Js = nano_hexapod.geometry.J;
<span class="org-keyword">case</span> <span class="org-string">'plates'</span>
Bc = Mc <span class="org-type">-</span> [0; 0; args.MO_B];
nano_hexapod.geometry.Js = [nano_hexapod.geometry.si<span class="org-type">'</span>, cross(Bc, nano_hexapod.geometry.si)<span class="org-type">'</span>];
<span class="org-keyword">end</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-org90b9ac2" class="outline-3">
<h3 id="org90b9ac2">Controller</h3>
<div class="outline-text-3" id="text-org90b9ac2">
<div class="org-src-container">
<pre class="src src-matlab"><span class="org-keyword">switch</span> <span class="org-constant">args.controller_type</span>
<span class="org-keyword">case</span> <span class="org-string">'none'</span>
nano_hexapod.controller.type = 1;
<span class="org-keyword">case</span> <span class="org-string">'iff'</span>
nano_hexapod.controller.type = 2;
<span class="org-keyword">case</span> <span class="org-string">'dvf'</span>
nano_hexapod.controller.type = 3;
<span class="org-keyword">end</span>
</pre>
</div>
</div>
</div>
<div id="outline-container-org8187b3b" class="outline-3">
<h3 id="org8187b3b">Save the Structure</h3>
<div class="outline-text-3" id="text-org8187b3b">
<div class="org-src-container">
<pre class="src src-matlab"><span class="org-keyword">if</span> nargout <span class="org-type">==</span> 0
save(<span class="org-string">'./mat/stages.mat'</span>, <span class="org-string">'nano_hexapod'</span>, <span class="org-string">'-append'</span>);
<span class="org-keyword">end</span>
</pre>
</div>
</div>
</div>
</div>
</div>
<div id="postamble" class="status">
<p class="author">Author: Dehaeze Thomas</p>
<p class="date">Created: 2021-05-06 jeu. 18:10</p>
</div>
</body>
</html>