diff --git a/docs/flexible_joints_study.html b/docs/flexible_joints_study.html index 2e773ce..3eccd2c 100644 --- a/docs/flexible_joints_study.html +++ b/docs/flexible_joints_study.html @@ -1,10 +1,9 @@ - - + Study of the Flexible Joints @@ -37,19 +36,19 @@ @@ -106,8 +112,8 @@ In this section, we wish to study the effect of the rotation flexibility of the

-
-

1.1 Initialization

+
+

1.1 Initialization

Let’s initialize all the stages with default parameters. @@ -128,8 +134,8 @@ initializeMirror(); Let’s consider the heaviest mass which should we the most problematic with it comes to the flexible joints.

-
initializeSample('mass', 50, 'freq', 200*ones(6,1));
-initializeReferences('Rz_type', 'rotating-not-filtered', 'Rz_period', 60);
+
initializeSample('mass', 50, 'freq', 200*ones(6,1));
+initializeReferences('Rz_type', 'rotating-not-filtered', 'Rz_period', 60);
 
@@ -147,10 +153,10 @@ Let’s compare the ideal case (zero stiffness in rotation and infinite stif
-
Kf_M = 15*ones(6,1);
-Kf_F = 15*ones(6,1);
-Kt_M = 20*ones(6,1);
-Kt_F = 20*ones(6,1);
+
Kf_M = 15*ones(6,1);
+Kf_F = 15*ones(6,1);
+Kt_M = 20*ones(6,1);
+Kt_F = 20*ones(6,1);
 
@@ -158,8 +164,8 @@ Kt_F = 20*ones(6,1); The stiffness and damping of the nano-hexapod’s legs are:

-
k_opt = 1e5; % [N/m]
-c_opt = 2e2; % [N/(m/s)]
+
k_opt = 1e5; % [N/m]
+c_opt = 2e2; % [N/(m/s)]
 
@@ -168,8 +174,8 @@ This corresponds to the optimal identified stiffness.

-
-

1.2.1 Direct Velocity Feedback

+
+

1.2.1 Direct Velocity Feedback

We identify the dynamics from actuators force \(\tau_i\) to relative motion sensors \(d\mathcal{L}_i\) with and without considering the flexible joint stiffness. @@ -189,8 +195,8 @@ It is shown that the adding of stiffness for the flexible joints does increase a

-
-

1.2.2 Primary Plant

+
+

1.2.2 Primary Plant

Let’s now identify the dynamics from \(\bm{\tau}^\prime\) to \(\bm{\epsilon}_{\mathcal{X}_n}\) (for the primary controller designed in the frame of the legs). @@ -210,10 +216,10 @@ The plant dynamics is not found to be changing significantly.

-
-

1.2.3 Conclusion

+
+

1.2.3 Conclusion

-
+

Considering realistic flexible joint bending stiffness for the nano-hexapod does not seems to impose any limitation on the DVF control nor on the primary control.

@@ -239,7 +245,7 @@ This will help to determine the requirements on the joint’s stiffness. Let’s consider the following bending stiffness of the flexible joints:

-
Ks = [1, 5, 10, 50, 100]; % [Nm/rad]
+
Ks = [1, 5, 10, 50, 100]; % [Nm/rad]
 
@@ -248,8 +254,8 @@ We also consider here a nano-hexapod with the identified optimal actuator stiffn

-
-

1.3.1 Direct Velocity Feedback

+
+

1.3.1 Direct Velocity Feedback

The dynamics from the actuators to the relative displacement sensor in each leg is identified and shown in Figure 3. @@ -279,8 +285,8 @@ It is shown that the bending stiffness of the flexible joints does indeed change

-
-

1.3.2 Primary Control

+
+

1.3.2 Primary Control

The dynamics from \(\bm{\tau}^\prime\) to \(\bm{\epsilon}_{\mathcal{X}_n}\) (for the primary controller designed in the frame of the legs) is shown in Figure 5. @@ -299,10 +305,10 @@ It is shown that the bending stiffness of the flexible joints have very little i

-
-

1.3.3 Conclusion

+
+

1.3.3 Conclusion

-
+

The bending stiffness of the flexible joint does not significantly change the dynamics.

@@ -333,16 +339,16 @@ We choose realistic values of the axial stiffness of the joints:

-
Kz_F = 60e6*ones(6,1); % [N/m]
-Kz_M = 60e6*ones(6,1); % [N/m]
-Cz_F = 1*ones(6,1); % [N/(m/s)]
-Cz_M = 1*ones(6,1); % [N/(m/s)]
+
Ka_F = 60e6*ones(6,1); % [N/m]
+Ka_M = 60e6*ones(6,1); % [N/m]
+Ca_F = 1*ones(6,1); % [N/(m/s)]
+Ca_M = 1*ones(6,1); % [N/(m/s)]
 
-
-

2.1.1 Initialization

+
+

2.1.1 Initialization

Let’s initialize all the stages with default parameters. @@ -363,15 +369,15 @@ initializeMirror(); Let’s consider the heaviest mass which should we the most problematic with it comes to the flexible joints.

-
initializeSample('mass', 50, 'freq', 200*ones(6,1));
-initializeReferences('Rz_type', 'rotating-not-filtered', 'Rz_period', 60);
+
initializeSample('mass', 50, 'freq', 200*ones(6,1));
+initializeReferences('Rz_type', 'rotating-not-filtered', 'Rz_period', 60);
 
-
-

2.1.2 Direct Velocity Feedback

+
+

2.1.2 Direct Velocity Feedback

The dynamics from actuators force \(\tau_i\) to relative motion sensors \(d\mathcal{L}_i\) with and without considering the flexible joint stiffness are identified. @@ -390,11 +396,11 @@ The obtained dynamics are shown in Figure 6.

-
-

2.1.3 Primary Plant

+
+

2.1.3 Primary Plant

-
Kdvf = 5e3*s/(1+s/2/pi/1e3)*eye(6);
+
Kdvf = 5e3*s/(1+s/2/pi/1e3)*eye(6);
 
@@ -415,10 +421,10 @@ The dynamics is compare with and without the joint flexibility in Figure
-
-

2.1.4 Conclusion

+
+

2.1.4 Conclusion

-
+

For the realistic value of the flexible joint axial stiffness, the dynamics is not much impact, and this should not be a problem for control.

@@ -439,7 +445,7 @@ We wish now to see what is the impact of the axial stiffness of the flexi Let’s consider the following values for the axial stiffness:

-
Kzs = [1e4, 1e5, 1e6, 1e7, 1e8, 1e9]; % [N/m]
+
Kas = [1e4, 1e5, 1e6, 1e7, 1e8, 1e9]; % [N/m]
 
@@ -448,8 +454,8 @@ We also consider here a nano-hexapod with the identified optimal actuator stiffn

-
-

2.2.1 Direct Velocity Feedback

+
-
-

2.2.2 Primary Control

+
-
-

2.3 Conclusion

+
+

2.3 Conclusion

-
+

The axial stiffness of the flexible joints should be maximized.

@@ -533,14 +539,14 @@ We may interpolate the results and say that the axial joint stiffness should be
-
-

3 Conclusion

+
+

3 Conclusion

-
+

In this study we considered the bending, torsional and axial stiffnesses of the flexible joints used for the nano-hexapod.

@@ -575,10 +581,80 @@ As there is generally a trade-off between bending stiffness and axial stiffness,
+ + +
+

4 Designed Flexible Joints

+
+
+
+

4.1 Initialization

+
+

+Let’s initialize all the stages with default parameters. +

+
+
initializeGround();
+initializeGranite();
+initializeTy();
+initializeRy();
+initializeRz();
+initializeMicroHexapod();
+initializeAxisc('type', 'none');
+initializeMirror('type', 'none');
+initializeMirror();
+
+
+ +

+Let’s consider the heaviest mass which should we the most problematic with it comes to the flexible joints. +

+
+
initializeSample('mass', 50, 'freq', 200*ones(6,1));
+initializeReferences('Rz_type', 'rotating-not-filtered', 'Rz_period', 60);
+
+
+ +
+
flex_joint = load('./mat/flexor_025.mat', 'int_xyz', 'int_i', 'n_xyz', 'n_i', 'nodes', 'M', 'K');
+apa = load('./mat/APA300ML_simplified_model.mat');
+
+
+ +
+
initializeNanoHexapod('actuator', 'amplified', ...
+                      'ke', apa.ke, 'ka', apa.ka, 'k1', apa.k1, 'c1', apa.c1, 'F_gain', apa.F_gain, ...
+                      'type_M', 'spherical_3dof', ...
+                      'Kr_M', flex_joint.K(1,1)*ones(6,1), ...
+                      'Ka_M', flex_joint.K(3,3)*ones(6,1), ...
+                      'Kf_M', flex_joint.K(4,4)*ones(6,1), ...
+                      'Kt_M', flex_joint.K(6,6)*ones(6,1), ...
+                      'type_F', 'spherical_3dof', ...
+                      'Kr_F', flex_joint.K(1,1)*ones(6,1), ...
+                      'Ka_F', flex_joint.K(3,3)*ones(6,1), ...
+                      'Kf_F', flex_joint.K(4,4)*ones(6,1), ...
+                      'Kt_F', flex_joint.K(6,6)*ones(6,1));
+
+
+ +
+
initializeNanoHexapod();
+
+
+
+
+ +
+

4.2 Direct Velocity Feedback

+
+
+

4.3 Integral Force Feedback

+
+

Author: Dehaeze Thomas

-

Created: 2020-05-05 mar. 11:50

+

Created: 2020-11-03 mar. 09:45

diff --git a/docs/simscape_subsystems.html b/docs/simscape_subsystems.html index f9bb5f5..02e8983 100644 --- a/docs/simscape_subsystems.html +++ b/docs/simscape_subsystems.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Subsystems used for the Simscape Models @@ -28,173 +28,173 @@
-
-

Function description

-
+
+

Function description

+
-
function [] = initializeSimscapeConfiguration(args)
+
function [] = initializeSimscapeConfiguration(args)
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
-  args.gravity logical {mustBeNumericOrLogical} = true
-end
+  args.gravity logical {mustBeNumericOrLogical} = true
+end
 
-
-

Structure initialization

-
+
+

Structure initialization

+
conf_simscape = struct();
 
@@ -286,25 +286,25 @@ end
-
-

Add Type

-
+
+

Add Type

+
-
if args.gravity
+
if args.gravity
   conf_simscape.type = 1;
-else
+else
   conf_simscape.type = 2;
-end
+end
 
-
-

Save the Structure

-
+
+

Save the Structure

+
-
save('./mat/conf_simscape.mat', 'conf_simscape');
+
save('./mat/conf_simscape.mat', 'conf_simscape');
 
@@ -319,32 +319,32 @@ end

-
-

Function description

-
+
+

Function description

+
-
function [] = initializeLoggingConfiguration(args)
+
function [] = initializeLoggingConfiguration(args)
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
-  args.log      char   {mustBeMember(args.log,{'none', 'all', 'forces'})} = 'none'
-  args.Ts (1,1) double {mustBeNumeric, mustBePositive} = 1e-3
-end
+  args.log      char   {mustBeMember(args.log,{'none', 'all', 'forces'})} = 'none'
+  args.Ts (1,1) double {mustBeNumeric, mustBePositive} = 1e-3
+end
 
-
-

Structure initialization

-
+
+

Structure initialization

+
conf_log = struct();
 
@@ -352,18 +352,18 @@ end
-
-

Add Type

-
+
+

Add Type

+
-
switch args.log
-  case 'none'
+
switch args.log
+  case 'none'
     conf_log.type = 0;
-  case 'all'
+  case 'all'
     conf_log.type = 1;
-  case 'forces'
+  case 'forces'
     conf_log.type = 2;
-end
+end
 
@@ -379,11 +379,11 @@ end
-
-

Save the Structure

-
+
+

Save the Structure

+
-
save('./mat/conf_log.mat', 'conf_log');
+
save('./mat/conf_log.mat', 'conf_log');
 
@@ -398,9 +398,9 @@ end

-
-

Simscape Model

-
+
+

Simscape Model

+

The model of the Ground is composed of:

@@ -425,32 +425,32 @@ The model of the Ground is composed of:
-
-

Function description

-
+
+

Function description

+
-
function [ground] = initializeGround(args)
+
function [ground] = initializeGround(args)
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
-  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]
-end
+  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]
+end
 
-
-

Structure initialization

-
+
+

Structure initialization

+

First, we initialize the granite structure.

@@ -461,16 +461,16 @@ First, we initialize the granite structure.
-
-

Add Type

-
+
+

Add Type

+
-
switch args.type
-  case 'none'
+
switch args.type
+  case 'none'
     ground.type = 0;
-  case 'rigid'
+  case 'rigid'
     ground.type = 1;
-end
+end
 
@@ -483,8 +483,8 @@ end We set the shape and density of the ground solid element.

-
ground.shape   = [2, 2, 0.5]; % [m]
-ground.density = 2800;        % [kg/m3]
+
ground.shape   = [2, 2, 0.5]; % [m]
+ground.density = 2800;        % [kg/m3]
 
@@ -500,14 +500,14 @@ ground.density = 2800; % [kg/m3]
-
-

Save the Structure

-
+
+

Save the Structure

+

The ground structure is saved.

-
save('./mat/stages.mat', 'ground', '-append');
+
save('./mat/stages.mat', 'ground', '-append');
 
@@ -522,9 +522,9 @@ The ground structure is saved.

-
-

Simscape Model

-
+
+

Simscape Model

+

The Simscape model of the granite is composed of:

@@ -553,38 +553,39 @@ The output sample_pos corresponds to the impact point of the X-ray.
-
-

Function description

-
+
+

Function description

+
-
function [granite] = initializeGranite(args)
+
function [granite] = initializeGranite(args)
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
-  args.type          char    {mustBeMember(args.type,{'rigid', 'flexible', 'none', 'modal-analysis', 'init'})} = 'flexible'
-  args.Foffset       logical {mustBeNumericOrLogical} = false
-  args.density (1,1) double {mustBeNumeric, mustBeNonnegative} = 2800 % Density [kg/m3]
-  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)]
-  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]
-end
+  args.type          char    {mustBeMember(args.type,{'rigid', 'flexible', 'none', 'modal-analysis', 'init'})} = 'flexible'
+  args.Foffset       logical {mustBeNumericOrLogical} = false
+  args.density (1,1) double {mustBeNumeric, mustBeNonnegative} = 2800 % Density [kg/m3]
+  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)]
+  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]
+  args.sample_pos (1,1) double {mustBeNumeric} = 0.8 % Height of the measurment point [m]
+end
 
-
-

Structure initialization

-
+
+

Structure initialization

+

First, we initialize the granite structure.

@@ -599,32 +600,32 @@ First, we initialize the granite structure.

Add Granite Type

-
switch args.type
-  case 'none'
+
switch args.type
+  case 'none'
     granite.type = 0;
-  case 'rigid'
+  case 'rigid'
     granite.type = 1;
-  case 'flexible'
+  case 'flexible'
     granite.type = 2;
-  case 'modal-analysis'
+  case 'modal-analysis'
     granite.type = 3;
-  case 'init'
+  case 'init'
     granite.type = 4;
-end
+end
 
-
-

Material and Geometry

-
+
+

Material and Geometry

+

Properties of the Material and link to the geometry of the granite.

-
granite.density = args.density; % [kg/m3]
-granite.STEP    = './STEPS/granite/granite.STEP';
+
granite.density = args.density; % [kg/m3]
+granite.STEP    = './STEPS/granite/granite.STEP';
 
@@ -632,63 +633,63 @@ granite.STEP = './STEPS/granite/granite.STEP'; Z-offset for the initial position of the sample with respect to the granite top surface.

-
granite.sample_pos = 0.8; % [m]
+
granite.sample_pos = args.sample_pos; % [m]
 
-
-

Stiffness and Damping properties

-
+
+

Stiffness and Damping properties

+
-
granite.K = args.K; % [N/m]
-granite.C = args.C; % [N/(m/s)]
+
granite.K = args.K; % [N/m]
+granite.C = args.C; % [N/(m/s)]
 
-
-

Equilibrium position of the each joint.

-
+
+

Equilibrium position of the each joint.

+
-
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
+
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
+end
 
-
-

Save the Structure

-
+
+

Save the Structure

+

The granite structure is saved.

-
save('./mat/stages.mat', 'granite', '-append');
+
save('./mat/stages.mat', 'granite', '-append');
 
-
-

5 Translation Stage

+
+

5 Translation Stage

-
-

Simscape Model

-
+
+

Simscape Model

+

The Simscape model of the Translation stage consist of:

@@ -718,32 +719,32 @@ It is used to impose the motion in the Y direction
-
-

Function description

-
+
+

Function description

+
-
function [ty] = initializeTy(args)
+
function [ty] = initializeTy(args)
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
-  args.type      char   {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init'})} = 'flexible'
-  args.Foffset logical {mustBeNumericOrLogical} = false
-end
+  args.type      char   {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init'})} = 'flexible'
+  args.Foffset logical {mustBeNumericOrLogical} = false
+end
 
-
-

Structure initialization

-
+
+

Structure initialization

+

First, we initialize the ty structure.

@@ -758,121 +759,121 @@ First, we initialize the ty structure.

Add Translation Stage Type

-
switch args.type
-  case 'none'
+
switch args.type
+  case 'none'
     ty.type = 0;
-  case 'rigid'
+  case 'rigid'
     ty.type = 1;
-  case 'flexible'
+  case 'flexible'
     ty.type = 2;
-  case 'modal-analysis'
+  case 'modal-analysis'
     ty.type = 3;
-  case 'init'
+  case 'init'
     ty.type = 4;
-end
+end
 
-
-

Material and Geometry

-
+
+

Material and Geometry

+

Define the density of the materials as well as the geometry (STEP files).

-
% Ty Granite frame
-ty.granite_frame.density = 7800; % [kg/m3] => 43kg
-ty.granite_frame.STEP    = './STEPS/Ty/Ty_Granite_Frame.STEP';
+
% 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';
+% 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_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_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_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 - 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 - 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 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';
+% Ty Rotor Part
+ty.rotor.density         = 5400; % [kg/m3]
+ty.rotor.STEP            = './STEPS/ty/Ty_Motor_Rotor.STEP';
 
-
-

Stiffness and Damping properties

-
+
+

Stiffness and Damping properties

+
-
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)]
+
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)]
 
-
-

Equilibrium position of the each joint.

-
+
+

Equilibrium position of the each joint.

+
-
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
+
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
+end
 
-
-

Save the Structure

-
+
+

Save the Structure

+

The ty structure is saved.

-
save('./mat/stages.mat', 'ty', '-append');
+
save('./mat/stages.mat', 'ty', '-append');
 
-
-

6 Tilt Stage

+
+

6 Tilt Stage

-
-

Simscape Model

-
+
+

Simscape Model

+

The Simscape model of the Tilt stage is composed of:

@@ -902,33 +903,33 @@ The Ry motion is imposed by the input.
-
-

Function description

-
+
+

Function description

+
-
function [ry] = initializeRy(args)
+
function [ry] = initializeRy(args)
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
-  args.type          char    {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init'})} = 'flexible'
-  args.Foffset       logical {mustBeNumericOrLogical} = false
+  args.type          char    {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init'})} = 'flexible'
+  args.Foffset       logical {mustBeNumericOrLogical} = false
   args.Ry_init (1,1) double  {mustBeNumeric} = 0
-end
+end
 
-
-

Structure initialization

-
+
+

Structure initialization

+

First, we initialize the ry structure.

@@ -944,45 +945,45 @@ First, we initialize the ry structure.

Add Tilt Type

-
switch args.type
-  case 'none'
+
switch args.type
+  case 'none'
     ry.type = 0;
-  case 'rigid'
+  case 'rigid'
     ry.type = 1;
-  case 'flexible'
+  case 'flexible'
     ry.type = 2;
-  case 'modal-analysis'
+  case 'modal-analysis'
     ry.type = 3;
-  case 'init'
+  case 'init'
     ry.type = 4;
-end
+end
 
-
-

Material and Geometry

-
+
+

Material and Geometry

+

Properties of the Material and link to the geometry of the Tilt stage.

-
% Ry - Guide for the tilt stage
-ry.guide.density = 7800; % [kg/m3]
-ry.guide.STEP    = './STEPS/ry/Tilt_Guide.STEP';
+
% 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 - 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 - 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';
+% Ry - Plateau Tilt
+ry.stage.density = 7800; % [kg/m3]
+ry.stage.STEP    = './STEPS/ry/Tilt_Stage.STEP';
 
@@ -990,20 +991,20 @@ ry.stage.STEP = './STEPS/ry/Tilt_Stage.STEP'; Z-Offset so that the center of rotation matches the sample center;

-
ry.z_offset = 0.58178; % [m]
+
ry.z_offset = 0.58178; % [m]
 
-
ry.Ry_init = args.Ry_init; % [rad]
+
ry.Ry_init = args.Ry_init; % [rad]
 
-
-

Stiffness and Damping properties

-
+
+

Stiffness and Damping properties

+
ry.K = [3.8e8; 4e8; 3.8e8; 1.2e8; 6e4; 1.2e8];
 ry.C = [1e5;   1e5; 1e5;   3e4;   1e3; 3e4];
@@ -1012,46 +1013,46 @@ ry.C = [1e5;   1e5; 1e5;   3e4;   1e3; 3e4];
 
-
-

Equilibrium position of the each joint.

-
+
+

Equilibrium position of the each joint.

+
-
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
+
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
+end
 
-
-

Save the Structure

-
+
+

Save the Structure

+

The ry structure is saved.

-
save('./mat/stages.mat', 'ry', '-append');
+
save('./mat/stages.mat', 'ry', '-append');
 
-
-

7 Spindle

+
+

7 Spindle

-
-

Simscape Model

-
+
+

Simscape Model

+

The Simscape model of the Spindle is composed of:

@@ -1077,32 +1078,32 @@ The Simscape model of the Spindle is composed of:
-
-

Function description

-
+
+

Function description

+
-
function [rz] = initializeRz(args)
+
function [rz] = initializeRz(args)
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
-  args.type    char    {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init'})} = 'flexible'
-  args.Foffset logical {mustBeNumericOrLogical} = false
-end
+  args.type    char    {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init'})} = 'flexible'
+  args.Foffset logical {mustBeNumericOrLogical} = false
+end
 
-
-

Structure initialization

-
+
+

Structure initialization

+

First, we initialize the rz structure.

@@ -1117,49 +1118,49 @@ First, we initialize the rz structure.

Add Spindle Type

-
switch args.type
-  case 'none'
+
switch args.type
+  case 'none'
     rz.type = 0;
-  case 'rigid'
+  case 'rigid'
     rz.type = 1;
-  case 'flexible'
+  case 'flexible'
     rz.type = 2;
-  case 'modal-analysis'
+  case 'modal-analysis'
     rz.type = 3;
-  case 'init'
+  case 'init'
     rz.type = 4;
-end
+end
 
-
-

Material and Geometry

-
+
+

Material and Geometry

+

Properties of the Material and link to the geometry of the spindle.

-
% Spindle - Slip Ring
-rz.slipring.density = 7800; % [kg/m3]
-rz.slipring.STEP    = './STEPS/rz/Spindle_Slip_Ring.STEP';
+
% 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 - 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';
+% Spindle - Stator
+rz.stator.density   = 7800; % [kg/m3]
+rz.stator.STEP      = './STEPS/rz/Spindle_Stator.STEP';
 
-
-

Stiffness and Damping properties

-
+
+

Stiffness and Damping properties

+
rz.K = [7e8; 7e8; 2e9; 1e7; 1e7; 1e7];
 rz.C = [4e4; 4e4; 7e4; 1e4; 1e4; 1e4];
@@ -1168,46 +1169,46 @@ rz.C = [4e4; 4e4; 7e4; 1e4; 1e4; 1e4];
 
-
-

Equilibrium position of the each joint.

-
+
+

Equilibrium position of the each joint.

+
-
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
+
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
+end
 
-
-

Save the Structure

-
+
+

Save the Structure

+

The rz structure is saved.

-
save('./mat/stages.mat', 'rz', '-append');
+
save('./mat/stages.mat', 'rz', '-append');
 
-
-

8 Micro Hexapod

+
+

8 Micro Hexapod

-
-

Simscape Model

-
+
+

Simscape Model

+

simscape_model_micro_hexapod.png @@ -1224,77 +1225,77 @@ The rz structure is saved.

-
-

Function description

-
+
+

Function description

+
-
function [micro_hexapod] = initializeMicroHexapod(args)
+
function [micro_hexapod] = initializeMicroHexapod(args)
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
-    args.type      char   {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init', 'compliance'})} = 'flexible'
-    % 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.type      char   {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init', 'compliance'})} = 'flexible'
+    % 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.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.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.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.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)
-    % Force that stiffness of each joint should apply at t=0
-    args.Foffset      logical {mustBeNumericOrLogical} = false
-end
+    % Force that stiffness of each joint should apply at t=0
+    args.Foffset      logical {mustBeNumericOrLogical} = false
+end
 
-
-

Function content

-
+
+

Function content

+
stewart = initializeStewartPlatform();
 
 stewart = initializeFramesPositions(stewart, ...
-                                    'H', args.H, ...
-                                    'MO_B', args.MO_B);
+                                    '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);
+                                       'FH', args.FH, ...
+                                       'FR', args.FR, ...
+                                       'FTh', args.FTh, ...
+                                       'MH', args.MH, ...
+                                       'MR', args.MR, ...
+                                       'MTh', args.MTh);
 
 stewart = computeJointsPose(stewart);
 
@@ -1302,42 +1303,42 @@ stewart = computeJointsPose(stewart);
stewart = initializeStrutDynamics(stewart, ...
-                                  'K', args.Ki, ...
-                                  'C', args.Ci);
+                                  'K', args.Ki, ...
+                                  'C', args.Ci);
 
 stewart = initializeJointDynamics(stewart, ...
-                                  'type_F', 'universal_p', ...
-                                  'type_M', 'spherical_p');
+                                  'type_F', 'universal_p', ...
+                                  'type_M', 'spherical_p');
 
stewart = initializeCylindricalPlatforms(stewart, ...
-                                         'Fpm', args.Fpm, ...
-                                         'Fph', args.Fph, ...
-                                         'Fpr', args.Fpr, ...
-                                         'Mpm', args.Mpm, ...
-                                         'Mph', args.Mph, ...
-                                         'Mpr', args.Mpr);
+                                         '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);
+                                      '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);
+                              'AP', args.AP, ...
+                              'ARB', args.ARB);
 
-
stewart = initializeInertialSensor(stewart, 'type', 'none');
+
stewart = initializeInertialSensor(stewart, 'type', 'none');
 
@@ -1345,49 +1346,49 @@ stewart = initializeStewartPose(stewart, ... Equilibrium position of the each joint.

-
if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
-  load('mat/Foffset.mat', 'Fhm');
-  stewart.actuators.dLeq = -Fhm'./args.Ki;
-else
+
if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
+  load('mat/Foffset.mat', 'Fhm');
+  stewart.actuators.dLeq = -Fhm'./args.Ki;
+else
   stewart.actuators.dLeq = zeros(6,1);
-end
+end
 
-
-

Add Type

-
+
+

Add Type

+
-
switch args.type
-  case 'none'
+
switch args.type
+  case 'none'
     stewart.type = 0;
-  case 'rigid'
+  case 'rigid'
     stewart.type = 1;
-  case 'flexible'
+  case 'flexible'
     stewart.type = 2;
-  case 'modal-analysis'
+  case 'modal-analysis'
     stewart.type = 3;
-  case 'init'
+  case 'init'
     stewart.type = 4;
-  case 'compliance'
+  case 'compliance'
     stewart.type = 5;
-end
+end
 
-
-

Save the Structure

-
+
+

Save the Structure

+

The micro_hexapod structure is saved.

micro_hexapod = stewart;
-save('./mat/stages.mat', 'micro_hexapod', '-append');
+save('./mat/stages.mat', 'micro_hexapod', '-append');
 
@@ -1402,9 +1403,9 @@ save('./mat/stages.mat', 'micro_hexapod', '-append');

-
-

Simscape Model

-
+
+

Simscape Model

+

The Simscape model of the Center of gravity compensator is composed of:

@@ -1429,31 +1430,31 @@ The Simscape model of the Center of gravity compensator is composed of:
-
-

Function description

-
+
+

Function description

+
-
function [axisc] = initializeAxisc(args)
+
function [axisc] = initializeAxisc(args)
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
-  args.type char {mustBeMember(args.type,{'none', 'rigid', 'flexible'})} = 'flexible'
-end
+  args.type char {mustBeMember(args.type,{'none', 'rigid', 'flexible'})} = 'flexible'
+end
 
-
-

Structure initialization

-
+
+

Structure initialization

+

First, we initialize the axisc structure.

@@ -1464,58 +1465,58 @@ First, we initialize the axisc structure.
-
-

Add Type

-
+
+

Add Type

+
-
switch args.type
-  case 'none'
+
switch args.type
+  case 'none'
     axisc.type = 0;
-  case 'rigid'
+  case 'rigid'
     axisc.type = 1;
-  case 'flexible'
+  case 'flexible'
     axisc.type = 2;
-end
+end
 
-
-

Material and Geometry

-
+
+

Material and Geometry

+

Properties of the Material and link to the geometry files.

-
% Structure
-axisc.structure.density = 3400; % [kg/m3]
-axisc.structure.STEP    = './STEPS/axisc/axisc_structure.STEP';
+
% 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';
+% 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';
+% 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';
+% Gear
+axisc.gear.density      = 7800; % [kg/m3]
+axisc.gear.STEP         = './STEPS/axisc/axisc_gear.STEP';
 
-
-

Save the Structure

-
+
+

Save the Structure

+

The axisc structure is saved.

-
save('./mat/stages.mat', 'axisc', '-append');
+
save('./mat/stages.mat', 'axisc', '-append');
 
@@ -1530,9 +1531,9 @@ The axisc structure is saved.

-
-

Simscape Model

-
+
+

Simscape Model

+

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 @@ -1554,35 +1555,35 @@ The output mirror_center corresponds to the center of the Sphere an

-
-

Function description

-
+
+

Function description

+
-
function [] = initializeMirror(args)
+
function [] = initializeMirror(args)
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
-    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]
-end
+    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]
+end
 
