2019-03-22 12:03:59 +01:00
#+TITLE : Stewart Platform - Simscape Model
:DRAWER:
2019-08-26 11:58:44 +02:00
#+HTML_LINK_HOME : ./index.html
#+HTML_LINK_UP : ./index.html
2019-03-22 12:03:59 +01:00
2019-08-26 11:58:44 +02:00
#+HTML_HEAD : <link rel="stylesheet" type="text/css" href="./css/htmlize.css"/>
#+HTML_HEAD : <link rel="stylesheet" type="text/css" href="./css/readtheorg.css"/>
#+HTML_HEAD : <script src="./js/jquery.min.js"></script>
#+HTML_HEAD : <script src="./js/bootstrap.min.js"></script>
#+HTML_HEAD : <script src="./js/jquery.stickytableheaders.min.js"></script>
#+HTML_HEAD : <script src="./js/readtheorg.js"></script>
2019-03-22 12:03:59 +01:00
#+PROPERTY : header-args:matlab :session *MATLAB*
2019-03-25 18:12:43 +01:00
#+PROPERTY : header-args:matlab+ :comments org
#+PROPERTY : header-args:matlab+ :exports both
2019-08-26 11:58:44 +02:00
#+PROPERTY : header-args:matlab+ :results none
2019-03-25 18:12:43 +01:00
#+PROPERTY : header-args:matlab+ :eval no-export
2019-08-26 11:58:44 +02:00
#+PROPERTY : header-args:matlab+ :noweb yes
2019-03-22 12:03:59 +01:00
#+PROPERTY : header-args:matlab+ :mkdirp yes
2019-08-26 11:58:44 +02:00
#+PROPERTY : header-args:matlab+ :output-dir figs
2019-03-22 12:03:59 +01:00
:END:
2019-10-09 11:08:42 +02:00
* Introduction :ignore:
2019-03-25 18:12:43 +01:00
Stewart platforms are generated in multiple steps.
2019-12-19 18:01:32 +01:00
We define 4 important *frames* :
- $\{F\}$: Frame fixed to the *Fixed* base and located at the center of its bottom surface.
This is used to fix the Stewart platform to some support.
- $\{M\}$: Frame fixed to the *Moving* platform and located at the center of its top surface.
This is used to place things on top of the Stewart platform.
- $\{A\}$: Frame fixed to the fixed base.
It defined the center of rotation of the moving platform.
- $\{B\}$: Frame fixed to the moving platform.
The motion of the moving platforms and forces applied to it are defined with respect to this frame $\{B\}$.
Then, we define the *location of the spherical joints* :
- $\bm{a}_{i}$ are the position of the spherical joints fixed to the fixed base
- $\bm{b}_{i}$ are the position of the spherical joints fixed to the moving platform
We define the *rest position* of the Stewart platform:
- For simplicity, we suppose that the fixed base and the moving platform are parallel and aligned with the vertical axis at their rest position.
- Thus, to define the rest position of the Stewart platform, we just have to defined its total height $H$.
$H$ corresponds to the distance from the bottom of the fixed base to the top of the moving platform.
From $\bm{a}_{i}$ and $\bm{b}_ {i}$, we can determine the *length and orientation of each strut* :
- $l_{i}$ is the length of the strut
- ${}^{A}\hat{\bm{s}}_{i}$ is the unit vector align with the strut
The position of the Spherical joints can be done using various methods:
- Cubic configuration
- Geometrical
- Definition them by hand
- These methods should be easily scriptable and corresponds to specific functions that returns ${}^{F}\bm{a}_{i}$ and ${}^{M}\bm{b}_ {i}$.
The input of these functions are the parameters corresponding to the wanted geometry.
We need also to know the height of the platform.
For Simscape, we need:
- The position of the frame $\{A\}$ with respect to the frame $\{F\}$: ${}^{F}\bm{O}_{A}$
- The position of the frame $\{B\}$ with respect to the frame $\{M\}$: ${}^{M}\bm{O}_{B}$
- The position and orientation of each spherical joint fixed to the fixed base: ${}^{F}\bm{a}_{i}$ and ${}^{F}\bm{R}_ {a_{i}}$
- The position and orientation of each spherical joint fixed to the moving platform: ${}^{M}\bm{b}_{i}$ and ${}^{M}\bm{R}_ {b_{i}}$
- The rest length of each strut: $l_{i}$
- The stiffness and damping of each actuator: $k_{i}$ and $c_ {i}$
------
The procedure is the following:
1. Choose $H$
2. Choose ${}^{F}\bm{O}_{A}$ and ${}^{M}\bm{O}_ {B}$
3. Choose $\bm{a}_{i}$ and $\bm{b}_ {i}$, probably by specifying ${}^{F}\bm{a}_{i}$ and ${}^{M}\bm{b}_ {i}$
4. Choose $k_{i}$ and $c_ {i}$
#+begin_src matlab
%% 1. Height of the platform. Location of {F} and {M}
H = 90e-3; % [m]
FO_M = [0; 0; H];
%% 2. Location of {A} and {B}
FO_A = [0; 0; 100e-3] + FO_M;% [m,m,m]
MO_B = [0; 0; 100e-3];% [m,m,m]
%% 3. Position and Orientation of ai and bi
Fa = zeros(3, 6); % Fa_i is the i'th vector of Fa
Mb = zeros(3, 6); % Mb_i is the i'th vector of Mb
Aa = Fa - repmat(FO_A, [1, 6]);
Bb = Mb - repmat(MO_B, [1, 6]);
Ab = Bb - repmat(-MO_B-FO_M+FO_A, [1, 6]);
Ba = Aa - repmat( MO_B+FO_M-FO_A, [1, 6]);
As = (Ab - Aa)./vecnorm(Ab - Aa); % As_i is the i'th vector of As
l = vecnorm(Ab - Aa);
Bs = (Bb - Ba)./vecnorm(Bb - Ba);
FRa = zeros(3,3,6);
MRb = zeros(3,3,6);
for i = 1:6
FRa(:,:,i) = [cross([0;1;0],As(:,i)) , cross(As(:,i), cross([0;1;0], As(:,i))) , As(:,i)];
FRa(:,:,i) = FRa(:,:,i)./vecnorm(FRa(:,:,i));
MRb(:,:,i) = [cross([0;1;0],Bs(:,i)) , cross(Bs(:,i), cross([0;1;0], Bs(:,i))) , Bs(:,i)];
MRb(:,:,i) = MRb(:,:,i)./vecnorm(MRb(:,:,i));
end
%% 4. Stiffness and Damping of each strut
Ki = 1e6*ones(6,1);
Ci = 1e2*ones(6,1);
#+end_src
------
2019-03-25 18:12:43 +01:00
First, geometrical parameters are defined:
2019-12-19 18:01:32 +01:00
- ${}^A\bm{a}_i$ - Position of the joints fixed to the fixed base w.r.t $\{A\}$
- ${}^A\bm{b}_i$ - Position of the joints fixed to the mobile platform w.r.t $\{A\}$
- ${}^B\bm{b}_i$ - Position of the joints fixed to the mobile platform w.r.t $\{B\}$
2019-03-25 18:12:43 +01:00
- $H$ - Total height of the mobile platform
These parameter are enough to determine all the kinematic properties of the platform like the Jacobian, stroke, stiffness, ...
These geometrical parameters can be generated using different functions: =initializeCubicConfiguration= for cubic configuration or =initializeGeneralConfiguration= for more general configuration.
A function =computeGeometricalProperties= is then used to compute:
2019-12-19 18:01:32 +01:00
- $\bm{J}_f$ - Jacobian matrix for the force location
- $\bm{J}_d$ - Jacobian matrix for displacement estimation
- $\bm{R}_m$ - Rotation matrices to position the leg vectors
2019-03-25 18:12:43 +01:00
Then, geometrical parameters are computed for all the mechanical elements with the function =initializeMechanicalElements= :
- Shape of the platforms
- External Radius
- Internal Radius
- Density
- Thickness
- Shape of the Legs
- Radius
- Size of ball joint
- Density
Other Parameters are defined for the Simscape simulation:
- Sample mass, volume and position (=initializeSample= function)
- Location of the inertial sensor
- Location of the point for the differential measurements
- Location of the Jacobian point for velocity/displacement computation
* initializeGeneralConfiguration
2019-12-19 18:01:32 +01:00
:PROPERTIES:
:HEADER-ARGS:matlab+: :exports code
:HEADER-ARGS:matlab+: :comments no
:HEADER-ARGS:matlab+: :eval no
:HEADER-ARGS:matlab+: :tangle src/initializeGeneralConfiguration.m
:END:
2019-03-25 18:12:43 +01:00
** Function description
The =initializeGeneralConfiguration= function takes one structure that contains configurations for the hexapod and returns one structure representing the Hexapod.
2019-03-22 12:03:59 +01:00
#+begin_src matlab
2019-03-25 18:12:43 +01:00
function [stewart] = initializeGeneralConfiguration(opts_param)
2019-03-22 12:03:59 +01:00
#+end_src
2019-03-25 18:12:43 +01:00
** Optional Parameters
2019-03-22 12:03:59 +01:00
Default values for opts.
#+begin_src matlab
opts = struct(...
2019-03-25 18:12:43 +01:00
'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]
2019-03-22 12:03:59 +01:00
);
#+end_src
Populate opts with input parameters
#+begin_src matlab
if exist('opts_param','var')
for opt = fieldnames(opts_param)'
opts.(opt{1}) = opts_param.(opt{1});
end
end
#+end_src
2019-03-25 18:12:43 +01:00
** Geometry Description
#+name : fig:stewart_bottom_plate
#+caption : Schematic of the bottom plates with all the parameters
[[file:./figs/stewart_bottom_plate.png ]]
** Compute Aa and Ab
We compute $[a_1, a_2, a_3, a_4, a_5, a_6]^T$ and $[b_1, b_2, b_3, b_4, b_5, b_6]^T$.
#+begin_src matlab
Aa = zeros(6, 3); % [mm]
Ab = zeros(6, 3); % [mm]
Bb = zeros(6, 3); % [mm]
#+end_src
2019-03-22 12:03:59 +01:00
#+begin_src matlab
2019-03-25 18:12:43 +01:00
for i = 1:3
Aa(2*i-1,:) = [opts.R_bot*cos( pi/180* (120*(i-1) - opts.a_bot) ), ...
opts.R_bot*sin( pi/180* (120*(i-1) - opts.a_bot) ), ...
opts.H_plate+opts.H_joint];
Aa(2*i,:) = [opts.R_bot*cos( pi/180* (120*(i-1) + opts.a_bot) ), ...
opts.R_bot*sin( pi/180* (120*(i-1) + opts.a_bot) ), ...
opts.H_plate+opts.H_joint];
Ab(2*i-1,:) = [opts.R_top*cos( pi/180* (120*(i-1) + opts.da_top - opts.a_top) ), ...
opts.R_top*sin( pi/180* (120*(i-1) + opts.da_top - opts.a_top) ), ...
opts.H_tot - opts.H_plate - opts.H_joint];
Ab(2*i,:) = [opts.R_top*cos( pi/180* (120*(i-1) + opts.da_top + opts.a_top) ), ...
opts.R_top*sin( pi/180* (120*(i-1) + opts.da_top + opts.a_top) ), ...
opts.H_tot - opts.H_plate - opts.H_joint];
end
Bb = Ab - opts.H_tot*[0,0,1];
#+end_src
** Returns Stewart Structure
#+begin_src matlab :results none
2019-03-22 12:03:59 +01:00
stewart = struct();
2019-03-25 18:12:43 +01:00
stewart.Aa = Aa;
stewart.Ab = Ab;
stewart.Bb = Bb;
stewart.H_tot = opts.H_tot;
end
#+end_src
* computeGeometricalProperties
2019-12-19 18:01:32 +01:00
:PROPERTIES:
:HEADER-ARGS:matlab+: :exports code
:HEADER-ARGS:matlab+: :comments no
:HEADER-ARGS:matlab+: :eval no
:HEADER-ARGS:matlab+: :tangle src/computeGeometricalProperties.m
:END:
2019-03-25 18:12:43 +01:00
** Function description
#+begin_src matlab
function [stewart] = computeGeometricalProperties(stewart, opts_param)
2019-03-22 12:03:59 +01:00
#+end_src
2019-03-25 18:12:43 +01:00
** Optional Parameters
Default values for opts.
2019-03-22 12:03:59 +01:00
#+begin_src matlab
2019-03-25 18:12:43 +01:00
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]
);
2019-03-22 12:03:59 +01:00
#+end_src
2019-03-25 18:12:43 +01:00
Populate opts with input parameters
#+begin_src matlab
if exist('opts_param','var')
for opt = fieldnames(opts_param)'
opts.(opt{1}) = opts_param.(opt{1});
end
end
#+end_src
** Rotation matrices
We initialize $l_i$ and $\hat{s}_i$
#+begin_src matlab
leg_length = zeros(6, 1); % [mm]
leg_vectors = zeros(6, 3);
#+end_src
We compute $b_i - a_i$, and then:
\begin{align*}
l_i &= \left|b_i - a_i\right| \\
\hat{s}_i &= \frac{b_i - a_i}{l_i}
\end{align*}
#+begin_src matlab
legs = stewart.Ab - stewart.Aa;
for i = 1:6
leg_length(i) = norm(legs(i,:));
leg_vectors(i,:) = legs(i,:) / leg_length(i);
end
#+end_src
We compute rotation matrices to have the orientation of the legs.
The rotation matrix transforms the $z$ axis to the axis of the leg. The other axis are not important here.
#+begin_src matlab
stewart.Rm = struct('R', eye(3));
for i = 1:6
sx = cross(leg_vectors(i,:), [1 0 0]);
sx = sx/norm(sx);
sy = -cross(sx, leg_vectors(i,:));
sy = sy/norm(sy);
sz = leg_vectors(i,:);
sz = sz/norm(sz);
stewart.Rm(i).R = [sx', sy', sz'];
end
#+end_src
** Jacobian matrices
Compute Jacobian Matrix
#+begin_src matlab
Jd = zeros(6);
for i = 1:6
Jd(i, 1:3) = leg_vectors(i, :);
Jd(i, 4:6) = cross(0.001*(stewart.Bb(i, :) - opts.Jd_pos), leg_vectors(i, :));
end
stewart.Jd = Jd;
stewart.Jd_inv = inv(Jd);
#+end_src
#+begin_src matlab
Jf = zeros(6);
for i = 1:6
Jf(i, 1:3) = leg_vectors(i, :);
Jf(i, 4:6) = cross(0.001*(stewart.Bb(i, :) - opts.Jf_pos), leg_vectors(i, :));
end
stewart.Jf = Jf;
stewart.Jf_inv = inv(Jf);
#+end_src
#+begin_src matlab
end
#+end_src
* initializeMechanicalElements
2019-12-19 18:01:32 +01:00
:PROPERTIES:
:HEADER-ARGS:matlab+: :exports code
:HEADER-ARGS:matlab+: :comments no
:HEADER-ARGS:matlab+: :eval no
:HEADER-ARGS:matlab+: :tangle src/initializeMechanicalElements.m
:END:
2019-03-25 18:12:43 +01:00
** Function description
#+begin_src matlab
function [stewart] = initializeMechanicalElements(stewart, opts_param)
#+end_src
** Optional Parameters
Default values for opts.
#+begin_src matlab
opts = struct(...
'thickness', 10, ... % Thickness of the base and platform [mm]
'density', 1000, ... % Density of the material used for the hexapod [kg/m3]
'k_ax', 1e8, ... % Stiffness of each actuator [N/m]
'c_ax', 1000, ... % Damping of each actuator [N/(m/s)]
'stroke', 50e-6 ... % Maximum stroke of each actuator [m]
);
#+end_src
Populate opts with input parameters
#+begin_src matlab
if exist('opts_param','var')
for opt = fieldnames(opts_param)'
opts.(opt{1}) = opts_param.(opt{1});
end
end
#+end_src
** Bottom Plate
2019-03-22 12:03:59 +01:00
#+name : fig:stewart_bottom_plate
#+caption : Schematic of the bottom plates with all the parameters
[[file:./figs/stewart_bottom_plate.png ]]
The bottom plate structure is initialized.
#+begin_src matlab
BP = struct();
#+end_src
We defined its internal radius (if there is a hole in the bottom plate) and its outer radius.
#+begin_src matlab
BP.Rint = 0; % Internal Radius [mm]
BP.Rext = 150; % External Radius [mm]
#+end_src
We define its thickness.
#+begin_src matlab
2019-03-25 18:12:43 +01:00
BP.H = opts.thickness; % Thickness of the Bottom Plate [mm]
2019-03-22 12:03:59 +01:00
#+end_src
We defined the density of the material of the bottom plate.
#+begin_src matlab
BP.density = opts.density; % Density of the material [kg/m3]
#+end_src
And its color.
#+begin_src matlab
BP.color = [0.7 0.7 0.7]; % Color [RGB]
#+end_src
Then the profile of the bottom plate is computed and will be used by Simscape
#+begin_src matlab
BP.shape = [BP.Rint BP.H; BP.Rint 0; BP.Rext 0; BP.Rext BP.H]; % [mm]
#+end_src
The structure is added to the stewart structure
#+begin_src matlab
stewart.BP = BP;
#+end_src
2019-03-25 18:12:43 +01:00
** Top Plate
2019-03-22 12:03:59 +01:00
The top plate structure is initialized.
#+begin_src matlab
TP = struct();
#+end_src
We defined the internal and external radius of the top plate.
#+begin_src matlab
TP.Rint = 0; % [mm]
TP.Rext = 100; % [mm]
#+end_src
The thickness of the top plate.
#+begin_src matlab
TP.H = 10; % [mm]
#+end_src
The density of its material.
#+begin_src matlab
TP.density = opts.density; % Density of the material [kg/m3]
#+end_src
Its color.
#+begin_src matlab
TP.color = [0.7 0.7 0.7]; % Color [RGB]
#+end_src
Then the shape of the top plate is computed
#+begin_src matlab
TP.shape = [TP.Rint TP.H; TP.Rint 0; TP.Rext 0; TP.Rext TP.H];
#+end_src
The structure is added to the stewart structure
#+begin_src matlab
stewart.TP = TP;
#+end_src
2019-03-25 18:12:43 +01:00
** Legs
2019-03-22 12:03:59 +01:00
#+name : fig:stewart_legs
#+caption : Schematic for the legs of the Stewart platform
[[file:./figs/stewart_legs.png ]]
The leg structure is initialized.
#+begin_src matlab
Leg = struct();
#+end_src
The maximum Stroke of each leg is defined.
#+begin_src matlab
Leg.stroke = opts.stroke; % [m]
#+end_src
The stiffness and damping of each leg are defined
#+begin_src matlab
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)]
#+end_src
The radius of the legs are defined
#+begin_src matlab
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]
#+end_src
The density of its material.
#+begin_src matlab
Leg.density = opts.density; % Density of the material used for the legs [kg/m3]
#+end_src
Its color.
#+begin_src matlab
Leg.color = [0.5 0.5 0.5]; % Color of the top part of the leg [RGB]
#+end_src
The radius of spheres representing the ball joints are defined.
#+begin_src matlab
Leg.R = 1.3*Leg.Rbot; % Size of the sphere at the extremity of the leg [mm]
#+end_src
2019-03-25 18:12:43 +01:00
We estimate the length of the legs.
#+begin_src matlab
legs = stewart.Ab - stewart.Aa;
Leg.lenght = norm(legs(1,:))/1.5;
#+end_src
Then the shape of the bottom leg is estimated
#+begin_src matlab
Leg.shape.bot = ...
[0 0; ...
Leg.Rbot 0; ...
Leg.Rbot Leg.lenght; ...
Leg.Rtop Leg.lenght; ...
Leg.Rtop 0.2*Leg.lenght; ...
0 0.2*Leg.lenght];
#+end_src
2019-03-22 12:03:59 +01:00
The structure is added to the stewart structure
#+begin_src matlab
stewart.Leg = Leg;
#+end_src
2019-03-25 18:12:43 +01:00
** Ball Joints
2019-03-22 12:03:59 +01:00
#+name : fig:stewart_ball_joints
#+caption : Schematic of the support for the ball joints
[[file:./figs/stewart_ball_joints.png ]]
=SP= is the structure representing the support for the ball joints at the extremity of each leg.
The =SP= structure is initialized.
#+begin_src matlab
SP = struct();
#+end_src
We can define its rotational stiffness and damping. For now, we use perfect joints.
#+begin_src matlab
SP.k = 0; % [N*m/deg]
SP.c = 0; % [N*m/deg]
#+end_src
Its height is defined
#+begin_src matlab
2019-03-25 18:12:43 +01:00
SP.H = stewart.Aa(1, 3) - BP.H; % [mm]
2019-03-22 12:03:59 +01:00
#+end_src
Its radius is based on the radius on the sphere at the end of the legs.
#+begin_src matlab
SP.R = Leg.R; % [mm]
#+end_src
#+begin_src matlab
SP.section = [0 SP.H-SP.R;
0 0;
SP.R 0;
SP.R SP.H];
#+end_src
The density of its material is defined.
#+begin_src matlab
SP.density = opts.density; % [kg/m^3]
#+end_src
Its color is defined.
#+begin_src matlab
SP.color = [0.7 0.7 0.7]; % [RGB]
#+end_src
The structure is added to the Hexapod structure
#+begin_src matlab
stewart.SP = SP;
#+end_src
2019-03-25 18:12:43 +01:00
* initializeSample
2019-12-19 18:01:32 +01:00
:PROPERTIES:
:HEADER-ARGS:matlab+: :exports code
:HEADER-ARGS:matlab+: :comments no
:HEADER-ARGS:matlab+: :eval no
:HEADER-ARGS:matlab+: :tangle src/initializeSample.m
:END:
2019-03-22 12:03:59 +01:00
2019-03-25 18:12:43 +01:00
** Function description
2019-03-22 12:03:59 +01:00
#+begin_src matlab
2019-03-25 18:12:43 +01:00
function [] = initializeSample(opts_param)
2019-03-22 12:03:59 +01:00
#+end_src
2019-03-25 18:12:43 +01:00
** Optional Parameters
Default values for opts.
2019-03-22 12:03:59 +01:00
#+begin_src matlab
2019-03-25 18:12:43 +01:00
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] ...
);
2019-03-22 12:03:59 +01:00
#+end_src
2019-03-25 18:12:43 +01:00
Populate opts with input parameters
2019-03-22 12:03:59 +01:00
#+begin_src matlab
2019-03-25 18:12:43 +01:00
if exist('opts_param','var')
for opt = fieldnames(opts_param)'
sample.(opt{1}) = opts_param.(opt{1});
2019-03-22 12:03:59 +01:00
end
end
#+end_src
2019-03-25 18:12:43 +01:00
** Save the Sample structure
2019-03-22 12:03:59 +01:00
#+begin_src matlab
2019-03-25 18:12:43 +01:00
save('./mat/sample.mat', 'sample');
2019-03-22 12:03:59 +01:00
#+end_src
#+begin_src matlab
end
#+end_src