diff --git a/.gitignore b/.gitignore index ddb0206..f218434 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,261 @@ -Figures/ -slprj/ \ No newline at end of file +mat/ +figures/ +ltximg/ +slprj/ +*.autosave +*.original +old/ + + +# ============================================================ +# ============================================================ +# LATEX +# ============================================================ +# ============================================================ + +## Core latex/pdflatex auxiliary files: +*.aux +*.lof +*.log +*.lot +*.fls +*.out +*.toc +*.fmt +*.fot +*.cb +*.cb2 +.*.lb + +## Intermediate documents: +*.dvi +*.xdv +*-converted-to.* +# these rules might exclude image files for figures etc. +# *.ps +# *.eps +# *.pdf + +## Generated if empty string is given at "Please type another file name for output:" +.pdf + +## Bibliography auxiliary files (bibtex/biblatex/biber): +*.bbl +*.bcf +*.blg +*-blx.aux +*-blx.bib +*.run.xml + +## Build tool auxiliary files: +*.fdb_latexmk +*.synctex +*.synctex(busy) +*.synctex.gz +*.synctex.gz(busy) +*.pdfsync + +## Build tool directories for auxiliary files +# latexrun +latex.out/ + +## Auxiliary and intermediate files from other packages: +# algorithms +*.alg +*.loa + +# achemso +acs-*.bib + +# amsthm +*.thm + +# beamer +*.nav +*.pre +*.snm +*.vrb + +# changes +*.soc + +# cprotect +*.cpt + +# elsarticle (documentclass of Elsevier journals) +*.spl + +# endnotes +*.ent + +# fixme +*.lox + +# feynmf/feynmp +*.mf +*.mp +*.t[1-9] +*.t[1-9][0-9] +*.tfm + +#(r)(e)ledmac/(r)(e)ledpar +*.end +*.?end +*.[1-9] +*.[1-9][0-9] +*.[1-9][0-9][0-9] +*.[1-9]R +*.[1-9][0-9]R +*.[1-9][0-9][0-9]R +*.eledsec[1-9] +*.eledsec[1-9]R +*.eledsec[1-9][0-9] +*.eledsec[1-9][0-9]R +*.eledsec[1-9][0-9][0-9] +*.eledsec[1-9][0-9][0-9]R + +# glossaries +*.acn +*.acr +*.glg +*.glo +*.gls +*.glsdefs + +# gnuplottex +*-gnuplottex-* + +# gregoriotex +*.gaux +*.gtex + +# htlatex +*.4ct +*.4tc +*.idv +*.lg +*.trc +*.xref + +# hyperref +*.brf + +# knitr +*-concordance.tex +# TODO Comment the next line if you want to keep your tikz graphics files +*.tikz +*-tikzDictionary + +# listings +*.lol + +# makeidx +*.idx +*.ilg +*.ind +*.ist + +# minitoc +*.maf +*.mlf +*.mlt +*.mtc[0-9]* +*.slf[0-9]* +*.slt[0-9]* +*.stc[0-9]* + +# minted +_minted* +*.pyg + +# morewrites +*.mw + +# nomencl +*.nlg +*.nlo +*.nls + +# pax +*.pax + +# pdfpcnotes +*.pdfpc + +# sagetex +*.sagetex.sage +*.sagetex.py +*.sagetex.scmd + +# scrwfile +*.wrt + +# sympy +*.sout +*.sympy +sympy-plots-for-*.tex/ + +# pdfcomment +*.upa +*.upb + +# pythontex +*.pytxcode +pythontex-files-*/ + +# thmtools +*.loe + +# TikZ & PGF +*.dpth +*.md5 +*.auxlock + +# todonotes +*.tdo + +# easy-todo +*.lod + +# xmpincl +*.xmpi + +# xindy +*.xdy + +# xypic precompiled matrices +*.xyc + +# endfloat +*.ttt +*.fff + +# Latexian +TSWLatexianTemp* + +## Editors: +# WinEdt +*.bak +*.sav + +# Texpad +.texpadtmp + +# LyX +*.lyx~ + +# Kile +*.backup + +# KBibTeX +*~[0-9]* + +# auto folder when using emacs and auctex +./auto/* +*.el + +# expex forward references with \gathertags +*-tags.tex + +# standalone packages +*.sta \ No newline at end of file diff --git a/cubic-configuration.html b/cubic-configuration.html new file mode 100644 index 0000000..ee32eb4 --- /dev/null +++ b/cubic-configuration.html @@ -0,0 +1,1349 @@ + + + + + + + +Cubic configuration for the Stewart Platform + + + + + + + + + + + + + + +
+

Cubic configuration for the Stewart Platform

+
+

Table of Contents

+ +
+ +

+The discovery of the Cubic configuration is done in. 1 +The specificity of the Cubic configuration is that each actuator is orthogonal with the others. +

+ +

+To generate and study the Cubic configuration, initializeCubicConfiguration is used (description in section 4). +

+ +
+

1 Questions we wish to answer with this analysis

+
+

+The goal is to study the benefits of using a cubic configuration: +

+
    +
  • Equal stiffness in all the degrees of freedom?
  • +
  • No coupling between the actuators?
  • +
  • Is the center of the cube an important point?
  • +
+
+
+ +
+

2 Configuration Analysis - Stiffness Matrix

+
+
+
+

2.1 Cubic Stewart platform centered with the cube center - Jacobian estimated at the cube center

+
+

+We create a cubic Stewart platform (figure 1) in such a way that the center of the cube (black dot) is located at the center of the Stewart platform (blue dot). +The Jacobian matrix is estimated at the location of the center of the cube. +

+ + +
+

3d-cubic-stewart-aligned.png +

+

Figure 1: Centered cubic configuration

+
+ +
+
opts = struct(...
+    'H_tot', 100, ... % Total height of the Hexapod [mm]
+    'L',     200/sqrt(3), ... % Size of the Cube [mm]
+    'H',     60, ... % Height between base joints and platform joints [mm]
+    'H0',    200/2-60/2 ... % Height between the corner of the cube and the plane containing the base joints [mm]
+    );
+stewart = initializeCubicConfiguration(opts);
+opts = struct(...
+    'Jd_pos', [0, 0, -50], ... % Position of the Jacobian for displacement estimation from the top of the mobile platform [mm]
+    'Jf_pos', [0, 0, -50]  ... % Position of the Jacobian for force location from the top of the mobile platform [mm]
+    );
+stewart = computeGeometricalProperties(stewart, opts);
+
+save('./mat/stewart.mat', 'stewart');
+
+
+ +
+
K = stewart.Jd'*stewart.Jd;
+
+
+ + + + +++ ++ ++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
21.9e-18-2.3e-171.8e-185.5e-17-1.5e-17
1.9e-1826.8e-18-6.1e-17-1.6e-184.8e-18
-2.3e-176.8e-182-6.7e-184.9e-185.3e-19
1.8e-18-6.1e-17-6.7e-180.0067-2.3e-20-6.1e-20
5.5e-17-1.6e-184.9e-18-2.3e-200.00671e-18
-1.5e-174.8e-185.3e-19-6.1e-201e-180.027
+
+
+ +
+

2.2 Cubic Stewart platform centered with the cube center - Jacobian not estimated at the cube center

+
+

+We create a cubic Stewart platform with center of the cube located at the center of the Stewart platform (figure 1). +The Jacobian matrix is not estimated at the location of the center of the cube. +

+ +
+
opts = struct(...
+    'H_tot', 100, ... % Total height of the Hexapod [mm]
+    'L',     200/sqrt(3), ... % Size of the Cube [mm]
+    'H',     60, ... % Height between base joints and platform joints [mm]
+    'H0',    200/2-60/2 ... % Height between the corner of the cube and the plane containing the base joints [mm]
+    );
+stewart = initializeCubicConfiguration(opts);
+opts = struct(...
+    'Jd_pos', [0, 0, 0], ... % Position of the Jacobian for displacement estimation from the top of the mobile platform [mm]
+    'Jf_pos', [0, 0, 0]  ... % Position of the Jacobian for force location from the top of the mobile platform [mm]
+    );
+stewart = computeGeometricalProperties(stewart, opts);
+
+
+ +
+
K = stewart.Jd'*stewart.Jd;
+
+
+ + + + +++ ++ ++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
21.9e-18-2.3e-171.5e-18-0.1-1.5e-17
1.9e-1826.8e-180.1-1.6e-184.8e-18
-2.3e-176.8e-182-5.1e-19-5.5e-185.3e-19
1.5e-180.1-5.1e-190.012-3e-193.1e-19
-0.1-1.6e-18-5.5e-18-3e-190.0121.9e-18
-1.5e-174.8e-185.3e-193.1e-191.9e-180.027
+
+
+ +
+

2.3 Cubic Stewart platform not centered with the cube center - Jacobian estimated at the cube center

+
+

+Here, the "center" of the Stewart platform is not at the cube center (figure 2). +The Jacobian is estimated at the cube center. +

+ + +
+

3d-cubic-stewart-misaligned.png +

+

Figure 2: Not centered cubic configuration

+
+ +

+The center of the cube is at \(z = 110\). +The Stewart platform is from \(z = H_0 = 75\) to \(z = H_0 + H_{tot} = 175\). +The center height of the Stewart platform is then at \(z = \frac{175-75}{2} = 50\). +The center of the cube from the top platform is at \(z = 110 - 175 = -65\). +

+ +
+
opts = struct(...
+    'H_tot', 100,         ... % Total height of the Hexapod [mm]
+    'L',     220/sqrt(3), ... % Size of the Cube [mm]
+    'H',     60,          ... % Height between base joints and platform joints [mm]
+    'H0',    75           ... % Height between the corner of the cube and the plane containing the base joints [mm]
+    );
+stewart = initializeCubicConfiguration(opts);
+opts = struct(...
+    'Jd_pos', [0, 0, -65], ... % Position of the Jacobian for displacement estimation from the top of the mobile platform [mm]
+    'Jf_pos', [0, 0, -65]  ... % Position of the Jacobian for force location from the top of the mobile platform [mm]
+    );
+stewart = computeGeometricalProperties(stewart, opts);
+
+
+ +
+
K = stewart.Jd'*stewart.Jd;
+
+
+ + + + +++ ++ ++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
2-1.8e-172.6e-173.3e-180.041.7e-19
-1.8e-1721.9e-16-0.042.2e-19-5.3e-19
2.6e-171.9e-162-8.9e-186.5e-19-5.8e-19
3.3e-18-0.04-8.9e-180.0089-9.3e-209.8e-20
0.042.2e-196.5e-19-9.3e-200.0089-2.4e-18
1.7e-19-5.3e-19-5.8e-199.8e-20-2.4e-180.032
+ +

+We obtain \(k_x = k_y = k_z\) and \(k_{\theta_x} = k_{\theta_y}\), but the Stiffness matrix is not diagonal. +

+
+
+ +
+

2.4 Cubic Stewart platform not centered with the cube center - Jacobian estimated at the Stewart platform center

+
+

+Here, the "center" of the Stewart platform is not at the cube center. +The Jacobian is estimated at the center of the Stewart platform. +

+ +

+The center of the cube is at \(z = 110\). +The Stewart platform is from \(z = H_0 = 75\) to \(z = H_0 + H_{tot} = 175\). +The center height of the Stewart platform is then at \(z = \frac{175-75}{2} = 50\). +The center of the cube from the top platform is at \(z = 110 - 175 = -65\). +

+ +
+
opts = struct(...
+    'H_tot', 100, ... % Total height of the Hexapod [mm]
+    'L',     220/sqrt(3), ... % Size of the Cube [mm]
+    'H',     60, ... % Height between base joints and platform joints [mm]
+    'H0',    75 ... % Height between the corner of the cube and the plane containing the base joints [mm]
+    );
+stewart = initializeCubicConfiguration(opts);
+opts = struct(...
+    'Jd_pos', [0, 0, -60], ... % Position of the Jacobian for displacement estimation from the top of the mobile platform [mm]
+    'Jf_pos', [0, 0, -60]  ... % Position of the Jacobian for force location from the top of the mobile platform [mm]
+    );
+stewart = computeGeometricalProperties(stewart, opts);
+
+
+ +
+
K = stewart.Jd'*stewart.Jd;
+
+
+ + + + +++ ++ ++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
2-1.8e-172.6e-17-5.7e-190.031.7e-19
-1.8e-1721.9e-16-0.032.2e-19-5.3e-19
2.6e-171.9e-162-1.5e-176.5e-19-5.8e-19
-5.7e-19-0.03-1.5e-170.00854.9e-201.7e-19
0.032.2e-196.5e-194.9e-200.0085-1.1e-18
1.7e-19-5.3e-19-5.8e-191.7e-19-1.1e-180.032
+ +

+We obtain \(k_x = k_y = k_z\) and \(k_{\theta_x} = k_{\theta_y}\), but the Stiffness matrix is not diagonal. +

+
+
+ +
+

2.5 Conclusion

+
+
+
    +
  • The cubic configuration permits to have \(k_x = k_y = k_z\) and \(k_{\theta\x} = k_{\theta_y}\)
  • +
  • The stiffness matrix \(K\) is diagonal for the cubic configuration if the Stewart platform and the cube are centered and the Jacobian is estimated at the cube center
  • +
+ +
+
+
+
+ +
+

3 Cubic size analysis

+
+

+We here study the effect of the size of the cube used for the Stewart configuration. +

+ +

+We fix the height of the Stewart platform, the center of the cube is at the center of the Stewart platform. +

+ +

+We only vary the size of the cube. +

+ +
+
H_cubes = 250:20:350;
+stewarts = {zeros(length(H_cubes), 1)};
+
+
+ +
+
for i = 1:length(H_cubes)
+  H_cube = H_cubes(i);
+  H_tot = 100;
+  H = 80;
+
+  opts = struct(...
+      'H_tot', H_tot, ... % Total height of the Hexapod [mm]
+      'L',     H_cube/sqrt(3), ... % Size of the Cube [mm]
+      'H',     H, ... % Height between base joints and platform joints [mm]
+      'H0',    H_cube/2-H/2 ... % Height between the corner of the cube and the plane containing the base joints [mm]
+      );
+  stewart = initializeCubicConfiguration(opts);
+
+  opts = struct(...
+      'Jd_pos', [0, 0, H_cube/2-opts.H0-opts.H_tot], ... % Position of the Jacobian for displacement estimation from the top of the mobile platform [mm]
+      'Jf_pos', [0, 0, H_cube/2-opts.H0-opts.H_tot]  ... % Position of the Jacobian for force location from the top of the mobile platform [mm]
+      );
+  stewart = computeGeometricalProperties(stewart, opts);
+  stewarts(i) = {stewart};
+end
+
+
+ + +

+The Stiffness matrix is computed for all generated Stewart platforms. +

+
+
Ks = zeros(6, 6, length(H_cube));
+for i = 1:length(H_cubes)
+  Ks(:, :, i) = stewarts{i}.Jd'*stewarts{i}.Jd;
+end
+
+
+ +

+The only elements of \(K\) that vary are \(k_{\theta_x} = k_{\theta_y}\) and \(k_{\theta_z}\). +

+ +

+Finally, we plot \(k_{\theta_x} = k_{\theta_y}\) and \(k_{\theta_z}\) +

+
+
figure;
+hold on;
+plot(H_cubes, squeeze(Ks(4, 4, :)), 'DisplayName', '$k_{\theta_x}$');
+plot(H_cubes, squeeze(Ks(6, 6, :)), 'DisplayName', '$k_{\theta_z}$');
+hold off;
+legend('location', 'northwest');
+xlabel('Cube Size [mm]'); ylabel('Rotational stiffnes [normalized]');
+
+
+ + +
+

stiffness_cube_size.png +

+

Figure 3: \(k_{\theta_x} = k_{\theta_y}\) and \(k_{\theta_z}\) function of the size of the cube

+
+ + +

+We observe that \(k_{\theta_x} = k_{\theta_y}\) and \(k_{\theta_z}\) increase linearly with the cube size. +

+ +
+

+In order to maximize the rotational stiffness of the Stewart platform, the size of the cube should be the highest possible. +In that case, the legs will the further separated. Size of the cube is then limited by allowed space. +

+ +
+
+
+ +
+

4 initializeCubicConfiguration

+
+

+ +

+
+ +
+

4.1 Function description

+
+
+
function [stewart] = initializeCubicConfiguration(opts_param)
+
+
+
+
+ +
+

4.2 Optional Parameters

+
+

+Default values for opts. +

+
+
opts = struct(...
+    'H_tot', 90,  ... % Total height of the Hexapod [mm]
+    'L',     110, ... % Size of the Cube [mm]
+    'H',     40,  ... % Height between base joints and platform joints [mm]
+    'H0',    75   ... % Height between the corner of the cube and the plane containing the base joints [mm]
+    );
+
+
+ +

+Populate opts with input parameters +

+
+
if exist('opts_param','var')
+    for opt = fieldnames(opts_param)'
+        opts.(opt{1}) = opts_param.(opt{1});
+    end
+end
+
+
+
+
+ +
+

4.3 Cube Creation

+
+
+
points = [0, 0, 0; ...
+          0, 0, 1; ...
+          0, 1, 0; ...
+          0, 1, 1; ...
+          1, 0, 0; ...
+          1, 0, 1; ...
+          1, 1, 0; ...
+          1, 1, 1];
+points = opts.L*points;
+
+
+ +

+We create the rotation matrix to rotate the cube +