-
-

Structure initialization

-
+
+

Structure initialization

+

First, we initialize the mirror structure.

@@ -1597,14 +1598,14 @@ First, we initialize the mirror structure.

Add Mirror Type

-
switch args.type
-  case 'none'
+
switch args.type
+  case 'none'
     mirror.type = 0;
-  case 'rigid'
+  case 'rigid'
     mirror.type = 1;
-  case 'flexible'
+  case 'flexible'
     mirror.type = 2;
-end
+end
 
@@ -1621,23 +1622,23 @@ mirror.freq = args.freq;
-
-

Stiffness and Damping properties

-
+
+

Stiffness and Damping properties

+
mirror.K = zeros(6,1);
-mirror.K(1:3) = mirror.mass * (2*pi*mirror.freq(1:3)).^2;
+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);
+mirror.C(1:3) = 0.2 * sqrt(mirror.K(1:3).*mirror.mass);
 
-
-

Equilibrium position of the each joint.

-
+
+

Equilibrium position of the each joint.

+
mirror.Deq = zeros(6,1);
 
@@ -1652,30 +1653,30 @@ mirror.C(1:3) = 0.2 * sqrt(mirror.K(1:3).*mirror.mass); We define the geometrical values.

-
mirror.h = 0.05; % Height of the mirror [m]
+
mirror.h = 0.05; % Height of the mirror [m]
 
-mirror.thickness = 0.025; % Thickness of the plate supporting the sample [m]
+mirror.thickness = 0.02; % Thickness of the plate supporting the sample [m]
 
-mirror.hole_rad = 0.125; % radius of the hole in the mirror [m]
+mirror.hole_rad = 0.125; % radius of the hole in the mirror [m]
 
-mirror.support_rad = 0.1; % radius of the support plate [m]
+mirror.support_rad = 0.1; % radius of the support plate [m]
 
-% point of interest offset in z (above the top surfave) [m]
-switch args.type
-  case 'none'
-    mirror.jacobian = 0.20;
-  case 'rigid'
-    mirror.jacobian = 0.20 - mirror.h;
-  case 'flexible'
-    mirror.jacobian = 0.20 - mirror.h;
-end
+% point of interest offset in z (above the top surfave) [m]
+switch args.type
+  case 'none'
+    mirror.jacobian = 0.205;
+  case 'rigid'
+    mirror.jacobian = 0.205 - mirror.h;
+  case 'flexible'
+    mirror.jacobian = 0.205 - mirror.h;
+end
 
-mirror.rad = 0.180; % radius of the mirror (at the bottom surface) [m]
+mirror.rad = 0.180; % radius of the mirror (at the bottom surface) [m]
 
-
mirror.cone_length = mirror.rad*tand(args.angle)+mirror.h+mirror.jacobian; % Distance from Apex point of the cone to jacobian point
+
mirror.cone_length = mirror.rad*tand(args.angle)+mirror.h+mirror.jacobian; % Distance from Apex point of the cone to jacobian point
 
@@ -1685,8 +1686,8 @@ We first start with the internal part.

mirror.shape = [...
-    mirror.support_rad+5e-3 mirror.h-mirror.thickness
-    mirror.hole_rad mirror.h-mirror.thickness; ...
+    mirror.support_rad+5e-3 mirror.h-mirror.thickness
+    mirror.hole_rad mirror.h-mirror.thickness; ...
     mirror.hole_rad 0; ...
     mirror.rad 0 ...
 ];
@@ -1697,17 +1698,17 @@ We first start with the internal part.
 Then, we define the reflective used part of the mirror.
 

-
if strcmp(args.shape, 'spherical')
-    mirror.sphere_radius = sqrt((mirror.jacobian+mirror.h)^2+mirror.rad^2); % Radius of the sphere [mm]
+
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
+    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
 
@@ -1715,37 +1716,37 @@ end Finally, we close the shape.

-
mirror.shape = [mirror.shape; mirror.support_rad+5e-3 mirror.h];
+
mirror.shape = [mirror.shape; mirror.support_rad+5e-3 mirror.h];
 
-
-

Save the Structure

-
+
+

Save the Structure

+

The mirror structure is saved.

-
save('./mat/stages.mat', 'mirror', '-append');
+
save('./mat/stages.mat', 'mirror', '-append');
 
-
-

11 Nano Hexapod

+
+

11 Nano Hexapod

-
-

Simscape Model

-
+
+

Simscape Model

+

simscape_model_nano_hexapod.png @@ -1762,153 +1763,159 @@ The mirror structure is saved.

-
-

Function description

-
+
+

Function description

+
-
function [nano_hexapod] = initializeNanoHexapod(args)
+
function [nano_hexapod] = initializeNanoHexapod(args)
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
-    args.type      char   {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'init'})} = 'flexible'
-    % initializeFramesPositions
-    args.H    (1,1) double {mustBeNumeric, mustBePositive} = 90e-3
-    args.MO_B (1,1) double {mustBeNumeric} = 175e-3
-    % 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
-    args.actuator  char   {mustBeMember(args.actuator,{'piezo', 'lorentz', 'amplified'})} = 'piezo'
+    args.type      char   {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'init'})} = 'flexible'
+    % initializeFramesPositions
+    args.H    (1,1) double {mustBeNumeric, mustBePositive} = 95e-3
+    args.MO_B (1,1) double {mustBeNumeric} = 170e-3
+    % 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
+    args.actuator  char   {mustBeMember(args.actuator,{'piezo', 'lorentz', 'amplified'})} = 'piezo'
     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
-    args.ce  (1,1) double {mustBeNumeric} = 10
-    args.ca  (1,1) double {mustBeNumeric} = 10
-    args.k   (1,1) double {mustBeNumeric} = -1
-    args.c   (1,1) double {mustBeNumeric} = -1
-    % initializeJointDynamics
-    args.type_F     char   {mustBeMember(args.type_F,{'universal', 'spherical', 'universal_p', 'spherical_p', 'universal_3dof'})} = 'universal'
-    args.type_M     char   {mustBeMember(args.type_M,{'universal', 'spherical', 'universal_p', 'spherical_p', 'spherical_3dof'})} = 'spherical'
-    args.Kf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 15*ones(6,1)
-    args.Cf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1)
-    args.Kt_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 20*ones(6,1)
-    args.Ct_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1)
-    args.Kz_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 60e6*ones(6,1)
-    args.Cz_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e2*ones(6,1)
-    args.Kf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 15*ones(6,1)
-    args.Cf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1)
-    args.Kt_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 20*ones(6,1)
-    args.Ct_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1)
-    args.Kz_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 60e6*ones(6,1)
-    args.Cz_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e2*ones(6,1)
-    % initializeCylindricalPlatforms
+    args.F_gain  (1,1) double {mustBeNumeric} = 1
+    args.k   (1,1) double {mustBeNumeric} = -1
+    args.c   (1,1) double {mustBeNumeric} = -1
+    % initializeJointDynamics
+    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)
+    args.Cf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1)
+    args.Kt_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 236*ones(6,1)
+    args.Ct_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1)
+    args.Kf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 33*ones(6,1)
+    args.Cf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1)
+    args.Kt_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 236*ones(6,1)
+    args.Ct_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1)
+    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)
+    % 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.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
-    args.Mpr (1,1) double {mustBeNumeric, mustBePositive} = 120e-3
-    % initializeCylindricalStruts
+    args.Mph (1,1) double {mustBeNumeric, mustBePositive} = 10e-3
+    args.Mpr (1,1) double {mustBeNumeric, mustBePositive} = 120e-3
+    % 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.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.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
+    % Equilibrium position of each leg
     args.dLeq (6,1) double {mustBeNumeric} = zeros(6,1)
-    % Force that stiffness of each joint should apply at t=0
-    args.Foffset      logical {mustBeNumericOrLogical} = false
-end
+    % Force that stiffness of each joint should apply at t=0
+    args.Foffset      logical {mustBeNumericOrLogical} = false
+end
 
-
-

Function content

-
+
+

Function content

+
stewart = initializeStewartPlatform();
 
-stewart = initializeFramesPositions(stewart, 'H', args.H, 'MO_B', args.MO_B);
+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 = generateGeneralConfiguration(stewart, 'FH', args.FH, 'FR', args.FR, 'FTh', args.FTh, 'MH', args.MH, 'MR', args.MR, 'MTh', args.MTh);
 
 stewart = computeJointsPose(stewart);
 
-
if args.k > 0 && args.c > 0
-    stewart = initializeStrutDynamics(stewart, 'type', 'classical', 'K', args.k*ones(6,1), 'C', args.c*ones(6,1));
-elseif args.k > 0
-    stewart = initializeStrutDynamics(stewart, 'type', 'classical', 'K', args.k*ones(6,1), 'C', 1.5*sqrt(args.k)*ones(6,1));
-elseif strcmp(args.actuator, 'piezo')
-    stewart = initializeStrutDynamics(stewart, 'type', 'classical', 'K', 1e7*ones(6,1), 'C', 1e2*ones(6,1));
-elseif strcmp(args.actuator, 'lorentz')
-    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), ...
-                                      'ca', args.ca*ones(6,1), ...
-                                      'ke', args.ke*ones(6,1), ...
-                                      'ce', args.ce*ones(6,1));
-else
-    error('args.actuator should be piezo, lorentz or amplified');
-end
+
if args.k > 0 && args.c > 0
+    stewart = initializeStrutDynamics(stewart, 'type', 'classical', 'K', args.k*ones(6,1), 'C', args.c*ones(6,1));
+elseif args.k > 0
+    stewart = initializeStrutDynamics(stewart, 'type', 'classical', 'K', args.k*ones(6,1), 'C', 1.5*sqrt(args.k)*ones(6,1));
+elseif strcmp(args.actuator, 'piezo')
+    stewart = initializeStrutDynamics(stewart, 'type', 'classical', 'K', 1e7*ones(6,1), 'C', 1e2*ones(6,1));
+elseif strcmp(args.actuator, 'lorentz')
+    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), ...
+                                      'F_gain', args.F_gain*ones(6,1));
+else
+    error('args.actuator should be piezo, lorentz or amplified');
+end
 
stewart = initializeJointDynamics(stewart, ...
-                                  'type_F', args.type_F, ...
-                                  'type_M', args.type_M, ...
-                                  'Kf_M'  , args.Kf_M, ...
-                                  'Cf_M'  , args.Cf_M, ...
-                                  'Kt_M'  , args.Kt_M, ...
-                                  'Ct_M'  , args.Ct_M, ...
-                                  'Kz_M'  , args.Kz_M, ...
-                                  'Cz_M'  , args.Cz_M, ...
-                                  'Kf_F'  , args.Kf_F, ...
-                                  'Cf_F'  , args.Cf_F, ...
-                                  'Kt_F'  , args.Kt_F, ...
-                                  'Ct_F'  , args.Ct_F, ...
-                                  'Kz_F'  , args.Kz_F, ...
-                                  'Cz_F'  , args.Cz_F);
+                                  'type_F', args.type_F, ...
+                                  'type_M', args.type_M, ...
+                                  '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);
 
-
stewart = initializeCylindricalPlatforms(stewart, 'Fpm', args.Fpm, 'Fph', args.Fph, 'Fpr', args.Fpr, 'Mpm', args.Mpm, 'Mph', args.Mph, 'Mpr', args.Mpr);
+
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 = 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);
+stewart = initializeStewartPose(stewart, 'AP', args.AP, 'ARB', args.ARB);
 
-
stewart = initializeInertialSensor(stewart, 'type', 'accelerometer');
+
stewart = initializeInertialSensor(stewart, 'type', 'accelerometer');
 
@@ -1917,42 +1924,42 @@ Equilibrium position of the each joint.

-if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
-  load('mat/Foffset.mat', 'Fnm');
-  stewart.actuators.dLeq = -Fnm'./stewart.Ki;
-else
+if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
+  load('mat/Foffset.mat', 'Fnm');
+  stewart.actuators.dLeq = -Fnm'./stewart.Ki;
+else
   stewart.actuators.dLeq = args.dLeq;
-end
+end
 
-
-

Add Type

-
+
+

Add Type

+
-
switch args.type
-  case 'none'
+
switch args.type
+  case 'none'
     stewart.type = 0;
-  case 'rigid'
+  case 'rigid'
     stewart.type = 1;
-  case 'flexible'
+  case 'flexible'
     stewart.type = 2;
-  case 'init'
+  case 'init'
     stewart.type = 4;
-end
+end
 
-
-

Save the Structure

-
+
+

Save the Structure

+
nano_hexapod = stewart;
-save('./mat/stages.mat', 'nano_hexapod', '-append');
+save('./mat/stages.mat', 'nano_hexapod', '-append');
 
@@ -1967,9 +1974,9 @@ save('./mat/stages.mat', 'nano_hexapod', '-append');

-
-

Simscape Model

-
+
+

Simscape Model

+

The Simscape model of the sample environment is composed of:

@@ -1997,37 +2004,37 @@ This could be the case for cable forces for instance.
-
-

Function description

-
+
+

Function description

+
-
function [sample] = initializeSample(args)
+
function [sample] = initializeSample(args)
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
-  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]
-  args.freq   (6,1) double  {mustBeNumeric, mustBePositive} = 100*ones(6,1) % [Hz]
-  args.offset (1,1) double  {mustBeNumeric} = 0 % [m]
-  args.Foffset      logical {mustBeNumericOrLogical} = false
-end
+  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]
+  args.freq   (6,1) double  {mustBeNumeric, mustBePositive} = 100*ones(6,1) % [Hz]
+  args.offset (1,1) double  {mustBeNumeric} = 0 % [m]
+  args.Foffset      logical {mustBeNumericOrLogical} = false
+end
 
-
-

Structure initialization

-
+
+

Structure initialization

+

First, we initialize the sample structure.

@@ -2042,32 +2049,32 @@ First, we initialize the sample structure.

Add Sample Type

-
switch args.type
-  case 'none'
+
switch args.type
+  case 'none'
     sample.type = 0;
-  case 'rigid'
+  case 'rigid'
     sample.type = 1;
-  case 'flexible'
+  case 'flexible'
     sample.type = 2;
-  case 'init'
+  case 'init'
     sample.type = 3;
-end
+end
 
-
-

Material and Geometry

-
+
+

Material and Geometry

+

We define the geometrical parameters of the sample as well as its mass and position.

-
sample.radius = args.radius; % [m]
-sample.height = args.height; % [m]
-sample.mass   = args.mass; % [kg]
-sample.offset = args.offset; % [m]
+
sample.radius = args.radius; % [m]
+sample.height = args.height; % [m]
+sample.mass   = args.mass; % [kg]
+sample.offset = args.offset; % [m]
 
@@ -2077,17 +2084,17 @@ sample.offset = args.offset; % [m]

Compute the Inertia

-
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];
+
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];
 
-
-

Stiffness and Damping properties

-
+
+

Stiffness and Damping properties

+
sample.K = zeros(6, 1);
 sample.C = zeros(6, 1);
@@ -2098,8 +2105,8 @@ sample.C = zeros(6, 1);
 Translation Stiffness and Damping:
 

-
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)]
+
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)]
 
@@ -2107,36 +2114,36 @@ sample.C(1:3) = 0.1 * sqrt(sample.K(1:3)*sample.mass); % [N/(m/s)] Rotational Stiffness and Damping:

-
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)]
+
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)]
 
-
-

Equilibrium position of the each joint.

-
+
+

Equilibrium position of the each joint.

+
-
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
+
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
   sample.Deq = zeros(6,1);
-end
+end
 
-
-

Save the Structure

-
+
+

Save the Structure

+

The sample structure is saved.

-
save('./mat/stages.mat', 'sample', '-append');
+
save('./mat/stages.mat', 'sample', '-append');
 
@@ -2151,31 +2158,31 @@ The sample structure is saved.

-
-

Function Declaration and Documentation

-
+
+

Function Declaration and Documentation

+
-
function [] = initializeController(args)
+
function [] = initializeController(args)
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
-  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'
-end
+  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'
+end
 
-
-

Structure initialization

-
+
+

Structure initialization

+

First, we initialize the controller structure.

@@ -2190,48 +2197,48 @@ First, we initialize the controller structure.

Controller Type

-
switch args.type
-  case 'open-loop'
+
switch args.type
+  case 'open-loop'
     controller.type = 1;
-    controller.name = 'Open-Loop';
-  case 'dvf'
+    controller.name = 'Open-Loop';
+  case 'dvf'
     controller.type = 2;
-    controller.name = 'Decentralized Direct Velocity Feedback';
-  case 'iff'
+    controller.name = 'Decentralized Direct Velocity Feedback';
+  case 'iff'
     controller.type = 3;
-    controller.name = 'Decentralized Integral Force Feedback';
-  case 'hac-dvf'
+    controller.name = 'Decentralized Integral Force Feedback';
+  case 'hac-dvf'
     controller.type = 4;
-    controller.name = 'HAC-DVF';
-  case 'ref-track-L'
+    controller.name = 'HAC-DVF';
+  case 'ref-track-L'
     controller.type = 5;
-    controller.name = 'Reference Tracking in the frame of the legs';
-  case 'ref-track-iff-L'
+    controller.name = 'Reference Tracking in the frame of the legs';
+  case 'ref-track-iff-L'
     controller.type = 6;
-    controller.name = 'Reference Tracking in the frame of the legs + IFF';
-  case 'cascade-hac-lac'
+    controller.name = 'Reference Tracking in the frame of the legs + IFF';
+  case 'cascade-hac-lac'
     controller.type = 7;
-    controller.name = 'Cascade Control + HAC-LAC';
-  case 'hac-iff'
+    controller.name = 'Cascade Control + HAC-LAC';
+  case 'hac-iff'
     controller.type = 8;
-    controller.name = 'HAC-IFF';
-  case 'stabilizing'
+    controller.name = 'HAC-IFF';
+  case 'stabilizing'
     controller.type = 9;
-    controller.name = 'Stabilizing Controller';
-end
+    controller.name = 'Stabilizing Controller';
+end
 
-
-

Save the Structure

-
+
+

Save the Structure

+

The controller structure is saved.

-
save('./mat/controller.mat', 'controller');
+
save('./mat/controller.mat', 'controller');
 
@@ -2246,56 +2253,56 @@ The controller structure is saved.

-
-

Function Declaration and Documentation

-
+
+

Function Declaration and Documentation

+
-
function [ref] = initializeReferences(args)
+
function [ref] = initializeReferences(args)
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
-    % Sampling Frequency [s]
-    args.Ts           (1,1) double {mustBeNumeric, mustBePositive} = 1e-3
-    % Maximum simulation time [s]
+    % 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]
+    % 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]
+    % 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]
+    % 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]
+    % Period of the displacement [s]
     args.Ry_period    (1,1) double {mustBeNumeric, mustBePositive} = 1
-    % Either "constant" / "rotating"
-    args.Rz_type      char {mustBeMember(args.Rz_type,{'constant', 'rotating', 'rotating-not-filtered'})} = 'constant'
-    % Initial angle [rad]
+    % Either "constant" / "rotating"
+    args.Rz_type      char {mustBeMember(args.Rz_type,{'constant', 'rotating', 'rotating-not-filtered'})} = 'constant'
+    % Initial angle [rad]
     args.Rz_amplitude (1,1) double {mustBeNumeric} = 0
-    % Period of the rotating [s]
+    % 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)
+    % 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
+    % 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
 
@@ -2306,159 +2313,159 @@ end

Initialize Parameters

-
%% Set Sampling Time
+
%% Set Sampling Time
 Ts = args.Ts;
 Tmax = args.Tmax;
 
-%% Low Pass Filter to filter out the references
-s = zpk('s');
-w0 = 2*pi*10;
+%% 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);
+H_lpf = 1/(1 + 2*xi/w0*s + s^2/w0^2);
 
-
-

Translation Stage

-
+
+

Translation Stage

+
-
%% Translation stage - Dy
-t = 0:Ts:Tmax; % Time Vector [s]
+
%% 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
+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
 
-    % The signal is filtered out
+    % 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
+    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);
+Dy = struct('time', t, 'signals', struct('values', Dy), 'deriv', Dyd, 'dderiv', Dydd);
 
-
-

Tilt Stage

-
+
+

Tilt Stage

+
-
%% Tilt Stage - Ry
-t = 0:Ts:Tmax; % Time Vector [s]
+
%% 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
+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
 
-    % The signal is filtered out
+    % 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  = 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
+    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);
+Ry = struct('time', t, 'signals', struct('values', Ry), 'deriv', Ryd, 'dderiv', Rydd);
 
-
-

Spindle

-
+
+

Spindle

+
-
%% Spindle - Rz
-t = 0:Ts:Tmax; % Time Vector [s]
+
%% Spindle - Rz
+t = 0:Ts:Tmax; % Time Vector [s]
 Rz   = zeros(length(t), 1);
 Rzd  = zeros(length(t), 1);
 Rzdd = zeros(length(t), 1);
 
-switch args.Rz_type
-  case 'constant'
-    Rz(:)   = args.Rz_amplitude;
-    Rzd(:)  = 0;
-    Rzdd(:) = 0;
-  case 'rotating-not-filtered'
-    Rz(:) = 2*pi/args.Rz_period*t;
+switch args.Rz_type
+  case 'constant'
+    Rz(:)   = args.Rz_amplitude;
+    Rzd(:)  = 0;
+    Rzdd(:) = 0;
+  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;
+    % 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;
+    % We add the angle offset
+    Rz = Rz + args.Rz_amplitude;
 
-  case 'rotating'
-    Rz(:) = 2*pi/args.Rz_period*t;
+  case 'rotating'
+    Rz(:) = 2*pi/args.Rz_period*t;
 
-    % The signal is filtered out
+    % 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);
+    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
+    % We add the angle offset
+    Rz = Rz + args.Rz_amplitude;
+  otherwise
+    warning('Rz_type is not set correctly');
+end
 
-Rz = struct('time', t, 'signals', struct('values', Rz), 'deriv', Rzd, 'dderiv', Rzdd);
+Rz = struct('time', t, 'signals', struct('values', Rz), 'deriv', Rzd, 'dderiv', Rzdd);
 
-
-

Micro Hexapod

-
+
+

Micro Hexapod

+
-
%% Micro-Hexapod
+
%% Micro-Hexapod
 t = [0, Ts];
 Dh = zeros(length(t), 6);
 Dhl = zeros(length(t), 6);
 
-switch args.Dh_type
-  case 'constant'
+switch args.Dh_type
+  case 'constant'
     Dh = [args.Dh_pos, args.Dh_pos];
 
-    load('mat/stages.mat', 'micro_hexapod');
+    load('mat/stages.mat', 'micro_hexapod');
 
     AP = [args.Dh_pos(1) ; args.Dh_pos(2) ; args.Dh_pos(3)];
 
@@ -2466,24 +2473,24 @@ switch args.Dh_type
     ty = args.Dh_pos(5);
     tz = args.Dh_pos(6);
 
-    ARB = [cos(tz) -sin(tz) 0;
+    ARB = [cos(tz) -sin(tz) 0;
            sin(tz)  cos(tz) 0;
-           0        0       1]*...
+           0        0       1]*...
           [ cos(ty) 0 sin(ty);
             0       1 0;
-           -sin(ty) 0 cos(ty)]*...
+           -sin(ty) 0 cos(ty)]*...
           [1 0        0;
-           0 cos(tx) -sin(tx);
+           0 cos(tx) -sin(tx);
            0 sin(tx)  cos(tx)];
 
-    [~, Dhl] = inverseKinematics(micro_hexapod, 'AP', AP, 'ARB', ARB);
+    [~, Dhl] = inverseKinematics(micro_hexapod, 'AP', AP, 'ARB', ARB);
     Dhl = [Dhl, Dhl];
-  otherwise
-    warning('Dh_type is not set correctly');
-end
+  otherwise
+    warning('Dh_type is not set correctly');
+end
 
-Dh = struct('time', t, 'signals', struct('values', Dh));
-Dhl = struct('time', t, 'signals', struct('values', Dhl));
+Dh = struct('time', t, 'signals', struct('values', Dh));
+Dhl = struct('time', t, 'signals', struct('values', Dhl));
 
@@ -2493,29 +2500,29 @@ Dhl = struct('time', t, 'signals', struct('values', Dhl));

Axis Compensation

-
%% Axis Compensation - Rm
+
%% Axis Compensation - Rm
 t = [0, Ts];
 
 Rm = [args.Rm_pos, args.Rm_pos];
-Rm = struct('time', t, 'signals', struct('values', Rm));
+Rm = struct('time', t, 'signals', struct('values', Rm));
 
-
-

Nano Hexapod

-
+
+

Nano Hexapod

+
-
%% Nano-Hexapod
+
%% Nano-Hexapod
 t = [0, Ts];
 Dn = zeros(length(t), 6);
 
-switch args.Dn_type
-  case 'constant'
+switch args.Dn_type
+  case 'constant'
     Dn = [args.Dn_pos, args.Dn_pos];
 
-    load('mat/stages.mat', 'nano_hexapod');
+    load('mat/stages.mat', 'nano_hexapod');
 
     AP = [args.Dn_pos(1) ; args.Dn_pos(2) ; args.Dn_pos(3)];
 
@@ -2523,36 +2530,36 @@ switch args.Dn_type
     ty = args.Dn_pos(5);
     tz = args.Dn_pos(6);
 
-    ARB = [cos(tz) -sin(tz) 0;
+    ARB = [cos(tz) -sin(tz) 0;
            sin(tz)  cos(tz) 0;
-           0        0       1]*...
+           0        0       1]*...
           [ cos(ty) 0 sin(ty);
             0       1 0;
-           -sin(ty) 0 cos(ty)]*...
+           -sin(ty) 0 cos(ty)]*...
           [1 0        0;
-           0 cos(tx) -sin(tx);
+           0 cos(tx) -sin(tx);
            0 sin(tx)  cos(tx)];
 
