From 9fb86964efcaad8927ae628191d119e12c22e7d9 Mon Sep 17 00:00:00 2001 From: Thomas Dehaeze Date: Tue, 10 Dec 2019 18:06:33 +0100 Subject: [PATCH] Test of position/orientation of an Hexapod --- kinematics/index.html | 315 +++++++++++++++++++- kinematics/index.org | 156 +++++++++- simscape/hexapod_tests.slx | Bin 0 -> 29520 bytes simscape/index.html | 443 ++++++++++++++++------------ simscape/index.org | 95 ++++-- simscape_subsystems/hexapod_leg.slx | Bin 0 -> 26042 bytes src/initializeMicroHexapod.m | 38 ++- 7 files changed, 819 insertions(+), 228 deletions(-) create mode 100644 simscape/hexapod_tests.slx create mode 100644 simscape_subsystems/hexapod_leg.slx diff --git a/kinematics/index.html b/kinematics/index.html index 0aab43e..752dc31 100644 --- a/kinematics/index.html +++ b/kinematics/index.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Kinematics of the station @@ -246,6 +246,31 @@ for the JavaScript code in this tag. } /*]]>*///--> + +
@@ -254,17 +279,299 @@ for the JavaScript code in this tag. HOME

Kinematics of the station

+ -

-All the files (data and Matlab scripts) are accessible here. +In this document, we discuss the way the motion of each stage is defined.

+
+

1 Micro Hexapod

+
+
+
+

1.1 How the Symetrie Hexapod is controlled on the micro station

+
+

+For the Micro-Hexapod, the convention for the angles are defined in MAN_A_Software API_4.0.150918_EN.pdf on page 13 (section 2.4 - Rotation Vectors): +

+ +
+

+The Euler type II convention is used to express the rotation vector. +This convention is mainly used in the aeronautics field (standard ISO 1151 concerning flight mechanics). +

+ +

+This convention uses the concepts of rotation of vehicles (ship, car and plane). +Generally, we consider that the main movement of the vehicle is following the X-axis and the Z-axis is parallel to the axis of gravity (at the initial position). +The roll rotation is around the X-axis, the pitch is around the Y-axis and yaw is the rotation around the Z-axis. +The order of rotation is: Rx, Ry and then Rz. +

+ +

+In most case, rotations are related to a reference with fixed axis; thus we say the rotations are around fixed axes. +The combination of these three rotations enables to write a rotation matrix. +This writing is unique and equal to: +\[ \bm{R} = \bm{R}_z(\gamma) \cdot \bm{R}_y(\beta) \cdot \bm{R}_x(\alpha) \] +

+ +

+The Euler type II convention corresponding to the succession of rotations with respect to fixed axes: first around X0, then Y0 and Z0. +This is equivalent to the succession of rotations with respect to mobile axes: first around Z0, then Y1' and X2'. +

+
+ +

+More generally on the Control of the Micro-Hexapod: +

+
+

+Note that for all control modes, the rotation center coincides with Object coordinate system origin. +Moreover, the movements are controlled with translation components at first (Tx, Ty, Tz) then rotation components (Rx, Ry, Rz). +

+
+ +

+Thus, it does the translations and then the rotation around the new translated frame. +

+
+
+ +
+

1.2 Control of the Micro-Hexapod using Simscape

+
+

+We can think of two main ways to position the Micro-Hexapod using Simscape. +

+ +

+The first one is to use only one Bushing Joint between the base and the mobile platform. +The advantage is that it is very easy to impose the wanted displacement, however, we loose the dynamical properties of the Hexapod. +

+ +

+The second way is to specify the wanted length of the legs of the Hexapod in order to have the wanted position of the mobile platform. +This require a little bit more of mathematical derivations but this is the chosen solution. +

+
+ +
+

1.2.1 Using Bushing Joint

+
+

+In the documentation of the Bushing Joint (doc "Bushing Joint") that is used to position the Hexapods, it is mention that the following frame is positioned with respect to the base frame in a way shown in figure 1. +

+ + +
+

bushing_joint_transform.png +

+

Figure 1: Joint Transformation Sequence for the Bushing Joint

+
+ +

+Basically, it performs the translations, and then the rotation along the X, Y and Z axis of the moving frame. +The three rotations that we define thus corresponds to the Euler U-V-W angles. +

+ +

