diff --git a/cubic-configuration.html b/cubic-configuration.html index 6a2234d..7a6a1c0 100644 --- a/cubic-configuration.html +++ b/cubic-configuration.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Cubic configuration for the Stewart Platform @@ -193,12 +193,12 @@ .org-svg { width: 90%; } /*]]>*/--> - - - - - - + + + + + + -
+
+ UP + | + HOME +

Cubic configuration for the Stewart Platform

Table of Contents

@@ -323,11 +327,11 @@ The specificity of the Cubic configuration is that each actuator is orthogonal w

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

-
-

1 Questions we wish to answer with this analysis

+
+

1 Questions we wish to answer with this analysis

The goal is to study the benefits of using a cubic configuration: @@ -340,45 +344,45 @@ The goal is to study the benefits of using a cubic configuration:

-
-

2 Configuration Analysis - Stiffness Matrix

+
+

2 Configuration Analysis - Stiffness Matrix

-
-

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

+
+

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). +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);
+
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');
+save('./mat/stewart.mat', 'stewart');
 
-
K = stewart.Jd'*stewart.Jd;
+
K = stewart.Jf'*stewart.Jf;
 
@@ -457,32 +461,32 @@ save('./mat/s
-
-

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

+
+

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). +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);
+
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;
+
K = stewart.Jf'*stewart.Jf;
 
@@ -561,16 +565,16 @@ stewart = computeGeometricalProperties(stew
-
-

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

+
+

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). +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

@@ -584,23 +588,23 @@ 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);
+
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;
+
K = stewart.Jf'*stewart.Jf;
 
@@ -683,8 +687,8 @@ We obtain \(k_x = k_y = k_z\) and \(k_{\theta_x} = k_{\theta_y}\), but the Stiff
-
-

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

+
+

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. @@ -699,23 +703,23 @@ 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);
+
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;
+
K = stewart.Jf'*stewart.Jf;
 
@@ -798,8 +802,8 @@ We obtain \(k_x = k_y = k_z\) and \(k_{\theta_x} = k_{\theta_y}\), but the Stiff
-
-

2.5 Conclusion

+
+

2.5 Conclusion

    @@ -812,8 +816,8 @@ We obtain \(k_x = k_y = k_z\) and \(k_{\theta_x} = k_{\theta_y}\), but the Stiff
-
-

3 Cubic size analysis

+
+

3 Cubic size analysis

We here study the effect of the size of the cube used for the Stewart configuration. @@ -828,32 +832,32 @@ We only vary the size of the cube.

-
H_cubes = 250:20:350;
-stewarts = {zeros(length(H_cubes), 1)};
+
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;
+
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(...
+      '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
+  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
 
@@ -862,10 +866,10 @@ stewarts = {zeros -
Ks = zeros(6, 6, length(H_cube));
-for i = 1:length(H_cubes)
-  Ks(:, :, i) = stewarts{i}.Jd'*stewarts{i}.Jd;
-end
+
Ks = zeros(6, 6, length(H_cube));
+for i = 1:length(H_cubes)
+  Ks(:, :, i) = stewarts{i}.Jd'*stewarts{i}.Jd;
+end
 
@@ -877,18 +881,18 @@ The only elements of \(K\) that vary are \(k_{\theta_x} = k_{\theta_y}\) and \(k Finally, we plot \(k_{\theta_x} = k_{\theta_y}\) and \(k_{\theta_z}\)

-
figure;
+
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}$');
+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]');
+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

@@ -909,37 +913,37 @@ In that case, the legs will the further separated. Size of the cube is then limi
-
-

4 initializeCubicConfiguration

+
+

4 initializeCubicConfiguration

- +

-
-

4.1 Function description

+
+

4.1 Function description

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

4.2 Optional Parameters

+
+

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]
-    );
+
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]
+    );
 
@@ -947,29 +951,29 @@ Default values for opts. Populate opts with input parameters

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

4.3 Cube Creation

+
+

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;
+
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;
 
@@ -977,16 +981,16 @@ 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);
+
sx = cross([1, 1, 1], [1 0 0]);
+sx = sx/norm(sx);
 
-sy = -cross(sx, [1, 1, 1]);
-sy = sy/norm(sy);
+sy = -cross(sx, [1, 1, 1]);
+sy = sy/norm(sy);
 
-sz = [1, 1, 1];
-sz = sz/norm(sz);
+sz = [1, 1, 1];
+sz = sz/norm(sz);
 