-    [~, Dnl] = inverseKinematics(nano_hexapod, 'AP', AP, 'ARB', ARB);
+    [~, Dnl] = inverseKinematics(nano_hexapod, 'AP', AP, 'ARB', ARB);
     Dnl = [Dnl, Dnl];
-  otherwise
-    warning('Dn_type is not set correctly');
-end
+  otherwise
+    warning('Dn_type is not set correctly');
+end
 
-Dn = struct('time', t, 'signals', struct('values', Dn));
-Dnl = struct('time', t, 'signals', struct('values', Dnl));
+Dn = struct('time', t, 'signals', struct('values', Dn));
+Dnl = struct('time', t, 'signals', struct('values', Dnl));
 
-
-

Save

-
+
+

Save

+
-
    %% Save
-    save('./mat/nass_references.mat', 'Dy', 'Ry', 'Rz', 'Dh', 'Dhl', 'Rm', 'Dn', 'Dnl', 'args', 'Ts');
-end
+
    %% Save
+    save('./mat/nass_references.mat', 'Dy', 'Ry', 'Rz', 'Dh', 'Dhl', 'Rm', 'Dn', 'Dnl', 'args', 'Ts');
+end
 
@@ -2567,43 +2574,43 @@ end

-
-

Function Declaration and Documentation

-
+
+

Function Declaration and Documentation

+
-
function [] = initializeDisturbances(args)
-% initializeDisturbances - Initialize the disturbances
-%
-% Syntax: [] = initializeDisturbances(args)
-%
-% Inputs:
-%    - args -
+
function [] = initializeDisturbances(args)
+% initializeDisturbances - Initialize the disturbances
+%
+% Syntax: [] = initializeDisturbances(args)
+%
+% Inputs:
+%    - args -
 
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
-    % Global parameter to enable or disable the disturbances
-    args.enable logical {mustBeNumericOrLogical} = true
-    % 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
-end
+    % Global parameter to enable or disable the disturbances
+    args.enable logical {mustBeNumericOrLogical} = true
+    % 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
+end
 
@@ -2614,7 +2621,7 @@ end

Load Data

-
load('./mat/dist_psd.mat', 'dist_f');
+
load('./mat/dist_psd.mat', 'dist_f');
 
@@ -2630,13 +2637,13 @@ We remove the first frequency point that usually is very large. We define some parameters that will be used in the algorithm.

-
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]
+
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]
 
@@ -2647,49 +2654,49 @@ Ts = 1/Fs; % Sampling Time [s]
phi = dist_f.psd_gm;
-C = zeros(N/2,1);
-for i = 1:N/2
-  C(i) = sqrt(phi(i)*df);
-end
+C = zeros(N/2,1);
+for i = 1:N/2
+  C(i) = sqrt(phi(i)*df);
+end
 
-
if args.Dwx && args.enable
-  rng(111);
-  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
+
if args.Dwx && args.enable
+  rng(111);
+  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
 
-
if args.Dwy && args.enable
-  rng(112);
-  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
+
if args.Dwy && args.enable
+  rng(112);
+  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
 
-
if args.Dwy && args.enable
-  rng(113);
-  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
+
if args.Dwy && args.enable
+  rng(113);
+  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
+end
 
@@ -2699,21 +2706,21 @@ end

Translation Stage - X direction

-
if args.Fty_x && args.enable
-  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
-  rng(121);
-  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]
+
if args.Fty_x && args.enable
+  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
+  rng(121);
+  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
+else
   Fty_x = zeros(length(t), 1);
-end
+end
 
@@ -2723,21 +2730,21 @@ end

Translation Stage - Z direction

-
if args.Fty_z && args.enable
+
if args.Fty_z && args.enable
   phi = dist_f.psd_ty;
-  C = zeros(N/2,1);
-  for i = 1:N/2
-    C(i) = sqrt(phi(i)*df);
-  end
-  rng(122);
-  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]
+  C = zeros(N/2,1);
+  for i = 1:N/2
+    C(i) = sqrt(phi(i)*df);
+  end
+  rng(122);
+  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
+else
   Fty_z = zeros(length(t), 1);
-end
+end
 
@@ -2747,21 +2754,21 @@ end

Spindle - Z direction

-
if args.Frz_z && args.enable
+
if args.Frz_z && args.enable
   phi = dist_f.psd_rz;
-  C = zeros(N/2,1);
-  for i = 1:N/2
-    C(i) = sqrt(phi(i)*df);
-  end
-  rng(131);
-  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]
+  C = zeros(N/2,1);
+  for i = 1:N/2
+    C(i) = sqrt(phi(i)*df);
+  end
+  rng(131);
+  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
+else
   Frz_z = zeros(length(t), 1);
-end
+end
 
@@ -2782,22 +2789,22 @@ Fd = u;

Set initial value to zero

-
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);
+
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);
 
-
-

Save

-
+
+

Save

+
-
save('./mat/nass_disturbances.mat', 'Dwx', 'Dwy', 'Dwz', 'Fty_x', 'Fty_z', 'Frz_z', 'Fd', 'Ts', 't', 'args');
+
save('./mat/nass_disturbances.mat', 'Dwx', 'Dwy', 'Dwz', 'Fty_x', 'Fty_z', 'Frz_z', 'Fd', 'Ts', 't', 'args');
 
@@ -2812,41 +2819,41 @@ Frz_z = Frz_z - Frz_z(1);

-
-

Function Declaration and Documentation

-
+
+

Function Declaration and Documentation

+
-
function [] = initializePosError(args)
-% initializePosError - Initialize the position errors
-%
-% Syntax: [] = initializePosError(args)
-%
-% Inputs:
-%    - args -
+
function [] = initializePosError(args)
+% initializePosError - Initialize the position errors
+%
+% Syntax: [] = initializePosError(args)
+%
+% Inputs:
+%    - args -
 
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
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
+    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
 
-
-

Structure initialization

-
+
+

Structure initialization

+

First, we initialize the pos_error structure.

@@ -2861,11 +2868,11 @@ First, we initialize the pos_error structure.

Type

-
if args.error
+
if args.error
   pos_error.type = 1;
-else
+else
   pos_error.type = 0;
-end
+end
 
@@ -2883,11 +2890,11 @@ pos_error.Rz = args.Rz;
-
-

Save

-
+
+

Save

+
-
save('./mat/pos_error.mat', 'pos_error');
+
save('./mat/pos_error.mat', 'pos_error');
 
@@ -2902,24 +2909,24 @@ pos_error.Rz = args.Rz;

-
function [geophone] = initializeZAxisGeophone(args)
+
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
+        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;
+    %% 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);
+    %% 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
+    %% Save
+    save('./mat/geophone_z_axis.mat', 'geophone');
+end
 
@@ -2933,27 +2940,27 @@ end

-
function [accelerometer] = initializeZAxisAccelerometer(args)
+
function [accelerometer] = initializeZAxisAccelerometer(args)
     arguments
-        args.mass (1,1) double {mustBeNumeric, mustBePositive} = 1e-3 % [kg]
-        args.freq (1,1) double {mustBeNumeric, mustBePositive} = 5e3  % [Hz]
-    end
+        args.mass (1,1) double {mustBeNumeric, mustBePositive} = 1e-3 % [kg]
+        args.freq (1,1) double {mustBeNumeric, mustBePositive} = 5e3  % [Hz]
+    end
 
-    %%
+    %%
     accelerometer.m = args.mass;
 
-    %% The Stiffness is set to have the damping resonance frequency
-    accelerometer.k = accelerometer.m * (2*pi*args.freq)^2;
+    %% 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);
+    %% We set the damping value to have critical damping
+    accelerometer.c = 2*sqrt(accelerometer.m * accelerometer.k);
 
-    %% Gain correction of the accelerometer to have a unity gain until the resonance
-    accelerometer.gain = -accelerometer.k/accelerometer.m;
+    %% Gain correction of the accelerometer to have a unity gain until the resonance
+    accelerometer.gain = -accelerometer.k/accelerometer.m;
 
-    %% Save
-    save('./mat/accelerometer_z_axis.mat', 'accelerometer');
-end
+    %% Save
+    save('./mat/accelerometer_z_axis.mat', 'accelerometer');
+end
 
@@ -2961,7 +2968,7 @@ end

Author: Dehaeze Thomas

-

Created: 2020-07-31 ven. 17:58

+

Created: 2020-11-03 mar. 09:45

diff --git a/docs/stewart_platform.html b/docs/stewart_platform.html index 65a8a51..9faff69 100644 --- a/docs/stewart_platform.html +++ b/docs/stewart_platform.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Stewart Platform - Simscape Model @@ -36,159 +36,150 @@
-
-

Documentation

-
+
+

Documentation

+
- -
-

Function description

-
+ -
-

Documentation

-
+
+

Documentation

+
- -
-

Function description

-
+
+

Function description

+
-
function [stewart] = initializeFramesPositions(stewart, args)
-% initializeFramesPositions - Initialize the positions of frames {A}, {B}, {F} and {M}
-%
-% Syntax: [stewart] = initializeFramesPositions(stewart, args)
-%
-% Inputs:
-%    - args - Can have the following fields:
-%        - H    [1x1] - Total Height of the Stewart Platform (height from {F} to {M}) [m]
-%        - MO_B [1x1] - Height of the frame {B} with respect to {M} [m]
-%
-% Outputs:
-%    - stewart - A structure with the following fields:
-%        - geometry.H      [1x1] - Total Height of the Stewart Platform [m]
-%        - geometry.FO_M   [3x1] - Position of {M} with respect to {F} [m]
-%        - platform_M.MO_B [3x1] - Position of {B} with respect to {M} [m]
-%        - platform_F.FO_A [3x1] - Position of {A} with respect to {F} [m]
+
function [stewart] = initializeFramesPositions(stewart, args)
+% initializeFramesPositions - Initialize the positions of frames {A}, {B}, {F} and {M}
+%
+% Syntax: [stewart] = initializeFramesPositions(stewart, args)
+%
+% Inputs:
+%    - args - Can have the following fields:
+%        - H    [1x1] - Total Height of the Stewart Platform (height from {F} to {M}) [m]
+%        - MO_B [1x1] - Height of the frame {B} with respect to {M} [m]
+%
+% Outputs:
+%    - stewart - A structure with the following fields:
+%        - geometry.H      [1x1] - Total Height of the Stewart Platform [m]
+%        - geometry.FO_M   [3x1] - Position of {M} with respect to {F} [m]
+%        - platform_M.MO_B [3x1] - Position of {B} with respect to {M} [m]
+%        - platform_F.FO_A [3x1] - Position of {A} with respect to {F} [m]
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
     stewart
-    args.H    (1,1) double {mustBeNumeric, mustBePositive} = 90e-3
-    args.MO_B (1,1) double {mustBeNumeric} = 50e-3
-end
+    args.H    (1,1) double {mustBeNumeric, mustBePositive} = 90e-3
+    args.MO_B (1,1) double {mustBeNumeric} = 50e-3
+end
 
@@ -402,21 +393,21 @@ end

Compute the position of each frame

-
H = args.H; % Total Height of the Stewart Platform [m]
+
H = args.H; % Total Height of the Stewart Platform [m]
 
-FO_M = [0; 0; H]; % Position of {M} with respect to {F} [m]
+FO_M = [0; 0; H]; % Position of {M} with respect to {F} [m]
 
-MO_B = [0; 0; args.MO_B]; % Position of {B} with respect to {M} [m]
+MO_B = [0; 0; args.MO_B]; % Position of {B} with respect to {M} [m]
 
-FO_A = MO_B + FO_M; % Position of {A} with respect to {F} [m]
+FO_A = MO_B + FO_M; % Position of {A} with respect to {F} [m]
 
-
-

Populate the stewart structure

-
+
+

Populate the stewart structure

+
stewart.geometry.H      = H;
 stewart.geometry.FO_M   = FO_M;
@@ -440,9 +431,9 @@ This Matlab function is accessible 
-

Documentation

-
+ -
-

Function description

-
+
+

Function description

+
-
function [stewart] = generateGeneralConfiguration(stewart, args)
-% generateGeneralConfiguration - Generate a Very General Configuration
-%
-% Syntax: [stewart] = generateGeneralConfiguration(stewart, args)
-%
-% Inputs:
-%    - args - Can have the following fields:
-%        - FH  [1x1] - Height of the position of the fixed joints with respect to the frame {F} [m]
-%        - FR  [1x1] - Radius of the position of the fixed joints in the X-Y [m]
-%        - FTh [6x1] - Angles of the fixed joints in the X-Y plane with respect to the X axis [rad]
-%        - MH  [1x1] - Height of the position of the mobile joints with respect to the frame {M} [m]
-%        - FR  [1x1] - Radius of the position of the mobile joints in the X-Y [m]
-%        - MTh [6x1] - Angles of the mobile joints in the X-Y plane with respect to the X axis [rad]
-%
-% Outputs:
-%    - stewart - updated Stewart structure with the added fields:
-%        - platform_F.Fa  [3x6] - Its i'th column is the position vector of joint ai with respect to {F}
-%        - platform_M.Mb  [3x6] - Its i'th column is the position vector of joint bi with respect to {M}
+
function [stewart] = generateGeneralConfiguration(stewart, args)
+% generateGeneralConfiguration - Generate a Very General Configuration
+%
+% Syntax: [stewart] = generateGeneralConfiguration(stewart, args)
+%
+% Inputs:
+%    - args - Can have the following fields:
+%        - FH  [1x1] - Height of the position of the fixed joints with respect to the frame {F} [m]
+%        - FR  [1x1] - Radius of the position of the fixed joints in the X-Y [m]
+%        - FTh [6x1] - Angles of the fixed joints in the X-Y plane with respect to the X axis [rad]
+%        - MH  [1x1] - Height of the position of the mobile joints with respect to the frame {M} [m]
+%        - FR  [1x1] - Radius of the position of the mobile joints in the X-Y [m]
+%        - MTh [6x1] - Angles of the mobile joints in the X-Y plane with respect to the X axis [rad]
+%
+% Outputs:
+%    - stewart - updated Stewart structure with the added fields:
+%        - platform_F.Fa  [3x6] - Its i'th column is the position vector of joint ai with respect to {F}
+%        - platform_M.Mb  [3x6] - Its i'th column is the position vector of joint bi with respect to {M}
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
     stewart
-    args.FH  (1,1) double {mustBeNumeric, mustBePositive} = 15e-3
-    args.FR  (1,1) double {mustBeNumeric, mustBePositive} = 115e-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);
-end
+    args.FH  (1,1) double {mustBeNumeric, mustBePositive} = 15e-3
+    args.FR  (1,1) double {mustBeNumeric, mustBePositive} = 115e-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);
+end
 
-
-

Compute the pose

-
+
+

Compute the pose

+
Fa = zeros(3,6);
 Mb = zeros(3,6);
@@ -512,18 +503,18 @@ Mb = zeros(3,6);
 
-
for i = 1:6
-  Fa(:,i) = [args.FR*cos(args.FTh(i)); args.FR*sin(args.FTh(i));  args.FH];
-  Mb(:,i) = [args.MR*cos(args.MTh(i)); args.MR*sin(args.MTh(i)); -args.MH];
-end
+
for i = 1:6
+  Fa(:,i) = [args.FR*cos(args.FTh(i)); args.FR*sin(args.FTh(i));  args.FH];
+  Mb(:,i) = [args.MR*cos(args.MTh(i)); args.MR*sin(args.MTh(i)); -args.MH];
+end
 
-
-

Populate the stewart structure

-
+
+

Populate the stewart structure

+
stewart.platform_F.Fa = Fa;
 stewart.platform_M.Mb = Mb;
@@ -545,9 +536,9 @@ This Matlab function is accessible here
 

-
-

Documentation

-
+
+

Documentation

+

stewart-struts.png @@ -557,58 +548,58 @@ This Matlab function is accessible here

-
-

Function description

-
+
+

Function description

+
-
function [stewart] = computeJointsPose(stewart)
-% computeJointsPose -
-%
-% Syntax: [stewart] = computeJointsPose(stewart)
-%
-% Inputs:
-%    - stewart - A structure with the following fields
-%        - platform_F.Fa   [3x6] - Its i'th column is the position vector of joint ai with respect to {F}
-%        - platform_M.Mb   [3x6] - Its i'th column is the position vector of joint bi with respect to {M}
-%        - platform_F.FO_A [3x1] - Position of {A} with respect to {F}
-%        - platform_M.MO_B [3x1] - Position of {B} with respect to {M}
-%        - geometry.FO_M   [3x1] - Position of {M} with respect to {F}
-%
-% Outputs:
-%    - stewart - A structure with the following added fields
-%        - geometry.Aa    [3x6]   - The i'th column is the position of ai with respect to {A}
-%        - geometry.Ab    [3x6]   - The i'th column is the position of bi with respect to {A}
-%        - geometry.Ba    [3x6]   - The i'th column is the position of ai with respect to {B}
-%        - geometry.Bb    [3x6]   - The i'th column is the position of bi with respect to {B}
-%        - geometry.l     [6x1]   - The i'th element is the initial length of strut i
-%        - geometry.As    [3x6]   - The i'th column is the unit vector of strut i expressed in {A}
-%        - geometry.Bs    [3x6]   - The i'th column is the unit vector of strut i expressed in {B}
-%        - struts_F.l     [6x1]   - Length of the Fixed part of the i'th strut
-%        - struts_M.l     [6x1]   - Length of the Mobile part of the i'th strut
-%        - platform_F.FRa [3x3x6] - The i'th 3x3 array is the rotation matrix to orientate the bottom of the i'th strut from {F}
-%        - platform_M.MRb [3x3x6] - The i'th 3x3 array is the rotation matrix to orientate the top of the i'th strut from {M}
+
function [stewart] = computeJointsPose(stewart)
+% computeJointsPose -
+%
+% Syntax: [stewart] = computeJointsPose(stewart)
+%
+% Inputs:
+%    - stewart - A structure with the following fields
+%        - platform_F.Fa   [3x6] - Its i'th column is the position vector of joint ai with respect to {F}
+%        - platform_M.Mb   [3x6] - Its i'th column is the position vector of joint bi with respect to {M}
+%        - platform_F.FO_A [3x1] - Position of {A} with respect to {F}
+%        - platform_M.MO_B [3x1] - Position of {B} with respect to {M}
+%        - geometry.FO_M   [3x1] - Position of {M} with respect to {F}
+%
+% Outputs:
+%    - stewart - A structure with the following added fields
+%        - geometry.Aa    [3x6]   - The i'th column is the position of ai with respect to {A}
+%        - geometry.Ab    [3x6]   - The i'th column is the position of bi with respect to {A}
+%        - geometry.Ba    [3x6]   - The i'th column is the position of ai with respect to {B}
+%        - geometry.Bb    [3x6]   - The i'th column is the position of bi with respect to {B}
+%        - geometry.l     [6x1]   - The i'th element is the initial length of strut i
+%        - geometry.As    [3x6]   - The i'th column is the unit vector of strut i expressed in {A}
+%        - geometry.Bs    [3x6]   - The i'th column is the unit vector of strut i expressed in {B}
+%        - struts_F.l     [6x1]   - Length of the Fixed part of the i'th strut
+%        - struts_M.l     [6x1]   - Length of the Mobile part of the i'th strut
+%        - platform_F.FRa [3x3x6] - The i'th 3x3 array is the rotation matrix to orientate the bottom of the i'th strut from {F}
+%        - platform_M.MRb [3x3x6] - The i'th 3x3 array is the rotation matrix to orientate the top of the i'th strut from {M}
 
-
-

Check the stewart structure elements

-
+
+

Check the stewart structure elements

+
-
assert(isfield(stewart.platform_F, 'Fa'),   'stewart.platform_F should have attribute Fa')
+
assert(isfield(stewart.platform_F, 'Fa'),   'stewart.platform_F should have attribute Fa')
 Fa = stewart.platform_F.Fa;
 
-assert(isfield(stewart.platform_M, 'Mb'),   'stewart.platform_M should have attribute Mb')
+assert(isfield(stewart.platform_M, 'Mb'),   'stewart.platform_M should have attribute Mb')
 Mb = stewart.platform_M.Mb;
 
-assert(isfield(stewart.platform_F, 'FO_A'), 'stewart.platform_F should have attribute FO_A')
+assert(isfield(stewart.platform_F, 'FO_A'), 'stewart.platform_F should have attribute FO_A')
 FO_A = stewart.platform_F.FO_A;
 
-assert(isfield(stewart.platform_M, 'MO_B'), 'stewart.platform_M should have attribute MO_B')
+assert(isfield(stewart.platform_M, 'MO_B'), 'stewart.platform_M should have attribute MO_B')
 MO_B = stewart.platform_M.MO_B;
 
-assert(isfield(stewart.geometry,   'FO_M'), 'stewart.geometry should have attribute FO_M')
+assert(isfield(stewart.geometry,   'FO_M'), 'stewart.geometry should have attribute FO_M')
 FO_M = stewart.geometry.FO_M;
 
@@ -619,11 +610,11 @@ FO_M = stewart.geometry.FO_M;

Compute the position of the Joints

-
Aa = Fa - repmat(FO_A, [1, 6]);
-Bb = Mb - repmat(MO_B, [1, 6]);
+
Aa = Fa - repmat(FO_A, [1, 6]);
+Bb = Mb - repmat(MO_B, [1, 6]);
 
-Ab = Bb - repmat(-MO_B-FO_M+FO_A, [1, 6]);
-Ba = Aa - repmat( MO_B+FO_M-FO_A, [1, 6]);
+Ab = Bb - repmat(-MO_B-FO_M+FO_A, [1, 6]);
+Ba = Aa - repmat( MO_B+FO_M-FO_A, [1, 6]);
 
@@ -633,14 +624,14 @@ Ba = Aa - repmat( MO_B+FO_M-FO_A, [1, 6]);

Compute the strut length and orientation

-
As = (Ab - Aa)./vecnorm(Ab - Aa); % As_i is the i'th vector of As
+
As = (Ab - Aa)./vecnorm(Ab - Aa); % As_i is the i'th vector of As
 
-l = vecnorm(Ab - Aa)';
+l = vecnorm(Ab - Aa)';
 
-
Bs = (Bb - Ba)./vecnorm(Bb - Ba);
+
Bs = (Bb - Ba)./vecnorm(Bb - Ba);
 
@@ -653,21 +644,21 @@ l = vecnorm(Ab - Aa)';
FRa = zeros(3,3,6);
 MRb = zeros(3,3,6);
 
-for i = 1:6
-  FRa(:,:,i) = [cross([0;1;0], As(:,i)) , cross(As(:,i), cross([0;1;0], As(:,i))) , As(:,i)];
-  FRa(:,:,i) = FRa(:,:,i)./vecnorm(FRa(:,:,i));
+for i = 1:6
+  FRa(:,:,i) = [cross([0;1;0], As(:,i)) , cross(As(:,i), cross([0;1;0], As(:,i))) , As(:,i)];
+  FRa(:,:,i) = FRa(:,:,i)./vecnorm(FRa(:,:,i));
 
-  MRb(:,:,i) = [cross([0;1;0], Bs(:,i)) , cross(Bs(:,i), cross([0;1;0], Bs(:,i))) , Bs(:,i)];
-  MRb(:,:,i) = MRb(:,:,i)./vecnorm(MRb(:,:,i));
-end
+  MRb(:,:,i) = [cross([0;1;0], Bs(:,i)) , cross(Bs(:,i), cross([0;1;0], Bs(:,i))) , Bs(:,i)];
+  MRb(:,:,i) = MRb(:,:,i)./vecnorm(MRb(:,:,i));
+end
 
-
-

Populate the stewart structure

-
+
+

Populate the stewart structure

+
-
-

Function description

-
+
+

Function description

+
-
function [stewart] = initializeStewartPose(stewart, args)
-% initializeStewartPose - Determine the initial stroke in each leg to have the wanted pose
-%                         It uses the inverse kinematic
-%
-% Syntax: [stewart] = initializeStewartPose(stewart, args)
-%
-% Inputs:
-%    - stewart - A structure with the following fields
-%        - Aa   [3x6] - The positions ai expressed in {A}
-%        - Bb   [3x6] - The positions bi expressed in {B}
-%    - args - Can have the following fields:
-%        - AP   [3x1] - The wanted position of {B} with respect to {A}
-%        - ARB  [3x3] - The rotation matrix that gives the wanted orientation of {B} with respect to {A}
-%
-% Outputs:
-%    - stewart - updated Stewart structure with the added fields:
-%      - actuators.Leq [6x1] - The 6 needed displacement of the struts from the initial position in [m] to have the wanted pose of {B} w.r.t. {A}
+
function [stewart] = initializeStewartPose(stewart, args)
+% initializeStewartPose - Determine the initial stroke in each leg to have the wanted pose
+%                         It uses the inverse kinematic
+%
+% Syntax: [stewart] = initializeStewartPose(stewart, args)
+%
+% Inputs:
+%    - stewart - A structure with the following fields
+%        - Aa   [3x6] - The positions ai expressed in {A}
+%        - Bb   [3x6] - The positions bi expressed in {B}
+%    - args - Can have the following fields:
+%        - AP   [3x1] - The wanted position of {B} with respect to {A}
+%        - ARB  [3x3] - The rotation matrix that gives the wanted orientation of {B} with respect to {A}
+%
+% Outputs:
+%    - stewart - updated Stewart structure with the added fields:
+%      - actuators.Leq [6x1] - The 6 needed displacement of the struts from the initial position in [m] to have the wanted pose of {B} w.r.t. {A}
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
     stewart
     args.AP  (3,1) double {mustBeNumeric} = zeros(3,1)
     args.ARB (3,3) double {mustBeNumeric} = eye(3)
-end
+end
 
@@ -744,15 +735,15 @@ end

Use the Inverse Kinematic function

-
[Li, dLi] = inverseKinematics(stewart, 'AP', args.AP, 'ARB', args.ARB);
+
[Li, dLi] = inverseKinematics(stewart, 'AP', args.AP, 'ARB', args.ARB);
 
-
-

Populate the stewart structure

-
+
+

Populate the stewart structure

+
stewart.actuators.Leq = dLi;
 
@@ -773,55 +764,55 @@ This Matlab function is accessible -

Function description

-
+
+

Function description

