From a581bc9dbd9773c0354435eaaa3e73bc1a740c14 Mon Sep 17 00:00:00 2001
From: Thomas Dehaeze
+The overall goal is to design a nano-hexapod that will allow the highest possible control bandwidth.
+
+In this section, we look at the effect of the spindle rotation speed on the plant dynamics.
+
+The rotation speed will have an effect due to the Coriolis effect.
+
+We initialize all the stages with the default parameters.
+
+We use a sample mass of 10kg.
+
+We don’t include disturbances in this model as it adds complexity to the simulations and does not alter the obtained dynamics.
+We however include gravity.
+
+We identify the dynamics for the following spindle rotation speeds
+And for the following nano-hexapod actuator stiffness
+We plot the change of dynamics due to the change of the spindle rotation speed (from 0rpm to 60rpm):
+
+ Figure 1: Change of dynamics from actuator \(\tau\) to actuator force sensor \(\tau_m\) for a spindle rotation speed from 0rpm to 60rpm (png, pdf)
+ Figure 2: Change of dynamics from actuator force \(\tau\) to actuator displacement \(d\mathcal{L}\) for a spindle rotation speed from 0rpm to 60rpm (png, pdf)
+The leg stiffness should be at higher than \(k_i = 10^4\ [N/m]\) such that the main resonance frequency does not shift too much when rotating.
+For the coupling, it is more difficult to conclude about the minimum required leg stiffness.
+
+Note that we can use very soft nano-hexapod if we limit the spindle rotating speed.
+
+We initialize all the stages with the default parameters.
+
+We put nothing on top of the micro-hexapod.
+
+And we identify the dynamics from forces/torques applied on the micro-hexapod top platform to the motion of the micro-hexapod top platform at the same point.
+The diagonal element of the identified Micro-Station compliance matrix are shown in Figure 5.
+
+We now identify the dynamics when the micro-station is rigid.
+This is equivalent of identifying the dynamics of the nano-hexapod when fixed to a rigid ground.
+We also choose the sample to be rigid and to have a mass of 10kg.
+
+As before, we identify the dynamics for the following actuator stiffnesses:
+
+We now initialize all the micro-station stages to be flexible.
+And we identify the dynamics of the nano-hexapod.
+
+We plot the change of dynamics due to the compliance of the Micro-Station.
+The solid curves are corresponding to the nano-hexapod without the micro-station, and the dashed curves with the micro-station:
+
+ Figure 6: Change of dynamics from actuator \(\tau\) to actuator force sensor \(\tau_m\) for a spindle rotation speed from 0rpm to 60rpm (png, pdf)
+ Figure 7: Change of dynamics from actuator force \(\tau\) to actuator displacement \(d\mathcal{L}\) for a spindle rotation speed from 0rpm to 60rpm (png, pdf)
+The dynamics of the nano-hexapod is not affected by the micro-station dynamics (compliance) when the stiffness of the legs is less than \(10^6\ [N/m]\).
+When the nano-hexapod is stiff (\(k>10^7\ [N/m]\)), the compliance of the micro-station appears in the primary plant.
+
+We initialize all the stages with the default parameters.
+We don’t include disturbances in this model as it adds complexity to the simulations and does not alter the obtained dynamics. :exports none
+
+We set the controller type to Open-Loop, and we do not need to log any signal.
+
+We make the following change of payload dynamics:
+
+We identify the dynamics for the following payload masses
+We then identify the dynamics for the following payload resonance frequencies
+We here compare the dynamics for the same payload mass, but different stiffness resulting in different resonance frequency of the payload:
+
+We can see two mass lines for the soft nano-hexapod (Figure 10):
+
+We here compare the dynamics for different payload mass with the same resonance frequency (100Hz):
+
+We can see here that for the soft nano-hexapod:
+
+We now plot the total change of dynamics due to change of the payload (Figure 14):
+
+
+
+We now consider the total change of nano-hexapod dynamics due to:
+
+The obtained dynamics are shown:
+
+And finally, in Figures 19 and 20 are shown an animation of the change of dynamics with the nano-hexapod’s stiffness.
+
+ Figure 15: Total variation of the dynamics from \(\mathcal{F}_x\) to \(\mathcal{X}_x\). Nano-hexapod leg’s stiffness is equal to \(k = 10^3\ [N/m]\) (png, pdf)
+ Figure 16: Total variation of the dynamics from \(\mathcal{F}_x\) to \(\mathcal{X}_x\). Nano-hexapod leg’s stiffness is equal to \(k = 10^5\ [N/m]\) (png, pdf)
+ Figure 17: Total variation of the dynamics from \(\mathcal{F}_x\) to \(\mathcal{X}_x\). Nano-hexapod leg’s stiffness is equal to \(k = 10^7\ [N/m]\) (png, pdf)
+ Figure 18: Total variation of the dynamics from \(\mathcal{F}_x\) to \(\mathcal{X}_x\). Nano-hexapod leg’s stiffness is equal to \(k = 10^9\ [N/m]\) (png, pdf)
+ Figure 19: Variability of the dynamics from \(\mathcal{F}_x\) to \(\mathcal{X}_x\) with varying nano-hexapod stiffness
+ Figure 20: Variability of the dynamics from \(\mathcal{F}_x\) to \(\mathcal{X}_x\) with varying nano-hexapod stiffness Created: 2020-04-01 mer. 17:19 Created: 2020-04-03 ven. 17:55Table of Contents
1 Spindle Rotation Speed
1.1 Initialization
+initializeGround();
+initializeGranite();
+initializeTy();
+initializeRy();
+initializeRz();
+initializeMicroHexapod();
+initializeAxisc();
+initializeMirror();
+
+initializeSample('mass', 10);
+
+initializeSimscapeConfiguration('gravity', true);
+initializeDisturbances('enable', false);
+initializeLoggingConfiguration('log', 'none');
+initializeController();
+
1.2 Identification when rotating at maximum speed
+Rz_rpm
:
+Rz_rpm = linspace(0, 60, 6);
+
+Ks
:
+Ks = logspace(3,9,7); % [N/m]
+
+1.3 Change of dynamics
+
+
+
+
+2 Micro-Station Compliance Effect
2.1 Identification of the micro-station compliance
+initializeGround();
+initializeGranite();
+initializeTy();
+initializeRy();
+initializeRz();
+initializeMicroHexapod('type', 'compliance');
+
initializeAxisc('type', 'none');
+initializeMirror('type', 'none');
+initializeNanoHexapod('type', 'none');
+initializeSample('type', 'none');
+
+2.2 Identification of the dynamics with a rigid micro-station
+initializeSample('type', 'rigid', 'mass', 10);
+
+Ks = logspace(3,9,7); % [N/m]
+
+2.3 Identification of the dynamics with a flexible micro-station
+2.4 Obtained Dynamics
+
+
+
+
+3 Payload “Impedance” Effect
3.1 Initialization
+initializeDisturbances('enable', false);
+
+initializeSimscapeConfiguration('gravity', true);
+initializeController();
+initializeLoggingConfiguration('log', 'none');
+initializeReferences();
+
+3.2 Identification of the dynamics while change the payload dynamics
+
+
+
+Ms
and nano-hexapod leg’s stiffnesses Ks
:
+Ms = [1, 20, 50]; % [Kg]
+Ks = logspace(3,9,7); % [N/m]
+
+Fs
:
+Fs = [50, 200, 500]; % [Hz]
+
+3.3 Change of dynamics for the primary controller
+3.3.1 Frequency variation
+
+
+
+
+
+
+
+
+
+
+
+3.3.2 Mass variation
+
+
+
+
+
+
+
+
+
+
+
+3.3.3 Total variation
+
+
+
+
+
+4 Total Change of dynamics
+
+
+
+Gk_wz_err
- Change of spindle rotation speedGf_err
and Gm_err
- Change of payload resonanceGmf_err
and Gmr_err
- Micro-Station compliance
+
+
+
-
-
-
-
-
-
function [] = initializeSimscapeConfiguration(args)@@ -472,9 +472,9 @@ These functions are defined below.
arguments
args.gravity logical {mustBeNumericOrLogical} = true
@@ -484,9 +484,9 @@ These functions are defined below.
conf_simscape = struct();@@ -494,9 +494,9 @@ These functions are defined below.
if args.gravity
conf_simscape.type = 1;
@@ -508,9 +508,9 @@ These functions are defined below.
save('./mat/conf_simscape.mat', 'conf_simscape');@@ -527,9 +527,9 @@ These functions are defined below.
function [] = initializeLoggingConfiguration(args)@@ -537,9 +537,9 @@ These functions are defined below.
arguments args.log char {mustBeMember(args.log,{'none', 'all', 'forces'})} = 'none' @@ -550,9 +550,9 @@ These functions are defined below.
conf_log = struct();@@ -560,9 +560,9 @@ These functions are defined below.
switch args.log case 'none' @@ -587,9 +587,9 @@ These functions are defined below.
save('./mat/conf_log.mat', 'conf_log');@@ -606,9 +606,9 @@ These functions are defined below.
The model of the Ground is composed of:
@@ -633,9 +633,9 @@ The model of the Ground is composed of:function [ground] = initializeGround(args)@@ -643,9 +643,9 @@ The model of the Ground is composed of:
arguments args.type char {mustBeMember(args.type,{'none', 'rigid'})} = 'rigid' @@ -656,9 +656,9 @@ The model of the Ground is composed of:
First, we initialize the granite
structure.
granite
structure.
switch args.type case 'none' @@ -708,9 +708,9 @@ ground.density = 2800; % [kg/m3]
The ground
structure is saved.
ground
structure is saved.
The Simscape model of the granite is composed of:
@@ -761,9 +761,9 @@ The outputsample_pos
corresponds to the impact point of the X-ray.
function [granite] = initializeGranite(args)@@ -771,9 +771,9 @@ The output
sample_pos
corresponds to the impact point of the X-ray.
arguments
args.type char {mustBeMember(args.type,{'rigid', 'flexible', 'none', 'modal-analysis', 'init'})} = 'flexible'
@@ -789,9 +789,9 @@ The output sample_pos
corresponds to the impact point of the X-ray.
First, we initialize the granite
structure.
granite
structure.
Properties of the Material and link to the geometry of the granite.
@@ -845,9 +845,9 @@ Z-offset for the initial position of the sample with respect to the granite topgranite.K = [4e9; 3e8; 8e8]; % [N/m] granite.C = [4.0e5; 1.1e5; 9.0e5]; % [N/(m/s)] @@ -856,9 +856,9 @@ granite.C = [4.0e5; 1.1e5; 9.0e5]; % [N/(m/s)]
if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init') load('mat/Foffset.mat', 'Fgm'); @@ -871,9 +871,9 @@ granite.C = [4.0e5; 1.1e5; 9.0e5]; % [N/(m/s)]
The granite
structure is saved.
granite
structure is saved.
The Simscape model of the Translation stage consist of:
@@ -925,9 +925,9 @@ It is used to impose the motion in the Y directionfunction [ty] = initializeTy(args)@@ -935,9 +935,9 @@ It is used to impose the motion in the Y direction
arguments args.type char {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init'})} = 'flexible' @@ -948,9 +948,9 @@ It is used to impose the motion in the Y direction
First, we initialize the ty
structure.
ty
structure.
Define the density of the materials as well as the geometry (STEP files).
@@ -1029,9 +1029,9 @@ ty.rotor.STEP = './STEPS/ty/Ty_Motor_Rotor.Sty.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)] @@ -1040,9 +1040,9 @@ ty.C = [8e4; 5e4; 8e4; 2e4; 3e4; 2e4]; % [N/(m/s), N*m
if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init') load('mat/Foffset.mat', 'Ftym'); @@ -1055,9 +1055,9 @@ ty.C = [8e4; 5e4; 8e4; 2e4; 3e4; 2e4]; % [N/(m/s), N*m
The ty
structure is saved.
ty
structure is saved.
The Simscape model of the Tilt stage is composed of:
@@ -1109,9 +1109,9 @@ The Ry motion is imposed by the input.function [ry] = initializeRy(args)@@ -1119,9 +1119,9 @@ The Ry motion is imposed by the input.
arguments args.type char {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init'})} = 'flexible' @@ -1133,9 +1133,9 @@ The Ry motion is imposed by the input.
First, we initialize the ry
structure.
ry
structure.
Properties of the Material and link to the geometry of the Tilt stage.
@@ -1208,9 +1208,9 @@ Z-Offset so that the center of rotation matches the sample center;ry.K = [3.8e8; 4e8; 3.8e8; 1.2e8; 6e4; 1.2e8]; ry.C = [1e5; 1e5; 1e5; 3e4; 1e3; 3e4]; @@ -1219,9 +1219,9 @@ ry.C = [1e5; 1e5; 1e5; 3e4; 1e3; 3e4];
if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init') load('mat/Foffset.mat', 'Fym'); @@ -1234,9 +1234,9 @@ ry.C = [1e5; 1e5; 1e5; 3e4; 1e3; 3e4];
The ry
structure is saved.
ry
structure is saved.
The Simscape model of the Spindle is composed of:
@@ -1284,9 +1284,9 @@ The Simscape model of the Spindle is composed of:function [rz] = initializeRz(args)@@ -1294,9 +1294,9 @@ The Simscape model of the Spindle is composed of:
arguments args.type char {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init'})} = 'flexible' @@ -1307,9 +1307,9 @@ The Simscape model of the Spindle is composed of:
First, we initialize the rz
structure.
rz
structure.
Properties of the Material and link to the geometry of the spindle.
@@ -1364,9 +1364,9 @@ rz.stator.STEP = './STEPS/rz/Spindle_Stator.STEP'<rz.K = [7e8; 7e8; 2e9; 1e7; 1e7; 1e7]; rz.C = [4e4; 4e4; 7e4; 1e4; 1e4; 1e4]; @@ -1375,9 +1375,9 @@ rz.C = [4e4; 4e4; 7e4; 1e4; 1e4; 1e4];
if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init') load('mat/Foffset.mat', 'Fzm'); @@ -1390,9 +1390,9 @@ rz.C = [4e4; 4e4; 7e4; 1e4; 1e4; 1e4];
The rz
structure is saved.
rz
structure is saved.
@@ -1431,9 +1431,9 @@ The rz
structure is saved.
function [micro_hexapod] = initializeMicroHexapod(args)@@ -1441,9 +1441,9 @@ The
rz
structure is saved.
arguments
args.type char {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init', 'compliance'})} = 'flexible'
@@ -1485,9 +1485,9 @@ The rz
structure is saved.
micro_hexapod = initializeFramesPositions('H', args.H, 'MO_B', args.MO_B); micro_hexapod = generateGeneralConfiguration(micro_hexapod, 'FH', args.FH, 'FR', args.FR, 'FTh', args.FTh, 'MH', args.MH, 'MR', args.MR, 'MTh', args.MTh); @@ -1517,9 +1517,9 @@ Equilibrium position of the each joint.
switch args.type case 'none' @@ -1540,9 +1540,9 @@ Equilibrium position of the each joint.
The micro_hexapod
structure is saved.
micro_hexapod
structure is saved.
The Simscape model of the Center of gravity compensator is composed of:
@@ -1589,9 +1589,9 @@ The Simscape model of the Center of gravity compensator is composed of:function [axisc] = initializeAxisc(args)@@ -1599,9 +1599,9 @@ The Simscape model of the Center of gravity compensator is composed of:
arguments args.type char {mustBeMember(args.type,{'none', 'rigid', 'flexible'})} = 'flexible' @@ -1611,9 +1611,9 @@ The Simscape model of the Center of gravity compensator is composed of:
First, we initialize the axisc
structure.
axisc
structure.
switch args.type
case 'none'
@@ -1641,9 +1641,9 @@ First, we initialize the axisc
structure.
Properties of the Material and link to the geometry files.
@@ -1668,9 +1668,9 @@ axisc.gear.STEP = './STEPS/axisc/axisc_gear.STE
The axisc
structure is saved.
axisc
structure is saved.
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
@@ -1714,9 +1714,9 @@ The output mirror_center
corresponds to the center of the Sphere an
function [] = initializeMirror(args)@@ -1724,9 +1724,9 @@ The output
mirror_center
corresponds to the center of the Sphere an
arguments
args.type char {mustBeMember(args.type,{'none', 'rigid'})} = 'rigid'
@@ -1738,9 +1738,9 @@ The output mirror_center
corresponds to the center of the Sphere an
First, we initialize the mirror
structure.
mirror
structure.
We define the geometrical values.
@@ -1845,9 +1845,9 @@ Finally, we close the shape.
The mirror
structure is saved.
mirror
structure is saved.
@@ -1886,9 +1886,9 @@ The mirror
structure is saved.
function [nano_hexapod] = initializeNanoHexapod(args)@@ -1896,9 +1896,9 @@ The
mirror
structure is saved.
arguments args.type char {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'init'})} = 'flexible' @@ -1914,6 +1914,8 @@ Themirror
structure is saved. 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'})} = 'piezo' + args.k (1,1) double {mustBeNumeric} = -1 + args.c (1,1) double {mustBeNumeric} = -1 % initializeCylindricalPlatforms args.Fpm (1,1) double {mustBeNumeric, mustBePositive} = 1 args.Fph (1,1) double {mustBeNumeric, mustBePositive} = 10e-3 @@ -1941,21 +1943,33 @@ Themirror
structure is saved.
nano_hexapod = initializeFramesPositions('H', args.H, 'MO_B', args.MO_B); nano_hexapod = generateGeneralConfiguration(nano_hexapod, 'FH', args.FH, 'FR', args.FR, 'FTh', args.FTh, 'MH', args.MH, 'MR', args.MR, 'MTh', args.MTh); nano_hexapod = computeJointsPose(nano_hexapod); -if strcmp(args.actuator, 'piezo') ++
if args.k > 0 && args.c > 0 + nano_hexapod = initializeStrutDynamics(nano_hexapod, 'Ki', args.k*ones(6,1), 'Ci', args.c*ones(6,1)); +elseif args.k > 0 + nano_hexapod = initializeStrutDynamics(nano_hexapod, 'Ki', args.k*ones(6,1), 'Ci', 1.5*sqrt(args.k)*ones(6,1)); +elseif strcmp(args.actuator, 'piezo') nano_hexapod = initializeStrutDynamics(nano_hexapod, 'Ki', 1e7*ones(6,1), 'Ci', 1e2*ones(6,1)); elseif strcmp(args.actuator, 'lorentz') nano_hexapod = initializeStrutDynamics(nano_hexapod, 'Ki', 1e4*ones(6,1), 'Ci', 1e2*ones(6,1)); else error('args.actuator should be piezo or lorentz'); end -nano_hexapod = initializeCylindricalPlatforms(nano_hexapod, 'Fpm', args.Fpm, 'Fph', args.Fph, 'Fpr', args.Fpr, 'Mpm', args.Mpm, 'Mph', args.Mph, 'Mpr', args.Mpr); ++
nano_hexapod = initializeCylindricalPlatforms(nano_hexapod, 'Fpm', args.Fpm, 'Fph', args.Fph, 'Fpr', args.Fpr, 'Mpm', args.Mpm, 'Mph', args.Mph, 'Mpr', args.Mpr); nano_hexapod = initializeCylindricalStruts(nano_hexapod, 'Fsm', args.Fsm, 'Fsh', args.Fsh, 'Fsr', args.Fsr, 'Msm', args.Msm, 'Msh', args.Msh, 'Msr', args.Msr); nano_hexapod = computeJacobian(nano_hexapod); [Li, dLi] = inverseKinematics(nano_hexapod, 'AP', args.AP, 'ARB', args.ARB); @@ -1980,9 +1994,9 @@ Equilibrium position of the each joint.
switch args.type case 'none' @@ -1999,9 +2013,9 @@ Equilibrium position of the each joint.
save('./mat/stages.mat', 'nano_hexapod', '-append');@@ -2018,9 +2032,9 @@ Equilibrium position of the each joint.
The Simscape model of the sample environment is composed of:
@@ -2048,9 +2062,9 @@ This could be the case for cable forces for instance.function [sample] = initializeSample(args)@@ -2058,9 +2072,9 @@ This could be the case for cable forces for instance.
arguments args.type char {mustBeMember(args.type,{'rigid', 'flexible', 'none', 'init'})} = 'flexible' @@ -2076,9 +2090,9 @@ This could be the case for cable forces for instance.
First, we initialize the sample
structure.
sample
structure.
We define the geometrical parameters of the sample as well as its mass and position.
@@ -2136,9 +2150,9 @@ sample.offset = args.offset; % [m]sample.K = zeros(6, 1); sample.C = zeros(6, 1); @@ -2165,9 +2179,9 @@ sample.C(4:6) = 0.1 *
if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init') load('mat/Foffset.mat', 'Fsm'); @@ -2180,9 +2194,9 @@ sample.C(4:6) = 0.1 *
The sample
structure is saved.
sample
structure is saved.
function [] = initializeController(args)@@ -2212,21 +2226,21 @@ The
sample
structure is saved.
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'})} = 'open-loop' + 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
First, we initialize the controller
structure.
controller
structure.
controller.type = 7;
case 'hac-iff'
controller.type = 8;
+ case 'stabilizing'
+ controller.type = 9;
end
The controller
structure is saved.
controller
structure is saved.
function [ref] = initializeReferences(args)@@ -2296,9 +2312,9 @@ The
controller
structure is saved.
arguments % Sampling Frequency [s] @@ -2318,7 +2334,7 @@ Thecontroller
structure is saved. % 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'})} = 'constant' + 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] @@ -2360,9 +2376,9 @@ H_lpf = 1/(1 + 2
%% Translation stage - Dy t = 0:Ts:Tmax; % Time Vector [s] @@ -2399,9 +2415,9 @@ Dy = struct('time', t,