-R = [sx', sy', sz']';
+R = [sx', sy', sz']';
 
@@ -994,25 +998,25 @@ R = [sx', sy', sz' -
cube = zeros(size(points));
-for i = 1:size(points, 1)
-  cube(i, :) = R * points(i, :)';
-end
+
cube = zeros(size(points));
+for i = 1:size(points, 1)
+  cube(i, :) = R * points(i, :)';
+end
 
-
-

4.4 Vectors of each leg

+
+

4.4 Vectors of each leg

-
leg_indices = [3, 4; ...
-               2, 4; ...
-               2, 6; ...
-               5, 6; ...
-               5, 7; ...
-               3, 7];
+
leg_indices = [3, 4; ...
+               2, 4; ...
+               2, 6; ...
+               5, 6; ...
+               5, 7; ...
+               3, 7];
 
@@ -1020,51 +1024,51 @@ We use to rotation matrix to rotate the cube Vectors are:

-
legs = zeros(6, 3);
-legs_start = zeros(6, 3);
+
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
+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

+
+

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
+
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

+
+

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
+
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
 
@@ -1072,11 +1076,11 @@ We now determine the location of the joints on the fixed platform w.r.t the fixe 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
+
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
 
@@ -1084,45 +1088,45 @@ And the location of the joints on the mobile platform with respect to \(\{A\}\). 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];
+
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];
+
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

+
+

4.7 Returns Stewart Structure

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

5 Tests

+
+

5 Tests

-
-

5.1 First attempt to parametrisation

+
+

5.1 First attempt to parametrisation

-
+

stewart_bottom_plate.png

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

@@ -1157,8 +1161,8 @@ Lets express \(a_i\), \(b_i\) and \(a_j\):
-
-

5.2 Second attempt

+
+

5.2 Second attempt

We start with the point of a cube in space: @@ -1177,50 +1181,50 @@ Then we have the direction of all the vectors expressed in the frame of the hexa

-
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 = [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')
+
figure;
+plot3(points(:,1), points(:,2), points(:,3), 'ko')
 
-
sx = cross([1, 1, 1], [1 0 0]);
-sx = sx/norm(sx);
+
sx = cross([1, 1, 1], [1 0 0]);
+sx = sx/norm(sx);
 
-sy = -cross(sx, [1, 1, 1]);
-sy = sy/norm(sy);
+sy = -cross(sx, [1, 1, 1]);
+sy = sy/norm(sy);
 
-sz = [1, 1, 1];
-sz = sz/norm(sz);
+sz = [1, 1, 1];
+sz = sz/norm(sz);
 
-R = [sx', sy', sz']';
+R = [sx', sy', sz']';
 
-
cube = zeros(size(points));
-for i = 1:size(points, 1)
-  cube(i, :) = R * points(i, :)';
-end
+
cube = zeros(size(points));
+for i = 1:size(points, 1)
+  cube(i, :) = R * points(i, :)';
+end
 
-
figure;
+
figure;
 hold on;
-plot3(points(:,1), points(:,2), points(:,3), 'ko');
-plot3(cube(:,1), cube(:,2), cube(:,3), 'ro');
+plot3(points(:,1), points(:,2), points(:,3), 'ko');
+plot3(cube(:,1), cube(:,2), cube(:,3), 'ro');
 hold off;
 
@@ -1229,18 +1233,18 @@ hold off; Now we plot the legs of the hexapod.

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

-
legs = zeros(6, 3);
-legs_start = zeros(6, 3);
+
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
+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
 
@@ -1271,7 +1275,7 @@ 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);
+
Hmax = cube(4, 3) - cube(2, 3);
 
@@ -1279,26 +1283,26 @@ Let's first estimate the maximum height of the Stewart platform. Let's then estimate the middle position of the platform

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

5.3 Generate the Stewart platform for a Cubic configuration

+
+

5.3 Generate the Stewart platform for a Cubic configuration

First we defined the height of the Hexapod.

-
H = Hmax/2;
+
H = Hmax/2;
 
-
Zs = 1.2*cube(2, 3); % Height of the fixed platform
-Ze = Zs + H; % Height of the mobile platform
+
Zs = 1.2*cube(2, 3); % Height of the fixed platform
+Ze = Zs + H; % Height of the mobile platform
 
@@ -1306,11 +1310,11 @@ Ze = Zs + H; 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
+
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
 
@@ -1318,11 +1322,11 @@ We now determine the location of the joints on the fixed platform. 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
+
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
 
@@ -1330,15 +1334,15 @@ And the location of the joints on the mobile platform And we plot the legs.

-
figure;
+
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
+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]);
+xlim([-1, 1]);
+ylim([-1, 1]);
+zlim([0, 2]);
 
@@ -1356,7 +1360,7 @@ zlim([

Author: Thomas Dehaeze

-

Created: 2019-03-26 mar. 08:47

+

Created: 2019-08-26 lun. 11:58

Validate

diff --git a/cubic-configuration.org b/cubic-configuration.org index e212b66..b825f9c 100644 --- a/cubic-configuration.org +++ b/cubic-configuration.org @@ -1,27 +1,24 @@ #+TITLE: Cubic configuration for the Stewart Platform :DRAWER: -#+STARTUP: overview +#+HTML_LINK_HOME: ./index.html +#+HTML_LINK_UP: ./index.html -#+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} +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: #+PROPERTY: header-args:matlab :session *MATLAB* +#+PROPERTY: header-args:matlab+ :tangle matlab/cubic_configuration.m #+PROPERTY: header-args:matlab+ :comments org #+PROPERTY: header-args:matlab+ :exports both +#+PROPERTY: header-args:matlab+ :results none #+PROPERTY: header-args:matlab+ :eval no-export -#+PROPERTY: header-args:matlab+ :output-dir figs +#+PROPERTY: header-args:matlab+ :noweb yes #+PROPERTY: header-args:matlab+ :mkdirp yes +#+PROPERTY: header-args:matlab+ :output-dir figs :END: #+begin_src matlab :results none :exports none :noweb yes diff --git a/identification.html b/identification.html index ae68ab6..2cae52a 100644 --- a/identification.html +++ b/identification.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Identification of the Stewart Platform using Simscape @@ -193,12 +193,12 @@ .org-svg { width: 90%; } /*]]>*/--> - - - - - - + + + + + + -
+
+ UP + | + HOME +

Identification of the Stewart Platform using Simscape

-
-

1 Identification

+
+

1 Identification

The hexapod structure and Sample structure are initialized.

-
initializeHexapod();
-initializeSample();
+
stewart = initializeGeneralConfiguration();
+stewart = computeGeometricalProperties(stewart);
+stewart = initializeMechanicalElements(stewart);
+save('./mat/stewart.mat', 'stewart');
+
+initializeSample();
 
-
G = identifyPlant();
+
G = identifyPlant();
+
+
+ +
+
freqs = logspace(2, 4, 1000);
 
-
-

2 Cartesian Plot

+
+

2 Cartesian Plot

From a force applied in the Cartesian frame to a displacement in the Cartesian frame.

-
figure;
+
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');
+
+
+ +
+
figure;
+bode(G.G_cart, freqs);
 
-
-

3 From a force to force sensor

+
+

3 From a force to force sensor

-
figure;
+
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');
 
-
figure;
+
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');
 
-
-

4 From a force applied in the leg to the displacement of the leg

+
+

4 From a force applied in the leg to the displacement of the leg

-
figure;
+
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]');
 
-
figure;
+
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');
 
-
-

5 Transmissibility

+
+

5 Transmissibility

-
figure;
+
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]');
 
-
figure;
+
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}$]');
 