+
-
function [stewart] = initializeCylindricalPlatforms(stewart, args)
-% initializeCylindricalPlatforms - Initialize the geometry of the Fixed and Mobile Platforms
-%
-% Syntax: [stewart] = initializeCylindricalPlatforms(args)
-%
-% Inputs:
-%    - args - Structure with the following fields:
-%        - Fpm [1x1] - Fixed Platform Mass [kg]
-%        - Fph [1x1] - Fixed Platform Height [m]
-%        - Fpr [1x1] - Fixed Platform Radius [m]
-%        - Mpm [1x1] - Mobile Platform Mass [kg]
-%        - Mph [1x1] - Mobile Platform Height [m]
-%        - Mpr [1x1] - Mobile Platform Radius [m]
-%
-% Outputs:
-%    - stewart - updated Stewart structure with the added fields:
-%      - platform_F [struct] - structure with the following fields:
-%        - type = 1
-%        - M [1x1] - Fixed Platform Mass [kg]
-%        - I [3x3] - Fixed Platform Inertia matrix [kg*m^2]
-%        - H [1x1] - Fixed Platform Height [m]
-%        - R [1x1] - Fixed Platform Radius [m]
-%      - platform_M [struct] - structure with the following fields:
-%        - M [1x1] - Mobile Platform Mass [kg]
-%        - I [3x3] - Mobile Platform Inertia matrix [kg*m^2]
-%        - H [1x1] - Mobile Platform Height [m]
-%        - R [1x1] - Mobile Platform Radius [m]
+
function [stewart] = initializeCylindricalPlatforms(stewart, args)
+% initializeCylindricalPlatforms - Initialize the geometry of the Fixed and Mobile Platforms
+%
+% Syntax: [stewart] = initializeCylindricalPlatforms(args)
+%
+% Inputs:
+%    - args - Structure with the following fields:
+%        - Fpm [1x1] - Fixed Platform Mass [kg]
+%        - Fph [1x1] - Fixed Platform Height [m]
+%        - Fpr [1x1] - Fixed Platform Radius [m]
+%        - Mpm [1x1] - Mobile Platform Mass [kg]
+%        - Mph [1x1] - Mobile Platform Height [m]
+%        - Mpr [1x1] - Mobile Platform Radius [m]
+%
+% Outputs:
+%    - stewart - updated Stewart structure with the added fields:
+%      - platform_F [struct] - structure with the following fields:
+%        - type = 1
+%        - M [1x1] - Fixed Platform Mass [kg]
+%        - I [3x3] - Fixed Platform Inertia matrix [kg*m^2]
+%        - H [1x1] - Fixed Platform Height [m]
+%        - R [1x1] - Fixed Platform Radius [m]
+%      - platform_M [struct] - structure with the following fields:
+%        - M [1x1] - Mobile Platform Mass [kg]
+%        - I [3x3] - Mobile Platform Inertia matrix [kg*m^2]
+%        - H [1x1] - Mobile Platform Height [m]
+%        - R [1x1] - Mobile Platform Radius [m]
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
     stewart
     args.Fpm (1,1) double {mustBeNumeric, mustBePositive} = 1
-    args.Fph (1,1) double {mustBeNumeric, mustBePositive} = 10e-3
-    args.Fpr (1,1) double {mustBeNumeric, mustBePositive} = 125e-3
+    args.Fph (1,1) double {mustBeNumeric, mustBePositive} = 10e-3
+    args.Fpr (1,1) double {mustBeNumeric, mustBePositive} = 125e-3
     args.Mpm (1,1) double {mustBeNumeric, mustBePositive} = 1
-    args.Mph (1,1) double {mustBeNumeric, mustBePositive} = 10e-3
-    args.Mpr (1,1) double {mustBeNumeric, mustBePositive} = 100e-3
-end
+    args.Mph (1,1) double {mustBeNumeric, mustBePositive} = 10e-3
+    args.Mpr (1,1) double {mustBeNumeric, mustBePositive} = 100e-3
+end
 
@@ -831,24 +822,24 @@ end

Compute the Inertia matrices of platforms

-
I_F = diag([1/12*args.Fpm * (3*args.Fpr^2 + args.Fph^2), ...
-            1/12*args.Fpm * (3*args.Fpr^2 + args.Fph^2), ...
-            1/2 *args.Fpm * args.Fpr^2]);
+
I_F = diag([1/12*args.Fpm * (3*args.Fpr^2 + args.Fph^2), ...
+            1/12*args.Fpm * (3*args.Fpr^2 + args.Fph^2), ...
+            1/2 *args.Fpm * args.Fpr^2]);
 
-
I_M = diag([1/12*args.Mpm * (3*args.Mpr^2 + args.Mph^2), ...
-            1/12*args.Mpm * (3*args.Mpr^2 + args.Mph^2), ...
-            1/2 *args.Mpm * args.Mpr^2]);
+
I_M = diag([1/12*args.Mpm * (3*args.Mpr^2 + args.Mph^2), ...
+            1/12*args.Mpm * (3*args.Mpr^2 + args.Mph^2), ...
+            1/2 *args.Mpm * args.Mpr^2]);
 
-
-

Populate the stewart structure

-
+
+

Populate the stewart structure

+
stewart.platform_F.type = 1;
 
@@ -884,54 +875,54 @@ This Matlab function is accessible 
-

Function description

-
+
+

Function description

+
-
function [stewart] = initializeCylindricalStruts(stewart, args)
-% initializeCylindricalStruts - Define the mass and moment of inertia of cylindrical struts
-%
-% Syntax: [stewart] = initializeCylindricalStruts(args)
-%
-% Inputs:
-%    - args - Structure with the following fields:
-%        - Fsm [1x1] - Mass of the Fixed part of the struts [kg]
-%        - Fsh [1x1] - Height of cylinder for the Fixed part of the struts [m]
-%        - Fsr [1x1] - Radius of cylinder for the Fixed part of the struts [m]
-%        - Msm [1x1] - Mass of the Mobile part of the struts [kg]
-%        - Msh [1x1] - Height of cylinder for the Mobile part of the struts [m]
-%        - Msr [1x1] - Radius of cylinder for the Mobile part of the struts [m]
-%
-% Outputs:
-%    - stewart - updated Stewart structure with the added fields:
-%      - struts_F [struct] - structure with the following fields:
-%        - M [6x1]   - Mass of the Fixed part of the struts [kg]
-%        - I [3x3x6] - Moment of Inertia for the Fixed part of the struts [kg*m^2]
-%        - H [6x1]   - Height of cylinder for the Fixed part of the struts [m]
-%        - R [6x1]   - Radius of cylinder for the Fixed part of the struts [m]
-%      - struts_M [struct] - structure with the following fields:
-%        - M [6x1]   - Mass of the Mobile part of the struts [kg]
-%        - I [3x3x6] - Moment of Inertia for the Mobile part of the struts [kg*m^2]
-%        - H [6x1]   - Height of cylinder for the Mobile part of the struts [m]
-%        - R [6x1]   - Radius of cylinder for the Mobile part of the struts [m]
+
function [stewart] = initializeCylindricalStruts(stewart, args)
+% initializeCylindricalStruts - Define the mass and moment of inertia of cylindrical struts
+%
+% Syntax: [stewart] = initializeCylindricalStruts(args)
+%
+% Inputs:
+%    - args - Structure with the following fields:
+%        - Fsm [1x1] - Mass of the Fixed part of the struts [kg]
+%        - Fsh [1x1] - Height of cylinder for the Fixed part of the struts [m]
+%        - Fsr [1x1] - Radius of cylinder for the Fixed part of the struts [m]
+%        - Msm [1x1] - Mass of the Mobile part of the struts [kg]
+%        - Msh [1x1] - Height of cylinder for the Mobile part of the struts [m]
+%        - Msr [1x1] - Radius of cylinder for the Mobile part of the struts [m]
+%
+% Outputs:
+%    - stewart - updated Stewart structure with the added fields:
+%      - struts_F [struct] - structure with the following fields:
+%        - M [6x1]   - Mass of the Fixed part of the struts [kg]
+%        - I [3x3x6] - Moment of Inertia for the Fixed part of the struts [kg*m^2]
+%        - H [6x1]   - Height of cylinder for the Fixed part of the struts [m]
+%        - R [6x1]   - Radius of cylinder for the Fixed part of the struts [m]
+%      - struts_M [struct] - structure with the following fields:
+%        - M [6x1]   - Mass of the Mobile part of the struts [kg]
+%        - I [3x3x6] - Moment of Inertia for the Mobile part of the struts [kg*m^2]
+%        - H [6x1]   - Height of cylinder for the Mobile part of the struts [m]
+%        - R [6x1]   - Radius of cylinder for the Mobile part of the struts [m]
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
     stewart
     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.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
-end
+    args.Msh (1,1) double {mustBeNumeric, mustBePositive} = 50e-3
+    args.Msr (1,1) double {mustBeNumeric, mustBePositive} = 5e-3
+end
 
@@ -941,37 +932,37 @@ end

Compute the properties of the cylindrical struts

-
Fsm = ones(6,1).*args.Fsm;
-Fsh = ones(6,1).*args.Fsh;
-Fsr = ones(6,1).*args.Fsr;
+
Fsm = ones(6,1).*args.Fsm;
+Fsh = ones(6,1).*args.Fsh;
+Fsr = ones(6,1).*args.Fsr;
 
-Msm = ones(6,1).*args.Msm;
-Msh = ones(6,1).*args.Msh;
-Msr = ones(6,1).*args.Msr;
+Msm = ones(6,1).*args.Msm;
+Msh = ones(6,1).*args.Msh;
+Msr = ones(6,1).*args.Msr;
 
-
I_F = zeros(3, 3, 6); % Inertia of the "fixed" part of the strut
-I_M = zeros(3, 3, 6); % Inertia of the "mobile" part of the strut
+
I_F = zeros(3, 3, 6); % Inertia of the "fixed" part of the strut
+I_M = zeros(3, 3, 6); % Inertia of the "mobile" part of the strut
 
-for i = 1:6
-  I_F(:,:,i) = diag([1/12 * Fsm(i) * (3*Fsr(i)^2 + Fsh(i)^2), ...
-                     1/12 * Fsm(i) * (3*Fsr(i)^2 + Fsh(i)^2), ...
-                     1/2  * Fsm(i) * Fsr(i)^2]);
+for i = 1:6
+  I_F(:,:,i) = diag([1/12 * Fsm(i) * (3*Fsr(i)^2 + Fsh(i)^2), ...
+                     1/12 * Fsm(i) * (3*Fsr(i)^2 + Fsh(i)^2), ...
+                     1/2  * Fsm(i) * Fsr(i)^2]);
 
-  I_M(:,:,i) = diag([1/12 * Msm(i) * (3*Msr(i)^2 + Msh(i)^2), ...
-                     1/12 * Msm(i) * (3*Msr(i)^2 + Msh(i)^2), ...
-                     1/2  * Msm(i) * Msr(i)^2]);
-end
+  I_M(:,:,i) = diag([1/12 * Msm(i) * (3*Msr(i)^2 + Msh(i)^2), ...
+                     1/12 * Msm(i) * (3*Msr(i)^2 + Msh(i)^2), ...
+                     1/2  * Msm(i) * Msr(i)^2]);
+end
 
-
-

Populate the stewart structure

-
+
+

Populate the stewart structure

+
-
-

Documentation

-
+
+

Documentation

+

piezoelectric_stack.jpg @@ -1038,48 +1029,47 @@ A simplistic model of such amplified actuator is shown in Figure -

Function description

-
+
+

Function description

+
-
function [stewart] = initializeStrutDynamics(stewart, args)
-% initializeStrutDynamics - Add Stiffness and Damping properties of each strut
-%
-% Syntax: [stewart] = initializeStrutDynamics(args)
-%
-% Inputs:
-%    - args - Structure with the following fields:
-%        - K [6x1] - Stiffness of each strut [N/m]
-%        - C [6x1] - Damping of each strut [N/(m/s)]
-%
-% Outputs:
-%    - stewart - updated Stewart structure with the added fields:
-%      - actuators.type = 1
-%      - actuators.K [6x1] - Stiffness of each strut [N/m]
-%      - actuators.C [6x1] - Damping of each strut [N/(m/s)]
+
function [stewart] = initializeStrutDynamics(stewart, args)
+% initializeStrutDynamics - Add Stiffness and Damping properties of each strut
+%
+% Syntax: [stewart] = initializeStrutDynamics(args)
+%
+% Inputs:
+%    - args - Structure with the following fields:
+%        - K [6x1] - Stiffness of each strut [N/m]
+%        - C [6x1] - Damping of each strut [N/(m/s)]
+%
+% Outputs:
+%    - stewart - updated Stewart structure with the added fields:
+%      - actuators.type = 1
+%      - actuators.K [6x1] - Stiffness of each strut [N/m]
+%      - actuators.C [6x1] - Damping of each strut [N/(m/s)]
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
     stewart
-    args.type char {mustBeMember(args.type,{'classical', 'amplified'})} = 'classical'
-    args.K (6,1) double {mustBeNumeric, mustBeNonnegative} = 20e6*ones(6,1)
-    args.C (6,1) double {mustBeNumeric, mustBeNonnegative} = 2e1*ones(6,1)
-    args.k1 (6,1) double {mustBeNumeric} = 1e6
-    args.ke (6,1) double {mustBeNumeric} = 5e6
-    args.ka (6,1) double {mustBeNumeric} = 60e6
-    args.c1 (6,1) double {mustBeNumeric} = 10
-    args.ce (6,1) double {mustBeNumeric} = 10
-    args.ca (6,1) double {mustBeNumeric} = 10
-    args.me (6,1) double {mustBeNumeric} = 0.05
-    args.ma (6,1) double {mustBeNumeric} = 0.05
-end
+    args.type char {mustBeMember(args.type,{'classical', 'amplified'})} = 'classical'
+    args.K (6,1) double {mustBeNumeric, mustBeNonnegative} = 20e6*ones(6,1)
+    args.C (6,1) double {mustBeNumeric, mustBeNonnegative} = 2e1*ones(6,1)
+    args.k1 (6,1) double {mustBeNumeric} = 1e6*ones(6,1)
+    args.ke (6,1) double {mustBeNumeric} = 5e6*ones(6,1)
+    args.ka (6,1) double {mustBeNumeric} = 60e6*ones(6,1)
+    args.c1 (6,1) double {mustBeNumeric} = 10*ones(6,1)
+    args.F_gain (6,1) double {mustBeNumeric} = 1*ones(6,1)
+    args.me (6,1) double {mustBeNumeric} = 0.01*ones(6,1)
+    args.ma (6,1) double {mustBeNumeric} = 0.01*ones(6,1)
+end
 
@@ -1089,11 +1079,11 @@ end

Add Stiffness and Damping properties of each strut

-
if strcmp(args.type, 'classical')
+
if strcmp(args.type, 'classical')
     stewart.actuators.type = 1;
-elseif strcmp(args.type, 'amplified')
+elseif strcmp(args.type, 'amplified')
     stewart.actuators.type = 2;
-end
+end
 
 stewart.actuators.K = args.K;
 stewart.actuators.C = args.C;
@@ -1102,10 +1092,9 @@ stewart.actuators.k1 = args.k1;
 stewart.actuators.c1 = args.c1;
 
 stewart.actuators.ka = args.ka;
-stewart.actuators.ca = args.ca;
-
 stewart.actuators.ke = args.ke;
-stewart.actuators.ce = args.ce;
+
+stewart.actuators.F_gain = args.F_gain;
 
 stewart.actuators.ma = args.ma;
 stewart.actuators.me = args.me;
@@ -1115,133 +1104,9 @@ stewart.actuators.me = args.me;
 
-
-

9 initializeAmplifiedStrutDynamics: Add Stiffness and Damping properties of each strut for an amplified piezoelectric actuator

-
-

- -

- -

-This Matlab function is accessible here. -

-
- -
-

Documentation

-
-

-An amplified piezoelectric actuator is shown in Figure 7. -

- - -
-

amplified_piezo_with_displacement_sensor.jpg -

-

Figure 7: Example of an Amplified piezoelectric actuator with an integrated displacement sensor (Cedrat Technologies)

-
- -

-A simplistic model of such amplified actuator is shown in Figure 8 where: -

-
    -
  • \(K_{r}\) represent the vertical stiffness when the piezoelectric stack is removed
  • -
  • \(K_{a}\) is the vertical stiffness contribution of the piezoelectric stack
  • -
  • \(F_{i}\) represents the part of the piezoelectric stack that is used as a force actuator
  • -
  • \(F_{m,i}\) represents the remaining part of the piezoelectric stack that is used as a force sensor
  • -
  • \(v_{m,i}\) represents the absolute velocity of the top part of the actuator
  • -
  • \(d_{m,i}\) represents the total relative displacement of the actuator
  • -
- - -
-

iff_1dof.png -

-

Figure 8: Model of an amplified actuator

-
-
-
- -
-

Function description

-
-
-
function [stewart] = initializeAmplifiedStrutDynamics(stewart, args)
-% initializeAmplifiedStrutDynamics - Add Stiffness and Damping properties of each strut
-%
-% Syntax: [stewart] = initializeAmplifiedStrutDynamics(args)
-%
-% Inputs:
-%    - args - Structure with the following fields:
-%        - Ka [6x1] - Vertical stiffness contribution of the piezoelectric stack [N/m]
-%        - Ca [6x1] - Vertical damping contribution of the piezoelectric stack [N/(m/s)]
-%        - Kr [6x1] - Vertical (residual) stiffness when the piezoelectric stack is removed [N/m]
-%        - Cr [6x1] - Vertical (residual) damping when the piezoelectric stack is removed [N/(m/s)]
-%
-% Outputs:
-%    - stewart - updated Stewart structure with the added fields:
-%      - actuators.type = 2
-%      - actuators.K   [6x1] - Total Stiffness of each strut [N/m]
-%      - actuators.C   [6x1] - Total Damping of each strut [N/(m/s)]
-%      - actuators.Ka [6x1] - Vertical stiffness contribution of the piezoelectric stack [N/m]
-%      - actuators.Ca [6x1] - Vertical damping contribution of the piezoelectric stack [N/(m/s)]
-%      - actuators.Kr [6x1] - Vertical stiffness when the piezoelectric stack is removed [N/m]
-%      - actuators.Cr [6x1] - Vertical damping when the piezoelectric stack is removed [N/(m/s)]
-
-
-
-
- -
-

Optional Parameters

-
-
-
arguments
-    stewart
-    args.Kr (6,1) double {mustBeNumeric, mustBeNonnegative} = 5e6*ones(6,1)
-    args.Cr (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
-    args.Ka (6,1) double {mustBeNumeric, mustBeNonnegative} = 15e6*ones(6,1)
-    args.Ca (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
-end
-
-
-
-
- -
-

Compute the total stiffness and damping

-
-
-
K = args.Ka + args.Kr;
-C = args.Ca + args.Cr;
-
-
-
-
- -
-

Populate the stewart structure

-
-
-
stewart.actuators.type = 2;
-
-stewart.actuators.Ka = args.Ka;
-stewart.actuators.Ca = args.Ca;
-
-stewart.actuators.Kr = args.Kr;
-stewart.actuators.Cr = args.Cr;
-
-stewart.actuators.K = K;
-stewart.actuators.C = K;
-
-
-
-
-
-
-

10 initializeJointDynamics: Add Stiffness and Damping properties for spherical joints

-
+

9 initializeJointDynamics: Add Stiffness and Damping properties for spherical joints

+
-
-

Function description

-
+
+

Function description

+
-
function [stewart] = initializeJointDynamics(stewart, args)
-% initializeJointDynamics - Add Stiffness and Damping properties for the spherical joints
-%
-% Syntax: [stewart] = initializeJointDynamics(args)
-%
-% Inputs:
-%    - args - Structure with the following fields:
-%        - type_F - 'universal', 'spherical', 'universal_p', 'spherical_p'
-%        - type_M - 'universal', 'spherical', 'universal_p', 'spherical_p'
-%        - Kf_M [6x1] - Bending (Rx, Ry) Stiffness for each top joints [(N.m)/rad]
-%        - Kt_M [6x1] - Torsion (Rz) Stiffness for each top joints [(N.m)/rad]
-%        - Cf_M [6x1] - Bending (Rx, Ry) Damping of each top joint [(N.m)/(rad/s)]
-%        - Ct_M [6x1] - Torsion (Rz) Damping of each top joint [(N.m)/(rad/s)]
-%        - Kz_M [6x1] - Translation (Tz) Stiffness for each top joints [N/m]
-%        - Cz_M [6x1] - Translation (Tz) Damping of each top joint [N/m]
-%        - Kf_F [6x1] - Bending (Rx, Ry) Stiffness for each bottom joints [(N.m)/rad]
-%        - Kt_F [6x1] - Torsion (Rz) Stiffness for each bottom joints [(N.m)/rad]
-%        - Cf_F [6x1] - Bending (Rx, Ry) Damping of each bottom joint [(N.m)/(rad/s)]
-%        - Cf_F [6x1] - Torsion (Rz) Damping of each bottom joint [(N.m)/(rad/s)]
-%        - Kz_F [6x1] - Translation (Tz) Stiffness for each bottom joints [N/m]
-%        - Cz_F [6x1] - Translation (Tz) Damping of each bottom joint [N/m]
-%
-% Outputs:
-%    - stewart - updated Stewart structure with the added fields:
-%      - stewart.joints_F and stewart.joints_M:
-%        - type - 1 (universal), 2 (spherical), 3 (universal perfect), 4 (spherical perfect)
-%        - Kx, Ky, Kz [6x1] - Translation (Tx, Ty, Tz) Stiffness [N/m]
-%        - Kf [6x1] - Flexion (Rx, Ry) Stiffness [(N.m)/rad]
-%        - Kt [6x1] - Torsion (Rz) Stiffness [(N.m)/rad]
-%        - Cx, Cy, Cz [6x1] - Translation (Rx, Ry) Damping [N/(m/s)]
-%        - Cf [6x1] - Flexion (Rx, Ry) Damping [(N.m)/(rad/s)]
-%        - Cb [6x1] - Torsion (Rz) Damping [(N.m)/(rad/s)]
+
function [stewart] = initializeJointDynamics(stewart, args)
+% initializeJointDynamics - Add Stiffness and Damping properties for the spherical joints
+%
+% Syntax: [stewart] = initializeJointDynamics(args)
+%
+% Inputs:
+%    - args - Structure with the following fields:
+%        - type_F - 'universal', 'spherical', 'universal_p', 'spherical_p'
+%        - type_M - 'universal', 'spherical', 'universal_p', 'spherical_p'
+%        - Kf_M [6x1] - Bending (Rx, Ry) Stiffness for each top joints [(N.m)/rad]
+%        - Kt_M [6x1] - Torsion (Rz) Stiffness for each top joints [(N.m)/rad]
+%        - Cf_M [6x1] - Bending (Rx, Ry) Damping of each top joint [(N.m)/(rad/s)]
+%        - Ct_M [6x1] - Torsion (Rz) Damping of each top joint [(N.m)/(rad/s)]
+%        - Kf_F [6x1] - Bending (Rx, Ry) Stiffness for each bottom joints [(N.m)/rad]
+%        - Kt_F [6x1] - Torsion (Rz) Stiffness for each bottom joints [(N.m)/rad]
+%        - Cf_F [6x1] - Bending (Rx, Ry) Damping of each bottom joint [(N.m)/(rad/s)]
+%        - Cf_F [6x1] - Torsion (Rz) Damping of each bottom joint [(N.m)/(rad/s)]
+%
+% Outputs:
+%    - stewart - updated Stewart structure with the added fields:
+%      - stewart.joints_F and stewart.joints_M:
+%        - type - 1 (universal), 2 (spherical), 3 (universal perfect), 4 (spherical perfect)
+%        - Kx, Ky, Kz [6x1] - Translation (Tx, Ty, Tz) Stiffness [N/m]
+%        - Kf [6x1] - Flexion (Rx, Ry) Stiffness [(N.m)/rad]
+%        - Kt [6x1] - Torsion (Rz) Stiffness [(N.m)/rad]
+%        - Cx, Cy, Cz [6x1] - Translation (Rx, Ry) Damping [N/(m/s)]
+%        - Cf [6x1] - Flexion (Rx, Ry) Damping [(N.m)/(rad/s)]
+%        - Cb [6x1] - Torsion (Rz) Damping [(N.m)/(rad/s)]
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
     stewart
-    args.type_F     char   {mustBeMember(args.type_F,{'universal', 'spherical', 'universal_p', 'spherical_p', 'universal_3dof'})} = 'universal'
-    args.type_M     char   {mustBeMember(args.type_M,{'universal', 'spherical', 'universal_p', 'spherical_p', 'spherical_3dof'})} = 'spherical'
-    args.Kf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 15*ones(6,1)
-    args.Cf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1)
-    args.Kt_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 20*ones(6,1)
-    args.Ct_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1)
-    args.Kz_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 60e6*ones(6,1)
-    args.Cz_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e2*ones(6,1)
-    args.Kf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 15*ones(6,1)
-    args.Cf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1)
-    args.Kt_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 20*ones(6,1)
-    args.Ct_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1)
-    args.Kz_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 60e6*ones(6,1)
-    args.Cz_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e2*ones(6,1)
-end
+    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.Kf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 33*ones(6,1)
+    args.Cf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1)
+    args.Kt_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 236*ones(6,1)
+    args.Ct_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1)
+    args.Kf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 33*ones(6,1)
+    args.Cf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1)
+    args.Kt_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 236*ones(6,1)
+    args.Ct_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1)
+    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)
+    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.K_M        double {mustBeNumeric} = zeros(6,6)
+    args.M_M        double {mustBeNumeric} = zeros(6,6)
+    args.n_xyz_M    double {mustBeNumeric} = zeros(2,3)
+    args.xi_M       double {mustBeNumeric} = 0.1
+    args.step_file_M char {} = ''
+    args.K_F        double {mustBeNumeric} = zeros(6,6)
+    args.M_F        double {mustBeNumeric} = zeros(6,6)
+    args.n_xyz_F    double {mustBeNumeric} = zeros(2,3)
+    args.xi_F       double {mustBeNumeric} = 0.1
+    args.step_file_F char {} = ''
+end
 
@@ -1322,63 +1197,39 @@ end

Add Actuator Type

-
switch args.type_F
-  case 'universal'
+
switch args.type_F
+  case 'universal'
     stewart.joints_F.type = 1;
-  case 'spherical'
+  case 'spherical'
     stewart.joints_F.type = 2;
-  case 'universal_p'
-    stewart.joints_F.type = 1;
-  case 'spherical_p'
-    stewart.joints_F.type = 2;
-  case 'universal_3dof'
+  case 'universal_p'
+    stewart.joints_F.type = 3;
+  case 'spherical_p'
+    stewart.joints_F.type = 4;
+  case 'flexible'
     stewart.joints_F.type = 5;
-end
+  case 'universal_3dof'
+    stewart.joints_F.type = 6;
+  case 'spherical_3dof'
+    stewart.joints_F.type = 7;
+end
 
-switch args.type_M
-  case 'universal'
+switch args.type_M
+  case 'universal'
     stewart.joints_M.type = 1;
-  case 'spherical'
+  case 'spherical'
     stewart.joints_M.type = 2;
-  case 'universal_p'
-    stewart.joints_M.type = 1;
-  case 'spherical_p'
-    stewart.joints_M.type = 2;
-  case 'spherical_3dof'
+  case 'universal_p'
+    stewart.joints_M.type = 3;
+  case 'spherical_p'
+    stewart.joints_M.type = 4;
+  case 'flexible'
+    stewart.joints_M.type = 5;
+  case 'universal_3dof'
     stewart.joints_M.type = 6;
-end
-
-
-
-
- -
-

10.1 Initialize Stiffness

-
-
-
stewart.joints_M.Kx = zeros(6,1);
-stewart.joints_M.Ky = zeros(6,1);
-stewart.joints_M.Kz = zeros(6,1);
-stewart.joints_F.Kx = zeros(6,1);
-stewart.joints_F.Ky = zeros(6,1);
-stewart.joints_F.Kz = zeros(6,1);
-
-stewart.joints_M.Kf = zeros(6,1);
-stewart.joints_M.Kt = zeros(6,1);
-stewart.joints_F.Kf = zeros(6,1);
-stewart.joints_F.Kt = zeros(6,1);
-
-stewart.joints_M.Cx = zeros(6,1);
-stewart.joints_M.Cy = zeros(6,1);
-stewart.joints_M.Cz = zeros(6,1);
-stewart.joints_F.Cx = zeros(6,1);
-stewart.joints_F.Cy = zeros(6,1);
-stewart.joints_F.Cz = zeros(6,1);
-
-stewart.joints_M.Cf = zeros(6,1);
-stewart.joints_M.Ct = zeros(6,1);
-stewart.joints_F.Cf = zeros(6,1);
-stewart.joints_F.Ct = zeros(6,1);
+  case 'spherical_3dof'
+    stewart.joints_M.type = 7;
+end
 
@@ -1388,18 +1239,26 @@ stewart.joints_F.Ct = zeros(6,1);

Add Stiffness and Damping in Translation of each strut

-Translation Stiffness +Axial and Radial (shear) Stiffness

-
if ~strcmp(args.type_M, 'universal_p') || ~strcmp(args.type_M, 'spherical_p')
-    stewart.joints_M.Kz = args.Kz_M;
-    stewart.joints_M.Cz = args.Cz_M;
-end
+
stewart.joints_M.Ka = args.Ka_M;
+stewart.joints_M.Kr = args.Kr_M;
 
