Cubic configuration for the Stewart Platform
Table of Contents
-
-
- 1. Questions we wish to answer with this analysis -
- 2. Configuration Analysis - Stiffness Matrix +
- 1. Questions we wish to answer with this analysis +
- 2. Configuration Analysis - Stiffness Matrix
-
-
- 2.1. Cubic Stewart platform centered with the cube center - Jacobian estimated at the cube center -
- 2.2. Cubic Stewart platform centered with the cube center - Jacobian not estimated at the cube center -
- 2.3. Cubic Stewart platform not centered with the cube center - Jacobian estimated at the cube center -
- 2.4. Cubic Stewart platform not centered with the cube center - Jacobian estimated at the Stewart platform center -
- 2.5. Conclusion +
- 2.1. Cubic Stewart platform centered with the cube center - Jacobian estimated at the cube center +
- 2.2. Cubic Stewart platform centered with the cube center - Jacobian not estimated at the cube center +
- 2.3. Cubic Stewart platform not centered with the cube center - Jacobian estimated at the cube center +
- 2.4. Cubic Stewart platform not centered with the cube center - Jacobian estimated at the Stewart platform center +
- 2.5. Conclusion
- - 3. Cubic size analysis -
- 4. initializeCubicConfiguration +
- 3. Cubic size analysis +
- 4. initializeCubicConfiguration
-
-
- 4.1. Function description -
- 4.2. Optional Parameters -
- 4.3. Cube Creation -
- 4.4. Vectors of each leg -
- 4.5. Verification of Height of the Stewart Platform -
- 4.6. Determinate the location of the joints -
- 4.7. Returns Stewart Structure +
- 4.1. Function description +
- 4.2. Optional Parameters +
- 4.3. Cube Creation +
- 4.4. Vectors of each leg +
- 4.5. Verification of Height of the Stewart Platform +
- 4.6. Determinate the location of the joints +
- 4.7. Returns Stewart Structure
- - 5. Tests +
- 5. Tests
-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.
-
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;
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;
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.
-
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;
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;
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
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
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]');
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 limi4 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] + );
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;
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
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];
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
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
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
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;
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;
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
Hmax = cube(4, 3) - cube(2, 3); +Hmax = cube(4, 3) - cube(2, 3);
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
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
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
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]);
Identification of the Stewart Platform using Simscape
Table of Contents
-
-
- 1. Identification -
- 2. Cartesian Plot -
- 3. From a force to force sensor -
- 4. From a force applied in the leg to the displacement of the leg -
- 5. Transmissibility -
- 6. Compliance -
- 7. Inertial -
- 8. identifyPlant +
- 1. Identification +
- 2. Cartesian Plot +
- 3. From a force to force sensor +
- 4. From a force applied in the leg to the displacement of the leg +
- 5. Transmissibility +
- 6. Compliance +
- 7. Inertial +
- 8. identifyPlant
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)
%% 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
options = linearizeOptions; -options.SampleTime = 0; +options.SampleTime = 0;
mdl = 'stewart';
+mdl = 'stewart';
%% 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
G = linearize(mdl, io, 0); +G = linearize(mdl, io, 0);
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'};
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
Created: 2019-03-22 ven. 12:03
+Created: 2019-08-26 lun. 11:55
-Kinematic Study of the Stewart Platform
Table of Contents
-
-
- 1. Needed Actuator Stroke +
- 1. Needed Actuator Stroke
-
-
- 1.1. Stewart architecture definition -
- 1.2. Wanted translations and rotations -
- 1.3. Needed stroke for "pure" rotations or translations -
- 1.4. Needed stroke for combined translations and rotations +
- 1.1. Stewart architecture definition +
- 1.2. Wanted translations and rotations +
- 1.3. Needed stroke for "pure" rotations or translations +
- 1.4. Needed stroke for combined translations and rotations
- - 2. Maximum Stroke -
- 3. Functions +
- 2. Maximum Stroke +
- 3. Functions
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
-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
Created: 2019-03-26 mar. 09:24
+Created: 2019-08-26 lun. 11:55
-Stewart Platform - Simscape Model
Table of Contents
-
-
- 1. initializeGeneralConfiguration +
- 1. initializeGeneralConfiguration -
- 2. computeGeometricalProperties +
- 2. computeGeometricalProperties -
- 3. initializeMechanicalElements +
- 3. initializeMechanicalElements -
- 4. initializeSample +
- 4. initializeSample
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] + );
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
Figure 1: Schematic of the bottom plates with all the parameters
@@ -435,85 +439,85 @@ Populate opts with input parameters1.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] + );
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);
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
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] + );
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
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();
BP.Rint = 0; % Internal Radius [mm] -BP.Rext = 150; % External Radius [mm] +BP.Rint = 0; % Internal Radius [mm] +BP.Rext = 150; % External Radius [mm]
BP.H = opts.thickness; % Thickness of the Bottom Plate [mm]
+BP.H = opts.thickness; % Thickness of the Bottom Plate [mm]
BP.density = opts.density; % Density of the material [kg/m3]
+BP.density = opts.density; % Density of the material [kg/m3]
BP.color = [0.7 0.7 0.7]; % Color [RGB] +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] +BP.shape = [BP.Rint BP.H; BP.Rint 0; BP.Rext 0; BP.Rext BP.H]; % [mm]
3.4 Top Plate
+3.4 Top Plate
The top plate structure is initialized.
TP = struct();
+TP = struct();
TP.Rint = 0; % [mm] -TP.Rext = 100; % [mm] +TP.Rint = 0; % [mm] +TP.Rext = 100; % [mm]
TP.H = 10; % [mm] +TP.H = 10; % [mm]
TP.density = opts.density; % Density of the material [kg/m3]
+TP.density = opts.density; % Density of the material [kg/m3]
TP.color = [0.7 0.7 0.7]; % Color [RGB] +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]; +TP.shape = [TP.Rint TP.H; TP.Rint 0; TP.Rext 0; TP.Rext TP.H];
3.5 Legs
+3.5 Legs
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();
Leg.stroke = opts.stroke; % [m]
+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.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.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.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.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] +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; +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]; +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];
3.6 Ball Joints
+3.6 Ball Joints
Figure 4: Schematic of the support for the ball joints
@@ -921,7 +925,7 @@ The structure is added to the stewart structure TheSP
structure is initialized.
SP = struct();
+SP = struct();
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]
SP.H = stewart.Aa(1, 3) - BP.H; % [mm] +SP.H = stewart.Aa(1, 3) - BP.H; % [mm]
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];
SP.density = opts.density; % [kg/m^3] +SP.density = opts.density; % [kg/m^3]
SP.color = [0.7 0.7 0.7]; % [RGB] +SP.color = [0.7 0.7 0.7]; % [RGB]
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] ... + );
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
Stiffness of the Stewart Platform
Table of Contents
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