nass-simscape/metrology/index.org

29 KiB

Metrology

Introduction   ignore

The global measurement and control schematic is shown in figure fig:control-schematic-nass.

/tdehaeze/nass-simscape/media/commit/4218b9bfea4a55c1d480997823016451b0c7727c/metrology/figs/control-schematic-nass.png
Global Control Schematic for the Station

In this document, we develop and verify that the two green blocs are working.

We suppose that we are able to measure perfectly the position of the sample with respect to the granite. This means that we do not care about the bloc "Compute Sample Position w.r.t. Granite" that makes the transformation from the interferometer measurements to the position of the sample. We suppose that we can directly measure perfectly the position of the sample with respect to the granite.

Also, all the stages can be perfectly positioned.

First, in section sec:measurement_principle, is explained how the measurement of the position of the sample with respect to the granite is performed (using Simscape blocs).

In section sec:compute_reference, we verify that the function developed to compute the wanted pose (translation and orientation) of the sample with respect to the granite can be determined from the wanted position of each stage (translation stage, tilt stage, spindle and micro-hexapod). This corresponds to the bloc "Compute Wanted Sample Position w.r.t. Granite" in figure fig:control-schematic-nass. To do so, we impose a perfect displacement and all the stage, we perfectly measure the position of the sample with respect to the granite, and we verify that this measured position corresponds to the computed wanted pose of the sample.

Then, in section sec:compute_pos_error, we introduce some positioning error in the micro-station's stages. The positioning error of the sample expressed with respect to the granite frame (the one measured) is expressed in a frame connected to the NASS top platform (corresponding to the green bloc "Compute Sample Position Error w.r.t. NASS" in figure fig:control-schematic-nass). Then, we move the NASS such that it compensate for the positioning error that are expressed in the frame of the NASS, and we verify that the positioning error of the sample is well compensated.

How do we measure the position of the sample with respect to the granite

<<sec:measurement_principle>> A transform sensor block gives the translation and orientation of the follower frame with respect to the base frame.

The base frame is fixed to the granite and located at the initial sample location that defines the zero position.

The follower frame is attached to the sample (or more precisely to the reflector).

The outputs of the transform sensor are:

  • the 3 translations x, y and z in meter
  • the rotation matrix $\bm{R}$ that permits to rotate the base frame into the follower frame.

We can then determine extract other orientation conventions such that Euler angles or screw axis.

Verify that the function to compute the reference pose is correct

<<sec:compute_reference>>

Introduction   ignore

The goal here is to perfectly move the station and verify that there is no mismatch between the metrology measurement and the computation of the reference pose.

Prepare the Simulation

We load the configuration.

  load('simscape/conf_simscape.mat');

We set a small StopTime.

  set_param(conf_simscape, 'StopTime', '0.5');

We initialize all the stages.

  initializeGround();
  initializeGranite();
  initializeTy();
  initializeRy();
  initializeRz();
  initializeMicroHexapod();
  initializeAxisc();
  initializeMirror();
  initializeNanoHexapod(struct('actuator', 'piezo'));
  initializeSample(struct('mass', 50));

We setup the reference path to be constant.

  opts = struct( ...
      'Ts',           1e-3, ...       % Sampling Frequency [s]
      'Dy_type',      'constant', ... % Either "constant" / "triangular" / "sinusoidal"
      'Dy_amplitude', 5e-3, ...          % Amplitude of the displacement [m]
      'Dy_period',    1, ...          % Period of the displacement [s]
      'Ry_type',      'constant', ... % Either "constant" / "triangular" / "sinusoidal"
      'Ry_amplitude', -1*pi/180, ...          % Amplitude [rad]
      'Ry_period',    10, ...         % Period of the displacement [s]
      'Rz_type',      'constant', ... % Either "constant" / "rotating"
      'Rz_amplitude', -135*pi/180, ...          % Initial angle [rad]
      'Rz_period',    1, ...          % Period of the rotating [s]
      'Dh_type',      'constant', ... % For now, only constant is implemented
      'Dh_pos',       [0.01; 0.02; -0.03; -3*pi/180; 1*pi/180; 3*pi/180], ...  % Initial position [m,m,m,rad,rad,rad] of the top platform
      'Rm_type',      'constant', ... % For now, only constant is implemented
      'Rm_pos',       [0, pi]', ...   % Initial position of the two masses
      'Dn_type',      'constant', ... % For now, only constant is implemented
      'Dn_pos',       [1e-3; 2e-3; 3e-3; 1*pi/180; 0; 1*pi/180] ...  % Initial position [m,m,m,rad,rad,rad] of the top platform
  );

  initializeReferences(opts);