-if ~strcmp(args.type_F, 'universal_p') || ~strcmp(args.type_F, 'spherical_p')
-    stewart.joints_F.Kz = args.Kz_F;
-    stewart.joints_F.Cz = args.Cz_F;
-end
+stewart.joints_F.Ka = args.Ka_F;
+stewart.joints_F.Kr = args.Kr_F;
+
+
+ +

+Translation Damping +

+
+
stewart.joints_M.Ca = args.Ca_M;
+stewart.joints_M.Cr = args.Cr_M;
+
+stewart.joints_F.Ca = args.Ca_F;
+stewart.joints_F.Cr = args.Cr_F;
 
@@ -1412,21 +1271,44 @@ end Rotational Stiffness

-
if ~strcmp(args.type_M, 'universal_p') || ~strcmp(args.type_M, 'spherical_p')
-    stewart.joints_M.Kf = args.Kf_M;
-    stewart.joints_M.Cf = args.Cf_M;
+
stewart.joints_M.Kf = args.Kf_M;
+stewart.joints_M.Kt = args.Kt_M;
 
-    stewart.joints_M.Kt = args.Kt_M;
-    stewart.joints_M.Ct = args.Ct_M;
-end
+stewart.joints_F.Kf = args.Kf_F;
+stewart.joints_F.Kt = args.Kt_F;
+
+
-if ~strcmp(args.type_F, 'universal_p') || ~strcmp(args.type_F, 'spherical_p') - stewart.joints_F.Kf = args.Kf_F; - stewart.joints_F.Cf = args.Cf_F; +

+Rotational Damping +

+
+
stewart.joints_M.Cf = args.Cf_M;
+stewart.joints_M.Ct = args.Ct_M;
 
-    stewart.joints_F.Kt = args.Kt_F;
-    stewart.joints_F.Ct = args.Ct_F;
-end
+stewart.joints_F.Cf = args.Cf_F;
+stewart.joints_F.Ct = args.Ct_F;
+
+
+
+
+ +
+

Stiffness and Mass matrices for flexible joint

+
+
+
stewart.joints_F.M = args.M_F;
+stewart.joints_F.K = args.K_F;
+stewart.joints_F.n_xyz = args.n_xyz_F;
+stewart.joints_F.xi = args.xi_F;
+stewart.joints_F.xi = args.xi_F;
+stewart.joints_F.step_file = args.step_file_F;
+
+stewart.joints_M.M = args.M_M;
+stewart.joints_M.K = args.K_M;
+stewart.joints_M.n_xyz = args.n_xyz_M;
+stewart.joints_M.xi = args.xi_M;
+stewart.joints_M.step_file = args.step_file_M;
 
@@ -1434,8 +1316,8 @@ end
-

11 initializeInertialSensor: Initialize the inertial sensor in each strut

-
+

10 initializeInertialSensor: Initialize the inertial sensor in each strut

+

@@ -1449,7 +1331,7 @@ This Matlab function is accessible h

Geophone - Working Principle

-From the schematic of the Z-axis geophone shown in Figure 9, we can write the transfer function from the support velocity \(\dot{w}\) to the relative velocity of the inertial mass \(\dot{d}\): +From the schematic of the Z-axis geophone shown in Figure 7, we can write the transfer function from the support velocity \(\dot{w}\) to the relative velocity of the inertial mass \(\dot{d}\): \[ \frac{\dot{d}}{\dot{w}} = \frac{-\frac{s^2}{{\omega_0}^2}}{\frac{s^2}{{\omega_0}^2} + 2 \xi \frac{s}{\omega_0} + 1} \] with:

@@ -1462,7 +1344,7 @@ with:

inertial_sensor.png

-

Figure 9: Schematic of a Z-Axis geophone

+

Figure 7: Schematic of a Z-Axis geophone

@@ -1484,7 +1366,7 @@ We generally want to have the smallest resonant frequency \(\omega_0\) to measur

Accelerometer - Working Principle

-From the schematic of the Z-axis accelerometer shown in Figure 10, we can write the transfer function from the support acceleration \(\ddot{w}\) to the relative position of the inertial mass \(d\): +From the schematic of the Z-axis accelerometer shown in Figure 8, we can write the transfer function from the support acceleration \(\ddot{w}\) to the relative position of the inertial mass \(d\): \[ \frac{d}{\ddot{w}} = \frac{-\frac{1}{{\omega_0}^2}}{\frac{s^2}{{\omega_0}^2} + 2 \xi \frac{s}{\omega_0} + 1} \] with:

@@ -1497,7 +1379,7 @@ with:

inertial_sensor.png

-

Figure 10: Schematic of a Z-Axis geophone

+

Figure 8: Schematic of a Z-Axis geophone

@@ -1519,44 +1401,44 @@ Note that there is trade-off between:

-
-

Function description

-
+
+

Function description

+
-
function [stewart] = initializeInertialSensor(stewart, args)
-% initializeInertialSensor - Initialize the inertial sensor in each strut
-%
-% Syntax: [stewart] = initializeInertialSensor(args)
-%
-% Inputs:
-%    - args - Structure with the following fields:
-%        - type       - 'geophone', 'accelerometer', 'none'
-%        - mass [1x1] - Weight of the inertial mass [kg]
-%        - freq [1x1] - Cutoff frequency [Hz]
-%
-% Outputs:
-%    - stewart - updated Stewart structure with the added fields:
-%      - stewart.sensors.inertial
-%        - type    - 1 (geophone), 2 (accelerometer), 3 (none)
-%        - K [1x1] - Stiffness [N/m]
-%        - C [1x1] - Damping [N/(m/s)]
-%        - M [1x1] - Inertial Mass [kg]
-%        - G [1x1] - Gain
+
function [stewart] = initializeInertialSensor(stewart, args)
+% initializeInertialSensor - Initialize the inertial sensor in each strut
+%
+% Syntax: [stewart] = initializeInertialSensor(args)
+%
+% Inputs:
+%    - args - Structure with the following fields:
+%        - type       - 'geophone', 'accelerometer', 'none'
+%        - mass [1x1] - Weight of the inertial mass [kg]
+%        - freq [1x1] - Cutoff frequency [Hz]
+%
+% Outputs:
+%    - stewart - updated Stewart structure with the added fields:
+%      - stewart.sensors.inertial
+%        - type    - 1 (geophone), 2 (accelerometer), 3 (none)
+%        - K [1x1] - Stiffness [N/m]
+%        - C [1x1] - Damping [N/(m/s)]
+%        - M [1x1] - Inertial Mass [kg]
+%        - G [1x1] - Gain
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
     stewart
-    args.type       char   {mustBeMember(args.type,{'geophone', 'accelerometer', 'none'})} = 'none'
-    args.mass (1,1) double {mustBeNumeric, mustBeNonnegative} = 1e-2
+    args.type       char   {mustBeMember(args.type,{'geophone', 'accelerometer', 'none'})} = 'none'
+    args.mass (1,1) double {mustBeNumeric, mustBeNonnegative} = 1e-2
     args.freq (1,1) double {mustBeNumeric, mustBeNonnegative} = 1e3
-end
+end
 
@@ -1568,31 +1450,31 @@ end
sensor = struct();
 
-switch args.type
-  case 'geophone'
+switch args.type
+  case 'geophone'
     sensor.type = 1;
 
     sensor.M = args.mass;
-    sensor.K = sensor.M * (2*pi*args.freq)^2;
-    sensor.C = 2*sqrt(sensor.M * sensor.K);
-  case 'accelerometer'
+    sensor.K = sensor.M * (2*pi*args.freq)^2;
+    sensor.C = 2*sqrt(sensor.M * sensor.K);
+  case 'accelerometer'
     sensor.type = 2;
 
     sensor.M = args.mass;
-    sensor.K = sensor.M * (2*pi*args.freq)^2;
-    sensor.C = 2*sqrt(sensor.M * sensor.K);
-    sensor.G = -sensor.K/sensor.M;
-  case 'none'
+    sensor.K = sensor.M * (2*pi*args.freq)^2;
+    sensor.C = 2*sqrt(sensor.M * sensor.K);
+    sensor.G = -sensor.K/sensor.M;
+  case 'none'
     sensor.type = 3;
-end
+end
 
-
-

Populate the stewart structure

-
+
+

Populate the stewart structure

+
stewart.sensors.inertial = sensor;
 
@@ -1602,8 +1484,8 @@ end
-

12 displayArchitecture: 3D plot of the Stewart platform architecture

-
+

11 displayArchitecture: 3D plot of the Stewart platform architecture

+
-
-

Function description

-
+
+

Function description

+
-
function [] = displayArchitecture(stewart, args)
-% displayArchitecture - 3D plot of the Stewart platform architecture
-%
-% Syntax: [] = displayArchitecture(args)
-%
-% Inputs:
-%    - stewart
-%    - args - Structure with the following fields:
-%        - AP   [3x1] - The wanted position of {B} with respect to {A}
-%        - ARB  [3x3] - The rotation matrix that gives the wanted orientation of {B} with respect to {A}
-%        - ARB  [3x3] - The rotation matrix that gives the wanted orientation of {B} with respect to {A}
-%        - F_color [color] - Color used for the Fixed elements
-%        - M_color [color] - Color used for the Mobile elements
-%        - L_color [color] - Color used for the Legs elements
-%        - frames    [true/false] - Display the Frames
-%        - legs      [true/false] - Display the Legs
-%        - joints    [true/false] - Display the Joints
-%        - labels    [true/false] - Display the Labels
-%        - platforms [true/false] - Display the Platforms
-%        - views     ['all', 'xy', 'yz', 'xz', 'default'] -
-%
-% Outputs:
+
function [] = displayArchitecture(stewart, args)
+% displayArchitecture - 3D plot of the Stewart platform architecture
+%
+% Syntax: [] = displayArchitecture(args)
+%
+% Inputs:
+%    - stewart
+%    - args - Structure with the following fields:
+%        - AP   [3x1] - The wanted position of {B} with respect to {A}
+%        - ARB  [3x3] - The rotation matrix that gives the wanted orientation of {B} with respect to {A}
+%        - ARB  [3x3] - The rotation matrix that gives the wanted orientation of {B} with respect to {A}
+%        - F_color [color] - Color used for the Fixed elements
+%        - M_color [color] - Color used for the Mobile elements
+%        - L_color [color] - Color used for the Legs elements
+%        - frames    [true/false] - Display the Frames
+%        - legs      [true/false] - Display the Legs
+%        - joints    [true/false] - Display the Joints
+%        - labels    [true/false] - Display the Labels
+%        - platforms [true/false] - Display the Platforms
+%        - views     ['all', 'xy', 'yz', 'xz', 'default'] -
+%
+% Outputs:
 
-
-

Optional Parameters

-
+ -
-

Check the stewart structure elements

-
+
+

Check the stewart structure elements

+
-
assert(isfield(stewart.platform_F, 'FO_A'), 'stewart.platform_F should have attribute FO_A')
+
assert(isfield(stewart.platform_F, 'FO_A'), 'stewart.platform_F should have attribute FO_A')
 FO_A = stewart.platform_F.FO_A;
 
-assert(isfield(stewart.platform_M, 'MO_B'), 'stewart.platform_M should have attribute MO_B')
+assert(isfield(stewart.platform_M, 'MO_B'), 'stewart.platform_M should have attribute MO_B')
 MO_B = stewart.platform_M.MO_B;
 
-assert(isfield(stewart.geometry, 'H'),   'stewart.geometry should have attribute H')
+assert(isfield(stewart.geometry, 'H'),   'stewart.geometry should have attribute H')
 H = stewart.geometry.H;
 
-assert(isfield(stewart.platform_F, 'Fa'),   'stewart.platform_F should have attribute Fa')
+assert(isfield(stewart.platform_F, 'Fa'),   'stewart.platform_F should have attribute Fa')
 Fa = stewart.platform_F.Fa;
 
-assert(isfield(stewart.platform_M, 'Mb'),   'stewart.platform_M should have attribute Mb')
+assert(isfield(stewart.platform_M, 'Mb'),   'stewart.platform_M should have attribute Mb')
 Mb = stewart.platform_M.Mb;
 
@@ -1698,11 +1580,11 @@ Mb = stewart.platform_M.Mb; The reference frame of the 3d plot corresponds to the frame \(\{F\}\).

-
if ~strcmp(args.views, 'all')
-  figure;
-else
-  f = figure('visible', 'off');
-end
+
if ~strcmp(args.views, 'all')
+  figure;
+else
+  f = figure('visible', 'off');
+end
 
 hold on;
 
@@ -1713,13 +1595,13 @@ We first compute homogeneous matrices that will be useful to position elements o

FTa = [eye(3), FO_A; ...
-       zeros(1,3), 1];
+       zeros(1,3), 1];
 ATb = [args.ARB, args.AP; ...
-       zeros(1,3), 1];
-BTm = [eye(3), -MO_B; ...
-       zeros(1,3), 1];
+       zeros(1,3), 1];
+BTm = [eye(3), -MO_B; ...
+       zeros(1,3), 1];
 
-FTm = FTa*ATb*BTm;
+FTm = FTa*ATb*BTm;
 
@@ -1727,7 +1609,7 @@ FTm = FTa*ATb*BTm; Let’s define a parameter that define the length of the unit vectors used to display the frames.

-
d_unit_vector = H/4;
+
d_unit_vector = H/4;
 
@@ -1735,7 +1617,7 @@ Let’s define a parameter that define the length of the unit vectors used t Let’s define a parameter used to position the labels with respect to the center of the element.

-
d_label = H/20;
+
d_label = H/20;
 
@@ -1749,16 +1631,16 @@ Let’s first plot the frame \(\{F\}\).

Ff = [0, 0, 0];
-if args.frames
-  quiver3(Ff(1)*ones(1,3), Ff(2)*ones(1,3), Ff(3)*ones(1,3), ...
-          [d_unit_vector 0 0], [0 d_unit_vector 0], [0 0 d_unit_vector], '-', 'Color', args.F_color)
+if args.frames
+  quiver3(Ff(1)*ones(1,3), Ff(2)*ones(1,3), Ff(3)*ones(1,3), ...
+          [d_unit_vector 0 0], [0 d_unit_vector 0], [0 0 d_unit_vector], '-', 'Color', args.F_color)
 
-  if args.labels
-    text(Ff(1) + d_label, ...
-        Ff(2) + d_label, ...
-        Ff(3) + d_label, '$\{F\}$', 'Color', args.F_color);
-  end
-end
+  if args.labels
+    text(Ff(1) + d_label, ...
+        Ff(2) + d_label, ...
+        Ff(3) + d_label, '$\{F\}$', 'Color', args.F_color);
+  end
+end
 
@@ -1766,16 +1648,16 @@ end Now plot the frame \(\{A\}\) fixed to the Base.

-
if args.frames
-  quiver3(FO_A(1)*ones(1,3), FO_A(2)*ones(1,3), FO_A(3)*ones(1,3), ...
-          [d_unit_vector 0 0], [0 d_unit_vector 0], [0 0 d_unit_vector], '-', 'Color', args.F_color)
+
if args.frames
+  quiver3(FO_A(1)*ones(1,3), FO_A(2)*ones(1,3), FO_A(3)*ones(1,3), ...
+          [d_unit_vector 0 0], [0 d_unit_vector 0], [0 0 d_unit_vector], '-', 'Color', args.F_color)
 
-  if args.labels
-    text(FO_A(1) + d_label, ...
-         FO_A(2) + d_label, ...
-         FO_A(3) + d_label, '$\{A\}$', 'Color', args.F_color);
-  end
-end
+  if args.labels
+    text(FO_A(1) + d_label, ...
+         FO_A(2) + d_label, ...
+         FO_A(3) + d_label, '$\{A\}$', 'Color', args.F_color);
+  end
+end
 
@@ -1783,18 +1665,18 @@ end Let’s then plot the circle corresponding to the shape of the Fixed base.