+We should have the same behavior for the Micro-Hexapod on Simscape (same inputs at least). +However, the Bushing Joint makes rotations around mobiles axes (X, Y' and then Z'') and not fixed axes (X, Y and Z). +

+
+
+ +
+

1.2.2 Using Inverse Kinematics and Leg Actuators

+
+

+Here, we can use the Inverse Kinematic of the Hexapod to determine the length of each leg in order to obtain some defined translation and rotation of the mobile platform. +

+ +

+The advantages are: +

+
    +
  • we can position the Hexapod as we want by specifying a rotation matrix
  • +
  • the hexapod keeps its full flexibility as we don't specify any wanted displacements, only leg's rest position
  • +
+
+ +
+
1.2.2.1 Theory
+
+

+For inverse kinematic analysis, it is assumed that the position \({}^A\bm{P}\) and orientation of the moving platform \({}^A\bm{R}_B\) are given and the problem is to obtain the joint variables, namely, \(\bm{L} = [l_1, l_2, \dots, l_6]^T\). +

+ +

+From the geometry of the manipulator, the loop closure for each limb, \(i = 1, 2, \dots, 6\) can be written as +

+\begin{align*} + l_i {}^A\hat{\bm{s}}_i &= {}^A\bm{A} + {}^A\bm{b}_i - {}^A\bm{a}_i \\ + &= {}^A\bm{A} + {}^A\bm{R}_b {}^B\bm{b}_i - {}^A\bm{a}_i +\end{align*} + +

+To obtain the length of each actuator and eliminate \(\hat{\bm{s}}_i\), it is sufficient to dot multiply each side by itself: +

+\begin{equation} + l_i^2 \left[ {}^A\hat{\bm{s}}_i^T {}^A\hat{\bm{s}}_i \right] = \left[ {}^A\bm{P} + {}^A\bm{R}_B {}^B\bm{b}_i - {}^A\bm{a}_i \right]^T \left[ {}^A\bm{P} + {}^A\bm{R}_B {}^B\bm{b}_i - {}^A\bm{a}_i \right] +\end{equation} + +

+Hence, for \(i = 1, 2, \dots, 6\), each limb length can be uniquely determined by: +

+\begin{equation} + l_i = \sqrt{{}^A\bm{P}^T {}^A\bm{P} + {}^B\bm{b}_i^T {}^B\bm{b}_i + {}^A\bm{a}_i^T {}^A\bm{a}_i - 2 {}^A\bm{P}^T {}^A\bm{a}_i + 2 {}^A\bm{P}^T \left[{}^A\bm{R}_B {}^B\bm{b}_i\right] - 2 \left[{}^A\bm{R}_B {}^B\bm{b}_i\right]^T {}^A\bm{a}_i} +\end{equation} + +

+If the position and orientation of the moving platform lie in the feasible workspace of the manipulator, one unique solution to the limb length is determined by the above equation. +Otherwise, when the limbs' lengths derived yield complex numbers, then the position or orientation of the moving platform is not reachable. +

+
+
+ +
+
1.2.2.2 Matlab Implementation
+
+
+
open 'simscape/hexapod_tests.slx'
+
+
+ +
+
load('simscape/conf_simscape.mat');
+set_param(conf_simscape, 'StopTime', '0.5');
+
+
+ +
+
tx = 0.1; % [rad]
+ty = 0.2; % [rad]
+tz = 0.05; % [rad]
+
+Rx = [1 0        0;
+      0 cos(tx) -sin(tx);
+      0 sin(tx)  cos(tx)];
+
+Ry = [ cos(ty) 0 sin(ty);
+      0        1 0;
+      -sin(ty) 0 cos(ty)];
+
+Rz = [cos(tz) -sin(tz) 0;
+      sin(tz)  cos(tz) 0;
+      0        0       1];
+
+ARB = Rz*Ry*Rx;
+AP = [0.01; 0.02; 0.03]; % [m]
+
+hexapod = initializeMicroHexapod(struct('AP', AP, 'ARB', ARB));
+
+
+ +
+
sim('simscape/hexapod_tests.slx')
+
+
+ +

+And we verify that we indeed succeed to go to the wanted position. +

+
+
[simout.x.Data(end) ; simout.y.Data(end) ; simout.z.Data(end)] - AP
+
+
+ + + + +++ + + + + + + + + + + + + + +
-2.12e-06
2.9787e-06
-4.4341e-06
+ +
+
simout.R.Data(:, :, end)-ARB
+
+
+ + + + +++ ++ ++ + + + + + + + + + + + + + + + + + + + +
-1.5714e-061.4513e-067.8133e-06
8.4113e-07-7.1485e-07-7.4572e-06
-7.5348e-067.7112e-06-2.3088e-06
+
+
+
+

Author: Dehaeze Thomas

-

Created: 2019-10-08 mar. 11:13

+

Created: 2019-12-10 mar. 18:03

Validate

diff --git a/kinematics/index.org b/kinematics/index.org index 88602ef..0b2f8a8 100644 --- a/kinematics/index.org +++ b/kinematics/index.org @@ -42,23 +42,91 @@ :END: * Introduction :ignore: +In this document, we discuss the way the motion of each stage is defined. -* ZIP file containing the data and matlab files :ignore: -#+begin_src bash :exports none :results none - if [ matlab/kinematics.m -nt data/kinematics.zip ]; then - cp matlab/kinematics.m kinematics.m; - zip data/kinematics \ - mat/data.mat \ - kinematics.m - rm kinematics.m; - fi -#+end_src +* Micro Hexapod +** How the Symetrie Hexapod is controlled on the micro station +For the Micro-Hexapod, the convention for the angles are defined in =MAN_A_Software API_4.0.150918_EN.pdf= on page 13 (section 2.4 - Rotation Vectors): -#+begin_note - All the files (data and Matlab scripts) are accessible [[file:data/kinematics.zip][here]]. -#+end_note +#+begin_quote +The *Euler type II convention* is used to express the rotation vector. +This convention is mainly used in the aeronautics field (standard ISO 1151 concerning flight mechanics). -* Matlab Init :noexport:ignore: +This convention uses the concepts of rotation of vehicles (ship, car and plane). +Generally, we consider that the main movement of the vehicle is following the X-axis and the Z-axis is parallel to the axis of gravity (at the initial position). +The roll rotation is around the X-axis, the pitch is around the Y-axis and yaw is the rotation around the Z-axis. +*The order of rotation is: Rx, Ry and then Rz.* + +In most case, rotations are related to a reference with fixed axis; thus we say the rotations are around fixed axes. +The combination of these three rotations enables to write a rotation matrix. +This writing is unique and equal to: +\[ \bm{R} = \bm{R}_z(\gamma) \cdot \bm{R}_y(\beta) \cdot \bm{R}_x(\alpha) \] + +The Euler type II convention corresponding to the *succession of rotations with respect to fixed axes*: first around X0, then Y0 and Z0. +This is equivalent to the succession of rotations with respect to mobile axes: first around Z0, then Y1' and X2'. +#+end_quote + +More generally on the Control of the Micro-Hexapod: +#+begin_quote +Note that for all control modes, *the rotation center coincides with Object coordinate system origin*. +Moreover, the movements are controlled with *translation components at first* (Tx, Ty, Tz) *then rotation components* (Rx, Ry, Rz). +#+end_quote + +Thus, it does the translations and then the rotation around the new translated frame. + +** Control of the Micro-Hexapod using Simscape +*** Introduction :ignore: +We can think of two main ways to position the Micro-Hexapod using Simscape. + +The first one is to use only one Bushing Joint between the base and the mobile platform. +The advantage is that it is very easy to impose the wanted displacement, however, we loose the dynamical properties of the Hexapod. + +The second way is to specify the wanted length of the legs of the Hexapod in order to have the wanted position of the mobile platform. +This require a little bit more of mathematical derivations but this is the chosen solution. + +*** Using Bushing Joint +In the documentation of the Bushing Joint (=doc "Bushing Joint"=) that is used to position the Hexapods, it is mention that the following frame is positioned with respect to the base frame in a way shown in figure [[fig:bushing_joint_transform]]. + +#+name: fig:bushing_joint_transform +#+caption: Joint Transformation Sequence for the Bushing Joint +[[file:figs/bushing_joint_transform.png]] + +Basically, it performs the translations, and then the rotation along the X, Y and Z axis of the moving frame. +The three rotations that we define thus corresponds to the Euler U-V-W angles. + +We should have the *same behavior* for the Micro-Hexapod on Simscape (same inputs at least). +However, the Bushing Joint makes rotations around mobiles axes (X, Y' and then Z'') and not fixed axes (X, Y and Z). + +*** Using Inverse Kinematics and Leg Actuators +Here, we can use the Inverse Kinematic of the Hexapod to determine the length of each leg in order to obtain some defined translation and rotation of the mobile platform. + +The advantages are: +- we can position the Hexapod as we want by specifying a rotation matrix +- the hexapod keeps its full flexibility as we don't specify any wanted displacements, only leg's rest position + +**** Theory +For inverse kinematic analysis, it is assumed that the position ${}^A\bm{P}$ and orientation of the moving platform ${}^A\bm{R}_B$ are given and the problem is to obtain the joint variables, namely, $\bm{L} = [l_1, l_2, \dots, l_6]^T$. + +From the geometry of the manipulator, the loop closure for each limb, $i = 1, 2, \dots, 6$ can be written as +\begin{align*} + l_i {}^A\hat{\bm{s}}_i &= {}^A\bm{A} + {}^A\bm{b}_i - {}^A\bm{a}_i \\ + &= {}^A\bm{A} + {}^A\bm{R}_b {}^B\bm{b}_i - {}^A\bm{a}_i +\end{align*} + +To obtain the length of each actuator and eliminate $\hat{\bm{s}}_i$, it is sufficient to dot multiply each side by itself: +\begin{equation} + l_i^2 \left[ {}^A\hat{\bm{s}}_i^T {}^A\hat{\bm{s}}_i \right] = \left[ {}^A\bm{P} + {}^A\bm{R}_B {}^B\bm{b}_i - {}^A\bm{a}_i \right]^T \left[ {}^A\bm{P} + {}^A\bm{R}_B {}^B\bm{b}_i - {}^A\bm{a}_i \right] +\end{equation} + +Hence, for $i = 1, 2, \dots, 6$, each limb length can be uniquely determined by: +\begin{equation} + l_i = \sqrt{{}^A\bm{P}^T {}^A\bm{P} + {}^B\bm{b}_i^T {}^B\bm{b}_i + {}^A\bm{a}_i^T {}^A\bm{a}_i - 2 {}^A\bm{P}^T {}^A\bm{a}_i + 2 {}^A\bm{P}^T \left[{}^A\bm{R}_B {}^B\bm{b}_i\right] - 2 \left[{}^A\bm{R}_B {}^B\bm{b}_i\right]^T {}^A\bm{a}_i} +\end{equation} + +If the position and orientation of the moving platform lie in the feasible workspace of the manipulator, one unique solution to the limb length is determined by the above equation. +Otherwise, when the limbs' lengths derived yield complex numbers, then the position or orientation of the moving platform is not reachable. + +**** Matlab Init :noexport:ignore: #+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name) <> #+end_src @@ -66,3 +134,63 @@ #+begin_src matlab :exports none :results silent :noweb yes <> #+end_src + +#+begin_src matlab :tangle no + simulinkproject('../'); +#+end_src + +**** Matlab Implementation +#+begin_src matlab + open 'simscape/hexapod_tests.slx' +#+end_src + +#+begin_src matlab + load('simscape/conf_simscape.mat'); + set_param(conf_simscape, 'StopTime', '0.5'); +#+end_src + +#+begin_src matlab + tx = 0.1; % [rad] + ty = 0.2; % [rad] + tz = 0.05; % [rad] + + Rx = [1 0 0; + 0 cos(tx) -sin(tx); + 0 sin(tx) cos(tx)]; + + Ry = [ cos(ty) 0 sin(ty); + 0 1 0; + -sin(ty) 0 cos(ty)]; + + Rz = [cos(tz) -sin(tz) 0; + sin(tz) cos(tz) 0; + 0 0 1]; + + ARB = Rz*Ry*Rx; + AP = [0.01; 0.02; 0.03]; % [m] + + hexapod = initializeMicroHexapod(struct('AP', AP, 'ARB', ARB)); +#+end_src + +#+begin_src matlab + sim('simscape/hexapod_tests.slx') +#+end_src + +And we verify that we indeed succeed to go to the wanted position. +#+begin_src matlab :results table replace + [simout.x.Data(end) ; simout.y.Data(end) ; simout.z.Data(end)] - AP +#+end_src + +#+RESULTS: +| -2.12e-06 | +| 2.9787e-06 | +| -4.4341e-06 | + +#+begin_src matlab :results table replace + simout.R.Data(:, :, end)-ARB +#+end_src + +#+RESULTS: +| -1.5714e-06 | 1.4513e-06 | 7.8133e-06 | +| 8.4113e-07 | -7.1485e-07 | -7.4572e-06 | +| -7.5348e-06 | 7.7112e-06 | -2.3088e-06 | diff --git a/simscape/hexapod_tests.slx b/simscape/hexapod_tests.slx new file mode 100644 index 0000000000000000000000000000000000000000..4e0d886312d50375b6bf0a98a98db3a87ea56a73 GIT binary patch literal 29520 zcmaI7b8zL)wm!UL+qN^YlZi92ZEIrNwr$%J+qTV#ZRgGRocG?k=iaK{KfAlSdZE{| zdUyA;>LVu!0*VR%03ZP)vEj0K+7V@sKmfoGXaE4^dsI`%#@f-?+EG`@&DPjKo6gnB zaxmG(W}X3Ys9PejxzuhKOtAEXr7?rW92*U9@2_J6eVFoB!UZi&PPQa>y&z>GTPeMl z_oeqV=gnwBglSbg#l3(=LWxa-U3%`WikRZzNy^*VYzPY!QY63_?(hU#C|yg6;>jX} zD9;Gx_D}e%ml5qXG;81l7t0?-wHl(ixs(YYU4gLkP1pBqI}74;j&Q3eN3JwOpvLe~ zOB@@?qq2pntu!X->TIeG)|KkjY*y~Cf{P0k zg1fg-6WyW)X=h=JlQz^M-ZC!HPm9Hl5*9!T0w0)D?g>*NF+<&A=a@+Wb`FEO_f&l<9 z-)W+2Z*1v6PxsGnQR28vKLetO57}*(9Wo;D!k-NP1u$g)TcCNPbhR*odhNB(pYWk< z2+gO4Xz^24f5)u}R%thohaRE?8g1d=H3%HdY3t-Bz%5sF#`Nw{zO%NyU;CDP^ z5%!ZQz-rR|V8_5#5*!*My}*rM8l}R!_gQ`Gfa95TIfRA!WOY_UIkO!Iy8h=jll=T{ z`%j7xx_8KQ5NdV>Rq_ealD8Am@B(}lifM>M@j8P+inUfXaRhnMZs?P)kOk>`W^*Nt zwnljNWwR?8AuFtO6n@p}nj3;LFW;1yaojVk@${5jm+U2X3cAaSsx+H19NWiyFIV^M z;q1fb!}H5FxsbIzquTMNea7?y*z}Ytk=YHBWj#1P#+nDlu6E|<4P5`;h);j?-Ffl8 zWVe1X?x+0&i2p<+X)G5@`5Tc|U;qH;8xbpGM|~rGM}2xj8+&6pdmCG0dq;C)hkrJ3 zl)}FddQTd88nDx7)FUecEv29)q6D^Mo??p%y%=GWzI)<`NeBLE+hA&9I(#OrDk={F zF;lF-Bt#l64~VbGk2em^Za%w)1{-2huhkGAk%IsStKj(y_gA7nKn2cB(+?^$jwO*D zYfW=qE)s4#K#$xW`eY<)&R^YSk<1$NOOI@aG#W$A*BGn;_9<9@A8*!3-PUH+^VFSz zk|P)!RLp`Q4Dxd+e9Re6tCAzm^f!z~YQ&!3%~(NMN4eE{X%-w;O3u#m!YT?p?`*rHE{>$mj(iAIe~tIp6j3ZmbL;QdcDtX%#t9>y`_ z*1(Lg-#cck3q?<)LTaV1pq%mpkf0{T5{5Fk%jhGEPHS>Jmppyb>HZWduu)qpyD;w5 z91lE7esnT7-aY?mNCT!y2tkDOXfK#-VCvYhu5?{e7+K_QG|My4iTis}SE3G&0oVoU z)K=E`V5+#3X$6U{l&#|7*AF-IKhjEZr{-g3ghx9+7Lp}4M<#jB_gP)B+f#ADs}2{m z>ge%DgHCXW)3-55;lFYRv#fo9Gh;9jF(>Q5K6oq|H=16mI^2N&GXSXMy%n9`3kUrU z0Qvtb03xp6$BToxjrBj7sU1CO-$#i0OE*Y=S{7MofXJ@sjBf4HX7@J}_y|Dd?J>&P zczOF}3b&#AEzQ$#OcC~HRZAggK$JD~QMPvn!D@2679mHfVNdp_Ua=7$rcVRou4Xt) zF_S)d1;s&jbP+8#Q9a(Q&>{YqYs5)>Ym^SH9=+`^`SIT*I$t3kz1N|+6*yzCx;Z}b z0f%@g9pyA+XG@{WvsyI?I9z7@G@8tR`5UAwWTn_Il6yzRE4a(B!G7_~Dqq)lK7;*d z06N%R$hyB5&iWky%KujY6pSs6^&O1GtxatH34v3z0D?aQY|zzv_?TBDl8E?Whud9# zzGy%JH4s~U-px^a7$*JWg7?)!qvwMqj%#jRlFE3jh#h2UAsvmAcJPb0H2SUtsHY$# zE;xqLX}+}PeU}TKW%#G_LUB{Av_W!~egqskx*uZmi?VDE4MjISFyIr2IO0$qw=S^A zj%nXN+FWy_<~ zZQAQA@(O|3ql(#Ks*=^iC)+f~%uq-hTmxPM5pp26rsM%Obn`0;XQ4;ywVoCQlI7C< z@JfJijQcCf!kjzcmJqQZu`8Ji_s%#1^BUDVK5QEY^x{s~{963x+MRSYJveklbMaAg zW}#uR9ov>gqH=Lz3>wj=rIP)~(lri=!seIOylL#oxN&NgA?=MwL7)R5#(b2y&Qm8# zCeKt(ZGaE&9&Z%SP644Pa|A6o9Hc$Ew;96PC~Z}ajE+Klp|`H(NE4?AX4#D zj>$q&!Qy)T)=d7rCRomlHC5@_+qh?H`)e^-n9|+!7Z!ZTI{e??Bz4%%hzYSAw9br^ zRPzJ$beb9(ZBCOyOtTb3w|~EU2+PG9NITvdjn*^DZN`wwxZJE5Er};GGY5wSX^DtL zdcyI*K^iGpH<@mH7SG3rs3QE|21Og{6Ph$&tovFYPyFMD zbXJRp^B;W|Zi!=(ljyh@WY_}Gbs~iHpJGK3qh6=;p61;4V=aI1ts*IkO6JL*v}~G&>ert$1~M!@g%|0Xg5_jbUc|hlWblcR_d`N*%*`#P zza$do=I1T&=v?EOyYyA9^npWk=~<)D7-H~+@ zuBBvT1Y293a`?Je*Vnm^=#~@R`N;2Ux~Gi0lTyz5b`evzi$Uo=qY_Y_``EvXQGOXz zPJ~ydA~G`@{@mOVcX4+we>w;&&dJFyOhmP<42)OM@@O9dGe>%3xHu7tcKso@BZ16h4k3ac=LkVmqIsiZ+(4@pl-OgNu)?vDJl4- zCLV|A!Q!Hmh^dbA1~Ml?QKN_IjcrGmS08D*K(}k1f{yXFaaHI?N%SQwa$QoFxA+2$sae*RHP^hJ_eAb&GAS4!3F ziS-gD(y0Yyi#O$RHQML zI7_z8xfsr?TcZknyrg$sMObS(Hb%bSyIVLEIWNba{z@oWRvt!RSax}P<8_rQTczj! z*~Z33)oFYl$FRyJ?^XnIYaADLeId951r2mvrkIXU!dC$#>4*v|@7rulDbVofAy~$W zDWtZZOOh={(-%a~eX88!r@|hWtQl^lI*z@ztLYq{)Eo7gqpEmuh9OUwar>QzMz@gt zY+rp$?l27)z;~XfB9&QegL~|0YwGB!iEX3JQJn`5PSRWPsDS@!i^!qNKV$XGsGOWE zPz22v{}|d`^?)nC(UOIi#o?*s?K{Bae{$?pVf3UV_937V`^%CVoc1& z#;ySolNe4Heak3kdy~N58Okpx*u)9DwAb4F`O~U1N0_ep?)H}Q3d>vG!MQ6ZBW1X6 z6zlEyLe1HU6^Eat7CmV2mrR?mRNH%`-j1chV#GNl6kO3Y-*!0|VI;0PH|=^#2UIAO zoQr!5LCMuJ_()`1YtE@VguXp3Dz3=Ec`rWaocBkk^ryU z%la?slJ{K2%bEmI-}<~+`H?(D?nGWepPA_3DraimY{jMJLmsQIitW|ByF;amotKw{ zoB9`q#R!Y@y(I$QeH_iu(h)ijCyEk}%F4>1n6CTo6EzA{ilX9QpYLVN+E3AQ9v*EM z#c^{TNv_h$i<9Hyq0u61SR{ zw8JKAPxH*1M4UC=ZVFX4wmgR%y$bhgW+VsSfCL+Qh!gbCLpl;G!nXy&)FQAskLxe98szq;5ZvB{WE<` z>;-bGvnm}DQ$j`?&zvlj)U0*$gqQ?5fu``dQ#$4*?hQBR{>2`l;Qo0uLG9j?dvQv% z=*ZwhAqN~BHl-;n>gy-|`{E%n%t`yJydp_u!qb#v_#c*3MYU%K)9zaEVk=-ONWmVD zz%g^is3Bar(z@d+ilKd=cAC$#f~PVK#aE@*_AVT5I8R0-R8-48z>;RpqwE6iOes-D8KHj22&(ewtNyklfiAGM|PASbPL}W$;!wlm2g)U_) zhju}8XPfRMT>1uR<{u{fQ_ZJqoG?2Ju*^yMPfxQPl~VHRSaRXR)RCN<5SMh(z&4vO zx2c~VjsCH=4k81O=|U zc%wy6#U>!|Nr{P>BR{^SG#(SBW9Q4s(d7q-Av_d_#{6P>yJX~Zy+egc#ql14Yeuu} zNRvR?(P(-bHT-H#!{Vq9_>0K{%F$Asl(aaG7lIur!5%dH=>J&$@dISrxuvE?5IBWr za3d*EpeBxkbZ>$gDOQ>e&Bv_Z34Z?-ixBP9W$PX!sN+b8FV~soO@UpX&L-LN!pDAN zr?qaKMnUEl1B7L8c=*T~9KiJ#KDu&Fu#0P&Zhy<9Brmg@`H^zL?OrtvHqI}io*cUy1AB%mOeK=cnbp z$do8MOE=&!I2m3r%JyKOAR&7~ALI73eaWkT4YexM-NV8Di5u}bZ36W1I~i?pa#T{G zHdzI`*dHrL+g~^P)Mj2JXlj3$F)y8_^l+2kpBC?fF6U>y#rS2()L&A(8;DiUOuU`c zz?Ggq!9)I8ILQM+CupjzMRbx+qRM)92vEy&rT2i8&&xj@E|t{eRS$lTCWVybbN`cK zS)snLFwpqtPvAiP`xJtk`e_oqHJYk6{VjaW{qDYHMCCK1O%hrj3ZjQnRY2!YupW7E z0dFYfaVmOxT_UxX662j}VToW<|Hv42zTp6W2i5xPz}sXwV5WC( z8do*aU?-aywC1M-6wu#ICcy4B1`YN)B7!)z)J9)UrM&pYK8p%C(ChK?o^m~DU zfphh^9wB&;k%hbyVzh%i0z9Lt?G*{RId_P@iV_G;Utd{Hu&|c-x44;ig+iyAIV>#W z5Cbr(`|2!%u2v(K(10x!@p2nS4>x|-^VH35QM5msbQeh+jHhn2`gp`g5h*o%LcsF# zairtZ3`n*`lV41khKY()K!9o;j)#YbF;4U~s;vPfmO6c*tu|-3Vf6R!l_7(zh`G2d z5QLmXA&n)Tc!mkBl&i#qeSZVjtKUo8DG`F^( zS2Q#;Hgd8w7W$@b{&^2JDv!ozFd%kLtG2X^YakLTuqh@N(Y?~&AHl&cH#htvW&C7C*cAN7yAdjp* z5-TZS&j1ydUPSsMklZcWZG>Zh7&<22RqyEUAD=m_*;3+PA}!)Y5PykA3uX{cMB+6F z514pC9%?z&&XM4U2ttlnzs6&_Z;i|p6705B|%Kg%xJRkmE3mdJ2i=QGWhpSa8~p5%ckfus8KHFS2fuP6?ybnAvqm z*9q|Iwz?m}@8FCoar%(K*I4LYm&$1;T%`%rK}&eJh1FG*WK<>o`K?2LkC)ruH}#gpf0et+4MJ|DG+{9rUv91&3{tAx0sOf}p-6 z5*L@n{4wxJL z$sdgH$WuO@vHsBSb;%G!MRX-g)!%*uvP$G0?7-Brtw`r;N(CDO5wiwU9|(OaPyUv& zC3B@?Y@y@s(kQYS-MCD&PaTR8rBx2mR*+O3no7x z6b;;0`D&JnR1i)wM3fI4s06#=0OK@^|8&8LERH%)3lu~cPO^@eNN9o<%+G)|PubXY zJV<`iGA=&pns|3_GJJ*3vYl9S^2x1So+QPJ25Clp;Z}-Sq#!S>DA-a+6ynN-P?1&V z5fbMY6BE?yLjB}1zupj_V>Y-Dc11Q+Hgs0p@GPB`aOMpkxpaIPzCF`k4e_KWU7g2E zk8tF3gyKyWNkZ&h;q{i?_D(s4{NVXJn|9evxwWJ7hAhF#tW`T+6|FA>IckmIZ(}pP zvCmS@>WZ1o(<{^-7Ozv}qbBGy@2^|F|IBzPLpAb(Z~ATm0stWWpa0SSu67t$+8A0G znd_U{>s$Sk_5Z4VbS_#+9xxyRcDfaAKiJM--0@Z7l=TG=T9w}^SB=(!rJ0Emwzgi+ z=)3gRH!E{#KT<~>5B0I*=kI(PM?d{3qS#D53K++GB$U>YIXzmsKW`F@Q3I9xa)UCf zeAS%2onIj$A#ZTX{}j-o*CjSkgFZz##G@_v|2pm&$^!QKA*l5l&rO7p58B0tPhhuQ z)%(iYP&T$2wD@3gFvU{TMB9$h6&TC>)JEQw%n-h5FgMm4OjfKcc@KjvUdegV#<)gj zE$8hG2en~vb$X^z1E?)^;;RZo!%9RmH`>QJ<0xQ)GclTNux zTNDmeJ*SXb7IiB)GR3&QvA#Ki?4{W8Ob$i~OQ*RgYUYv}6W=VTvQ|tbX@y2-{u{=U zF>B|Elfoj?x`cAKQ}p@#e}SCcdKK~K8(h3^pvnF($c8r7Cg!G!#*Y8R&;AQ#!q#keYf?S<{cGt83wII+S_9NR1AXf%Pr~pVD$WyoqNPc) z<%9HSRy{j!JHPA3t0%P_tXkvrno<90&#+xF>29u8?9!j6S@o>lXs@O!+wU1?#97l& zWW_nGxA{w(>r3GXxH}v>#fz^0t6T(1ovVrVefMbkF7jgh&t)4J85x`CJ6SsZt5h_p zW)*|Yj`+EyTel`#wE#+|T+{?i3?IEAJ{+NDFIHAQ;tEkaWnp7QPyh0ebwh`XyERT$ zUj7TZ_b~0|IZd_X!8>Kt3}gtpYVBrm-2~Tfj|=VhVl+&%=bh$z*PYOr#_!J+3`=9R zr4TZj!iFq@{L-ZJs(^+c8=1l+$pYNjwYU>2kaE$SJcO5G#R}tg?Te{_Jt$USL?K*3 zE&b3X7QPK$(Y}2Ww(wGL#|6k!LwI@5*ym&>0B7w`<2$V0VO-YLHYL_`Rpb=URo=`?zM@ObCFtEyg8Jli`zK}=H4Ufu_He5 zDPMHLmn=Z<#hv!Hp43DMfsQD(#!KH}^pSa`wfaK5m%u}63~Wx`p_hU_x!evcXVs2b zuY5(oU2~IS0*k1e2@Q0EiuR}#=$!|l-d3#fGRS|e??(Fbc)OnN9eRUs=UT7yz+IwjK-QmpJ$D*d?o6VOYJXXIQ5_UM&PfcZL19GuI5bUDy3uY zT9JUG&_Jv5apA2bGx5euV98;L%Zk5IDN>U1+XwLOCK}^uBOm#8g@NLor$o!Y#_bVY zDjqmWYHN=)rtW1~>+|(+L}i00>@bZzwSmdOGt%0ZH$>IAhoDhJDH0^PbqK)rN1C6V zX=i&Ua(h$d6Ny#`$WX>=W_`7z`(>Oosb@im;$m+*>`_a_@bI*GmdUelRJMNJqSgGF zNOp&JWTAUDW0fg5D=WiCa7!lr93JsWF4o0pGWC7g^4WP(gC6&#bt~pjm3_GVvxreW zjZ5MsX1&p>Xu;6;fs{3ASCXYt0imzeOPc*zNtmczG_^K*Z7r4OX>QT#@t`3hUPpNp zCn>!pT6&TFgFoL5i{o&381gNC3MR^}@knO)Z;bvkK7veF1dH@L#N_Jh_m- zLQao!X={qe(y|>}a_Ey;_mk6ZZCmCdaL~aF0QtC+zgxgOcVOqyJ{428#MSX_2da5dd*?fx*NQ?koZsSzF~#?(*~5dpO7nintu>*dh?Rk zg;uc)A(;FPAdc|L51D$Oh{o2J#hmW6_6jVEz2Kw6VWkg1Atelx;Z~!KQWR{i9-wt& zE0*!JoNr#=2PI?_+o#2@%G*$JacR^yu%blSiDp2$SY~&XYbXhpRx)6p6(0PBFX{;R zfr8!!_^nx%&@14|Wk1HVM%_K)lsi8_f90&-+glmX@SKY0@)YS5QYR4D_D$O@Xa#Ul z3fKfLfKru~4&zue04mh;A1AoELxNleVPbE9b&oUd>K*}Xe_y0?4^JNc!>7DEx09m4x(bqqRsEsks#-mk{% zUe85KaGMnfy82U@-ben1zrH4xu#?q{mbwt`%d)oi`AiSv8Ques*dL+V87TeF?0vi9 zRm9Ec-<51W=wOPZEpIdfmJQy1W6&yK#X9ufZY zmeg_d(6h$^01yI!{^v{ff8UQTyeu5nIhGEe-l3B`nkziGng%mSWj4IWm#vrA>Xz*( zP8=s&%%GBAf{9s4lQ=rtzr291iQ_;a`I9Nfd6nm})cb&@Ia{)hh-_=0bYl!_9?*i~ zaGtxZ&ABhC&~G7nXC6emt)=(hF1D6@F1lCSA%jP_@2&!D&j(t}&iXq>J~LEks04X; zr&X(-rZ7L+7G1jXcV`1oxB@VPD9i^n-+VSQt)Cv9Ya|9`J&&e@AOe8G^D}m4!e)jE z-;t#=f!5X#-pl#F-sj~RvIARqR1Oc{KvO(q9q%!XA$mcz3p})*cZcxy<1ezB^c&YN zey>WN$Iam7m%~a%7_#TPd*J^d*j0FXiZqZpM?`BFtHU97#D~SLiP^(^BSRj?l_JlM zsQu<0Z}zujhbbK)3IRfoeGl}RqQq`jVB1pxvy?ZT*Lfnn0k+pW-Xeu=&5xrg+k))B zl*{HTGS13md2KHC5q?C;*WJ0=d3v9^A8$O&a^8yG^e=T4Gi&T@gc+=P9Pb;lgq9Fh zyB@s6$P8B|e`Rr)VnY;qz>lcP*HzUn?xJ0W7zT11BzkgEct2eKw69Y%qZrcRbmtGC zpLL9EY;cmaacO*<$i{AcM{0m}Pv5jkh$bf^0PjB`92$GtyaB`J;ppNH{iOdS!RAQd zthuU(UE_v+_i%CCeV&30QU_7Re;qbD9yoSk4-dHJzC^t9=@M-TQcpL4+w{PIL+H+# z6W6o&^7%X-yb7K6!5zFh6}F}LH7B^tPQc8`wD(%aoNalL;k;~Z;aoE827fyTMdcCQ zl)!f~K@eyb`Tm@<*(dbmY_ZYk!sJ-T*TQ>l*vKQy!UNqwNE_v5(hIVUV8G>ZE1A>o zl853w+`kW#txTRBux^?vMK7fC64SDtP^WbF4#D$i7iL)LN3h77iP{O>$C2T9D!KOp z@w61i+*ieY-cGW8GnK`Ca8q=6CQ~(@e%9lV6)NM{^_2A_JV!bZN1>nUx`C1OejLba z&YM;b(O+YYS_q5NqnAYF-#DqK>KZ9lnC{CC*Ov$l0JAdEI4Hs zF-YqNA4lHVGb4U&OXIb}*+ur2$aVo{RLqV2&g%yhw(WQhPd-p1s48B8=qb>yTHn~a zG=#mK*fIxEI#>1^JJ;P!WmHsW7iT4n&u*Y@F^W!@5Iv?R5y6R?J%yH&dG9JVkuvVn zn!vG4sQ3rRfT5^F`34VhUIyVcJf5}9aDq2a)Ng3q;9mCg(ZZj%SP9#svL&B{Rz?Id zIc+aoRoDn)^ghomk~$pn(t{X^^v*W;f(NiMz#S480nyq^#PuN&(m&VCpDQGFNTJ%_ z4WzhrZ_nRP&odJxXx7(U;u%6a^+^A|Il9WdjjU|1#RQC|R_3!3gC$w}Luoq=mZSYG zMT9T4_`7ivlVa;rkB5S2~&4bxz9t3=Rcu-g6@F5RvZHz?LtKLx62*kaW9kSMFQd#0BCew`=Cs zkYRDYQu2r%C8zWI?$RgbmmSW~cB-PPm_Pd7;O9vXA8*x)kK5C>Yq)vbidpck!hMoZ zw~E5)IVQ+)6}oob(J$WYac7f{oRO;;zl0@0+h>)>4$j46$S&!MHz$|?2p+%Bn09?k z(3{L)2V{YAgfcI3j=?zJynX9OQTbCs*sLpuV7K05LgESwXxP$dr0Nh*dsi*u>Gj`# z?I@b=3Dz>#K&y913zN=iAipldK-U6$zVkT&poh>9^OLa98v>`1C%6;MrS=Mx|0Us%BBPaxVoRHwc4d&0akg7cGgWMwY)zzNv*2bhT zJ>8H$?_3++{kazvgwdB1Gwj|W;WHVt!bSNx7b`X6_ollsYIi+3e8EF2vB(P|o2o`4 zusIL_1ra}xB}$tA1HwKjuRSG*iBk9za3jQtJdF`fj^rSyx*!M_ys}EB>JLoGQYZ+q zYbF7%6$ZLqHJ=tM8eksk6XqbNR2SabvKbgnu*-F%%9_<#{&5KA60M48Kr1;s>MtE3 z$72_|X9M~2arL`&}PbOZ3`#;AkxAu~t0Y|mqcn$yD`MCg^fK7T5Tt*Pxn z1D_difUu4f>P%fzg8E4{tg>D47%x|Y9R?oYNc1c@@3FL=?DsYQL(*sc^t985F{B6d zMN2Bo1e&zNHx)%}j11<85nE>U=JbdVGlvUQd5<+h`c9_+N{0f)nnz-|&lx-UGB6>v z?0WU)>hgHEK#0p1We;m~A@$yrt>tyTeWLcf;$_eA(`?o!!S)zY)(Nu(xs&;vJIecg z_hv`?(cy2)Jh9zDP=^%(Q+23BpJD1Zt#h^ZsZ3YI zT^ZY*t;C7w{=jsi&lGU>z`90OO&x;dSAuQlY!N)g=kj$)^cH&C7SjruLOq#oM;mw0 zGBKD!%uZ*&5mnSsbGAqGo9MZ_8Wrlrp|z``t$?=jD5VxZgI7`fed@W0Lnvn;&-Yu!Zs#&HVWN8da`uq$uR zU8s8(c=J0OVn*{V;g~IT$Q5cYn%j|JdMNa48MSjreo$-m)xCz81rJ=+6$>`l`Y)?Q z-m!V;C-b0CFB$2n?gnS56tA#Q+n-x#JiV2ZfICtyPI0dGUKrPT5{Ntvfk_R$#`!fL!z!OlBf?@65 z?93FHFPSsygPAjb%- zTM*U*t`H1YjF0d|f@$w8psU4`E1b%dnJkK588`^|GYolLqmqGkFN6F7)EVnt4Z7S( zi=12r9S`*Gcy8=|!+Xj{roHW<=yNm9?fo>4yRSwO8wJN}}W!(__gz)6s)7SY~7ln&!R-cr%`GiJRkvpg)F{w^8)$P#%`y_sLaom|) z19xijOhU`tKd#gqD;HIMs$L!w*@`b-$yy^IM1L+12b}G%C-6zakVCw z8aW^E&xl3`C_W*<#rT)jC*-e4XAVF4#e_hZ7h;2FXI>FyNSRSxW&{~+;JT6oraSBKn%%>h$wr+IA0{)38~?atn+ zTezoyrJAa~t1Gd2jBMs*s&Mi|XA@LU;%@E&Lh`L3c}luwl!6twLubSLmhsSyY^YHI zTg(C1$CgfFdGSZ|?v^^G-wcjpI)(_LG7uhZ>-|9P)5QM4$`q+F(2_LVhBtA&C%Cf5 zgfNcrVBF!Jrs}o*wcOHRD|K8^UCPyB<@;u|Huc;wTja#(=Fs&-q76U%EVq2dBD~9R zSs(h0GxZHo(XC0!+H&f$4j3@KZHl-f3bb)O<9AF~`WR!m6U%;_ke=F8<4BxV>{!!| z4!UyGpDLt9k)xGu3!2{Uz{3x@&=C(ecNpP}Mw>L6e3@}uIa8F?h_#p&DnQu{Uo#PO z80CLk0-o!g6>U8(>aWj{9o5xDIBz6AjodYCMCdwQRS)r0d-@Gkp3PbkrjT*D1 z3cF>oFU8}zpx+CVgueoB!U)=lUg5wDQ4>g>kcApzQgq!-9L3;<;VF(*6Q&O^Jw8<* zhgV}g^L5P+t~L)~Zf^qirSI&o6w`1tjz6^EQu4U%KhA56iiv%S+zo95apQyipr^cx z(@DFH8ud#fHD*~lT)<0>=WdIT@7wo4Y6M*(Rf7UV+1al#k*Hl#b7~2bbRoIqEpt>aNx`m_c9ac3ty7@i$=5O!WK)wjlK>=$4d;} zzNi=1wxQ4gW7}$PmHdhWbQj(D&tUgzP5VUBtjh)U!LV=r9l)A-kX=W5Ov(>^C26pv zJMAhLqvot2uBzsOi%1xN)JGKgI1gOcT0s1nxE(LHoB*cXS874-y%PhORKuvRktOw7 zNrW67l19jRDT3KKUv?z!9RC?`mJo^iEUzu8Y_hv0CDXCjN}37ANopqhsR(Hgy+~U* z0l`iT(Ld*6OGlKKFoAKPIfrmmuY`8G+Yz1hv*cc*DZl3&Ez#9-p<}cPwM(YK!}0=$ zJH1T3X{!#l!qmk|h>|;|P1;_pc)WkD-SSOo0)1%rj6t)3d(0$-^7!2%jQuZ*TCUBQ zqBYsNP6Zatk@7^-LsO%)8C^o{!g?`FjY0hpGogyF8j!)?umK4^G8N~`2ha`t4qcK1(%q+s^NhBm>Z=Rn9i$3!O_R}AgUK`Vk$-~5T9GnZZDg*?QbFZR zR-nqFn60ZXi`G-~FVTOL{dcDp)bCpy>>oV?Og%Lnp57uf+Y?O8Ut}n>;U@G6`i#uM zMe~UL@i~ZdPA4dWS@y483Icj+zWPAHA_oNj?to#U>#1>k;9{a@ul3Xd`hj6#7-&1N zef3vSgGFq*$4~_SrK*l8xM&@=KmV!zCoOo2N;wm)_CNCSWsv`pXZml^MQ?am7+I_T zR;~lrQ)>y`Z}3O=FFv}+KcRB`R<#V&6bAU;c8S0Ke+T|i*LQN% zQ+vGt9{evCef4)20kGpk473~E9=dG(`6iEhu;bFl&$C{L(Nv@Ui!Gh~J@(FNv7Pqm zgADcKft1Vn_Gz)c5bE#_@dJiGh6%bxv(PSd_RTymVZfk8w6DSJC>Jh;4}rgL%&~#4 z`jN!TNdEJjtGr7{5R3ieZ*P#hXre7`lcU)rKB#=L57Pc4JG_csZKg^h482RA^f_q4 z4mQTcrUFBxcx`;0U^aZ1CmI zY4aa5b3FrxlXVGYWH3f754sUN&9N49Sm%!7vYm&5I31q|$Ra06Yeaf^8b#wNq_ z5EM1E!{&SL;CWmQP;NlZOJteO9R&7di%fCH#89*CO6T0Y?sKT1?BVgDUPQBTJ%xx~ zBpZXPK4g8Mv*g`qPoQr>xivlgx^!ZF`mP=KX1ofoaVox|9S07+l-!LJ!V14%H)E)K zN)PK4OHiVR%2(yv81;@~ahutB%^7~E2amAflm|A`44_w5KyrXwS1(^d2!0@6K|w@7 z(6JqWvIY73n+Q2ErQ1Eg;Gt0({eD<6)1bqSa5A0Fa=JeXR<@iNh7IK0AV@BN|K=4C z1mp`02nr+wK+o<2W#F(9beC}Yg96j+jB5<#fy19RJE zVGDDi1gHw-#30N2n<#uy0aOyPeZc?B7epld$91Z2*Qo#s|F}*#2u?Otap|FPr5R2O zl5NcfLWRsSt32jwn(j*pkO$;b5{JVRLi2xH_NDx`Ec|U*7%24Ha!Lp#8-=_Qn0zJ0 zs$x7Nlk7vGX2o>r=A^>UZyv0iV&wtUchB5+4~!7H%@VC%VvZ=2Jn7w-j@#*d2fiy7 zH|)fwZ*fT~1ng{N#Sh9$Nn(-=s+nB(xLaRoru~zF?v{Po~PzJW_~6TM_*TL zKW%_9r2y~&yw$`ouLHsncOZHYdUW9U1&Rml*UJ=o;joff`^wGhYIQ_u9O-6nBg5?!^9(MO{DXX_45s)8jhG zm$y?cHs6p*2n1VdU>T9pP@qRw?G+Fi5x^cIF9>3YKTl@3tDu>Ttcc}7qtm_IfO~b7 zB%_G4c~;#kcdepSoF8sKbkK!KzRfPxE%2(yqt(KupC%!cuFKS z+ubD>G|iHui*`6oea2bjqHb{3PB>3ULf@p5Hjo5B3#bLy7HkK)2hEq}_aHzOPz})f zu6yl-gQ{8{f;pqAR-OR2qpBJ$FJo17BW3J`lLjRer}jbF_XB^=1ZojfK>kO(81vsM zNKb*Z;x7ExR-Vw#CNB~<^-U{3H7uFCyQ24?lNMyo(E(cDsr_FD55Ry_L-8S6@~Qvv zVlZL|EhFttT+?H!#5$Np#fP0u`lZmAU1lU_^|Ehqg&v^H-&Ya@1V-u!takmb5A@yo z0sy!!lrdt8I00T=&r4tx-SP-rB`6N^MdTuF$yO30QTlKBc%N+(#)n~NM0-Q33 z$m%~fpv%`(FTvOYSmtot46+=wEdzze{L`=AM z?(22Tn*Ms^>84mt45O7%%5lLi}B|X0UuuN!v`8#7pz)VeadRneH`Zg z37*jvpXZMPD@s<3>??co0YUIsCB$))h}*VHpzvnXORE1v?dJp1mpa;dqsIE;MahL& zqefdF*^^_{z)y6FF711_4T?Q6E;nKuzG=m5b#qMZ6$VS?Gn|mI1(q2FSjx6ZGt-Zj z;=JtJjqvY7Y569LqO7_nN|I&7HD5rMx$x7aw?-DncfnKIgi=YGf<`;)Z{s}bQ**j* z3kn~bs{K~Ym9yK+ekjAG^GErhyrWGDZIPsokw|RppZwVmqC|D$GCTL0;%f;hL;)r) zcy4<_6k0TtHR%jOf6xU`MSa?D_8LqcRd(2a%$5y@ z00wxC#ysfNxRGV^@i%nM04PvJ8f_F_l6d2Z$_yBWHCdHh48KH`9J^Q504Nrq3=6u- zcljb%Q^3S&NomMmhaKcwCT($54hzO){>-1Qfy+XIQ9-*#GYpEUqM>>LS{eegZQ)ca zhFzk+b^Tr~Ry~VVvWSFr3tFL~fs`iYkKjIY{K9D^^5Kc}v{)t{U6PoxzP6dWIdkE$ zHjo^hb0L?9s)7H+Y2`9lPUK?iu1c&%ma++H!A&%21J{|8qSs(xv8t)iw>zh`Mnxox z(z-N^|2TIlCq>pHXBE`B`T0coYyZUti@v!0>iC-y6K3)dS6u-$OmUgU*vb&U$~5hq zX&9}3(aFf}AX`85zytRi(bJeX9Y{!NBi9_ye?CBhvxONtX5_sikUO61)HuJ`Y^6oJ z-mgIPa++;M*>1g?iGAU9y6OunuX&5!G~46c)?8NnnsC{lC*;rd^%+2g9sa9FD2 ze+mPe0Zms;-d5&UBbW7k%SFM}yk0eHk6`mt0e%VY+Vf#GaJMQW_4mzH)l(bQEN5+@ z?hX=9BM^qe4{q%T4si-EMl~znydXs7regy-y#GxZb12B#SS73XrPI0VY3nD(h6{66 zeT|yIZ!et&)tm|m$;Z4I7pWFF%hi(3k>?er3BYAJEWtG;U zHGpY&iX40O!kKH8TR#?5_nGfRn=(1pNap~qJ2C7fnN!nwI@7$EEnQoLB&A#1oGjxo z`_GDof_z35GQ$qhw(WqPxSeJbbZD=TSrub{Wll;n8y%-f?PzA&0IYM!O@1O8v(npy zWH{FS;t;IkKK28rc+HA&iHerPz>KaRQrYbwzzgkHmy;4?1 zgR((GHT|-|tQzw}^)Ya=;Jm7_bvkw}hFcw-EufBb+ukWE@T$o*htY71@_;Y0K^X7> z7>g(jUp+OU4ni@KXXHIFfpU~kjATsuQmZwyblunp45ec*9^WNw`U#njq_jS=VHl0| zsTVM5!yh`8zIj{>Ito2{f<3iMz5+eCLOpVc+A=+a9)cbYAmGxEpsb*dgOlc-oyh3!-K;9f1RBLR9s27wi|Z|1Sf&uG%mrNKyY`0ySr;b5+q2F z#yz+OcX#(-!QF#P2>i|Dn@Of;zPtW=SzWBtXLUWbyUyvV+IyXPw-p+`S{fx0^n0n+ zZ>yJliG=$eGA*{G`U;Yf`d^;TzS3(=FSnT};umY4^v`hI0?59Rk8axt{#M}-rhW

!^>rP0-fIbG&etN7(Tw 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 TD<1UQ2>^!R5q`$%;obiOVbC`H literal 0 HcmV?d00001 diff --git a/simscape/index.html b/simscape/index.html index 7fe3a76..295be48 100644 --- a/simscape/index.html +++ b/simscape/index.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Simscape Model @@ -258,64 +258,65 @@ for the JavaScript code in this tag.

Table of Contents

@@ -326,19 +327,19 @@ for the JavaScript code in this tag. This file is used to explain how this Simscape Model works.

    -
  • In section 1, the simulink project with the associated scripts are presented
  • -
  • In section 2, an introduction to Simscape Multibody is done
  • -
  • In section 3, each simscape files are presented with the associated signal names and joint architectures
  • -
  • In section 4, the list of the Simulink library elements are described
  • -
  • In section 5, a list of Matlab function that will be used are defined here
  • -
  • In section 6, all the functions that are used to initialize the Simscape Multibody elements are defined here. This includes the mass of all solids for instance.
  • +
  • In section 1, the simulink project with the associated scripts are presented
  • +
  • In section 2, an introduction to Simscape Multibody is done
  • +
  • In section 3, each simscape files are presented with the associated signal names and joint architectures
  • +
  • In section 4, the list of the Simulink library elements are described
  • +
  • In section 5, a list of Matlab function that will be used are defined here
  • +
  • In section 6, all the functions that are used to initialize the Simscape Multibody elements are defined here. This includes the mass of all solids for instance.
-
-

1 Simulink Project - Startup and Shutdown scripts

+
+

1 Simulink Project - Startup and Shutdown scripts

- +

@@ -400,11 +401,11 @@ The project also permits to automatically add defined folder to the path when th

-
-

2 Simscape Multibody - Presentation

+
+

2 Simscape Multibody - Presentation

- +

@@ -416,8 +417,8 @@ A simscape model per

-
-

2.1 Solid bodies

+
+

2.1 Solid bodies

Each solid body is represented by a solid block. @@ -426,8 +427,8 @@ The geometry of the solid body can be imported using a step file. T

-
-

2.2 Frames

+
+

2.2 Frames

Frames are very important in simscape multibody, they defined where the forces are applied, where the joints are located and where the measurements are made. @@ -439,8 +440,8 @@ They can be defined from the solid body geometry, or using the -

2.3 Joints

+
+

2.3 Joints

Solid Bodies are connected with joints (between frames of the two solid bodies). @@ -450,7 +451,7 @@ Solid Bodies are connected with joints (between frames of the two solid bodies). There are various types of joints that are all described here.

- +
@@ -583,7 +584,7 @@ Joint blocks are assortments of joint primitives:
  • Constant Velocity: Allows rotation at constant velocity between intersection through arbitrarily aligned shafts: CV
  • -
    Table 1: Degrees of freedom associated with each joint
    +
    @@ -875,8 +876,8 @@ Composite Force/Torque sensing: -
    -

    2.4 Measurements

    +
    +

    2.4 Measurements

    A transform sensor block measures the spatial relationship between two frames: the base B and the follower F. @@ -900,8 +901,8 @@ If we want to simulate an inertial sensor, we just have to choose B

    -
    -

    2.5 Excitation

    +
    +

    2.5 Excitation

    We can apply external forces to the model by using an external force and torque block. @@ -914,11 +915,11 @@ Internal force, acting reciprocally between base and following origins is implem

    -
    -

    3 Simulink files and signal names

    +
    +

    3 Simulink files and signal names

    - +

    @@ -926,8 +927,8 @@ In order to "normalize" things, the names of all the signal are listed here.

    -
    -

    3.1 List of Simscape files

    +
    +

    3.1 List of Simscape files

    Few different Simulink files are used: @@ -939,7 +940,7 @@ Few different Simulink files are used:

  • control
  • -
    Table 2: Joint primitives for each joint type
    +
    @@ -1006,14 +1007,14 @@ Few different Simulink files are used: -
    -

    3.2 List of Inputs

    +
    +

    3.2 List of Inputs

    -
    -

    3.2.1 Perturbations

    +
    +

    3.2.1 Perturbations

    -
    Table 3: List of simscape files
    +
    @@ -1059,10 +1060,10 @@ Few different Simulink files are used: -
    -

    3.2.2 Measurement Noise

    +
    +

    3.2.2 Measurement Noise

    -
    Table 4: List of Disturbances
    +
    @@ -1094,10 +1095,10 @@ Few different Simulink files are used: -
    -

    3.2.3 Control Inputs

    +
    +

    3.2.3 Control Inputs

    -
    Table 5: List of Measurement Noise
    +
    @@ -1219,10 +1220,10 @@ Few different Simulink files are used: -
    -

    3.3 List of Outputs

    +
    +

    3.3 List of Outputs

    -
    Table 6: List of Control Inputs
    +
    @@ -1338,11 +1339,11 @@ Few different Simulink files are used: -
    -

    4 Simulink Library

    +
    +

    4 Simulink Library

    - +

    @@ -1350,8 +1351,8 @@ A simulink library is developed in order to share elements between the different

    -
    -

    4.1 inputs

    +
    +

    4.1 inputs

    inputs.slx @@ -1359,8 +1360,8 @@ A simulink library is developed in order to share elements between the different

    -
    -

    4.2 nass_library

    +
    +

    4.2 nass_library

    nasslibrary.slx @@ -1368,8 +1369,8 @@ A simulink library is developed in order to share elements between the different

    -
    -

    4.3 pos_error_wrt_nass_base

    +
    +

    4.3 pos_error_wrt_nass_base

    poserrorwrtnassbase.slx @@ -1377,8 +1378,8 @@ A simulink library is developed in order to share elements between the different

    -
    -

    4.4 QuaternionToAngles

    +
    +

    4.4 QuaternionToAngles

    QuaternionToAngles.slx @@ -1386,8 +1387,8 @@ A simulink library is developed in order to share elements between the different

    -
    -

    4.5 RotationMatrixToAngle

    +
    +

    4.5 RotationMatrixToAngle

    RotationMatrixToAngle.slx @@ -1396,18 +1397,18 @@ A simulink library is developed in order to share elements between the different

    -
    -

    5 Functions

    +
    +

    5 Functions

    - +

    -
    -

    5.1 computePsdDispl

    +
    +

    5.1 computePsdDispl

    - +

    @@ -1443,11 +1444,11 @@ This Matlab function is accessible here.

    -
    -

    5.2 computeSetpoint

    +
    +

    5.2 computeSetpoint

    - +

    @@ -1519,11 +1520,11 @@ setpoint( -

    5.3 converErrorBasis

    +
    +

    5.3 converErrorBasis

    - +

    @@ -1661,11 +1662,11 @@ error_nass = [dx; dy; dz; th

    -
    -

    5.4 generateDiagPidControl

    +
    +

    5.4 generateDiagPidControl

    - +

    @@ -1695,11 +1696,11 @@ This Matlab function is accessible her

    -
    -

    5.5 identifyPlant

    +
    +

    5.5 identifyPlant

    - +

    @@ -1791,11 +1792,11 @@ This Matlab function is accessible here.

    -
    -

    5.6 runSimulation

    +
    +

    5.6 runSimulation

    - +

    @@ -1864,18 +1865,18 @@ This Matlab function is accessible here.

    -
    -

    6 Initialize Elements

    +
    +

    6 Initialize Elements

    - +

    -
    -

    6.1 Experiment

    +
    +

    6.1 Experiment

    - +

    @@ -1909,11 +1910,11 @@ This Matlab function is accessible here<

    -
    -

    6.2 Generate Reference Signals

    +
    +

    6.2 Generate Reference Signals

    - +

    @@ -1929,10 +1930,10 @@ This Matlab function is accessible here. 'Dy_amplitude', 0, ... % Amplitude of the displacement [m] 'Dy_period', 1, ... % Period of the displacement [s] 'Ry_type', 'constant', ... % Either "constant" / "triangular" / "sinusoidal" - 'Ry_amplitude', 0, ... % Amplitude [deg] + 'Ry_amplitude', 0, ... % Amplitude [rad] 'Ry_period', 10, ... % Period of the displacement [s] 'Rz_type', 'constant', ... % Either "constant" / "rotating" - 'Rz_amplitude', 0, ... % Initial angle [deg] + 'Rz_amplitude', 0, ... % Initial angle [rad] 'Rz_period', 1, ... % Period of the rotating [s] 'Dh_type', 'constant', ... % For now, only constant is implemented 'Dh_pos', [0; 0; 0; 0; 0; 0], ... % Initial position [m,m,m,rad,rad,rad] of the top platform @@ -1976,13 +1977,13 @@ This Matlab function is accessible here. switch opts.Ry_type case 'constant' - Ry(:) = pi/180*opts.Ry_amplitude; + Ry(:) = opts.Ry_amplitude; case 'triangular' - Ry(:) = -4*(pi/180*opts.Ry_amplitude) + 4*(pi/180*opts.Ry_amplitude)/opts.Ry_period*t; - Ry(t<0.75*opts.Ry_period) = 2*(pi/180*opts.Ry_amplitude) - 4*(pi/180*opts.Ry_amplitude)/opts.Ry_period*t(t<0.75*opts.Ry_period); - Ry(t<0.25*opts.Ry_period) = 4*(pi/180*opts.Ry_amplitude)/opts.Ry_period*t(t<0.25*opts.Ry_period); + Ry(:) = -4*opts.Ry_amplitude + 4*opts.Ry_amplitude/opts.Ry_period*t; + Ry(t<0.75*opts.Ry_period) = 2*opts.Ry_amplitude - 4*opts.Ry_amplitude/opts.Ry_period*t(t<0.75*opts.Ry_period); + Ry(t<0.25*opts.Ry_period) = 4*opts.Ry_amplitude/opts.Ry_period*t(t<0.25*opts.Ry_period); case 'sinusoidal' - Ry(:) = opts.Ry_amplitude*sin(2*pi/opts.Ry_period*t); + otherwise warning('Ry_type is not set correctly'); end @@ -1994,9 +1995,9 @@ This Matlab function is accessible here. switch opts.Rz_type case 'constant' - Rz(:) = pi/180*opts.Rz_amplitude; + Rz(:) = opts.Rz_amplitude; case 'rotating' - Rz(:) = pi/180*opts.Rz_amplitude+2*pi/opts.Rz_period*t; + Rz(:) = opts.Rz_amplitude+2*pi/opts.Rz_period*t; otherwise warning('Rz_type is not set correctly'); end @@ -2006,8 +2007,6 @@ This Matlab function is accessible here. t = [0, Ts]; Dh = zeros(length(t), 6); - opts.Dh_pos(4:6) = pi/180*opts.Dh_pos(4:6); % convert from [deg] to [rad] - switch opts.Dh_type case 'constant' Dh = [opts.Dh_pos, opts.Dh_pos]; @@ -2025,8 +2024,6 @@ This Matlab function is accessible here. t = [0, Ts]; Dn = zeros(length(t), 6); - opts.Dn_pos(4:6) = pi/180*opts.Dn_pos(4:6); % convert from [deg] to [rad] - switch opts.Dn_type case 'constant' Dn = [opts.Dn_pos, opts.Dn_pos]; @@ -2043,11 +2040,11 @@ This Matlab function is accessible here.

    -
    -

    6.3 TODO Inputs

    +
    +

    6.3 TODO Inputs

    - +

      @@ -2239,11 +2236,11 @@ This Matlab function is accessible here.
    -
    -

    6.4 Ground

    +
    +

    6.4 Ground

    - +

    @@ -2267,11 +2264,11 @@ This Matlab function is accessible here.

    -
    -

    6.5 Granite

    +
    +

    6.5 Granite

    - +

    @@ -2337,11 +2334,11 @@ This Matlab function is accessible here

    -
    -

    6.6 Translation Stage

    +
    +

    6.6 Translation Stage

    - +

    @@ -2423,11 +2420,11 @@ This Matlab function is accessible here.

    -
    -

    6.7 Tilt Stage

    +
    +

    6.7 Tilt Stage

    - +

    @@ -2498,11 +2495,11 @@ This Matlab function is accessible here.

    -
    -

    6.8 Spindle

    +
    +

    6.8 Spindle

    - +

    @@ -2569,11 +2566,49 @@ This Matlab function is accessible here.

    -
    -

    6.9 Micro Hexapod

    +
    +

    6.9 Initialize Hexapod legs' length

    - + +

    + +

    +This Matlab function is accessible here. +

    + +
    +
    function [hexapod] = initializeHexapodPosition(hexapod, AP, ARB)
    +% initializeHexapodPosition -
    +%
    +% Syntax: initializeHexapodPosition(hexapod, AP, ARB)
    +%
    +% Inputs:
    +%    - hexapod - Hexapod object containing the geometry of the hexapod
    +%    - AP - Position vector of point OB expressed in frame {A}
    +%    - ARB - Rotation Matrix expressed in frame {A}
    +
    +  L0 = zeros(6, 1);
    +
    +  for i = 1:length(L)
    +    Bbi = hexapod.pos_top_tranform(i, :)';
    +    Aai = hexapod.pos_base(i, :)';
    +
    +    L0(i) = sqrt(AP'*AP + Bbi'*Bbi + Aai'*Aai - 2*AP'*Aai + 2*AP'*(ARB*Bbi) - 2*(ARB*Bbi)'*Aai);
    +  end
    +
    +  hexapod.L0 = L0;
    +end
    +
    +
    +
    +
    + +
    +

    6.10 Micro Hexapod

    +
    +

    +

    @@ -2583,7 +2618,11 @@ This Matlab function is accessible her

    function [micro_hexapod] = initializeMicroHexapod(opts_param)
         %% Default values for opts
    -    opts = struct('rigid', false);
    +    opts = struct(...
    +      'rigid', false, ...
    +      'AP',    zeros(3, 1), ... % Wanted position in [m] of OB with respect to frame {A}
    +      'ARB',   eye(3) ...       % Rotation Matrix that represent the wanted orientation of frame {B} with respect to frame {A}
    +    );
     
         %% Populate opts with input parameters
         if exist('opts_param','var')
    @@ -2595,7 +2634,7 @@ This Matlab function is accessible her
         %% Stewart Object
         micro_hexapod = struct();
         micro_hexapod.h        = 350; % Total height of the platform [mm]
    -    micro_hexapod.jacobian = 270; % Distance from the top platform to the Jacobian point [mm]
    +    micro_hexapod.jacobian = 270; % Distance from the top of the mobile platform to the Jacobian point [mm]
     
         %% Bottom Plate - Mechanical Design
         BP = struct();
    @@ -2630,7 +2669,7 @@ This Matlab function is accessible her
         else
           Leg.k.ax     = 2e7; % Stiffness of each leg [N/m]
         end
    -    Leg.ksi.ax     = 0.1;     % Modal damping ksi = 1/2*c/sqrt(km) []
    +    Leg.ksi.ax     = 0.1;   % Modal damping ksi = 1/2*c/sqrt(km) []
         Leg.rad.bottom = 25;    % Radius of the cylinder of the bottom part [mm]
         Leg.rad.top    = 17;    % Radius of the cylinder of the top part [mm]
         Leg.density    = 8000;  % Density of the material [kg/m^3]
    @@ -2676,6 +2715,9 @@ This Matlab function is accessible her
         %%
         micro_hexapod = initializeParameters(micro_hexapod);
     
    +    %% Setup equilibrium position of each leg
    +    micro_hexapod.L0 = initializeHexapodPosition(micro_hexapod, opts.AP, opts.ARB);
    +
         %% Save
         save('./mat/stages.mat', 'micro_hexapod', '-append');
     
    @@ -2769,24 +2811,47 @@ This Matlab function is accessible her
             stewart.J  = getJacobianMatrix(leg_vectors', aa');
         end
     
    -    function J  = getJacobianMatrix(RM,M_pos_base)
    +    %%
    +    function J  = getJacobianMatrix(RM, M_pos_base)
             % RM: [3x6] unit vector of each leg in the fixed frame
             % M_pos_base: [3x6] vector of the leg connection at the top platform location in the fixed frame
             J = zeros(6);
             J(:, 1:3) = RM';
             J(:, 4:6) = cross(M_pos_base, RM)';
         end
    +
    +    %%
    +    function [L] = initializeHexapodPosition(hexapod, AP, ARB)
    +    % initializeHexapodPosition - Compute the initial position of each leg to have the wanted Hexapod's position
    +    %
    +    % Syntax: initializeHexapodPosition(hexapod, AP, ARB)
    +    %
    +    % Inputs:
    +    %    - hexapod - Hexapod object containing the geometry of the hexapod
    +    %    - AP - Position vector of point OB expressed in frame {A} in [m]
    +    %    - ARB - Rotation Matrix expressed in frame {A}
    +
    +      % Wanted Length of the hexapod's legs [m]
    +      L = zeros(6, 1);
    +
    +      for i = 1:length(L)
    +        Bbi = hexapod.pos_top_tranform(i, :)' - 1e-3*[0 ; 0 ; hexapod.TP.thickness+hexapod.Leg.sphere.top+hexapod.SP.thickness.top+hexapod.jacobian]; % [m]
    +        Aai = hexapod.pos_base(i, :)' + 1e-3*[0 ; 0 ; hexapod.BP.thickness+hexapod.Leg.sphere.bottom+hexapod.SP.thickness.bottom-micro_hexapod.h-hexapod.jacobian]; % [m]
    +
    +        L(i) = sqrt(AP'*AP + Bbi'*Bbi + Aai'*Aai - 2*AP'*Aai + 2*AP'*(ARB*Bbi) - 2*(ARB*Bbi)'*Aai);
    +      end
    +    end
     end
     
    -
    -

    6.10 Center of gravity compensation

    -
    +
    +

    6.11 Center of gravity compensation

    +

    - +

    @@ -2830,11 +2895,11 @@ This Matlab function is accessible here.

    -
    -

    6.11 Mirror

    -
    +
    +

    6.12 Mirror

    +

    - +

    @@ -2900,11 +2965,11 @@ This Matlab function is accessible here.

    -
    -

    6.12 Nano Hexapod

    -
    +
    +

    6.13 Nano Hexapod

    +

    - +

    @@ -3121,11 +3186,11 @@ This Matlab function is accessible here

    -
    -

    6.13 Cedrat Actuator

    -
    +
    +

    6.14 Cedrat Actuator

    +

    - +

    @@ -3165,11 +3230,11 @@ This Matlab function is accessible here

    -
    -

    6.14 Sample

    -
    +
    +

    6.15 Sample

    +

    - +

    @@ -3214,7 +3279,7 @@ This Matlab function is accessible here.

    Author: Dehaeze Thomas

    -

    Created: 2019-12-06 ven. 12:04

    +

    Created: 2019-12-10 mar. 18:05

    Validate

    diff --git a/simscape/index.org b/simscape/index.org index 6f74b68..7909dc4 100644 --- a/simscape/index.org +++ b/simscape/index.org @@ -797,6 +797,7 @@ This Matlab function is accessible [[file:../src/initializeExperiment.m][here]]. :header-args:matlab+: :comments org :mkdirp yes :header-args:matlab+: :eval no :results none :END: + <> This Matlab function is accessible [[file:../src/initializeInputs.m][here]]. @@ -810,10 +811,10 @@ This Matlab function is accessible [[file:../src/initializeInputs.m][here]]. 'Dy_amplitude', 0, ... % Amplitude of the displacement [m] 'Dy_period', 1, ... % Period of the displacement [s] 'Ry_type', 'constant', ... % Either "constant" / "triangular" / "sinusoidal" - 'Ry_amplitude', 0, ... % Amplitude [deg] + 'Ry_amplitude', 0, ... % Amplitude [rad] 'Ry_period', 10, ... % Period of the displacement [s] 'Rz_type', 'constant', ... % Either "constant" / "rotating" - 'Rz_amplitude', 0, ... % Initial angle [deg] + 'Rz_amplitude', 0, ... % Initial angle [rad] 'Rz_period', 1, ... % Period of the rotating [s] 'Dh_type', 'constant', ... % For now, only constant is implemented 'Dh_pos', [0; 0; 0; 0; 0; 0], ... % Initial position [m,m,m,rad,rad,rad] of the top platform @@ -857,13 +858,13 @@ This Matlab function is accessible [[file:../src/initializeInputs.m][here]]. switch opts.Ry_type case 'constant' - Ry(:) = pi/180*opts.Ry_amplitude; + Ry(:) = opts.Ry_amplitude; case 'triangular' - Ry(:) = -4*(pi/180*opts.Ry_amplitude) + 4*(pi/180*opts.Ry_amplitude)/opts.Ry_period*t; - Ry(t<0.75*opts.Ry_period) = 2*(pi/180*opts.Ry_amplitude) - 4*(pi/180*opts.Ry_amplitude)/opts.Ry_period*t(t<0.75*opts.Ry_period); - Ry(t<0.25*opts.Ry_period) = 4*(pi/180*opts.Ry_amplitude)/opts.Ry_period*t(t<0.25*opts.Ry_period); + Ry(:) = -4*opts.Ry_amplitude + 4*opts.Ry_amplitude/opts.Ry_period*t; + Ry(t<0.75*opts.Ry_period) = 2*opts.Ry_amplitude - 4*opts.Ry_amplitude/opts.Ry_period*t(t<0.75*opts.Ry_period); + Ry(t<0.25*opts.Ry_period) = 4*opts.Ry_amplitude/opts.Ry_period*t(t<0.25*opts.Ry_period); case 'sinusoidal' - Ry(:) = opts.Ry_amplitude*sin(2*pi/opts.Ry_period*t); + otherwise warning('Ry_type is not set correctly'); end @@ -875,9 +876,9 @@ This Matlab function is accessible [[file:../src/initializeInputs.m][here]]. switch opts.Rz_type case 'constant' - Rz(:) = pi/180*opts.Rz_amplitude; + Rz(:) = opts.Rz_amplitude; case 'rotating' - Rz(:) = pi/180*opts.Rz_amplitude+2*pi/opts.Rz_period*t; + Rz(:) = opts.Rz_amplitude+2*pi/opts.Rz_period*t; otherwise warning('Rz_type is not set correctly'); end @@ -887,8 +888,6 @@ This Matlab function is accessible [[file:../src/initializeInputs.m][here]]. t = [0, Ts]; Dh = zeros(length(t), 6); - opts.Dh_pos(4:6) = pi/180*opts.Dh_pos(4:6); % convert from [deg] to [rad] - switch opts.Dh_type case 'constant' Dh = [opts.Dh_pos, opts.Dh_pos]; @@ -906,8 +905,6 @@ This Matlab function is accessible [[file:../src/initializeInputs.m][here]]. t = [0, Ts]; Dn = zeros(length(t), 6); - opts.Dn_pos(4:6) = pi/180*opts.Dn_pos(4:6); % convert from [deg] to [rad] - switch opts.Dn_type case 'constant' Dn = [opts.Dn_pos, opts.Dn_pos]; @@ -1421,6 +1418,40 @@ This Matlab function is accessible [[file:../src/initializeRz.m][here]]. end #+end_src +** Initialize Hexapod legs' length +:PROPERTIES: +:header-args:matlab+: :tangle ../src/initializeHexapodPosition.m +:header-args:matlab+: :comments org :mkdirp yes +:header-args:matlab+: :eval no :results none +:END: +<> + +This Matlab function is accessible [[file:../src/initializeHexapodPosition.m][here]]. + +#+begin_src matlab + function [hexapod] = initializeHexapodPosition(hexapod, AP, ARB) + % initializeHexapodPosition - + % + % Syntax: initializeHexapodPosition(hexapod, AP, ARB) + % + % Inputs: + % - hexapod - Hexapod object containing the geometry of the hexapod + % - AP - Position vector of point OB expressed in frame {A} + % - ARB - Rotation Matrix expressed in frame {A} + + L0 = zeros(6, 1); + + for i = 1:length(L) + Bbi = hexapod.pos_top_tranform(i, :)'; + Aai = hexapod.pos_base(i, :)'; + + L0(i) = sqrt(AP'*AP + Bbi'*Bbi + Aai'*Aai - 2*AP'*Aai + 2*AP'*(ARB*Bbi) - 2*(ARB*Bbi)'*Aai); + end + + hexapod.L0 = L0; + end +#+end_src + ** Micro Hexapod :PROPERTIES: :header-args:matlab+: :tangle ../src/initializeMicroHexapod.m @@ -1434,7 +1465,11 @@ This Matlab function is accessible [[file:../src/initializeMicroHexapod.m][here] #+begin_src matlab function [micro_hexapod] = initializeMicroHexapod(opts_param) %% Default values for opts - opts = struct('rigid', false); + opts = struct(... + 'rigid', false, ... + 'AP', zeros(3, 1), ... % Wanted position in [m] of OB with respect to frame {A} + 'ARB', eye(3) ... % Rotation Matrix that represent the wanted orientation of frame {B} with respect to frame {A} + ); %% Populate opts with input parameters if exist('opts_param','var') @@ -1446,7 +1481,7 @@ This Matlab function is accessible [[file:../src/initializeMicroHexapod.m][here] %% Stewart Object micro_hexapod = struct(); micro_hexapod.h = 350; % Total height of the platform [mm] - micro_hexapod.jacobian = 270; % Distance from the top platform to the Jacobian point [mm] + micro_hexapod.jacobian = 270; % Distance from the top of the mobile platform to the Jacobian point [mm] %% Bottom Plate - Mechanical Design BP = struct(); @@ -1481,7 +1516,7 @@ This Matlab function is accessible [[file:../src/initializeMicroHexapod.m][here] else Leg.k.ax = 2e7; % Stiffness of each leg [N/m] end - Leg.ksi.ax = 0.1; % Modal damping ksi = 1/2*c/sqrt(km) [] + Leg.ksi.ax = 0.1; % Modal damping ksi = 1/2*c/sqrt(km) [] Leg.rad.bottom = 25; % Radius of the cylinder of the bottom part [mm] Leg.rad.top = 17; % Radius of the cylinder of the top part [mm] Leg.density = 8000; % Density of the material [kg/m^3] @@ -1527,6 +1562,9 @@ This Matlab function is accessible [[file:../src/initializeMicroHexapod.m][here] %% micro_hexapod = initializeParameters(micro_hexapod); + %% Setup equilibrium position of each leg + micro_hexapod.L0 = initializeHexapodPosition(micro_hexapod, opts.AP, opts.ARB); + %% Save save('./mat/stages.mat', 'micro_hexapod', '-append'); @@ -1620,13 +1658,36 @@ This Matlab function is accessible [[file:../src/initializeMicroHexapod.m][here] stewart.J = getJacobianMatrix(leg_vectors', aa'); end - function J = getJacobianMatrix(RM,M_pos_base) + %% + function J = getJacobianMatrix(RM, M_pos_base) % RM: [3x6] unit vector of each leg in the fixed frame % M_pos_base: [3x6] vector of the leg connection at the top platform location in the fixed frame J = zeros(6); J(:, 1:3) = RM'; J(:, 4:6) = cross(M_pos_base, RM)'; end + + %% + function [L] = initializeHexapodPosition(hexapod, AP, ARB) + % initializeHexapodPosition - Compute the initial position of each leg to have the wanted Hexapod's position + % + % Syntax: initializeHexapodPosition(hexapod, AP, ARB) + % + % Inputs: + % - hexapod - Hexapod object containing the geometry of the hexapod + % - AP - Position vector of point OB expressed in frame {A} in [m] + % - ARB - Rotation Matrix expressed in frame {A} + + % Wanted Length of the hexapod's legs [m] + L = zeros(6, 1); + + for i = 1:length(L) + Bbi = hexapod.pos_top_tranform(i, :)' - 1e-3*[0 ; 0 ; hexapod.TP.thickness+hexapod.Leg.sphere.top+hexapod.SP.thickness.top+hexapod.jacobian]; % [m] + Aai = hexapod.pos_base(i, :)' + 1e-3*[0 ; 0 ; hexapod.BP.thickness+hexapod.Leg.sphere.bottom+hexapod.SP.thickness.bottom-micro_hexapod.h-hexapod.jacobian]; % [m] + + L(i) = sqrt(AP'*AP + Bbi'*Bbi + Aai'*Aai - 2*AP'*Aai + 2*AP'*(ARB*Bbi) - 2*(ARB*Bbi)'*Aai); + end + end end #+end_src diff --git a/simscape_subsystems/hexapod_leg.slx b/simscape_subsystems/hexapod_leg.slx new file mode 100644 index 0000000000000000000000000000000000000000..497b5defbed710689af6ee0a91e6f164938d13ce GIT binary patch literal 26042 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
    Table 7: List of Outputs