No position error for now (perfect positioning).

  Dye = 0; % [m]
  Rye = 0; % [rad]
  Rze = 0; % [rad]
  Dhe = zeros(6,1); % [m,rad]
  Dhle = zeros(6,1); % [m]
  Dne = zeros(6,1); % [m,rad]

And we run the simulation.

  sim('simscape/sim_nano_station_metrology.slx');

Verify that the pose of the sample is the same as the computed one

Let's denote:

  • $\{W\}$ the initial fixed frame (base in which the interferometric measurement is done)
  • $\{R\}$ the reference frame corresponding to the wanted pose of the sample
  • $\{M\}$ the frame corresponding to the measured pose of the sample

We have then computed:

  • ${}^W\bm{T}_R$ which corresponds to the wanted pose of the sample with respect to the granite
  • ${}^W\bm{T}_M$ which corresponds to the measured pose of the sample with respect to the granite

We load the reference and we compute the desired trajectory of the sample in the form of an homogeneous transformation matrix ${}^W\bm{T}_R$.

  n = length(Dref.Dy.Time);
  WTr = zeros(4, 4, n);
  for i = 1:n
    WTr(:, :, i) = computeReferencePose(Dref.Dy.Data(i), Dref.Ry.Data(i), Dref.Rz.Data(i), Dref.Dh.Data(i,:), Dref.Dn.Data(i,:));
  end