-
if args.platforms && stewart.platform_F.type == 1
-  theta = [0:0.01:2*pi+0.01]; % Angles [rad]
-  v = null([0; 0; 1]'); % Two vectors that are perpendicular to the circle normal
-  center = [0; 0; 0]; % Center of the circle
-  radius = stewart.platform_F.R; % Radius of the circle [m]
+
if args.platforms && stewart.platform_F.type == 1
+  theta = [0:0.01:2*pi+0.01]; % Angles [rad]
+  v = null([0; 0; 1]'); % Two vectors that are perpendicular to the circle normal
+  center = [0; 0; 0]; % Center of the circle
+  radius = stewart.platform_F.R; % Radius of the circle [m]
 
-  points = center*ones(1, length(theta)) + radius*(v(:,1)*cos(theta) + v(:,2)*sin(theta));
+  points = center*ones(1, length(theta)) + radius*(v(:,1)*cos(theta) + v(:,2)*sin(theta));
 
-  plot3(points(1,:), ...
-        points(2,:), ...
-        points(3,:), '-', 'Color', args.F_color);
-end
+  plot3(points(1,:), ...
+        points(2,:), ...
+        points(3,:), '-', 'Color', args.F_color);
+end
 
@@ -1802,18 +1684,18 @@ end Let’s now plot the position and labels of the Fixed Joints

-
if args.joints
-  scatter3(Fa(1,:), ...
-           Fa(2,:), ...
-           Fa(3,:), 'MarkerEdgeColor', args.F_color);
-  if args.labels
-    for i = 1:size(Fa,2)
-      text(Fa(1,i) + d_label, ...
-           Fa(2,i), ...
-           Fa(3,i), sprintf('$a_{%i}$', i), 'Color', args.F_color);
-    end
-  end
-end
+
if args.joints
+  scatter3(Fa(1,:), ...
+           Fa(2,:), ...
+           Fa(3,:), 'MarkerEdgeColor', args.F_color);
+  if args.labels
+    for i = 1:size(Fa,2)
+      text(Fa(1,i) + d_label, ...
+           Fa(2,i), ...
+           Fa(3,i), sprintf('$a_{%i}$', i), 'Color', args.F_color);
+    end
+  end
+end
 
@@ -1826,19 +1708,19 @@ end Plot the frame \(\{M\}\).

-
Fm = FTm*[0; 0; 0; 1]; % Get the position of frame {M} w.r.t. {F}
+
Fm = FTm*[0; 0; 0; 1]; % Get the position of frame {M} w.r.t. {F}
 
-if args.frames
-  FM_uv = FTm*[d_unit_vector*eye(3); zeros(1,3)]; % Rotated Unit vectors
-  quiver3(Fm(1)*ones(1,3), Fm(2)*ones(1,3), Fm(3)*ones(1,3), ...
-          FM_uv(1,1:3), FM_uv(2,1:3), FM_uv(3,1:3), '-', 'Color', args.M_color)
+if args.frames
+  FM_uv = FTm*[d_unit_vector*eye(3); zeros(1,3)]; % Rotated Unit vectors
+  quiver3(Fm(1)*ones(1,3), Fm(2)*ones(1,3), Fm(3)*ones(1,3), ...
+          FM_uv(1,1:3), FM_uv(2,1:3), FM_uv(3,1:3), '-', 'Color', args.M_color)
 
-  if args.labels
-    text(Fm(1) + d_label, ...
-         Fm(2) + d_label, ...
-         Fm(3) + d_label, '$\{M\}$', 'Color', args.M_color);
-  end
-end
+  if args.labels
+    text(Fm(1) + d_label, ...
+         Fm(2) + d_label, ...
+         Fm(3) + d_label, '$\{M\}$', 'Color', args.M_color);
+  end
+end
 
@@ -1846,19 +1728,19 @@ end Plot the frame \(\{B\}\).

-
FB = FO_A + args.AP;
+
FB = FO_A + args.AP;
 
-if args.frames
-  FB_uv = FTm*[d_unit_vector*eye(3); zeros(1,3)]; % Rotated Unit vectors
-  quiver3(FB(1)*ones(1,3), FB(2)*ones(1,3), FB(3)*ones(1,3), ...
-          FB_uv(1,1:3), FB_uv(2,1:3), FB_uv(3,1:3), '-', 'Color', args.M_color)
+if args.frames
+  FB_uv = FTm*[d_unit_vector*eye(3); zeros(1,3)]; % Rotated Unit vectors
+  quiver3(FB(1)*ones(1,3), FB(2)*ones(1,3), FB(3)*ones(1,3), ...
+          FB_uv(1,1:3), FB_uv(2,1:3), FB_uv(3,1:3), '-', 'Color', args.M_color)
 
-  if args.labels
-    text(FB(1) - d_label, ...
-         FB(2) + d_label, ...
-         FB(3) + d_label, '$\{B\}$', 'Color', args.M_color);
-  end
-end
+  if args.labels
+    text(FB(1) - d_label, ...
+         FB(2) + d_label, ...
+         FB(3) + d_label, '$\{B\}$', 'Color', args.M_color);
+  end
+end
 
@@ -1866,18 +1748,18 @@ end Let’s then plot the circle corresponding to the shape of the Mobile platform.

-
if args.platforms && stewart.platform_M.type == 1
-  theta = [0:0.01:2*pi+0.01]; % Angles [rad]
-  v = null((FTm(1:3,1:3)*[0;0;1])'); % Two vectors that are perpendicular to the circle normal
-  center = Fm(1:3); % Center of the circle
-  radius = stewart.platform_M.R; % Radius of the circle [m]
+
if args.platforms && stewart.platform_M.type == 1
+  theta = [0:0.01:2*pi+0.01]; % Angles [rad]
+  v = null((FTm(1:3,1:3)*[0;0;1])'); % Two vectors that are perpendicular to the circle normal
+  center = Fm(1:3); % Center of the circle
+  radius = stewart.platform_M.R; % Radius of the circle [m]
 
-  points = center*ones(1, length(theta)) + radius*(v(:,1)*cos(theta) + v(:,2)*sin(theta));
+  points = center*ones(1, length(theta)) + radius*(v(:,1)*cos(theta) + v(:,2)*sin(theta));
 
-  plot3(points(1,:), ...
-        points(2,:), ...
-        points(3,:), '-', 'Color', args.M_color);
-end
+  plot3(points(1,:), ...
+        points(2,:), ...
+        points(3,:), '-', 'Color', args.M_color);
+end
 
@@ -1885,21 +1767,21 @@ end Plot the position and labels of the rotation joints fixed to the mobile platform.

-
if args.joints
-  Fb = FTm*[Mb;ones(1,6)];
+
if args.joints
+  Fb = FTm*[Mb;ones(1,6)];
 
-  scatter3(Fb(1,:), ...
-           Fb(2,:), ...
-           Fb(3,:), 'MarkerEdgeColor', args.M_color);
+  scatter3(Fb(1,:), ...
+           Fb(2,:), ...
+           Fb(3,:), 'MarkerEdgeColor', args.M_color);
 
-  if args.labels
-    for i = 1:size(Fb,2)
-      text(Fb(1,i) + d_label, ...
-           Fb(2,i), ...
-           Fb(3,i), sprintf('$b_{%i}$', i), 'Color', args.M_color);
-    end
-  end
-end
+  if args.labels
+    for i = 1:size(Fb,2)
+      text(Fb(1,i) + d_label, ...
+           Fb(2,i), ...
+           Fb(3,i), sprintf('$b_{%i}$', i), 'Color', args.M_color);
+    end
+  end
+end
 
@@ -1912,82 +1794,82 @@ end Plot the legs connecting the joints of the fixed base to the joints of the mobile platform.

-
if args.legs
-  for i = 1:6
-    plot3([Fa(1,i), Fb(1,i)], ...
-          [Fa(2,i), Fb(2,i)], ...
-          [Fa(3,i), Fb(3,i)], '-', 'Color', args.L_color);
+
if args.legs
+  for i = 1:6
+    plot3([Fa(1,i), Fb(1,i)], ...
+          [Fa(2,i), Fb(2,i)], ...
+          [Fa(3,i), Fb(3,i)], '-', 'Color', args.L_color);
 
-    if args.labels
-      text((Fa(1,i)+Fb(1,i))/2 + d_label, ...
-           (Fa(2,i)+Fb(2,i))/2, ...
-           (Fa(3,i)+Fb(3,i))/2, sprintf('$%i$', i), 'Color', args.L_color);
-    end
-  end
-end
+    if args.labels
+      text((Fa(1,i)+Fb(1,i))/2 + d_label, ...
+           (Fa(2,i)+Fb(2,i))/2, ...
+           (Fa(3,i)+Fb(3,i))/2, sprintf('$%i$', i), 'Color', args.L_color);
+    end
+  end
+end
 
-

12.1 Figure parameters

-
+

11.1 Figure parameters

+
-
switch args.views
-  case 'default'
-      view([1 -0.6 0.4]);
-  case 'xy'
+
switch args.views
+  case 'default'
+      view([1 -0.6 0.4]);
+  case 'xy'
       view([0 0 1]);
-  case 'xz'
-      view([0 -1 0]);
-  case 'yz'
+  case 'xz'
+      view([0 -1 0]);
+  case 'yz'
       view([1 0 0]);
-end
-axis equal;
-axis off;
+end
+axis equal;
+axis off;
 
-

12.2 Subplots

-
+

11.2 Subplots

+
-
if strcmp(args.views, 'all')
-  hAx = findobj('type', 'axes');
+
if strcmp(args.views, 'all')
+  hAx = findobj('type', 'axes');
 
-  figure;
+  figure;
   s1 = subplot(2,2,1);
-  copyobj(get(hAx(1), 'Children'), s1);
+  copyobj(get(hAx(1), 'Children'), s1);
   view([0 0 1]);
-  axis equal;
-  axis off;
-  title('Top')
+  axis equal;
+  axis off;
+  title('Top')
 
   s2 = subplot(2,2,2);
-  copyobj(get(hAx(1), 'Children'), s2);
-  view([1 -0.6 0.4]);
-  axis equal;
-  axis off;
+  copyobj(get(hAx(1), 'Children'), s2);
+  view([1 -0.6 0.4]);
+  axis equal;
+  axis off;
 
   s3 = subplot(2,2,3);
-  copyobj(get(hAx(1), 'Children'), s3);
+  copyobj(get(hAx(1), 'Children'), s3);
   view([1 0 0]);
-  axis equal;
-  axis off;
-  title('Front')
+  axis equal;
+  axis off;
+  title('Front')
 
   s4 = subplot(2,2,4);
-  copyobj(get(hAx(1), 'Children'), s4);
-  view([0 -1 0]);
-  axis equal;
-  axis off;
-  title('Side')
+  copyobj(get(hAx(1), 'Children'), s4);
+  view([0 -1 0]);
+  axis equal;
+  axis off;
+  title('Side')
 
   close(f);
-end
+end
 
@@ -1996,8 +1878,8 @@ end
-

13 describeStewartPlatform: Display some text describing the current defined Stewart Platform

-
+

12 describeStewartPlatform: Display some text describing the current defined Stewart Platform

+
-
-

Function description

-
+
+

Function description

+
-
function [] = describeStewartPlatform(stewart)
-% describeStewartPlatform - Display some text describing the current defined Stewart Platform
-%
-% Syntax: [] = describeStewartPlatform(args)
-%
-% Inputs:
-%    - stewart
-%
-% Outputs:
+
function [] = describeStewartPlatform(stewart)
+% describeStewartPlatform - Display some text describing the current defined Stewart Platform
+%
+% Syntax: [] = describeStewartPlatform(args)
+%
+% Inputs:
+%    - stewart
+%
+% Outputs:
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
     stewart
-end
+end
 
-

13.1 Geometry

-
+

12.1 Geometry

+
-
fprintf('GEOMETRY:\n')
-fprintf('- The height between the fixed based and the top platform is %.3g [mm].\n', 1e3*stewart.geometry.H)
+
fprintf('GEOMETRY:\n')
+fprintf('- The height between the fixed based and the top platform is %.3g [mm].\n', 1e3*stewart.geometry.H)
 
-if stewart.platform_M.MO_B(3) > 0
-  fprintf('- Frame {A} is located %.3g [mm] above the top platform.\n',  1e3*stewart.platform_M.MO_B(3))
-else
-  fprintf('- Frame {A} is located %.3g [mm] below the top platform.\n', - 1e3*stewart.platform_M.MO_B(3))
-end
+if stewart.platform_M.MO_B(3) > 0
+  fprintf('- Frame {A} is located %.3g [mm] above the top platform.\n',  1e3*stewart.platform_M.MO_B(3))
+else
+  fprintf('- Frame {A} is located %.3g [mm] below the top platform.\n', - 1e3*stewart.platform_M.MO_B(3))
+end
 
-fprintf('- The initial length of the struts are:\n')
-fprintf('\t %.3g, %.3g, %.3g, %.3g, %.3g, %.3g [mm]\n', 1e3*stewart.geometry.l)
-fprintf('\n')
+fprintf('- The initial length of the struts are:\n')
+fprintf('\t %.3g, %.3g, %.3g, %.3g, %.3g, %.3g [mm]\n', 1e3*stewart.geometry.l)
+fprintf('\n')
 
-

13.2 Actuators

-
+

12.2 Actuators

+
-
fprintf('ACTUATORS:\n')
-if stewart.actuators.type == 1
-    fprintf('- The actuators are classical.\n')
-    fprintf('- The Stiffness and Damping of each actuators is:\n')
-    fprintf('\t k = %.0e [N/m] \t c = %.0e [N/(m/s)]\n', stewart.actuators.K(1), stewart.actuators.C(1))
-elseif stewart.actuators.type == 2
-    fprintf('- The actuators are mechanicaly amplified.\n')
-    fprintf('- The vertical stiffness and damping contribution of the piezoelectric stack is:\n')
-    fprintf('\t ka = %.0e [N/m] \t ca = %.0e [N/(m/s)]\n', stewart.actuators.Ka(1), stewart.actuators.Ca(1))
-    fprintf('- Vertical stiffness when the piezoelectric stack is removed is:\n')
-    fprintf('\t kr = %.0e [N/m] \t cr = %.0e [N/(m/s)]\n', stewart.actuators.Kr(1), stewart.actuators.Cr(1))
-end
-fprintf('\n')
+
fprintf('ACTUATORS:\n')
+if stewart.actuators.type == 1
+    fprintf('- The actuators are classical.\n')
+    fprintf('- The Stiffness and Damping of each actuators is:\n')
+    fprintf('\t k = %.0e [N/m] \t c = %.0e [N/(m/s)]\n', stewart.actuators.K(1), stewart.actuators.C(1))
+elseif stewart.actuators.type == 2
+    fprintf('- The actuators are mechanicaly amplified.\n')
+    fprintf('- The vertical stiffness and damping contribution of the piezoelectric stack is:\n')
+    fprintf('\t ka = %.0e [N/m] \t ca = %.0e [N/(m/s)]\n', stewart.actuators.Ka(1), stewart.actuators.Ca(1))
+    fprintf('- Vertical stiffness when the piezoelectric stack is removed is:\n')
+    fprintf('\t kr = %.0e [N/m] \t cr = %.0e [N/(m/s)]\n', stewart.actuators.Kr(1), stewart.actuators.Cr(1))
+end
+fprintf('\n')
 
-

13.3 Joints

-
+

12.3 Joints

+
-
fprintf('JOINTS:\n')
+
fprintf('JOINTS:\n')
 
@@ -2092,16 +1974,16 @@ fprintf('\n') Type of the joints on the fixed base.

-
switch stewart.joints_F.type
-  case 1
-    fprintf('- The joints on the fixed based are universal joints\n')
-  case 2
-    fprintf('- The joints on the fixed based are spherical joints\n')
-  case 3
-    fprintf('- The joints on the fixed based are perfect universal joints\n')
-  case 4
-    fprintf('- The joints on the fixed based are perfect spherical joints\n')
-end
+
switch stewart.joints_F.type
+  case 1
+    fprintf('- The joints on the fixed based are universal joints\n')
+  case 2
+    fprintf('- The joints on the fixed based are spherical joints\n')
+  case 3
+    fprintf('- The joints on the fixed based are perfect universal joints\n')
+  case 4
+    fprintf('- The joints on the fixed based are perfect spherical joints\n')
+end
 
@@ -2109,16 +1991,16 @@ end Type of the joints on the mobile platform.

-
switch stewart.joints_M.type
-  case 1
-    fprintf('- The joints on the mobile based are universal joints\n')
-  case 2
-    fprintf('- The joints on the mobile based are spherical joints\n')
-  case 3
-    fprintf('- The joints on the mobile based are perfect universal joints\n')
-  case 4
-    fprintf('- The joints on the mobile based are perfect spherical joints\n')
-end
+
switch stewart.joints_M.type
+  case 1
+    fprintf('- The joints on the mobile based are universal joints\n')
+  case 2
+    fprintf('- The joints on the mobile based are spherical joints\n')
+  case 3
+    fprintf('- The joints on the mobile based are perfect universal joints\n')
+  case 4
+    fprintf('- The joints on the mobile based are perfect spherical joints\n')
+end
 
@@ -2126,8 +2008,8 @@ end Position of the fixed joints

-
fprintf('- The position of the joints on the fixed based with respect to {F} are (in [mm]):\n')
-fprintf('\t % .3g \t % .3g \t % .3g\n', 1e3*stewart.platform_F.Fa)
+
fprintf('- The position of the joints on the fixed based with respect to {F} are (in [mm]):\n')
+fprintf('\t % .3g \t % .3g \t % .3g\n', 1e3*stewart.platform_F.Fa)
 
@@ -2135,29 +2017,29 @@ fprintf('\t % .3g \t % .3g \t % .3g\n', 1e3*stewart.platform_F.Fa) Position of the mobile joints

-
fprintf('- The position of the joints on the mobile based with respect to {M} are (in [mm]):\n')
-fprintf('\t % .3g \t % .3g \t % .3g\n', 1e3*stewart.platform_M.Mb)
-fprintf('\n')
+
fprintf('- The position of the joints on the mobile based with respect to {M} are (in [mm]):\n')
+fprintf('\t % .3g \t % .3g \t % .3g\n', 1e3*stewart.platform_M.Mb)
+fprintf('\n')
 
-

13.4 Kinematics

-
+

12.4 Kinematics

+
-
fprintf('KINEMATICS:\n')
+
fprintf('KINEMATICS:\n')
 
-if isfield(stewart.kinematics, 'K')
-  fprintf('- The Stiffness matrix K is (in [N/m]):\n')
-  fprintf('\t % .0e \t % .0e \t % .0e \t % .0e \t % .0e \t % .0e\n', stewart.kinematics.K)
-end
+if isfield(stewart.kinematics, 'K')
+  fprintf('- The Stiffness matrix K is (in [N/m]):\n')
+  fprintf('\t % .0e \t % .0e \t % .0e \t % .0e \t % .0e \t % .0e\n', stewart.kinematics.K)
+end
 
-if isfield(stewart.kinematics, 'C')
-  fprintf('- The Damping matrix C is (in [m/N]):\n')
-  fprintf('\t % .0e \t % .0e \t % .0e \t % .0e \t % .0e \t % .0e\n', stewart.kinematics.C)
-end
+if isfield(stewart.kinematics, 'C')
+  fprintf('- The Damping matrix C is (in [m/N]):\n')
+  fprintf('\t % .0e \t % .0e \t % .0e \t % .0e \t % .0e \t % .0e\n', stewart.kinematics.C)
+end
 
@@ -2165,8 +2047,8 @@ end
-

14 generateCubicConfiguration: Generate a Cubic Configuration

-
+

13 generateCubicConfiguration: Generate a Cubic Configuration

+
-
-

Function description

-
+
+

Function description

+
-
function [stewart] = generateCubicConfiguration(stewart, args)
-% generateCubicConfiguration - Generate a Cubic Configuration
-%
-% Syntax: [stewart] = generateCubicConfiguration(stewart, args)
-%
-% Inputs:
-%    - stewart - A structure with the following fields
-%        - geometry.H [1x1] - Total height of the platform [m]
-%    - args - Can have the following fields:
-%        - Hc  [1x1] - Height of the "useful" part of the cube [m]
-%        - FOc [1x1] - Height of the center of the cube with respect to {F} [m]
-%        - FHa [1x1] - Height of the plane joining the points ai with respect to the frame {F} [m]
-%        - MHb [1x1] - Height of the plane joining the points bi with respect to the frame {M} [m]
-%
-% Outputs:
-%    - stewart - updated Stewart structure with the added fields:
-%        - platform_F.Fa  [3x6] - Its i'th column is the position vector of joint ai with respect to {F}
-%        - platform_M.Mb  [3x6] - Its i'th column is the position vector of joint bi with respect to {M}
+
function [stewart] = generateCubicConfiguration(stewart, args)
+% generateCubicConfiguration - Generate a Cubic Configuration
+%
+% Syntax: [stewart] = generateCubicConfiguration(stewart, args)
+%
+% Inputs:
+%    - stewart - A structure with the following fields
+%        - geometry.H [1x1] - Total height of the platform [m]
+%    - args - Can have the following fields:
+%        - Hc  [1x1] - Height of the "useful" part of the cube [m]
+%        - FOc [1x1] - Height of the center of the cube with respect to {F} [m]
+%        - FHa [1x1] - Height of the plane joining the points ai with respect to the frame {F} [m]
+%        - MHb [1x1] - Height of the plane joining the points bi with respect to the frame {M} [m]
+%
+% Outputs:
+%    - stewart - updated Stewart structure with the added fields:
+%        - platform_F.Fa  [3x6] - Its i'th column is the position vector of joint ai with respect to {F}
+%        - platform_M.Mb  [3x6] - Its i'th column is the position vector of joint bi with respect to {M}
 
-
-

Documentation

-
+
+

Documentation

+

cubic-configuration-definition.png

-

Figure 11: Cubic Configuration

+

Figure 9: Cubic Configuration

-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
     stewart
-    args.Hc  (1,1) double {mustBeNumeric, mustBePositive} = 60e-3
-    args.FOc (1,1) double {mustBeNumeric} = 50e-3
-    args.FHa (1,1) double {mustBeNumeric, mustBeNonnegative} = 15e-3
-    args.MHb (1,1) double {mustBeNumeric, mustBeNonnegative} = 15e-3
-end
+    args.Hc  (1,1) double {mustBeNumeric, mustBePositive} = 60e-3
+    args.FOc (1,1) double {mustBeNumeric} = 50e-3
+    args.FHa (1,1) double {mustBeNumeric, mustBeNonnegative} = 15e-3
+    args.MHb (1,1) double {mustBeNumeric, mustBeNonnegative} = 15e-3
+end
 
-
-

Check the stewart structure elements

-
+
+

Check the stewart structure elements

+
-
assert(isfield(stewart.geometry, 'H'),   'stewart.geometry should have attribute H')
+
assert(isfield(stewart.geometry, 'H'),   'stewart.geometry should have attribute H')
 H = stewart.geometry.H;
 
@@ -2251,31 +2133,31 @@ We define the useful points of the cube with respect to the Cube’s center.

-
sx = [ 2; -1; -1];
-sy = [ 0;  1; -1];
+
sx = [ 2; -1; -1];
+sy = [ 0;  1; -1];
 sz = [ 1;  1;  1];
 
-R = [sx, sy, sz]./vecnorm([sx, sy, sz]);
+R = [sx, sy, sz]./vecnorm([sx, sy, sz]);
 
-L = args.Hc*sqrt(3);
+L = args.Hc*sqrt(3);
 
-Cc = R'*[[0;0;L],[L;0;L],[L;0;0],[L;L;0],[0;L;0],[0;L;L]] - [0;0;1.5*args.Hc];
+Cc = R'*[[0;0;L],[L;0;L],[L;0;0],[L;L;0],[0;L;0],[0;L;L]] - [0;0;1.5*args.Hc];
 
-CCf = [Cc(:,1), Cc(:,3), Cc(:,3), Cc(:,5), Cc(:,5), Cc(:,1)]; % CCf(:,i) corresponds to the bottom cube's vertice corresponding to the i'th leg
-CCm = [Cc(:,2), Cc(:,2), Cc(:,4), Cc(:,4), Cc(:,6), Cc(:,6)]; % CCm(:,i) corresponds to the top cube's vertice corresponding to the i'th leg
+CCf = [Cc(:,1), Cc(:,3), Cc(:,3), Cc(:,5), Cc(:,5), Cc(:,1)]; % CCf(:,i) corresponds to the bottom cube's vertice corresponding to the i'th leg
+CCm = [Cc(:,2), Cc(:,2), Cc(:,4), Cc(:,4), Cc(:,6), Cc(:,6)]; % CCm(:,i) corresponds to the top cube's vertice corresponding to the i'th leg
 
-
-

Compute the pose

-
+
+

Compute the pose

+

We can compute the vector of each leg \({}^{C}\hat{\bm{s}}_{i}\) (unit vector from \({}^{C}C_{f}\) to \({}^{C}C_{m}\)).

-
CSi = (CCm - CCf)./vecnorm(CCm - CCf);
+
CSi = (CCm - CCf)./vecnorm(CCm - CCf);
 
@@ -2283,16 +2165,16 @@ We can compute the vector of each leg \({}^{C}\hat{\bm{s}}_{i}\) (unit vector fr We now which to compute the position of the joints \(a_{i}\) and \(b_{i}\).

-
Fa = CCf + [0; 0; args.FOc] + ((args.FHa-(args.FOc-args.Hc/2))./CSi(3,:)).*CSi;
-Mb = CCf + [0; 0; args.FOc-H] + ((H-args.MHb-(args.FOc-args.Hc/2))./CSi(3,:)).*CSi;
+
Fa = CCf + [0; 0; args.FOc] + ((args.FHa-(args.FOc-args.Hc/2))./CSi(3,:)).*CSi;
+Mb = CCf + [0; 0; args.FOc-H] + ((H-args.MHb-(args.FOc-args.Hc/2))./CSi(3,:)).*CSi;
 
-
-

Populate the stewart structure

-
+
+

Populate the stewart structure

+
stewart.platform_F.Fa = Fa;
 stewart.platform_M.Mb = Mb;
@@ -2303,8 +2185,8 @@ stewart.platform_M.Mb = Mb;
 
-

15 computeJacobian: Compute the Jacobian Matrix

-
+

14 computeJacobian: Compute the Jacobian Matrix

+

@@ -2314,42 +2196,42 @@ This Matlab function is accessible here.

-
-

Function description

-
+
+

Function description

+
-
function [stewart] = computeJacobian(stewart)
-% computeJacobian -
-%
-% Syntax: [stewart] = computeJacobian(stewart)
-%
-% Inputs:
-%    - stewart - With at least the following fields:
-%      - geometry.As [3x6] - The 6 unit vectors for each strut expressed in {A}
-%      - geometry.Ab [3x6] - The 6 position of the joints bi expressed in {A}
-%      - actuators.K [6x1] - Total stiffness of the actuators
-%
-% Outputs:
-%    - stewart - With the 3 added field:
-%        - kinematics.J [6x6] - The Jacobian Matrix
-%        - kinematics.K [6x6] - The Stiffness Matrix
-%        - kinematics.C [6x6] - The Compliance Matrix
+
function [stewart] = computeJacobian(stewart)
+% computeJacobian -
+%
+% Syntax: [stewart] = computeJacobian(stewart)
+%
+% Inputs:
+%    - stewart - With at least the following fields:
+%      - geometry.As [3x6] - The 6 unit vectors for each strut expressed in {A}
+%      - geometry.Ab [3x6] - The 6 position of the joints bi expressed in {A}
+%      - actuators.K [6x1] - Total stiffness of the actuators
+%
+% Outputs:
+%    - stewart - With the 3 added field:
+%        - kinematics.J [6x6] - The Jacobian Matrix
+%        - kinematics.K [6x6] - The Stiffness Matrix
+%        - kinematics.C [6x6] - The Compliance Matrix
 
-
-

Check the stewart structure elements

-
+
+

Check the stewart structure elements

+
-
assert(isfield(stewart.geometry, 'As'),   'stewart.geometry should have attribute As')
+
assert(isfield(stewart.geometry, 'As'),   'stewart.geometry should have attribute As')
 As = stewart.geometry.As;
 
-assert(isfield(stewart.geometry, 'Ab'),   'stewart.geometry should have attribute Ab')
+assert(isfield(stewart.geometry, 'Ab'),   'stewart.geometry should have attribute Ab')
 Ab = stewart.geometry.Ab;
 
-assert(isfield(stewart.actuators, 'K'),   'stewart.actuators should have attribute K')
+assert(isfield(stewart.actuators, 'K'),   'stewart.actuators should have attribute K')
 Ki = stewart.actuators.K;
 
@@ -2361,7 +2243,7 @@ Ki = stewart.actuators.K;

Compute Jacobian Matrix

-
J = [As' , cross(Ab, As)'];
+
J = [As' , cross(Ab, As)'];
 
@@ -2371,7 +2253,7 @@ Ki = stewart.actuators.K;

Compute Stiffness Matrix

-
K = J'*diag(Ki)*J;
+
K = J'*diag(Ki)*J;
 
@@ -2387,9 +2269,9 @@ Ki = stewart.actuators.K;
-
-

Populate the stewart structure

-
+
+

Populate the stewart structure

+
stewart.kinematics.J = J;
 stewart.kinematics.K = K;
@@ -2402,8 +2284,8 @@ stewart.kinematics.C = C;
 
 
 
-

16 inverseKinematics: Compute Inverse Kinematics

-
+

15 inverseKinematics: Compute Inverse Kinematics

+

@@ -2449,57 +2331,57 @@ Otherwise, when the limbs’ lengths derived yield complex numbers, then the
-
-

Function description

-
+
+

Function description

+
-
function [Li, dLi] = inverseKinematics(stewart, args)
-% inverseKinematics - Compute the needed length of each strut to have the wanted position and orientation of {B} with respect to {A}
-%
-% Syntax: [stewart] = inverseKinematics(stewart)
-%
-% Inputs:
-%    - stewart - A structure with the following fields
-%        - geometry.Aa   [3x6] - The positions ai expressed in {A}
-%        - geometry.Bb   [3x6] - The positions bi expressed in {B}
-%        - geometry.l    [6x1] - Length of each strut
-%    - args - Can have the following fields:
-%        - AP   [3x1] - The wanted position of {B} with respect to {A}
-%        - ARB  [3x3] - The rotation matrix that gives the wanted orientation of {B} with respect to {A}
-%
-% Outputs:
-%    - Li   [6x1] - The 6 needed length of the struts in [m] to have the wanted pose of {B} w.r.t. {A}
-%    - dLi  [6x1] - The 6 needed displacement of the struts from the initial position in [m] to have the wanted pose of {B} w.r.t. {A}
+
function [Li, dLi] = inverseKinematics(stewart, args)
+% inverseKinematics - Compute the needed length of each strut to have the wanted position and orientation of {B} with respect to {A}
+%
+% Syntax: [stewart] = inverseKinematics(stewart)
+%
+% Inputs:
+%    - stewart - A structure with the following fields
+%        - geometry.Aa   [3x6] - The positions ai expressed in {A}
+%        - geometry.Bb   [3x6] - The positions bi expressed in {B}
+%        - geometry.l    [6x1] - Length of each strut
+%    - args - Can have the following fields:
+%        - AP   [3x1] - The wanted position of {B} with respect to {A}
+%        - ARB  [3x3] - The rotation matrix that gives the wanted orientation of {B} with respect to {A}
+%
+% Outputs:
+%    - Li   [6x1] - The 6 needed length of the struts in [m] to have the wanted pose of {B} w.r.t. {A}
+%    - dLi  [6x1] - The 6 needed displacement of the struts from the initial position in [m] to have the wanted pose of {B} w.r.t. {A}
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
     stewart
     args.AP  (3,1) double {mustBeNumeric} = zeros(3,1)
     args.ARB (3,3) double {mustBeNumeric} = eye(3)
-end
+end
 
-
-

Check the stewart structure elements

-
+
+

Check the stewart structure elements

+
-
assert(isfield(stewart.geometry, 'Aa'),   'stewart.geometry should have attribute Aa')
+
assert(isfield(stewart.geometry, 'Aa'),   'stewart.geometry should have attribute Aa')
 Aa = stewart.geometry.Aa;
 
-assert(isfield(stewart.geometry, 'Bb'),   'stewart.geometry should have attribute Bb')
+assert(isfield(stewart.geometry, 'Bb'),   'stewart.geometry should have attribute Bb')
 Bb = stewart.geometry.Bb;
 
-assert(isfield(stewart.geometry, 'l'),   'stewart.geometry should have attribute l')
+assert(isfield(stewart.geometry, 'l'),   'stewart.geometry should have attribute l')
 l = stewart.geometry.l;
 
@@ -2511,12 +2393,12 @@ l = stewart.geometry.l;

Compute

-
Li = sqrt(args.AP'*args.AP + diag(Bb'*Bb) + diag(Aa'*Aa) - (2*args.AP'*Aa)' + (2*args.AP'*(args.ARB*Bb))' - diag(2*(args.ARB*Bb)'*Aa));
+
Li = sqrt(args.AP'*args.AP + diag(Bb'*Bb) + diag(Aa'*Aa) - (2*args.AP'*Aa)' + (2*args.AP'*(args.ARB*Bb))' - diag(2*(args.ARB*Bb)'*Aa));
 
-
dLi = Li-l;
+
dLi = Li-l;
 
@@ -2524,8 +2406,8 @@ l = stewart.geometry.l;
-

17 forwardKinematicsApprox: Compute the Approximate Forward Kinematics

-
+

16 forwardKinematicsApprox: Compute the Approximate Forward Kinematics

+
-
-

Function description

-
+
+

Function description

+
-
function [P, R] = forwardKinematicsApprox(stewart, args)
-% forwardKinematicsApprox - Computed the approximate pose of {B} with respect to {A} from the length of each strut and using
-%                           the Jacobian Matrix
-%
-% Syntax: [P, R] = forwardKinematicsApprox(stewart, args)
-%
-% Inputs:
-%    - stewart - A structure with the following fields
-%        - kinematics.J  [6x6] - The Jacobian Matrix
-%    - args - Can have the following fields:
-%        - dL [6x1] - Displacement of each strut [m]
-%
-% Outputs:
-%    - P  [3x1] - The estimated position of {B} with respect to {A}
-%    - R  [3x3] - The estimated rotation matrix that gives the orientation of {B} with respect to {A}
+
function [P, R] = forwardKinematicsApprox(stewart, args)
+% forwardKinematicsApprox - Computed the approximate pose of {B} with respect to {A} from the length of each strut and using
+%                           the Jacobian Matrix
+%
+% Syntax: [P, R] = forwardKinematicsApprox(stewart, args)
+%
+% Inputs:
+%    - stewart - A structure with the following fields
+%        - kinematics.J  [6x6] - The Jacobian Matrix
+%    - args - Can have the following fields:
+%        - dL [6x1] - Displacement of each strut [m]
+%
+% Outputs:
+%    - P  [3x1] - The estimated position of {B} with respect to {A}
+%    - R  [3x3] - The estimated rotation matrix that gives the orientation of {B} with respect to {A}
 
-
-

Optional Parameters

-
+
+

Optional Parameters

+
arguments
     stewart
     args.dL (6,1) double {mustBeNumeric} = zeros(6,1)
-end
+end
 
-
-

Check the stewart structure elements

-
+
+

Check the stewart structure elements

+
-
assert(isfield(stewart.kinematics, 'J'),   'stewart.kinematics should have attribute J')
+
assert(isfield(stewart.kinematics, 'J'),   'stewart.kinematics should have attribute J')
 J = stewart.kinematics.J;
 
@@ -2592,7 +2474,7 @@ position and orientation of {B} with respect to {A} using the following formula: \[ d \bm{\mathcal{X}} = \bm{J}^{-1} d\bm{\mathcal{L}} \]

-
X = J\args.dL;
+
X = J\args.dL;
 
@@ -2600,7 +2482,7 @@ position and orientation of {B} with respect to {A} using the following formula: The position vector corresponds to the first 3 elements.

-
P = X(1:3);
+
P = X(1:3);
 
@@ -2609,8 +2491,8 @@ The next 3 elements are the orientation of {B} with respect to {A} expressed using the screw axis.

-
theta = norm(X(4:6));
-s = X(4:6)/theta;
+
theta = norm(X(4:6));
+s = X(4:6)/theta;
 
@@ -2618,9 +2500,9 @@ s = X(4:6)/theta; We then compute the corresponding rotation matrix.

-
R = [s(1)^2*(1-cos(theta)) + cos(theta) ,        s(1)*s(2)*(1-cos(theta)) - s(3)*sin(theta), s(1)*s(3)*(1-cos(theta)) + s(2)*sin(theta);
-     s(2)*s(1)*(1-cos(theta)) + s(3)*sin(theta), s(2)^2*(1-cos(theta)) + cos(theta),         s(2)*s(3)*(1-cos(theta)) - s(1)*sin(theta);
-     s(3)*s(1)*(1-cos(theta)) - s(2)*sin(theta), s(3)*s(2)*(1-cos(theta)) + s(1)*sin(theta), s(3)^2*(1-cos(theta)) + cos(theta)];
+
R = [s(1)^2*(1-cos(theta)) + cos(theta) ,        s(1)*s(2)*(1-cos(theta)) - s(3)*sin(theta), s(1)*s(3)*(1-cos(theta)) + s(2)*sin(theta);
+     s(2)*s(1)*(1-cos(theta)) + s(3)*sin(theta), s(2)^2*(1-cos(theta)) + cos(theta),         s(2)*s(3)*(1-cos(theta)) - s(1)*sin(theta);
+     s(3)*s(1)*(1-cos(theta)) - s(2)*sin(theta), s(3)*s(2)*(1-cos(theta)) + s(1)*sin(theta), s(3)^2*(1-cos(theta)) + cos(theta)];
 
@@ -2629,7 +2511,7 @@ We then compute the corresponding rotation matrix.

Author: Dehaeze Thomas

-

Created: 2020-09-01 mar. 13:48

+

Created: 2020-11-03 mar. 09:45

