2019-12-11 17:09:32 +01:00
#+TITLE : Subsystems used for the Simscape Models
2020-04-17 10:25:44 +02:00
#+SETUPFILE : ./setup/org-setup-file.org
2019-12-11 17:09:32 +01:00
2020-02-03 17:50:32 +01:00
* Introduction :ignore:
The full Simscape Model is represented in Figure [[fig:simscape_picture ]].
#+name : fig:simscape_picture
#+caption : Screenshot of the Multi-Body Model representation
[[file:figs/images/simscape_picture.png ]]
This model is divided into multiple subsystems that are independent.
These subsystems are saved in separate files and imported in the main file using a block balled "subsystem reference".
Each stage is configured (geometry, mass properties, dynamic properties ...) using one function.
These functions are defined below.
2020-02-17 18:21:20 +01:00
* Simscape Configuration
:PROPERTIES:
:header-args:matlab+: :tangle ../src/initializeSimscapeConfiguration.m
:header-args:matlab+: :comments none :mkdirp yes :eval no
:END:
<<sec:initializeSimscapeConfiguration >>
** Function description
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
function [] = initializeSimscapeConfiguration(args)
#+end_src
** Optional Parameters
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
arguments
args.gravity logical {mustBeNumericOrLogical} = true
end
#+end_src
** Structure initialization
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
conf_simscape = struct();
#+end_src
** Add Type
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
if args.gravity
conf_simscape.type = 1;
else
conf_simscape.type = 2;
end
#+end_src
** Save the Structure
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
save('./mat/conf_simscape.mat', 'conf_simscape');
#+end_src
2020-02-18 11:33:04 +01:00
* Logging Configuration
:PROPERTIES:
:header-args:matlab+: :tangle ../src/initializeLoggingConfiguration.m
:header-args:matlab+: :comments none :mkdirp yes :eval no
:END:
<<sec:initializeLoggingConfiguration >>
** Function description
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
function [] = initializeLoggingConfiguration(args)
#+end_src
** Optional Parameters
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
arguments
2020-02-25 17:49:08 +01:00
args.log char {mustBeMember(args.log,{'none', 'all', 'forces'})} = 'none'
2020-02-18 11:33:04 +01:00
args.Ts (1,1) double {mustBeNumeric, mustBePositive} = 1e-3
end
#+end_src
** Structure initialization
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
conf_log = struct();
#+end_src
** Add Type
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
switch args.log
case 'none'
conf_log.type = 0;
case 'all'
conf_log.type = 1;
2020-02-25 17:49:08 +01:00
case 'forces'
conf_log.type = 2;
2020-02-18 11:33:04 +01:00
end
#+end_src
** Sampling Time
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
conf_log.Ts = args.Ts;
#+end_src
** Save the Structure
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
save('./mat/conf_log.mat', 'conf_log');
#+end_src
2020-02-03 17:50:32 +01:00
* Ground
:PROPERTIES:
:header-args:matlab+: :tangle ../src/initializeGround.m
:header-args:matlab+: :comments none :mkdirp yes :eval no
:END:
<<sec:initializeGround >>
** Simscape Model
:PROPERTIES:
:UNNUMBERED: t
:END:
The model of the Ground is composed of:
- A *Cartesian* joint that is used to simulation the ground motion
- A solid that represents the ground on which the granite is located
#+name : fig:simscape_model_ground
#+attr_org : :width 800
#+caption : Simscape model for the Ground
[[file:figs/images/simscape_model_ground.png ]]
#+name : fig:simscape_picture_ground
#+attr_org : :width 800
#+caption : Simscape picture for the Ground
[[file:figs/images/simscape_picture_ground.png ]]
** Function description
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
2020-02-17 18:21:20 +01:00
function [ground] = initializeGround(args)
2020-02-03 17:50:32 +01:00
#+end_src
2020-02-17 18:21:20 +01:00
** Optional Parameters
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
arguments
2020-03-13 17:40:22 +01:00
args.type char {mustBeMember(args.type,{'none', 'rigid'})} = 'rigid'
args.rot_point (3,1) double {mustBeNumeric} = zeros(3,1) % Rotation point for the ground motion [m]
2020-02-17 18:21:20 +01:00
end
#+end_src
** Structure initialization
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-03 17:50:32 +01:00
First, we initialize the =granite= structure.
#+begin_src matlab
ground = struct();
#+end_src
2020-02-17 18:21:20 +01:00
** Add Type
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
switch args.type
case 'none'
ground.type = 0;
2020-02-18 16:46:35 +01:00
case 'rigid'
2020-02-17 18:21:20 +01:00
ground.type = 1;
end
#+end_src
** Ground Solid properties
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-03 17:50:32 +01:00
We set the shape and density of the ground solid element.
#+begin_src matlab
2020-02-17 18:21:20 +01:00
ground.shape = [2, 2, 0.5]; % [m]
ground.density = 2800; % [kg/m3]
2020-02-03 17:50:32 +01:00
#+end_src
2020-03-13 17:40:22 +01:00
** Rotation Point
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
ground.rot_point = args.rot_point;
#+end_src
2020-02-17 18:21:20 +01:00
** Save the Structure
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-03 17:50:32 +01:00
The =ground= structure is saved.
#+begin_src matlab
save('./mat/stages.mat', 'ground', '-append');
#+end_src
* Granite
:PROPERTIES:
:header-args:matlab+: :tangle ../src/initializeGranite.m
:header-args:matlab+: :comments none :mkdirp yes :eval no
:END:
<<sec:initializeGranite >>
** Simscape Model
:PROPERTIES:
:UNNUMBERED: t
:END:
The Simscape model of the granite is composed of:
- A cartesian joint such that the granite can vibrations along x, y and z axis
- A solid
The output =sample_pos= corresponds to the impact point of the X-ray.
#+name : fig:simscape_model_granite
#+attr_org : :width 800
#+caption : Simscape model for the Granite
[[file:figs/images/simscape_model_granite.png ]]
#+name : fig:simscape_picture_granite
#+attr_org : :width 800
#+caption : Simscape picture for the Granite
[[file:figs/images/simscape_picture_granite.png ]]
** Function description
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
function [granite] = initializeGranite(args)
#+end_src
** Optional Parameters
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
2020-02-17 18:21:20 +01:00
arguments
2020-02-25 17:49:08 +01:00
args.type char {mustBeMember(args.type,{'rigid', 'flexible', 'none', 'modal-analysis', 'init'})} = 'flexible'
2020-03-17 11:22:57 +01:00
args.Foffset logical {mustBeNumericOrLogical} = false
2020-02-17 18:21:20 +01:00
args.density (1,1) double {mustBeNumeric, mustBeNonnegative} = 2800 % Density [kg/m3]
2020-04-07 15:26:29 +02:00
args.K (3,1) double {mustBeNumeric, mustBeNonnegative} = [4e9; 3e8; 8e8] % [N/m]
args.C (3,1) double {mustBeNumeric, mustBeNonnegative} = [4.0e5; 1.1e5; 9.0e5] % [N/(m/s)]
2020-02-17 18:21:20 +01:00
args.x0 (1,1) double {mustBeNumeric} = 0 % Rest position of the Joint in the X direction [m]
args.y0 (1,1) double {mustBeNumeric} = 0 % Rest position of the Joint in the Y direction [m]
args.z0 (1,1) double {mustBeNumeric} = 0 % Rest position of the Joint in the Z direction [m]
2020-11-03 09:45:50 +01:00
args.sample_pos (1,1) double {mustBeNumeric} = 0.8 % Height of the measurment point [m]
2020-02-17 18:21:20 +01:00
end
2020-02-03 17:50:32 +01:00
#+end_src
2020-02-17 18:21:20 +01:00
** Structure initialization
2020-02-03 17:50:32 +01:00
:PROPERTIES:
:UNNUMBERED: t
:END:
First, we initialize the =granite= structure.
#+begin_src matlab
granite = struct();
#+end_src
2020-02-17 18:21:20 +01:00
** Add Granite Type
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
switch args.type
case 'none'
granite.type = 0;
case 'rigid'
granite.type = 1;
case 'flexible'
granite.type = 2;
2020-02-18 16:46:35 +01:00
case 'modal-analysis'
granite.type = 3;
2020-02-25 17:49:08 +01:00
case 'init'
granite.type = 4;
2020-02-17 18:21:20 +01:00
end
#+end_src
2020-02-25 17:49:08 +01:00
** Material and Geometry
2020-02-17 18:21:20 +01:00
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-25 17:49:08 +01:00
2020-02-03 17:50:32 +01:00
Properties of the Material and link to the geometry of the granite.
#+begin_src matlab
granite.density = args.density; % [kg/m3]
granite.STEP = './STEPS/granite/granite.STEP';
#+end_src
2020-02-25 17:49:08 +01:00
Z-offset for the initial position of the sample with respect to the granite top surface.
2020-02-03 17:50:32 +01:00
#+begin_src matlab
2020-11-03 09:45:50 +01:00
granite.sample_pos = args.sample_pos; % [m]
2020-02-03 17:50:32 +01:00
#+end_src
2020-02-25 17:49:08 +01:00
** Stiffness and Damping properties
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-03 17:50:32 +01:00
#+begin_src matlab
2020-04-07 15:26:29 +02:00
granite.K = args.K; % [N/m]
granite.C = args.C; % [N/(m/s)]
2020-02-03 17:50:32 +01:00
#+end_src
2020-02-25 17:49:08 +01:00
** Equilibrium position of the each joint.
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-03 17:50:32 +01:00
#+begin_src matlab
2020-02-25 17:49:08 +01:00
if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
load('mat/Foffset.mat', 'Fgm');
granite.Deq = -Fgm'./granite.K;
else
granite.Deq = zeros(6,1);
end
2020-02-03 17:50:32 +01:00
#+end_src
2020-02-17 18:21:20 +01:00
** Save the Structure
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-03 17:50:32 +01:00
The =granite= structure is saved.
#+begin_src matlab
save('./mat/stages.mat', 'granite', '-append');
#+end_src
* Translation Stage
:PROPERTIES:
:header-args:matlab+: :tangle ../src/initializeTy.m
:header-args:matlab+: :comments none :mkdirp yes :eval no
:END:
<<sec:initializeTy >>
** Simscape Model
:PROPERTIES:
:UNNUMBERED: t
:END:
The Simscape model of the Translation stage consist of:
- One rigid body for the fixed part of the translation stage
- One rigid body for the moving part of the translation stage
- Four 6-DOF Joints that only have some rigidity in the X and Z directions.
The rigidity in rotation comes from the fact that we use multiple joints that are located at different points
- One 6-DOF joint that represent the Actuator.
It is used to impose the motion in the Y direction
- One 6-DOF joint to inject force disturbance in the X and Z directions
#+name : fig:simscape_model_ty
#+ATTR_ORG : :width 800
#+caption : Simscape model for the Translation Stage
[[file:figs/images/simscape_model_ty.png ]]
#+name : fig:simscape_picture_ty
#+attr_org : :width 800
#+caption : Simscape picture for the Translation Stage
[[file:figs/images/simscape_picture_ty.png ]]
** Function description
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
function [ty] = initializeTy(args)
#+end_src
** Optional Parameters
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
arguments
2020-02-25 17:49:08 +01:00
args.type char {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init'})} = 'flexible'
2020-03-17 11:22:57 +01:00
args.Foffset logical {mustBeNumericOrLogical} = false
2020-02-03 17:50:32 +01:00
end
#+end_src
2020-02-17 18:21:20 +01:00
** Structure initialization
2020-02-03 17:50:32 +01:00
:PROPERTIES:
:UNNUMBERED: t
:END:
First, we initialize the =ty= structure.
#+begin_src matlab
ty = struct();
#+end_src
2020-02-17 18:21:20 +01:00
** Add Translation Stage Type
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
switch args.type
case 'none'
ty.type = 0;
case 'rigid'
ty.type = 1;
case 'flexible'
ty.type = 2;
2020-02-18 16:46:35 +01:00
case 'modal-analysis'
ty.type = 3;
2020-02-25 17:49:08 +01:00
case 'init'
ty.type = 4;
2020-02-17 18:21:20 +01:00
end
#+end_src
2020-02-25 17:49:08 +01:00
** Material and Geometry
2020-02-17 18:21:20 +01:00
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-03 17:50:32 +01:00
Define the density of the materials as well as the geometry (STEP files).
#+begin_src matlab
% Ty Granite frame
ty.granite_frame.density = 7800; % [kg/m3] = > 43kg
ty.granite_frame.STEP = './STEPS/Ty/Ty_Granite_Frame.STEP';
% Guide Translation Ty
ty.guide.density = 7800; % [kg/m3] = > 76kg
ty.guide.STEP = './STEPS/ty/Ty_Guide.STEP';
% Ty - Guide_Translation12
ty.guide12.density = 7800; % [kg/m3]
ty.guide12.STEP = './STEPS/Ty/Ty_Guide_12.STEP';
% Ty - Guide_Translation11
ty.guide11.density = 7800; % [kg/m3]
ty.guide11.STEP = './STEPS/ty/Ty_Guide_11.STEP';
% Ty - Guide_Translation22
ty.guide22.density = 7800; % [kg/m3]
ty.guide22.STEP = './STEPS/ty/Ty_Guide_22.STEP';
% Ty - Guide_Translation21
ty.guide21.density = 7800; % [kg/m3]
ty.guide21.STEP = './STEPS/Ty/Ty_Guide_21.STEP';
% Ty - Plateau translation
ty.frame.density = 7800; % [kg/m3]
ty.frame.STEP = './STEPS/ty/Ty_Stage.STEP';
% Ty Stator Part
ty.stator.density = 5400; % [kg/m3]
ty.stator.STEP = './STEPS/ty/Ty_Motor_Stator.STEP';
% Ty Rotor Part
ty.rotor.density = 5400; % [kg/m3]
ty.rotor.STEP = './STEPS/ty/Ty_Motor_Rotor.STEP';
#+end_src
2020-02-25 17:49:08 +01:00
** Stiffness and Damping properties
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-03 17:50:32 +01:00
#+begin_src matlab
2020-02-25 17:49:08 +01:00
ty.K = [2e8; 1e8; 2e8; 6e7; 9e7; 6e7]; % [N/m, N*m/rad]
ty.C = [8e4; 5e4; 8e4; 2e4; 3e4; 2e4]; % [N/(m/s), N*m/ (rad/s)]
2020-02-03 17:50:32 +01:00
#+end_src
2020-02-25 17:49:08 +01:00
** Equilibrium position of the each joint.
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-03 17:50:32 +01:00
#+begin_src matlab
2020-02-25 17:49:08 +01:00
if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
load('mat/Foffset.mat', 'Ftym');
ty.Deq = -Ftym'./ty.K;
else
ty.Deq = zeros(6,1);
end
2020-02-03 17:50:32 +01:00
#+end_src
2020-02-17 18:21:20 +01:00
** Save the Structure
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-03 17:50:32 +01:00
The =ty= structure is saved.
#+begin_src matlab
save('./mat/stages.mat', 'ty', '-append');
#+end_src
* Tilt Stage
:PROPERTIES:
:header-args:matlab+: :tangle ../src/initializeRy.m
:header-args:matlab+: :comments none :mkdirp yes :eval no
:END:
<<sec:initializeRy >>
** Simscape Model
:PROPERTIES:
:UNNUMBERED: t
:END:
The Simscape model of the Tilt stage is composed of:
- Two solid bodies for the two part of the stage
- *Four* 6-DOF joints to model the flexibility of the stage.
These joints are virtually located along the rotation axis and are connecting the two solid bodies.
These joints have some translation stiffness in the u-v-w directions aligned with the joint.
The stiffness in rotation between the two solids is due to the fact that the 4 joints are connecting the two solids are different locations
- A Bushing Joint used for the Actuator.
The Ry motion is imposed by the input.
#+name : fig:simscape_model_ry
#+attr_org : :width 800
#+caption : Simscape model for the Tilt Stage
[[file:figs/images/simscape_model_ry.png ]]
#+name : fig:simscape_picture_ry
#+attr_org : :width 800
#+caption : Simscape picture for the Tilt Stage
[[file:figs/images/simscape_picture_ry.png ]]
** Function description
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
function [ry] = initializeRy(args)
#+end_src
** Optional Parameters
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
arguments
2020-02-25 17:49:08 +01:00
args.type char {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init'})} = 'flexible'
2020-03-17 11:22:57 +01:00
args.Foffset logical {mustBeNumericOrLogical} = false
2020-02-25 17:49:08 +01:00
args.Ry_init (1,1) double {mustBeNumeric} = 0
2020-02-03 17:50:32 +01:00
end
#+end_src
2020-02-17 18:21:20 +01:00
** Structure initialization
2020-02-03 17:50:32 +01:00
:PROPERTIES:
:UNNUMBERED: t
:END:
First, we initialize the =ry= structure.
#+begin_src matlab
ry = struct();
#+end_src
2020-02-17 18:21:20 +01:00
** Add Tilt Type
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
switch args.type
case 'none'
ry.type = 0;
case 'rigid'
ry.type = 1;
case 'flexible'
ry.type = 2;
2020-02-18 16:46:35 +01:00
case 'modal-analysis'
ry.type = 3;
2020-02-25 17:49:08 +01:00
case 'init'
ry.type = 4;
2020-02-17 18:21:20 +01:00
end
#+end_src
2020-02-25 17:49:08 +01:00
** Material and Geometry
2020-02-17 18:21:20 +01:00
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-03 17:50:32 +01:00
Properties of the Material and link to the geometry of the Tilt stage.
#+begin_src matlab
% Ry - Guide for the tilt stage
ry.guide.density = 7800; % [kg/m3]
ry.guide.STEP = './STEPS/ry/Tilt_Guide.STEP';
% Ry - Rotor of the motor
ry.rotor.density = 2400; % [kg/m3]
ry.rotor.STEP = './STEPS/ry/Tilt_Motor_Axis.STEP';
% Ry - Motor
ry.motor.density = 3200; % [kg/m3]
ry.motor.STEP = './STEPS/ry/Tilt_Motor.STEP';
% Ry - Plateau Tilt
ry.stage.density = 7800; % [kg/m3]
ry.stage.STEP = './STEPS/ry/Tilt_Stage.STEP';
#+end_src
2020-02-25 17:49:08 +01:00
Z-Offset so that the center of rotation matches the sample center;
2020-02-03 17:50:32 +01:00
#+begin_src matlab
2020-02-25 17:49:08 +01:00
ry.z_offset = 0.58178; % [m]
2020-02-03 17:50:32 +01:00
#+end_src
#+begin_src matlab
2020-02-25 17:49:08 +01:00
ry.Ry_init = args.Ry_init; % [rad]
2020-02-03 17:50:32 +01:00
#+end_src
2020-02-25 17:49:08 +01:00
** Stiffness and Damping properties
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-03 17:50:32 +01:00
#+begin_src matlab
2020-02-25 17:49:08 +01:00
ry.K = [3.8e8; 4e8; 3.8e8; 1.2e8; 6e4; 1.2e8];
ry.C = [1e5; 1e5; 1e5; 3e4; 1e3; 3e4];
2020-02-03 17:50:32 +01:00
#+end_src
2020-02-25 17:49:08 +01:00
** Equilibrium position of the each joint.
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-03 17:50:32 +01:00
#+begin_src matlab
2020-02-25 17:49:08 +01:00
if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
load('mat/Foffset.mat', 'Fym');
ry.Deq = -Fym'./ry.K;
else
ry.Deq = zeros(6,1);
end
2020-02-03 17:50:32 +01:00
#+end_src
2020-02-17 18:21:20 +01:00
** Save the Structure
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-25 17:49:08 +01:00
The =ry= structure is saved.
2020-02-03 17:50:32 +01:00
#+begin_src matlab
save('./mat/stages.mat', 'ry', '-append');
#+end_src
* Spindle
:PROPERTIES:
:header-args:matlab+: :tangle ../src/initializeRz.m
:header-args:matlab+: :comments none :mkdirp yes :eval no
:END:
<<sec:initializeRz >>
** Simscape Model
:PROPERTIES:
:UNNUMBERED: t
:END:
The Simscape model of the Spindle is composed of:
- Two rigid bodies: the stator and the rotor
- A Bushing Joint that is used both as the actuator (the Rz motion is imposed by the input) and as the force perturbation in the Z direction.
- The Bushing joint has some flexibility in the X-Y-Z directions as well as in Rx and Ry rotations
#+name : fig:simscape_model_rz
#+attr_org : :width 800
#+caption : Simscape model for the Spindle
[[file:figs/images/simscape_model_rz.png ]]
#+name : fig:simscape_picture_rz
#+attr_org : :width 800
#+caption : Simscape picture for the Spindle
[[file:figs/images/simscape_picture_rz.png ]]
** Function description
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
function [rz] = initializeRz(args)
#+end_src
** Optional Parameters
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
arguments
2020-02-25 17:49:08 +01:00
args.type char {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init'})} = 'flexible'
2020-03-17 11:22:57 +01:00
args.Foffset logical {mustBeNumericOrLogical} = false
2020-02-03 17:50:32 +01:00
end
#+end_src
2020-02-17 18:21:20 +01:00
** Structure initialization
2020-02-03 17:50:32 +01:00
:PROPERTIES:
:UNNUMBERED: t
:END:
First, we initialize the =rz= structure.
#+begin_src matlab
rz = struct();
#+end_src
2020-02-17 18:21:20 +01:00
** Add Spindle Type
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
switch args.type
case 'none'
rz.type = 0;
case 'rigid'
rz.type = 1;
case 'flexible'
rz.type = 2;
2020-02-18 16:46:35 +01:00
case 'modal-analysis'
rz.type = 3;
2020-02-25 17:49:08 +01:00
case 'init'
rz.type = 4;
2020-02-17 18:21:20 +01:00
end
#+end_src
2020-02-25 17:49:08 +01:00
** Material and Geometry
2020-02-17 18:21:20 +01:00
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-25 17:49:08 +01:00
2020-02-03 17:50:32 +01:00
Properties of the Material and link to the geometry of the spindle.
#+begin_src matlab
% Spindle - Slip Ring
rz.slipring.density = 7800; % [kg/m3]
rz.slipring.STEP = './STEPS/rz/Spindle_Slip_Ring.STEP';
% Spindle - Rotor
rz.rotor.density = 7800; % [kg/m3]
rz.rotor.STEP = './STEPS/rz/Spindle_Rotor.STEP';
% Spindle - Stator
rz.stator.density = 7800; % [kg/m3]
rz.stator.STEP = './STEPS/rz/Spindle_Stator.STEP';
#+end_src
2020-02-25 17:49:08 +01:00
** Stiffness and Damping properties
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-03 17:50:32 +01:00
#+begin_src matlab
2020-02-25 17:49:08 +01:00
rz.K = [7e8; 7e8; 2e9; 1e7; 1e7; 1e7];
rz.C = [4e4; 4e4; 7e4; 1e4; 1e4; 1e4];
2020-02-03 17:50:32 +01:00
#+end_src
2020-02-25 17:49:08 +01:00
** Equilibrium position of the each joint.
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-03 17:50:32 +01:00
#+begin_src matlab
2020-02-25 17:49:08 +01:00
if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
load('mat/Foffset.mat', 'Fzm');
rz.Deq = -Fzm'./rz.K;
else
rz.Deq = zeros(6,1);
end
2020-02-03 17:50:32 +01:00
#+end_src
2020-02-17 18:21:20 +01:00
** Save the Structure
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-03 17:50:32 +01:00
The =rz= structure is saved.
#+begin_src matlab
save('./mat/stages.mat', 'rz', '-append');
#+end_src
* Micro Hexapod
:PROPERTIES:
:header-args:matlab+: :tangle ../src/initializeMicroHexapod.m
:header-args:matlab+: :comments none :mkdirp yes :eval no
:END:
<<sec:initializeMicroHexapod >>
** Simscape Model
:PROPERTIES:
:UNNUMBERED: t
:END:
#+name : fig:simscape_model_micro_hexapod
#+attr_org : :width 800
#+caption : Simscape model for the Micro-Hexapod
[[file:figs/images/simscape_model_micro_hexapod.png ]]
#+name : fig:simscape_picture_micro_hexapod
#+attr_org : :width 800
#+caption : Simscape picture for the Micro-Hexapod
[[file:figs/images/simscape_picture_micro_hexapod.png ]]
** Function description
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
function [micro_hexapod] = initializeMicroHexapod(args)
#+end_src
** Optional Parameters
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
arguments
2020-03-31 11:38:15 +02:00
args.type char {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init', 'compliance'})} = 'flexible'
2020-02-03 17:50:32 +01:00
% initializeFramesPositions
args.H (1,1) double {mustBeNumeric, mustBePositive} = 350e-3
args.MO_B (1,1) double {mustBeNumeric} = 270e-3
% generateGeneralConfiguration
args.FH (1,1) double {mustBeNumeric, mustBePositive} = 50e-3
args.FR (1,1) double {mustBeNumeric, mustBePositive} = 175.5e-3
args.FTh (6,1) double {mustBeNumeric} = [-10, 10, 120-10, 120+10, 240-10, 240+10]*(pi/180)
args.MH (1,1) double {mustBeNumeric, mustBePositive} = 45e-3
args.MR (1,1) double {mustBeNumeric, mustBePositive} = 118e-3
args.MTh (6,1) double {mustBeNumeric} = [-60+10, 60-10, 60+10, 180-10, 180+10, -60-10]*(pi/180)
% initializeStrutDynamics
args.Ki (6,1) double {mustBeNumeric, mustBeNonnegative} = 2e7*ones(6,1)
args.Ci (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.4e3*ones(6,1)
% initializeCylindricalPlatforms
args.Fpm (1,1) double {mustBeNumeric, mustBePositive} = 10
args.Fph (1,1) double {mustBeNumeric, mustBePositive} = 26e-3
args.Fpr (1,1) double {mustBeNumeric, mustBePositive} = 207.5e-3
args.Mpm (1,1) double {mustBeNumeric, mustBePositive} = 10
args.Mph (1,1) double {mustBeNumeric, mustBePositive} = 26e-3
args.Mpr (1,1) double {mustBeNumeric, mustBePositive} = 150e-3
% initializeCylindricalStruts
args.Fsm (1,1) double {mustBeNumeric, mustBePositive} = 1
args.Fsh (1,1) double {mustBeNumeric, mustBePositive} = 100e-3
args.Fsr (1,1) double {mustBeNumeric, mustBePositive} = 25e-3
args.Msm (1,1) double {mustBeNumeric, mustBePositive} = 1
args.Msh (1,1) double {mustBeNumeric, mustBePositive} = 100e-3
args.Msr (1,1) double {mustBeNumeric, mustBePositive} = 25e-3
% inverseKinematics
args.AP (3,1) double {mustBeNumeric} = zeros(3,1)
args.ARB (3,3) double {mustBeNumeric} = eye(3)
2020-02-25 17:49:08 +01:00
% Force that stiffness of each joint should apply at t=0
2020-03-17 11:22:57 +01:00
args.Foffset logical {mustBeNumericOrLogical} = false
2020-02-03 17:50:32 +01:00
end
#+end_src
** Function content
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
2020-05-04 12:03:08 +02:00
stewart = initializeStewartPlatform();
stewart = initializeFramesPositions(stewart, ...
'H', args.H, ...
'MO_B', args.MO_B);
stewart = generateGeneralConfiguration(stewart, ...
'FH', args.FH, ...
'FR', args.FR, ...
'FTh', args.FTh, ...
'MH', args.MH, ...
'MR', args.MR, ...
'MTh', args.MTh);
stewart = computeJointsPose(stewart);
#+end_src
#+begin_src matlab
stewart = initializeStrutDynamics(stewart, ...
'K', args.Ki, ...
'C', args.Ci);
stewart = initializeJointDynamics(stewart, ...
'type_F', 'universal_p', ...
'type_M', 'spherical_p');
#+end_src
#+begin_src matlab
stewart = initializeCylindricalPlatforms(stewart, ...
'Fpm', args.Fpm, ...
'Fph', args.Fph, ...
'Fpr', args.Fpr, ...
'Mpm', args.Mpm, ...
'Mph', args.Mph, ...
'Mpr', args.Mpr);
stewart = initializeCylindricalStruts(stewart, ...
'Fsm', args.Fsm, ...
'Fsh', args.Fsh, ...
'Fsr', args.Fsr, ...
'Msm', args.Msm, ...
'Msh', args.Msh, ...
'Msr', args.Msr);
stewart = computeJacobian(stewart);
stewart = initializeStewartPose(stewart, ...
'AP', args.AP, ...
'ARB', args.ARB);
#+end_src
#+begin_src matlab
stewart = initializeInertialSensor(stewart, 'type', 'none');
2020-02-03 17:50:32 +01:00
#+end_src
Equilibrium position of the each joint.
#+begin_src matlab
2020-02-25 17:49:08 +01:00
if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
load('mat/Foffset.mat', 'Fhm');
2020-05-04 12:03:08 +02:00
stewart.actuators.dLeq = -Fhm'./args.Ki;
2020-02-25 17:49:08 +01:00
else
2020-05-04 12:03:08 +02:00
stewart.actuators.dLeq = zeros(6,1);
2020-02-25 17:49:08 +01:00
end
2020-02-03 17:50:32 +01:00
#+end_src
2020-02-18 16:46:35 +01:00
** Add Type
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
switch args.type
case 'none'
2020-05-04 12:03:08 +02:00
stewart.type = 0;
2020-02-18 16:46:35 +01:00
case 'rigid'
2020-05-04 12:03:08 +02:00
stewart.type = 1;
2020-02-18 16:46:35 +01:00
case 'flexible'
2020-05-04 12:03:08 +02:00
stewart.type = 2;
2020-02-18 17:30:27 +01:00
case 'modal-analysis'
2020-05-04 12:03:08 +02:00
stewart.type = 3;
2020-02-25 17:49:08 +01:00
case 'init'
2020-05-04 12:03:08 +02:00
stewart.type = 4;
2020-03-31 11:38:15 +02:00
case 'compliance'
2020-05-04 12:03:08 +02:00
stewart.type = 5;
2020-02-18 16:46:35 +01:00
end
#+end_src
2020-02-17 18:21:20 +01:00
** Save the Structure
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-03 17:50:32 +01:00
The =micro_hexapod= structure is saved.
#+begin_src matlab
2020-05-04 12:03:08 +02:00
micro_hexapod = stewart;
2020-02-03 17:50:32 +01:00
save('./mat/stages.mat', 'micro_hexapod', '-append');
#+end_src
* Center of gravity compensation
:PROPERTIES:
:header-args:matlab+: :tangle ../src/initializeAxisc.m
:header-args:matlab+: :comments none :mkdirp yes :eval no
:END:
<<sec:initializeAxisc >>
** Simscape Model
:PROPERTIES:
:UNNUMBERED: t
:END:
The Simscape model of the Center of gravity compensator is composed of:
- One main solid that is connected to two other solids (the masses to position of center of mass) through two revolute joints
- The angle of both revolute joints is set by the input
#+name : fig:simscape_model_axisc
#+attr_org : :width 800
#+caption : Simscape model for the Center of Mass compensation system
[[file:figs/images/simscape_model_axisc.png ]]
#+name : fig:simscape_picture_axisc
#+attr_org : :width 800
#+caption : Simscape picture for the Center of Mass compensation system
[[file:figs/images/simscape_picture_axisc.png ]]
** Function description
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
2020-02-17 18:21:20 +01:00
function [axisc] = initializeAxisc(args)
2020-02-03 17:50:32 +01:00
#+end_src
** Optional Parameters
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-17 18:21:20 +01:00
#+begin_src matlab
arguments
2020-02-18 17:30:27 +01:00
args.type char {mustBeMember(args.type,{'none', 'rigid', 'flexible'})} = 'flexible'
2020-02-17 18:21:20 +01:00
end
#+end_src
2020-02-03 17:50:32 +01:00
2020-02-17 18:21:20 +01:00
** Structure initialization
2020-02-03 17:50:32 +01:00
:PROPERTIES:
:UNNUMBERED: t
:END:
First, we initialize the =axisc= structure.
#+begin_src matlab
axisc = struct();
#+end_src
2020-02-17 18:21:20 +01:00
** Add Type
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
switch args.type
case 'none'
axisc.type = 0;
case 'rigid'
axisc.type = 1;
case 'flexible'
axisc.type = 2;
end
#+end_src
2020-02-25 17:49:08 +01:00
** Material and Geometry
2020-02-17 18:21:20 +01:00
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-25 17:49:08 +01:00
2020-02-03 17:50:32 +01:00
Properties of the Material and link to the geometry files.
#+begin_src matlab
% Structure
axisc.structure.density = 3400; % [kg/m3]
axisc.structure.STEP = './STEPS/axisc/axisc_structure.STEP';
% Wheel
axisc.wheel.density = 2700; % [kg/m3]
axisc.wheel.STEP = './STEPS/axisc/axisc_wheel.STEP';
% Mass
axisc.mass.density = 7800; % [kg/m3]
axisc.mass.STEP = './STEPS/axisc/axisc_mass.STEP';
% Gear
axisc.gear.density = 7800; % [kg/m3]
axisc.gear.STEP = './STEPS/axisc/axisc_gear.STEP';
#+end_src
2020-02-17 18:21:20 +01:00
** Save the Structure
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-03 17:50:32 +01:00
The =axisc= structure is saved.
#+begin_src matlab
save('./mat/stages.mat', 'axisc', '-append');
#+end_src
* Mirror
:PROPERTIES:
:header-args:matlab+: :tangle ../src/initializeMirror.m
:header-args:matlab+: :comments none :mkdirp yes :eval no
:END:
<<sec:initializeMirror >>
** Simscape Model
:PROPERTIES:
:UNNUMBERED: t
:END:
The Simscape Model of the mirror is just a solid body.
The output =mirror_center= corresponds to the center of the Sphere and is the point of measurement for the metrology
#+name : fig:simscape_model_mirror
#+attr_org : :width 800
#+caption : Simscape model for the Mirror
[[file:figs/images/simscape_model_mirror.png ]]
#+name : fig:simscape_picture_mirror
#+attr_org : :width 800
#+caption : Simscape picture for the Mirror
[[file:figs/images/simscape_picture_mirror.png ]]
** Function description
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
function [] = initializeMirror(args)
#+end_src
** Optional Parameters
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
arguments
2020-04-14 11:30:25 +02:00
args.type char {mustBeMember(args.type,{'none', 'rigid', 'flexible'})} = 'rigid'
args.shape char {mustBeMember(args.shape,{'spherical', 'conical'})} = 'spherical'
args.angle (1,1) double {mustBeNumeric, mustBePositive} = 45 % [deg]
args.mass (1,1) double {mustBeNumeric, mustBePositive} = 10 % [kg]
args.freq (6,1) double {mustBeNumeric, mustBeNonnegative} = 200*ones(6,1) % [Hz]
2020-02-03 17:50:32 +01:00
end
#+end_src
2020-02-17 18:21:20 +01:00
** Structure initialization
2020-02-03 17:50:32 +01:00
:PROPERTIES:
:UNNUMBERED: t
:END:
First, we initialize the =mirror= structure.
#+begin_src matlab
mirror = struct();
#+end_src
2020-02-17 18:21:20 +01:00
** Add Mirror Type
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
switch args.type
case 'none'
mirror.type = 0;
case 'rigid'
mirror.type = 1;
2020-04-14 11:30:25 +02:00
case 'flexible'
mirror.type = 2;
2020-02-17 18:21:20 +01:00
end
#+end_src
2020-04-14 11:30:25 +02:00
** Mass and Inertia
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
mirror.mass = args.mass;
mirror.freq = args.freq;
#+end_src
** Stiffness and Damping properties
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
mirror.K = zeros(6,1);
mirror.K(1:3) = mirror.mass * (2*pi*mirror.freq(1:3)).^2;
mirror.C = zeros(6,1);
mirror.C(1:3) = 0.2 * sqrt(mirror.K(1:3).*mirror.mass);
#+end_src
** Equilibrium position of the each joint.
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
mirror.Deq = zeros(6,1);
#+end_src
** Geometry
2020-02-17 18:21:20 +01:00
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-25 17:49:08 +01:00
2020-02-03 17:50:32 +01:00
We define the geometrical values.
#+begin_src matlab
2020-02-25 17:49:08 +01:00
mirror.h = 0.05; % Height of the mirror [m]
2020-02-17 18:21:20 +01:00
2020-11-03 09:45:50 +01:00
mirror.thickness = 0.02; % Thickness of the plate supporting the sample [m]
2020-02-17 18:21:20 +01:00
2020-04-14 11:30:25 +02:00
mirror.hole_rad = 0.125; % radius of the hole in the mirror [m]
2020-02-17 18:21:20 +01:00
2020-02-25 17:49:08 +01:00
mirror.support_rad = 0.1; % radius of the support plate [m]
2020-02-17 18:21:20 +01:00
2020-02-25 17:49:08 +01:00
% point of interest offset in z (above the top surfave) [m]
2020-02-17 18:21:20 +01:00
switch args.type
case 'none'
2020-11-03 09:45:50 +01:00
mirror.jacobian = 0.205;
2020-02-17 18:21:20 +01:00
case 'rigid'
2020-11-03 09:45:50 +01:00
mirror.jacobian = 0.205 - mirror.h;
2020-04-14 11:30:25 +02:00
case 'flexible'
2020-11-03 09:45:50 +01:00
mirror.jacobian = 0.205 - mirror.h;
2020-02-17 18:21:20 +01:00
end
2020-02-25 17:49:08 +01:00
mirror.rad = 0.180; % radius of the mirror (at the bottom surface) [m]
2020-02-03 17:50:32 +01:00
#+end_src
#+begin_src matlab
mirror.cone_length = mirror.rad*tand(args.angle)+mirror.h+mirror.jacobian; % Distance from Apex point of the cone to jacobian point
#+end_src
Now we define the Shape of the mirror.
We first start with the internal part.
#+begin_src matlab
mirror.shape = [...
2020-04-14 11:30:25 +02:00
mirror.support_rad+5e-3 mirror.h-mirror.thickness
2020-02-03 17:50:32 +01:00
mirror.hole_rad mirror.h-mirror.thickness; ...
mirror.hole_rad 0; ...
mirror.rad 0 ...
];
#+end_src
Then, we define the reflective used part of the mirror.
#+begin_src matlab
if strcmp(args.shape, 'spherical')
mirror.sphere_radius = sqrt((mirror.jacobian+mirror.h)^2+mirror.rad^2); % Radius of the sphere [mm]
for z = linspace(0, mirror.h, 101)
mirror.shape = [mirror.shape; sqrt(mirror.sphere_radius^2-(z-mirror.jacobian-mirror.h)^2) z];
end
elseif strcmp(args.shape, 'conical')
mirror.shape = [mirror.shape; mirror.rad+mirror.h/tand(args.angle) mirror.h];
else
error('Shape should be either conical or spherical');
end
#+end_src
Finally, we close the shape.
#+begin_src matlab
2020-04-14 11:30:25 +02:00
mirror.shape = [mirror.shape; mirror.support_rad+5e-3 mirror.h];
2020-02-03 17:50:32 +01:00
#+end_src
2020-02-17 18:21:20 +01:00
** Save the Structure
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-03 17:50:32 +01:00
The =mirror= structure is saved.
#+begin_src matlab
save('./mat/stages.mat', 'mirror', '-append');
#+end_src
* Nano Hexapod
:PROPERTIES:
:header-args:matlab+: :tangle ../src/initializeNanoHexapod.m
:header-args:matlab+: :comments none :mkdirp yes :eval no
:END:
<<sec:initializeNanoHexapod >>
** Simscape Model
:PROPERTIES:
:UNNUMBERED: t
:END:
#+name : fig:simscape_model_nano_hexapod
#+attr_org : :width 800
#+caption : Simscape model for the Nano Hexapod
[[file:figs/images/simscape_model_nano_hexapod.png ]]
#+name : fig:simscape_picture_nano_hexapod
#+attr_org : :width 800
#+caption : Simscape picture for the Nano Hexapod
[[file:figs/images/simscape_picture_nano_hexapod.png ]]
** Function description
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
function [nano_hexapod] = initializeNanoHexapod(args)
#+end_src
** Optional Parameters
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
arguments
2020-03-31 16:07:13 +02:00
args.type char {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'init'})} = 'flexible'
2020-02-03 17:50:32 +01:00
% initializeFramesPositions
2020-11-03 09:45:50 +01:00
args.H (1,1) double {mustBeNumeric, mustBePositive} = 95e-3
args.MO_B (1,1) double {mustBeNumeric} = 170e-3
2020-02-03 17:50:32 +01:00
% generateGeneralConfiguration
args.FH (1,1) double {mustBeNumeric, mustBePositive} = 15e-3
args.FR (1,1) double {mustBeNumeric, mustBePositive} = 100e-3
args.FTh (6,1) double {mustBeNumeric} = [-10, 10, 120-10, 120+10, 240-10, 240+10]*(pi/180)
args.MH (1,1) double {mustBeNumeric, mustBePositive} = 15e-3
args.MR (1,1) double {mustBeNumeric, mustBePositive} = 90e-3
args.MTh (6,1) double {mustBeNumeric} = [-60+10, 60-10, 60+10, 180-10, 180+10, -60-10]*(pi/180)
% initializeStrutDynamics
2020-05-20 16:04:05 +02:00
args.actuator char {mustBeMember(args.actuator,{'piezo', 'lorentz', 'amplified'})} = 'piezo'
2020-05-20 16:41:34 +02:00
args.k1 (1,1) double {mustBeNumeric} = 1e6
args.ke (1,1) double {mustBeNumeric} = 5e6
args.ka (1,1) double {mustBeNumeric} = 60e6
args.c1 (1,1) double {mustBeNumeric} = 10
2020-11-03 09:45:50 +01:00
args.F_gain (1,1) double {mustBeNumeric} = 1
2020-04-02 15:29:22 +02:00
args.k (1,1) double {mustBeNumeric} = -1
args.c (1,1) double {mustBeNumeric} = -1
2020-05-04 12:03:08 +02:00
% initializeJointDynamics
2020-11-03 09:45:50 +01:00
args.type_F char {mustBeMember(args.type_F,{'universal', 'spherical', 'universal_p', 'spherical_p', 'universal_3dof', 'spherical_3dof', 'flexible'})} = 'universal'
args.type_M char {mustBeMember(args.type_M,{'universal', 'spherical', 'universal_p', 'spherical_p', 'universal_3dof', 'spherical_3dof', 'flexible'})} = 'spherical'
args.Ka_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.2e8*ones(6,1)
args.Ca_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
args.Kr_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.1e7*ones(6,1)
args.Cr_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
args.Kf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 33*ones(6,1)
2020-05-04 12:03:08 +02:00
args.Cf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1)
2020-11-03 09:45:50 +01:00
args.Kt_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 236*ones(6,1)
2020-05-04 12:03:08 +02:00
args.Ct_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1)
2020-11-03 09:45:50 +01:00
args.Kf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 33*ones(6,1)
2020-05-04 12:03:08 +02:00
args.Cf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1)
2020-11-03 09:45:50 +01:00
args.Kt_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 236*ones(6,1)
2020-05-04 12:03:08 +02:00
args.Ct_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1)
2020-11-03 09:45:50 +01:00
args.Ka_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.2e8*ones(6,1)
args.Ca_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
args.Kr_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.1e7*ones(6,1)
args.Cr_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
2020-02-03 17:50:32 +01:00
% initializeCylindricalPlatforms
args.Fpm (1,1) double {mustBeNumeric, mustBePositive} = 1
args.Fph (1,1) double {mustBeNumeric, mustBePositive} = 10e-3
args.Fpr (1,1) double {mustBeNumeric, mustBePositive} = 150e-3
args.Mpm (1,1) double {mustBeNumeric, mustBePositive} = 1
args.Mph (1,1) double {mustBeNumeric, mustBePositive} = 10e-3
2020-04-14 11:30:25 +02:00
args.Mpr (1,1) double {mustBeNumeric, mustBePositive} = 120e-3
2020-02-03 17:50:32 +01:00
% initializeCylindricalStruts
args.Fsm (1,1) double {mustBeNumeric, mustBePositive} = 0.1
args.Fsh (1,1) double {mustBeNumeric, mustBePositive} = 50e-3
args.Fsr (1,1) double {mustBeNumeric, mustBePositive} = 5e-3
args.Msm (1,1) double {mustBeNumeric, mustBePositive} = 0.1
args.Msh (1,1) double {mustBeNumeric, mustBePositive} = 50e-3
args.Msr (1,1) double {mustBeNumeric, mustBePositive} = 5e-3
% inverseKinematics
args.AP (3,1) double {mustBeNumeric} = zeros(3,1)
args.ARB (3,3) double {mustBeNumeric} = eye(3)
% Equilibrium position of each leg
args.dLeq (6,1) double {mustBeNumeric} = zeros(6,1)
2020-03-31 19:32:02 +02:00
% Force that stiffness of each joint should apply at t=0
args.Foffset logical {mustBeNumericOrLogical} = false
2020-02-03 17:50:32 +01:00
end
#+end_src
** Function content
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
2020-05-04 12:03:08 +02:00
stewart = initializeStewartPlatform();
stewart = initializeFramesPositions(stewart, 'H', args.H, 'MO_B', args.MO_B);
stewart = generateGeneralConfiguration(stewart, 'FH', args.FH, 'FR', args.FR, 'FTh', args.FTh, 'MH', args.MH, 'MR', args.MR, 'MTh', args.MTh);
stewart = computeJointsPose(stewart);
2020-04-02 15:29:22 +02:00
#+end_src
#+begin_src matlab
if args.k > 0 && args.c > 0
2020-05-20 16:41:34 +02:00
stewart = initializeStrutDynamics(stewart, 'type', 'classical', 'K', args.k*ones(6,1), 'C', args.c*ones(6,1));
2020-04-02 15:29:22 +02:00
elseif args.k > 0
2020-05-20 16:41:34 +02:00
stewart = initializeStrutDynamics(stewart, 'type', 'classical', 'K', args.k*ones(6,1), 'C', 1.5*sqrt(args.k)*ones(6,1));
2020-04-02 15:29:22 +02:00
elseif strcmp(args.actuator, 'piezo')
2020-05-20 16:41:34 +02:00
stewart = initializeStrutDynamics(stewart, 'type', 'classical', 'K', 1e7*ones(6,1), 'C', 1e2*ones(6,1));
2020-02-03 17:50:32 +01:00
elseif strcmp(args.actuator, 'lorentz')
2020-05-20 16:41:34 +02:00
stewart = initializeStrutDynamics(stewart, 'type', 'classical', 'K', 1e4*ones(6,1), 'C', 1e2*ones(6,1));
elseif strcmp(args.actuator, 'amplified')
stewart = initializeStrutDynamics(stewart, 'type', 'amplified', ...
'k1', args.k1*ones(6,1), ...
'c1', args.c1*ones(6,1), ...
'ka', args.ka*ones(6,1), ...
'ke', args.ke*ones(6,1), ...
2020-11-03 09:45:50 +01:00
'F_gain', args.F_gain*ones(6,1));
2020-02-03 17:50:32 +01:00
else
2020-05-20 16:41:34 +02:00
error('args.actuator should be piezo, lorentz or amplified');
2020-02-03 17:50:32 +01:00
end
2020-04-02 15:29:22 +02:00
#+end_src
#+begin_src matlab
2020-05-04 12:03:08 +02:00
stewart = initializeJointDynamics(stewart, ...
'type_F', args.type_F, ...
'type_M', args.type_M, ...
2020-11-03 09:45:50 +01:00
'Kf_M', args.Kf_M, ...
'Cf_M', args.Cf_M, ...
'Kt_M', args.Kt_M, ...
'Ct_M', args.Ct_M, ...
'Kf_F', args.Kf_F, ...
'Cf_F', args.Cf_F, ...
'Kt_F', args.Kt_F, ...
'Ct_F', args.Ct_F, ...
'Ka_F', args.Ka_F, ...
'Ca_F', args.Ca_F, ...
'Kr_F', args.Kr_F, ...
'Cr_F', args.Cr_F, ...
'Ka_M', args.Ka_M, ...
'Ca_M', args.Ca_M, ...
'Kr_M', args.Kr_M, ...
'Cr_M', args.Cr_M);
2020-05-04 12:03:08 +02:00
#+end_src
#+begin_src matlab
stewart = initializeCylindricalPlatforms(stewart, 'Fpm', args.Fpm, 'Fph', args.Fph, 'Fpr', args.Fpr, 'Mpm', args.Mpm, 'Mph', args.Mph, 'Mpr', args.Mpr);
stewart = initializeCylindricalStruts(stewart, 'Fsm', args.Fsm, 'Fsh', args.Fsh, 'Fsr', args.Fsr, 'Msm', args.Msm, 'Msh', args.Msh, 'Msr', args.Msr);
stewart = computeJacobian(stewart);
stewart = initializeStewartPose(stewart, 'AP', args.AP, 'ARB', args.ARB);
#+end_src
#+begin_src matlab
stewart = initializeInertialSensor(stewart, 'type', 'accelerometer');
2020-02-03 17:50:32 +01:00
#+end_src
2020-03-31 19:32:02 +02:00
Equilibrium position of the each joint.
2020-02-03 17:50:32 +01:00
#+begin_src matlab
2020-03-31 19:32:02 +02:00
if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
load('mat/Foffset.mat', 'Fnm');
2020-05-04 12:03:08 +02:00
stewart.actuators.dLeq = -Fnm'./stewart.Ki;
2020-03-31 19:32:02 +02:00
else
2020-05-04 12:03:08 +02:00
stewart.actuators.dLeq = args.dLeq;
2020-03-31 19:32:02 +02:00
end
2020-02-03 17:50:32 +01:00
#+end_src
2020-02-18 16:46:35 +01:00
** Add Type
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
switch args.type
case 'none'
2020-05-04 12:03:08 +02:00
stewart.type = 0;
2020-02-18 16:46:35 +01:00
case 'rigid'
2020-05-04 12:03:08 +02:00
stewart.type = 1;
2020-02-18 16:46:35 +01:00
case 'flexible'
2020-05-04 12:03:08 +02:00
stewart.type = 2;
2020-03-31 16:07:13 +02:00
case 'init'
2020-05-04 12:03:08 +02:00
stewart.type = 4;
2020-02-18 16:46:35 +01:00
end
#+end_src
2020-02-17 18:21:20 +01:00
** Save the Structure
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-03 17:50:32 +01:00
#+begin_src matlab
2020-05-04 12:03:08 +02:00
nano_hexapod = stewart;
2020-02-03 17:50:32 +01:00
save('./mat/stages.mat', 'nano_hexapod', '-append');
#+end_src
* Sample
:PROPERTIES:
:header-args:matlab+: :tangle ../src/initializeSample.m
:header-args:matlab+: :comments none :mkdirp yes :eval no
:END:
<<sec:initializeSample >>
** Simscape Model
:PROPERTIES:
:UNNUMBERED: t
:END:
The Simscape model of the sample environment is composed of:
- A rigid transform that can be used to translate the sample (position offset)
- A cartesian joint to add some flexibility to the sample environment mount
- A solid that represent the sample
- An input is added to apply some external forces and torques at the center of the sample environment.
This could be the case for cable forces for instance.
#+name : fig:simscape_model_sample
#+attr_org : :width 800
#+caption : Simscape model for the Sample
[[file:figs/images/simscape_model_sample.png ]]
#+name : fig:simscape_picture_sample
#+attr_org : :width 800
#+caption : Simscape picture for the Sample
[[file:figs/images/simscape_picture_sample.png ]]
** Function description
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
function [sample] = initializeSample(args)
#+end_src
** Optional Parameters
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
arguments
2020-02-25 17:49:08 +01:00
args.type char {mustBeMember(args.type,{'rigid', 'flexible', 'none', 'init'})} = 'flexible'
args.radius (1,1) double {mustBeNumeric, mustBePositive} = 0.1 % [m]
args.height (1,1) double {mustBeNumeric, mustBePositive} = 0.3 % [m]
args.mass (1,1) double {mustBeNumeric, mustBePositive} = 50 % [kg]
2020-03-30 17:39:40 +02:00
args.freq (6,1) double {mustBeNumeric, mustBePositive} = 100*ones(6,1) % [Hz]
2020-02-25 17:49:08 +01:00
args.offset (1,1) double {mustBeNumeric} = 0 % [m]
2020-03-17 11:22:57 +01:00
args.Foffset logical {mustBeNumericOrLogical} = false
2020-02-03 17:50:32 +01:00
end
#+end_src
2020-02-17 18:21:20 +01:00
** Structure initialization
2020-02-03 17:50:32 +01:00
:PROPERTIES:
:UNNUMBERED: t
:END:
First, we initialize the =sample= structure.
#+begin_src matlab
sample = struct();
#+end_src
2020-02-17 18:21:20 +01:00
** Add Sample Type
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
switch args.type
case 'none'
sample.type = 0;
case 'rigid'
sample.type = 1;
case 'flexible'
sample.type = 2;
2020-02-25 17:49:08 +01:00
case 'init'
sample.type = 3;
2020-02-17 18:21:20 +01:00
end
#+end_src
2020-02-25 17:49:08 +01:00
** Material and Geometry
2020-02-17 18:21:20 +01:00
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-25 17:49:08 +01:00
2020-02-03 17:50:32 +01:00
We define the geometrical parameters of the sample as well as its mass and position.
#+begin_src matlab
sample.radius = args.radius; % [m]
sample.height = args.height; % [m]
2020-02-25 17:49:08 +01:00
sample.mass = args.mass; % [kg]
2020-02-03 17:50:32 +01:00
sample.offset = args.offset; % [m]
#+end_src
2020-03-30 17:39:40 +02:00
** Compute the Inertia
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
sample.inertia = [1/12 * sample.mass * (3*sample.radius^2 + sample.height^2); ...
1/12 * sample.mass * (3*sample.radius^2 + sample.height^2); ...
1/2 * sample.mass * sample.radius^2];
#+end_src
2020-02-25 17:49:08 +01:00
** Stiffness and Damping properties
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-03 17:50:32 +01:00
#+begin_src matlab
2020-03-30 17:39:40 +02:00
sample.K = zeros(6, 1);
sample.C = zeros(6, 1);
#+end_src
Translation Stiffness and Damping:
#+begin_src matlab
sample.K(1:3) = sample.mass .* (2*pi * args.freq(1:3)).^2; % [N/m]
sample.C(1:3) = 0.1 * sqrt(sample.K(1:3)*sample.mass); % [N/(m/s)]
#+end_src
Rotational Stiffness and Damping:
#+begin_src matlab
sample.K(4:6) = sample.inertia .* (2*pi * args.freq(4:6)).^2; % [N/m]
sample.C(4:6) = 0.1 * sqrt(sample.K(4:6).*sample.inertia); % [N/(m/s)]
2020-02-03 17:50:32 +01:00
#+end_src
2020-02-25 17:49:08 +01:00
** Equilibrium position of the each joint.
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-03 17:50:32 +01:00
#+begin_src matlab
2020-02-25 17:49:08 +01:00
if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
load('mat/Foffset.mat', 'Fsm');
sample.Deq = -Fsm'./sample.K;
else
2020-03-30 17:39:40 +02:00
sample.Deq = zeros(6,1);
2020-02-25 17:49:08 +01:00
end
2020-02-03 17:50:32 +01:00
#+end_src
2020-02-17 18:21:20 +01:00
** Save the Structure
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-02-03 17:50:32 +01:00
The =sample= structure is saved.
#+begin_src matlab
save('./mat/stages.mat', 'sample', '-append');
#+end_src
2020-02-17 18:21:20 +01:00
* Initialize Controller
:PROPERTIES:
:header-args:matlab+: :tangle ../src/initializeController.m
:header-args:matlab+: :comments none :mkdirp yes :eval no
:END:
<<sec:initializeController >>
** Function Declaration and Documentation
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
function [] = initializeController(args)
#+end_src
** Optional Parameters
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
arguments
2020-04-02 15:29:22 +02:00
args.type char {mustBeMember(args.type,{'open-loop', 'iff', 'dvf', 'hac-dvf', 'ref-track-L', 'ref-track-iff-L', 'cascade-hac-lac', 'hac-iff', 'stabilizing'})} = 'open-loop'
2020-02-17 18:21:20 +01:00
end
#+end_src
** Structure initialization
:PROPERTIES:
:UNNUMBERED: t
:END:
First, we initialize the =controller= structure.
#+begin_src matlab
controller = struct();
#+end_src
** Controller Type
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
switch args.type
case 'open-loop'
controller.type = 1;
2020-04-15 10:56:18 +02:00
controller.name = 'Open-Loop';
2020-02-17 18:21:20 +01:00
case 'dvf'
controller.type = 2;
2020-04-15 10:56:18 +02:00
controller.name = 'Decentralized Direct Velocity Feedback';
2020-02-17 18:21:20 +01:00
case 'iff'
controller.type = 3;
2020-04-15 10:56:18 +02:00
controller.name = 'Decentralized Integral Force Feedback';
2020-03-13 17:40:22 +01:00
case 'hac-dvf'
controller.type = 4;
2020-04-15 10:56:18 +02:00
controller.name = 'HAC-DVF';
2020-03-23 10:05:32 +01:00
case 'ref-track-L'
controller.type = 5;
2020-04-15 10:56:18 +02:00
controller.name = 'Reference Tracking in the frame of the legs';
2020-03-23 10:05:32 +01:00
case 'ref-track-iff-L'
controller.type = 6;
2020-04-15 10:56:18 +02:00
controller.name = 'Reference Tracking in the frame of the legs + IFF';
2020-03-23 10:05:32 +01:00
case 'cascade-hac-lac'
controller.type = 7;
2020-04-15 10:56:18 +02:00
controller.name = 'Cascade Control + HAC-LAC';
2020-03-25 19:23:22 +01:00
case 'hac-iff'
controller.type = 8;
2020-04-15 10:56:18 +02:00
controller.name = 'HAC-IFF';
2020-04-02 15:29:22 +02:00
case 'stabilizing'
controller.type = 9;
2020-04-15 10:56:18 +02:00
controller.name = 'Stabilizing Controller';
2020-02-17 18:21:20 +01:00
end
#+end_src
** Save the Structure
:PROPERTIES:
:UNNUMBERED: t
:END:
The =controller= structure is saved.
#+begin_src matlab
save('./mat/controller.mat', 'controller');
#+end_src
2020-02-03 17:50:32 +01:00
* Generate Reference Signals
2019-12-11 17:09:32 +01:00
:PROPERTIES:
:header-args:matlab+: :tangle ../src/initializeReferences.m
:header-args:matlab+: :comments none :mkdirp yes :eval no
:END:
<<sec:initializeReferences >>
2020-02-03 17:50:32 +01:00
** Function Declaration and Documentation
:PROPERTIES:
:UNNUMBERED: t
:END:
2019-12-11 17:09:32 +01:00
#+begin_src matlab
2020-01-13 11:42:31 +01:00
function [ref] = initializeReferences(args)
#+end_src
2020-02-03 17:50:32 +01:00
** Optional Parameters
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-01-13 11:42:31 +01:00
#+begin_src matlab
arguments
% Sampling Frequency [s]
args.Ts (1,1) double {mustBeNumeric, mustBePositive} = 1e-3
% Maximum simulation time [s]
args.Tmax (1,1) double {mustBeNumeric, mustBePositive} = 100
% Either "constant" / "triangular" / "sinusoidal"
args.Dy_type char {mustBeMember(args.Dy_type,{'constant', 'triangular', 'sinusoidal'})} = 'constant'
% Amplitude of the displacement [m]
args.Dy_amplitude (1,1) double {mustBeNumeric} = 0
% Period of the displacement [s]
args.Dy_period (1,1) double {mustBeNumeric, mustBePositive} = 1
% Either "constant" / "triangular" / "sinusoidal"
args.Ry_type char {mustBeMember(args.Ry_type,{'constant', 'triangular', 'sinusoidal'})} = 'constant'
% Amplitude [rad]
args.Ry_amplitude (1,1) double {mustBeNumeric} = 0
% Period of the displacement [s]
args.Ry_period (1,1) double {mustBeNumeric, mustBePositive} = 1
% Either "constant" / "rotating"
2020-04-03 14:10:14 +02:00
args.Rz_type char {mustBeMember(args.Rz_type,{'constant', 'rotating', 'rotating-not-filtered'})} = 'constant'
2020-01-13 11:42:31 +01:00
% Initial angle [rad]
args.Rz_amplitude (1,1) double {mustBeNumeric} = 0
% Period of the rotating [s]
args.Rz_period (1,1) double {mustBeNumeric, mustBePositive} = 1
% For now, only constant is implemented
args.Dh_type char {mustBeMember(args.Dh_type,{'constant'})} = 'constant'
% Initial position [m,m,m,rad,rad,rad] of the top platform (Pitch-Roll-Yaw Euler angles)
args.Dh_pos (6,1) double {mustBeNumeric} = zeros(6, 1), ...
% For now, only constant is implemented
args.Rm_type char {mustBeMember(args.Rm_type,{'constant'})} = 'constant'
% Initial position of the two masses
args.Rm_pos (2,1) double {mustBeNumeric} = [0; pi]
% For now, only constant is implemented
args.Dn_type char {mustBeMember(args.Dn_type,{'constant'})} = 'constant'
% Initial position [m,m,m,rad,rad,rad] of the top platform
args.Dn_pos (6,1) double {mustBeNumeric} = zeros(6,1)
end
#+end_src
2019-12-11 17:09:32 +01:00
2020-01-13 11:42:31 +01:00
2020-02-03 17:50:32 +01:00
** Initialize Parameters
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-01-13 11:42:31 +01:00
#+begin_src matlab
2020-01-16 11:49:13 +01:00
%% Set Sampling Time
Ts = args.Ts;
Tmax = args.Tmax;
%% Low Pass Filter to filter out the references
s = zpk('s');
w0 = 2*pi*10;
xi = 1;
H_lpf = 1/(1 + 2*xi/w0*s + s^2/w0^2);
2020-01-13 11:42:31 +01:00
#+end_src
2019-12-11 17:09:32 +01:00
2020-02-03 17:50:32 +01:00
** Translation Stage
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-01-13 11:42:31 +01:00
#+begin_src matlab
2020-02-04 16:13:52 +01:00
%% Translation stage - Dy
t = 0:Ts:Tmax; % Time Vector [s]
Dy = zeros(length(t), 1);
Dyd = zeros(length(t), 1);
Dydd = zeros(length(t), 1);
switch args.Dy_type
case 'constant'
Dy(:) = args.Dy_amplitude;
Dyd(:) = 0;
Dydd(:) = 0;
case 'triangular'
% This is done to unsure that we start with no displacement
Dy_raw = args.Dy_amplitude*sawtooth(2*pi*t/args.Dy_period,1/2);
i0 = find(t>=args.Dy_period/4,1);
Dy(1:end-i0+1) = Dy_raw(i0:end);
Dy(end-i0+2:end) = Dy_raw(end); % we fix the last value
2019-12-11 17:09:32 +01:00
2020-02-04 16:13:52 +01:00
% The signal is filtered out
Dy = lsim(H_lpf, Dy, t);
Dyd = lsim(H_lpf*s, Dy, t);
Dydd = lsim(H_lpf*s^2, Dy, t);
case 'sinusoidal'
Dy(:) = args.Dy_amplitude*sin(2*pi/args.Dy_period*t);
Dyd = args.Dy_amplitude*2*pi/args.Dy_period*cos(2*pi/args.Dy_period*t);
Dydd = -args.Dy_amplitude*(2*pi/args.Dy_period)^2*sin(2*pi/args.Dy_period*t);
otherwise
warning('Dy_type is not set correctly');
end
Dy = struct('time', t, 'signals', struct('values', Dy), 'deriv', Dyd, 'dderiv', Dydd);
2020-01-13 11:42:31 +01:00
#+end_src
2019-12-11 17:09:32 +01:00
2020-02-03 17:50:32 +01:00
** Tilt Stage
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-01-13 11:42:31 +01:00
#+begin_src matlab
2020-02-04 16:13:52 +01:00
%% Tilt Stage - Ry
t = 0:Ts:Tmax; % Time Vector [s]
Ry = zeros(length(t), 1);
Ryd = zeros(length(t), 1);
Rydd = zeros(length(t), 1);
switch args.Ry_type
case 'constant'
Ry(:) = args.Ry_amplitude;
Ryd(:) = 0;
Rydd(:) = 0;
case 'triangular'
Ry_raw = args.Ry_amplitude*sawtooth(2*pi*t/args.Ry_period,1/2);
i0 = find(t>=args.Ry_period/4,1);
Ry(1:end-i0+1) = Ry_raw(i0:end);
Ry(end-i0+2:end) = Ry_raw(end); % we fix the last value
2019-12-17 18:03:21 +01:00
2020-02-04 16:13:52 +01:00
% The signal is filtered out
Ry = lsim(H_lpf, Ry, t);
Ryd = lsim(H_lpf*s, Ry, t);
Rydd = lsim(H_lpf*s^2, Ry, t);
case 'sinusoidal'
Ry(:) = args.Ry_amplitude*sin(2*pi/args.Ry_period*t);
Ryd = args.Ry_amplitude*2*pi/args.Ry_period*cos(2*pi/args.Ry_period*t);
Rydd = -args.Ry_amplitude*(2*pi/args.Ry_period)^2*sin(2*pi/args.Ry_period*t);
otherwise
warning('Ry_type is not set correctly');
end
Ry = struct('time', t, 'signals', struct('values', Ry), 'deriv', Ryd, 'dderiv', Rydd);
2020-01-13 11:42:31 +01:00
#+end_src
2019-12-11 17:09:32 +01:00
2020-02-03 17:50:32 +01:00
** Spindle
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-01-13 11:42:31 +01:00
#+begin_src matlab
2020-02-04 10:28:05 +01:00
%% Spindle - Rz
t = 0:Ts:Tmax; % Time Vector [s]
Rz = zeros(length(t), 1);
Rzd = zeros(length(t), 1);
Rzdd = zeros(length(t), 1);
2019-12-17 18:03:21 +01:00
2020-02-04 10:28:05 +01:00
switch args.Rz_type
case 'constant'
Rz(:) = args.Rz_amplitude;
Rzd(:) = 0;
Rzdd(:) = 0;
2020-04-03 14:10:14 +02:00
case 'rotating-not-filtered'
Rz(:) = 2*pi/args.Rz_period*t;
% The signal is filtered out
Rz(:) = 2*pi/args.Rz_period*t;
Rzd(:) = 2*pi/args.Rz_period;
Rzdd(:) = 0;
% We add the angle offset
Rz = Rz + args.Rz_amplitude;
2020-02-04 10:28:05 +01:00
case 'rotating'
Rz(:) = 2*pi/args.Rz_period*t;
% The signal is filtered out
Rz = lsim(H_lpf, Rz, t);
Rzd = lsim(H_lpf*s, Rz, t);
Rzdd = lsim(H_lpf*s^2, Rz, t);
% We add the angle offset
Rz = Rz + args.Rz_amplitude;
otherwise
warning('Rz_type is not set correctly');
end
2019-12-17 18:03:21 +01:00
2020-02-04 10:28:05 +01:00
Rz = struct('time', t, 'signals', struct('values', Rz), 'deriv', Rzd, 'dderiv', Rzdd);
2020-01-13 11:42:31 +01:00
#+end_src
2019-12-11 17:09:32 +01:00
2020-02-03 17:50:32 +01:00
** Micro Hexapod
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-01-13 11:42:31 +01:00
#+begin_src matlab
2020-02-03 17:50:32 +01:00
%% Micro-Hexapod
t = [0, Ts];
Dh = zeros(length(t), 6);
Dhl = zeros(length(t), 6);
switch args.Dh_type
case 'constant'
Dh = [args.Dh_pos, args.Dh_pos];
load('mat/stages.mat', 'micro_hexapod');
AP = [args.Dh_pos(1) ; args.Dh_pos(2) ; args.Dh_pos(3)];
tx = args.Dh_pos(4);
ty = args.Dh_pos(5);
tz = args.Dh_pos(6);
ARB = [cos(tz) -sin(tz) 0;
sin(tz) cos(tz) 0;
0 0 1]*...
[ cos(ty) 0 sin(ty);
0 1 0;
-sin(ty) 0 cos(ty)]*...
[1 0 0;
0 cos(tx) -sin(tx);
0 sin(tx) cos(tx)];
[~, Dhl] = inverseKinematics(micro_hexapod, 'AP', AP, 'ARB', ARB);
Dhl = [Dhl, Dhl];
otherwise
warning('Dh_type is not set correctly');
end
2019-12-17 18:03:21 +01:00
2020-02-03 17:50:32 +01:00
Dh = struct('time', t, 'signals', struct('values', Dh));
Dhl = struct('time', t, 'signals', struct('values', Dhl));
2020-01-13 11:42:31 +01:00
#+end_src
2019-12-11 17:09:32 +01:00
2020-02-03 17:50:32 +01:00
** Axis Compensation
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-01-13 11:42:31 +01:00
#+begin_src matlab
2020-02-04 16:13:52 +01:00
%% Axis Compensation - Rm
t = [0, Ts];
2019-12-17 18:03:21 +01:00
2020-02-04 16:13:52 +01:00
Rm = [args.Rm_pos, args.Rm_pos];
Rm = struct('time', t, 'signals', struct('values', Rm));
2020-01-13 11:42:31 +01:00
#+end_src
2019-12-11 17:09:32 +01:00
2020-02-03 17:50:32 +01:00
** Nano Hexapod
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-01-13 11:42:31 +01:00
#+begin_src matlab
2020-02-04 16:13:52 +01:00
%% Nano-Hexapod
t = [0, Ts];
Dn = zeros(length(t), 6);
2019-12-11 17:09:32 +01:00
2020-02-04 16:13:52 +01:00
switch args.Dn_type
case 'constant'
Dn = [args.Dn_pos, args.Dn_pos];
2020-02-25 17:49:08 +01:00
load('mat/stages.mat', 'nano_hexapod');
AP = [args.Dn_pos(1) ; args.Dn_pos(2) ; args.Dn_pos(3)];
tx = args.Dn_pos(4);
ty = args.Dn_pos(5);
tz = args.Dn_pos(6);
ARB = [cos(tz) -sin(tz) 0;
sin(tz) cos(tz) 0;
0 0 1]*...
[ cos(ty) 0 sin(ty);
0 1 0;
-sin(ty) 0 cos(ty)]*...
[1 0 0;
0 cos(tx) -sin(tx);
0 sin(tx) cos(tx)];
[~, Dnl] = inverseKinematics(nano_hexapod, 'AP', AP, 'ARB', ARB);
Dnl = [Dnl, Dnl];
2020-02-04 16:13:52 +01:00
otherwise
warning('Dn_type is not set correctly');
end
2019-12-17 18:03:21 +01:00
2020-02-04 16:13:52 +01:00
Dn = struct('time', t, 'signals', struct('values', Dn));
2020-02-25 17:49:08 +01:00
Dnl = struct('time', t, 'signals', struct('values', Dnl));
2020-01-13 11:42:31 +01:00
#+end_src
2019-12-11 17:09:32 +01:00
2020-02-03 17:50:32 +01:00
** Save
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-01-13 11:42:31 +01:00
#+begin_src matlab
2019-12-11 17:09:32 +01:00
%% Save
2020-04-15 10:56:18 +02:00
save('./mat/nass_references.mat', 'Dy', 'Ry', 'Rz', 'Dh', 'Dhl', 'Rm', 'Dn', 'Dnl', 'args', 'Ts');
2019-12-11 17:09:32 +01:00
end
#+end_src
2020-02-03 17:50:32 +01:00
* Initialize Disturbances
2019-12-11 17:34:42 +01:00
:PROPERTIES:
2020-01-21 15:49:02 +01:00
:header-args:matlab+: :tangle ../src/initializeDisturbances.m
2019-12-11 17:34:42 +01:00
:header-args:matlab+: :comments none :mkdirp yes
:header-args:matlab+: :eval no :results none
:END:
2020-01-21 15:49:02 +01:00
<<sec:initializeDisturbances >>
2019-12-11 17:34:42 +01:00
2020-02-03 17:50:32 +01:00
** Function Declaration and Documentation
:PROPERTIES:
:UNNUMBERED: t
:END:
2019-12-11 17:34:42 +01:00
#+begin_src matlab
2020-01-21 15:49:02 +01:00
function [] = initializeDisturbances(args)
% initializeDisturbances - Initialize the disturbances
2019-12-11 17:34:42 +01:00
%
2020-01-21 15:49:02 +01:00
% Syntax: [] = initializeDisturbances(args)
2019-12-11 17:34:42 +01:00
%
% Inputs:
2020-01-13 11:42:31 +01:00
% - args -
2019-12-11 17:34:42 +01:00
#+end_src
2020-02-03 17:50:32 +01:00
** Optional Parameters
:PROPERTIES:
:UNNUMBERED: t
:END:
2019-12-11 17:34:42 +01:00
#+begin_src matlab
2020-01-13 11:42:31 +01:00
arguments
2020-01-21 15:46:34 +01:00
% Global parameter to enable or disable the disturbances
args.enable logical {mustBeNumericOrLogical} = true
2020-01-13 11:42:31 +01:00
% Ground Motion - X direction
args.Dwx logical {mustBeNumericOrLogical} = true
% Ground Motion - Y direction
args.Dwy logical {mustBeNumericOrLogical} = true
% Ground Motion - Z direction
args.Dwz logical {mustBeNumericOrLogical} = true
% Translation Stage - X direction
args.Fty_x logical {mustBeNumericOrLogical} = true
% Translation Stage - Z direction
args.Fty_z logical {mustBeNumericOrLogical} = true
% Spindle - Z direction
args.Frz_z logical {mustBeNumericOrLogical} = true
2019-12-11 17:34:42 +01:00
end
#+end_src
2020-01-13 11:42:31 +01:00
2020-02-03 17:50:32 +01:00
** Load Data
:PROPERTIES:
:UNNUMBERED: t
:END:
2019-12-11 17:34:42 +01:00
#+begin_src matlab
2020-03-13 17:40:22 +01:00
load('./mat/dist_psd.mat', 'dist_f');
2019-12-11 17:34:42 +01:00
#+end_src
We remove the first frequency point that usually is very large.
#+begin_src matlab :exports none
dist_f.f = dist_f.f(2:end);
dist_f.psd_gm = dist_f.psd_gm(2:end);
dist_f.psd_ty = dist_f.psd_ty(2:end);
dist_f.psd_rz = dist_f.psd_rz(2:end);
#+end_src
2020-02-03 17:50:32 +01:00
** Parameters
:PROPERTIES:
:UNNUMBERED: t
:END:
2019-12-11 17:34:42 +01:00
We define some parameters that will be used in the algorithm.
#+begin_src matlab
Fs = 2*dist_f.f(end); % Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz]
N = 2*length(dist_f.f); % Number of Samples match the one of the wanted PSD
T0 = N/Fs; % Signal Duration [s]
df = 1/T0; % Frequency resolution of the DFT [Hz]
% Also equal to (dist_f.f(2)-dist_f.f(1))
t = linspace(0, T0, N+1)'; % Time Vector [s]
Ts = 1/Fs; % Sampling Time [s]
#+end_src
2020-02-03 17:50:32 +01:00
** Ground Motion
:PROPERTIES:
:UNNUMBERED: t
:END:
2019-12-11 17:34:42 +01:00
#+begin_src matlab
phi = dist_f.psd_gm;
C = zeros(N/2,1);
for i = 1:N/2
C(i) = sqrt(phi(i)*df);
end
2019-12-13 19:07:54 +01:00
#+end_src
#+begin_src matlab
2020-01-21 15:46:34 +01:00
if args.Dwx && args.enable
2020-02-05 13:36:41 +01:00
rng(111);
2019-12-13 19:07:54 +01:00
theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
Cx = [0 ; C.*complex(cos(theta),sin(theta))];
Cx = [Cx; flipud(conj(Cx(2:end)))];;
Dwx = N/sqrt(2)*ifft(Cx); % Ground Motion - x direction [m]
else
Dwx = zeros(length(t), 1);
end
#+end_src
#+begin_src matlab
2020-01-21 15:46:34 +01:00
if args.Dwy && args.enable
2020-02-05 13:36:41 +01:00
rng(112);
2019-12-13 19:07:54 +01:00
theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
Cx = [0 ; C.*complex(cos(theta),sin(theta))];
Cx = [Cx; flipud(conj(Cx(2:end)))];;
Dwy = N/sqrt(2)*ifft(Cx); % Ground Motion - y direction [m]
else
Dwy = zeros(length(t), 1);
end
#+end_src
#+begin_src matlab
2020-01-21 15:46:34 +01:00
if args.Dwy && args.enable
2020-02-05 13:36:41 +01:00
rng(113);
2019-12-13 19:07:54 +01:00
theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
Cx = [0 ; C.*complex(cos(theta),sin(theta))];
Cx = [Cx; flipud(conj(Cx(2:end)))];;
Dwz = N/sqrt(2)*ifft(Cx); % Ground Motion - z direction [m]
else
Dwz = zeros(length(t), 1);
end
2019-12-11 17:34:42 +01:00
#+end_src
2020-02-03 17:50:32 +01:00
** Translation Stage - X direction
:PROPERTIES:
:UNNUMBERED: t
:END:
2019-12-11 17:34:42 +01:00
#+begin_src matlab
2020-01-21 15:46:34 +01:00
if args.Fty_x && args.enable
2019-12-13 19:07:54 +01:00
phi = dist_f.psd_ty; % TODO - we take here the vertical direction which is wrong but approximate
C = zeros(N/2,1);
for i = 1:N/2
C(i) = sqrt(phi(i)*df);
end
2020-02-05 13:36:41 +01:00
rng(121);
2019-12-13 19:07:54 +01:00
theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
Cx = [0 ; C.*complex(cos(theta),sin(theta))];
Cx = [Cx; flipud(conj(Cx(2:end)))];;
u = N/sqrt(2)*ifft(Cx); % Disturbance Force Ty x [N]
Fty_x = u;
else
Fty_x = zeros(length(t), 1);
2019-12-11 17:34:42 +01:00
end
#+end_src
2020-02-03 17:50:32 +01:00
** Translation Stage - Z direction
:PROPERTIES:
:UNNUMBERED: t
:END:
2019-12-11 17:34:42 +01:00
#+begin_src matlab
2020-01-21 15:46:34 +01:00
if args.Fty_z && args.enable
2019-12-13 19:07:54 +01:00
phi = dist_f.psd_ty;
C = zeros(N/2,1);
for i = 1:N/2
C(i) = sqrt(phi(i)*df);
end
2020-02-05 13:36:41 +01:00
rng(122);
2019-12-13 19:07:54 +01:00
theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
Cx = [0 ; C.*complex(cos(theta),sin(theta))];
Cx = [Cx; flipud(conj(Cx(2:end)))];;
u = N/sqrt(2)*ifft(Cx); % Disturbance Force Ty z [N]
Fty_z = u;
else
Fty_z = zeros(length(t), 1);
2019-12-11 17:34:42 +01:00
end
#+end_src
2020-02-03 17:50:32 +01:00
** Spindle - Z direction
:PROPERTIES:
:UNNUMBERED: t
:END:
2019-12-11 17:34:42 +01:00
#+begin_src matlab
2020-01-21 15:46:34 +01:00
if args.Frz_z && args.enable
2019-12-13 19:07:54 +01:00
phi = dist_f.psd_rz;
C = zeros(N/2,1);
for i = 1:N/2
C(i) = sqrt(phi(i)*df);
end
2020-02-05 13:36:41 +01:00
rng(131);
2019-12-13 19:07:54 +01:00
theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
Cx = [0 ; C.*complex(cos(theta),sin(theta))];
Cx = [Cx; flipud(conj(Cx(2:end)))];;
u = N/sqrt(2)*ifft(Cx); % Disturbance Force Rz z [N]
Frz_z = u;
else
Frz_z = zeros(length(t), 1);
2019-12-11 17:34:42 +01:00
end
#+end_src
2020-02-03 17:50:32 +01:00
** Direct Forces
:PROPERTIES:
:UNNUMBERED: t
:END:
2019-12-11 17:34:42 +01:00
#+begin_src matlab
u = zeros(length(t), 6);
Fd = u;
#+end_src
2020-02-03 17:50:32 +01:00
** Set initial value to zero
:PROPERTIES:
:UNNUMBERED: t
:END:
2019-12-11 17:34:42 +01:00
#+begin_src matlab
Dwx = Dwx - Dwx(1);
Dwy = Dwy - Dwy(1);
Dwz = Dwz - Dwz(1);
Fty_x = Fty_x - Fty_x(1);
Fty_z = Fty_z - Fty_z(1);
Frz_z = Frz_z - Frz_z(1);
#+end_src
2020-02-03 17:50:32 +01:00
** Save
:PROPERTIES:
:UNNUMBERED: t
:END:
2019-12-11 17:34:42 +01:00
#+begin_src matlab
2020-04-15 10:56:18 +02:00
save('./mat/nass_disturbances.mat', 'Dwx', 'Dwy', 'Dwz', 'Fty_x', 'Fty_z', 'Frz_z', 'Fd', 'Ts', 't', 'args');
2019-12-11 17:34:42 +01:00
#+end_src
2020-02-25 17:49:08 +01:00
* Initialize Position Errors
:PROPERTIES:
:header-args:matlab+: :tangle ../src/initializePosError.m
:header-args:matlab+: :comments none :mkdirp yes
:header-args:matlab+: :eval no :results none
:END:
<<sec:initializePosError >>
** Function Declaration and Documentation
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
function [] = initializePosError(args)
% initializePosError - Initialize the position errors
%
% Syntax: [] = initializePosError(args)
%
% Inputs:
% - args -
#+end_src
** Optional Parameters
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
arguments
args.error logical {mustBeNumericOrLogical} = false
args.Dy (1,1) double {mustBeNumeric} = 0 % [m]
args.Ry (1,1) double {mustBeNumeric} = 0 % [m]
args.Rz (1,1) double {mustBeNumeric} = 0 % [m]
end
#+end_src
** Structure initialization
:PROPERTIES:
:UNNUMBERED: t
:END:
First, we initialize the =pos_error= structure.
#+begin_src matlab
pos_error = struct();
#+end_src
** Type
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
if args.error
pos_error.type = 1;
else
pos_error.type = 0;
end
#+end_src
** Position Errors
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
pos_error.Dy = args.Dy;
pos_error.Ry = args.Ry;
pos_error.Rz = args.Rz;
#+end_src
** Save
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
2020-03-13 17:40:22 +01:00
save('./mat/pos_error.mat', 'pos_error');
2020-02-25 17:49:08 +01:00
#+end_src
2020-02-03 17:50:32 +01:00
* Z-Axis Geophone
2020-01-16 11:49:13 +01:00
:PROPERTIES:
:header-args:matlab+: :tangle ../src/initializeZAxisGeophone.m
:header-args:matlab+: :comments none :mkdirp yes :eval no
:END:
<<sec:initializeZAxisGeophone >>
#+begin_src matlab
function [geophone] = initializeZAxisGeophone(args)
arguments
args.mass (1,1) double {mustBeNumeric, mustBePositive} = 1e-3 % [kg]
args.freq (1,1) double {mustBeNumeric, mustBePositive} = 1 % [Hz]
end
%%
geophone.m = args.mass;
%% The Stiffness is set to have the damping resonance frequency
geophone.k = geophone.m * (2*pi*args.freq)^2;
%% We set the damping value to have critical damping
geophone.c = 2*sqrt(geophone.m * geophone.k);
%% Save
save('./mat/geophone_z_axis.mat', 'geophone');
end
#+end_src
2020-02-03 17:50:32 +01:00
* Z-Axis Accelerometer
2020-01-16 11:49:13 +01:00
:PROPERTIES:
:header-args:matlab+: :tangle ../src/initializeZAxisAccelerometer.m
:header-args:matlab+: :comments none :mkdirp yes :eval no
:END:
<<sec:initializeZAxisAccelerometer >>
#+begin_src matlab
function [accelerometer] = initializeZAxisAccelerometer(args)
arguments
args.mass (1,1) double {mustBeNumeric, mustBePositive} = 1e-3 % [kg]
2020-01-20 17:21:11 +01:00
args.freq (1,1) double {mustBeNumeric, mustBePositive} = 5e3 % [Hz]
2020-01-16 11:49:13 +01:00
end
%%
accelerometer.m = args.mass;
%% The Stiffness is set to have the damping resonance frequency
accelerometer.k = accelerometer.m * (2*pi*args.freq)^2;
%% We set the damping value to have critical damping
accelerometer.c = 2*sqrt(accelerometer.m * accelerometer.k);
2020-01-20 17:21:11 +01:00
%% Gain correction of the accelerometer to have a unity gain until the resonance
accelerometer.gain = -accelerometer.k/accelerometer.m;
2020-01-16 11:49:13 +01:00
%% Save
save('./mat/accelerometer_z_axis.mat', 'accelerometer');
end
#+end_src
2020-02-03 17:50:32 +01:00
* Old functions :noexport:
2019-12-11 17:09:32 +01:00
** Micro Hexapod
:PROPERTIES:
2020-02-03 17:50:32 +01:00
:header-args:matlab+: :tangle ../src/initializeMicroHexapodOld.m
2019-12-11 17:09:32 +01:00
:header-args:matlab+: :comments none :mkdirp yes :eval no
:END:
<<sec:initializeMicroHexapod >>
#+begin_src matlab
2020-01-13 11:42:31 +01:00
function [micro_hexapod] = initializeMicroHexapod(args)
arguments
args.rigid logical {mustBeNumericOrLogical} = false
args.AP (3,1) double {mustBeNumeric} = zeros(3,1)
args.ARB (3,3) double {mustBeNumeric} = eye(3)
2019-12-11 17:09:32 +01:00
end
%% Stewart Object
micro_hexapod = struct();
micro_hexapod.h = 350; % Total height of the platform [mm]
micro_hexapod.jacobian = 270; % Distance from the top of the mobile platform to the Jacobian point [mm]
%% Bottom Plate - Mechanical Design
BP = struct();
BP.rad.int = 110; % Internal Radius [mm]
BP.rad.ext = 207.5; % External Radius [mm]
BP.thickness = 26; % Thickness [mm]
BP.leg.rad = 175.5; % Radius where the legs articulations are positionned [mm]
BP.leg.ang = 9.5; % Angle Offset [deg]
BP.density = 8000; % Density of the material [kg/m^3]
BP.color = [0.6 0.6 0.6]; % Color [rgb]
BP.shape = [BP.rad.int BP.thickness; BP.rad.int 0; BP.rad.ext 0; BP.rad.ext BP.thickness];
%% Top Plate - Mechanical Design
TP = struct();
TP.rad.int = 82; % Internal Radius [mm]
TP.rad.ext = 150; % Internal Radius [mm]
TP.thickness = 26; % Thickness [mm]
TP.leg.rad = 118; % Radius where the legs articulations are positionned [mm]
TP.leg.ang = 12.1; % Angle Offset [deg]
TP.density = 8000; % Density of the material [kg/m^3]
TP.color = [0.6 0.6 0.6]; % Color [rgb]
TP.shape = [TP.rad.int TP.thickness; TP.rad.int 0; TP.rad.ext 0; TP.rad.ext TP.thickness];
%% Struts
Leg = struct();
Leg.stroke = 10e-3; % Maximum Stroke of each leg [m]
2020-01-13 11:42:31 +01:00
if args.rigid
2019-12-11 17:09:32 +01:00
Leg.k.ax = 1e12; % Stiffness of each leg [N/m]
else
Leg.k.ax = 2e7; % Stiffness of each leg [N/m]
end
Leg.ksi.ax = 0.1; % Modal damping ksi = 1/2*c/sqrt(km) []
Leg.rad.bottom = 25; % Radius of the cylinder of the bottom part [mm]
Leg.rad.top = 17; % Radius of the cylinder of the top part [mm]
Leg.density = 8000; % Density of the material [kg/m^3]
Leg.color.bottom = [0.5 0.5 0.5]; % Color [rgb]
Leg.color.top = [0.5 0.5 0.5]; % Color [rgb]
Leg.sphere.bottom = Leg.rad.bottom; % Size of the sphere at the end of the leg [mm]
Leg.sphere.top = Leg.rad.top; % Size of the sphere at the end of the leg [mm]
Leg.m = TP.density*((pi* (TP.rad.ext/1000)^2)*(TP.thickness/1000)-(pi* (TP.rad.int/1000^2))*(TP.thickness/1000))/6; % TODO [kg]
Leg = updateDamping(Leg);
%% Sphere
SP = struct();
SP.height.bottom = 27; % [mm]
SP.height.top = 27; % [mm]
SP.density.bottom = 8000; % [kg/m^3]
SP.density.top = 8000; % [kg/m^3]
SP.color.bottom = [0.6 0.6 0.6]; % [rgb]
SP.color.top = [0.6 0.6 0.6]; % [rgb]
SP.k.ax = 0; % [N*m/deg]
SP.ksi.ax = 10;
SP.thickness.bottom = SP.height.bottom-Leg.sphere.bottom; % [mm]
SP.thickness.top = SP.height.top-Leg.sphere.top; % [mm]
SP.rad.bottom = Leg.sphere.bottom; % [mm]
SP.rad.top = Leg.sphere.top; % [mm]
SP.m = SP.density.bottom*2*pi*((SP.rad.bottom*1e-3)^2)* (SP.height.bottom*1e-3); % TODO [kg]
SP = updateDamping(SP);
%%
Leg.support.bottom = [0 SP.thickness.bottom; 0 0; SP.rad.bottom 0; SP.rad.bottom SP.height.bottom];
Leg.support.top = [0 SP.thickness.top; 0 0; SP.rad.top 0; SP.rad.top SP.height.top];
%%
micro_hexapod.BP = BP;
micro_hexapod.TP = TP;
micro_hexapod.Leg = Leg;
micro_hexapod.SP = SP;
%%
micro_hexapod = initializeParameters(micro_hexapod);
%% Setup equilibrium position of each leg
2020-01-13 11:42:31 +01:00
micro_hexapod.L0 = inverseKinematicsHexapod(micro_hexapod, args.AP, args.ARB);
2019-12-11 17:09:32 +01:00
%% Save
save('./mat/stages.mat', 'micro_hexapod', '-append');
%%
function [element] = updateDamping(element)
field = fieldnames(element.k);
for i = 1:length(field)
element.c.(field{i}) = 2*element.ksi.(field{i})*sqrt(element.k.(field{i})*element.m);
end
end
%%
function [stewart] = initializeParameters(stewart)
%% Connection points on base and top plate w.r.t. World frame at the center of the base plate
stewart.pos_base = zeros(6, 3);
stewart.pos_top = zeros(6, 3);
alpha_b = stewart.BP.leg.ang*pi/180; % angle de décalage par rapport à 120 deg (pour positionner les supports bases)
alpha_t = stewart.TP.leg.ang*pi/180; % +- offset angle from 120 degree spacing on top
height = (stewart.h-stewart.BP.thickness-stewart.TP.thickness-stewart.Leg.sphere.bottom-stewart.Leg.sphere.top-stewart.SP.thickness.bottom-stewart.SP.thickness.top)*0.001; % TODO
radius_b = stewart.BP.leg.rad*0.001; % rayon emplacement support base
radius_t = stewart.TP.leg.rad*0.001; % top radius in meters
for i = 1:3
% base points
angle_m_b = (2*pi/3)* (i-1) - alpha_b;
angle_p_b = (2*pi/3)* (i-1) + alpha_b;
stewart.pos_base(2*i-1,:) = [radius_b*cos(angle_m_b), radius_b*sin(angle_m_b), 0.0];
stewart.pos_base(2*i,:) = [radius_b*cos(angle_p_b), radius_b*sin(angle_p_b), 0.0];
% top points
% Top points are 60 degrees offset
angle_m_t = (2*pi/3)* (i-1) - alpha_t + 2*pi/6;
angle_p_t = (2*pi/3)* (i-1) + alpha_t + 2*pi/6;
stewart.pos_top(2*i-1,:) = [radius_t*cos(angle_m_t), radius_t*sin(angle_m_t), height];
stewart.pos_top(2*i,:) = [radius_t*cos(angle_p_t), radius_t*sin(angle_p_t), height];
end
% permute pos_top points so that legs are end points of base and top points
stewart.pos_top = [stewart.pos_top(6,:); stewart.pos_top(1:5,:)]; %6th point on top connects to 1st on bottom
stewart.pos_top_tranform = stewart.pos_top - height*[zeros(6, 2),ones(6, 1)];
%% leg vectors
legs = stewart.pos_top - stewart.pos_base;
leg_length = zeros(6, 1);
leg_vectors = zeros(6, 3);
for i = 1:6
leg_length(i) = norm(legs(i,:));
leg_vectors(i,:) = legs(i,:) / leg_length(i);
end
stewart.Leg.lenght = 1000*leg_length(1)/1.5;
stewart.Leg.shape.bot = [0 0; ...
stewart.Leg.rad.bottom 0; ...
stewart.Leg.rad.bottom stewart.Leg.lenght; ...
stewart.Leg.rad.top stewart.Leg.lenght; ...
stewart.Leg.rad.top 0.2*stewart.Leg.lenght; ...
0 0.2*stewart.Leg.lenght];
%% Calculate revolute and cylindrical axes
rev1 = zeros(6, 3);
rev2 = zeros(6, 3);
cyl1 = zeros(6, 3);
for i = 1:6
rev1(i,:) = cross(leg_vectors(i,:), [0 0 1]);
rev1(i,:) = rev1(i,:) / norm(rev1(i,:));
rev2(i,:) = - cross(rev1(i,:), leg_vectors(i,:));
rev2(i,:) = rev2(i,:) / norm(rev2(i,:));
cyl1(i,:) = leg_vectors(i,:);
end
%% Coordinate systems
stewart.lower_leg = struct('rotation', eye(3));
stewart.upper_leg = struct('rotation', eye(3));
for i = 1:6
stewart.lower_leg(i).rotation = [rev1(i,:)', rev2(i,:)', cyl1(i,:)'];
stewart.upper_leg(i).rotation = [rev1(i,:)', rev2(i,:)', cyl1(i,:)'];
end
%% Position Matrix
stewart.M_pos_base = stewart.pos_base + (height+ (stewart.TP.thickness+stewart.Leg.sphere.top+stewart.SP.thickness.top+stewart.jacobian)*1e-3)* [zeros(6, 2),ones(6, 1)];
%% Compute Jacobian Matrix
aa = stewart.pos_top_tranform + (stewart.jacobian - stewart.TP.thickness - stewart.SP.height.top)*1e-3* [zeros(6, 2),ones(6, 1)];
stewart.J = getJacobianMatrix(leg_vectors', aa');
end
%%
function J = getJacobianMatrix(RM, M_pos_base)
% RM: [3x6] unit vector of each leg in the fixed frame
% M_pos_base: [3x6] vector of the leg connection at the top platform location in the fixed frame
J = zeros(6);
J(:, 1:3) = RM';
J(:, 4:6) = cross(M_pos_base, RM)';
end
end
#+end_src
** Cedrat Actuator
:PROPERTIES:
:header-args:matlab+: :tangle ../src/initializeCedratPiezo.m
:header-args:matlab+: :comments none :mkdirp yes :eval no
:END:
<<sec:initializeCedratPiezo >>
#+begin_src matlab
2020-01-13 11:42:31 +01:00
function [cedrat] = initializeCedratPiezo()
2019-12-11 17:09:32 +01:00
%% Stewart Object
cedrat = struct();
cedrat.k = 10e7; % Linear Stiffness of each "blade" [N/m]
cedrat.ka = 10e7; % Linear Stiffness of the stack [N/m]
cedrat.c = 0.1*sqrt(1*cedrat.k); % [N/(m/s)]
cedrat.ca = 0.1*sqrt(1*cedrat.ka); % [N/(m/s)]
cedrat.L = 80; % Total Width of the Actuator[mm]
cedrat.H = 45; % Total Height of the Actuator [mm]
cedrat.L2 = sqrt((cedrat.L/2)^2 + (cedrat.H/2)^2); % Length of the elipsoidal sections [mm]
cedrat.alpha = 180/pi*atan2(cedrat.L/2, cedrat.H/2); % [deg]
%% Save
save('./mat/stages.mat', 'cedrat', '-append');
end
#+end_src