-
figure;
+
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]');
 
-
-

6 Compliance

+
+

6 Compliance

From a force applied in the Cartesian frame to a relative displacement of the mobile platform with respect to the base.

-
figure;
+
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]');
 
-
-

7 Inertial

+
+

7 Inertial

From a force applied on the Cartesian frame to the absolute displacement of the mobile platform.

-
figure;
+
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]');
 
-
-

8 identifyPlant

+
+

8 identifyPlant

-
function [sys] = identifyPlant(opts_param)
+
function [sys] = identifyPlant(opts_param)
 
@@ -470,15 +503,15 @@ hold off; We use this code block to pass optional parameters.

-
%% Default values for opts
-opts = struct();
+
%% Default values for opts
+opts = struct();
 
-%% Populate opts with input parameters
-if exist('opts_param','var')
-    for opt = fieldnames(opts_param)'
-        opts.(opt{1}) = opts_param.(opt{1});
-    end
-end
+%% Populate opts with input parameters
+if exist('opts_param','var')
+    for opt = fieldnames(opts_param)'
+        opts.(opt{1}) = opts_param.(opt{1});
+    end
+end
 
@@ -488,7 +521,7 @@ Here, we just identify the system at time \(t = 0\).

options = linearizeOptions;
-options.SampleTime = 0;
+options.SampleTime = 0;
 
@@ -496,7 +529,7 @@ options.SampleTime = 0; We define the name of the Simulink File used to identification.

-
mdl = 'stewart';
+
mdl = 'stewart';
 
@@ -504,17 +537,17 @@ We define the name of the Simulink File used to identification. Then we defined the input/output of the transfer function we want to identify.

-
%% Inputs
-io(1) = linio([mdl, '/F'],  1, 'input'); % Cartesian forces
-io(2) = linio([mdl, '/Fl'], 1, 'input'); % Leg forces
-io(3) = linio([mdl, '/Fd'], 1, 'input'); % Direct forces
-io(4) = linio([mdl, '/Dw'], 1, 'input'); % Base motion
+
%% Inputs
+io(1) = linio([mdl, '/F'],  1, 'input'); % Cartesian forces
+io(2) = linio([mdl, '/Fl'], 1, 'input'); % Leg forces
+io(3) = linio([mdl, '/Fd'], 1, 'input'); % Direct forces
+io(4) = linio([mdl, '/Dw'], 1, 'input'); % Base motion
 
-%% Outputs
-io(5) = linio([mdl, '/Dm'],  1, 'output'); % Relative Motion
-io(6) = linio([mdl, '/Dlm'], 1, 'output'); % Displacement of each leg
-io(7) = linio([mdl, '/Flm'], 1, 'output'); % Force sensor in each leg
-io(8) = linio([mdl, '/Xm'],  1, 'output'); % Absolute motion of platform
+%% Outputs
+io(5) = linio([mdl, '/Dm'],  1, 'output'); % Relative Motion
+io(6) = linio([mdl, '/Dlm'], 1, 'output'); % Displacement of each leg
+io(7) = linio([mdl, '/Flm'], 1, 'output'); % Force sensor in each leg
+io(8) = linio([mdl, '/Xm'],  1, 'output'); % Absolute motion of platform
 
@@ -522,7 +555,7 @@ io(8
-
G = linearize(mdl, io, 0);
+
G = linearize(mdl, io, 0);
 
@@ -530,14 +563,14 @@ The linearization is run. We defined all the Input/Output names of the identified transfer function.

-
G.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz', ...
-                'F1', 'F2', 'F3', 'F4', 'F5', 'F6', ...
-                'Fdx', 'Fdy', 'Fdz', 'Mdx', 'Mdy', 'Mdz', ...
-                'Dwx', 'Dwy', 'Dwz', 'Rwx', 'Rwy', 'Rwz'};
-G.OutputName = {'Dxm', 'Dym', 'Dzm', 'Rxm', 'Rym', 'Rzm', ...
-                'D1m', 'D2m', 'D3m', 'D4m', 'D5m', 'D6m', ...
-                'F1m', 'F2m', 'F3m', 'F4m', 'F5m', 'F6m', ...
-                'Dxtm', 'Dytm', 'Dztm', 'Rxtm', 'Rytm', 'Rztm'};
+
G.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz', ...
+                'F1', 'F2', 'F3', 'F4', 'F5', 'F6', ...
+                'Fdx', 'Fdy', 'Fdz', 'Mdx', 'Mdy', 'Mdz', ...
+                'Dwx', 'Dwy', 'Dwz', 'Rwx', 'Rwy', 'Rwz'};
+G.OutputName = {'Dxm', 'Dym', 'Dzm', 'Rxm', 'Rym', 'Rzm', ...
+                'D1m', 'D2m', 'D3m', 'D4m', 'D5m', 'D6m', ...
+                'F1m', 'F2m', 'F3m', 'F4m', 'F5m', 'F6m', ...
+                'Dxtm', 'Dytm', 'Dztm', 'Rxtm', 'Rytm', 'Rztm'};
 