diff --git a/mat/APA300ML.mat b/mat/APA300ML.mat new file mode 100644 index 0000000..560064a Binary files /dev/null and b/mat/APA300ML.mat differ diff --git a/mat/APA300ML_simplified_model.mat b/mat/APA300ML_simplified_model.mat new file mode 100644 index 0000000..8186553 Binary files /dev/null and b/mat/APA300ML_simplified_model.mat differ diff --git a/mat/conf_log.mat b/mat/conf_log.mat index cd9f9c7..5498a97 100644 Binary files a/mat/conf_log.mat and b/mat/conf_log.mat differ diff --git a/mat/conf_simscape.mat b/mat/conf_simscape.mat index 6d79f55..fdcfbf2 100644 Binary files a/mat/conf_simscape.mat and b/mat/conf_simscape.mat differ diff --git a/mat/controller.mat b/mat/controller.mat index 4f0d599..b5abd15 100644 Binary files a/mat/controller.mat and b/mat/controller.mat differ diff --git a/mat/flexor_025.mat b/mat/flexor_025.mat new file mode 100644 index 0000000..a86058a Binary files /dev/null and b/mat/flexor_025.mat differ diff --git a/mat/nass_disturbances.mat b/mat/nass_disturbances.mat index 465e5f2..aadbc48 100644 Binary files a/mat/nass_disturbances.mat and b/mat/nass_disturbances.mat differ diff --git a/mat/nass_references.mat b/mat/nass_references.mat index 0dc6799..640f3e2 100644 Binary files a/mat/nass_references.mat and b/mat/nass_references.mat differ diff --git a/mat/stages.mat b/mat/stages.mat index c4bb0de..278ac2f 100644 Binary files a/mat/stages.mat and b/mat/stages.mat differ diff --git a/matlab/nano_hexapod_strut.slx b/matlab/nano_hexapod_strut.slx index fea38c4..8df52ee 100644 Binary files a/matlab/nano_hexapod_strut.slx and b/matlab/nano_hexapod_strut.slx differ diff --git a/matlab/nass_model.slx b/matlab/nass_model.slx index 0494da4..632f0ba 100644 Binary files a/matlab/nass_model.slx and b/matlab/nass_model.slx differ diff --git a/org/flexible_joints_study.org b/org/flexible_joints_study.org index 0bcac19..094173c 100644 --- a/org/flexible_joints_study.org +++ b/org/flexible_joints_study.org @@ -534,10 +534,10 @@ We choose realistic values of the axial stiffness of the joints: \[ K_a = 60\,[N/\mu m] \] #+begin_src matlab - Kz_F = 60e6*ones(6,1); % [N/m] - Kz_M = 60e6*ones(6,1); % [N/m] - Cz_F = 1*ones(6,1); % [N/(m/s)] - Cz_M = 1*ones(6,1); % [N/(m/s)] + Ka_F = 60e6*ones(6,1); % [N/m] + Ka_M = 60e6*ones(6,1); % [N/m] + Ca_F = 1*ones(6,1); % [N/(m/s)] + Ca_M = 1*ones(6,1); % [N/(m/s)] #+end_src *** Initialization @@ -591,10 +591,10 @@ The obtained dynamics are shown in Figure [[fig:flex_joint_trans_dvf]]. initializeNanoHexapod('k', k_opt, 'c', c_opt, ... 'type_F', 'universal_3dof', ... 'type_M', 'spherical_3dof', ... - 'Kz_F', Kz_F, ... - 'Kz_M', Kz_M, ... - 'Cz_F', Cz_F, ... - 'Cz_M', Cz_M); + 'Ka_F', Ka_F, ... + 'Ka_M', Ka_M, ... + 'Ca_F', Ca_F, ... + 'Ca_M', Ca_M); G_dvf_3dof = linearize(mdl, io); G_dvf_3dof.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}; @@ -674,10 +674,10 @@ The dynamics is compare with and without the joint flexibility in Figure [[fig:f initializeNanoHexapod('k', k_opt, 'c', c_opt, ... 'type_F', 'universal_3dof', ... 'type_M', 'spherical_3dof', ... - 'Kz_F', Kz_F, ... - 'Kz_M', Kz_M, ... - 'Cz_F', Cz_F, ... - 'Cz_M', Cz_M); + 'Ka_F', Ka_F, ... + 'Ka_M', Ka_M, ... + 'Ca_F', Ca_F, ... + 'Ca_M', Ca_M); G = linearize(mdl, io); G.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}; @@ -759,7 +759,7 @@ We wish now to see what is the impact of the *axial* stiffness of the flexible j Let's consider the following values for the axial stiffness: #+begin_src matlab - Kzs = [1e4, 1e5, 1e6, 1e7, 1e8, 1e9]; % [N/m] + Kas = [1e4, 1e5, 1e6, 1e7, 1e8, 1e9]; % [N/m] #+end_src We also consider here a nano-hexapod with the identified optimal actuator stiffness ($k = 10^5\,[N/m]$). @@ -788,16 +788,16 @@ It can be seen that very little active damping can be achieve for axial stiffnes io(io_i) = linio([mdl, '/Controller'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Dnlm'); io_i = io_i + 1; % Force Sensors - G_dvf_3dof_s = {zeros(length(Kzs), 1)}; + G_dvf_3dof_s = {zeros(length(Kas), 1)}; - for i = 1:length(Kzs) + for i = 1:length(Kas) initializeNanoHexapod('k', k_opt, 'c', c_opt, ... 'type_F', 'universal_3dof', ... 'type_M', 'spherical_3dof', ... - 'Kz_F', Kzs(i), ... - 'Kz_M', Kzs(i), ... - 'Cz_F', 0.05*sqrt(Kzs(i)*10), ... - 'Cz_M', 0.05*sqrt(Kzs(i)*10)); + 'Ka_F', Kas(i), ... + 'Ka_M', Kas(i), ... + 'Ca_F', 0.05*sqrt(Kas(i)*10), ... + 'Ca_M', 0.05*sqrt(Kas(i)*10)); G = linearize(mdl, io); G.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}; @@ -814,7 +814,7 @@ It can be seen that very little active damping can be achieve for axial stiffnes ax1 = subplot(2, 1, 1); hold on; - for i = 1:length(Kzs) + for i = 1:length(Kas) plot(freqs, abs(squeeze(freqresp(G_dvf_3dof_s{i}(1, 1), freqs, 'Hz')))); end plot(freqs, abs(squeeze(freqresp(G_dvf(1, 1), freqs, 'Hz'))), 'k--'); @@ -824,9 +824,9 @@ It can be seen that very little active damping can be achieve for axial stiffnes ax2 = subplot(2, 1, 2); hold on; - for i = 1:length(Kzs) + for i = 1:length(Kas) plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_dvf_3dof_s{i}(1, 1), freqs, 'Hz')))), ... - 'DisplayName', sprintf('$k = %.0g$ [N/m]', Kzs(i))); + 'DisplayName', sprintf('$k = %.0g$ [N/m]', Kas(i))); end plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_dvf(1, 1), freqs, 'Hz')))), 'k--', ... 'DisplayName', 'Perfect Joint'); @@ -855,10 +855,10 @@ It can be seen that very little active damping can be achieve for axial stiffnes gains = logspace(2, 5, 300); hold on; - for i = 1:length(Kzs) + for i = 1:length(Kas) set(gca,'ColorOrderIndex',i); plot(real(pole(G_dvf_3dof_s{i})), imag(pole(G_dvf_3dof_s{i})), 'x', ... - 'DisplayName', sprintf('$k = %.0g$ [N/m]', Kzs(i))); + 'DisplayName', sprintf('$k = %.0g$ [N/m]', Kas(i))); set(gca,'ColorOrderIndex',i); plot(real(tzero(G_dvf_3dof_s{i})), imag(tzero(G_dvf_3dof_s{i})), 'o', ... 'HandleVisibility', 'off'); @@ -918,16 +918,16 @@ The dynamics from $\bm{\tau}^\prime$ to $\bm{\epsilon}_{\mathcal{X}_n}$ (for the load('mat/stages.mat', 'nano_hexapod'); - Gl_3dof_s = {zeros(length(Kzs), 1)}; + Gl_3dof_s = {zeros(length(Kas), 1)}; - for i = 1:length(Kzs) + for i = 1:length(Kas) initializeNanoHexapod('k', k_opt, 'c', c_opt, ... 'type_F', 'universal_3dof', ... 'type_M', 'spherical_3dof', ... - 'Kz_F', Kzs(i), ... - 'Kz_M', Kzs(i), ... - 'Cz_F', 0.05*sqrt(Kzs(i)*10), ... - 'Cz_M', 0.05*sqrt(Kzs(i)*10)); + 'Ka_F', Kas(i), ... + 'Ka_M', Kas(i), ... + 'Ca_F', 0.05*sqrt(Kas(i)*10), ... + 'Ca_M', 0.05*sqrt(Kas(i)*10)); G = linearize(mdl, io); G.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}; @@ -946,7 +946,7 @@ The dynamics from $\bm{\tau}^\prime$ to $\bm{\epsilon}_{\mathcal{X}_n}$ (for the ax1 = subplot(2, 1, 1); hold on; - for i = 1:length(Kzs) + for i = 1:length(Kas) plot(freqs, abs(squeeze(freqresp(Gl_3dof_s{i}(1, 1), freqs, 'Hz')))); end hold off; @@ -955,9 +955,9 @@ The dynamics from $\bm{\tau}^\prime$ to $\bm{\epsilon}_{\mathcal{X}_n}$ (for the ax2 = subplot(2, 1, 2); hold on; - for i = 1:length(Kzs) + for i = 1:length(Kas) plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(Gl_3dof_s{i}(1, 1), freqs, 'Hz')))), ... - 'DisplayName', sprintf('$k = %.0g$ [N/m]', Kzs(i))); + 'DisplayName', sprintf('$k = %.0g$ [N/m]', Kas(i))); end hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin'); @@ -1012,3 +1012,262 @@ The dynamics from $\bm{\tau}^\prime$ to $\bm{\epsilon}_{\mathcal{X}_n}$ (for the As there is generally a trade-off between bending stiffness and axial stiffness, it should be highlighted that the *axial* stiffness is the most important property of the flexible joints. #+end_important + + +* Designed Flexible Joints +** Matlab Init :noexport:ignore: +#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name) + <> +#+end_src + +#+begin_src matlab :exports none :results silent :noweb yes + <> +#+end_src + +#+begin_src matlab :tangle no + simulinkproject('../'); +#+end_src + +#+begin_src matlab + load('mat/conf_simulink.mat'); + open('nass_model.slx') +#+end_src + +** Initialization +Let's initialize all the stages with default parameters. +#+begin_src matlab + initializeGround(); + initializeGranite(); + initializeTy(); + initializeRy(); + initializeRz(); + initializeMicroHexapod(); + initializeAxisc('type', 'none'); + initializeMirror('type', 'none'); + initializeMirror(); +#+end_src + +#+begin_src matlab :exports none + initializeSimscapeConfiguration(); + initializeDisturbances('enable', false); + initializeLoggingConfiguration('log', 'none'); + + initializeController('type', 'hac-dvf'); +#+end_src + +Let's consider the heaviest mass which should we the most problematic with it comes to the flexible joints. +#+begin_src matlab + initializeSample('mass', 50, 'freq', 200*ones(6,1)); + initializeReferences('Rz_type', 'rotating-not-filtered', 'Rz_period', 60); +#+end_src + +#+begin_src matlab :exports none + K = tf(zeros(6)); + Kdvf = tf(zeros(6)); +#+end_src + +#+begin_src matlab + flex_joint = load('./mat/flexor_025.mat', 'int_xyz', 'int_i', 'n_xyz', 'n_i', 'nodes', 'M', 'K'); + apa = load('./mat/APA300ML_simplified_model.mat'); +#+end_src + +#+begin_src matlab + initializeNanoHexapod('actuator', 'amplified', ... + 'ke', apa.ke, 'ka', apa.ka, 'k1', apa.k1, 'c1', apa.c1, 'F_gain', apa.F_gain, ... + 'type_M', 'spherical_3dof', ... + 'Kr_M', flex_joint.K(1,1)*ones(6,1), ... + 'Ka_M', flex_joint.K(3,3)*ones(6,1), ... + 'Kf_M', flex_joint.K(4,4)*ones(6,1), ... + 'Kt_M', flex_joint.K(6,6)*ones(6,1), ... + 'type_F', 'spherical_3dof', ... + 'Kr_F', flex_joint.K(1,1)*ones(6,1), ... + 'Ka_F', flex_joint.K(3,3)*ones(6,1), ... + 'Kf_F', flex_joint.K(4,4)*ones(6,1), ... + 'Kt_F', flex_joint.K(6,6)*ones(6,1)); +#+end_src + +#+begin_src matlab + initializeNanoHexapod(); +#+end_src + +** Direct Velocity Feedback +#+begin_src matlab :exports none + %% Name of the Simulink File + mdl = 'nass_model'; + + %% Input/Output definition + clear io; io_i = 1; + io(io_i) = linio([mdl, '/Controller'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs + io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Dnlm'); io_i = io_i + 1; % Force Sensors +#+end_src + +#+begin_src matlab :exports none + G_dvf = linearize(mdl, io); + G_dvf.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}; + G_dvf.OutputName = {'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6'}; +#+end_src + +#+begin_src matlab :exports none + freqs = logspace(0, 4, 1000); + + figure; + + ax1 = subplot(2, 1, 1); + hold on; + plot(freqs, abs(squeeze(freqresp(G_dvf(1, 1), freqs, 'Hz')))); + hold off; + set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); + ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]); + + ax2 = subplot(2, 1, 2); + hold on; + plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_dvf(1, 1), freqs, 'Hz')))), ... + 'DisplayName', 'Designed Joints'); + hold off; + set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin'); + ylabel('Phase [deg]'); xlabel('Frequency [Hz]'); + ylim([-270, 90]); + yticks([-360:90:360]); + legend('location', 'northeast'); + + linkaxes([ax1,ax2],'x'); +#+end_src + +#+begin_src matlab :exports none + K_iff = 1e6*s/(1 + s/2/pi/100)/(1 + s/2/pi/100); + + freqs = logspace(0, 4, 1000); + + figure; + + ax1 = subplot(2, 1, 1); + hold on; + plot(freqs, abs(squeeze(freqresp(K_iff*G_dvf(1, 1), freqs, 'Hz')))); + hold off; + set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); + ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]); + + ax2 = subplot(2, 1, 2); + hold on; + plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(K_iff*G_dvf(1, 1), freqs, 'Hz')))), ... + 'DisplayName', 'Designed Joints'); + hold off; + set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin'); + ylabel('Phase [deg]'); xlabel('Frequency [Hz]'); + ylim([-270, 90]); + yticks([-360:90:360]); + legend('location', 'northeast'); + + linkaxes([ax1,ax2],'x'); +#+end_src + +#+begin_src matlab :exports none + gains = logspace(0, 5, 100); + + figure; + hold on; + plot(real(pole(G_dvf)), imag(pole(G_dvf)), 'x'); + set(gca,'ColorOrderIndex',1); + plot(real(tzero(G_dvf)), imag(tzero(G_dvf)), 'o'); + for i = 1:length(gains) + set(gca,'ColorOrderIndex',1); + cl_poles = pole(feedback(G_dvf, (gains(i)*s/(1+s/2/pi/100)^2)*eye(6))); + plot(real(cl_poles), imag(cl_poles), '.'); + end + % ylim([0, 2*pi*500]); + % xlim([-2*pi*500,0]); + xlabel('Real Part') + ylabel('Imaginary Part') + axis square +#+end_src + +** Integral Force Feedback +#+begin_src matlab :exports none + %% Name of the Simulink File + mdl = 'nass_model'; + + %% Input/Output definition + clear io; io_i = 1; + io(io_i) = linio([mdl, '/Controller'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs + io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Fnlm'); io_i = io_i + 1; % Force Sensors +#+end_src + +#+begin_src matlab :exports none + G_iff = linearize(mdl, io); + G_iff.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}; + G_iff.OutputName = {'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6'}; +#+end_src + +#+begin_src matlab :exports none + freqs = logspace(0, 4, 1000); + + figure; + + ax1 = subplot(2, 1, 1); + hold on; + plot(freqs, abs(squeeze(freqresp(G_iff(1, 1), freqs, 'Hz')))); + hold off; + set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); + ylabel('Amplitude [N/N]'); set(gca, 'XTickLabel',[]); + + ax2 = subplot(2, 1, 2); + hold on; + plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_iff(1, 1), freqs, 'Hz')))), ... + 'DisplayName', 'Designed Joints'); + hold off; + set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin'); + ylabel('Phase [deg]'); xlabel('Frequency [Hz]'); + ylim([-270, 90]); + yticks([-360:90:360]); + legend('location', 'northeast'); + + linkaxes([ax1,ax2],'x'); +#+end_src + +#+begin_src matlab :exports none + K_iff = -1e4/(s + 2*pi*5)*s/(s + 2*pi*5); + + freqs = logspace(-1, 4, 1000); + + figure; + + ax1 = subplot(2, 1, 1); + hold on; + plot(freqs, abs(squeeze(freqresp(K_iff*G_iff(1, 1), freqs, 'Hz')))); + hold off; + set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); + ylabel('Loop Gain'); set(gca, 'XTickLabel',[]); + + ax2 = subplot(2, 1, 2); + hold on; + plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(K_iff*G_iff(1, 1), freqs, 'Hz')))), ... + 'DisplayName', 'Designed Joints'); + hold off; + set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin'); + ylabel('Phase [deg]'); xlabel('Frequency [Hz]'); + ylim([-180, 180]); + yticks([-360:90:360]); + legend('location', 'northeast'); + + linkaxes([ax1,ax2],'x'); +#+end_src + +#+begin_src matlab :exports none + gains = logspace(0, 5, 100); + + figure; + hold on; + plot(real(pole(G_iff)), imag(pole(G_iff)), 'x'); + set(gca,'ColorOrderIndex',1); + plot(real(tzero(G_iff)), imag(tzero(G_iff)), 'o'); + for i = 1:length(gains) + set(gca,'ColorOrderIndex',1); + cl_poles = pole(feedback(G_iff, -(gains(i)/(s + 2*pi*5)*s/(s + 2*pi*5))*eye(6))); + plot(real(cl_poles), imag(cl_poles), '.'); + end + ylim([0, 2*pi*500]); + xlim([-2*pi*500,0]); + xlabel('Real Part') + ylabel('Imaginary Part') + axis square +#+end_src diff --git a/org/simscape_subsystems.org b/org/simscape_subsystems.org index 2fe18f0..e293c57 100644 --- a/org/simscape_subsystems.org +++ b/org/simscape_subsystems.org @@ -278,6 +278,7 @@ The output =sample_pos= corresponds to the impact point of the X-ray. 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] + args.sample_pos (1,1) double {mustBeNumeric} = 0.8 % Height of the measurment point [m] end #+end_src @@ -322,7 +323,7 @@ Properties of the Material and link to the geometry of the granite. Z-offset for the initial position of the sample with respect to the granite top surface. #+begin_src matlab - granite.sample_pos = 0.8; % [m] + granite.sample_pos = args.sample_pos; % [m] #+end_src ** Stiffness and Damping properties @@ -1169,7 +1170,7 @@ We define the geometrical values. #+begin_src matlab mirror.h = 0.05; % Height of the mirror [m] - mirror.thickness = 0.025; % Thickness of the plate supporting the sample [m] + mirror.thickness = 0.02; % Thickness of the plate supporting the sample [m] mirror.hole_rad = 0.125; % radius of the hole in the mirror [m] @@ -1178,11 +1179,11 @@ We define the geometrical values. % point of interest offset in z (above the top surfave) [m] switch args.type case 'none' - mirror.jacobian = 0.20; + mirror.jacobian = 0.205; case 'rigid' - mirror.jacobian = 0.20 - mirror.h; + mirror.jacobian = 0.205 - mirror.h; case 'flexible' - mirror.jacobian = 0.20 - mirror.h; + mirror.jacobian = 0.205 - mirror.h; end mirror.rad = 0.180; % radius of the mirror (at the bottom surface) [m] @@ -1269,8 +1270,8 @@ The =mirror= structure is saved. arguments args.type char {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'init'})} = 'flexible' % initializeFramesPositions - args.H (1,1) double {mustBeNumeric, mustBePositive} = 90e-3 - args.MO_B (1,1) double {mustBeNumeric} = 175e-3 + args.H (1,1) double {mustBeNumeric, mustBePositive} = 95e-3 + args.MO_B (1,1) double {mustBeNumeric} = 170e-3 % generateGeneralConfiguration args.FH (1,1) double {mustBeNumeric, mustBePositive} = 15e-3 args.FR (1,1) double {mustBeNumeric, mustBePositive} = 100e-3 @@ -1284,25 +1285,28 @@ The =mirror= structure is saved. args.ke (1,1) double {mustBeNumeric} = 5e6 args.ka (1,1) double {mustBeNumeric} = 60e6 args.c1 (1,1) double {mustBeNumeric} = 10 - args.ce (1,1) double {mustBeNumeric} = 10 - args.ca (1,1) double {mustBeNumeric} = 10 + args.F_gain (1,1) double {mustBeNumeric} = 1 args.k (1,1) double {mustBeNumeric} = -1 args.c (1,1) double {mustBeNumeric} = -1 % initializeJointDynamics - args.type_F char {mustBeMember(args.type_F,{'universal', 'spherical', 'universal_p', 'spherical_p', 'universal_3dof'})} = 'universal' - args.type_M char {mustBeMember(args.type_M,{'universal', 'spherical', 'universal_p', 'spherical_p', 'spherical_3dof'})} = 'spherical' - args.Kf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 15*ones(6,1) + 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) args.Cf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1) - args.Kt_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 20*ones(6,1) + args.Kt_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 236*ones(6,1) args.Ct_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1) - args.Kz_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 60e6*ones(6,1) - args.Cz_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e2*ones(6,1) - args.Kf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 15*ones(6,1) + args.Kf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 33*ones(6,1) args.Cf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1) - args.Kt_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 20*ones(6,1) + args.Kt_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 236*ones(6,1) args.Ct_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1) - args.Kz_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 60e6*ones(6,1) - args.Cz_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e2*ones(6,1) + 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) % initializeCylindricalPlatforms args.Fpm (1,1) double {mustBeNumeric, mustBePositive} = 1 args.Fph (1,1) double {mustBeNumeric, mustBePositive} = 10e-3 @@ -1355,9 +1359,8 @@ The =mirror= structure is saved. 'k1', args.k1*ones(6,1), ... 'c1', args.c1*ones(6,1), ... 'ka', args.ka*ones(6,1), ... - 'ca', args.ca*ones(6,1), ... 'ke', args.ke*ones(6,1), ... - 'ce', args.ce*ones(6,1)); + 'F_gain', args.F_gain*ones(6,1)); else error('args.actuator should be piezo, lorentz or amplified'); end @@ -1367,18 +1370,22 @@ The =mirror= structure is saved. stewart = initializeJointDynamics(stewart, ... 'type_F', args.type_F, ... 'type_M', args.type_M, ... - 'Kf_M' , args.Kf_M, ... - 'Cf_M' , args.Cf_M, ... - 'Kt_M' , args.Kt_M, ... - 'Ct_M' , args.Ct_M, ... - 'Kz_M' , args.Kz_M, ... - 'Cz_M' , args.Cz_M, ... - 'Kf_F' , args.Kf_F, ... - 'Cf_F' , args.Cf_F, ... - 'Kt_F' , args.Kt_F, ... - 'Ct_F' , args.Ct_F, ... - 'Kz_F' , args.Kz_F, ... - 'Cz_F' , args.Cz_F); + '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); #+end_src #+begin_src matlab diff --git a/org/stewart_platform.org b/org/stewart_platform.org index a0cce0f..5c5a9e7 100644 --- a/org/stewart_platform.org +++ b/org/stewart_platform.org @@ -198,7 +198,7 @@ This Matlab function is accessible [[file:../src/generateGeneralConfiguration.m] Joints are positions on a circle centered with the Z axis of {F} and {M} and at a chosen distance from {F} and {M}. The radius of the circles can be chosen as well as the angles where the joints are located (see Figure [[fig:joint_position_general]]). -#+begin_src latex :file stewart_bottom_plate.pdf +#+begin_src latex :file stewart_bottom_plate.pdf :tangle no \begin{tikzpicture} % Internal and external limit \draw[fill=white!80!black] (0, 0) circle [radius=3]; @@ -742,7 +742,7 @@ A simplistic model of such amplified actuator is shown in Figure [[fig:actuator_ - $v_{m}$ represents the absolute velocity of the top part of the actuator - $d_{m}$ represents the total relative displacement of the actuator -#+begin_src latex :file actuator_model_simple.pdf +#+begin_src latex :file actuator_model_simple.pdf :tangle no \begin{tikzpicture} \draw (-1, 0) -- (1, 0); @@ -801,14 +801,13 @@ A simplistic model of such amplified actuator is shown in Figure [[fig:actuator_ args.type char {mustBeMember(args.type,{'classical', 'amplified'})} = 'classical' args.K (6,1) double {mustBeNumeric, mustBeNonnegative} = 20e6*ones(6,1) args.C (6,1) double {mustBeNumeric, mustBeNonnegative} = 2e1*ones(6,1) - args.k1 (6,1) double {mustBeNumeric} = 1e6 - args.ke (6,1) double {mustBeNumeric} = 5e6 - args.ka (6,1) double {mustBeNumeric} = 60e6 - args.c1 (6,1) double {mustBeNumeric} = 10 - args.ce (6,1) double {mustBeNumeric} = 10 - args.ca (6,1) double {mustBeNumeric} = 10 - args.me (6,1) double {mustBeNumeric} = 0.05 - args.ma (6,1) double {mustBeNumeric} = 0.05 + args.k1 (6,1) double {mustBeNumeric} = 1e6*ones(6,1) + args.ke (6,1) double {mustBeNumeric} = 5e6*ones(6,1) + args.ka (6,1) double {mustBeNumeric} = 60e6*ones(6,1) + args.c1 (6,1) double {mustBeNumeric} = 10*ones(6,1) + args.F_gain (6,1) double {mustBeNumeric} = 1*ones(6,1) + args.me (6,1) double {mustBeNumeric} = 0.01*ones(6,1) + args.ma (6,1) double {mustBeNumeric} = 0.01*ones(6,1) end #+end_src @@ -830,144 +829,14 @@ A simplistic model of such amplified actuator is shown in Figure [[fig:actuator_ stewart.actuators.c1 = args.c1; stewart.actuators.ka = args.ka; - stewart.actuators.ca = args.ca; - stewart.actuators.ke = args.ke; - stewart.actuators.ce = args.ce; + + stewart.actuators.F_gain = args.F_gain; stewart.actuators.ma = args.ma; stewart.actuators.me = args.me; #+end_src -* =initializeAmplifiedStrutDynamics=: Add Stiffness and Damping properties of each strut for an amplified piezoelectric actuator -:PROPERTIES: -:header-args:matlab+: :tangle ../src/initializeAmplifiedStrutDynamics.m -:header-args:matlab+: :comments none :mkdirp yes :eval no -:END: -<> - -This Matlab function is accessible [[file:../src/initializeAmplifiedStrutDynamics.m][here]]. - -** Documentation -:PROPERTIES: -:UNNUMBERED: t -:END: - -An amplified piezoelectric actuator is shown in Figure [[fig:cedrat_apa95ml]]. - -#+name: fig:cedrat_apa95ml -#+attr_html: :width 500px -#+caption: Example of an Amplified piezoelectric actuator with an integrated displacement sensor (Cedrat Technologies) -[[file:figs/amplified_piezo_with_displacement_sensor.jpg]] - -A simplistic model of such amplified actuator is shown in Figure [[fig:amplified_piezo_model]] where: -- $K_{r}$ represent the vertical stiffness when the piezoelectric stack is removed -- $K_{a}$ is the vertical stiffness contribution of the piezoelectric stack -- $F_{i}$ represents the part of the piezoelectric stack that is used as a force actuator -- $F_{m,i}$ represents the remaining part of the piezoelectric stack that is used as a force sensor -- $v_{m,i}$ represents the absolute velocity of the top part of the actuator -- $d_{m,i}$ represents the total relative displacement of the actuator - -#+begin_src latex :file iff_1dof.pdf - \begin{tikzpicture} - % Ground - \draw (-1.2, 0) -- (1, 0); - - % Mass - \draw (-1.2, 1.4) -- ++(2.2, 0); - \node[forcesensor={0.4}{0.4}] (fsensn) at (0, 1){}; - \draw[] (-0.4, 1) -- (0.4, 1); - \node[right] at (fsensn.east) {$F_{m}$}; - - % Spring, Damper, and Actuator - \draw[spring] (-0.4, 0) -- (-0.4, 1) node[midway, right=0.1]{$K_{a}$}; - \draw[actuator={0.4}{0.2}] (0.4, 0) -- (0.4, 1) node[midway, right=0.1]{$F$}; - - \draw[spring] (-1, 0) -- (-1, 1.4) node[midway, left=0.1]{$K_{r}$}; - - \draw[dashed] (1, 0) -- ++(0.4, 0); - - \draw[dashed] (1, 1.4) -- ++(0.4, 0); - - \draw[->] (0, 1.4)node[]{$\bullet$} -- ++(0, 0.5) node[right]{$v_{m}$}; - - \draw[<->] (1.4, 0) -- ++(0, 1.4) node[midway, right]{$d_{m}$}; - \end{tikzpicture} -#+end_src - -#+name: fig:amplified_piezo_model -#+caption: Model of an amplified actuator -#+RESULTS: -[[file:figs/iff_1dof.png]] - -** Function description -:PROPERTIES: -:UNNUMBERED: t -:END: -#+begin_src matlab - function [stewart] = initializeAmplifiedStrutDynamics(stewart, args) - % initializeAmplifiedStrutDynamics - Add Stiffness and Damping properties of each strut - % - % Syntax: [stewart] = initializeAmplifiedStrutDynamics(args) - % - % Inputs: - % - args - Structure with the following fields: - % - Ka [6x1] - Vertical stiffness contribution of the piezoelectric stack [N/m] - % - Ca [6x1] - Vertical damping contribution of the piezoelectric stack [N/(m/s)] - % - Kr [6x1] - Vertical (residual) stiffness when the piezoelectric stack is removed [N/m] - % - Cr [6x1] - Vertical (residual) damping when the piezoelectric stack is removed [N/(m/s)] - % - % Outputs: - % - stewart - updated Stewart structure with the added fields: - % - actuators.type = 2 - % - actuators.K [6x1] - Total Stiffness of each strut [N/m] - % - actuators.C [6x1] - Total Damping of each strut [N/(m/s)] - % - actuators.Ka [6x1] - Vertical stiffness contribution of the piezoelectric stack [N/m] - % - actuators.Ca [6x1] - Vertical damping contribution of the piezoelectric stack [N/(m/s)] - % - actuators.Kr [6x1] - Vertical stiffness when the piezoelectric stack is removed [N/m] - % - actuators.Cr [6x1] - Vertical damping when the piezoelectric stack is removed [N/(m/s)] -#+end_src - -** Optional Parameters -:PROPERTIES: -:UNNUMBERED: t -:END: -#+begin_src matlab - arguments - stewart - args.Kr (6,1) double {mustBeNumeric, mustBeNonnegative} = 5e6*ones(6,1) - args.Cr (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1) - args.Ka (6,1) double {mustBeNumeric, mustBeNonnegative} = 15e6*ones(6,1) - args.Ca (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1) - end -#+end_src - -** Compute the total stiffness and damping -:PROPERTIES: -:UNNUMBERED: t -:END: -#+begin_src matlab - K = args.Ka + args.Kr; - C = args.Ca + args.Cr; -#+end_src - -** Populate the =stewart= structure -:PROPERTIES: -:UNNUMBERED: t -:END: -#+begin_src matlab - stewart.actuators.type = 2; - - stewart.actuators.Ka = args.Ka; - stewart.actuators.Ca = args.Ca; - - stewart.actuators.Kr = args.Kr; - stewart.actuators.Cr = args.Cr; - - stewart.actuators.K = K; - stewart.actuators.C = K; -#+end_src - * =initializeJointDynamics=: Add Stiffness and Damping properties for spherical joints :PROPERTIES: :header-args:matlab+: :tangle ../src/initializeJointDynamics.m @@ -995,14 +864,10 @@ This Matlab function is accessible [[file:../src/initializeJointDynamics.m][here % - Kt_M [6x1] - Torsion (Rz) Stiffness for each top joints [(N.m)/rad] % - Cf_M [6x1] - Bending (Rx, Ry) Damping of each top joint [(N.m)/(rad/s)] % - Ct_M [6x1] - Torsion (Rz) Damping of each top joint [(N.m)/(rad/s)] - % - Kz_M [6x1] - Translation (Tz) Stiffness for each top joints [N/m] - % - Cz_M [6x1] - Translation (Tz) Damping of each top joint [N/m] % - Kf_F [6x1] - Bending (Rx, Ry) Stiffness for each bottom joints [(N.m)/rad] % - Kt_F [6x1] - Torsion (Rz) Stiffness for each bottom joints [(N.m)/rad] % - Cf_F [6x1] - Bending (Rx, Ry) Damping of each bottom joint [(N.m)/(rad/s)] % - Cf_F [6x1] - Torsion (Rz) Damping of each bottom joint [(N.m)/(rad/s)] - % - Kz_F [6x1] - Translation (Tz) Stiffness for each bottom joints [N/m] - % - Cz_F [6x1] - Translation (Tz) Damping of each bottom joint [N/m] % % Outputs: % - stewart - updated Stewart structure with the added fields: @@ -1023,20 +888,34 @@ This Matlab function is accessible [[file:../src/initializeJointDynamics.m][here #+begin_src matlab arguments stewart - args.type_F char {mustBeMember(args.type_F,{'universal', 'spherical', 'universal_p', 'spherical_p', 'universal_3dof'})} = 'universal' - args.type_M char {mustBeMember(args.type_M,{'universal', 'spherical', 'universal_p', 'spherical_p', 'spherical_3dof'})} = 'spherical' - args.Kf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 15*ones(6,1) + 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.Kf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 33*ones(6,1) args.Cf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1) - args.Kt_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 20*ones(6,1) + args.Kt_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 236*ones(6,1) args.Ct_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1) - args.Kz_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 60e6*ones(6,1) - args.Cz_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e2*ones(6,1) - args.Kf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 15*ones(6,1) + args.Kf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 33*ones(6,1) args.Cf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1) - args.Kt_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 20*ones(6,1) + args.Kt_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 236*ones(6,1) args.Ct_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1) - args.Kz_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 60e6*ones(6,1) - args.Cz_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e2*ones(6,1) + 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) + 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.K_M double {mustBeNumeric} = zeros(6,6) + args.M_M double {mustBeNumeric} = zeros(6,6) + args.n_xyz_M double {mustBeNumeric} = zeros(2,3) + args.xi_M double {mustBeNumeric} = 0.1 + args.step_file_M char {} = '' + args.K_F double {mustBeNumeric} = zeros(6,6) + args.M_F double {mustBeNumeric} = zeros(6,6) + args.n_xyz_F double {mustBeNumeric} = zeros(2,3) + args.xi_F double {mustBeNumeric} = 0.1 + args.step_file_F char {} = '' end #+end_src @@ -1051,11 +930,15 @@ This Matlab function is accessible [[file:../src/initializeJointDynamics.m][here case 'spherical' stewart.joints_F.type = 2; case 'universal_p' - stewart.joints_F.type = 1; + stewart.joints_F.type = 3; case 'spherical_p' - stewart.joints_F.type = 2; - case 'universal_3dof' + stewart.joints_F.type = 4; + case 'flexible' stewart.joints_F.type = 5; + case 'universal_3dof' + stewart.joints_F.type = 6; + case 'spherical_3dof' + stewart.joints_F.type = 7; end switch args.type_M @@ -1064,56 +947,38 @@ This Matlab function is accessible [[file:../src/initializeJointDynamics.m][here case 'spherical' stewart.joints_M.type = 2; case 'universal_p' - stewart.joints_M.type = 1; + stewart.joints_M.type = 3; case 'spherical_p' - stewart.joints_M.type = 2; - case 'spherical_3dof' + stewart.joints_M.type = 4; + case 'flexible' + stewart.joints_M.type = 5; + case 'universal_3dof' stewart.joints_M.type = 6; + case 'spherical_3dof' + stewart.joints_M.type = 7; end #+end_src -** Initialize Stiffness -#+begin_src matlab - stewart.joints_M.Kx = zeros(6,1); - stewart.joints_M.Ky = zeros(6,1); - stewart.joints_M.Kz = zeros(6,1); - stewart.joints_F.Kx = zeros(6,1); - stewart.joints_F.Ky = zeros(6,1); - stewart.joints_F.Kz = zeros(6,1); - - stewart.joints_M.Kf = zeros(6,1); - stewart.joints_M.Kt = zeros(6,1); - stewart.joints_F.Kf = zeros(6,1); - stewart.joints_F.Kt = zeros(6,1); - - stewart.joints_M.Cx = zeros(6,1); - stewart.joints_M.Cy = zeros(6,1); - stewart.joints_M.Cz = zeros(6,1); - stewart.joints_F.Cx = zeros(6,1); - stewart.joints_F.Cy = zeros(6,1); - stewart.joints_F.Cz = zeros(6,1); - - stewart.joints_M.Cf = zeros(6,1); - stewart.joints_M.Ct = zeros(6,1); - stewart.joints_F.Cf = zeros(6,1); - stewart.joints_F.Ct = zeros(6,1); -#+end_src - ** Add Stiffness and Damping in Translation of each strut :PROPERTIES: :UNNUMBERED: t :END: -Translation Stiffness +Axial and Radial (shear) Stiffness #+begin_src matlab - if ~strcmp(args.type_M, 'universal_p') || ~strcmp(args.type_M, 'spherical_p') - stewart.joints_M.Kz = args.Kz_M; - stewart.joints_M.Cz = args.Cz_M; - end + stewart.joints_M.Ka = args.Ka_M; + stewart.joints_M.Kr = args.Kr_M; - if ~strcmp(args.type_F, 'universal_p') || ~strcmp(args.type_F, 'spherical_p') - stewart.joints_F.Kz = args.Kz_F; - stewart.joints_F.Cz = args.Cz_F; - end + stewart.joints_F.Ka = args.Ka_F; + stewart.joints_F.Kr = args.Kr_F; +#+end_src + +Translation Damping +#+begin_src matlab + stewart.joints_M.Ca = args.Ca_M; + stewart.joints_M.Cr = args.Cr_M; + + stewart.joints_F.Ca = args.Ca_F; + stewart.joints_F.Cr = args.Cr_F; #+end_src ** Add Stiffness and Damping in Rotation of each strut @@ -1122,21 +987,40 @@ Translation Stiffness :END: Rotational Stiffness #+begin_src matlab - if ~strcmp(args.type_M, 'universal_p') || ~strcmp(args.type_M, 'spherical_p') - stewart.joints_M.Kf = args.Kf_M; - stewart.joints_M.Cf = args.Cf_M; + stewart.joints_M.Kf = args.Kf_M; + stewart.joints_M.Kt = args.Kt_M; - stewart.joints_M.Kt = args.Kt_M; - stewart.joints_M.Ct = args.Ct_M; - end + stewart.joints_F.Kf = args.Kf_F; + stewart.joints_F.Kt = args.Kt_F; +#+end_src - if ~strcmp(args.type_F, 'universal_p') || ~strcmp(args.type_F, 'spherical_p') - stewart.joints_F.Kf = args.Kf_F; - stewart.joints_F.Cf = args.Cf_F; +Rotational Damping +#+begin_src matlab + stewart.joints_M.Cf = args.Cf_M; + stewart.joints_M.Ct = args.Ct_M; - stewart.joints_F.Kt = args.Kt_F; - stewart.joints_F.Ct = args.Ct_F; - end + stewart.joints_F.Cf = args.Cf_F; + stewart.joints_F.Ct = args.Ct_F; +#+end_src + +** Stiffness and Mass matrices for flexible joint +:PROPERTIES: +:UNNUMBERED: t +:END: + +#+begin_src matlab + stewart.joints_F.M = args.M_F; + stewart.joints_F.K = args.K_F; + stewart.joints_F.n_xyz = args.n_xyz_F; + stewart.joints_F.xi = args.xi_F; + stewart.joints_F.xi = args.xi_F; + stewart.joints_F.step_file = args.step_file_F; + + stewart.joints_M.M = args.M_M; + stewart.joints_M.K = args.K_M; + stewart.joints_M.n_xyz = args.n_xyz_M; + stewart.joints_M.xi = args.xi_M; + stewart.joints_M.step_file = args.step_file_M; #+end_src * =initializeInertialSensor=: Initialize the inertial sensor in each strut diff --git a/src/describeStewartPlatform.m b/src/describeStewartPlatform.m index f7e5a7b..256fc60 100644 --- a/src/describeStewartPlatform.m +++ b/src/describeStewartPlatform.m @@ -46,6 +46,10 @@ switch stewart.joints_F.type fprintf('- The joints on the fixed based are universal joints\n') case 2 fprintf('- The joints on the fixed based are spherical joints\n') + case 3 + fprintf('- The joints on the fixed based are perfect universal joints\n') + case 4 + fprintf('- The joints on the fixed based are perfect spherical joints\n') end switch stewart.joints_M.type @@ -53,6 +57,10 @@ switch stewart.joints_M.type fprintf('- The joints on the mobile based are universal joints\n') case 2 fprintf('- The joints on the mobile based are spherical joints\n') + case 3 + fprintf('- The joints on the mobile based are perfect universal joints\n') + case 4 + fprintf('- The joints on the mobile based are perfect spherical joints\n') end fprintf('- The position of the joints on the fixed based with respect to {F} are (in [mm]):\n') diff --git a/src/initializeGranite.m b/src/initializeGranite.m index b06b5db..67c1e75 100644 --- a/src/initializeGranite.m +++ b/src/initializeGranite.m @@ -9,6 +9,7 @@ arguments 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] + args.sample_pos (1,1) double {mustBeNumeric} = 0.8 % Height of the measurment point [m] end granite = struct(); @@ -29,7 +30,7 @@ end granite.density = args.density; % [kg/m3] granite.STEP = './STEPS/granite/granite.STEP'; -granite.sample_pos = 0.8; % [m] +granite.sample_pos = args.sample_pos; % [m] granite.K = args.K; % [N/m] granite.C = args.C; % [N/(m/s)] diff --git a/src/initializeJointDynamics.m b/src/initializeJointDynamics.m index 1392281..cc78b3a 100644 --- a/src/initializeJointDynamics.m +++ b/src/initializeJointDynamics.m @@ -11,14 +11,10 @@ function [stewart] = initializeJointDynamics(stewart, args) % - Kt_M [6x1] - Torsion (Rz) Stiffness for each top joints [(N.m)/rad] % - Cf_M [6x1] - Bending (Rx, Ry) Damping of each top joint [(N.m)/(rad/s)] % - Ct_M [6x1] - Torsion (Rz) Damping of each top joint [(N.m)/(rad/s)] -% - Kz_M [6x1] - Translation (Tz) Stiffness for each top joints [N/m] -% - Cz_M [6x1] - Translation (Tz) Damping of each top joint [N/m] % - Kf_F [6x1] - Bending (Rx, Ry) Stiffness for each bottom joints [(N.m)/rad] % - Kt_F [6x1] - Torsion (Rz) Stiffness for each bottom joints [(N.m)/rad] % - Cf_F [6x1] - Bending (Rx, Ry) Damping of each bottom joint [(N.m)/(rad/s)] % - Cf_F [6x1] - Torsion (Rz) Damping of each bottom joint [(N.m)/(rad/s)] -% - Kz_F [6x1] - Translation (Tz) Stiffness for each bottom joints [N/m] -% - Cz_F [6x1] - Translation (Tz) Damping of each bottom joint [N/m] % % Outputs: % - stewart - updated Stewart structure with the added fields: @@ -33,20 +29,34 @@ function [stewart] = initializeJointDynamics(stewart, args) arguments stewart - args.type_F char {mustBeMember(args.type_F,{'universal', 'spherical', 'universal_p', 'spherical_p', 'universal_3dof'})} = 'universal' - args.type_M char {mustBeMember(args.type_M,{'universal', 'spherical', 'universal_p', 'spherical_p', 'spherical_3dof'})} = 'spherical' - args.Kf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 15*ones(6,1) + 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.Kf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 33*ones(6,1) args.Cf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1) - args.Kt_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 20*ones(6,1) + args.Kt_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 236*ones(6,1) args.Ct_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1) - args.Kz_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 60e6*ones(6,1) - args.Cz_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e2*ones(6,1) - args.Kf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 15*ones(6,1) + args.Kf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 33*ones(6,1) args.Cf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1) - args.Kt_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 20*ones(6,1) + args.Kt_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 236*ones(6,1) args.Ct_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1) - args.Kz_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 60e6*ones(6,1) - args.Cz_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e2*ones(6,1) + 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) + 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.K_M double {mustBeNumeric} = zeros(6,6) + args.M_M double {mustBeNumeric} = zeros(6,6) + args.n_xyz_M double {mustBeNumeric} = zeros(2,3) + args.xi_M double {mustBeNumeric} = 0.1 + args.step_file_M char {} = '' + args.K_F double {mustBeNumeric} = zeros(6,6) + args.M_F double {mustBeNumeric} = zeros(6,6) + args.n_xyz_F double {mustBeNumeric} = zeros(2,3) + args.xi_F double {mustBeNumeric} = 0.1 + args.step_file_F char {} = '' end switch args.type_F @@ -55,11 +65,15 @@ switch args.type_F case 'spherical' stewart.joints_F.type = 2; case 'universal_p' - stewart.joints_F.type = 1; + stewart.joints_F.type = 3; case 'spherical_p' - stewart.joints_F.type = 2; - case 'universal_3dof' + stewart.joints_F.type = 4; + case 'flexible' stewart.joints_F.type = 5; + case 'universal_3dof' + stewart.joints_F.type = 6; + case 'spherical_3dof' + stewart.joints_F.type = 7; end switch args.type_M @@ -68,59 +82,50 @@ switch args.type_M case 'spherical' stewart.joints_M.type = 2; case 'universal_p' - stewart.joints_M.type = 1; + stewart.joints_M.type = 3; case 'spherical_p' - stewart.joints_M.type = 2; - case 'spherical_3dof' + stewart.joints_M.type = 4; + case 'flexible' + stewart.joints_M.type = 5; + case 'universal_3dof' stewart.joints_M.type = 6; + case 'spherical_3dof' + stewart.joints_M.type = 7; end -stewart.joints_M.Kx = zeros(6,1); -stewart.joints_M.Ky = zeros(6,1); -stewart.joints_M.Kz = zeros(6,1); -stewart.joints_F.Kx = zeros(6,1); -stewart.joints_F.Ky = zeros(6,1); -stewart.joints_F.Kz = zeros(6,1); +stewart.joints_M.Ka = args.Ka_M; +stewart.joints_M.Kr = args.Kr_M; -stewart.joints_M.Kf = zeros(6,1); -stewart.joints_M.Kt = zeros(6,1); -stewart.joints_F.Kf = zeros(6,1); -stewart.joints_F.Kt = zeros(6,1); +stewart.joints_F.Ka = args.Ka_F; +stewart.joints_F.Kr = args.Kr_F; -stewart.joints_M.Cx = zeros(6,1); -stewart.joints_M.Cy = zeros(6,1); -stewart.joints_M.Cz = zeros(6,1); -stewart.joints_F.Cx = zeros(6,1); -stewart.joints_F.Cy = zeros(6,1); -stewart.joints_F.Cz = zeros(6,1); +stewart.joints_M.Ca = args.Ca_M; +stewart.joints_M.Cr = args.Cr_M; -stewart.joints_M.Cf = zeros(6,1); -stewart.joints_M.Ct = zeros(6,1); -stewart.joints_F.Cf = zeros(6,1); -stewart.joints_F.Ct = zeros(6,1); +stewart.joints_F.Ca = args.Ca_F; +stewart.joints_F.Cr = args.Cr_F; -if ~strcmp(args.type_M, 'universal_p') || ~strcmp(args.type_M, 'spherical_p') - stewart.joints_M.Kz = args.Kz_M; - stewart.joints_M.Cz = args.Cz_M; -end +stewart.joints_M.Kf = args.Kf_M; +stewart.joints_M.Kt = args.Kt_M; -if ~strcmp(args.type_F, 'universal_p') || ~strcmp(args.type_F, 'spherical_p') - stewart.joints_F.Kz = args.Kz_F; - stewart.joints_F.Cz = args.Cz_F; -end +stewart.joints_F.Kf = args.Kf_F; +stewart.joints_F.Kt = args.Kt_F; -if ~strcmp(args.type_M, 'universal_p') || ~strcmp(args.type_M, 'spherical_p') - stewart.joints_M.Kf = args.Kf_M; - stewart.joints_M.Cf = args.Cf_M; +stewart.joints_M.Cf = args.Cf_M; +stewart.joints_M.Ct = args.Ct_M; - stewart.joints_M.Kt = args.Kt_M; - stewart.joints_M.Ct = args.Ct_M; -end +stewart.joints_F.Cf = args.Cf_F; +stewart.joints_F.Ct = args.Ct_F; -if ~strcmp(args.type_F, 'universal_p') || ~strcmp(args.type_F, 'spherical_p') - stewart.joints_F.Kf = args.Kf_F; - stewart.joints_F.Cf = args.Cf_F; +stewart.joints_F.M = args.M_F; +stewart.joints_F.K = args.K_F; +stewart.joints_F.n_xyz = args.n_xyz_F; +stewart.joints_F.xi = args.xi_F; +stewart.joints_F.xi = args.xi_F; +stewart.joints_F.step_file = args.step_file_F; - stewart.joints_F.Kt = args.Kt_F; - stewart.joints_F.Ct = args.Ct_F; -end +stewart.joints_M.M = args.M_M; +stewart.joints_M.K = args.K_M; +stewart.joints_M.n_xyz = args.n_xyz_M; +stewart.joints_M.xi = args.xi_M; +stewart.joints_M.step_file = args.step_file_M; diff --git a/src/initializeMirror.m b/src/initializeMirror.m index 0b0a671..ca98db1 100644 --- a/src/initializeMirror.m +++ b/src/initializeMirror.m @@ -32,7 +32,7 @@ mirror.Deq = zeros(6,1); mirror.h = 0.05; % Height of the mirror [m] -mirror.thickness = 0.025; % Thickness of the plate supporting the sample [m] +mirror.thickness = 0.02; % Thickness of the plate supporting the sample [m] mirror.hole_rad = 0.125; % radius of the hole in the mirror [m] @@ -41,11 +41,11 @@ mirror.support_rad = 0.1; % radius of the support plate [m] % point of interest offset in z (above the top surfave) [m] switch args.type case 'none' - mirror.jacobian = 0.20; + mirror.jacobian = 0.205; case 'rigid' - mirror.jacobian = 0.20 - mirror.h; + mirror.jacobian = 0.205 - mirror.h; case 'flexible' - mirror.jacobian = 0.20 - mirror.h; + mirror.jacobian = 0.205 - mirror.h; end mirror.rad = 0.180; % radius of the mirror (at the bottom surface) [m] diff --git a/src/initializeNanoHexapod.m b/src/initializeNanoHexapod.m index edfbf32..4a97fe4 100644 --- a/src/initializeNanoHexapod.m +++ b/src/initializeNanoHexapod.m @@ -3,8 +3,8 @@ function [nano_hexapod] = initializeNanoHexapod(args) arguments args.type char {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'init'})} = 'flexible' % initializeFramesPositions - args.H (1,1) double {mustBeNumeric, mustBePositive} = 90e-3 - args.MO_B (1,1) double {mustBeNumeric} = 175e-3 + args.H (1,1) double {mustBeNumeric, mustBePositive} = 95e-3 + args.MO_B (1,1) double {mustBeNumeric} = 170e-3 % generateGeneralConfiguration args.FH (1,1) double {mustBeNumeric, mustBePositive} = 15e-3 args.FR (1,1) double {mustBeNumeric, mustBePositive} = 100e-3 @@ -18,25 +18,28 @@ arguments args.ke (1,1) double {mustBeNumeric} = 5e6 args.ka (1,1) double {mustBeNumeric} = 60e6 args.c1 (1,1) double {mustBeNumeric} = 10 - args.ce (1,1) double {mustBeNumeric} = 10 - args.ca (1,1) double {mustBeNumeric} = 10 + args.F_gain (1,1) double {mustBeNumeric} = 1 args.k (1,1) double {mustBeNumeric} = -1 args.c (1,1) double {mustBeNumeric} = -1 % initializeJointDynamics - args.type_F char {mustBeMember(args.type_F,{'universal', 'spherical', 'universal_p', 'spherical_p', 'universal_3dof'})} = 'universal' - args.type_M char {mustBeMember(args.type_M,{'universal', 'spherical', 'universal_p', 'spherical_p', 'spherical_3dof'})} = 'spherical' - args.Kf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 15*ones(6,1) + 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) args.Cf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1) - args.Kt_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 20*ones(6,1) + args.Kt_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 236*ones(6,1) args.Ct_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1) - args.Kz_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 60e6*ones(6,1) - args.Cz_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e2*ones(6,1) - args.Kf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 15*ones(6,1) + args.Kf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 33*ones(6,1) args.Cf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1) - args.Kt_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 20*ones(6,1) + args.Kt_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 236*ones(6,1) args.Ct_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1) - args.Kz_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 60e6*ones(6,1) - args.Cz_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e2*ones(6,1) + 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) % initializeCylindricalPlatforms args.Fpm (1,1) double {mustBeNumeric, mustBePositive} = 1 args.Fph (1,1) double {mustBeNumeric, mustBePositive} = 10e-3 @@ -81,9 +84,8 @@ elseif strcmp(args.actuator, 'amplified') 'k1', args.k1*ones(6,1), ... 'c1', args.c1*ones(6,1), ... 'ka', args.ka*ones(6,1), ... - 'ca', args.ca*ones(6,1), ... 'ke', args.ke*ones(6,1), ... - 'ce', args.ce*ones(6,1)); + 'F_gain', args.F_gain*ones(6,1)); else error('args.actuator should be piezo, lorentz or amplified'); end @@ -91,18 +93,22 @@ end stewart = initializeJointDynamics(stewart, ... 'type_F', args.type_F, ... 'type_M', args.type_M, ... - 'Kf_M' , args.Kf_M, ... - 'Cf_M' , args.Cf_M, ... - 'Kt_M' , args.Kt_M, ... - 'Ct_M' , args.Ct_M, ... - 'Kz_M' , args.Kz_M, ... - 'Cz_M' , args.Cz_M, ... - 'Kf_F' , args.Kf_F, ... - 'Cf_F' , args.Cf_F, ... - 'Kt_F' , args.Kt_F, ... - 'Ct_F' , args.Ct_F, ... - 'Kz_F' , args.Kz_F, ... - 'Cz_F' , args.Cz_F); + '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); stewart = initializeCylindricalPlatforms(stewart, 'Fpm', args.Fpm, 'Fph', args.Fph, 'Fpr', args.Fpr, 'Mpm', args.Mpm, 'Mph', args.Mph, 'Mpr', args.Mpr); diff --git a/src/initializeStrutDynamics.m b/src/initializeStrutDynamics.m index 0b70a35..69dc518 100644 --- a/src/initializeStrutDynamics.m +++ b/src/initializeStrutDynamics.m @@ -19,14 +19,13 @@ arguments args.type char {mustBeMember(args.type,{'classical', 'amplified'})} = 'classical' args.K (6,1) double {mustBeNumeric, mustBeNonnegative} = 20e6*ones(6,1) args.C (6,1) double {mustBeNumeric, mustBeNonnegative} = 2e1*ones(6,1) - args.k1 (6,1) double {mustBeNumeric} = 1e6 - args.ke (6,1) double {mustBeNumeric} = 5e6 - args.ka (6,1) double {mustBeNumeric} = 60e6 - args.c1 (6,1) double {mustBeNumeric} = 10 - args.ce (6,1) double {mustBeNumeric} = 10 - args.ca (6,1) double {mustBeNumeric} = 10 - args.me (6,1) double {mustBeNumeric} = 0.05 - args.ma (6,1) double {mustBeNumeric} = 0.05 + args.k1 (6,1) double {mustBeNumeric} = 1e6*ones(6,1) + args.ke (6,1) double {mustBeNumeric} = 5e6*ones(6,1) + args.ka (6,1) double {mustBeNumeric} = 60e6*ones(6,1) + args.c1 (6,1) double {mustBeNumeric} = 10*ones(6,1) + args.F_gain (6,1) double {mustBeNumeric} = 1*ones(6,1) + args.me (6,1) double {mustBeNumeric} = 0.01*ones(6,1) + args.ma (6,1) double {mustBeNumeric} = 0.01*ones(6,1) end if strcmp(args.type, 'classical') @@ -42,10 +41,9 @@ stewart.actuators.k1 = args.k1; stewart.actuators.c1 = args.c1; stewart.actuators.ka = args.ka; -stewart.actuators.ca = args.ca; - stewart.actuators.ke = args.ke; -stewart.actuators.ce = args.ce; + +stewart.actuators.F_gain = args.F_gain; stewart.actuators.ma = args.ma; stewart.actuators.me = args.me;