Any Robot + RobotDK + Python: Verify Hand-Eye Calibration Result Via Touch Test


This tutorial has only been tested on UR5e and Yaskawa H10, and it only works with robots supported by RoboDK.


Sometimes it is hard to measure how accurate the Hand-Eye Calibration is. Therefore, we created a Touch Test to verify accuracy easily. In this test, we use RoboDK to move the robot. This sample works for the results of both types of Hand-Eye Calibration, Eye-in-Hand and Eye-to-Hand. The Touch Test consists in placing the Zivid Calibration Board in the FOV of the camera, capturing it, and controlling the robot to touch it at a specific point. After touching, you can move the Zivid Calibration Board and instruct the robot to touch it again. You can repeat this process as many times as you want. The only two limitations are the robot’s reach and the camera’s FOV.

In the image below, you can see the expected result from the Touch Test.

The expected result of the Touch Test.


The accuracy of the touch depends on the Robot Calibration error, the Hand-Eye Calibration error, the TCP Calibration error, and Checkerboard Pose Estimation error.


Pointed Hand-Eye Verification Tool

The Pointed Hand-Eye Verification Tool is used in this tutorial as the touching tool. This tool is compatible with UR5e (ISO 9409-1-50-4-M6) and the Yaskawa HC10 (ISO 9409-1-63-4-M6).

The Pointed Hand-Eye Verification Tool is illustrated in the following image.

Pointed Hand-Eye Verification Tool

On-arm Mounts

In this tutorial, we assume using the Zivid On-Arm Mount Extender and the Zivid On-Arm Mount attached between the robot end-effector and the Pointed Hand-Eye Verification Tool. These mounts increase the distance between the robot end effector and the Pointed Hand-Eye Verification Tool. You can find the measurements added for each mount in the image below.

Zivid On-Arm Mount and On-Arm Mount Extender

The on-arm-mounts.yaml file contains the transformation matrix of the two mounts installed between the robot end effector and the Pointed Hand-Eye Verification Tool. For more details about the mounts, check out on-arm camera mount datasheet and on-arm mount extender datasheet.

If you already have the RoboDK environment set up and you are connected to your robot, you can jump to Create the Capture Pose for the Touch Test

Set Up RoboDK Environment

RoboDK .rdk files store information about the robot, targe pose, and environment. The components in the .rdk file needed to perform the Touch Test are:

  • Robot model file (.robot)

  • One target pose (in the example demonstrated in this tutorial it’s named “touch_test_pose”)

  • Virtual model of robot’s environment (optional)

  • CAD model of the camera the in use, e.g., Zivid Two CAD file (optional)

  • CAD model of the Pointed Hand-Eye Verification Tool (optional)

Add Robot to RoboDK Environment

Start by opening the RoboDK program and adding the robot that will be used. To add the robot, open the library using the GUI by going to File -> Open online library. Find the robot that matches your model through this interface, hover over it with the mouse and choose Open. If the robot does not appear in the station, choose Download instead and drag and drop it into the .rdk environment. This is also described in the Select a robot RoboDK tutorial.

Connect to Robot through RoboDK


Depending on the brand of robot being used, a driver setup might be required to connect to RoboDK. For help on this set up, check out the robot tips section in the RoboDK documentation. For example, here is the advice for ABB robots.

Before running the Touch Test script, it is first necessary to connect to the robot using the RoboDK interface. In RoboDK GUI navigate to Connect -> Connect Robot. This will open a side panel where you can insert the Robot IP and the port number.

Tilted Zivid Calibration Board.


Most robots will have a remote mode on their control pendant or tablet. Make sure your robot is in remote mode to be able to establish the connection.

To connect to the robot you must know its IP address, it should be found/listed in the robot control pendant. Follow the steps for connecting to the robot for RoboDK. Another connection that should be verified is the port number. The default number that comes with the driver should work unless changes have been made previously.

Just click Connect and if the Connection status box is green, the RoboDK interface can be used to control the robot. If it is red instead, make sure that you have the right port number and IP address. If it is still red, check the Troubleshoot RoboDK chapter at the end of this tutorial.

Create the Capture Pose for the Touch Test

Learn how to create a target in RoboDK in order to save the Capture Pose for the Touch Test.

Creating poses using RoboDK can be approached in two ways:

  1. Moving the robot physically to the desired poses using the pendant, then connecting through RoboDK and recording the poses

  2. Moving the robot remotely through RoboDK to create and save the poses


