Skip to content
Snippets Groups Projects

Absolute Encoder Calibration

This Python library serves as a toolbox to calibrate joins on robots integrated into ArmarX.


Standalone Usage

Note: This repository is integrated into Axii and already a feature of most robots such as ARMAR-6, ARMAR-DE, ARMAR-7a and ARMAR-7b. See below in "Robot-Specific Usage".

To activate it, run:

axii workspace add h2t/absolute_encoder_calibration
axii workspace upgr -m h2t/absolute_encoder_calibration
axii workspace install

Axii should then provide executables to start the Jupyter notebook with the corresponding joint calibrations.

Robot-Specific Usage

The examples provided here are with ARMAR-DE. It is be very similar for ARMAR-7 and ARMAR-6 though.

Prepare

  1. Open a terminal on the RT PC and enable your workspace, and then start the Jupyter notebook:
    start_armarde_absolute_encoder_calibration_notebook
    On other robots, this command will have a slightly different name.
  2. Open the provided link in the terminal in your browser (Ctrl + Click on the link, e.g., http://armar-de-0:8888/?token=xxxx).
  3. Start the notebook ARMAR_DE_Calibration.ipynb.
  4. Start the Simox RobotViewer and load the robot model that corresponds to the robot you are going to calibrate.
  5. Start etherkitten from the RT PC in a new terminal:
    etherkitten
    If for some reason etherkitten does not provide any readings on the onboard PC, you'll have to attach the bus to an external laptop that has ehterkittten installed and the run it there.

Calibrate Revolute Joints with Hard Stops

Note: Joints like ArmL2_Sho1, ArmL4_Sho3, and ArmL6_Elb2 are limitless joints, which require a different strategy to calibrate the absolute encoder, see section "Calibrate Limitless Revolute Joints" below.

  1. In RobotViewer GUI, find the joint to be calibrated, e.g. ArmL1_Cla1 of ARMAR-DE. Move the joint to its lower and upper limit (slide bar of Joint Value). This step tells you where the lower and upper limits are. E.g. the image belows shows the lower and upper limit of ArmL1_Cla1. lower_lim

    Fig. 1 Lower Limit

    upper_lim

    Fig. 2 Upper Limit

  2. Now, move the joint on the real robot to its lower limit (corresponding to RobotViewer like Fig. 1). Push it firmly against the hard stop and ensure that it does not come back. Do not touch the robot while reading sensor values.

  3. Read the absolute values from the etherkitten GUI.

    1. Find the corresponding slave (Better to check the serial number and make sure it matches that in the hardware configuration file).

    2. Find sensor_actuator_board -> PDO -> Absolute Encoder Value, as shown below.

      pdo_abs_enc

      Fig. 3 Absolute encoder values in PDO

    3. Read the value and enter it into the code block for the joint in the notebook, first entry (LOWER_LIMIT) of the tuple as shown below.

      Cla1_L = C(name="Cla1_L",
                 measured_limits_ticks=(LOWER_LIMIT, UPPER_LIMIT),
                 measured_zero_ticks=MIDDLE_OF_RANGE,
                 joint_offset_degree=15,
                 joint_limits_degree=(-82, 82),
                 method="hard_stop",
                 **ctx)
  4. Repeat 1 to 3 for the upper limit and middle of the range and put the values to the field UPPER_LIMIT and MIDDLE_OF_RANGE, respectively. Please note that MIDDLE_OF_RANGE does not have to be very accurate - aligning it visually is sufficient.

  5. Execute the first cell in the notebook, as well as the cell you just modified. It generates the hardware configuration line for the corresponding joint, as well as plots for you to visually validate the calibration, and a range of motion analysis. Check the plots to visually verify the calibration. If it looks correct, proceed with the next steps.

  6. Calibrate sensor conversion and offsets: The generated line for the hardware configuration should looks similar to this:

    <ModularConvertedValue name="absoluteEncoder" zeroOffset="524288" discontinuityOffset="698666" maxValue="2^20" isInverted="true" />

    Paste this conversion configuration into the hardware configuration of the corresponding slave.

  7. Calibrate Range of Motion: The range of motion analysis will print several upper and lower limits for you to calibrate different aspects of the robots. It looks like this:

    Range of motion analysis for 'Cla1_L':
    
    Definitions:
      RoM: Range of motion
      loss/gain: Loss or gain of range of motion compared to model limits
    
    CAD model limits:
      -82.000° to 82.000° (RoM: 164.000°)
      -1.431 rad to 1.431 rad (RoM: 2.862 rad)
    
    Physical limits (to hard stops):
      -81.804° to 81.804° (RoM: 163.608°, loss of 0.392°)
      -1.428 rad to 1.428 rad (RoM: 2.855 rad, loss of 0.007 rad)
    
    Hard limits (considering hard_limit_margin_degrees = 1°):
      -80.804° to 80.804° (RoM: 161.608°, loss of 2.392°)
      -1.410 rad to 1.410 rad (RoM: 2.821 rad, loss of 0.042 rad)
    
    Soft limits (considering hard_limit_margin_degrees = 1° and soft_limit_margin_degrees = 1°):
      -79.804° to 79.804° (RoM: 159.608°, loss of 4.392°)
      -1.393 rad to 1.393 rad (RoM: 2.786 rad, loss of 0.077 rad)

    From top to bottom:

    1. CAD model limits: These are the theoretical limits from one hard stop to another according to the CAD model, not the Simox/URDF robot model file. Please verify with the hardware team that these values are correct and comply with the CAD model. This output is informational for the hardware team to validate.
    2. Physical limits: These limits are the actual range of motion that could be achieved with the calibration procedure. Minor deviations are unavoidable here depending on the concrete joint type, but it should correspond to the CAD model limits. This output is informational and should align with the CAD model limits.
    3. Hard limits: These limits are the ones the lowest-level controllers should obey to. The hard limits are calculated from the actual range of motion and additionally accounting for a margin that can be configured with the parameter hard_limit_margin_degrees (default: 1°). The purpose of the margin is that controllers have a little bit leeway even if they overshoot/oscillate so they don't crash into the hard stops. These limits must be configured in the hardware configuration for the respective controllers.

      ⚠️ WARNING: If the hard limits are not more conservative than the physical limits, controllers might crash into the hard stops and damage or even break them.

    4. Soft limits: These limits are the ones the higher-level controllers should obey to. They are calculated from the hard limits and an additional margin that can be configured with the parameter soft_limit_margin_degrees (default: 1°, so with the hard margin this makes for a margin of 2° to the physical limits by default). Thus, these limits are the most conservative ones and allow for the higher-level controllers to overshoot/oscillate without producing jerky behaviour. These limits must be configured in the Simox and URDF robot models.

      ⚠️ WARNING: If the soft limits are not more conservative than the hard limits, controllers might reach the low-level controller's limits, resulting in significant jerks or abrupt stops.

Validate the Calibration on the Real Robot

  1. If you attached the bus to the external laptop, reattach it to connect the bus back to the robot's PC. Otherwise, just launch the realtime unit, e.g. start_unit on the RT PC.
  2. Open the kinematic unit GUI.
  3. Put the robot to soft emergency stop (SS2), trigger the PDO device.
  4. Move the calibrated joint to its lower and upper limit (according to the model), check the readings in the kinematic unit GUI. If it moves continuously from one limits to another, we are good to go.
  5. Be careful at this step, hold the emergency stop (STO) for any unexpected motion. Release the soft emergency stop (SS2), and put the joint to position control mode. If the joint moves at all (e.g. automatically moving towards the limit), trigger the emergency stop (SS2 or STO) immediately. It is most likely that the sign of the relative encoder is wrong. To fix this, do the following, otherwise go to next step.
    1. Go to the hardware config of the joint, and check whether there are the following two entries
    <LinearConvertedValue name="relativePosition" factor="2.27256413020095e-06" offset="0" />
    <LinearConvertedValue name="velocity" factor="2.27256413020095e-06" offset="0.0" />
    in config field
    <Device type="Joint" name="ArmR5_Elb1" profile="default">
         <Slave type="Elmo" profile="U2 1:100">
             <Identifier>
                 <VendorID>154</VendorID>
                 <ProductID>198948</ProductID>
                 <Serial>0x01087507</Serial>
             </Identifier>
             <Config>
                 <Float name="loLimit">-0.680678</Float>
                 <Float name="hiLimit">2.54818</Float>
                 <Bool name="limitless">false</Bool>
                 <Bool name="InvertedSTOValue">true</Bool>
                 <LinearConvertedValue name="targetTorque" factor="-7.0" offset="0.0" />
             </Config>
         </Slave>
    1. If it is not there, then copy these two entries from the default profile Profiles.xml and search for U2 1:120.
    2. Flip the sign of the factors. Do not change the factor and ensure it is consistent with the profile.
  6. Now repeat 5 and check if the joint is stable in position mode. If so, then try to move the joint to its lower and upper limit.
  7. If the joint move smoothly inside the motion range, then you are done.

Calibrate Limitless Revolute Joints

TBD

Calibrate Magnetic Absolute Encoder

The ThumbCircumduction joint of the thumb of ARMAR-DE and ARMAR-7 has a magnetic absolute encoder. It measures the angle of the magnetic field. Since this joint is not backdrivable, you have to use a etherketten laptop to drive it to reach its lower and upper limits.

  1. Similarly to other cases, you'll need to validate which limit is the lower/upper limit in RobotViewer.

  2. Attach the ethernet cable of the hand (or the arm containing the hand) to the etherkitten laptop.

  3. Drive the hand to the lower limit by setting a proper PWM value.

  4. Read the magnetometer values. We are interested in the x and y readings. Record it as

    xlx_l
    and
    yly_l
    .

  5. Drive the joint to the upper limit and record the x and y value again, as

    xux_u
    and
    yuy_u
    .

  6. Compute the angle at both limits

    There was an error rendering this math block. KaTeX parse error: Undefined control sequence: \atan at position 12: \alpha_l = \̲a̲t̲a̲n̲2(y_l, x_l), \a…

  7. Set the motorPositionZeroOffset in the hardware config file of that joint to

    αlow-\alpha_{low}
    .

  8. Compute the motorPositionScaling

    ss
    . Find the range of the motion (in radian) as
    RR
    , e.g.
    π/2\pi/2
    .

    • Usually,
      s=R/αumod(2π)αlmod(2π)s = R / \vert\alpha_u \bmod (2 \pi) - \alpha_l \bmod (2 \pi)\vert
    • However, for whatever reason, this does not match reality. In pratice, you can put the motorPositionZeroOffset in the hardware config, and set motorPositionScaling to 1, launch the unit and see the behavior of the joint. If it does not match the expected range of motion, then slightly twick the motorPositionScaling until satisfied.
  9. In the kinematic Unit GUI, try to put the joint into position control mode. Ff the motor moves to the maximum even if you haven't change target or only changed slightly, then revert the motorPositionIsInverted entry.

  10. Reboot the unit until you can control the joint smoothly in the entire range of motion.