432 lines
15 KiB
Org Mode
432 lines
15 KiB
Org Mode
#+TITLE: Stewart Platform - Simscape Model
|
|
:DRAWER:
|
|
#+STARTUP: overview
|
|
|
|
#+LANGUAGE: en
|
|
#+EMAIL: dehaeze.thomas@gmail.com
|
|
#+AUTHOR: Dehaeze Thomas
|
|
|
|
#+HTML_LINK_HOME: ./index.html
|
|
#+HTML_LINK_UP: ./index.html
|
|
|
|
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="https://research.tdehaeze.xyz/css/style.css"/>
|
|
#+HTML_HEAD: <script type="text/javascript" src="https://research.tdehaeze.xyz/js/script.js"></script>
|
|
|
|
#+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+ :noweb yes
|
|
#+PROPERTY: header-args:matlab+ :mkdirp yes
|
|
#+PROPERTY: header-args:matlab+ :output-dir figs
|
|
|
|
#+PROPERTY: header-args:latex :headers '("\\usepackage{tikz}" "\\usepackage{import}" "\\import{$HOME/Cloud/tikz/org/}{config.tex}")
|
|
#+PROPERTY: header-args:latex+ :imagemagick t :fit yes
|
|
#+PROPERTY: header-args:latex+ :iminoptions -scale 100% -density 150
|
|
#+PROPERTY: header-args:latex+ :imoutoptions -quality 100
|
|
#+PROPERTY: header-args:latex+ :results file raw replace
|
|
#+PROPERTY: header-args:latex+ :buffer no
|
|
#+PROPERTY: header-args:latex+ :eval no-export
|
|
#+PROPERTY: header-args:latex+ :exports results
|
|
#+PROPERTY: header-args:latex+ :mkdirp yes
|
|
#+PROPERTY: header-args:latex+ :output-dir figs
|
|
#+PROPERTY: header-args:latex+ :post pdf2svg(file=*this*, ext="png")
|
|
:END:
|
|
|
|
* Introduction :ignore:
|
|
In this document is explained how the Simscape model of the Stewart Platform is implemented.
|
|
|
|
It is divided in the following sections:
|
|
- section [[sec:simscape_parameters]]: is explained how the parameters of the Stewart platform are set for the Simscape model
|
|
- section [[sec:simulink_configuration]]: the Simulink configuration (solver, simulation time, ...) is shared among all the Simulink files. It is explain how this is done.
|
|
- section [[sec:subsystem_reference]]: All the elements (platforms, struts, sensors, ...) are saved in separate files and imported in Simulink files using "subsystem referenced".
|
|
- section [[sec:fixed_mobile_platforms]]: The simscape model for the fixed base and mobile platform are described in this section.
|
|
- section [[sec:struts]]: The simscape model for the Stewart platform struts is described in this section.
|
|
|
|
* Parameters used for the Simscape Model
|
|
<<sec:simscape_parameters>>
|
|
The Simscape Model of the Stewart Platform is working with the =stewart= structure generated using the functions described [[file:stewart-architecture.org][here]].
|
|
|
|
All the geometry and inertia of the mechanical elements are defined in the =stewart= structure.
|
|
|
|
By updating the =stewart= structure in the workspace, the Simscape model will be automatically updated.
|
|
|
|
Thus, nothing should be changed by hand inside the Simscape model.
|
|
|
|
The main advantage to have all the parameters defined in one structure (and not hard-coded in some simulink blocs) it that we can easily change the Stewart architecture/parameters in a Matlab script to perform some parametric study for instance.
|
|
|
|
* Simulation Configuration - Configuration reference
|
|
<<sec:simulink_configuration>>
|
|
As multiple simulink files will be used for simulation and tests, it is very useful to determine good simulation configuration that will be *shared* among all the simulink files.
|
|
|
|
This is done using something called "*Configuration Reference*" ([[https://fr.mathworks.com/help/simulink/ug/more-about-configuration-references.html][documentation]]).
|
|
|
|
Basically, the configuration is stored in a mat file =conf_simscape.mat= and then loaded in the workspace for it to be accessible to all the simulink models.
|
|
It is automatically loaded when the Simulink project is open. It can be loaded manually with the command:
|
|
#+begin_src matlab :eval no
|
|
load('mat/conf_simscape.mat');
|
|
#+end_src
|
|
|
|
It is however possible to modify specific parameters just for one simulation using the =set_param= command:
|
|
#+begin_src matlab :eval no
|
|
set_param(conf_simscape, 'StopTime', 1);
|
|
#+end_src
|
|
|
|
* Subsystem Reference
|
|
<<sec:subsystem_reference>>
|
|
Several Stewart platform models are used, for instance one is use to study the dynamics while the other is used to apply active damping techniques.
|
|
|
|
However, all the Simscape models share some subsystems using the *Subsystem Reference* Simulink block ([[https://fr.mathworks.com/help/simulink/ug/referenced-subsystem-1.html][documentation]]).
|
|
|
|
These shared subsystems are:
|
|
- =Fixed_Based.slx= - Fixed base of the Stewart Platform
|
|
- =Mobile_Platform.slx= - Mobile platform of the Stewart Platform
|
|
- =stewart_strut.slx= - One strut containing two spherical/universal joints, the actuator as well as the included sensors. A parameter =i= is initialized to determine what it the "number" of the strut.
|
|
|
|
These subsystems are referenced from another subsystem called =Stewart_Platform.slx= shown in figure [[fig:simscape_stewart_platform]], that basically connect them correctly.
|
|
This subsystem is then referenced in other simulink models for various purposes (control, analysis, simulation, ...).
|
|
|
|
#+name: fig:simscape_stewart_platform
|
|
#+caption: Simscape Subsystem of the Stewart platform. Encapsulate the Subsystems corresponding to the fixed base, mobile platform and all the struts.
|
|
[[file:figs/simscape_stewart_platform.png]]
|
|
|
|
* Subsystem - Fixed base and Mobile Platform
|
|
<<sec:fixed_mobile_platforms>>
|
|
Both the fixed base and the mobile platform simscape models share many similarities.
|
|
|
|
Their are both composed of:
|
|
- a solid body representing the platform
|
|
- 6 rigid transform blocks to go from the frame $\{F\}$ (resp. $\{M\}$) to the location of the joints.
|
|
These rigid transform are using ${}^F\bm{a}_i$ (resp. ${}^M\bm{b}_i$) for the position of the joint and ${}^F\bm{R}_{a_i}$ (resp. ${}^M\bm{R}_{b_i}$) for the orientation of the joint.
|
|
|
|
As always, the parameters that define the geometry are taken from the =stewart= structure.
|
|
|
|
#+name: fig:simscape_fixed_base
|
|
#+caption: Simscape Model of the Fixed base
|
|
#+attr_html: :width 1000px
|
|
[[file:figs/simscape_fixed_base.png]]
|
|
|
|
#+name: fig:simscape_mobile_platform
|
|
#+caption: Simscape Model of the Mobile platform
|
|
#+attr_html: :width 800px
|
|
[[file:figs/simscape_mobile_platform.png]]
|
|
|
|
* Subsystem - Struts
|
|
<<sec:struts>>
|
|
For the Stewart platform, the 6 struts are identical.
|
|
Thus, all the struts used in the Stewart platform are referring to the same subsystem called =stewart_strut.slx= and shown in Figure [[fig:simscape_strut]].
|
|
|
|
This strut has the following structure:
|
|
- *Universal Joint* connected on the Fixed base
|
|
- *Prismatic Joint* for the actuator
|
|
- *Spherical Joint* connected on the Mobile platform
|
|
|
|
This configuration is called *UPS*.
|
|
|
|
The other common configuration *SPS* has the disadvantage of having additional passive degrees-of-freedom corresponding to the rotation of the strut around its main axis.
|
|
This is why the *UPS* configuration is used, but other configuration can be easily implemented.
|
|
|
|
#+name: fig:simscape_strut
|
|
#+caption: Simscape model of the Stewart platform's strut
|
|
#+attr_html: :width 800px
|
|
[[file:figs/simscape_strut.png]]
|
|
|
|
Several sensors are included in the strut that may or may not be used for control:
|
|
- Relative Displacement sensor: gives the relative displacement of the strut.
|
|
- Force sensor: measure the total force applied by the force actuator, the stiffness and damping forces in the direction of the strut.
|
|
- Inertial sensor: measure the absolute motion (velocity) of the top part of the strut in the direction of the strut.
|
|
|
|
There is two main types of inertial sensor that can be used to measure the absolute motion of the top part of the strut in the direction of the strut:
|
|
- a geophone that measures the absolute velocity above some frequency
|
|
- an accelerometer that measures the absolute acceleration below some frequency
|
|
|
|
Both inertial sensors are described bellow.
|
|
|
|
* Other Elements
|
|
** Payload
|
|
:PROPERTIES:
|
|
:header-args:matlab+: :tangle ../src/initializePayload.m
|
|
:header-args:matlab+: :comments none :mkdirp yes :eval no
|
|
:END:
|
|
<<sec:initializePayload>>
|
|
|
|
This Matlab function is accessible [[file:../src/initializePayload.m][here]].
|
|
|
|
*** Function description
|
|
:PROPERTIES:
|
|
:UNNUMBERED: t
|
|
:END:
|
|
#+begin_src matlab
|
|
function [payload] = initializePayload(args)
|
|
% initializePayload - Initialize the Payload that can then be used for simulations and analysis
|
|
%
|
|
% Syntax: [payload] = initializePayload(args)
|
|
%
|
|
% Inputs:
|
|
% - args - Structure with the following fields:
|
|
% - type - 'none', 'rigid', 'flexible', 'cartesian'
|
|
% - h [1x1] - Height of the CoM of the payload w.r.t {M} [m]
|
|
% This also the position where K and C are defined
|
|
% - K [6x1] - Stiffness of the Payload [N/m, N/rad]
|
|
% - C [6x1] - Damping of the Payload [N/(m/s), N/(rad/s)]
|
|
% - m [1x1] - Mass of the Payload [kg]
|
|
% - I [3x3] - Inertia matrix for the Payload [kg*m2]
|
|
%
|
|
% Outputs:
|
|
% - payload - Struture with the following properties:
|
|
% - type - 1 (none), 2 (rigid), 3 (flexible)
|
|
% - h [1x1] - Height of the CoM of the payload w.r.t {M} [m]
|
|
% - K [6x1] - Stiffness of the Payload [N/m, N/rad]
|
|
% - C [6x1] - Stiffness of the Payload [N/(m/s), N/(rad/s)]
|
|
% - m [1x1] - Mass of the Payload [kg]
|
|
% - I [3x3] - Inertia matrix for the Payload [kg*m2]
|
|
#+end_src
|
|
|
|
*** Optional Parameters
|
|
:PROPERTIES:
|
|
:UNNUMBERED: t
|
|
:END:
|
|
#+begin_src matlab
|
|
arguments
|
|
args.type char {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'cartesian'})} = 'none'
|
|
args.K (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e8*ones(6,1)
|
|
args.C (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
|
|
args.h (1,1) double {mustBeNumeric, mustBeNonnegative} = 100e-3
|
|
args.m (1,1) double {mustBeNumeric, mustBeNonnegative} = 10
|
|
args.I (3,3) double {mustBeNumeric, mustBeNonnegative} = 1*eye(3)
|
|
end
|
|
#+end_src
|
|
|
|
*** Add Payload Type
|
|
:PROPERTIES:
|
|
:UNNUMBERED: t
|
|
:END:
|
|
#+begin_src matlab
|
|
switch args.type
|
|
case 'none'
|
|
payload.type = 1;
|
|
case 'rigid'
|
|
payload.type = 2;
|
|
case 'flexible'
|
|
payload.type = 3;
|
|
case 'cartesian'
|
|
payload.type = 4;
|
|
end
|
|
#+end_src
|
|
|
|
*** Add Stiffness, Damping and Mass properties of the Payload
|
|
:PROPERTIES:
|
|
:UNNUMBERED: t
|
|
:END:
|
|
#+begin_src matlab
|
|
payload.K = args.K;
|
|
payload.C = args.C;
|
|
payload.m = args.m;
|
|
payload.I = args.I;
|
|
|
|
payload.h = args.h;
|
|
#+end_src
|
|
|
|
** Ground
|
|
:PROPERTIES:
|
|
:header-args:matlab+: :tangle ../src/initializeGround.m
|
|
:header-args:matlab+: :comments none :mkdirp yes :eval no
|
|
:END:
|
|
<<sec:initializeGround>>
|
|
|
|
This Matlab function is accessible [[file:../src/initializeGround.m][here]].
|
|
|
|
*** Function description
|
|
:PROPERTIES:
|
|
:UNNUMBERED: t
|
|
:END:
|
|
#+begin_src matlab
|
|
function [ground] = initializeGround(args)
|
|
% initializeGround - Initialize the Ground that can then be used for simulations and analysis
|
|
%
|
|
% Syntax: [ground] = initializeGround(args)
|
|
%
|
|
% Inputs:
|
|
% - args - Structure with the following fields:
|
|
% - type - 'none', 'solid', 'flexible'
|
|
% - rot_point [3x1] - Rotation point for the ground motion [m]
|
|
% - K [3x1] - Translation Stiffness of the Ground [N/m]
|
|
% - C [3x1] - Translation Damping of the Ground [N/(m/s)]
|
|
%
|
|
% Outputs:
|
|
% - ground - Struture with the following properties:
|
|
% - type - 1 (none), 2 (rigid), 3 (flexible)
|
|
% - K [3x1] - Translation Stiffness of the Ground [N/m]
|
|
% - C [3x1] - Translation Damping of the Ground [N/(m/s)]
|
|
#+end_src
|
|
|
|
*** Optional Parameters
|
|
:PROPERTIES:
|
|
:UNNUMBERED: t
|
|
:END:
|
|
#+begin_src matlab
|
|
arguments
|
|
args.type char {mustBeMember(args.type,{'none', 'rigid', 'flexible'})} = 'none'
|
|
args.rot_point (3,1) double {mustBeNumeric} = zeros(3,1)
|
|
args.K (3,1) double {mustBeNumeric, mustBeNonnegative} = 1e8*ones(3,1)
|
|
args.C (3,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(3,1)
|
|
end
|
|
#+end_src
|
|
|
|
*** Add Ground Type
|
|
:PROPERTIES:
|
|
:UNNUMBERED: t
|
|
:END:
|
|
#+begin_src matlab
|
|
switch args.type
|
|
case 'none'
|
|
ground.type = 1;
|
|
case 'rigid'
|
|
ground.type = 2;
|
|
case 'flexible'
|
|
ground.type = 3;
|
|
end
|
|
#+end_src
|
|
|
|
*** Add Stiffness and Damping properties of the Ground
|
|
:PROPERTIES:
|
|
:UNNUMBERED: t
|
|
:END:
|
|
#+begin_src matlab
|
|
ground.K = args.K;
|
|
ground.C = args.C;
|
|
#+end_src
|
|
|
|
*** Rotation Point
|
|
:PROPERTIES:
|
|
:UNNUMBERED: t
|
|
:END:
|
|
#+begin_src matlab
|
|
ground.rot_point = args.rot_point;
|
|
#+end_src
|
|
* Initialize Disturbances
|
|
:PROPERTIES:
|
|
:header-args:matlab+: :tangle ../src/initializeDisturbances.m
|
|
:header-args:matlab+: :comments none :mkdirp yes
|
|
:header-args:matlab+: :eval no :results none
|
|
:END:
|
|
<<sec:initializeDisturbances>>
|
|
|
|
** Function Declaration and Documentation
|
|
:PROPERTIES:
|
|
:UNNUMBERED: t
|
|
:END:
|
|
#+begin_src matlab
|
|
function [disturbances] = initializeDisturbances(args)
|
|
% initializeDisturbances - Initialize the disturbances
|
|
%
|
|
% Syntax: [disturbances] = initializeDisturbances(args)
|
|
%
|
|
% Inputs:
|
|
% - args -
|
|
|
|
#+end_src
|
|
|
|
** Optional Parameters
|
|
:PROPERTIES:
|
|
:UNNUMBERED: t
|
|
:END:
|
|
#+begin_src matlab
|
|
arguments
|
|
args.Fd double {mustBeNumeric, mustBeReal} = zeros(6,1)
|
|
args.Fd_t double {mustBeNumeric, mustBeReal} = 0
|
|
args.Dw double {mustBeNumeric, mustBeReal} = zeros(6,1)
|
|
args.Dw_t double {mustBeNumeric, mustBeReal} = 0
|
|
end
|
|
#+end_src
|
|
|
|
|
|
** Structure initialization
|
|
:PROPERTIES:
|
|
:UNNUMBERED: t
|
|
:END:
|
|
#+begin_src matlab
|
|
disturbances = struct();
|
|
#+end_src
|
|
|
|
** Ground Motion
|
|
:PROPERTIES:
|
|
:UNNUMBERED: t
|
|
:END:
|
|
#+begin_src matlab
|
|
disturbances.Dw = timeseries([args.Dw], args.Dw_t);
|
|
#+end_src
|
|
|
|
** Direct Forces
|
|
:PROPERTIES:
|
|
:UNNUMBERED: t
|
|
:END:
|
|
#+begin_src matlab
|
|
disturbances.Fd = timeseries([args.Fd], args.Fd_t);
|
|
#+end_src
|
|
|
|
* Initialize References
|
|
:PROPERTIES:
|
|
:header-args:matlab+: :tangle ../src/initializeReferences.m
|
|
:header-args:matlab+: :comments none :mkdirp yes
|
|
:header-args:matlab+: :eval no :results none
|
|
:END:
|
|
<<sec:initializeReferences>>
|
|
|
|
** Function Declaration and Documentation
|
|
:PROPERTIES:
|
|
:UNNUMBERED: t
|
|
:END:
|
|
#+begin_src matlab
|
|
function [references] = initializeReferences(stewart, args)
|
|
% initializeReferences - Initialize the references
|
|
%
|
|
% Syntax: [references] = initializeReferences(args)
|
|
%
|
|
% Inputs:
|
|
% - args -
|
|
|
|
#+end_src
|
|
|
|
** Optional Parameters
|
|
:PROPERTIES:
|
|
:UNNUMBERED: t
|
|
:END:
|
|
#+begin_src matlab
|
|
arguments
|
|
stewart
|
|
args.t double {mustBeNumeric, mustBeReal} = 0
|
|
args.r double {mustBeNumeric, mustBeReal} = zeros(6, 1)
|
|
end
|
|
#+end_src
|
|
|
|
** Compute the corresponding strut length
|
|
#+begin_src matlab
|
|
rL = zeros(6, length(args.t));
|
|
|
|
for i = 1:length(args.t)
|
|
R = [cos(args.r(6,i)) -sin(args.r(6,i)) 0;
|
|
sin(args.r(6,i)) cos(args.r(6,i)) 0;
|
|
0 0 1] * ...
|
|
[cos(args.r(5,i)) 0 sin(args.r(5,i));
|
|
0 1 0;
|
|
-sin(args.r(5,i)) 0 cos(args.r(5,i))] * ...
|
|
[1 0 0;
|
|
0 cos(args.r(4,i)) -sin(args.r(4,i));
|
|
0 sin(args.r(4,i)) cos(args.r(4,i))];
|
|
|
|
[Li, dLi] = inverseKinematics(stewart, 'AP', [args.r(1,i); args.r(2,i); args.r(3,i)], 'ARB', R);
|
|
rL(:, i) = dLi;
|
|
end
|
|
#+end_src
|
|
|
|
** References
|
|
:PROPERTIES:
|
|
:UNNUMBERED: t
|
|
:END:
|
|
#+begin_src matlab
|
|
references.r = timeseries(args.r, args.t);
|
|
references.rL = timeseries(rL, args.t);
|
|
#+end_src
|