@@ -545,18 +578,18 @@ G.OutputName = { -
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_iner = minreal(G({'Dxtm', 'Dytm', 'Dztm', 'Rxtm', 'Rytm', 'Rztm'}, {'Fdx', 'Fdy', 'Fdz', 'Mdx', 'Mdy', 'Mdz'}));
-% sys.G_all  = minreal(G);
+
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_iner = minreal(G({'Dxtm', 'Dytm', 'Dztm', 'Rxtm', 'Rytm', 'Rztm'}, {'Fdx', 'Fdy', 'Fdz', 'Mdx', 'Mdy', 'Mdz'}));
+% sys.G_all  = minreal(G);
 
-
end
+
end
 
@@ -564,7 +597,7 @@ sys.G_iner = minreal(G

Author: Thomas Dehaeze

-

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

+

Created: 2019-08-26 lun. 11:55

Validate

diff --git a/identification.org b/identification.org index 334136b..42fc5e1 100644 --- a/identification.org +++ b/identification.org @@ -1,27 +1,24 @@ #+TITLE: Identification of the Stewart Platform using Simscape :DRAWER: -#+STARTUP: overview +#+HTML_LINK_HOME: ./index.html +#+HTML_LINK_UP: ./index.html -#+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} +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: #+PROPERTY: header-args:matlab :session *MATLAB* +#+PROPERTY: header-args:matlab+ :tangle matlab/identification.m #+PROPERTY: header-args:matlab+ :comments org #+PROPERTY: header-args:matlab+ :exports both +#+PROPERTY: header-args:matlab+ :results none #+PROPERTY: header-args:matlab+ :eval no-export -#+PROPERTY: header-args:matlab+ :output-dir figs +#+PROPERTY: header-args:matlab+ :noweb yes #+PROPERTY: header-args:matlab+ :mkdirp yes +#+PROPERTY: header-args:matlab+ :output-dir figs :END: * Identification diff --git a/index.html b/index.html index fd92b09..90c9dec 100644 --- a/index.html +++ b/index.html @@ -3,10 +3,10 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + -Stewart Platform Studies +Stewart Platforms - - - - - - + + + + + + -
+
+ UP + | + HOME +

Kinematic Study of the Stewart Platform

-
-

1 Needed Actuator Stroke

+
+

1 Needed Actuator Stroke

The goal is to determine the needed stroke of the actuators to obtain wanted translations and rotations.

-
-

1.1 Stewart architecture definition

+
+

1.1 Stewart architecture definition

We use a cubic architecture.

-
opts = struct(...
-    'H_tot', 90, ... % Total height of the Hexapod [mm]
-    'L',     180/sqrt(3), ... % Size of the Cube [mm]
-    'H',     60, ... % Height between base joints and platform joints [mm]
-    'H0',    180/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, 100], ... % 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);
-opts = struct(...
-    'stroke', 50e-6 ... % Maximum stroke of each actuator [m]
-    );
-stewart = initializeMechanicalElements(stewart, opts);
+
opts = struct(...
+    'H_tot', 90, ... % 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, 100], ... % 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);
+opts = struct(...
+    'stroke', 50e-6 ... % Maximum stroke of each actuator [m]
+    );
+stewart = initializeMechanicalElements(stewart, opts);
 
-save('./mat/stewart.mat', 'stewart');
+save('./mat/stewart.mat', 'stewart');
 
-
-

1.2 Wanted translations and rotations

+
+

1.2 Wanted translations and rotations

We define wanted translations and rotations

-
Tx_max = 15e-6; % Translation [m]
-Ty_max = 15e-6; % Translation [m]
-Tz_max = 15e-6; % Translation [m]
-Rx_max = 30e-6; % Rotation [rad]
-Ry_max = 30e-6; % Rotation [rad]
+
Tx_max = 15e-6; % Translation [m]
+Ty_max = 15e-6; % Translation [m]
+Tz_max = 15e-6; % Translation [m]
+Rx_max = 30e-6; % Rotation [rad]
+Ry_max = 30e-6; % Rotation [rad]
 
-
-

1.3 Needed stroke for "pure" rotations or translations

+
+

1.3 Needed stroke for "pure" rotations or translations

First, we estimate the needed actuator stroke for "pure" rotations and translation.

-
LTx = stewart.Jd*[Tx_max 0 0 0 0 0]';
-LTy = stewart.Jd*[0 Ty_max 0 0 0 0]';
-LTz = stewart.Jd*[0 0 Tz_max 0 0 0]';
-LRx = stewart.Jd*[0 0 0 Rx_max 0 0]';
-LRy = stewart.Jd*[0 0 0 0 Ry_max 0]';
+
LTx = stewart.Jd*[Tx_max 0 0 0 0 0]';
+LTy = stewart.Jd*[0 Ty_max 0 0 0 0]';
+LTz = stewart.Jd*[0 0 Tz_max 0 0 0]';
+LRx = stewart.Jd*[0 0 0 Rx_max 0 0]';
+LRy = stewart.Jd*[0 0 0 0 Ry_max 0]';
 
-1.0607e-05
+From -1.2e-05[m] to 1.1e-05[m]: Total stroke = 22.9[um]
 
-
-

1.4 Needed stroke for combined translations and rotations

+
+

1.4 Needed stroke for combined translations and rotations

Now, we combine translations and rotations, and we try to find the worst case (that we suppose to happen at the border).