If you are moving the robot through RoboDK and the robot is not moving fast enough or slow enough, check this link to set the robot speed in RoboDK. After setting the speed, remember to right-click on the program that you have created and mark Run on the robot and then right-click again and choose Run.

Before creating the Touch Test Capture Pose, you must consider where you plan to put the Zivid Calibration Board. If Eye-in-Hand, ensure it will be in the FOV of the camera. If Eye-to-Hand, ensure that the robot will not block the view of the Zivid Calibration Board. Only one pose is needed for the Touch Test. You can see illustrated bellow how it looks in RoboDK.

Pose for Touch Test on RoboDK.


To have control of the robot configurations used, ensure the saved targets are joint targets, not cartesian targets. Right-clicking on a target in RoboDK and choosing a joint target will transform the pose into a joint target. This will also change the target symbol color from red to green.

Difference between cartesian target and joint target.

Run the Touch Test

Before running the script, it is required to have the .rdk file open and be connected to the robot. The script can be found in the Zivid Python Samples; it takes the following command line arguments, as shown below.

Go to source


type_group.add_argument("--eih", "--eye-in-hand", action="store_true", help="eye-in-hand calibration")
type_group.add_argument("--eth", "--eye-to-hand", action="store_true", help="eye-to-hand calibration")
parser.add_argument("--ip", required=True, help="IP address of the robot controller")
    help="RoboDK target name representing a robot pose at which the calibration board is in the field of view of the camera",
    help="Path to YAML file that represents the Pointed Hand-Eye Verification Tool transformation matrix",
    help="Path to YAML file that represents the on-arm mounts transformation matrix",
    help="Path to the YAML file that contains the Hand-Eye transformation matrix",

Once the script is initialized, the robot moves to the Capture Pose previously defined. Then, the user is asked to put the Zivid Calibration Board in the FOV and press Enter. After that, the camera captures the board, the pose of the touching point is computed, and the robot touches the checkerboard corner. When the user presses the Enter key, the robot pulls back and returns to the Capture Pose. At this point, the Zivid Calibration Board can be moved to perform the Touch Test at a different location. The user is asked to input “y” on “n” to repeat or abort the touch test.

Script walk-through

For the RoboDK Hand-Eye Calibration verification script to be functional it requires three additional Python files.

  1. is used to configure the robot.

  2. is used to save and load matrices to or from YAML files.

The script runs through the following steps respectively:

Connect to robot

Firstly, we connect to the robot using the IP address. We then get a rdk object used to establish a link with the simulator and a robot object containing various robot configuration parameters.

Go to source


rdk, robot = connect_to_robot(user_options.ip)

Set robot speed and acceleration

The last step of the robot configuration is defining the speed and acceleration of the robot.

Go to source


set_robot_speed_and_acceleration(robot, speed=120, joint_speed=120, acceleration=120, joint_acceleration=120)

Load Pointed Hand-Eye Verification Tool transformation matrix

The transformation matrix that defines the Pointed Hand-Eye Verification Tool is then loaded.

Go to source


print("Loading the Pointed Hand-Eye Verification Tool transformation matrix from a YAML file")
pointed_hand_eye_verification_tool_matrix = load_and_assert_affine_matrix(user_options.tool_yaml)

Define TCP transformation matrix

Then we need to define the tool center point (TCP). Firstly the program will check if the user provided a .yaml file containing an on-arm mounts matrix. If the user does not provide any on-arm mounts matrix, we assume the Pointed Hand-Eye Verification Tool is directly attached to the robot’s end effector. Therefore, the TCP matrix is equivalent to the Pointed Hand-Eye Verification Tool matrix.

Go to source


if user_options.mounts_yaml:
    print("Loading the on-arm mounts transformation matrix from a YAML file")
    flange_to_on_arm_mounts_transform = load_and_assert_affine_matrix(user_options.mounts_yaml)

    tcp = flange_to_on_arm_mounts_transform @ pointed_hand_eye_verification_tool_matrix
    tcp = pointed_hand_eye_verification_tool_matrix

Move to Capture Pose

The robot moves to the capture_pose, which is obtained from the .rdk file that is open while running this sample.

Go to source


