diff --git a/simscape-model.html b/simscape-model.html index ecc545b..0116ad9 100644 --- a/simscape-model.html +++ b/simscape-model.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
- +initializeFramesPositions
: Initialize the positions of frames {A}, {B}, {F} and {M}
generateCubicConfiguration
: Generate a Cubic Configuration
computeJointsPose
: Compute the Pose of the Joints
+initializeStrutDynamics
: Add Stiffness and Damping properties of each strut
+
-First, geometrical parameters are defined: +We define 4 important frames:
-These parameter are enough to determine all the kinematic properties of the platform like the Jacobian, stroke, stiffness, …
-These geometrical parameters can be generated using different functions: initializeCubicConfiguration
for cubic configuration or initializeGeneralConfiguration
for more general configuration.
-
-A function computeGeometricalProperties
is then used to compute:
+Then, we define the location of the spherical joints:
-Then, geometrical parameters are computed for all the mechanical elements with the function initializeMechanicalElements
:
+We define the rest position of the Stewart platform:
-Other Parameters are defined for the Simscape simulation: +From \(\bm{a}_{i}\) and \(\bm{b}_{i}\), we can determine the length and orientation of each strut:
initializeSample
function)+The position of the Spherical joints can be computed using various methods: +
++For Simscape, we need: +
+
-The initializeGeneralConfiguration
function takes one structure that contains configurations for the hexapod and returns one structure representing the Hexapod.
+The procedure to define the Stewart platform is the following:
function [stewart] = initializeGeneralConfiguration(opts_param) --
-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] - ); --
initializeFramesPositions
function.
+We have to specify the total height of the Stewart platform \(H\) and the position \({}^{M}O_{B}\) of {B} with respect to {M}.generateCubicConfiguration
permits to generate a cubic configurationcomputeJointsPose
function.
-Populate opts with input parameters
+By following this procedure, we obtain a Matlab structure stewart
that contains all the information for the Simscape model and for further analysis.
if exist('opts_param','var') - for opt = fieldnames(opts_param)' - opts.(opt{1}) = opts_param.(opt{1}); - end -end --
-
-Figure 1: Schematic of the bottom plates with all the parameters
--We compute \([a_1, a_2, a_3, a_4, a_5, a_6]^T\) and \([b_1, b_2, b_3, b_4, b_5, b_6]^T\). -
- -Aa = zeros(6, 3); % [mm] -Ab = zeros(6, 3); % [mm] -Bb = zeros(6, 3); % [mm] --
for i = 1:3 - Aa(2*i-1,:) = [opts.R_bot*cos( pi/180*(120*(i-1) - opts.a_bot) ), ... - opts.R_bot*sin( pi/180*(120*(i-1) - opts.a_bot) ), ... - opts.H_plate+opts.H_joint]; - Aa(2*i,:) = [opts.R_bot*cos( pi/180*(120*(i-1) + opts.a_bot) ), ... - opts.R_bot*sin( pi/180*(120*(i-1) + opts.a_bot) ), ... - opts.H_plate+opts.H_joint]; - - Ab(2*i-1,:) = [opts.R_top*cos( pi/180*(120*(i-1) + opts.da_top - opts.a_top) ), ... - opts.R_top*sin( pi/180*(120*(i-1) + opts.da_top - opts.a_top) ), ... - opts.H_tot - opts.H_plate - opts.H_joint]; - Ab(2*i,:) = [opts.R_top*cos( pi/180*(120*(i-1) + opts.da_top + opts.a_top) ), ... - opts.R_top*sin( pi/180*(120*(i-1) + opts.da_top + opts.a_top) ), ... - opts.H_tot - opts.H_plate - opts.H_joint]; -end - -Bb = Ab - opts.H_tot*[0,0,1]; --
stewart = struct(); - stewart.Aa = Aa; - stewart.Ab = Ab; - stewart.Bb = Bb; - stewart.H_tot = opts.H_tot; -end --
function [stewart] = computeGeometricalProperties(stewart, opts_param) +open('stewart_platform.slx')
-Default values for opts. -
opts = struct(... - 'Jd_pos', [0, 0, 30], ... % Position of the Jacobian for displacement estimation from the top of the mobile platform [mm] - 'Jf_pos', [0, 0, 30] ... % Position of the Jacobian for force location from the top of the mobile platform [mm] - ); --
-Populate opts with input parameters -
-if exist('opts_param','var') - for opt = fieldnames(opts_param)' - opts.(opt{1}) = opts_param.(opt{1}); - end -end --
-We initialize \(l_i\) and \(\hat{s}_i\) -
-leg_length = zeros(6, 1); % [mm] -leg_vectors = zeros(6, 3); --
-We compute \(b_i - a_i\), and then: -
-\begin{align*} - l_i &= \left|b_i - a_i\right| \\ - \hat{s}_i &= \frac{b_i - a_i}{l_i} -\end{align*} - -legs = stewart.Ab - stewart.Aa; - -for i = 1:6 - leg_length(i) = norm(legs(i,:)); - leg_vectors(i,:) = legs(i,:) / leg_length(i); -end --
-We compute rotation matrices to have the orientation of the legs. -The rotation matrix transforms the \(z\) axis to the axis of the leg. The other axis are not important here. -
-stewart.Rm = struct('R', eye(3)); - -for i = 1:6 - sx = cross(leg_vectors(i,:), [1 0 0]); - sx = sx/norm(sx); - - sy = -cross(sx, leg_vectors(i,:)); - sy = sy/norm(sy); - - sz = leg_vectors(i,:); - sz = sz/norm(sz); - - stewart.Rm(i).R = [sx', sy', sz']; -end --
-Compute Jacobian Matrix -
-Jd = zeros(6); - -for i = 1:6 - Jd(i, 1:3) = leg_vectors(i, :); - Jd(i, 4:6) = cross(0.001*(stewart.Bb(i, :) - opts.Jd_pos), leg_vectors(i, :)); -end - -stewart.Jd = Jd; -stewart.Jd_inv = inv(Jd); --
Jf = zeros(6); - -for i = 1:6 - Jf(i, 1:3) = leg_vectors(i, :); - Jf(i, 4:6) = cross(0.001*(stewart.Bb(i, :) - opts.Jf_pos), leg_vectors(i, :)); -end - -stewart.Jf = Jf; -stewart.Jf_inv = inv(Jf); --
end +stewart = initializeFramesPositions(struct('H', 90e-3, 'MO_B', 50e-3)); +stewart = generateCubicConfiguration(stewart, struct('Hc', 60e-3, 'FOc', 50e-3, 'FHa', 15e-3, 'MHb', 15e-3)); +stewart = computeJointsPose(stewart); +stewart = initializeStrutDynamics(stewart, struct('Ki', 1e6*ones(6,1), 'Ci', 1e2*ones(6,1)));
initializeFramesPositions
: Initialize the positions of frames {A}, {B}, {F} and {M}+This Matlab function is accessible here. +
function [stewart] = initializeMechanicalElements(stewart, opts_param) +function [stewart] = initializeFramesPositions(opts_param) +% initializeFramesPositions - Initialize the positions of frames {A}, {B}, {F} and {M} +% +% Syntax: [stewart] = initializeFramesPositions(H, MO_B) +% +% Inputs: +% - opts_param - Structure with the following fields: +% - H [1x1] - Total Height of the Stewart Platform [m] +% - MO_B [1x1] - Height of the frame {B} with respect to {M} [m] +% +% Outputs: +% - stewart - A structure with the following fields: +% - H [1x1] - Total Height of the Stewart Platform [m] +% - FO_M [3x1] - Position of {M} with respect to {F} [m] +% - MO_B [3x1] - Position of {B} with respect to {M} [m] +% - FO_A [3x1] - Position of {A} with respect to {F} [m]
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( ... + 'H', 90e-3, ... % [m] + 'MO_B', 50e-3 ... % [m] + );
if exist('opts_param','var') +if exist('opts_param','var') for opt = fieldnames(opts_param)' - opts.(opt{1}) = opts_param.(opt{1}); + opts.(opt{1}) = opts_param.(opt{1}); end end@@ -675,350 +513,85 @@ Populate opts with input parameters
-
-Figure 2: Schematic of the bottom plates with all the parameters
--The bottom plate structure is initialized. -
BP = struct();
-
--We defined its internal radius (if there is a hole in the bottom plate) and its outer radius. -
-BP.Rint = 0; % Internal Radius [mm] -BP.Rext = 150; % External Radius [mm] --
-We define its thickness. -
-BP.H = opts.thickness; % Thickness of the Bottom Plate [mm]
-
--We defined the density of the material of the bottom plate. -
-BP.density = opts.density; % Density of the material [kg/m3]
-
--And its color. -
-BP.color = [0.7 0.7 0.7]; % Color [RGB] --
-Then the profile of the bottom plate is computed and will be used by Simscape -
-BP.shape = [BP.Rint BP.H; BP.Rint 0; BP.Rext 0; BP.Rext BP.H]; % [mm] --
-The structure is added to the stewart structure -
-stewart.BP = BP;
+stewart = struct();
-The top plate structure is initialized. -
TP = struct();
-
-stewart.H = opts.H; % Total Height of the Stewart Platform [m] --We defined the internal and external radius of the top plate. -
--+stewart.FO_M = [0; 0; stewart.H]; % Position of {M} with respect to {F} [m] -TP.Rint = 0; % [mm] -TP.Rext = 100; % [mm] ---The thickness of the top plate. -
--+stewart.MO_B = [0; 0; opts.MO_B]; % Position of {B} with respect to {M} [m] -TP.H = 10; % [mm] ---The density of its material. -
--- -TP.density = opts.density; % Density of the material [kg/m3] -
--Its color. -
--- -TP.color = [0.7 0.7 0.7]; % Color [RGB] ---Then the shape of the top plate is computed -
--- -TP.shape = [TP.Rint TP.H; TP.Rint 0; TP.Rext 0; TP.Rext TP.H]; ---The structure is added to the stewart structure -
---stewart.TP = TP; --
-
-Figure 3: Schematic for the legs of the Stewart platform
--The leg structure is initialized. -
-Leg = struct();
-
--The maximum Stroke of each leg is defined. -
-Leg.stroke = opts.stroke; % [m]
-
--The stiffness and damping of each leg are defined -
-Leg.k_ax = opts.k_ax; % Stiffness of each leg [N/m] -Leg.c_ax = opts.c_ax; % Damping of each leg [N/(m/s)] --
-The radius of the legs are defined -
-Leg.Rtop = 10; % Radius of the cylinder of the top part of the leg[mm] -Leg.Rbot = 12; % Radius of the cylinder of the bottom part of the leg [mm] --
-The density of its material. -
-Leg.density = opts.density; % Density of the material used for the legs [kg/m3]
-
--Its color. -
-Leg.color = [0.5 0.5 0.5]; % Color of the top part of the leg [RGB] --
-The radius of spheres representing the ball joints are defined. -
-Leg.R = 1.3*Leg.Rbot; % Size of the sphere at the extremity of the leg [mm] --
-We estimate the length of the legs. -
-legs = stewart.Ab - stewart.Aa; -Leg.lenght = norm(legs(1,:))/1.5; --
-Then the shape of the bottom leg is estimated -
-Leg.shape.bot = ... - [0 0; ... - Leg.Rbot 0; ... - Leg.Rbot Leg.lenght; ... - Leg.Rtop Leg.lenght; ... - Leg.Rtop 0.2*Leg.lenght; ... - 0 0.2*Leg.lenght]; --
-The structure is added to the stewart structure -
-stewart.Leg = Leg; --
-
-Figure 4: Schematic of the support for the ball joints
-
-SP
is the structure representing the support for the ball joints at the extremity of each leg.
-
-The SP
structure is initialized.
-
SP = struct();
-
--We can define its rotational stiffness and damping. For now, we use perfect joints. -
-SP.k = 0; % [N*m/deg] -SP.c = 0; % [N*m/deg] --
-Its height is defined -
-SP.H = stewart.Aa(1, 3) - BP.H; % [mm] --
-Its radius is based on the radius on the sphere at the end of the legs. -
-SP.R = Leg.R; % [mm]
-
-SP.section = [0 SP.H-SP.R; - 0 0; - SP.R 0; - SP.R SP.H]; --
-The density of its material is defined. -
-SP.density = opts.density; % [kg/m^3] --
-Its color is defined. -
-SP.color = [0.7 0.7 0.7]; % [RGB] --
-The structure is added to the Hexapod structure -
-stewart.SP = SP; +stewart.FO_A = stewart.MO_B + stewart.FO_M; % Position of {A} with respect to {F} [m]
generateCubicConfiguration
: Generate a Cubic Configuration+This Matlab function is accessible here. +
function [] = initializeSample(opts_param) +function [stewart] = generateCubicConfiguration(stewart, opts_param) +% generateCubicConfiguration - Generate a Cubic Configuration +% +% Syntax: [stewart] = generateCubicConfiguration(stewart, opts_param) +% +% Inputs: +% - stewart - A structure with the following fields +% - H [1x1] - Total height of the platform [m] +% - opts_param - Structure with the following fields: +% - Hc [1x1] - Height of the "useful" part of the cube [m] +% - FOc [1x1] - Height of the center of the cute with respect to {F} [m] +% - FHa [1x1] - Height of the plane joining the points ai with respect to the frame {F} [m] +% - MHb [1x1] - Height of the plane joining the points bi with respect to the frame {M} [m] +% +% Outputs: +% - stewart - updated Stewart structure with the added fields: +% - Fa [3x6] - Its i'th column is the position vector of joint ai with respect to {F} +% - Mb [3x6] - Its i'th column is the position vector of joint bi with respect to {M}
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] ... - ); +opts = struct( ... + 'Hc', 60e-3, ... % [m] + 'FOc', 50e-3, ... % [m] + 'FHa', 15e-3, ... % [m] + 'MHb', 15e-3 ... % [m] + );
if exist('opts_param','var') +if exist('opts_param','var') for opt = fieldnames(opts_param)' - sample.(opt{1}) = opts_param.(opt{1}); + opts.(opt{1}) = opts_param.(opt{1}); end end@@ -1036,16 +609,217 @@ Populate opts with input parameters
+We define the useful points of the cube with respect to the Cube's center. +\({}^{C}C\) are the 6 vertices of the cubes expressed in a frame {C} which is located at the center of the cube and aligned with {F} and {M}. +
save('./mat/sample.mat', 'sample'); +sx = [ 2; -1; -1]; +sy = [ 0; 1; -1]; +sz = [ 1; 1; 1]; + +R = [sx, sy, sz]./vecnorm([sx, sy, sz]); + +L = opts.Hc*sqrt(3); + +Cc = R'*[[0;0;L],[L;0;L],[L;0;0],[L;L;0],[0;L;0],[0;L;L]] - [0;0;1.5*opts.Hc]; + +CCf = [Cc(:,1), Cc(:,3), Cc(:,3), Cc(:,5), Cc(:,5), Cc(:,1)]; % CCf(:,i) corresponds to the bottom cube's vertice corresponding to the i'th leg +CCm = [Cc(:,2), Cc(:,2), Cc(:,4), Cc(:,4), Cc(:,6), Cc(:,6)]; % CCm(:,i) corresponds to the top cube's vertice corresponding to the i'th leg ++
+We can compute the vector of each leg \({}^{C}\hat{\bm{s}}_{i}\) (unit vector from \({}^{C}C_{f}\) to \({}^{C}C_{m}\)). +
+CSi = (CCm - CCf)./vecnorm(CCm - CCf); ++
+We now which to compute the position of the joints \(a_{i}\) and \(b_{i}\). +
+stewart.Fa = CCf + [0; 0; opts.FOc] + ((opts.FHa-(opts.FOc-opts.Hc/2))./CSi(3,:)).*CSi; +stewart.Mb = CCf + [0; 0; opts.FOc-stewart.H] + ((stewart.H-opts.MHb-(opts.FOc-opts.Hc/2))./CSi(3,:)).*CSi; ++
computeJointsPose
: Compute the Pose of the Joints+This Matlab function is accessible here. +
+function [stewart] = computeJointsPose(stewart) +% computeJointsPose - +% +% Syntax: [stewart] = computeJointsPose(stewart, opts_param) +% +% Inputs: +% - stewart - A structure with the following fields +% - FO_A [3x1] - Position of {A} with respect to {F} +% - MO_B [3x1] - Position of {B} with respect to {M} +% - FO_M [3x1] - Position of {M} with respect to {F} +% +% Outputs: +% - stewart - A structure with the following added fields +% - Aa [3x6] - The i'th column is the position of ai with respect to {A} +% - Ab [3x6] - The i'th column is the position of bi with respect to {A} +% - Ba [3x6] - The i'th column is the position of ai with respect to {B} +% - Bb [3x6] - The i'th column is the position of bi with respect to {B} +% - l [6x1] - The i'th element is the initial length of strut i +% - As [3x6] - The i'th column is the unit vector of strut i expressed in {A} +% - Bs [3x6] - The i'th column is the unit vector of strut i expressed in {B} +% - FRa [3x3x6] - The i'th 3x3 array is the rotation matrix to orientate the bottom of the i'th strut from {F} +% - MRb [3x3x6] - The i'th 3x3 array is the rotation matrix to orientate the top of the i'th strut from {M} ++
stewart.Aa = stewart.Fa - repmat(stewart.FO_A, [1, 6]); +stewart.Bb = stewart.Mb - repmat(stewart.MO_B, [1, 6]); + +stewart.Ab = stewart.Bb - repmat(-stewart.MO_B-stewart.FO_M+stewart.FO_A, [1, 6]); +stewart.Ba = stewart.Aa - repmat( stewart.MO_B+stewart.FO_M-stewart.FO_A, [1, 6]); ++
stewart.As = (stewart.Ab - stewart.Aa)./vecnorm(stewart.Ab - stewart.Aa); % As_i is the i'th vector of As + +stewart.l = vecnorm(stewart.Ab - stewart.Aa)';
end +stewart.Bs = (stewart.Bb - stewart.Ba)./vecnorm(stewart.Bb - stewart.Ba); ++
stewart.FRa = zeros(3,3,6); +stewart.MRb = zeros(3,3,6); + +for i = 1:6 + stewart.FRa(:,:,i) = [cross([0;1;0], stewart.As(:,i)) , cross(stewart.As(:,i), cross([0;1;0], stewart.As(:,i))) , stewart.As(:,i)]; + stewart.FRa(:,:,i) = stewart.FRa(:,:,i)./vecnorm(stewart.FRa(:,:,i)); + + stewart.MRb(:,:,i) = [cross([0;1;0], stewart.Bs(:,i)) , cross(stewart.Bs(:,i), cross([0;1;0], stewart.Bs(:,i))) , stewart.Bs(:,i)]; + stewart.MRb(:,:,i) = stewart.MRb(:,:,i)./vecnorm(stewart.MRb(:,:,i)); +end ++
initializeStrutDynamics
: Add Stiffness and Damping properties of each strut+This Matlab function is accessible here. +
+function [stewart] = initializeStrutDynamics(stewart, opts_param) +% initializeStrutDynamics - Add Stiffness and Damping properties of each strut +% +% Syntax: [stewart] = initializeStrutDynamics(opts_param) +% +% Inputs: +% - opts_param - Structure with the following fields: +% - Ki [6x1] - Stiffness of each strut [N/m] +% - Ci [6x1] - Damping of each strut [N/(m/s)] +% +% Outputs: +% - stewart - updated Stewart structure with the added fields: +% - Ki [6x1] - Stiffness of each strut [N/m] +% - Ci [6x1] - Damping of each strut [N/(m/s)] ++
+Default values for opts. +
+opts = struct( ... + 'Ki', 1e6*ones(6,1), ... % [N/m] + 'Ci', 1e2*ones(6,1) ... % [N/(m/s)] + ); ++
+Populate opts with input parameters +
+if exist('opts_param','var') + for opt = fieldnames(opts_param)' + opts.(opt{1}) = opts_param.(opt{1}); + end +end ++
stewart.Ki = opts.Ki; +stewart.Ci = opts.Ci;