As the displacement is perfect, we also measure in simulation the pose of the sample with respect to the granite. From that we can compute the homogeneous transformation matrix ${}^W\bm{T}_M$.

  n = length(Dsm.R.Time);
  WTm = zeros(4, 4, n);
  WTm(1:3, 1:3, :) = Dsm.R.Data;
  WTm(1:3, 4, :) = [Dsm.x.Data' ; Dsm.y.Data' ; Dsm.z.Data'];
  WTm(4, 4, :) = 1;

As the simulation is perfect (no measurement error and no motion error), we should have that \[ {}^W\bm{T}_R = {}^W\bm{T}_M \]

Or are least: \[ {}^W\bm{T}_R(1:3, 4) = {}^W\bm{T}_M(1:3, 4) \] \[ {}^W\bm{R}_R^t \cdot {}^W\bm{R}_M = \bm{I}_3 \]

  WTr(1:3, 4, end)-WTm(1:3, 4, end)
  WTr(1:3, 1:3, end)'*WTm(1:3, 1:3, end)-eye(3)
WTr(1:3, 4, end)-WTm(1:3, 4, end)
ans =
       1.8027246362351e-14
      1.40408518145563e-14
      6.93889390390723e-17
WTr(1:3, 1:3, end)'*WTm(1:3, 1:3, end)-eye(3)
ans =
      1.59872115546023e-14     -1.56629266848118e-14     -3.71230823859037e-16
      1.56742023874057e-14      1.59872115546023e-14     -2.12330153459561e-15
     -1.14144804719274e-15     -5.51642065360625e-16      9.28146448586631e-14

Conclusion

We are able to compute the wanted position and orientation of the sample. Both the measurement and the theory gives the same result.

Verify that the function to convert the position error in the frame fixed to the nano-hexapod is working

<<sec:compute_pos_error>>

Introduction   ignore

We now introduce some positioning error in the stage. This will induce a global positioning error of the sample with respect to the desired pose that we can compute.

We want to verify that we are able to measure this positioning error and convert it in the frame attached to the Nano-hexapod.

Prepare the Simulation

We load the configuration.

  load('simscape/conf_simscape.mat');

We set a small StopTime.

  set_param(conf_simscape, 'StopTime', '0.5');

We initialize all the stages.

  initializeGround();
  initializeGranite();
  initializeTy();
  initializeRy();
  initializeRz();
  initializeMicroHexapod();
  initializeAxisc();
  initializeMirror();
  initializeNanoHexapod(struct('actuator', 'piezo'));
  initializeSample(struct('mass', 50));

We setup the reference path to be constant.

  opts = struct(   ...
      'Ts',           1e-3, ...       % Sampling Frequency [s]
      'Dy_type',      'constant', ... % Either "constant" / "triangular" / "sinusoidal"
      'Dy_amplitude', 0, ...          % Amplitude of the displacement [m]
      'Ry_type',      'constant', ... % Either "constant" / "triangular" / "sinusoidal"
      'Ry_amplitude', 0, ...          % Amplitude [rad]
      'Rz_type',      'constant', ... % Either "constant" / "rotating"
      'Rz_amplitude', 0*pi/180, ...          % Initial angle [rad]
      'Dh_type',      'constant', ... % For now, only constant is implemented
      'Dh_pos',       [0; 0; 0; 0; 0; 0],  ...  % Initial position [m,m,m,rad,rad,rad] of the top platform
      'Rm_type',      'constant', ... % For now, only constant is implemented
      'Rm_pos',       [0, pi]', ...   % Initial position of the two masses
      'Dn_type',      'constant', ... % For now, only constant is implemented
      'Dn_pos',       [0; 0; 0; 0; 0; 0]  ...  % Initial position [m,m,m,rad,rad,rad] of the top platform
  );

  initializeReferences(opts);

Now we introduce some positioning error.

  Dye = 1e-6; % [m]
  Rye = 2e-4; % [rad]
  Rze = 1e-5; % [rad]
  Dhe = zeros(6,1);
  % Dne = [1e-3 ; 0 ; 2e-3 ; 0 ; 3e-3 ; 1e-3]; % [m,rad]
  Dhle = [1e-6 ; 2e-6 ; 3e-6 ; -2e-6 ; 1e-6 ; 2e-6]; % [m]
  Dne = zeros(6,1);

And we run the simulation.

  sim('simscape/sim_nano_station_metrology.slx');

Compute the wanted pose of the sample in the NASS Base from the metrology and the reference

Now that we have introduced some positioning error, the computed wanted pose and the measured pose will not be the same.

We would like to compute ${}^M\bm{T}_R$ which corresponds to the wanted pose of the sample expressed in a frame attached to the top platform of the nano-hexapod (frame $\{M\}$).

We have:

\begin{align} {}^M\bm{T}_R &= {}^M\bm{T}_W \cdot {}^W\bm{T}_R \\ &= {}^W{\bm{T}_M}^{-1} \cdot {}^W\bm{T}_R \end{align}

The top platform of the nano-hexapod is considered to be rigidly connected to the sample, thus, ${}^M\bm{T}_R$ corresponds to the pose error of the sample with respect to the nano-hexapod platform.

We load the reference and we compute the desired trajectory of the sample in the form of an homogeneous transformation matrix ${}^W\bm{T}_R$.

  n = length(Dref.Dy.Time);
  WTr = zeros(4, 4, n);
  for i = 1:n
    WTr(:, :, i) = computeReferencePose(Dref.Dy.Data(i), Dref.Ry.Data(i), Dref.Rz.Data(i), Dref.Dh.Data(i,:), Dref.Dn.Data(i,:));
  end

We also measure in simulation the pose of the sample with respect to the granite. From that we can compute the homogeneous transformation matrix ${}^W\bm{T}_M$.

  n = length(Dsm.R.Time);
  WTm = zeros(4, 4, n);
  WTm(1:3, 1:3, :) = Dsm.R.Data;
  WTm(1:3, 4, :) = [Dsm.x.Data' ; Dsm.y.Data' ; Dsm.z.Data'];
  WTm(4, 4, :) = 1;

The inverse of the transformation matrix can be obtain by (it is less computation intensive than doing a full inverse)

\begin{equation} {}^B\bm{T}_A = {}^A\bm{T}_B^{-1} = \left[ \begin{array}{ccc|c} & & & \\ & {}^A\bm{R}_B^T & & -{}^A \bm{R}_B^T {}^A\bm{P}_{O_B} \\ & & & \\ \hline 0 & 0 & 0 & 1 \\ \end{array} \right] \end{equation}

Finally, we compute ${}^M\bm{T}_R$.

  MTr = zeros(4, 4, n);
  for i = 1:n
    MTr(:, :, i) = [WTm(1:3,1:3,i)', -WTm(1:3,1:3,i)'*WTm(1:3,4,i) ; 0 0 0 1]*WTr(:,:,i);
  end

Verify that the pose error corresponds to the positioning error of the stages.

  MTr(1:3, 1:3, end)
  Rx = [1 0       0;
        0 cos(Erx) -sin(Erx);
        0 sin(Erx)  cos(Erx)];

  Ry = [ cos(Ery) 0 sin(Ery);
        0      1 0;
        -sin(Ery) 0 cos(Ery)];

  Rz = [cos(Erz) -sin(Erz) 0;
        sin(Erz)  cos(Erz) 0;
        0       0      1];
Edx [m] Edy [m] Edz [m] Erx [rad] Ery [rad] Erz [rad]
Error 2.8e-06 -2.0e-06 -1.3e-06 -5.1e-06 -1.8e-04 4.2e-07

Verify that be imposing the error motion on the nano-hexapod, we indeed have zero error at the end

We now keep the wanted pose but we impose a displacement of the nano hexapod corresponding to the measured position error.

  opts.Dn_pos = [Edx, Edy, Edz, Erx, Ery, Erz]';
  initializeReferences(opts);

And we run the simulation.

  sim('simscape/sim_nano_station_metrology.slx');

We keep the old computed computed reference pose ${}^W\bm{T}_r$ even though we have change the nano hexapod reference, but this is not a real wanted reference but rather a adaptation to reject the positioning errors.

As the displacement is perfect, we also measure in simulation the pose of the sample with respect to the granite. From that we can compute the homogeneous transformation matrix ${}^W\bm{T}_M$.

  n = length(Dsm.R.Time);
  WTm = zeros(4, 4, n);
  WTm(1:3, 1:3, :) = Dsm.R.Data;
  WTm(1:3, 4, :) = [Dsm.x.Data' ; Dsm.y.Data' ; Dsm.z.Data'];
  WTm(4, 4, :) = 1;

Finally, we compute ${}^M\bm{T}_R$.

  MTr = zeros(4, 4, n);
  for i = 1:n
    MTr(:, :, i) = [WTm(1:3,1:3,i)', -WTm(1:3,1:3,i)'*WTm(1:3,4,i) ; 0 0 0 1]*WTr(:,:,i);
  end

Verify that the pose error is small.

Edx [m] Edy [m] Edz [m] Erx [rad] Ery [rad] Erz [rad]
Error 1.0e-16 -1.1e-18 3.3e-20 1.5e-16 5.8e-17 -6.1e-16

Conclusion

Indeed, we are able to convert the position error in the frame of the NASS and then compensate these errors with the NASS.

Functions

computeReferencePose

<<sec:computeReferencePose>>

This Matlab function is accessible here.

  function [WTr] = computeReferencePose(Dy, Ry, Rz, Dh, Dn)
  % computeReferencePose - Compute the homogeneous transformation matrix corresponding to the wanted pose of the sample
  %
  % Syntax: [WTr] = computeReferencePose(Dy, Ry, Rz, Dh, Dn)
  %
  % Inputs:
  %    - Dy - Reference of the Translation Stage [m]
  %    - Ry - Reference of the Tilt Stage [rad]
  %    - Rz - Reference of the Spindle [rad]
  %    - Dh - Reference of the Micro Hexapod (Pitch, Roll, Yaw angles) [m, m, m, rad, rad, rad]
  %    - Dn - Reference of the Nano Hexapod [m, m, m, rad, rad, rad]
  %
  % Outputs:
  %    - WTr -

    %% Translation Stage
    Rty = [1 0 0 0;
           0 1 0 Dy;
           0 0 1 0;
           0 0 0 1];

    %% Tilt Stage - Pure rotating aligned with Ob
    Rry = [ cos(Ry) 0 sin(Ry) 0;
            0       1 0       0;
           -sin(Ry) 0 cos(Ry) 0;
            0       0 0       1];

    %% Spindle - Rotation along the Z axis
    Rrz = [cos(Rz) -sin(Rz) 0 0 ;
           sin(Rz)  cos(Rz) 0 0 ;
           0        0       1 0 ;
           0        0       0 1 ];


    %% Micro-Hexapod
    Rhx = [1 0           0;
           0 cos(Dh(4)) -sin(Dh(4));
           0 sin(Dh(4))  cos(Dh(4))];

    Rhy = [ cos(Dh(5)) 0 sin(Dh(5));
           0           1 0;
           -sin(Dh(5)) 0 cos(Dh(5))];

    Rhz = [cos(Dh(6)) -sin(Dh(6)) 0;
           sin(Dh(6))  cos(Dh(6)) 0;
           0           0          1];

    Rh = [1 0 0 Dh(1) ;
          0 1 0 Dh(2) ;
          0 0 1 Dh(3) ;
          0 0 0 1 ];

    Rh(1:3, 1:3) = Rhz*Rhy*Rhx;

    %% Nano-Hexapod
    Rnx = [1 0           0;
           0 cos(Dn(4)) -sin(Dn(4));
           0 sin(Dn(4))  cos(Dn(4))];

    Rny = [ cos(Dn(5)) 0 sin(Dn(5));
           0           1 0;
           -sin(Dn(5)) 0 cos(Dn(5))];

    Rnz = [cos(Dn(6)) -sin(Dn(6)) 0;
           sin(Dn(6))  cos(Dn(6)) 0;
           0           0          1];

    Rn = [1 0 0 Dn(1) ;
          0 1 0 Dn(2) ;
          0 0 1 Dn(3) ;
          0 0 0 1 ];

    Rn(1:3, 1:3) = Rnx*Rny*Rnz;

    %% Total Homogeneous transformation
    WTr = Rty*Rry*Rrz*Rh*Rn;
  end