capture_pose = get_robot_targets(rdk, target_keyword=user_options.target_keyword)
if not capture_pose:
    raise IndexError(
        "The list of poses retrieved from RoboDK is empty...\nMake sure that you have created a Capture Pose and that you introduced the right keyword for it."

Place the Zivid Calibration Board

The next step is to ensure the user has placed the Zivid Calibration Board in the FOV of the camera.

Go to source


print("\nPlace the calibration board in the FOV of the camera.")
input("Press enter to start.")

Zivid Calibration Board Detection and Pose Estimation

After pressing Enter, the Zivid Calibration Board is captured and its pose in the camera frame is estimated.

Go to source


print("Detecting the calibration board pose (upper left checkerboard corner)")
camera_to_calibration_board_transform = _capture_and_estimate_calibration_board_pose(camera)

Transform the Zivid Calibration Board Pose from Camera to Robot Base Frame

Go to source


print("Calculating the calibration board pose in robot base frame")
robot_base_to_calibration_board_transform = _get_robot_base_to_calibration_board_transform(

To understand the maths behind this transformation, check out Hand-Eye Calibration Solution.

Get the Touch Pose

Since the touch pose we control the robot to move to is the end-effector (flange) pose, we need to take the TCP into consideration.

Go to source


print("Calculating pose for robot to touch the calibration board")
touch_pose = robot_base_to_calibration_board_transform @ np.linalg.inv(tcp)

Get the Approach Pose

We define the approach pose as an offset from the touch pose in the Z axis, arbitrarily chosen to be -140 mm.

Go to source


print("Calculating pose for the robot to approach the calibration board")
touch_pose_offset = np.identity(4)
touch_pose_offset[2, 3] = -140
approach_pose = touch_pose @ touch_pose_offset

Touch the Zivid Calibration Board

To touch the Zivid Calibration Board, the robot first moves to the approach pose with joint movement. Then it moves in a straight line to the touch pose. At this point, the user can get close to the Zivid Calibration Board and visually inspect the accuracy of the performed touch.

Go to source


print("Touching calibration board (upper left checkerboard corner)")

Move Away from the Zivid Calibration Board

The program expects the user to press Enter for the robot to move away from the Zivid Calibration Board back to the Capture Pose.

Go to source


input("\nPress enter to pull back and return to the capture pose...")

Touch the Zivid Calibration Board Again

At this point, the Zivid Calibration Board can be moved to perform the Touch Test at a different location within the FOV of the camera. The user is asked to input “y” or “n” to repeat or abort the touch test.

Go to source


print("\nThe board can be moved at this time.")
answer = _yes_no_prompt("Perform another touch?")
if answer == "n":

Troubleshoot RoboDK

Robot Moving to Different Configuration than Intended

To have a repeatable Touch Test process, use joint targets because the robot will always assume the same configuration. Using cartesian targets allows the robot to choose the configuration, which can lead to collisions. In the image below, you can see two targets, the target 1 represented with a red color and the target 2 colored green. The red color means the target is cartesian, and the green means it is a joint target.

Difference between cartesian target and joint target.
Connect Through Firewall on windows


This method was tested on Windows 10.

Check driver blockage

When connecting to a computer running Windows be aware that the firewall can prevent the connection to the robot. One option is to disable the firewall completely, but this is not recommended as it will leave your system vulnerable.

Instead, you can add a new rule to your windows firewall to allow communication only for the driver and IP address of the robot you use. To find these two attributes expand the connect to robot panel by choosing more options. In this case, the driver is apiur.

Showing the driver's name.

Go to the Windows Defender Firewall on your system and go into the Advanced settings. This will lead you to the rules definitions for the firewall. Here the inbound rules can be changed to allow communications with the driver needed to control the robot.

Check in the inbound rules if the robot driver has a blocked sign. If the driver is blocked, disable this rule; otherwise, the firewall blocks communication.

Blocked driver and disable rule button.

Once this rule is disabled, check if the RoboDK software can connect to the robot. If you can still not connect to the robot, you need to make a rule that specifically allows the driver to communicate with the robot.

Create a new inbound rule

By clicking New Rule… you create and define a rule that allows communication between your computer and the robot.

Add new inbound rule.

To begin with, you need to choose the option Custom on the first page and All programs on the second. you can find it illustrated below.

First two steps.

On the next page you need to choose the TCP as protocol, then choose a specific local port and insert the number of the port matching the one in RoboDK.

Choose the protocol and ports.

The next step is setting the IP address. Under Which remote IP address does this rule apply to?, choose These IP addresses. Then click on Add and set the IP that matches the one in RoboDK.

Choose the rule scope.

After hitting OK and Next, choose Allow all connections and on the next page, check all boxes.

Set actions and profiles.

Finally, just choose a proper name for the rule, click Finish and you are good to go!

Set actions and profiles.