+
4.1 computeReferencePose
+
-
+
@@ -821,13 +886,17 @@ This Matlab function is accessible here
-
function [WTr] = computeReferencePose(Dy, Ry, Rz, Dh)
+function [WTr] = computeReferencePose(Dy, Ry, Rz, Dh, Dn)
-
+
-
+
+
+
+
+
@@ -869,10 +938,30 @@ This Matlab function is accessible here
0 0 1 Dh(3) ;
0 0 0 1 ];
- Rh(1:3, 1:3) = Rhx*Rhy*Rhz;
+ Rh(1:3, 1:3) = Rhz*Rhy*Rhx;
+
+
+ Rnx = [1 0 0;
+ 0 cos(Dn(4)) -sin(Dn(4));
+ 0 sin(Dn(4)) cos(Dn(4))];
+
+ Rny = [ cos(Dn(5)) 0 sin(Dn(5));
+ 0 1 0;
+ -sin(Dn(5)) 0 cos(Dn(5))];
+
+ Rnz = [cos(Dn(6)) -sin(Dn(6)) 0;
+ sin(Dn(6)) cos(Dn(6)) 0;
+ 0 0 1];
+
+ Rn = [1 0 0 Dn(1) ;
+ 0 1 0 Dn(2) ;
+ 0 0 1 Dn(3) ;
+ 0 0 0 1 ];
+
+ Rn(1:3, 1:3) = Rnx*Rny*Rnz;
- WTr = Rty*Rry*Rrz*Rh;
+ WTr = Rty*Rry*Rrz*Rh*Rn;
end
@@ -882,7 +971,7 @@ This Matlab function is accessible
here
Author: Dehaeze Thomas
-
Created: 2019-12-06 ven. 12:02
+
Created: 2019-12-11 mer. 09:33
Validate
diff --git a/metrology/index.org b/metrology/index.org
index 243325e..45f9388 100644
--- a/metrology/index.org
+++ b/metrology/index.org
@@ -64,7 +64,7 @@ The follower frame is attached to the sample (or more precisely to the reflector
The outputs of the transform sensor are:
- the 3 translations x, y and z in meter
-- the rotation matrix $\boldsymbol{R}$ that permits to rotate the base frame into the follower frame.
+- the *rotation matrix* $\bm{R}$ that permits to rotate the base frame into the follower frame.
We can then determine extract other orientation conventions such that Euler angles or screw axis.
@@ -101,6 +101,20 @@ We set a small =StopTime=.
set_param(conf_simscape, 'StopTime', '0.5');
#+end_src
+We initialize all the stages.
+#+begin_src matlab
+ initializeGround();
+ initializeGranite();
+ initializeTy();
+ initializeRy();
+ initializeRz();
+ initializeMicroHexapod();
+ initializeAxisc();
+ initializeMirror();
+ initializeNanoHexapod(struct('actuator', 'piezo'));
+ initializeSample(struct('mass', 50));
+#+end_src
+
We setup the reference path to be constant.
#+begin_src matlab
opts = struct( ...
@@ -115,11 +129,11 @@ We setup the reference path to be constant.
'Rz_amplitude', -135*pi/180, ... % 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; -3*pi/180; 1*pi/180; 3*pi/180], ... % Initial position [m,m,m,rad,rad,rad] of the top platform
+ 'Dh_pos', [0.01; 0.02; -0.03; -3*pi/180; 1*pi/180; 3*pi/180], ... % Initial position [m,m,m,rad,rad,rad] of the top platform
'Rm_type', 'constant', ... % For now, only constant is implemented
'Rm_pos', [0, pi]', ... % Initial position of the two masses
'Dn_type', 'constant', ... % For now, only constant is implemented
- 'Dn_pos', [1e-3; 0; 0; 1*pi/180; 0; 1*pi/180] ... % Initial position [m,m,m,rad,rad,rad] of the top platform
+ 'Dn_pos', [1e-3; 2e-3; 3e-3; 1*pi/180; 0; 1*pi/180] ... % Initial position [m,m,m,rad,rad,rad] of the top platform
);
initializeReferences(opts);
@@ -146,8 +160,8 @@ Let's denote:
- $\{M\}$ the frame corresponding to the measured pose of the sample
We have then computed:
-- ${}^W\boldsymbol{T}_R$ which corresponds to the wanted pose of the sample with respect to the granite
-- ${}^W\boldsymbol{T}_M$ which corresponds to the measured pose of the sample with respect to the granite
+- ${}^W\bm{T}_R$ which corresponds to the wanted pose of the sample with respect to the granite
+- ${}^W\bm{T}_M$ which corresponds to the measured pose of the sample with respect to the granite
We load the reference and we compute the desired trajectory of the sample in the form of an homogeneous transformation matrix ${}^WT_R$.
#+begin_src matlab
@@ -169,11 +183,11 @@ From that we can compute the homogeneous transformation matrix ${}^WT_M$.
#+end_src
As the simulation is perfect (no measurement error and no motion error), we should have that
-\[ {}^W\boldsymbol{T}_R = {}^W\boldsymbol{T}_M \]
+\[ {}^W\bm{T}_R = {}^W\bm{T}_M \]
Or are least:
-\[ {}^W\boldsymbol{T}_R(1:3, 4) = {}^W\boldsymbol{T}_M(1:3, 4) \]
-\[ {}^W\boldsymbol{R}_R^t \cdot {}^W\boldsymbol{R}_M = \boldsymbol{I}_3 \]
+\[ {}^W\bm{T}_R(1:3, 4) = {}^W\bm{T}_M(1:3, 4) \]
+\[ {}^W\bm{R}_R^t \cdot {}^W\bm{R}_M = \bm{I}_3 \]
#+begin_src matlab :results output replace
WTr(1:3, 4, end)-WTm(1:3, 4, end)
@@ -184,14 +198,14 @@ Or are least:
#+begin_example
WTr(1:3, 4, end)-WTm(1:3, 4, end)
ans =
- -8.47173893536723e-15
- -1.38430933382949e-15
- -8.88361324636402e-16
+ 1.8027246362351e-14
+ 1.40408518145563e-14
+ 6.93889390390723e-17
WTr(1:3, 1:3, end)'*WTm(1:3, 1:3, end)-eye(3)
ans =
- 2.66453525910038e-15 1.19459143341844e-15 -1.07098845850834e-17
- -1.185456383777e-15 2.66453525910038e-15 2.9392720896082e-16
- 1.07732002978906e-17 -2.9392720896082e-16 2.88657986402541e-15
+ 1.59872115546023e-14 -1.56629266848118e-14 -3.71230823859037e-16
+ 1.56742023874057e-14 1.59872115546023e-14 -2.12330153459561e-15
+ -1.14144804719274e-15 -5.51642065360625e-16 9.28146448586631e-14
#+end_example
** Conclusion
@@ -276,17 +290,17 @@ And we run the simulation.
** Compute the wanted pose of the sample in the NASS Base from the metrology and the reference
Now that we have introduced some positioning error, the computed wanted pose and the measured pose will not be the same.
-We would like to compute ${}^M\boldsymbol{T}_R$ which corresponds to the wanted pose of the sample expressed in a frame attached to the top platform of the nano-hexapod (frame $\{M\}$).
+We would like to compute ${}^M\bm{T}_R$ which corresponds to the wanted pose of the sample expressed in a frame attached to the top platform of the nano-hexapod (frame $\{M\}$).
We have:
\begin{align}
- {}^M\boldsymbol{T}_R &= {}^M\boldsymbol{T}_W \cdot {}^W\boldsymbol{T}_R \\
- &= {}^W{\boldsymbol{T}_M}^{-1} \cdot {}^W\boldsymbol{T}_R
+ {}^M\bm{T}_R &= {}^M\bm{T}_W \cdot {}^W\bm{T}_R \\
+ &= {}^W{\bm{T}_M}^{-1} \cdot {}^W\bm{T}_R
\end{align}
-The top platform of the nano-hexapod is considered to be rigidly connected to the sample, thus, ${}^M\boldsymbol{T}_R$ corresponds to the pose error of the sample with respect to the nano-hexapod platform.
+The top platform of the nano-hexapod is considered to be rigidly connected to the sample, thus, ${}^M\bm{T}_R$ corresponds to the pose error of the sample with respect to the nano-hexapod platform.
-We load the reference and we compute the desired trajectory of the sample in the form of an homogeneous transformation matrix ${}^W\boldsymbol{T}_R$.
+We load the reference and we compute the desired trajectory of the sample in the form of an homogeneous transformation matrix ${}^W\bm{T}_R$.
#+begin_src matlab
n = length(Dref.Dy.Time);
WTr = zeros(4, 4, n);
@@ -296,7 +310,7 @@ We load the reference and we compute the desired trajectory of the sample in the
#+end_src
We also measure in simulation the pose of the sample with respect to the granite.
-From that we can compute the homogeneous transformation matrix ${}^W\boldsymbol{T}_M$.
+From that we can compute the homogeneous transformation matrix ${}^W\bm{T}_M$.
#+begin_src matlab
n = length(Dsm.R.Time);
WTm = zeros(4, 4, n);
@@ -307,17 +321,17 @@ From that we can compute the homogeneous transformation matrix ${}^W\boldsymbol{
The *inverse of the transformation matrix* can be obtain by (it is less computation intensive than doing a full inverse)
\begin{equation}
- {}^B\boldsymbol{T}_A = {}^A\boldsymbol{T}_B^{-1} =
+ {}^B\bm{T}_A = {}^A\bm{T}_B^{-1} =
\left[ \begin{array}{ccc|c}
& & & \\
- & {}^A\boldsymbol{R}_B^T & & -{}^A \boldsymbol{R}_B^T {}^A\boldsymbol{P}_{O_B} \\
+ & {}^A\bm{R}_B^T & & -{}^A \bm{R}_B^T {}^A\bm{P}_{O_B} \\
& & & \\
\hline
0 & 0 & 0 & 1 \\
\end{array} \right]
\end{equation}
-Finally, we compute ${}^M\boldsymbol{T}_R$.
+Finally, we compute ${}^M\bm{T}_R$.
#+begin_src matlab
MTr = zeros(4, 4, n);
for i = 1:n
@@ -372,10 +386,10 @@ And we run the simulation.
sim('simscape/sim_nano_station_metrology.slx');
#+end_src
-We keep the old computed computed reference pose ${}^W\boldsymbol{T}_r$ even though we have change the nano hexapod reference, but this is not a real wanted reference but rather a adaptation to reject the positioning errors.
+We keep the old computed computed reference pose ${}^W\bm{T}_r$ even though we have change the nano hexapod reference, but this is not a real wanted reference but rather a adaptation to reject the positioning errors.
As the displacement is perfect, we also measure in simulation the pose of the sample with respect to the granite.
-From that we can compute the homogeneous transformation matrix ${}^W\boldsymbol{T}_M$.
+From that we can compute the homogeneous transformation matrix ${}^W\bm{T}_M$.
#+begin_src matlab
n = length(Dsm.R.Time);
WTm = zeros(4, 4, n);
@@ -384,7 +398,7 @@ From that we can compute the homogeneous transformation matrix ${}^W\boldsymbol{
WTm(4, 4, :) = 1;
#+end_src
-Finally, we compute ${}^M\boldsymbol{T}_R$.
+Finally, we compute ${}^M\bm{T}_R$.
#+begin_src matlab
MTr = zeros(4, 4, n);
for i = 1:n
@@ -437,7 +451,7 @@ This Matlab function is accessible [[file:src/computeReferencePose.m][here]].
% - Dy - Reference of the Translation Stage [m]
% - Ry - Reference of the Tilt Stage [rad]
% - Rz - Reference of the Spindle [rad]
- % - Dh - Reference of the Micro Hexapod [m, m, m, rad, rad, rad]
+ % - Dh - Reference of the Micro Hexapod (Pitch, Roll, Yaw angles) [m, m, m, rad, rad, rad]
% - Dn - Reference of the Nano Hexapod [m, m, m, rad, rad, rad]
%
% Outputs:
@@ -480,7 +494,7 @@ This Matlab function is accessible [[file:src/computeReferencePose.m][here]].
0 0 1 Dh(3) ;
0 0 0 1 ];
- Rh(1:3, 1:3) = Rhx*Rhy*Rhz;
+ Rh(1:3, 1:3) = Rhz*Rhy*Rhx;
%% Nano-Hexapod
Rnx = [1 0 0;
@@ -534,8 +548,8 @@ Let's define the following frames:
The origin of $T$ is $O_T$ and is the wanted position of the sample.
Thus:
-- the *measurement* of the position of the sample corresponds to ${}^W O_S = \begin{bmatrix} {}^WP_{x,m} & {}^WP_{y,m} & {}^WP_{z,m} \end{bmatrix}^T$ in translation and to $\theta_m {}^W\boldsymbol{s}_m = \theta_m \cdot \begin{bmatrix} {}^Ws_{x,m} & {}^Ws_{y,m} & {}^Ws_{z,m} \end{bmatrix}^T$ in rotations
-- the *wanted position* of the sample expressed w.r.t. the granite is ${}^W O_T = \begin{bmatrix} {}^WP_{x,r} & {}^WP_{y,r} & {}^WP_{z,r} \end{bmatrix}^T$ in translation and to $\theta_r {}^W\boldsymbol{s}_r = \theta_r \cdot \begin{bmatrix} {}^Ws_{x,r} & {}^Ws_{y,r} & {}^Ws_{z,r} \end{bmatrix}^T$ in rotations
+- the *measurement* of the position of the sample corresponds to ${}^W O_S = \begin{bmatrix} {}^WP_{x,m} & {}^WP_{y,m} & {}^WP_{z,m} \end{bmatrix}^T$ in translation and to $\theta_m {}^W\bm{s}_m = \theta_m \cdot \begin{bmatrix} {}^Ws_{x,m} & {}^Ws_{y,m} & {}^Ws_{z,m} \end{bmatrix}^T$ in rotations
+- the *wanted position* of the sample expressed w.r.t. the granite is ${}^W O_T = \begin{bmatrix} {}^WP_{x,r} & {}^WP_{y,r} & {}^WP_{z,r} \end{bmatrix}^T$ in translation and to $\theta_r {}^W\bm{s}_r = \theta_r \cdot \begin{bmatrix} {}^Ws_{x,r} & {}^Ws_{y,r} & {}^Ws_{z,r} \end{bmatrix}^T$ in rotations
** Matlab Init :noexport:ignore:
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
@@ -655,7 +669,7 @@ Let's compute the corresponding orientation using screw axis.
We then obtain the orientation measurement in the form of screw coordinate $\theta_m ({}^Ws_{x,m},\ {}^Ws_{y,m},\ {}^Ws_{z,m})^T$ where:
- $\theta_m = \cos^{-1} \frac{\text{Tr}(R) - 1}{2}$
-- ${}^W\boldsymbol{s}_m$ is the eigen vector of the rotation matrix $R$ corresponding to the eigen value $\lambda = 1$
+- ${}^W\bm{s}_m$ is the eigen vector of the rotation matrix $R$ corresponding to the eigen value $\lambda = 1$
#+begin_src matlab
thetam = acos((trace(STw(1:3, 1:3))-1)/2); % [rad]
@@ -675,7 +689,7 @@ We then obtain the orientation measurement in the form of screw coordinate $\the
The wanted position expressed with respect to the granite is ${}^WO_T$ and the measured position with respect to the granite is ${}^WO_S$, thus the *position error* expressed in $\{W\}$ is
\[ {}^W E = {}^W O_T - {}^W O_S \]
The same is true for rotations:
-\[ \theta_\epsilon {}^W\boldsymbol{s}_\epsilon = \theta_r {}^W\boldsymbol{s}_r - \theta_m {}^W\boldsymbol{s}_m \]
+\[ \theta_\epsilon {}^W\bm{s}_\epsilon = \theta_r {}^W\bm{s}_r - \theta_m {}^W\bm{s}_m \]
#+begin_src matlab
WPe = WPr - WPm;
diff --git a/simscape/index.org b/simscape/index.org
index 7909dc4..ee72cb4 100644
--- a/simscape/index.org
+++ b/simscape/index.org
@@ -755,8 +755,7 @@ This Matlab function is accessible [[file:../src/runSimulation.m][here]].
'time', 'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz', 'K');
end
#+end_src
-* Initialize Elements
-<
>
+* Helping Functions
** Experiment
:PROPERTIES:
:header-args:matlab+: :tangle ../src/initializeExperiment.m
@@ -797,7 +796,6 @@ 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]].
@@ -817,7 +815,7 @@ This Matlab function is accessible [[file:../src/initializeInputs.m][here]].
'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
+ 'Dh_pos', [0; 0; 0; 0; 0; 0], ... % Initial position [m,m,m,rad,rad,rad] of the top platform (Pitch-Roll-Yaw Euler angles)
'Rm_type', 'constant', ... % For now, only constant is implemented
'Rm_pos', [0; pi], ... % Initial position of the two masses
'Dn_type', 'constant', ... % For now, only constant is implemented
@@ -887,14 +885,37 @@ This Matlab function is accessible [[file:../src/initializeInputs.m][here]].
%% Micro-Hexapod
t = [0, Ts];
Dh = zeros(length(t), 6);
+ Dhl = zeros(length(t), 6);
switch opts.Dh_type
case 'constant'
Dh = [opts.Dh_pos, opts.Dh_pos];
+
+ load('./mat/stages.mat', 'micro_hexapod');
+
+ AP = [opts.Dh_pos(1) ; opts.Dh_pos(2) ; opts.Dh_pos(3)];
+
+ tx = opts.Dh_pos(4);
+ ty = opts.Dh_pos(5);
+ tz = opts.Dh_pos(6);
+
+ ARB = [cos(tz) -sin(tz) 0;
+ sin(tz) cos(tz) 0;
+ 0 0 1]*...
+ [ cos(ty) 0 sin(ty);
+ 0 1 0;
+ -sin(ty) 0 cos(ty)]*...
+ [1 0 0;
+ 0 cos(tx) -sin(tx);
+ 0 sin(tx) cos(tx)];
+
+ [Dhl] = inverseKinematicsHexapod(micro_hexapod, AP, ARB);
+ Dhl = [Dhl, Dhl];
otherwise
warning('Dh_type is not set correctly');
end
Dh = struct('time', t, 'signals', struct('values', Dh));
+ Dhl = struct('time', t, 'signals', struct('values', Dhl));
%% Axis Compensation - Rm
t = [0, Ts];
@@ -914,7 +935,7 @@ This Matlab function is accessible [[file:../src/initializeInputs.m][here]].
Dn = struct('time', t, 'signals', struct('values', Dn));
%% Save
- save('./mat/nass_references.mat', 'Dy', 'Ry', 'Rz', 'Dh', 'Rm', 'Dn', 'Ts');
+ save('./mat/nass_references.mat', 'Dy', 'Ry', 'Rz', 'Dh', 'Dhl', 'Rm', 'Dn', 'Ts');
end
#+end_src
@@ -1108,6 +1129,42 @@ This Matlab function is accessible [[file:../src/initializeInputs.m][here]].
end
#+end_src
+** Inverse Kinematics of the Hexapod
+:PROPERTIES:
+:header-args:matlab+: :tangle ../src/inverseKinematicsHexapod.m
+:header-args:matlab+: :comments org :mkdirp yes
+:header-args:matlab+: :eval no :results none
+:END:
+<>
+
+This Matlab function is accessible [[file:src/inverseKinematicsHexapod.m][here]].
+
+#+begin_src matlab
+ function [L] = inverseKinematicsHexapod(hexapod, AP, ARB)
+ % inverseKinematicsHexapod - Compute the initial position of each leg to have the wanted Hexapod's position
+ %
+ % Syntax: inverseKinematicsHexapod(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-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_src
+
+
+* Initialize Elements
+<>
** Ground
:PROPERTIES:
:header-args:matlab+: :tangle ../src/initializeGround.m
@@ -1420,19 +1477,19 @@ This Matlab function is accessible [[file:../src/initializeRz.m][here]].
** Initialize Hexapod legs' length
:PROPERTIES:
-:header-args:matlab+: :tangle ../src/initializeHexapodPosition.m
+:header-args:matlab+: :tangle ../src/inverseKinematicsHexapod.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]].
+This Matlab function is accessible [[file:../src/inverseKinematicsHexapod.m][here]].
#+begin_src matlab
- function [hexapod] = initializeHexapodPosition(hexapod, AP, ARB)
- % initializeHexapodPosition -
+ function [hexapod] = inverseKinematicsHexapod(hexapod, AP, ARB)
+ % inverseKinematicsHexapod -
%
- % Syntax: initializeHexapodPosition(hexapod, AP, ARB)
+ % Syntax: inverseKinematicsHexapod(hexapod, AP, ARB)
%
% Inputs:
% - hexapod - Hexapod object containing the geometry of the hexapod
@@ -1563,7 +1620,7 @@ 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);
+ micro_hexapod.L0 = inverseKinematicsHexapod(micro_hexapod, opts.AP, opts.ARB);
%% Save
save('./mat/stages.mat', 'micro_hexapod', '-append');
@@ -1666,28 +1723,6 @@ This Matlab function is accessible [[file:../src/initializeMicroHexapod.m][here]
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/sim_nano_station_disp.slx b/simscape/sim_nano_station_disp.slx
index 99a295c..97ea0d6 100644
Binary files a/simscape/sim_nano_station_disp.slx and b/simscape/sim_nano_station_disp.slx differ
diff --git a/simscape/sim_nano_station_metrology.slx b/simscape/sim_nano_station_metrology.slx
index a9413db..04b879a 100644
Binary files a/simscape/sim_nano_station_metrology.slx and b/simscape/sim_nano_station_metrology.slx differ
diff --git a/simscape_subsystems/hexapod_leg.slx b/simscape_subsystems/hexapod_leg.slx
index 497b5de..44760e1 100644
Binary files a/simscape_subsystems/hexapod_leg.slx and b/simscape_subsystems/hexapod_leg.slx differ
diff --git a/simscape_subsystems/micro_hexapod_rigid_simple.slx b/simscape_subsystems/micro_hexapod_rigid_simple.slx
index ec66059..c0e1823 100644
Binary files a/simscape_subsystems/micro_hexapod_rigid_simple.slx and b/simscape_subsystems/micro_hexapod_rigid_simple.slx differ
diff --git a/simscape_subsystems/nass_references.slx b/simscape_subsystems/nass_references.slx
index a080576..4252ed2 100644
Binary files a/simscape_subsystems/nass_references.slx and b/simscape_subsystems/nass_references.slx differ
diff --git a/src/computeReferencePose.m b/src/computeReferencePose.m
index a6c4177..e040d2a 100644
--- a/src/computeReferencePose.m
+++ b/src/computeReferencePose.m
@@ -9,13 +9,17 @@
% This Matlab function is accessible [[file:src/computeReferencePose.m][here]].
-function [WTr] = computeReferencePose(Dy, Ry, Rz, Dh)
+function [WTr] = computeReferencePose(Dy, Ry, Rz, Dh, Dn)
% computeReferencePose - Compute the homogeneous transformation matrix corresponding to the wanted pose of the sample
%
-% Syntax: [WTr] = computeReferencePose(Dy, Ry, Rz, Dh)
+% Syntax: [WTr] = computeReferencePose(Dy, Ry, Rz, Dh, Dn)
%
% Inputs:
-% - Dy, Ry, Rz, Dh -
+% - Dy - Reference of the Translation Stage [m]
+% - Ry - Reference of the Tilt Stage [rad]
+% - Rz - Reference of the Spindle [rad]
+% - Dh - Reference of the Micro Hexapod (Pitch, Roll, Yaw angles) [m, m, m, rad, rad, rad]
+% - Dn - Reference of the Nano Hexapod [m, m, m, rad, rad, rad]
%
% Outputs:
% - WTr -
@@ -57,8 +61,28 @@ function [WTr] = computeReferencePose(Dy, Ry, Rz, Dh)
0 0 1 Dh(3) ;
0 0 0 1 ];
- Rh(1:3, 1:3) = Rhx*Rhy*Rhz;
+ Rh(1:3, 1:3) = Rhz*Rhy*Rhx;
+
+ %% Nano-Hexapod
+ Rnx = [1 0 0;
+ 0 cos(Dn(4)) -sin(Dn(4));
+ 0 sin(Dn(4)) cos(Dn(4))];
+
+ Rny = [ cos(Dn(5)) 0 sin(Dn(5));
+ 0 1 0;
+ -sin(Dn(5)) 0 cos(Dn(5))];
+
+ Rnz = [cos(Dn(6)) -sin(Dn(6)) 0;
+ sin(Dn(6)) cos(Dn(6)) 0;
+ 0 0 1];
+
+ Rn = [1 0 0 Dn(1) ;
+ 0 1 0 Dn(2) ;
+ 0 0 1 Dn(3) ;
+ 0 0 0 1 ];
+
+ Rn(1:3, 1:3) = Rnx*Rny*Rnz;
%% Total Homogeneous transformation
- WTr = Rty*Rry*Rrz*Rh;
+ WTr = Rty*Rry*Rrz*Rh*Rn;
end
diff --git a/src/initializeMicroHexapod.m b/src/initializeMicroHexapod.m
index eeeb604..96df29c 100644
--- a/src/initializeMicroHexapod.m
+++ b/src/initializeMicroHexapod.m
@@ -109,7 +109,7 @@ function [micro_hexapod] = initializeMicroHexapod(opts_param)
micro_hexapod = initializeParameters(micro_hexapod);
%% Setup equilibrium position of each leg
- micro_hexapod.L0 = initializeHexapodPosition(micro_hexapod, opts.AP, opts.ARB);
+ micro_hexapod.L0 = inverseKinematicsHexapod(micro_hexapod, opts.AP, opts.ARB);
%% Save
save('./mat/stages.mat', 'micro_hexapod', '-append');
@@ -212,26 +212,4 @@ function [micro_hexapod] = initializeMicroHexapod(opts_param)
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
diff --git a/src/initializeReferences.m b/src/initializeReferences.m
index 4bfc4d4..3606c4b 100644
--- a/src/initializeReferences.m
+++ b/src/initializeReferences.m
@@ -17,13 +17,13 @@ function [ref] = initializeReferences(opts_param)
'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
+ 'Dh_pos', [0; 0; 0; 0; 0; 0], ... % Initial position [m,m,m,rad,rad,rad] of the top platform (Pitch-Roll-Yaw Euler angles)
'Rm_type', 'constant', ... % For now, only constant is implemented
'Rm_pos', [0; pi], ... % Initial position of the two masses
'Dn_type', 'constant', ... % For now, only constant is implemented
@@ -64,13 +64,13 @@ function [ref] = initializeReferences(opts_param)
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
@@ -82,9 +82,9 @@ function [ref] = initializeReferences(opts_param)
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
@@ -93,16 +93,37 @@ function [ref] = initializeReferences(opts_param)
%% Micro-Hexapod
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]
+ Dhl = zeros(length(t), 6);
switch opts.Dh_type
case 'constant'
Dh = [opts.Dh_pos, opts.Dh_pos];
+
+ load('./mat/stages.mat', 'micro_hexapod');
+
+ AP = [opts.Dh_pos(1) ; opts.Dh_pos(2) ; opts.Dh_pos(3)];
+
+ tx = opts.Dh_pos(4);
+ ty = opts.Dh_pos(5);
+ tz = opts.Dh_pos(6);
+
+ ARB = [cos(tz) -sin(tz) 0;
+ sin(tz) cos(tz) 0;
+ 0 0 1]*...
+ [ cos(ty) 0 sin(ty);
+ 0 1 0;
+ -sin(ty) 0 cos(ty)]*...
+ [1 0 0;
+ 0 cos(tx) -sin(tx);
+ 0 sin(tx) cos(tx)];
+
+ [Dhl] = inverseKinematicsHexapod(micro_hexapod, AP, ARB);
+ Dhl = [Dhl, Dhl];
otherwise
warning('Dh_type is not set correctly');
end
Dh = struct('time', t, 'signals', struct('values', Dh));
+ Dhl = struct('time', t, 'signals', struct('values', Dhl));
%% Axis Compensation - Rm
t = [0, Ts];
@@ -113,8 +134,6 @@ function [ref] = initializeReferences(opts_param)
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];
@@ -124,5 +143,5 @@ function [ref] = initializeReferences(opts_param)
Dn = struct('time', t, 'signals', struct('values', Dn));
%% Save
- save('./mat/nass_references.mat', 'Dy', 'Ry', 'Rz', 'Dh', 'Rm', 'Dn', 'Ts');
+ save('./mat/nass_references.mat', 'Dy', 'Ry', 'Rz', 'Dh', 'Dhl', 'Rm', 'Dn', 'Ts');
end