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
- Open a terminal on the RT PC and enable your workspace, and then start the Jupyter notebook:
start_armarde_absolute_encoder_calibration_notebook
- Open the provided link in the terminal in your browser (Ctrl + Click on the link, e.g.,
http://armar-de-0:8888/?token=xxxx
). - Start the notebook
ARMAR_DE_Calibration.ipynb
. - Start the Simox
RobotViewer
and load the robot model that corresponds to the robot you are going to calibrate. - Start
etherkitten
from the RT PC in a new terminal:etherkitten
etherkitten
does not provide any readings on the onboard PC, you'll have to attach the bus to an external laptop that hasehterkittten
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.
-
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 ofJoint Value
). This step tells you where the lower and upper limits are. E.g. the image belows shows the lower and upper limit ofArmL1_Cla1
.Fig. 1 Lower Limit
Fig. 2 Upper Limit
-
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. -
Read the absolute values from the
etherkitten
GUI.-
Find the corresponding slave (Better to check the serial number and make sure it matches that in the hardware configuration file).
-
Find
sensor_actuator_board
->PDO
->Absolute Encoder Value
, as shown below.Fig. 3 Absolute encoder values in PDO
-
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)
-
-
Repeat 1 to 3 for the upper limit and middle of the range and put the values to the field
UPPER_LIMIT
andMIDDLE_OF_RANGE
, respectively. Please note thatMIDDLE_OF_RANGE
does not have to be very accurate - aligning it visually is sufficient. -
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.
-
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.
-
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:
- 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.
- 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.
- 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.
- 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
- 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. - Open the kinematic unit GUI.
- Put the robot to soft emergency stop (SS2), trigger the PDO device.
- 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.
-
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.
- 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" />
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>
- If it is not there, then copy these two entries from the default profile
Profiles.xml
and search forU2 1:120
. - Flip the sign of the factors. Do not change the factor and ensure it is consistent with the profile.
- 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.
- 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.
-
Similarly to other cases, you'll need to validate which limit is the lower/upper limit in
RobotViewer
. -
Attach the ethernet cable of the hand (or the arm containing the hand) to the etherkitten laptop.
-
Drive the hand to the lower limit by setting a proper PWM value.
-
Read the magnetometer values. We are interested in the
x
andy
readings. Record it asand. -
Drive the joint to the upper limit and record the
x
andy
value again, asand. -
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… -
Set the
motorPositionZeroOffset
in the hardware config file of that joint to. -
Compute the
motorPositionScaling
. Find the range of the motion (in radian) as, e.g..- Usually,
- However, for whatever reason, this does not match reality. In pratice, you can put the
motorPositionZeroOffset
in the hardware config, and setmotorPositionScaling
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 themotorPositionScaling
until satisfied.
- Usually,
-
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. -
Reboot the unit until you can control the joint smoothly in the entire range of motion.