-
Lmax = 0;
-pos = [0, 0, 0, 0, 0];
-for Tx = [-Tx_max,Tx_max]
-for Ty = [-Ty_max,Ty_max]
-for Tz = [-Tz_max,Tz_max]
-for Rx = [-Rx_max,Rx_max]
-for Ry = [-Ry_max,Ry_max]
-    L = max(stewart.Jd*[Tx Ty Tz Rx Ry 0]');
-    if L > Lmax
-        Lmax = L;
-        pos = [Tx Ty Tz Rx Ry];
-    end
-end
-end
-end
-end
-end
+
Lmax = 0;
+Lmin = 0;
+pos = [0, 0, 0, 0, 0];
+for Tx = [-Tx_max,Tx_max]
+for Ty = [-Ty_max,Ty_max]
+for Tz = [-Tz_max,Tz_max]
+for Rx = [-Rx_max,Rx_max]
+for Ry = [-Ry_max,Ry_max]
+    lmax = max(stewart.Jd*[Tx Ty Tz Rx Ry 0]');
+    lmin = min(stewart.Jd*[Tx Ty Tz Rx Ry 0]');
+    if lmax > Lmax
+        Lmax = lmax;
+        pos = [Tx Ty Tz Rx Ry];
+    end
+    if lmin < Lmin
+        Lmin = lmin;
+    end
+end
+end
+end
+end
+end
 
@@ -380,76 +389,76 @@ pos = [0
-3.0927e-05
+From -3.1e-05[m] to 3.1e-05[m]: Total stroke = 61.5[um]
 
-
-

2 Maximum Stroke

+
+

2 Maximum Stroke

From a specified actuator stroke, we try to estimate the available maneuverability of the Stewart platform.

-
[X, Y, Z] = getMaxPositions(stewart);
+
[X, Y, Z] = getMaxPositions(stewart);
 
-
figure;
-plot3(X, Y, Z, 'k-')
+
figure;
+plot3(X, Y, Z, 'k-')
 
-
-

3 Functions

+
+

3 Functions

-
-

3.1 getMaxPositions

+
+

3.1 getMaxPositions

-
function [X, Y, Z] = getMaxPositions(stewart)
+
function [X, Y, Z] = getMaxPositions(stewart)
     Leg = stewart.Leg;
     J = stewart.Jd;
-    theta = linspace(0, 2*pi, 100);
-    phi = linspace(-pi/2 , pi/2, 100);
-    dmax = zeros(length(theta), length(phi));
+    theta = linspace(0, 2*pi, 100);
+    phi = linspace(-pi/2 , pi/2, 100);
+    dmax = zeros(length(theta), length(phi));
 
-    for i = 1:length(theta)
-        for j = 1:length(phi)
-            L = J*[cos(phi(j))*cos(theta(i)) cos(phi(j))*sin(theta(i)) sin(phi(j)) 0 0 0]';
-            dmax(i, j) = Leg.stroke/max(abs(L));
-        end
-    end
+    for i = 1:length(theta)
+        for j = 1:length(phi)
+            L = J*[cos(phi(j))*cos(theta(i)) cos(phi(j))*sin(theta(i)) sin(phi(j)) 0 0 0]';
+            dmax(i, j) = Leg.stroke/max(abs(L));
+        end
+    end
 
-    X = dmax.*cos(repmat(phi,length(theta),1)).*cos(repmat(theta,length(phi),1))';
-    Y = dmax.*cos(repmat(phi,length(theta),1)).*sin(repmat(theta,length(phi),1))';
-    Z = dmax.*sin(repmat(phi,length(theta),1));
-end
+    X = dmax.*cos(repmat(phi,length(theta),1)).*cos(repmat(theta,length(phi),1))';
+    Y = dmax.*cos(repmat(phi,length(theta),1)).*sin(repmat(theta,length(phi),1))';
+    Z = dmax.*sin(repmat(phi,length(theta),1));
+end
 
-
-

3.2 getMaxPureDisplacement

+
+

3.2 getMaxPureDisplacement

-
function [max_disp] = getMaxPureDisplacement(Leg, J)
-    max_disp = zeros(6, 1);
-    max_disp(1) = Leg.stroke/max(abs(J*[1 0 0 0 0 0]'));
-    max_disp(2) = Leg.stroke/max(abs(J*[0 1 0 0 0 0]'));
-    max_disp(3) = Leg.stroke/max(abs(J*[0 0 1 0 0 0]'));
-    max_disp(4) = Leg.stroke/max(abs(J*[0 0 0 1 0 0]'));
-    max_disp(5) = Leg.stroke/max(abs(J*[0 0 0 0 1 0]'));
-    max_disp(6) = Leg.stroke/max(abs(J*[0 0 0 0 0 1]'));
-end
+
function [max_disp] = getMaxPureDisplacement(Leg, J)
+    max_disp = zeros(6, 1);
+    max_disp(1) = Leg.stroke/max(abs(J*[1 0 0 0 0 0]'));
+    max_disp(2) = Leg.stroke/max(abs(J*[0 1 0 0 0 0]'));
+    max_disp(3) = Leg.stroke/max(abs(J*[0 0 1 0 0 0]'));
+    max_disp(4) = Leg.stroke/max(abs(J*[0 0 0 1 0 0]'));
+    max_disp(5) = Leg.stroke/max(abs(J*[0 0 0 0 1 0]'));
+    max_disp(6) = Leg.stroke/max(abs(J*[0 0 0 0 0 1]'));
+end
 
@@ -458,7 +467,7 @@ plot3(X, Y, Z,

Author: Thomas Dehaeze

-

Created: 2019-03-26 mar. 09:24

+

Created: 2019-08-26 lun. 11:55

Validate

diff --git a/kinematic-study.org b/kinematic-study.org index b2f5b53..5b471ed 100644 --- a/kinematic-study.org +++ b/kinematic-study.org @@ -1,27 +1,24 @@ #+TITLE: Kinematic Study of the Stewart Platform :DRAWER: -#+STARTUP: overview +#+HTML_LINK_HOME: ./index.html +#+HTML_LINK_UP: ./index.html -#+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} +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: #+PROPERTY: header-args:matlab :session *MATLAB* +#+PROPERTY: header-args:matlab+ :tangle matlab/kinematic_study.m #+PROPERTY: header-args:matlab+ :comments org #+PROPERTY: header-args:matlab+ :exports both +#+PROPERTY: header-args:matlab+ :results none #+PROPERTY: header-args:matlab+ :eval no-export -#+PROPERTY: header-args:matlab+ :output-dir figs +#+PROPERTY: header-args:matlab+ :noweb yes #+PROPERTY: header-args:matlab+ :mkdirp yes +#+PROPERTY: header-args:matlab+ :output-dir figs :END: #+begin_src matlab :results none :exports none :noweb yes @@ -39,9 +36,9 @@ We use a cubic architecture. #+begin_src matlab :results silent opts = struct(... 'H_tot', 90, ... % Total height of the Hexapod [mm] - 'L', 180/sqrt(3), ... % Size of the Cube [mm] + 'L', 200/sqrt(3), ... % Size of the Cube [mm] 'H', 60, ... % Height between base joints and platform joints [mm] - 'H0', 180/2-60/2 ... % Height between the corner of the cube and the plane containing the base 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(... @@ -78,27 +75,32 @@ First, we estimate the needed actuator stroke for "pure" rotations and translati #+end_src #+begin_src matlab :results value :exports results - ans = max(max([LTx, LTy, LTz, LRx, LRy])) + ans = sprintf('From %.2g[m] to %.2g[m]: Total stroke = %.1f[um]', min(min([LTx,LTy,LTz,LRx,LRy])), max(max([LTx,LTy,LTz,LRx,LRy])), 1e6*(max(max([LTx,LTy,LTz,LRx,LRy]))-min(min([LTx,LTy,LTz,LRx,LRy])))) #+end_src #+RESULTS: -: 1.0607e-05 +: From -1.2e-05[m] to 1.1e-05[m]: Total stroke = 22.9[um] ** Needed stroke for combined translations and rotations Now, we combine translations and rotations, and we try to find the worst case (that we suppose to happen at the border). #+begin_src matlab :results none Lmax = 0; + Lmin = 0; pos = [0, 0, 0, 0, 0]; for Tx = [-Tx_max,Tx_max] for Ty = [-Ty_max,Ty_max] for Tz = [-Tz_max,Tz_max] for Rx = [-Rx_max,Rx_max] for Ry = [-Ry_max,Ry_max] - L = max(stewart.Jd*[Tx Ty Tz Rx Ry 0]'); - if L > Lmax - Lmax = L; + lmax = max(stewart.Jd*[Tx Ty Tz Rx Ry 0]'); + lmin = min(stewart.Jd*[Tx Ty Tz Rx Ry 0]'); + if lmax > Lmax + Lmax = lmax; pos = [Tx Ty Tz Rx Ry]; end + if lmin < Lmin + Lmin = lmin; + end end end end @@ -108,11 +110,11 @@ Now, we combine translations and rotations, and we try to find the worst case (t We obtain a needed stroke shown below (almost two times the needed stroke for "pure" rotations and translations). #+begin_src matlab :results value :exports results - ans = Lmax + ans = sprintf('From %.2g[m] to %.2g[m]: Total stroke = %.1f[um]', Lmin, Lmax, 1e6*(Lmax-Lmin)) #+end_src #+RESULTS: -: 3.0927e-05 +: From -3.1e-05[m] to 3.1e-05[m]: Total stroke = 61.5[um] * Maximum Stroke From a specified actuator stroke, we try to estimate the available maneuverability of the Stewart platform. diff --git a/simscape-model.html b/simscape-model.html index 31fcfea..ecc545b 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 @@ -193,12 +193,12 @@ .org-svg { width: 90%; } /*]]>*/--> - - - - - - + + + + + + -
+
+ UP + | + HOME +

Stewart Platform - Simscape Model

Table of Contents

@@ -370,42 +374,42 @@ Other Parameters are defined for the Simscape simulation:
  • Location of the Jacobian point for velocity/displacement computation
  • -
    -

    1 initializeGeneralConfiguration

    +
    +

    1 initializeGeneralConfiguration

    -
    -

    1.1 Function description

    +
    +

    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)
    +
    function [stewart] = initializeGeneralConfiguration(opts_param)
     
    -
    -

    1.2 Optional Parameters

    +
    +

    1.2 Optional Parameters

    Default values for opts.

    -
    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]
    -    );
    +
    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]
    +    );
     
    @@ -413,21 +417,21 @@ Default values for opts. Populate opts with input parameters

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

    1.3 Geometry Description

    +
    +

    1.3 Geometry Description

    -
    +

    stewart_bottom_plate.png

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

    @@ -435,85 +439,85 @@ Populate opts with input parameters
    -
    -

    1.4 Compute Aa and Ab

    +
    +

    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]
    +
    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];
    +
    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
    +    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];
    +Bb = Ab - opts.H_tot*[0,0,1];
     
    -
    -

    1.5 Returns Stewart Structure

    +
    +

    1.5 Returns Stewart Structure

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

    2 computeGeometricalProperties

    +
    +

    2 computeGeometricalProperties

    -
    -

    2.1 Function description

    +
    +

    2.1 Function description

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

    2.2 Optional Parameters

    +
    +

    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]
    -    );
    +
    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]
    +    );
     
    @@ -521,25 +525,25 @@ Default values for opts. Populate opts with input parameters

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

    2.3 Rotation matrices

    +
    +

    2.3 Rotation matrices

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

    -
    leg_length = zeros(6, 1); % [mm]
    -leg_vectors = zeros(6, 3);
    +
    leg_length = zeros(6, 1); % [mm]
    +leg_vectors = zeros(6, 3);
     
    @@ -552,12 +556,12 @@ We compute \(b_i - a_i\), and then: \end{align*}
    -
    legs = stewart.Ab - stewart.Aa;
    +
    legs = stewart.Ab - stewart.Aa;
     
    -for i = 1:6
    -    leg_length(i) = norm(legs(i,:));
    -    leg_vectors(i,:) = legs(i,:) / leg_length(i);
    -end
    +for i = 1:6
    +    leg_length(i) = norm(legs(i,:));
    +    leg_vectors(i,:) = legs(i,:) / leg_length(i);
    +end
     
    @@ -566,94 +570,94 @@ 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));
    +
    stewart.Rm = struct('R', eye(3));
     
    -for i = 1:6
    -  sx = cross(leg_vectors(i,:), [1 0 0]);
    -  sx = sx/norm(sx);
    +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);
    +  sy = -cross(sx, leg_vectors(i,:));
    +  sy = sy/norm(sy);
     
    -  sz = leg_vectors(i,:);
    -  sz = sz/norm(sz);
    +  sz = leg_vectors(i,:);
    +  sz = sz/norm(sz);
     
    -  stewart.Rm(i).R = [sx', sy', sz'];
    -end
    +  stewart.Rm(i).R = [sx', sy', sz'];
    +end
     
    -
    -

    2.4 Jacobian matrices

    +
    +

    2.4 Jacobian matrices

    Compute Jacobian Matrix

    -
    Jd = zeros(6);
    +
    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
    +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);
    +stewart.Jd_inv = inv(Jd);
     
    -
    Jf = zeros(6);
    +
    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
    +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);
    +stewart.Jf_inv = inv(Jf);
     
    -
    end
    +
    end
     
    -
    -

    3 initializeMechanicalElements

    +
    +

    3 initializeMechanicalElements

    -
    -

    3.1 Function description

    +
    +

    3.1 Function description

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

    3.2 Optional Parameters

    +
    +

    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]
    -    );
    +
    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]
    +    );
     
    @@ -661,21 +665,21 @@ Default values for opts. Populate opts with input parameters

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

    3.3 Bottom Plate

    +
    +

    3.3 Bottom Plate

    -
    +

    stewart_bottom_plate.png

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

    @@ -685,7 +689,7 @@ Populate opts with input parameters The bottom plate structure is initialized.

    -
    BP = struct();
    +
    BP = struct();
     
    @@ -693,8 +697,8 @@ The bottom plate structure is initialized. 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]
    +
    BP.Rint = 0;   % Internal Radius [mm]
    +BP.Rext = 150; % External Radius [mm]
     
    @@ -702,7 +706,7 @@ BP.Rext = 150; -
    BP.H = opts.thickness; % Thickness of the Bottom Plate [mm]
    +
    BP.H = opts.thickness; % Thickness of the Bottom Plate [mm]
     
    @@ -710,7 +714,7 @@ We define its thickness. We defined the density of the material of the bottom plate.

    -
    BP.density = opts.density; % Density of the material [kg/m3]
    +
    BP.density = opts.density; % Density of the material [kg/m3]
     
    @@ -718,7 +722,7 @@ We defined the density of the material of the bottom plate. And its color.

    -
    BP.color = [0.7 0.7 0.7]; % Color [RGB]
    +
    BP.color = [0.7 0.7 0.7]; % Color [RGB]
     
    @@ -726,7 +730,7 @@ And its color. 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]
    +
    BP.shape = [BP.Rint BP.H; BP.Rint 0; BP.Rext 0; BP.Rext BP.H]; % [mm]
     
    @@ -740,14 +744,14 @@ The structure is added to the stewart structure
    -
    -

    3.4 Top Plate

    +
    +

    3.4 Top Plate

    The top plate structure is initialized.

    -
    TP = struct();
    +
    TP = struct();
     
    @@ -755,8 +759,8 @@ The top plate structure is initialized. We defined the internal and external radius of the top plate.

    -
    TP.Rint = 0;   % [mm]
    -TP.Rext = 100; % [mm]
    +
    TP.Rint = 0;   % [mm]
    +TP.Rext = 100; % [mm]
     
    @@ -764,7 +768,7 @@ TP.Rext = 100; -
    TP.H = 10; % [mm]
    +
    TP.H = 10; % [mm]
     
    @@ -772,7 +776,7 @@ The thickness of the top plate. The density of its material.

    -
    TP.density = opts.density; % Density of the material [kg/m3]
    +
    TP.density = opts.density; % Density of the material [kg/m3]
     
    @@ -780,7 +784,7 @@ The density of its material. Its color.

    -
    TP.color = [0.7 0.7 0.7]; % Color [RGB]
    +
    TP.color = [0.7 0.7 0.7]; % Color [RGB]
     
    @@ -788,7 +792,7 @@ Its color. 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];
    +
    TP.shape = [TP.Rint TP.H; TP.Rint 0; TP.Rext 0; TP.Rext TP.H];
     
    @@ -802,11 +806,11 @@ The structure is added to the stewart structure
    -
    -

    3.5 Legs

    +
    +

    3.5 Legs

    -
    +

    stewart_legs.png

    Figure 3: Schematic for the legs of the Stewart platform

    @@ -816,7 +820,7 @@ The structure is added to the stewart structure The leg structure is initialized.

    -
    Leg = struct();
    +
    Leg = struct();
     
    @@ -824,7 +828,7 @@ The leg structure is initialized. The maximum Stroke of each leg is defined.

    -
    Leg.stroke = opts.stroke; % [m]
    +
    Leg.stroke = opts.stroke; % [m]
     
    @@ -832,8 +836,8 @@ The maximum Stroke of each leg is defined. 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)]
    +
    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)]
     
    @@ -841,8 +845,8 @@ Leg.c_ax = opts.c_ax; % Damping of each leg [N/(m/ 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]
    +
    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]
     
    @@ -850,7 +854,7 @@ Leg.Rbot = 12; -
    Leg.density = opts.density; % Density of the material used for the legs [kg/m3]
    +
    Leg.density = opts.density; % Density of the material used for the legs [kg/m3]
     
    @@ -858,7 +862,7 @@ The density of its material. Its color.

    -
    Leg.color = [0.5 0.5 0.5]; % Color of the top part of the leg [RGB]
    +
    Leg.color = [0.5 0.5 0.5]; % Color of the top part of the leg [RGB]
     
    @@ -866,7 +870,7 @@ Its color. 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]
    +
    Leg.R = 1.3*Leg.Rbot; % Size of the sphere at the extremity of the leg [mm]
     
    @@ -874,8 +878,8 @@ 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;
    +
    legs = stewart.Ab - stewart.Aa;
    +Leg.lenght = norm(legs(1,:))/1.5;
     
    @@ -883,13 +887,13 @@ Leg.lenght = norm(legs -
    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];
    +
    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];
     
    @@ -903,11 +907,11 @@ The structure is added to the stewart structure
    -
    -

    3.6 Ball Joints

    +
    +

    3.6 Ball Joints

    -
    +

    stewart_ball_joints.png

    Figure 4: Schematic of the support for the ball joints

    @@ -921,7 +925,7 @@ The structure is added to the stewart structure The SP structure is initialized.

    -
    SP = struct();
    +
    SP = struct();
     
    @@ -929,8 +933,8 @@ The SP structure is initialized. 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]
    +
    SP.k = 0; % [N*m/deg]
    +SP.c = 0; % [N*m/deg]
     
    @@ -938,7 +942,7 @@ SP.c = 0; % [ Its height is defined

    -
    SP.H = stewart.Aa(1, 3) - BP.H; % [mm]
    +
    SP.H = stewart.Aa(1, 3) - BP.H; % [mm]
     
    @@ -946,15 +950,15 @@ Its height is defined Its radius is based on the radius on the sphere at the end of the legs.

    -
    SP.R = Leg.R; % [mm]
    +
    SP.R = Leg.R; % [mm]
     
    -
    SP.section = [0    SP.H-SP.R;
    -              0    0;
    -              SP.R 0;
    -              SP.R SP.H];
    +
    SP.section = [0    SP.H-SP.R;
    +              0    0;
    +              SP.R 0;
    +              SP.R SP.H];
     
    @@ -962,7 +966,7 @@ Its radius is based on the radius on the sphere at the end of the legs. The density of its material is defined.

    -
    SP.density = opts.density; % [kg/m^3]
    +
    SP.density = opts.density; % [kg/m^3]
     
    @@ -970,7 +974,7 @@ The density of its material is defined. Its color is defined.

    -
    SP.color = [0.7 0.7 0.7]; % [RGB]
    +
    SP.color = [0.7 0.7 0.7]; % [RGB]
     
    @@ -985,36 +989,36 @@ The structure is added to the Hexapod structure
    -
    -

    4 initializeSample

    +
    +

    4 initializeSample

    -
    -

    4.1 Function description

    +
    +

    4.1 Function description

    -
    function [] = initializeSample(opts_param)
    +
    function [] = initializeSample(opts_param)
     
    -
    -

    4.2 Optional Parameters

    +
    +

    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] ...
    -    );
    +
    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] ...
    +    );
     
    @@ -1022,26 +1026,26 @@ Default values for opts. Populate opts with input parameters

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

    4.3 Save the Sample structure

    +
    +

    4.3 Save the Sample structure

    -
    save('./mat/sample.mat', 'sample');
    +
    save('./mat/sample.mat', 'sample');
     
    -
    end
    +
    end
     
    @@ -1050,7 +1054,7 @@ Populate opts with input parameters

    Author: Thomas Dehaeze

    -

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

    +

    Created: 2019-08-26 lun. 11:56

    Validate

    diff --git a/simscape-model.org b/simscape-model.org index 717d3e7..7a8ff35 100644 --- a/simscape-model.org +++ b/simscape-model.org @@ -1,27 +1,23 @@ #+TITLE: Stewart Platform - Simscape Model :DRAWER: -#+STARTUP: overview +#+HTML_LINK_HOME: ./index.html +#+HTML_LINK_UP: ./index.html -#+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} +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: #+PROPERTY: header-args:matlab :session *MATLAB* #+PROPERTY: header-args:matlab+ :comments org #+PROPERTY: header-args:matlab+ :exports both +#+PROPERTY: header-args:matlab+ :results none #+PROPERTY: header-args:matlab+ :eval no-export -#+PROPERTY: header-args:matlab+ :output-dir figs +#+PROPERTY: header-args:matlab+ :noweb yes #+PROPERTY: header-args:matlab+ :mkdirp yes +#+PROPERTY: header-args:matlab+ :output-dir figs :END: Stewart platforms are generated in multiple steps. diff --git a/stiffness-study.html b/stiffness-study.html index 74fb341..254d5fb 100644 --- a/stiffness-study.html +++ b/stiffness-study.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Stiffness of the Stewart Platform @@ -193,6 +193,12 @@ .org-svg { width: 90%; } /*]]>*/--> + + + + + + -
    +
    + UP + | + HOME +

    Stiffness of the Stewart Platform

    -
    -

    1 Functions

    +
    +

    1 Functions

    -
    -

    1.1 getStiffnessMatrix

    +
    +

    1.1 getStiffnessMatrix

    -
    function [K] = getStiffnessMatrix(k, J)
    -% k - leg stiffness
    -% J - Jacobian matrix
    -    K = k*(J'*J);
    -end
    +
    function [K] = getStiffnessMatrix(k, J)
    +% k - leg stiffness
    +% J - Jacobian matrix
    +    K = k*(J'*J);
    +end
     
    @@ -277,7 +287,7 @@ for the JavaScript code in this tag.

    Author: Thomas Dehaeze

    -

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

    +

    Created: 2019-08-26 lun. 11:56

    Validate

    diff --git a/stiffness-study.org b/stiffness-study.org index 0aee23b..4c734f1 100644 --- a/stiffness-study.org +++ b/stiffness-study.org @@ -1,27 +1,24 @@ #+TITLE: Stiffness of the Stewart Platform :DRAWER: -#+STARTUP: overview +#+HTML_LINK_HOME: ./index.html +#+HTML_LINK_UP: ./index.html -#+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} +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: #+PROPERTY: header-args:matlab :session *MATLAB* +#+PROPERTY: header-args:matlab+ :tangle matlab/stiffness_study.m #+PROPERTY: header-args:matlab+ :comments org #+PROPERTY: header-args:matlab+ :exports both +#+PROPERTY: header-args:matlab+ :results none #+PROPERTY: header-args:matlab+ :eval no-export -#+PROPERTY: header-args:matlab+ :output-dir figs +#+PROPERTY: header-args:matlab+ :noweb yes #+PROPERTY: header-args:matlab+ :mkdirp yes +#+PROPERTY: header-args:matlab+ :output-dir figs :END: * Functions