+
+
sx = cross([1, 1, 1], [1 0 0]);
+sx = sx/norm(sx);
+
+sy = -cross(sx, [1, 1, 1]);
+sy = sy/norm(sy);
+
+sz = [1, 1, 1];
+sz = sz/norm(sz);
+
+R = [sx', sy', sz']';
+
+
+ +

+We use to rotation matrix to rotate the cube +

+
+
cube = zeros(size(points));
+for i = 1:size(points, 1)
+  cube(i, :) = R * points(i, :)';
+end
+
+
+
+
+ +
+

4.4 Vectors of each leg

+
+
+
leg_indices = [3, 4; ...
+               2, 4; ...
+               2, 6; ...
+               5, 6; ...
+               5, 7; ...
+               3, 7];
+
+
+ +

+Vectors are: +

+
+
legs = zeros(6, 3);
+legs_start = zeros(6, 3);
+
+for i = 1:6
+  legs(i, :) = cube(leg_indices(i, 2), :) - cube(leg_indices(i, 1), :);
+  legs_start(i, :) = cube(leg_indices(i, 1), :);
+end
+
+
+
+
+ +
+

4.5 Verification of Height of the Stewart Platform

+
+

+If the Stewart platform is not contained in the cube, throw an error. +

+ +
+
Hmax = cube(4, 3) - cube(2, 3);
+if opts.H0 < cube(2, 3)
+  error(sprintf('H0 is not high enought. Minimum H0 = %.1f', cube(2, 3)));
+else if opts.H0 + opts.H > cube(4, 3)
+  error(sprintf('H0+H is too high. Maximum H0+H = %.1f', cube(4, 3)));
+  error('H0+H is too high');
+end
+
+
+
+
+ +
+

4.6 Determinate the location of the joints

+
+

+We now determine the location of the joints on the fixed platform w.r.t the fixed frame \(\{A\}\). +\(\{A\}\) is fixed to the bottom of the base. +

+
+
Aa = zeros(6, 3);
+for i = 1:6
+  t = (opts.H0-legs_start(i, 3))/(legs(i, 3));
+  Aa(i, :) = legs_start(i, :) + t*legs(i, :);
+end
+
+
+ +

+And the location of the joints on the mobile platform with respect to \(\{A\}\). +

+
+
Ab = zeros(6, 3);
+for i = 1:6
+  t = (opts.H0+opts.H-legs_start(i, 3))/(legs(i, 3));
+  Ab(i, :) = legs_start(i, :) + t*legs(i, :);
+end
+
+
+ +

+And the location of the joints on the mobile platform with respect to \(\{B\}\). +

+
+
Bb = zeros(6, 3);
+Bb = Ab - (opts.H0 + opts.H_tot/2 + opts.H/2)*[0, 0, 1];
+
+
+ +
+
h = opts.H0 + opts.H/2 - opts.H_tot/2;
+Aa = Aa - h*[0, 0, 1];
+Ab = Ab - h*[0, 0, 1];
+
+
+
+
+ +
+

4.7 Returns Stewart Structure

+
+
+
  stewart = struct();
+  stewart.Aa = Aa;
+  stewart.Ab = Ab;
+  stewart.Bb = Bb;
+  stewart.H_tot = opts.H_tot;
+end
+
+
+
+
+
+ +
+

5 Tests

+
+
+
+

5.1 First attempt to parametrisation

+
+ +
+

stewart_bottom_plate.png +

+

Figure 4: Schematic of the bottom plates with all the parameters

+
+ +

+The goal is to choose \(\alpha\), \(\beta\), \(R_\text{leg, t}\) and \(R_\text{leg, b}\) in such a way that the configuration is cubic. +

+ + +

+The configuration is cubic if: +\[ \overrightarrow{a_i b_i} \cdot \overrightarrow{a_j b_j} = 0, \ \forall i, j = [1, \hdots, 6], i \ne j \] +

+ +

+Lets express \(a_i\), \(b_i\) and \(a_j\): +

+\begin{equation*} + a_1 = \begin{bmatrix}R_{\text{leg,b}} \cos(120 - \alpha) \\ R_{\text{leg,b}} \cos(120 - \alpha) \\ 0\end{bmatrix} ; \quad + a_2 = \begin{bmatrix}R_{\text{leg,b}} \cos(120 + \alpha) \\ R_{\text{leg,b}} \cos(120 + \alpha) \\ 0\end{bmatrix} ; \quad +\end{equation*} + +\begin{equation*} + b_1 = \begin{bmatrix}R_{\text{leg,t}} \cos(120 - \beta) \\ R_{\text{leg,t}} \cos(120 - \beta\\ H\end{bmatrix} ; \quad + b_2 = \begin{bmatrix}R_{\text{leg,t}} \cos(120 + \beta) \\ R_{\text{leg,t}} \cos(120 + \beta\\ H\end{bmatrix} ; \quad +\end{equation*} + +

+\[ \overrightarrow{a_1 b_1} = b_1 - a_1 = \begin{bmatrix}R_{\text{leg}} \cos(120 - \alpha) \\ R_{\text{leg}} \cos(120 - \alpha) \\ 0\end{bmatrix}\] +

+
+
+ +
+

5.2 Second attempt

+
+

+We start with the point of a cube in space: +

+\begin{align*} + [0, 0, 0] ; \ [0, 0, 1]; \ ... +\end{align*} + +

+We also want the cube to point upward: +\[ [1, 1, 1] \Rightarrow [0, 0, 1] \] +

+ +

+Then we have the direction of all the vectors expressed in the frame of the hexapod. +

+ +
+
points = [0, 0, 0; ...
+          0, 0, 1; ...
+          0, 1, 0; ...
+          0, 1, 1; ...
+          1, 0, 0; ...
+          1, 0, 1; ...
+          1, 1, 0; ...
+          1, 1, 1];
+
+
+ +
+
figure;
+plot3(points(:,1), points(:,2), points(:,3), 'ko')
+
+
+ +
+
sx = cross([1, 1, 1], [1 0 0]);
+sx = sx/norm(sx);
+
+sy = -cross(sx, [1, 1, 1]);
+sy = sy/norm(sy);
+
+sz = [1, 1, 1];
+sz = sz/norm(sz);
+
+R = [sx', sy', sz']';
+
+
+ +
+
cube = zeros(size(points));
+for i = 1:size(points, 1)
+  cube(i, :) = R * points(i, :)';
+end
+
+
+ +
+
figure;
+hold on;
+plot3(points(:,1), points(:,2), points(:,3), 'ko');
+plot3(cube(:,1), cube(:,2), cube(:,3), 'ro');
+hold off;
+
+
+ +

+Now we plot the legs of the hexapod. +

+
+
leg_indices = [3, 4; ...
+               2, 4; ...
+               2, 6; ...
+               5, 6; ...
+               5, 7; ...
+               3, 7]
+
+figure;
+hold on;
+for i = 1:6
+  plot3(cube(leg_indices(i, :),1), cube(leg_indices(i, :),2), cube(leg_indices(i, :),3), '-');
+end
+hold off;
+
+
+ +

+Vectors are: +

+
+
legs = zeros(6, 3);
+legs_start = zeros(6, 3);
+
+for i = 1:6
+  legs(i, :) = cube(leg_indices(i, 2), :) - cube(leg_indices(i, 1), :);
+  legs_start(i, :) = cube(leg_indices(i, 1), :)
+end
+
+
+ +

+We now have the orientation of each leg. +

+ +

+We here want to see if the position of the "slice" changes something. +

+ +

+Let's first estimate the maximum height of the Stewart platform. +

+
+
Hmax = cube(4, 3) - cube(2, 3);
+
+
+ +

+Let's then estimate the middle position of the platform +

+
+
Hmid = cube(8, 3)/2;
+
+
+
+
+ +
+

5.3 Generate the Stewart platform for a Cubic configuration

+
+

+First we defined the height of the Hexapod. +

+
+
H = Hmax/2;
+
+
+ +
+
Zs = 1.2*cube(2, 3); % Height of the fixed platform
+Ze = Zs + H; % Height of the mobile platform
+
+
+ +

+We now determine the location of the joints on the fixed platform. +

+
+
Aa = zeros(6, 3);
+for i = 1:6
+  t = (Zs-legs_start(i, 3))/(legs(i, 3));
+  Aa(i, :) = legs_start(i, :) + t*legs(i, :);
+end
+
+
+ +

+And the location of the joints on the mobile platform +

+
+
Ab = zeros(6, 3);
+for i = 1:6
+  t = (Ze-legs_start(i, 3))/(legs(i, 3));
+  Ab(i, :) = legs_start(i, :) + t*legs(i, :);
+end
+
+
+ +

+And we plot the legs. +

+
+
figure;
+hold on;
+for i = 1:6
+  plot3([Ab(i, 1),Aa(i, 1)], [Ab(i, 2),Aa(i, 2)], [Ab(i, 3),Aa(i, 3)], 'k-');
+end
+hold off;
+xlim([-1, 1]);
+ylim([-1, 1]);
+zlim([0, 2]);
+
+
+
+
+
+ +
    +
  1. Z.J. Geng, and L.S. Haynes, , Six Degree-Of-Freedom Active Vibration Control Using the Stewart Platforms, IEEE Transactions on Control Systems Technology, 2(1), pp. 45-53 (1994). http://dx.doi.org/10.1109/87.273110.
  2. +
+
+
+

Author: Thomas Dehaeze

+

Created: 2019-03-25 lun. 18:11

+

Validate

+
+ + diff --git a/cubic-configuration.org b/cubic-configuration.org new file mode 100644 index 0000000..2ac21cf --- /dev/null +++ b/cubic-configuration.org @@ -0,0 +1,607 @@ +#+TITLE: Cubic configuration for the Stewart Platform +:DRAWER: +#+STARTUP: overview + +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: + +#+LATEX_CLASS: cleanreport +#+LaTeX_CLASS_OPTIONS: [tocnp, secbreak, minted] +#+LaTeX_HEADER: \usepackage{svg} +#+LaTeX_HEADER: \newcommand{\authorFirstName}{Thomas} +#+LaTeX_HEADER: \newcommand{\authorLastName}{Dehaeze} +#+LaTeX_HEADER: \newcommand{\authorEmail}{dehaeze.thomas@gmail.com} + +#+PROPERTY: header-args:matlab :session *MATLAB* +#+PROPERTY: header-args:matlab+ :comments org +#+PROPERTY: header-args:matlab+ :exports both +#+PROPERTY: header-args:matlab+ :eval no-export +#+PROPERTY: header-args:matlab+ :output-dir figs +#+PROPERTY: header-args:matlab+ :mkdirp yes +:END: + +#+begin_src matlab :results none :exports none :noweb yes + <> + addpath('src'); + addpath('library'); +#+end_src + +The discovery of the Cubic configuration is done in citenum:geng94_six_degree_of_freed_activ. +The specificity of the Cubic configuration is that each actuator is orthogonal with the others. + +To generate and study the Cubic configuration, =initializeCubicConfiguration= is used (description in section [[sec:initializeCubicConfiguration]]). + +* Questions we wish to answer with this analysis +The goal is to study the benefits of using a cubic configuration: +- Equal stiffness in all the degrees of freedom? +- No coupling between the actuators? +- Is the center of the cube an important point? + +* Configuration Analysis - Stiffness Matrix +** Cubic Stewart platform centered with the cube center - Jacobian estimated at the cube center +We create a cubic Stewart platform (figure [[fig:3d-cubic-stewart-aligned]]) in such a way that the center of the cube (black dot) is located at the center of the Stewart platform (blue dot). +The Jacobian matrix is estimated at the location of the center of the cube. + +#+name: fig:3d-cubic-stewart-aligned +#+caption: Centered cubic configuration +[[file:./figs/3d-cubic-stewart-aligned.png]] + +#+begin_src matlab :results silent + opts = struct(... + 'H_tot', 100, ... % Total height of the Hexapod [mm] + 'L', 200/sqrt(3), ... % Size of the Cube [mm] + 'H', 60, ... % Height between base joints and platform joints [mm] + 'H0', 200/2-60/2 ... % Height between the corner of the cube and the plane containing the base joints [mm] + ); + stewart = initializeCubicConfiguration(opts); + opts = struct(... + 'Jd_pos', [0, 0, -50], ... % Position of the Jacobian for displacement estimation from the top of the mobile platform [mm] + 'Jf_pos', [0, 0, -50] ... % Position of the Jacobian for force location from the top of the mobile platform [mm] + ); + stewart = computeGeometricalProperties(stewart, opts); + + save('./mat/stewart.mat', 'stewart'); +#+end_src + +#+begin_src matlab :results none :exports code + K = stewart.Jd'*stewart.Jd; +#+end_src + +#+begin_src matlab :results value table :exports results + data = K; + data2orgtable(data, {}, {}, ' %.2g '); +#+end_src + +#+RESULTS: +| 2 | 1.9e-18 | -2.3e-17 | 1.8e-18 | 5.5e-17 | -1.5e-17 | +| 1.9e-18 | 2 | 6.8e-18 | -6.1e-17 | -1.6e-18 | 4.8e-18 | +| -2.3e-17 | 6.8e-18 | 2 | -6.7e-18 | 4.9e-18 | 5.3e-19 | +| 1.8e-18 | -6.1e-17 | -6.7e-18 | 0.0067 | -2.3e-20 | -6.1e-20 | +| 5.5e-17 | -1.6e-18 | 4.9e-18 | -2.3e-20 | 0.0067 | 1e-18 | +| -1.5e-17 | 4.8e-18 | 5.3e-19 | -6.1e-20 | 1e-18 | 0.027 | + +** Cubic Stewart platform centered with the cube center - Jacobian not estimated at the cube center +We create a cubic Stewart platform with center of the cube located at the center of the Stewart platform (figure [[fig:3d-cubic-stewart-aligned]]). +The Jacobian matrix is not estimated at the location of the center of the cube. + +#+begin_src matlab :results silent + opts = struct(... + 'H_tot', 100, ... % Total height of the Hexapod [mm] + 'L', 200/sqrt(3), ... % Size of the Cube [mm] + 'H', 60, ... % Height between base joints and platform joints [mm] + 'H0', 200/2-60/2 ... % Height between the corner of the cube and the plane containing the base joints [mm] + ); + stewart = initializeCubicConfiguration(opts); + opts = struct(... + 'Jd_pos', [0, 0, 0], ... % Position of the Jacobian for displacement estimation from the top of the mobile platform [mm] + 'Jf_pos', [0, 0, 0] ... % Position of the Jacobian for force location from the top of the mobile platform [mm] + ); + stewart = computeGeometricalProperties(stewart, opts); +#+end_src + +#+begin_src matlab :results none :exports code + K = stewart.Jd'*stewart.Jd; +#+end_src + +#+begin_src matlab :results value table :exports results + data = K; + data2orgtable(data', {}, {}, ' %.2g '); +#+end_src + +#+RESULTS: +| 2 | 1.9e-18 | -2.3e-17 | 1.5e-18 | -0.1 | -1.5e-17 | +| 1.9e-18 | 2 | 6.8e-18 | 0.1 | -1.6e-18 | 4.8e-18 | +| -2.3e-17 | 6.8e-18 | 2 | -5.1e-19 | -5.5e-18 | 5.3e-19 | +| 1.5e-18 | 0.1 | -5.1e-19 | 0.012 | -3e-19 | 3.1e-19 | +| -0.1 | -1.6e-18 | -5.5e-18 | -3e-19 | 0.012 | 1.9e-18 | +| -1.5e-17 | 4.8e-18 | 5.3e-19 | 3.1e-19 | 1.9e-18 | 0.027 | + +** Cubic Stewart platform not centered with the cube center - Jacobian estimated at the cube center +Here, the "center" of the Stewart platform is not at the cube center (figure [[fig:3d-cubic-stewart-misaligned]]). +The Jacobian is estimated at the cube center. + +#+name: fig:3d-cubic-stewart-misaligned +#+caption: Not centered cubic configuration +[[file:./figs/3d-cubic-stewart-misaligned.png]] + +The center of the cube is at $z = 110$. +The Stewart platform is from $z = H_0 = 75$ to $z = H_0 + H_{tot} = 175$. +The center height of the Stewart platform is then at $z = \frac{175-75}{2} = 50$. +The center of the cube from the top platform is at $z = 110 - 175 = -65$. + +#+begin_src matlab :results silent + opts = struct(... + 'H_tot', 100, ... % Total height of the Hexapod [mm] + 'L', 220/sqrt(3), ... % Size of the Cube [mm] + 'H', 60, ... % Height between base joints and platform joints [mm] + 'H0', 75 ... % Height between the corner of the cube and the plane containing the base joints [mm] + ); + stewart = initializeCubicConfiguration(opts); + opts = struct(... + 'Jd_pos', [0, 0, -65], ... % Position of the Jacobian for displacement estimation from the top of the mobile platform [mm] + 'Jf_pos', [0, 0, -65] ... % Position of the Jacobian for force location from the top of the mobile platform [mm] + ); + stewart = computeGeometricalProperties(stewart, opts); +#+end_src + +#+begin_src matlab :results none :exports code + K = stewart.Jd'*stewart.Jd; +#+end_src + +#+begin_src matlab :results value table :exports results + data = K; + data2orgtable(data', {}, {}, ' %.2g '); +#+end_src + +#+RESULTS: +| 2 | -1.8e-17 | 2.6e-17 | 3.3e-18 | 0.04 | 1.7e-19 | +| -1.8e-17 | 2 | 1.9e-16 | -0.04 | 2.2e-19 | -5.3e-19 | +| 2.6e-17 | 1.9e-16 | 2 | -8.9e-18 | 6.5e-19 | -5.8e-19 | +| 3.3e-18 | -0.04 | -8.9e-18 | 0.0089 | -9.3e-20 | 9.8e-20 | +| 0.04 | 2.2e-19 | 6.5e-19 | -9.3e-20 | 0.0089 | -2.4e-18 | +| 1.7e-19 | -5.3e-19 | -5.8e-19 | 9.8e-20 | -2.4e-18 | 0.032 | + +We obtain $k_x = k_y = k_z$ and $k_{\theta_x} = k_{\theta_y}$, but the Stiffness matrix is not diagonal. + +** Cubic Stewart platform not centered with the cube center - Jacobian estimated at the Stewart platform center +Here, the "center" of the Stewart platform is not at the cube center. +The Jacobian is estimated at the center of the Stewart platform. + +The center of the cube is at $z = 110$. +The Stewart platform is from $z = H_0 = 75$ to $z = H_0 + H_{tot} = 175$. +The center height of the Stewart platform is then at $z = \frac{175-75}{2} = 50$. +The center of the cube from the top platform is at $z = 110 - 175 = -65$. + +#+begin_src matlab :results silent + opts = struct(... + 'H_tot', 100, ... % Total height of the Hexapod [mm] + 'L', 220/sqrt(3), ... % Size of the Cube [mm] + 'H', 60, ... % Height between base joints and platform joints [mm] + 'H0', 75 ... % Height between the corner of the cube and the plane containing the base joints [mm] + ); + stewart = initializeCubicConfiguration(opts); + opts = struct(... + 'Jd_pos', [0, 0, -60], ... % Position of the Jacobian for displacement estimation from the top of the mobile platform [mm] + 'Jf_pos', [0, 0, -60] ... % Position of the Jacobian for force location from the top of the mobile platform [mm] + ); + stewart = computeGeometricalProperties(stewart, opts); +#+end_src + +#+begin_src matlab :results none :exports code + K = stewart.Jd'*stewart.Jd; +#+end_src + +#+begin_src matlab :results value table :exports results + data = K; + data2orgtable(data', {}, {}, ' %.2g '); +#+end_src + +#+RESULTS: +| 2 | -1.8e-17 | 2.6e-17 | -5.7e-19 | 0.03 | 1.7e-19 | +| -1.8e-17 | 2 | 1.9e-16 | -0.03 | 2.2e-19 | -5.3e-19 | +| 2.6e-17 | 1.9e-16 | 2 | -1.5e-17 | 6.5e-19 | -5.8e-19 | +| -5.7e-19 | -0.03 | -1.5e-17 | 0.0085 | 4.9e-20 | 1.7e-19 | +| 0.03 | 2.2e-19 | 6.5e-19 | 4.9e-20 | 0.0085 | -1.1e-18 | +| 1.7e-19 | -5.3e-19 | -5.8e-19 | 1.7e-19 | -1.1e-18 | 0.032 | + +We obtain $k_x = k_y = k_z$ and $k_{\theta_x} = k_{\theta_y}$, but the Stiffness matrix is not diagonal. + +** Conclusion +#+begin_important + - The cubic configuration permits to have $k_x = k_y = k_z$ and $k_{\theta\x} = k_{\theta_y}$ + - The stiffness matrix $K$ is diagonal for the cubic configuration if the Stewart platform and the cube are centered *and* the Jacobian is estimated at the cube center +#+end_important + +* Cubic size analysis +We here study the effect of the size of the cube used for the Stewart configuration. + +We fix the height of the Stewart platform, the center of the cube is at the center of the Stewart platform. + +We only vary the size of the cube. + +#+begin_src matlab :results silent + H_cubes = 250:20:350; + stewarts = {zeros(length(H_cubes), 1)}; +#+end_src + +#+begin_src matlab :results silent + for i = 1:length(H_cubes) + H_cube = H_cubes(i); + H_tot = 100; + H = 80; + + opts = struct(... + 'H_tot', H_tot, ... % Total height of the Hexapod [mm] + 'L', H_cube/sqrt(3), ... % Size of the Cube [mm] + 'H', H, ... % Height between base joints and platform joints [mm] + 'H0', H_cube/2-H/2 ... % Height between the corner of the cube and the plane containing the base joints [mm] + ); + stewart = initializeCubicConfiguration(opts); + + opts = struct(... + 'Jd_pos', [0, 0, H_cube/2-opts.H0-opts.H_tot], ... % Position of the Jacobian for displacement estimation from the top of the mobile platform [mm] + 'Jf_pos', [0, 0, H_cube/2-opts.H0-opts.H_tot] ... % Position of the Jacobian for force location from the top of the mobile platform [mm] + ); + stewart = computeGeometricalProperties(stewart, opts); + stewarts(i) = {stewart}; + end +#+end_src + + +The Stiffness matrix is computed for all generated Stewart platforms. +#+begin_src matlab :results none :exports code + Ks = zeros(6, 6, length(H_cube)); + for i = 1:length(H_cubes) + Ks(:, :, i) = stewarts{i}.Jd'*stewarts{i}.Jd; + end +#+end_src + +The only elements of $K$ that vary are $k_{\theta_x} = k_{\theta_y}$ and $k_{\theta_z}$. + +Finally, we plot $k_{\theta_x} = k_{\theta_y}$ and $k_{\theta_z}$ +#+begin_src matlab :results none :exports code + figure; + hold on; + plot(H_cubes, squeeze(Ks(4, 4, :)), 'DisplayName', '$k_{\theta_x}$'); + plot(H_cubes, squeeze(Ks(6, 6, :)), 'DisplayName', '$k_{\theta_z}$'); + hold off; + legend('location', 'northwest'); + xlabel('Cube Size [mm]'); ylabel('Rotational stiffnes [normalized]'); +#+end_src + +#+NAME: fig:stiffness_cube_size +#+HEADER: :tangle no :exports results :results raw :noweb yes +#+begin_src matlab :var filepath="figs/stiffness_cube_size.pdf" :var figsize="normal-normal" :post pdf2svg(file=*this*, ext="png") + <> +#+end_src + +#+NAME: fig:stiffness_cube_size +#+CAPTION: $k_{\theta_x} = k_{\theta_y}$ and $k_{\theta_z}$ function of the size of the cube +#+RESULTS: fig:stiffness_cube_size +[[file:figs/stiffness_cube_size.png]] + + +We observe that $k_{\theta_x} = k_{\theta_y}$ and $k_{\theta_z}$ increase linearly with the cube size. + +#+begin_important + In order to maximize the rotational stiffness of the Stewart platform, the size of the cube should be the highest possible. + In that case, the legs will the further separated. Size of the cube is then limited by allowed space. +#+end_important + +* initializeCubicConfiguration + :PROPERTIES: + :HEADER-ARGS:matlab+: :exports code + :HEADER-ARGS:matlab+: :comments no + :HEADER-ARGS:matlab+: :eval no + :HEADER-ARGS:matlab+: :tangle src/initializeCubicConfiguration.m + :END: + <> + +** Function description +#+begin_src matlab + function [stewart] = initializeCubicConfiguration(opts_param) +#+end_src + +** Optional Parameters +Default values for opts. +#+begin_src matlab + opts = struct(... + 'H_tot', 90, ... % Total height of the Hexapod [mm] + 'L', 110, ... % Size of the Cube [mm] + 'H', 40, ... % Height between base joints and platform joints [mm] + 'H0', 75 ... % Height between the corner of the cube and the plane containing the base joints [mm] + ); +#+end_src + +Populate opts with input parameters +#+begin_src matlab + if exist('opts_param','var') + for opt = fieldnames(opts_param)' + opts.(opt{1}) = opts_param.(opt{1}); + end + end +#+end_src + +** Cube Creation +#+begin_src matlab :results none + points = [0, 0, 0; ... + 0, 0, 1; ... + 0, 1, 0; ... + 0, 1, 1; ... + 1, 0, 0; ... + 1, 0, 1; ... + 1, 1, 0; ... + 1, 1, 1]; + points = opts.L*points; +#+end_src + +We create the rotation matrix to rotate the cube +#+begin_src matlab :results none + sx = cross([1, 1, 1], [1 0 0]); + sx = sx/norm(sx); + + sy = -cross(sx, [1, 1, 1]); + sy = sy/norm(sy); + + sz = [1, 1, 1]; + sz = sz/norm(sz); + + R = [sx', sy', sz']'; +#+end_src + +We use to rotation matrix to rotate the cube +#+begin_src matlab :results none + cube = zeros(size(points)); + for i = 1:size(points, 1) + cube(i, :) = R * points(i, :)'; + end +#+end_src + +** Vectors of each leg +#+begin_src matlab :results none + leg_indices = [3, 4; ... + 2, 4; ... + 2, 6; ... + 5, 6; ... + 5, 7; ... + 3, 7]; +#+end_src + +Vectors are: +#+begin_src matlab :results none + legs = zeros(6, 3); + legs_start = zeros(6, 3); + + for i = 1:6 + legs(i, :) = cube(leg_indices(i, 2), :) - cube(leg_indices(i, 1), :); + legs_start(i, :) = cube(leg_indices(i, 1), :); + end +#+end_src + +** Verification of Height of the Stewart Platform +If the Stewart platform is not contained in the cube, throw an error. + +#+begin_src matlab :results none + Hmax = cube(4, 3) - cube(2, 3); + if opts.H0 < cube(2, 3) + error(sprintf('H0 is not high enought. Minimum H0 = %.1f', cube(2, 3))); + else if opts.H0 + opts.H > cube(4, 3) + error(sprintf('H0+H is too high. Maximum H0+H = %.1f', cube(4, 3))); + error('H0+H is too high'); + end +#+end_src + +** Determinate the location of the joints +We now determine the location of the joints on the fixed platform w.r.t the fixed frame $\{A\}$. +$\{A\}$ is fixed to the bottom of the base. +#+begin_src matlab :results none + Aa = zeros(6, 3); + for i = 1:6 + t = (opts.H0-legs_start(i, 3))/(legs(i, 3)); + Aa(i, :) = legs_start(i, :) + t*legs(i, :); + end +#+end_src + +And the location of the joints on the mobile platform with respect to $\{A\}$. +#+begin_src matlab :results none + Ab = zeros(6, 3); + for i = 1:6 + t = (opts.H0+opts.H-legs_start(i, 3))/(legs(i, 3)); + Ab(i, :) = legs_start(i, :) + t*legs(i, :); + end +#+end_src + +And the location of the joints on the mobile platform with respect to $\{B\}$. +#+begin_src matlab :results none + Bb = zeros(6, 3); + Bb = Ab - (opts.H0 + opts.H_tot/2 + opts.H/2)*[0, 0, 1]; +#+end_src + +#+begin_src matlab :results none + h = opts.H0 + opts.H/2 - opts.H_tot/2; + Aa = Aa - h*[0, 0, 1]; + Ab = Ab - h*[0, 0, 1]; +#+end_src + +** Returns Stewart Structure +#+begin_src matlab :results none + stewart = struct(); + stewart.Aa = Aa; + stewart.Ab = Ab; + stewart.Bb = Bb; + stewart.H_tot = opts.H_tot; +end +#+end_src + +* Tests +** First attempt to parametrisation +#+name: fig:stewart_bottom_plate +#+caption: Schematic of the bottom plates with all the parameters +[[file:./figs/stewart_bottom_plate.png]] + +The goal is to choose $\alpha$, $\beta$, $R_\text{leg, t}$ and $R_\text{leg, b}$ in such a way that the configuration is cubic. + + +The configuration is cubic if: +\[ \overrightarrow{a_i b_i} \cdot \overrightarrow{a_j b_j} = 0, \ \forall i, j = [1, \hdots, 6], i \ne j \] + +Lets express $a_i$, $b_i$ and $a_j$: +\begin{equation*} + a_1 = \begin{bmatrix}R_{\text{leg,b}} \cos(120 - \alpha) \\ R_{\text{leg,b}} \cos(120 - \alpha) \\ 0\end{bmatrix} ; \quad + a_2 = \begin{bmatrix}R_{\text{leg,b}} \cos(120 + \alpha) \\ R_{\text{leg,b}} \cos(120 + \alpha) \\ 0\end{bmatrix} ; \quad +\end{equation*} + +\begin{equation*} + b_1 = \begin{bmatrix}R_{\text{leg,t}} \cos(120 - \beta) \\ R_{\text{leg,t}} \cos(120 - \beta\\ H\end{bmatrix} ; \quad + b_2 = \begin{bmatrix}R_{\text{leg,t}} \cos(120 + \beta) \\ R_{\text{leg,t}} \cos(120 + \beta\\ H\end{bmatrix} ; \quad +\end{equation*} + +\[ \overrightarrow{a_1 b_1} = b_1 - a_1 = \begin{bmatrix}R_{\text{leg}} \cos(120 - \alpha) \\ R_{\text{leg}} \cos(120 - \alpha) \\ 0\end{bmatrix}\] + +** Second attempt +We start with the point of a cube in space: +\begin{align*} + [0, 0, 0] ; \ [0, 0, 1]; \ ... +\end{align*} + +We also want the cube to point upward: +\[ [1, 1, 1] \Rightarrow [0, 0, 1] \] + +Then we have the direction of all the vectors expressed in the frame of the hexapod. + +#+begin_src matlab :results none + points = [0, 0, 0; ... + 0, 0, 1; ... + 0, 1, 0; ... + 0, 1, 1; ... + 1, 0, 0; ... + 1, 0, 1; ... + 1, 1, 0; ... + 1, 1, 1]; +#+end_src + +#+begin_src matlab :results none + figure; + plot3(points(:,1), points(:,2), points(:,3), 'ko') +#+end_src + +#+begin_src matlab :results none + sx = cross([1, 1, 1], [1 0 0]); + sx = sx/norm(sx); + + sy = -cross(sx, [1, 1, 1]); + sy = sy/norm(sy); + + sz = [1, 1, 1]; + sz = sz/norm(sz); + + R = [sx', sy', sz']'; +#+end_src + +#+begin_src matlab :results none + cube = zeros(size(points)); + for i = 1:size(points, 1) + cube(i, :) = R * points(i, :)'; + end +#+end_src + +#+begin_src matlab :results none + figure; + hold on; + plot3(points(:,1), points(:,2), points(:,3), 'ko'); + plot3(cube(:,1), cube(:,2), cube(:,3), 'ro'); + hold off; +#+end_src + +Now we plot the legs of the hexapod. +#+begin_src matlab :results none + leg_indices = [3, 4; ... + 2, 4; ... + 2, 6; ... + 5, 6; ... + 5, 7; ... + 3, 7] + + figure; + hold on; + for i = 1:6 + plot3(cube(leg_indices(i, :),1), cube(leg_indices(i, :),2), cube(leg_indices(i, :),3), '-'); + end + hold off; +#+end_src + +Vectors are: +#+begin_src matlab :results none + legs = zeros(6, 3); + legs_start = zeros(6, 3); + + for i = 1:6 + legs(i, :) = cube(leg_indices(i, 2), :) - cube(leg_indices(i, 1), :); + legs_start(i, :) = cube(leg_indices(i, 1), :) + end +#+end_src + +We now have the orientation of each leg. + +We here want to see if the position of the "slice" changes something. + +Let's first estimate the maximum height of the Stewart platform. +#+begin_src matlab :results none + Hmax = cube(4, 3) - cube(2, 3); +#+end_src + +Let's then estimate the middle position of the platform +#+begin_src matlab :results none + Hmid = cube(8, 3)/2; +#+end_src + +** Generate the Stewart platform for a Cubic configuration + +First we defined the height of the Hexapod. +#+begin_src matlab :results none + H = Hmax/2; +#+end_src + +#+begin_src matlab :results none + Zs = 1.2*cube(2, 3); % Height of the fixed platform + Ze = Zs + H; % Height of the mobile platform +#+end_src + +We now determine the location of the joints on the fixed platform. +#+begin_src matlab :results none + Aa = zeros(6, 3); + for i = 1:6 + t = (Zs-legs_start(i, 3))/(legs(i, 3)); + Aa(i, :) = legs_start(i, :) + t*legs(i, :); + end +#+end_src + +And the location of the joints on the mobile platform +#+begin_src matlab :results none + Ab = zeros(6, 3); + for i = 1:6 + t = (Ze-legs_start(i, 3))/(legs(i, 3)); + Ab(i, :) = legs_start(i, :) + t*legs(i, :); + end +#+end_src + +And we plot the legs. +#+begin_src matlab :results none + figure; + hold on; + for i = 1:6 + plot3([Ab(i, 1),Aa(i, 1)], [Ab(i, 2),Aa(i, 2)], [Ab(i, 3),Aa(i, 3)], 'k-'); + end + hold off; + xlim([-1, 1]); + ylim([-1, 1]); + zlim([0, 2]); +#+end_src + +* Bibliography :ignore: +bibliographystyle:unsrt +bibliography:references.bib diff --git a/figs/3d-cubic-stewart-aligned.png b/figs/3d-cubic-stewart-aligned.png new file mode 100644 index 0000000..f8d4d7b Binary files /dev/null and b/figs/3d-cubic-stewart-aligned.png differ diff --git a/figs/3d-cubic-stewart-misaligned.png b/figs/3d-cubic-stewart-misaligned.png new file mode 100644 index 0000000..e87def8 Binary files /dev/null and b/figs/3d-cubic-stewart-misaligned.png differ diff --git a/figs/stiffness_cube_size.pdf b/figs/stiffness_cube_size.pdf new file mode 100644 index 0000000..3179062 Binary files /dev/null and b/figs/stiffness_cube_size.pdf differ diff --git a/figs/stiffness_cube_size.png b/figs/stiffness_cube_size.png new file mode 100644 index 0000000..c302295 Binary files /dev/null and b/figs/stiffness_cube_size.png differ diff --git a/figs/stiffness_cube_size.svg b/figs/stiffness_cube_size.svg new file mode 100644 index 0000000..fe8c4a8 --- /dev/null +++ b/figs/stiffness_cube_size.svg @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/figs/stiffness_cube_size.tex b/figs/stiffness_cube_size.tex new file mode 100644 index 0000000..24095d4 --- /dev/null +++ b/figs/stiffness_cube_size.tex @@ -0,0 +1,54 @@ +% This file was created by matlab2tikz. +% +\definecolor{mycolor1}{rgb}{0.00000,0.44700,0.74100}% +\definecolor{mycolor2}{rgb}{0.85000,0.32500,0.09800}% +% +\begin{tikzpicture} + +\begin{axis}[% +width=3.23in, +height=1.99in, +at={(0.528in,0.42in)}, +scale only axis, +separate axis lines, +every outer x axis line/.append style={black}, +every x tick label/.append style={font=\color{black}}, +every x tick/.append style={black}, +xmin=250, +xmax=350, +xlabel={Cube Size [mm]}, +every outer y axis line/.append style={black}, +every y tick label/.append style={font=\color{black}}, +every y tick/.append style={black}, +ymin=0, +ymax=0.0816666666666492, +ylabel={Rotational stiffnes [normalized]}, +axis background/.style={fill=white}, +xmajorgrids, +ymajorgrids, +legend style={at={(0.6,2.222)}, anchor=south west, legend cell align=left, align=left, draw=black} +] +\addplot [color=mycolor1, line width=1.5pt] + table[row sep=crcr]{% +250 0.0106166666666923\\ +270 0.0123500000000263\\ +290 0.0142166666666412\\ +310 0.0162166666666508\\ +330 0.0183499999999981\\ +350 0.0206166666666832\\ +}; +\addlegendentry{$k_{\theta_x}$} + +\addplot [color=mycolor2, line width=1.5pt] + table[row sep=crcr]{% +250 0.0416666666666856\\ +270 0.0486000000000217\\ +290 0.0560666666666521\\ +310 0.0640666666666903\\ +330 0.0726000000000226\\ +350 0.0816666666666492\\ +}; +\addlegendentry{$k_{\theta_z}$} + +\end{axis} +\end{tikzpicture}% \ No newline at end of file diff --git a/identification.org b/identification.org index d9a291b..334136b 100644 --- a/identification.org +++ b/identification.org @@ -25,7 +25,7 @@ :END: * Identification -#+begin_src matlab :results none :exports none +#+begin_src matlab :results none :exports none :noweb yes <> addpath('src'); addpath('library'); @@ -37,7 +37,11 @@ The hexapod structure and Sample structure are initialized. #+begin_src matlab :results none - initializeHexapod(); + stewart = initializeGeneralConfiguration(); + stewart = computeGeometricalProperties(stewart); + stewart = initializeMechanicalElements(stewart); + save('./mat/stewart.mat', 'stewart'); + initializeSample(); #+end_src @@ -45,92 +49,111 @@ The hexapod structure and Sample structure are initialized. G = identifyPlant(); #+end_src +#+begin_src matlab :results none + freqs = logspace(2, 4, 1000); +#+end_src + * Cartesian Plot From a force applied in the Cartesian frame to a displacement in the Cartesian frame. #+begin_src matlab :results none figure; hold on; - bode(G.G_cart(1, 1)); - bode(G.G_cart(3, 3)); + plot(freqs, abs(squeeze(freqresp(G.G_cart(1, 1), freqs, 'Hz')))); + plot(freqs, abs(squeeze(freqresp(G.G_cart(2, 1), freqs, 'Hz')))); + plot(freqs, abs(squeeze(freqresp(G.G_cart(3, 1), freqs, 'Hz')))); hold off; + set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); + xlabel('Frequency [Hz]'); ylabel('Amplitude'); +#+end_src + +#+begin_src matlab :results none + figure; + bode(G.G_cart, freqs); #+end_src * From a force to force sensor #+begin_src matlab :results none figure; hold on; - bode(G.G_forc(1, 1)); - bode(G.G_forc(2, 2)); - bode(G.G_forc(3, 3)); - bode(G.G_forc(4, 4)); - bode(G.G_forc(5, 5)); - bode(G.G_forc(6, 6)); + plot(freqs, abs(squeeze(freqresp(G.G_forc(1, 1), freqs, 'Hz'))), 'k-', 'DisplayName', '$F_{m_i}/F_{i}$'); hold off; + set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); + xlabel('Frequency [Hz]'); ylabel('Amplitude [N/N]'); + legend('location', 'southeast'); #+end_src #+begin_src matlab :results none figure; hold on; - bode(G.G_forc(1, 1)); - bode(G.G_forc(1, 2)); - bode(G.G_forc(1, 3)); - bode(G.G_forc(1, 4)); - bode(G.G_forc(1, 5)); - bode(G.G_forc(1, 6)); + plot(freqs, abs(squeeze(freqresp(G.G_forc(1, 1), freqs, 'Hz'))), 'k-', 'DisplayName', '$F_{m_i}/F_{i}$'); + plot(freqs, abs(squeeze(freqresp(G.G_forc(2, 1), freqs, 'Hz'))), 'k--', 'DisplayName', '$F_{m_j}/F_{i}$'); + plot(freqs, abs(squeeze(freqresp(G.G_forc(3, 1), freqs, 'Hz'))), 'k--', 'HandleVisibility', 'off'); + plot(freqs, abs(squeeze(freqresp(G.G_forc(4, 1), freqs, 'Hz'))), 'k--', 'HandleVisibility', 'off'); + plot(freqs, abs(squeeze(freqresp(G.G_forc(5, 1), freqs, 'Hz'))), 'k--', 'HandleVisibility', 'off'); + plot(freqs, abs(squeeze(freqresp(G.G_forc(6, 1), freqs, 'Hz'))), 'k--', 'HandleVisibility', 'off'); hold off; + set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); + xlabel('Frequency [Hz]'); ylabel('Amplitude [N/N]'); + legend('location', 'southeast'); #+end_src * From a force applied in the leg to the displacement of the leg #+begin_src matlab :results none figure; hold on; - bode(G.G_legs(1, 1)); - bode(G.G_legs(2, 2)); - bode(G.G_legs(3, 3)); - bode(G.G_legs(4, 4)); - bode(G.G_legs(5, 5)); - bode(G.G_legs(6, 6)); + plot(freqs, abs(squeeze(freqresp(G.G_legs(1, 1), freqs, 'Hz'))), 'k-', 'DisplayName', '$D_{i}/F_{i}$'); hold off; + set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); + xlabel('Frequency [Hz]'); ylabel('Amplitude [m/N]'); #+end_src #+begin_src matlab :results none figure; hold on; - bode(G.G_legs(1, 1)); - bode(G.G_legs(1, 2)); - bode(G.G_legs(1, 3)); - bode(G.G_legs(1, 4)); - bode(G.G_legs(1, 5)); - bode(G.G_legs(1, 6)); + plot(freqs, abs(squeeze(freqresp(G.G_legs(1, 1), freqs, 'Hz'))), 'k-', 'DisplayName', '$D_{i}/F_{i}$'); + plot(freqs, abs(squeeze(freqresp(G.G_legs(2, 1), freqs, 'Hz'))), 'k--', 'DisplayName', '$D_{j}/F_{i}$'); + plot(freqs, abs(squeeze(freqresp(G.G_legs(3, 1), freqs, 'Hz'))), 'k--', 'HandleVisibility', 'off'); + plot(freqs, abs(squeeze(freqresp(G.G_legs(4, 1), freqs, 'Hz'))), 'k--', 'HandleVisibility', 'off'); + plot(freqs, abs(squeeze(freqresp(G.G_legs(5, 1), freqs, 'Hz'))), 'k--', 'HandleVisibility', 'off'); + plot(freqs, abs(squeeze(freqresp(G.G_legs(6, 1), freqs, 'Hz'))), 'k--', 'HandleVisibility', 'off'); hold off; + set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); + xlabel('Frequency [Hz]'); ylabel('Amplitude [m/N]'); + legend('location', 'northeast'); #+end_src * Transmissibility #+begin_src matlab :results none figure; hold on; - bode(G.G_tran(1, 1)); - bode(G.G_tran(2, 2)); - bode(G.G_tran(3, 3)); + plot(freqs, abs(squeeze(freqresp(G.G_tran(1, 1), freqs, 'Hz')))); + plot(freqs, abs(squeeze(freqresp(G.G_tran(2, 2), freqs, 'Hz')))); + plot(freqs, abs(squeeze(freqresp(G.G_tran(3, 3), freqs, 'Hz')))); hold off; + set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); + xlabel('Frequency [Hz]'); ylabel('Amplitude [m/m]'); #+end_src #+begin_src matlab :results none figure; hold on; - bode(G.G_tran(4, 4)); - bode(G.G_tran(5, 5)); - bode(G.G_tran(6, 6)); + plot(freqs, abs(squeeze(freqresp(G.G_tran(4, 4), freqs, 'Hz')))); + plot(freqs, abs(squeeze(freqresp(G.G_tran(5, 5), freqs, 'Hz')))); + plot(freqs, abs(squeeze(freqresp(G.G_tran(6, 6), freqs, 'Hz')))); hold off; + set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); + xlabel('Frequency [Hz]'); ylabel('Amplitude [$\frac{rad/s}{rad/s}$]'); #+end_src #+begin_src matlab :results none figure; hold on; - bode(G.G_tran(1, 1)); - bode(G.G_tran(2, 1)); - bode(G.G_tran(3, 1)); + plot(freqs, abs(squeeze(freqresp(G.G_tran(1, 1), freqs, 'Hz')))); + plot(freqs, abs(squeeze(freqresp(G.G_tran(1, 2), freqs, 'Hz')))); + plot(freqs, abs(squeeze(freqresp(G.G_tran(1, 3), freqs, 'Hz')))); hold off; + set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); + xlabel('Frequency [Hz]'); ylabel('Amplitude [m/m]'); #+end_src * Compliance @@ -139,10 +162,12 @@ From a force applied in the Cartesian frame to a relative displacement of the mo #+begin_src matlab :results none figure; hold on; - bode(G.G_comp(1, 1)); - bode(G.G_comp(2, 2)); - bode(G.G_comp(3, 3)); + plot(freqs, abs(squeeze(freqresp(G.G_comp(1, 1), freqs, 'Hz')))); + plot(freqs, abs(squeeze(freqresp(G.G_comp(2, 2), freqs, 'Hz')))); + plot(freqs, abs(squeeze(freqresp(G.G_comp(3, 3), freqs, 'Hz')))); hold off; + set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); + xlabel('Frequency [Hz]'); ylabel('Amplitude [m/N]'); #+end_src * Inertial @@ -151,10 +176,12 @@ From a force applied on the Cartesian frame to the absolute displacement of the #+begin_src matlab :results none figure; hold on; - bode(G.G_iner(1, 1)); - bode(G.G_iner(2, 2)); - bode(G.G_iner(3, 3)); + plot(freqs, abs(squeeze(freqresp(G.G_iner(1, 1), freqs, 'Hz')))); + plot(freqs, abs(squeeze(freqresp(G.G_iner(2, 2), freqs, 'Hz')))); + plot(freqs, abs(squeeze(freqresp(G.G_iner(3, 3), freqs, 'Hz')))); hold off; + set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); + xlabel('Frequency [Hz]'); ylabel('Amplitude [m/N]'); #+end_src * identifyPlant @@ -228,11 +255,11 @@ We defined all the Input/Output names of the identified transfer function. We split the transfer function into sub transfer functions and we compute their minimum realization. #+begin_src matlab - sys.G_cart = minreal(G({'Dxm', 'Dym', 'Dzm', 'Rxm', 'Rym', 'Rzm'}, {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'})); - sys.G_forc = minreal(G({'F1m', 'F2m', 'F3m', 'F4m', 'F5m', 'F6m'}, {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'})); - sys.G_legs = minreal(G({'D1m', 'D2m', 'D3m', 'D4m', 'D5m', 'D6m'}, {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'})); + sys.G_cart = minreal(G({'Dxm', 'Dym', 'Dzm', 'Rxm', 'Rym', 'Rzm'}, {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'})); + sys.G_forc = minreal(G({'F1m', 'F2m', 'F3m', 'F4m', 'F5m', 'F6m'}, {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'})); + sys.G_legs = minreal(G({'D1m', 'D2m', 'D3m', 'D4m', 'D5m', 'D6m'}, {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'})); sys.G_tran = minreal(G({'Dxtm', 'Dytm', 'Dztm', 'Rxtm', 'Rytm', 'Rztm'}, {'Dwx', 'Dwy', 'Dwz', 'Rwx', 'Rwy', 'Rwz'})); - sys.G_comp = minreal(G({'Dxm', 'Dym', 'Dzm', 'Rxm', 'Rym', 'Rzm'}, {'Fdx', 'Fdy', 'Fdz', 'Mdx', 'Mdy', 'Mdz'})); + sys.G_comp = minreal(G({'Dxm', 'Dym', 'Dzm', 'Rxm', 'Rym', 'Rzm'}, {'Fdx', 'Fdy', 'Fdz', 'Mdx', 'Mdy', 'Mdz'})); sys.G_iner = minreal(G({'Dxtm', 'Dytm', 'Dztm', 'Rxtm', 'Rytm', 'Rztm'}, {'Fdx', 'Fdy', 'Fdz', 'Mdx', 'Mdy', 'Mdz'})); % sys.G_all = minreal(G); #+end_src diff --git a/index.html b/index.html index 1337f4b..fd92b09 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Stewart Platform Studies @@ -253,36 +253,37 @@ for the JavaScript code in this tag.

Table of Contents

-
-

1 Simscape Model

+ -
-

2 Architecture Study

+
+

2 Architecture Study

-
-

3 Motion Control

+
+

3 Motion Control

  • Active Damping
  • @@ -294,7 +295,7 @@ for the JavaScript code in this tag.

Author: Thomas Dehaeze

-

Created: 2019-03-22 ven. 12:03

+

Created: 2019-03-25 lun. 18:11

Validate

diff --git a/index.org b/index.org index 5e25b0f..fea6aaa 100644 --- a/index.org +++ b/index.org @@ -26,12 +26,13 @@ * Simscape Model - [[file:simscape-model.org][Model of the Stewart Platform]] -- [[file:identification.org][Identification]] +- [[file:identification.org][Identification of the Simscape Model]] * Architecture Study - [[file:kinematic-study.org][Kinematic Study]] - [[file:stiffness-study.org][Stiffness Matrix Study]] - Jacobian Study +- [[file:cubic-configuration.org][Cubic Architecture]] * Motion Control - Active Damping diff --git a/kinematic-study.org b/kinematic-study.org index 00cfb4d..301baf4 100644 --- a/kinematic-study.org +++ b/kinematic-study.org @@ -1,4 +1,28 @@ #+TITLE: Kinematic Study of the Stewart Platform +:DRAWER: +#+STARTUP: overview + +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: + +#+LATEX_CLASS: cleanreport +#+LaTeX_CLASS_OPTIONS: [tocnp, secbreak, minted] +#+LaTeX_HEADER: \usepackage{svg} +#+LaTeX_HEADER: \newcommand{\authorFirstName}{Thomas} +#+LaTeX_HEADER: \newcommand{\authorLastName}{Dehaeze} +#+LaTeX_HEADER: \newcommand{\authorEmail}{dehaeze.thomas@gmail.com} + +#+PROPERTY: header-args:matlab :session *MATLAB* +#+PROPERTY: header-args:matlab+ :comments org +#+PROPERTY: header-args:matlab+ :exports both +#+PROPERTY: header-args:matlab+ :eval no-export +#+PROPERTY: header-args:matlab+ :output-dir figs +#+PROPERTY: header-args:matlab+ :mkdirp yes +:END: * Functions :PROPERTIES: diff --git a/mat/sample.mat b/mat/sample.mat index 85ab8c0..db071b7 100644 Binary files a/mat/sample.mat and b/mat/sample.mat differ diff --git a/mat/stewart.mat b/mat/stewart.mat index 8f31a2d..4b9186e 100644 Binary files a/mat/stewart.mat and b/mat/stewart.mat differ diff --git a/references.bib b/references.bib new file mode 100644 index 0000000..957b49f --- /dev/null +++ b/references.bib @@ -0,0 +1,37 @@ +@inproceedings{abbas14_vibrat_stewar_platf, + author = {Hussain Abbas and Huang Hai}, + title = {Vibration isolation concepts for non-cubic Stewart Platform + using modal control}, + booktitle = {Proceedings of 2014 11th International Bhurban Conference on + Applied Sciences \& Technology (IBCAST) Islamabad, Pakistan, + 14th - 18th January, 2014}, + year = 2014, + pages = {nil}, + doi = {10.1109/ibcast.2014.6778139}, + url = {https://doi.org/10.1109/ibcast.2014.6778139}, + month = 1, +} + +@book{taghirad13_paral, + author = {Taghirad, Hamid}, + title = {Parallel robots : mechanics and control}, + year = 2013, + publisher = {CRC Press}, + address = {Boca Raton, FL}, + isbn = 9781466555778, + keywords = {favorite}, +} + +@article{geng94_six_degree_of_freed_activ, + author = {Z.J. Geng and L.S. Haynes}, + title = {Six Degree-Of-Freedom Active Vibration Control Using the + Stewart Platforms}, + journal = {IEEE Transactions on Control Systems Technology}, + volume = 2, + number = 1, + pages = {45-53}, + year = 1994, + doi = {10.1109/87.273110}, + url = {https://doi.org/10.1109/87.273110}, + keywords = {}, +} \ No newline at end of file diff --git a/simscape-model.html b/simscape-model.html index ef43443..31fcfea 100644 --- a/simscape-model.html +++ b/simscape-model.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Stewart Platform - Simscape Model @@ -275,42 +275,136 @@ for the JavaScript code in this tag.

Table of Contents

-
-

1 Function description and arguments

-

-The initializeHexapod function takes one structure that contains configurations for the hexapod and returns one structure representing the hexapod. +Stewart platforms are generated in multiple steps.

-
-
function [stewart] = initializeHexapod(opts_param)
-
+ +

+First, geometrical parameters are defined: +

+
    +
  • \({}^Aa_i\) - Position of the joints fixed to the fixed base w.r.t \(\{A\}\)
  • +
  • \({}^Ab_i\) - Position of the joints fixed to the mobile platform w.r.t \(\{A\}\)
  • +
  • \({}^Bb_i\) - Position of the joints fixed to the mobile platform w.r.t \(\{B\}\)
  • +
  • \(H\) - Total height of the mobile platform
  • +
+ +

+These parameter are enough to determine all the kinematic properties of the platform like the Jacobian, stroke, stiffness, … +These geometrical parameters can be generated using different functions: initializeCubicConfiguration for cubic configuration or initializeGeneralConfiguration for more general configuration. +

+ +

+A function computeGeometricalProperties is then used to compute: +

+
    +
  • \(J_f\) - Jacobian matrix for the force location
  • +
  • \(J_d\) - Jacobian matrix for displacement estimation
  • +
  • \(R_m\) - Rotation matrices to position the leg vectors
  • +
+ +

+Then, geometrical parameters are computed for all the mechanical elements with the function initializeMechanicalElements: +

+
    +
  • Shape of the platforms +
      +
    • External Radius
    • +
    • Internal Radius
    • +
    • Density
    • +
    • Thickness
    • +
  • +
  • Shape of the Legs +
      +
    • Radius
    • +
    • Size of ball joint
    • +
    • Density
    • +
  • +
+ +

+Other Parameters are defined for the Simscape simulation: +

+
    +
  • Sample mass, volume and position (initializeSample function)
  • +
  • Location of the inertial sensor
  • +
  • Location of the point for the differential measurements
  • +
  • Location of the Jacobian point for velocity/displacement computation
  • +
+ +
+

1 initializeGeneralConfiguration

+
+
+

1.1 Function description

+
+

+The initializeGeneralConfiguration function takes one structure that contains configurations for the hexapod and returns one structure representing the Hexapod. +

+ +
+
function [stewart] = initializeGeneralConfiguration(opts_param)
+
+
+
+
+ +
+

1.2 Optional Parameters

+

Default values for opts.

opts = struct(...
-    'height',  90,    ... % Height of the platform [mm]
-    'density', 8000,  ... % Density of the material used for the hexapod [kg/m3]
-    'k_ax',    1e8,   ... % Stiffness of each actuator [N/m]
-    'c_ax',    1000,   ... % Damping of each actuator [N/(m/s)]
-    'stroke',  50e-6, ... % Maximum stroke of each actuator [m]
-    'name',    'stewart' ... % Name of the file
+    'H_tot',   90, ... % Height of the platform [mm]
+    'H_joint', 15, ... % Height of the joints [mm]
+    'H_plate', 10, ... % Thickness of the fixed and mobile platforms [mm]
+    'R_bot',  100, ... % Radius where the legs articulations are positionned [mm]
+    'R_top',  80,  ... % Radius where the legs articulations are positionned [mm]
+    'a_bot',  10,  ... % Angle Offset [deg]
+    'a_top',  40,  ... % Angle Offset [deg]
+    'da_top', 0    ... % Angle Offset from 0 position [deg]
     );
 
@@ -329,37 +423,263 @@ Populate opts with input parameters
-
-

2 Initialization of the stewart structure

-
-

-We initialize the Stewart structure -

-
-
stewart = struct();
-
-
+
+

1.3 Geometry Description

+
-

-And we defined its total height. -

-
-
stewart.H = opts.height; % [mm]
-
-
-
-
- -
-

3 Bottom Plate

-
- -
+

stewart_bottom_plate.png

Figure 1: Schematic of the bottom plates with all the parameters

+
+
+
+

1.4 Compute Aa and Ab

+
+

+We compute \([a_1, a_2, a_3, a_4, a_5, a_6]^T\) and \([b_1, b_2, b_3, b_4, b_5, b_6]^T\). +

+ +
+
Aa = zeros(6, 3); % [mm]
+Ab = zeros(6, 3); % [mm]
+Bb = zeros(6, 3); % [mm]
+
+
+ +
+
for i = 1:3
+    Aa(2*i-1,:) = [opts.R_bot*cos( pi/180*(120*(i-1) - opts.a_bot) ), ...
+                   opts.R_bot*sin( pi/180*(120*(i-1) - opts.a_bot) ), ...
+                   opts.H_plate+opts.H_joint];
+    Aa(2*i,:)   = [opts.R_bot*cos( pi/180*(120*(i-1) + opts.a_bot) ), ...
+                   opts.R_bot*sin( pi/180*(120*(i-1) + opts.a_bot) ), ...
+                   opts.H_plate+opts.H_joint];
+
+    Ab(2*i-1,:) = [opts.R_top*cos( pi/180*(120*(i-1) + opts.da_top - opts.a_top) ), ...
+                   opts.R_top*sin( pi/180*(120*(i-1) + opts.da_top - opts.a_top) ), ...
+                   opts.H_tot - opts.H_plate - opts.H_joint];
+    Ab(2*i,:)   = [opts.R_top*cos( pi/180*(120*(i-1) + opts.da_top + opts.a_top) ), ...
+                   opts.R_top*sin( pi/180*(120*(i-1) + opts.da_top + opts.a_top) ), ...
+                   opts.H_tot - opts.H_plate - opts.H_joint];
+end
+
+Bb = Ab - opts.H_tot*[0,0,1];
+
+
+
+
+ +
+

1.5 Returns Stewart Structure

+
+
+
  stewart = struct();
+  stewart.Aa = Aa;
+  stewart.Ab = Ab;
+  stewart.Bb = Bb;
+  stewart.H_tot = opts.H_tot;
+end
+
+
+
+
+
+ +
+

2 computeGeometricalProperties

+
+
+ +
+

2.1 Function description

+
+
+
function [stewart] = computeGeometricalProperties(stewart, opts_param)
+
+
+
+
+ +
+

2.2 Optional Parameters

+
+

+Default values for opts. +

+
+
opts = struct(...
+    'Jd_pos', [0, 0, 30], ... % Position of the Jacobian for displacement estimation from the top of the mobile platform [mm]
+    'Jf_pos', [0, 0, 30]  ... % Position of the Jacobian for force location from the top of the mobile platform [mm]
+    );
+
+
+ +

+Populate opts with input parameters +

+
+
if exist('opts_param','var')
+    for opt = fieldnames(opts_param)'
+        opts.(opt{1}) = opts_param.(opt{1});
+    end
+end
+
+
+
+
+ +
+

2.3 Rotation matrices

+
+

+We initialize \(l_i\) and \(\hat{s}_i\) +

+
+
leg_length = zeros(6, 1); % [mm]
+leg_vectors = zeros(6, 3);
+
+
+ +

+We compute \(b_i - a_i\), and then: +

+\begin{align*} + l_i &= \left|b_i - a_i\right| \\ + \hat{s}_i &= \frac{b_i - a_i}{l_i} +\end{align*} + +
+
legs = stewart.Ab - stewart.Aa;
+
+for i = 1:6
+    leg_length(i) = norm(legs(i,:));
+    leg_vectors(i,:) = legs(i,:) / leg_length(i);
+end
+
+
+ +

+We compute rotation matrices to have the orientation of the legs. +The rotation matrix transforms the \(z\) axis to the axis of the leg. The other axis are not important here. +

+
+
stewart.Rm = struct('R', eye(3));
+
+for i = 1:6
+  sx = cross(leg_vectors(i,:), [1 0 0]);
+  sx = sx/norm(sx);
+
+  sy = -cross(sx, leg_vectors(i,:));
+  sy = sy/norm(sy);
+
+  sz = leg_vectors(i,:);
+  sz = sz/norm(sz);
+
+  stewart.Rm(i).R = [sx', sy', sz'];
+end
+
+
+
+
+ +
+

2.4 Jacobian matrices

+
+

+Compute Jacobian Matrix +

+
+
Jd = zeros(6);
+
+for i = 1:6
+  Jd(i, 1:3) = leg_vectors(i, :);
+  Jd(i, 4:6) = cross(0.001*(stewart.Bb(i, :) - opts.Jd_pos), leg_vectors(i, :));
+end
+
+stewart.Jd = Jd;
+stewart.Jd_inv = inv(Jd);
+
+
+ +
+
Jf = zeros(6);
+
+for i = 1:6
+  Jf(i, 1:3) = leg_vectors(i, :);
+  Jf(i, 4:6) = cross(0.001*(stewart.Bb(i, :) - opts.Jf_pos), leg_vectors(i, :));
+end
+
+stewart.Jf = Jf;
+stewart.Jf_inv = inv(Jf);
+
+
+ +
+
end
+
+
+
+
+
+ +
+

3 initializeMechanicalElements

+
+
+ +
+

3.1 Function description

+
+
+
function [stewart] = initializeMechanicalElements(stewart, opts_param)
+
+
+
+
+ +
+

3.2 Optional Parameters

+
+

+Default values for opts. +

+
+
opts = struct(...
+    'thickness', 10, ... % Thickness of the base and platform [mm]
+    'density',   1000, ... % Density of the material used for the hexapod [kg/m3]
+    'k_ax',      1e8, ... % Stiffness of each actuator [N/m]
+    'c_ax',      1000, ... % Damping of each actuator [N/(m/s)]
+    'stroke',    50e-6  ... % Maximum stroke of each actuator [m]
+    );
+
+
+ +

+Populate opts with input parameters +

+
+
if exist('opts_param','var')
+    for opt = fieldnames(opts_param)'
+        opts.(opt{1}) = opts_param.(opt{1});
+    end
+end
+
+
+
+
+ +
+

3.3 Bottom Plate

+
+ +
+

stewart_bottom_plate.png +

+

Figure 2: Schematic of the bottom plates with all the parameters

+

The bottom plate structure is initialized. @@ -382,16 +702,7 @@ BP.Rext = 150; -

BP.H = 10; % Thickness of the Bottom Plate [mm]
-
-
- -

-At which radius legs will be fixed and with that angle offset. -

-
-
BP.Rleg  = 100; % Radius where the legs articulations are positionned [mm]
-BP.alpha = 10;  % Angle Offset [deg]
+
BP.H = opts.thickness; % Thickness of the Bottom Plate [mm]
 
@@ -429,9 +740,9 @@ The structure is added to the stewart structure
-
-

4 Top Plate

-
+
+

3.4 Top Plate

+

The top plate structure is initialized.

@@ -457,16 +768,6 @@ The thickness of the top plate.
-

-At which radius and angle are fixed the legs. -

-
-
TP.Rleg   = 100; % Radius where the legs articulations are positionned [mm]
-TP.alpha  = 20; % Angle [deg]
-TP.dalpha = 0; % Angle Offset from 0 position [deg]
-
-
-

The density of its material.

@@ -501,17 +802,16 @@ The structure is added to the stewart structure
-
-

5 Legs

-
+
+

3.5 Legs

+
-
+

stewart_legs.png

-

Figure 2: Schematic for the legs of the Stewart platform

+

Figure 3: Schematic for the legs of the Stewart platform

-

The leg structure is initialized.

@@ -570,6 +870,29 @@ The radius of spheres representing the ball joints are defined.
+

+We estimate the length of the legs. +

+
+
legs = stewart.Ab - stewart.Aa;
+Leg.lenght = norm(legs(1,:))/1.5;
+
+
+ +

+Then the shape of the bottom leg is estimated +

+
+
Leg.shape.bot = ...
+    [0        0; ...
+     Leg.Rbot 0; ...
+     Leg.Rbot Leg.lenght; ...
+     Leg.Rtop Leg.lenght; ...
+     Leg.Rtop 0.2*Leg.lenght; ...
+     0        0.2*Leg.lenght];
+
+
+

The structure is added to the stewart structure

@@ -580,14 +903,14 @@ The structure is added to the stewart structure
-
-

6 Ball Joints

-
+
+

3.6 Ball Joints

+
-
+

stewart_ball_joints.png

-

Figure 3: Schematic of the support for the ball joints

+

Figure 4: Schematic of the support for the ball joints

@@ -615,7 +938,7 @@ SP.c = 0; % [ Its height is defined

-
SP.H = 15; % [mm]
+
SP.H = stewart.Aa(1, 3) - BP.H; % [mm]
 
@@ -660,195 +983,74 @@ The structure is added to the Hexapod structure
- -
-

7 More parameters are initialized

-
-
-
stewart = initializeParameters(stewart);
-
-
-
-
-

8 Save the Stewart Structure

-
-
-
save('./mat/stewart.mat', 'stewart')
-
-
-
+
+

4 initializeSample

+
-
-

9 initializeParameters Function

-
-
-
function [stewart] = initializeParameters(stewart)
-
-
- -

-We first compute \([a_1, a_2, a_3, a_4, a_5, a_6]^T\) and \([b_1, b_2, b_3, b_4, b_5, b_6]^T\). -

-
-
stewart.Aa = zeros(6, 3); % [mm]
-stewart.Ab = zeros(6, 3); % [mm]
-stewart.Bb = zeros(6, 3); % [mm]
-
-
- -
-
for i = 1:3
-    stewart.Aa(2*i-1,:) = [stewart.BP.Rleg*cos( pi/180*(120*(i-1) - stewart.BP.alpha) ), ...
-                           stewart.BP.Rleg*sin( pi/180*(120*(i-1) - stewart.BP.alpha) ), ...
-                           stewart.BP.H+stewart.SP.H];
-    stewart.Aa(2*i,:)   = [stewart.BP.Rleg*cos( pi/180*(120*(i-1) + stewart.BP.alpha) ), ...
-                           stewart.BP.Rleg*sin( pi/180*(120*(i-1) + stewart.BP.alpha) ), ...
-                           stewart.BP.H+stewart.SP.H];
-
-    stewart.Ab(2*i-1,:) = [stewart.TP.Rleg*cos( pi/180*(120*(i-1) + stewart.TP.dalpha - stewart.TP.alpha) ), ...
-                           stewart.TP.Rleg*sin( pi/180*(120*(i-1) + stewart.TP.dalpha - stewart.TP.alpha) ), ...
-                           stewart.H - stewart.TP.H - stewart.SP.H];
-    stewart.Ab(2*i,:)   = [stewart.TP.Rleg*cos( pi/180*(120*(i-1) + stewart.TP.dalpha + stewart.TP.alpha) ), ...
-                           stewart.TP.Rleg*sin( pi/180*(120*(i-1) + stewart.TP.dalpha + stewart.TP.alpha) ), ...
-                           stewart.H - stewart.TP.H - stewart.SP.H];
-end
-stewart.Bb = stewart.Ab - stewart.H*[0,0,1];
-
-
- -

-Now, we compute the leg vectors \(\hat{s}_i\) and leg position \(l_i\): -\[ b_i - a_i = l_i \hat{s}_i \] -

- -

-We initialize \(l_i\) and \(\hat{s}_i\) -

-
-
leg_length = zeros(6, 1); % [mm]
-leg_vectors = zeros(6, 3);
-
-
- -

-We compute \(b_i - a_i\), and then: -

-\begin{align*} - l_i &= \left|b_i - a_i\right| \\ - \hat{s}_i &= \frac{b_i - a_i}{l_i} -\end{align*} - -
-
legs = stewart.Ab - stewart.Aa;
-
-for i = 1:6
-    leg_length(i) = norm(legs(i,:));
-    leg_vectors(i,:) = legs(i,:) / leg_length(i);
-end
-
-
- -

-Then the shape of the bottom leg is estimated -

-
-
stewart.Leg.lenght = leg_length(1)/1.5;
-stewart.Leg.shape.bot = ...
-    [0                0; ...
-     stewart.Leg.Rbot 0; ...
-     stewart.Leg.Rbot stewart.Leg.lenght; ...
-     stewart.Leg.Rtop stewart.Leg.lenght; ...
-     stewart.Leg.Rtop 0.2*stewart.Leg.lenght; ...
-     0                0.2*stewart.Leg.lenght];
-
-
- -

-We compute rotation matrices to have the orientation of the legs. -The rotation matrix transforms the \(z\) axis to the axis of the leg. The other axis are not important here. -

-
-
stewart.Rm = struct('R', eye(3));
-
-for i = 1:6
-  sx = cross(leg_vectors(i,:), [1 0 0]);
-  sx = sx/norm(sx);
-
-  sy = -cross(sx, leg_vectors(i,:));
-  sy = sy/norm(sy);
-
-  sz = leg_vectors(i,:);
-  sz = sz/norm(sz);
-
-  stewart.Rm(i).R = [sx', sy', sz'];
-end
-
-
- -

-Compute Jacobian Matrix -

-
-
J = zeros(6);
-
-for i = 1:6
-  J(i, 1:3) = leg_vectors(i, :);
-  J(i, 4:6) = cross(0.001*(stewart.Ab(i, :)- stewart.H*[0,0,1]), leg_vectors(i, :));
-end
-
-stewart.J = J;
-stewart.Jinv = inv(J);
-
-
- -
-
stewart.K = stewart.Leg.k_ax*stewart.J'*stewart.J;
-
-
- -
-
  end
-end
-
-
-
-
-
-

10 initializeSample

-
+
+

4.1 Function description

+
function [] = initializeSample(opts_param)
-%% Default values for opts
-    sample = struct( ...
-        'radius',     100, ... % radius of the cylinder [mm]
-        'height',     100, ... % height of the cylinder [mm]
-        'mass',       10,  ... % mass of the cylinder [kg]
-        'measheight', 50, ... % measurement point z-offset [mm]
-        'offset',     [0, 0, 0],   ... % offset position of the sample [mm]
-        'color',      [0.9 0.1 0.1] ...
-        );
+
+
+
+
- %% Populate opts with input parameters - if exist('opts_param','var') - for opt = fieldnames(opts_param)' - sample.(opt{1}) = opts_param.(opt{1}); - end +
+

4.2 Optional Parameters

+
+

+Default values for opts. +

+
+
sample = struct( ...
+    'radius',     100, ... % radius of the cylinder [mm]
+    'height',     100, ... % height of the cylinder [mm]
+    'mass',       10,  ... % mass of the cylinder [kg]
+    'measheight', 50, ... % measurement point z-offset [mm]
+    'offset',     [0, 0, 0],   ... % offset position of the sample [mm]
+    'color',      [0.9 0.1 0.1] ...
+    );
+
+
+ +

+Populate opts with input parameters +

+
+
if exist('opts_param','var')
+    for opt = fieldnames(opts_param)'
+        sample.(opt{1}) = opts_param.(opt{1});
     end
-
-    %% Save
-    save('./mat/sample.mat', 'sample');
 end
 
+ +
+

4.3 Save the Sample structure

+
+
+
save('./mat/sample.mat', 'sample');
+
+
+ +
+
end
+
+
+
+
+

Author: Thomas Dehaeze

-

Created: 2019-03-22 ven. 12:03

+

Created: 2019-03-25 lun. 11:18

Validate

diff --git a/simscape-model.org b/simscape-model.org index 25d7635..717d3e7 100644 --- a/simscape-model.org +++ b/simscape-model.org @@ -17,29 +17,73 @@ #+LaTeX_HEADER: \newcommand{\authorEmail}{dehaeze.thomas@gmail.com} #+PROPERTY: header-args:matlab :session *MATLAB* -#+PROPERTY: header-args:matlab+ :comments no -#+PROPERTY: header-args:matlab+ :exports bode -#+PROPERTY: header-args:matlab+ :eval no +#+PROPERTY: header-args:matlab+ :comments org +#+PROPERTY: header-args:matlab+ :exports both +#+PROPERTY: header-args:matlab+ :eval no-export #+PROPERTY: header-args:matlab+ :output-dir figs #+PROPERTY: header-args:matlab+ :mkdirp yes -#+PROPERTY: header-args:matlab+ :tangle src/initializeHexapod.m :END: -* Function description and arguments -The =initializeHexapod= function takes one structure that contains configurations for the hexapod and returns one structure representing the hexapod. +Stewart platforms are generated in multiple steps. + +First, geometrical parameters are defined: +- ${}^Aa_i$ - Position of the joints fixed to the fixed base w.r.t $\{A\}$ +- ${}^Ab_i$ - Position of the joints fixed to the mobile platform w.r.t $\{A\}$ +- ${}^Bb_i$ - Position of the joints fixed to the mobile platform w.r.t $\{B\}$ +- $H$ - Total height of the mobile platform + +These parameter are enough to determine all the kinematic properties of the platform like the Jacobian, stroke, stiffness, ... +These geometrical parameters can be generated using different functions: =initializeCubicConfiguration= for cubic configuration or =initializeGeneralConfiguration= for more general configuration. + +A function =computeGeometricalProperties= is then used to compute: +- $J_f$ - Jacobian matrix for the force location +- $J_d$ - Jacobian matrix for displacement estimation +- $R_m$ - Rotation matrices to position the leg vectors + +Then, geometrical parameters are computed for all the mechanical elements with the function =initializeMechanicalElements=: +- Shape of the platforms + - External Radius + - Internal Radius + - Density + - Thickness +- Shape of the Legs + - Radius + - Size of ball joint + - Density + +Other Parameters are defined for the Simscape simulation: +- Sample mass, volume and position (=initializeSample= function) +- Location of the inertial sensor +- Location of the point for the differential measurements +- Location of the Jacobian point for velocity/displacement computation + +* initializeGeneralConfiguration + :PROPERTIES: + :HEADER-ARGS:matlab+: :exports code + :HEADER-ARGS:matlab+: :comments no + :HEADER-ARGS:matlab+: :eval no + :HEADER-ARGS:matlab+: :tangle src/initializeGeneralConfiguration.m + :END: + +** Function description +The =initializeGeneralConfiguration= function takes one structure that contains configurations for the hexapod and returns one structure representing the Hexapod. + #+begin_src matlab - function [stewart] = initializeHexapod(opts_param) + function [stewart] = initializeGeneralConfiguration(opts_param) #+end_src +** Optional Parameters Default values for opts. #+begin_src matlab opts = struct(... - 'height', 90, ... % Height of the platform [mm] - 'density', 8000, ... % Density of the material used for the hexapod [kg/m3] - 'k_ax', 1e8, ... % Stiffness of each actuator [N/m] - 'c_ax', 1000, ... % Damping of each actuator [N/(m/s)] - 'stroke', 50e-6, ... % Maximum stroke of each actuator [m] - 'name', 'stewart' ... % Name of the file + 'H_tot', 90, ... % Height of the platform [mm] + 'H_joint', 15, ... % Height of the joints [mm] + 'H_plate', 10, ... % Thickness of the fixed and mobile platforms [mm] + 'R_bot', 100, ... % Radius where the legs articulations are positionned [mm] + 'R_top', 80, ... % Radius where the legs articulations are positionned [mm] + 'a_bot', 10, ... % Angle Offset [deg] + 'a_top', 40, ... % Angle Offset [deg] + 'da_top', 0 ... % Angle Offset from 0 position [deg] ); #+end_src @@ -52,22 +96,190 @@ Populate opts with input parameters end #+end_src -* Initialization of the stewart structure -We initialize the Stewart structure -#+begin_src matlab - stewart = struct(); -#+end_src - -And we defined its total height. -#+begin_src matlab - stewart.H = opts.height; % [mm] -#+end_src - -* Bottom Plate +** Geometry Description #+name: fig:stewart_bottom_plate #+caption: Schematic of the bottom plates with all the parameters [[file:./figs/stewart_bottom_plate.png]] +** Compute Aa and Ab +We compute $[a_1, a_2, a_3, a_4, a_5, a_6]^T$ and $[b_1, b_2, b_3, b_4, b_5, b_6]^T$. + +#+begin_src matlab + Aa = zeros(6, 3); % [mm] + Ab = zeros(6, 3); % [mm] + Bb = zeros(6, 3); % [mm] +#+end_src + +#+begin_src matlab + for i = 1:3 + Aa(2*i-1,:) = [opts.R_bot*cos( pi/180*(120*(i-1) - opts.a_bot) ), ... + opts.R_bot*sin( pi/180*(120*(i-1) - opts.a_bot) ), ... + opts.H_plate+opts.H_joint]; + Aa(2*i,:) = [opts.R_bot*cos( pi/180*(120*(i-1) + opts.a_bot) ), ... + opts.R_bot*sin( pi/180*(120*(i-1) + opts.a_bot) ), ... + opts.H_plate+opts.H_joint]; + + Ab(2*i-1,:) = [opts.R_top*cos( pi/180*(120*(i-1) + opts.da_top - opts.a_top) ), ... + opts.R_top*sin( pi/180*(120*(i-1) + opts.da_top - opts.a_top) ), ... + opts.H_tot - opts.H_plate - opts.H_joint]; + Ab(2*i,:) = [opts.R_top*cos( pi/180*(120*(i-1) + opts.da_top + opts.a_top) ), ... + opts.R_top*sin( pi/180*(120*(i-1) + opts.da_top + opts.a_top) ), ... + opts.H_tot - opts.H_plate - opts.H_joint]; + end + + Bb = Ab - opts.H_tot*[0,0,1]; +#+end_src + +** Returns Stewart Structure +#+begin_src matlab :results none + stewart = struct(); + stewart.Aa = Aa; + stewart.Ab = Ab; + stewart.Bb = Bb; + stewart.H_tot = opts.H_tot; +end +#+end_src + +* computeGeometricalProperties + :PROPERTIES: + :HEADER-ARGS:matlab+: :exports code + :HEADER-ARGS:matlab+: :comments no + :HEADER-ARGS:matlab+: :eval no + :HEADER-ARGS:matlab+: :tangle src/computeGeometricalProperties.m + :END: + +** Function description +#+begin_src matlab + function [stewart] = computeGeometricalProperties(stewart, opts_param) +#+end_src + +** Optional Parameters +Default values for opts. +#+begin_src matlab + opts = struct(... + 'Jd_pos', [0, 0, 30], ... % Position of the Jacobian for displacement estimation from the top of the mobile platform [mm] + 'Jf_pos', [0, 0, 30] ... % Position of the Jacobian for force location from the top of the mobile platform [mm] + ); +#+end_src + +Populate opts with input parameters +#+begin_src matlab + if exist('opts_param','var') + for opt = fieldnames(opts_param)' + opts.(opt{1}) = opts_param.(opt{1}); + end + end +#+end_src + +** Rotation matrices +We initialize $l_i$ and $\hat{s}_i$ +#+begin_src matlab + leg_length = zeros(6, 1); % [mm] + leg_vectors = zeros(6, 3); +#+end_src + +We compute $b_i - a_i$, and then: +\begin{align*} + l_i &= \left|b_i - a_i\right| \\ + \hat{s}_i &= \frac{b_i - a_i}{l_i} +\end{align*} + +#+begin_src matlab + legs = stewart.Ab - stewart.Aa; + + for i = 1:6 + leg_length(i) = norm(legs(i,:)); + leg_vectors(i,:) = legs(i,:) / leg_length(i); + end +#+end_src + +We compute rotation matrices to have the orientation of the legs. +The rotation matrix transforms the $z$ axis to the axis of the leg. The other axis are not important here. +#+begin_src matlab + stewart.Rm = struct('R', eye(3)); + + for i = 1:6 + sx = cross(leg_vectors(i,:), [1 0 0]); + sx = sx/norm(sx); + + sy = -cross(sx, leg_vectors(i,:)); + sy = sy/norm(sy); + + sz = leg_vectors(i,:); + sz = sz/norm(sz); + + stewart.Rm(i).R = [sx', sy', sz']; + end +#+end_src + +** Jacobian matrices +Compute Jacobian Matrix +#+begin_src matlab + Jd = zeros(6); + + for i = 1:6 + Jd(i, 1:3) = leg_vectors(i, :); + Jd(i, 4:6) = cross(0.001*(stewart.Bb(i, :) - opts.Jd_pos), leg_vectors(i, :)); + end + + stewart.Jd = Jd; + stewart.Jd_inv = inv(Jd); +#+end_src + +#+begin_src matlab + Jf = zeros(6); + + for i = 1:6 + Jf(i, 1:3) = leg_vectors(i, :); + Jf(i, 4:6) = cross(0.001*(stewart.Bb(i, :) - opts.Jf_pos), leg_vectors(i, :)); + end + + stewart.Jf = Jf; + stewart.Jf_inv = inv(Jf); +#+end_src + +#+begin_src matlab + end +#+end_src + +* initializeMechanicalElements + :PROPERTIES: + :HEADER-ARGS:matlab+: :exports code + :HEADER-ARGS:matlab+: :comments no + :HEADER-ARGS:matlab+: :eval no + :HEADER-ARGS:matlab+: :tangle src/initializeMechanicalElements.m + :END: + +** Function description +#+begin_src matlab + function [stewart] = initializeMechanicalElements(stewart, opts_param) +#+end_src + +** Optional Parameters +Default values for opts. +#+begin_src matlab + opts = struct(... + 'thickness', 10, ... % Thickness of the base and platform [mm] + 'density', 1000, ... % Density of the material used for the hexapod [kg/m3] + 'k_ax', 1e8, ... % Stiffness of each actuator [N/m] + 'c_ax', 1000, ... % Damping of each actuator [N/(m/s)] + 'stroke', 50e-6 ... % Maximum stroke of each actuator [m] + ); +#+end_src + +Populate opts with input parameters +#+begin_src matlab + if exist('opts_param','var') + for opt = fieldnames(opts_param)' + opts.(opt{1}) = opts_param.(opt{1}); + end + end +#+end_src + +** Bottom Plate +#+name: fig:stewart_bottom_plate +#+caption: Schematic of the bottom plates with all the parameters +[[file:./figs/stewart_bottom_plate.png]] The bottom plate structure is initialized. #+begin_src matlab @@ -82,13 +294,7 @@ We defined its internal radius (if there is a hole in the bottom plate) and its We define its thickness. #+begin_src matlab - BP.H = 10; % Thickness of the Bottom Plate [mm] -#+end_src - -At which radius legs will be fixed and with that angle offset. -#+begin_src matlab - BP.Rleg = 100; % Radius where the legs articulations are positionned [mm] - BP.alpha = 10; % Angle Offset [deg] + BP.H = opts.thickness; % Thickness of the Bottom Plate [mm] #+end_src We defined the density of the material of the bottom plate. @@ -111,7 +317,7 @@ The structure is added to the stewart structure stewart.BP = BP; #+end_src -* Top Plate +** Top Plate The top plate structure is initialized. #+begin_src matlab TP = struct(); @@ -128,13 +334,6 @@ The thickness of the top plate. TP.H = 10; % [mm] #+end_src -At which radius and angle are fixed the legs. -#+begin_src matlab - TP.Rleg = 100; % Radius where the legs articulations are positionned [mm] - TP.alpha = 20; % Angle [deg] - TP.dalpha = 0; % Angle Offset from 0 position [deg] -#+end_src - The density of its material. #+begin_src matlab TP.density = opts.density; % Density of the material [kg/m3] @@ -155,12 +354,11 @@ The structure is added to the stewart structure stewart.TP = TP; #+end_src -* Legs +** Legs #+name: fig:stewart_legs #+caption: Schematic for the legs of the Stewart platform [[file:./figs/stewart_legs.png]] - The leg structure is initialized. #+begin_src matlab Leg = struct(); @@ -198,12 +396,29 @@ The radius of spheres representing the ball joints are defined. Leg.R = 1.3*Leg.Rbot; % Size of the sphere at the extremity of the leg [mm] #+end_src +We estimate the length of the legs. +#+begin_src matlab + legs = stewart.Ab - stewart.Aa; + Leg.lenght = norm(legs(1,:))/1.5; +#+end_src + +Then the shape of the bottom leg is estimated +#+begin_src matlab + Leg.shape.bot = ... + [0 0; ... + Leg.Rbot 0; ... + Leg.Rbot Leg.lenght; ... + Leg.Rtop Leg.lenght; ... + Leg.Rtop 0.2*Leg.lenght; ... + 0 0.2*Leg.lenght]; +#+end_src + The structure is added to the stewart structure #+begin_src matlab stewart.Leg = Leg; #+end_src -* Ball Joints +** Ball Joints #+name: fig:stewart_ball_joints #+caption: Schematic of the support for the ball joints [[file:./figs/stewart_ball_joints.png]] @@ -223,7 +438,7 @@ We can define its rotational stiffness and damping. For now, we use perfect join Its height is defined #+begin_src matlab - SP.H = 15; % [mm] + SP.H = stewart.Aa(1, 3) - BP.H; % [mm] #+end_src Its radius is based on the radius on the sphere at the end of the legs. @@ -253,251 +468,46 @@ The structure is added to the Hexapod structure stewart.SP = SP; #+end_src -* More parameters are initialized -#+begin_src matlab - stewart = initializeParameters(stewart); -#+end_src - -* Save the Stewart Structure -#+begin_src matlab - save('./mat/stewart.mat', 'stewart') -#+end_src - -* initializeParameters Function :noexport: - :PROPERTIES: - :HEADER-ARGS:matlab+: :tangle no - :END: -#+begin_src matlab - function [stewart] = initializeParameters(stewart) -#+end_src - -Computation of the position of the connection points on the base and moving platform -We first initialize =pos_base= corresponding to $[a_1, a_2, a_3, a_4, a_5, a_6]^T$ and =pos_top= corresponding to $[b_1, b_2, b_3, b_4, b_5, b_6]^T$. -#+begin_src matlab - stewart.pos_base = zeros(6, 3); - stewart.pos_top = zeros(6, 3); -#+end_src - -We estimate the height between the ball joints of the bottom platform and of the top platform. -#+begin_src matlab - height = stewart.H - stewart.BP.H - stewart.TP.H - 2*stewart.SP.H; % [mm] -#+end_src - -#+begin_src matlab - for i = 1:3 - % base points - angle_m_b = 120*(i-1) - stewart.BP.alpha; - angle_p_b = 120*(i-1) + stewart.BP.alpha; - - stewart.pos_base(2*i-1,:) = [stewart.BP.Rleg*cos(angle_m_b), stewart.BP.Rleg*sin(angle_m_b), 0.0]; - stewart.pos_base(2*i,:) = [stewart.BP.Rleg*cos(angle_p_b), stewart.BP.Rleg*sin(angle_p_b), 0.0]; - - % top points - angle_m_t = 120*(i-1) - stewart.TP.alpha + stewart.TP.dalpha; - angle_p_t = 120*(i-1) + stewart.TP.alpha + stewart.TP.dalpha; - - stewart.pos_top(2*i-1,:) = [stewart.TP.Rleg*cos(angle_m_t), stewart.TP.Rleg*sin(angle_m_t), height]; - stewart.pos_top(2*i,:) = [stewart.TP.Rleg*cos(angle_p_t), stewart.TP.Rleg*sin(angle_p_t), height]; - end - - % permute pos_top points so that legs are end points of base and top points - stewart.pos_top = [stewart.pos_top(6,:); stewart.pos_top(1:5,:)]; %6th point on top connects to 1st on bottom - stewart.pos_top_tranform = stewart.pos_top - height*[zeros(6, 2),ones(6, 1)]; -#+end_src - -leg vectors -#+begin_src matlab - legs = stewart.pos_top - stewart.pos_base; - leg_length = zeros(6, 1); - leg_vectors = zeros(6, 3); - for i = 1:6 - leg_length(i) = norm(legs(i,:)); - leg_vectors(i,:) = legs(i,:) / leg_length(i); - end - - stewart.Leg.lenght = 1000*leg_length(1)/1.5; - stewart.Leg.shape.bot = [0 0; ... - stewart.Leg.rad.bottom 0; ... - stewart.Leg.rad.bottom stewart.Leg.lenght; ... - stewart.Leg.rad.top stewart.Leg.lenght; ... - stewart.Leg.rad.top 0.2*stewart.Leg.lenght; ... - 0 0.2*stewart.Leg.lenght]; -#+end_src - -Calculate revolute and cylindrical axes -#+begin_src matlab - rev1 = zeros(6, 3); - rev2 = zeros(6, 3); - cyl1 = zeros(6, 3); - for i = 1:6 - rev1(i,:) = cross(leg_vectors(i,:), [0 0 1]); - rev1(i,:) = rev1(i,:) / norm(rev1(i,:)); - - rev2(i,:) = - cross(rev1(i,:), leg_vectors(i,:)); - rev2(i,:) = rev2(i,:) / norm(rev2(i,:)); - - cyl1(i,:) = leg_vectors(i,:); - end -#+end_src - -Coordinate systems -#+begin_src matlab - stewart.lower_leg = struct('rotation', eye(3)); - stewart.upper_leg = struct('rotation', eye(3)); - - for i = 1:6 - stewart.lower_leg(i).rotation = [rev1(i,:)', rev2(i,:)', cyl1(i,:)']; - stewart.upper_leg(i).rotation = [rev1(i,:)', rev2(i,:)', cyl1(i,:)']; - end -#+end_src - -Position Matrix -#+begin_src matlab - stewart.M_pos_base = stewart.pos_base + (height+(stewart.TP.h+stewart.Leg.sphere.top+stewart.SP.h.top+stewart.jacobian)*1e-3)*[zeros(6, 2),ones(6, 1)]; -#+end_src - -Compute Jacobian Matrix -#+begin_src matlab - % aa = stewart.pos_top_tranform + (stewart.jacobian - stewart.TP.h - stewart.SP.height.top)*1e-3*[zeros(6, 2),ones(6, 1)]; - bb = stewart.pos_top_tranform - (stewart.TP.h + stewart.SP.height.top)*1e-3*[zeros(6, 2),ones(6, 1)]; - bb = bb - stewart.jacobian*1e-3*[zeros(6, 2),ones(6, 1)]; - stewart.J = getJacobianMatrix(leg_vectors', bb'); - - stewart.K = stewart.Leg.k.ax*stewart.J'*stewart.J; - end -#+end_src - -* initializeParameters Function -#+begin_src matlab - function [stewart] = initializeParameters(stewart) -#+end_src - -We first compute $[a_1, a_2, a_3, a_4, a_5, a_6]^T$ and $[b_1, b_2, b_3, b_4, b_5, b_6]^T$. -#+begin_src matlab - stewart.Aa = zeros(6, 3); % [mm] - stewart.Ab = zeros(6, 3); % [mm] - stewart.Bb = zeros(6, 3); % [mm] -#+end_src - -#+begin_src matlab - for i = 1:3 - stewart.Aa(2*i-1,:) = [stewart.BP.Rleg*cos( pi/180*(120*(i-1) - stewart.BP.alpha) ), ... - stewart.BP.Rleg*sin( pi/180*(120*(i-1) - stewart.BP.alpha) ), ... - stewart.BP.H+stewart.SP.H]; - stewart.Aa(2*i,:) = [stewart.BP.Rleg*cos( pi/180*(120*(i-1) + stewart.BP.alpha) ), ... - stewart.BP.Rleg*sin( pi/180*(120*(i-1) + stewart.BP.alpha) ), ... - stewart.BP.H+stewart.SP.H]; - - stewart.Ab(2*i-1,:) = [stewart.TP.Rleg*cos( pi/180*(120*(i-1) + stewart.TP.dalpha - stewart.TP.alpha) ), ... - stewart.TP.Rleg*sin( pi/180*(120*(i-1) + stewart.TP.dalpha - stewart.TP.alpha) ), ... - stewart.H - stewart.TP.H - stewart.SP.H]; - stewart.Ab(2*i,:) = [stewart.TP.Rleg*cos( pi/180*(120*(i-1) + stewart.TP.dalpha + stewart.TP.alpha) ), ... - stewart.TP.Rleg*sin( pi/180*(120*(i-1) + stewart.TP.dalpha + stewart.TP.alpha) ), ... - stewart.H - stewart.TP.H - stewart.SP.H]; - end - stewart.Bb = stewart.Ab - stewart.H*[0,0,1]; -#+end_src - -Now, we compute the leg vectors $\hat{s}_i$ and leg position $l_i$: -\[ b_i - a_i = l_i \hat{s}_i \] - -We initialize $l_i$ and $\hat{s}_i$ -#+begin_src matlab - leg_length = zeros(6, 1); % [mm] - leg_vectors = zeros(6, 3); -#+end_src - -We compute $b_i - a_i$, and then: -\begin{align*} - l_i &= \left|b_i - a_i\right| \\ - \hat{s}_i &= \frac{b_i - a_i}{l_i} -\end{align*} - -#+begin_src matlab - legs = stewart.Ab - stewart.Aa; - - for i = 1:6 - leg_length(i) = norm(legs(i,:)); - leg_vectors(i,:) = legs(i,:) / leg_length(i); - end -#+end_src - -Then the shape of the bottom leg is estimated -#+begin_src matlab - stewart.Leg.lenght = leg_length(1)/1.5; - stewart.Leg.shape.bot = ... - [0 0; ... - stewart.Leg.Rbot 0; ... - stewart.Leg.Rbot stewart.Leg.lenght; ... - stewart.Leg.Rtop stewart.Leg.lenght; ... - stewart.Leg.Rtop 0.2*stewart.Leg.lenght; ... - 0 0.2*stewart.Leg.lenght]; -#+end_src - -We compute rotation matrices to have the orientation of the legs. -The rotation matrix transforms the $z$ axis to the axis of the leg. The other axis are not important here. -#+begin_src matlab - stewart.Rm = struct('R', eye(3)); - - for i = 1:6 - sx = cross(leg_vectors(i,:), [1 0 0]); - sx = sx/norm(sx); - - sy = -cross(sx, leg_vectors(i,:)); - sy = sy/norm(sy); - - sz = leg_vectors(i,:); - sz = sz/norm(sz); - - stewart.Rm(i).R = [sx', sy', sz']; - end -#+end_src - -Compute Jacobian Matrix -#+begin_src matlab - J = zeros(6); - - for i = 1:6 - J(i, 1:3) = leg_vectors(i, :); - J(i, 4:6) = cross(0.001*(stewart.Ab(i, :)- stewart.H*[0,0,1]), leg_vectors(i, :)); - end - - stewart.J = J; - stewart.Jinv = inv(J); -#+end_src - -#+begin_src matlab - stewart.K = stewart.Leg.k_ax*stewart.J'*stewart.J; -#+end_src - -#+begin_src matlab - end - end -#+end_src * initializeSample :PROPERTIES: + :HEADER-ARGS:matlab+: :exports code + :HEADER-ARGS:matlab+: :comments no + :HEADER-ARGS:matlab+: :eval no :HEADER-ARGS:matlab+: :tangle src/initializeSample.m :END: + +** Function description #+begin_src matlab function [] = initializeSample(opts_param) - %% Default values for opts - sample = struct( ... - 'radius', 100, ... % radius of the cylinder [mm] - 'height', 100, ... % height of the cylinder [mm] - 'mass', 10, ... % mass of the cylinder [kg] - 'measheight', 50, ... % measurement point z-offset [mm] - 'offset', [0, 0, 0], ... % offset position of the sample [mm] - 'color', [0.9 0.1 0.1] ... - ); +#+end_src - %% Populate opts with input parameters - if exist('opts_param','var') - for opt = fieldnames(opts_param)' - sample.(opt{1}) = opts_param.(opt{1}); - end +** Optional Parameters +Default values for opts. +#+begin_src matlab + sample = struct( ... + 'radius', 100, ... % radius of the cylinder [mm] + 'height', 100, ... % height of the cylinder [mm] + 'mass', 10, ... % mass of the cylinder [kg] + 'measheight', 50, ... % measurement point z-offset [mm] + 'offset', [0, 0, 0], ... % offset position of the sample [mm] + 'color', [0.9 0.1 0.1] ... + ); +#+end_src + +Populate opts with input parameters +#+begin_src matlab + if exist('opts_param','var') + for opt = fieldnames(opts_param)' + sample.(opt{1}) = opts_param.(opt{1}); end - - %% Save - save('./mat/sample.mat', 'sample'); + end +#+end_src + +** Save the Sample structure +#+begin_src matlab + save('./mat/sample.mat', 'sample'); +#+end_src + +#+begin_src matlab end #+end_src diff --git a/src/computeGeometricalProperties.m b/src/computeGeometricalProperties.m new file mode 100644 index 0000000..8278cb2 --- /dev/null +++ b/src/computeGeometricalProperties.m @@ -0,0 +1,59 @@ +function [stewart] = computeGeometricalProperties(stewart, opts_param) + +opts = struct(... + 'Jd_pos', [0, 0, 30], ... % Position of the Jacobian for displacement estimation from the top of the mobile platform [mm] + 'Jf_pos', [0, 0, 30] ... % Position of the Jacobian for force location from the top of the mobile platform [mm] + ); + +if exist('opts_param','var') + for opt = fieldnames(opts_param)' + opts.(opt{1}) = opts_param.(opt{1}); + end +end + +leg_length = zeros(6, 1); % [mm] +leg_vectors = zeros(6, 3); + +legs = stewart.Ab - stewart.Aa; + +for i = 1:6 + leg_length(i) = norm(legs(i,:)); + leg_vectors(i,:) = legs(i,:) / leg_length(i); +end + +stewart.Rm = struct('R', eye(3)); + +for i = 1:6 + sx = cross(leg_vectors(i,:), [1 0 0]); + sx = sx/norm(sx); + + sy = -cross(sx, leg_vectors(i,:)); + sy = sy/norm(sy); + + sz = leg_vectors(i,:); + sz = sz/norm(sz); + + stewart.Rm(i).R = [sx', sy', sz']; +end + +Jd = zeros(6); + +for i = 1:6 + Jd(i, 1:3) = leg_vectors(i, :); + Jd(i, 4:6) = cross(0.001*(stewart.Bb(i, :) - opts.Jd_pos), leg_vectors(i, :)); +end + +stewart.Jd = Jd; +stewart.Jd_inv = inv(Jd); + +Jf = zeros(6); + +for i = 1:6 + Jf(i, 1:3) = leg_vectors(i, :); + Jf(i, 4:6) = cross(0.001*(stewart.Bb(i, :) - opts.Jf_pos), leg_vectors(i, :)); +end + +stewart.Jf = Jf; +stewart.Jf_inv = inv(Jf); + +end diff --git a/src/identifyPlant.m b/src/identifyPlant.m index 929a3fd..868b2a8 100644 --- a/src/identifyPlant.m +++ b/src/identifyPlant.m @@ -53,7 +53,7 @@ G.OutputName = {'Dxm', 'Dym', 'Dzm', 'Rxm', 'Rym', 'Rzm', ... % identifyPlant:7 ends here % [[file:~/MEGA/These/Matlab/Simscape/stewart-simscape/identification.org::*identifyPlant][identifyPlant:8]] -sys.G_cart = minreal(G({'Dxm', 'Dym', 'Dzm', 'Rxm', 'Rym', 'Rzm'}, {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'})); +sys.G_cart = G({'Dxm', 'Dym', 'Dzm', 'Rxm', 'Rym', 'Rzm'}, {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'}); sys.G_forc = minreal(G({'F1m', 'F2m', 'F3m', 'F4m', 'F5m', 'F6m'}, {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'})); sys.G_legs = minreal(G({'D1m', 'D2m', 'D3m', 'D4m', 'D5m', 'D6m'}, {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'})); sys.G_tran = minreal(G({'Dxtm', 'Dytm', 'Dztm', 'Rxtm', 'Rytm', 'Rztm'}, {'Dwx', 'Dwy', 'Dwz', 'Rwx', 'Rwy', 'Rwz'})); diff --git a/src/initializeCubicConfiguration.m b/src/initializeCubicConfiguration.m new file mode 100644 index 0000000..6817217 --- /dev/null +++ b/src/initializeCubicConfiguration.m @@ -0,0 +1,89 @@ +function [stewart] = initializeCubicConfiguration(opts_param) + +opts = struct(... + 'H_tot', 90, ... % Total height of the Hexapod [mm] + 'L', 110, ... % Size of the Cube [mm] + 'H', 40, ... % Height between base joints and platform joints [mm] + 'H0', 75 ... % Height between the corner of the cube and the plane containing the base joints [mm] + ); + +if exist('opts_param','var') + for opt = fieldnames(opts_param)' + opts.(opt{1}) = opts_param.(opt{1}); + end +end + +points = [0, 0, 0; ... + 0, 0, 1; ... + 0, 1, 0; ... + 0, 1, 1; ... + 1, 0, 0; ... + 1, 0, 1; ... + 1, 1, 0; ... + 1, 1, 1]; +points = opts.L*points; + +sx = cross([1, 1, 1], [1 0 0]); +sx = sx/norm(sx); + +sy = -cross(sx, [1, 1, 1]); +sy = sy/norm(sy); + +sz = [1, 1, 1]; +sz = sz/norm(sz); + +R = [sx', sy', sz']'; + +cube = zeros(size(points)); +for i = 1:size(points, 1) + cube(i, :) = R * points(i, :)'; +end + +leg_indices = [3, 4; ... + 2, 4; ... + 2, 6; ... + 5, 6; ... + 5, 7; ... + 3, 7]; + +legs = zeros(6, 3); +legs_start = zeros(6, 3); + +for i = 1:6 + legs(i, :) = cube(leg_indices(i, 2), :) - cube(leg_indices(i, 1), :); + legs_start(i, :) = cube(leg_indices(i, 1), :); +end + +Hmax = cube(4, 3) - cube(2, 3); +if opts.H0 < cube(2, 3) + error(sprintf('H0 is not high enought. Minimum H0 = %.1f', cube(2, 3))); +else if opts.H0 + opts.H > cube(4, 3) + error(sprintf('H0+H is too high. Maximum H0+H = %.1f', cube(4, 3))); + error('H0+H is too high'); +end + +Aa = zeros(6, 3); +for i = 1:6 + t = (opts.H0-legs_start(i, 3))/(legs(i, 3)); + Aa(i, :) = legs_start(i, :) + t*legs(i, :); +end + +Ab = zeros(6, 3); +for i = 1:6 + t = (opts.H0+opts.H-legs_start(i, 3))/(legs(i, 3)); + Ab(i, :) = legs_start(i, :) + t*legs(i, :); +end + +Bb = zeros(6, 3); +Bb = Ab - (opts.H0 + opts.H_tot/2 + opts.H/2)*[0, 0, 1]; + +h = opts.H0 + opts.H/2 - opts.H_tot/2; +Aa = Aa - h*[0, 0, 1]; +Ab = Ab - h*[0, 0, 1]; + +stewart = struct(); + stewart.Aa = Aa; + stewart.Ab = Ab; + stewart.Bb = Bb; + stewart.H_tot = opts.H_tot; +end diff --git a/src/initializeGeneralConfiguration.m b/src/initializeGeneralConfiguration.m new file mode 100644 index 0000000..05ec300 --- /dev/null +++ b/src/initializeGeneralConfiguration.m @@ -0,0 +1,47 @@ +function [stewart] = initializeGeneralConfiguration(opts_param) + +opts = struct(... + 'H_tot', 90, ... % Height of the platform [mm] + 'H_joint', 15, ... % Height of the joints [mm] + 'H_plate', 10, ... % Thickness of the fixed and mobile platforms [mm] + 'R_bot', 100, ... % Radius where the legs articulations are positionned [mm] + 'R_top', 80, ... % Radius where the legs articulations are positionned [mm] + 'a_bot', 10, ... % Angle Offset [deg] + 'a_top', 40, ... % Angle Offset [deg] + 'da_top', 0 ... % Angle Offset from 0 position [deg] + ); + +if exist('opts_param','var') + for opt = fieldnames(opts_param)' + opts.(opt{1}) = opts_param.(opt{1}); + end +end + +Aa = zeros(6, 3); % [mm] +Ab = zeros(6, 3); % [mm] +Bb = zeros(6, 3); % [mm] + +for i = 1:3 + Aa(2*i-1,:) = [opts.R_bot*cos( pi/180*(120*(i-1) - opts.a_bot) ), ... + opts.R_bot*sin( pi/180*(120*(i-1) - opts.a_bot) ), ... + opts.H_plate+opts.H_joint]; + Aa(2*i,:) = [opts.R_bot*cos( pi/180*(120*(i-1) + opts.a_bot) ), ... + opts.R_bot*sin( pi/180*(120*(i-1) + opts.a_bot) ), ... + opts.H_plate+opts.H_joint]; + + Ab(2*i-1,:) = [opts.R_top*cos( pi/180*(120*(i-1) + opts.da_top - opts.a_top) ), ... + opts.R_top*sin( pi/180*(120*(i-1) + opts.da_top - opts.a_top) ), ... + opts.H_tot - opts.H_plate - opts.H_joint]; + Ab(2*i,:) = [opts.R_top*cos( pi/180*(120*(i-1) + opts.da_top + opts.a_top) ), ... + opts.R_top*sin( pi/180*(120*(i-1) + opts.da_top + opts.a_top) ), ... + opts.H_tot - opts.H_plate - opts.H_joint]; +end + +Bb = Ab - opts.H_tot*[0,0,1]; + +stewart = struct(); + stewart.Aa = Aa; + stewart.Ab = Ab; + stewart.Bb = Bb; + stewart.H_tot = opts.H_tot; +end diff --git a/src/initializeHexapod.m b/src/initializeHexapod.m index 21cfd3f..d7517da 100644 --- a/src/initializeHexapod.m +++ b/src/initializeHexapod.m @@ -1,228 +1,86 @@ -% Function description and arguments -% The =initializeHexapod= function takes one structure that contains configurations for the hexapod and returns one structure representing the hexapod. - function [stewart] = initializeHexapod(opts_param) - - -% Default values for opts. - opts = struct(... 'height', 90, ... % Height of the platform [mm] - 'density', 8000, ... % Density of the material used for the hexapod [kg/m3] + 'density', 10, ... % Density of the material used for the hexapod [kg/m3] 'k_ax', 1e8, ... % Stiffness of each actuator [N/m] 'c_ax', 1000, ... % Damping of each actuator [N/(m/s)] 'stroke', 50e-6, ... % Maximum stroke of each actuator [m] 'name', 'stewart' ... % Name of the file ); - - -% Populate opts with input parameters - if exist('opts_param','var') for opt = fieldnames(opts_param)' opts.(opt{1}) = opts_param.(opt{1}); end end -% Initialization of the stewart structure -% We initialize the Stewart structure - stewart = struct(); - - -% And we defined its total height. - stewart.H = opts.height; % [mm] -% Bottom Plate -% #+name: fig:stewart_bottom_plate -% #+caption: Schematic of the bottom plates with all the parameters -% [[file:./figs/stewart_bottom_plate.png]] - - -% The bottom plate structure is initialized. - BP = struct(); - - -% We defined its internal radius (if there is a hole in the bottom plate) and its outer radius. - BP.Rint = 0; % Internal Radius [mm] BP.Rext = 150; % External Radius [mm] - - -% We define its thickness. - BP.H = 10; % Thickness of the Bottom Plate [mm] - - -% At which radius legs will be fixed and with that angle offset. - BP.Rleg = 100; % Radius where the legs articulations are positionned [mm] -BP.alpha = 10; % Angle Offset [deg] - - - -% We defined the density of the material of the bottom plate. +BP.alpha = 30; % Angle Offset [deg] BP.density = opts.density; % Density of the material [kg/m3] - - -% And its color. - BP.color = [0.7 0.7 0.7]; % Color [RGB] - - -% Then the profile of the bottom plate is computed and will be used by Simscape - BP.shape = [BP.Rint BP.H; BP.Rint 0; BP.Rext 0; BP.Rext BP.H]; % [mm] - - -% The structure is added to the stewart structure - stewart.BP = BP; -% Top Plate -% The top plate structure is initialized. - TP = struct(); - - -% We defined the internal and external radius of the top plate. - TP.Rint = 0; % [mm] TP.Rext = 100; % [mm] - - -% The thickness of the top plate. - TP.H = 10; % [mm] - - -% At which radius and angle are fixed the legs. - -TP.Rleg = 100; % Radius where the legs articulations are positionned [mm] -TP.alpha = 20; % Angle [deg] +TP.Rleg = 80; % Radius where the legs articulations are positionned [mm] +TP.alpha = 10; % Angle [deg] TP.dalpha = 0; % Angle Offset from 0 position [deg] - - -% The density of its material. - TP.density = opts.density; % Density of the material [kg/m3] - - -% Its color. - TP.color = [0.7 0.7 0.7]; % Color [RGB] - - -% Then the shape of the top plate is computed - TP.shape = [TP.Rint TP.H; TP.Rint 0; TP.Rext 0; TP.Rext TP.H]; - - -% The structure is added to the stewart structure - stewart.TP = TP; -% Legs -% #+name: fig:stewart_legs -% #+caption: Schematic for the legs of the Stewart platform -% [[file:./figs/stewart_legs.png]] - - -% The leg structure is initialized. - Leg = struct(); - - -% The maximum Stroke of each leg is defined. - Leg.stroke = opts.stroke; % [m] - - -% The stiffness and damping of each leg are defined - Leg.k_ax = opts.k_ax; % Stiffness of each leg [N/m] Leg.c_ax = opts.c_ax; % Damping of each leg [N/(m/s)] - - -% The radius of the legs are defined - Leg.Rtop = 10; % Radius of the cylinder of the top part of the leg[mm] Leg.Rbot = 12; % Radius of the cylinder of the bottom part of the leg [mm] - - -% The density of its material. - -Leg.density = opts.density; % Density of the material used for the legs [kg/m3] - - - -% Its color. +Leg.density = 0.01*opts.density; % Density of the material used for the legs [kg/m3] Leg.color = [0.5 0.5 0.5]; % Color of the top part of the leg [RGB] - - -% The radius of spheres representing the ball joints are defined. - Leg.R = 1.3*Leg.Rbot; % Size of the sphere at the extremity of the leg [mm] - - -% The structure is added to the stewart structure - stewart.Leg = Leg; -% Ball Joints -% #+name: fig:stewart_ball_joints -% #+caption: Schematic of the support for the ball joints -% [[file:./figs/stewart_ball_joints.png]] - -% =SP= is the structure representing the support for the ball joints at the extremity of each leg. - -% The =SP= structure is initialized. - SP = struct(); - - -% We can define its rotational stiffness and damping. For now, we use perfect joints. - SP.k = 0; % [N*m/deg] SP.c = 0; % [N*m/deg] - - -% Its height is defined - SP.H = 15; % [mm] - - -% Its radius is based on the radius on the sphere at the end of the legs. - SP.R = Leg.R; % [mm] SP.section = [0 SP.H-SP.R; @@ -230,40 +88,18 @@ SP.section = [0 SP.H-SP.R; SP.R 0; SP.R SP.H]; - - -% The density of its material is defined. - SP.density = opts.density; % [kg/m^3] - - -% Its color is defined. - SP.color = [0.7 0.7 0.7]; % [RGB] - - -% The structure is added to the Hexapod structure - stewart.SP = SP; -% More parameters are initialized - stewart = initializeParameters(stewart); -% Save the Stewart Structure - save('./mat/stewart.mat', 'stewart') -% initializeParameters Function - function [stewart] = initializeParameters(stewart) - - -% We first compute $[a_1, a_2, a_3, a_4, a_5, a_6]^T$ and $[b_1, b_2, b_3, b_4, b_5, b_6]^T$. - stewart.Aa = zeros(6, 3); % [mm] stewart.Ab = zeros(6, 3); % [mm] stewart.Bb = zeros(6, 3); % [mm] @@ -285,25 +121,9 @@ for i = 1:3 end stewart.Bb = stewart.Ab - stewart.H*[0,0,1]; - - -% Now, we compute the leg vectors $\hat{s}_i$ and leg position $l_i$: -% \[ b_i - a_i = l_i \hat{s}_i \] - -% We initialize $l_i$ and $\hat{s}_i$ - leg_length = zeros(6, 1); % [mm] leg_vectors = zeros(6, 3); - - -% We compute $b_i - a_i$, and then: -% \begin{align*} -% l_i &= \left|b_i - a_i\right| \\ -% \hat{s}_i &= \frac{b_i - a_i}{l_i} -% \end{align*} - - legs = stewart.Ab - stewart.Aa; for i = 1:6 @@ -311,10 +131,6 @@ for i = 1:6 leg_vectors(i,:) = legs(i,:) / leg_length(i); end - - -% Then the shape of the bottom leg is estimated - stewart.Leg.lenght = leg_length(1)/1.5; stewart.Leg.shape.bot = ... [0 0; ... @@ -324,11 +140,6 @@ stewart.Leg.shape.bot = ... stewart.Leg.Rtop 0.2*stewart.Leg.lenght; ... 0 0.2*stewart.Leg.lenght]; - - -% We compute rotation matrices to have the orientation of the legs. -% The rotation matrix transforms the $z$ axis to the axis of the leg. The other axis are not important here. - stewart.Rm = struct('R', eye(3)); for i = 1:6 @@ -344,10 +155,6 @@ for i = 1:6 stewart.Rm(i).R = [sx', sy', sz']; end - - -% Compute Jacobian Matrix - J = zeros(6); for i = 1:6 diff --git a/src/initializeMechanicalElements.m b/src/initializeMechanicalElements.m new file mode 100644 index 0000000..1ec9077 --- /dev/null +++ b/src/initializeMechanicalElements.m @@ -0,0 +1,94 @@ +function [stewart] = initializeMechanicalElements(stewart, opts_param) + +opts = struct(... + 'thickness', 10, ... % Thickness of the base and platform [mm] + 'density', 1000, ... % Density of the material used for the hexapod [kg/m3] + 'k_ax', 1e8, ... % Stiffness of each actuator [N/m] + 'c_ax', 1000, ... % Damping of each actuator [N/(m/s)] + 'stroke', 50e-6 ... % Maximum stroke of each actuator [m] + ); + +if exist('opts_param','var') + for opt = fieldnames(opts_param)' + opts.(opt{1}) = opts_param.(opt{1}); + end +end + +BP = struct(); + +BP.Rint = 0; % Internal Radius [mm] +BP.Rext = 150; % External Radius [mm] + +BP.H = opts.thickness; % Thickness of the Bottom Plate [mm] + +BP.density = opts.density; % Density of the material [kg/m3] + +BP.color = [0.7 0.7 0.7]; % Color [RGB] + +BP.shape = [BP.Rint BP.H; BP.Rint 0; BP.Rext 0; BP.Rext BP.H]; % [mm] + +stewart.BP = BP; + +TP = struct(); + +TP.Rint = 0; % [mm] +TP.Rext = 100; % [mm] + +TP.H = 10; % [mm] + +TP.density = opts.density; % Density of the material [kg/m3] + +TP.color = [0.7 0.7 0.7]; % Color [RGB] + +TP.shape = [TP.Rint TP.H; TP.Rint 0; TP.Rext 0; TP.Rext TP.H]; + +stewart.TP = TP; + +Leg = struct(); + +Leg.stroke = opts.stroke; % [m] + +Leg.k_ax = opts.k_ax; % Stiffness of each leg [N/m] +Leg.c_ax = opts.c_ax; % Damping of each leg [N/(m/s)] + +Leg.Rtop = 10; % Radius of the cylinder of the top part of the leg[mm] +Leg.Rbot = 12; % Radius of the cylinder of the bottom part of the leg [mm] + +Leg.density = opts.density; % Density of the material used for the legs [kg/m3] + +Leg.color = [0.5 0.5 0.5]; % Color of the top part of the leg [RGB] + +Leg.R = 1.3*Leg.Rbot; % Size of the sphere at the extremity of the leg [mm] + +legs = stewart.Ab - stewart.Aa; +Leg.lenght = norm(legs(1,:))/1.5; + +Leg.shape.bot = ... + [0 0; ... + Leg.Rbot 0; ... + Leg.Rbot Leg.lenght; ... + Leg.Rtop Leg.lenght; ... + Leg.Rtop 0.2*Leg.lenght; ... + 0 0.2*Leg.lenght]; + +stewart.Leg = Leg; + +SP = struct(); + +SP.k = 0; % [N*m/deg] +SP.c = 0; % [N*m/deg] + +SP.H = stewart.Aa(1, 3) - BP.H; % [mm] + +SP.R = Leg.R; % [mm] + +SP.section = [0 SP.H-SP.R; + 0 0; + SP.R 0; + SP.R SP.H]; + +SP.density = opts.density; % [kg/m^3] + +SP.color = [0.7 0.7 0.7]; % [RGB] + +stewart.SP = SP; diff --git a/src/initializeSample.m b/src/initializeSample.m index 2c5c848..1ae05e8 100644 --- a/src/initializeSample.m +++ b/src/initializeSample.m @@ -1,21 +1,20 @@ function [] = initializeSample(opts_param) -%% Default values for opts - sample = struct( ... - 'radius', 100, ... % radius of the cylinder [mm] - 'height', 100, ... % height of the cylinder [mm] - 'mass', 10, ... % mass of the cylinder [kg] - 'measheight', 50, ... % measurement point z-offset [mm] - 'offset', [0, 0, 0], ... % offset position of the sample [mm] - 'color', [0.9 0.1 0.1] ... - ); - %% Populate opts with input parameters - if exist('opts_param','var') - for opt = fieldnames(opts_param)' - sample.(opt{1}) = opts_param.(opt{1}); - end +sample = struct( ... + 'radius', 100, ... % radius of the cylinder [mm] + 'height', 100, ... % height of the cylinder [mm] + 'mass', 10, ... % mass of the cylinder [kg] + 'measheight', 50, ... % measurement point z-offset [mm] + 'offset', [0, 0, 0], ... % offset position of the sample [mm] + 'color', [0.9 0.1 0.1] ... + ); + +if exist('opts_param','var') + for opt = fieldnames(opts_param)' + sample.(opt{1}) = opts_param.(opt{1}); end - - %% Save - save('./mat/sample.mat', 'sample'); +end + +save('./mat/sample.mat', 'sample'); + end diff --git a/src/initializeSimscapeData.m b/src/initializeSimscapeData.m new file mode 100644 index 0000000..ff0bfa5 --- /dev/null +++ b/src/initializeSimscapeData.m @@ -0,0 +1,59 @@ +function [stewart] = initializeSimscapeData(stewart, opts_param) + +opts = struct(... + 'Jd_pos', [0, 0, 30], ... % Position of the Jacobian for displacement estimation from the top of the mobile platform [mm] + 'Jf_pos', [0, 0, 30] ... % Position of the Jacobian for force location from the top of the mobile platform [mm] + ); + +if exist('opts_param','var') + for opt = fieldnames(opts_param)' + opts.(opt{1}) = opts_param.(opt{1}); + end +end + +leg_length = zeros(6, 1); % [mm] +leg_vectors = zeros(6, 3); + +legs = stewart.Ab - stewart.Aa; + +for i = 1:6 + leg_length(i) = norm(legs(i,:)); + leg_vectors(i,:) = legs(i,:) / leg_length(i); +end + +stewart.Rm = struct('R', eye(3)); + +for i = 1:6 + sx = cross(leg_vectors(i,:), [1 0 0]); + sx = sx/norm(sx); + + sy = -cross(sx, leg_vectors(i,:)); + sy = sy/norm(sy); + + sz = leg_vectors(i,:); + sz = sz/norm(sz); + + stewart.Rm(i).R = [sx', sy', sz']; +end + +Jd = zeros(6); + +for i = 1:6 + Jd(i, 1:3) = leg_vectors(i, :); + Jd(i, 4:6) = cross(0.001*(stewart.Bb(i, :) - opts.Jd_pos), leg_vectors(i, :)); +end + +stewart.Jd = Jd; +stewart.Jd_inv = inv(Jd); + +Jf = zeros(6); + +for i = 1:6 + Jf(i, 1:3) = leg_vectors(i, :); + Jf(i, 4:6) = cross(0.001*(stewart.Bb(i, :) - opts.Jf_pos), leg_vectors(i, :)); +end + +stewart.Jf = Jf; +stewart.Jf_inv = inv(Jf); + +end diff --git a/src/initializeStewartPlatform.m b/src/initializeStewartPlatform.m new file mode 100644 index 0000000..0d48c10 --- /dev/null +++ b/src/initializeStewartPlatform.m @@ -0,0 +1,94 @@ +function [stewart] = initializeStewartPlatform(stewart, opts_param) + +opts = struct(... + 'thickness', 10, ... % Thickness of the base and platform [mm] + 'density', 1000, ... % Density of the material used for the hexapod [kg/m3] + 'k_ax', 1e8, ... % Stiffness of each actuator [N/m] + 'c_ax', 1000, ... % Damping of each actuator [N/(m/s)] + 'stroke', 50e-6 ... % Maximum stroke of each actuator [m] + ); + +if exist('opts_param','var') + for opt = fieldnames(opts_param)' + opts.(opt{1}) = opts_param.(opt{1}); + end +end + +BP = struct(); + +BP.Rint = 0; % Internal Radius [mm] +BP.Rext = 150; % External Radius [mm] + +BP.H = opts.thickness; % Thickness of the Bottom Plate [mm] + +BP.density = opts.density; % Density of the material [kg/m3] + +BP.color = [0.7 0.7 0.7]; % Color [RGB] + +BP.shape = [BP.Rint BP.H; BP.Rint 0; BP.Rext 0; BP.Rext BP.H]; % [mm] + +stewart.BP = BP; + +TP = struct(); + +TP.Rint = 0; % [mm] +TP.Rext = 100; % [mm] + +TP.H = 10; % [mm] + +TP.density = opts.density; % Density of the material [kg/m3] + +TP.color = [0.7 0.7 0.7]; % Color [RGB] + +TP.shape = [TP.Rint TP.H; TP.Rint 0; TP.Rext 0; TP.Rext TP.H]; + +stewart.TP = TP; + +Leg = struct(); + +Leg.stroke = opts.stroke; % [m] + +Leg.k_ax = opts.k_ax; % Stiffness of each leg [N/m] +Leg.c_ax = opts.c_ax; % Damping of each leg [N/(m/s)] + +Leg.Rtop = 10; % Radius of the cylinder of the top part of the leg[mm] +Leg.Rbot = 12; % Radius of the cylinder of the bottom part of the leg [mm] + +Leg.density = opts.density; % Density of the material used for the legs [kg/m3] + +Leg.color = [0.5 0.5 0.5]; % Color of the top part of the leg [RGB] + +Leg.R = 1.3*Leg.Rbot; % Size of the sphere at the extremity of the leg [mm] + +legs = stewart.Ab - stewart.Aa; +Leg.lenght = norm(legs(1,:))/1.5; + +Leg.shape.bot = ... + [0 0; ... + Leg.Rbot 0; ... + Leg.Rbot Leg.lenght; ... + Leg.Rtop Leg.lenght; ... + Leg.Rtop 0.2*Leg.lenght; ... + 0 0.2*Leg.lenght]; + +stewart.Leg = Leg; + +SP = struct(); + +SP.k = 0; % [N*m/deg] +SP.c = 0; % [N*m/deg] + +SP.H = stewart.Aa(1, 3) - BP.H; % [mm] + +SP.R = Leg.R; % [mm] + +SP.section = [0 SP.H-SP.R; + 0 0; + SP.R 0; + SP.R SP.H]; + +SP.density = opts.density; % [kg/m^3] + +SP.color = [0.7 0.7 0.7]; % [RGB] + +stewart.SP = SP; diff --git a/stewart.slx b/stewart.slx index 2f4e76c..6b993a8 100644 Binary files a/stewart.slx and b/stewart.slx differ diff --git a/stiffness-study.org b/stiffness-study.org index 392e58f..0aee23b 100644 --- a/stiffness-study.org +++ b/stiffness-study.org @@ -1,4 +1,28 @@ #+TITLE: Stiffness of the Stewart Platform +:DRAWER: +#+STARTUP: overview + +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: + +#+LATEX_CLASS: cleanreport +#+LaTeX_CLASS_OPTIONS: [tocnp, secbreak, minted] +#+LaTeX_HEADER: \usepackage{svg} +#+LaTeX_HEADER: \newcommand{\authorFirstName}{Thomas} +#+LaTeX_HEADER: \newcommand{\authorLastName}{Dehaeze} +#+LaTeX_HEADER: \newcommand{\authorEmail}{dehaeze.thomas@gmail.com} + +#+PROPERTY: header-args:matlab :session *MATLAB* +#+PROPERTY: header-args:matlab+ :comments org +#+PROPERTY: header-args:matlab+ :exports both +#+PROPERTY: header-args:matlab+ :eval no-export +#+PROPERTY: header-args:matlab+ :output-dir figs +#+PROPERTY: header-args:matlab+ :mkdirp yes +:END: * Functions :PROPERTIES: