UR5 Robot + Python: Generate Dataset and perform Hand-Eye Calibration

참고

이 튜토리얼은 Universal Robots UR5e를 사용하여 구축 및 테스트되었습니다.

Introduction

정확한 핸드-아이 칼리브레이션에는 좋은 데이터 세트가 필요하지만 이 데이터 세트를 생성하는 것은 쉬운 일이 아닙니다. 이 튜토리얼에서는 먼저 Zivid 카메라와 Universal Robots(UR) UR5e 간의 통신을 설정합니다. 그런 다음 3D 이미지와 로봇 포즈로 구성된 데이터 세트를 추출합니다. 마지막으로 이 데이터 세트를 사용하여 핸드-아이 칼리브레이션을 수행합니다. 샘플은 Eye-in-hand와 Eye-to-hand 모두에서 작동합니다.

핸드-아이 칼리브레이션에 익숙하지 않은 경우 다음을 먼저 확인하는 것이 좋습니다. Hand-Eye Calibration.

Requirements

Prepare UR5e robot

Github에서 zivid-python-samples 을 복제하고 ur_hand_eye_calibration 폴더로 이동한 후 runtime requirements 를 설치합니다.

cd source\applications\advanced\hand_eye_calibration\ur_hand_eye_calibration
pip install -r requirements.txt
cd source/applications/advanced/hand_eye_calibration/ur_hand_eye_calibration
pip install -r requirements.txt

UR RTDE (Real-Time Data Exchange) 통신 프로토콜을 포함한 모든 타사 라이브러리를 설치합니다.

이 샘플에 필요한 세 개의 파일은 다음과 같습니다.

  • universal_robots_communication_file.xml - I/O 레지스터가 있는 구성 파일입니다.

  • universal_robots_robot_motion_script.urp - UR 컨트롤러에서 생성되고 실행되는 로봇 모션 스크립트입니다.

  • universal_robots_perform_hand_eye_calibration.py - 이미지와 포즈를 캡처하고 저장하고 핸드-아이 칼리브레이션을 수행하는 Python 스크립트입니다.

로봇 모션 스크립트는 칼리브레이션에 사용되는 모든 로봇 포즈를 설정하는 곳입니다. python 스크립트는 이미지를 캡처하고, 로봇 포즈를 읽고, 핸드-아이 칼리브레이션을 수행합니다. 로봇과 컴퓨터 간의 통신은 UR RTDE (Real-Time Data Exchange) 를 통해 이루어집니다. 통신 흐름의 개요는 아래에 설명되어 있습니다.

../../../_images/hand-eye-ur5-python-flow-diagram.png

데이터세트를 생성하기 전에 UR 로봇 모션 스크립트를 일부 조정해야 합니다.

Modify universal_robots_robot_motion_script.urp robot motion script

먼저 USB 드라이브에 universal_robots_hand_eye_script.urp 파일을 저장하고 UR 컨트롤러에 스크립트를 로드합니다. 컨트롤러 인터페이스는 다음과 유사해야 합니다.

../../../_images/hand-eye-ur5-script-screenshot.png

Here, capture_hand_eye is a subprogram that triggers the camera to capture one image, which is done for every robot pose. The subprogram communicates with the PC via registers - logical channels on the communication interface. The following are I/O variables used to communicate with the Python script:

  • image_count

  • start_capture

  • camera_ready

  • finish_capture

output_int_register_24 = image_count:

획득한 이미지와 포즈의 수를 계산합니다.

output_bit_register_64 = start_capture:

Bool that triggers the camera to capture an image.

input_bit_register_64 = finish_capture:

Bool that triggers the UR robot to move to the next position.

input_bit_register_65 = ready_to_capture::

카메라를 사용할 준비가 되었음을 UR 로봇에 알리는 Bool입니다.

The universal_robots_communication_file.xml file states which of the registers we are writing to. If we change a register in the Python script, we must change the same register in the configuration file.

<?xml version="1.0"?>
<rtde_config>
    <recipe key="out">
        <field name="actual_TCP_pose" type="VECTOR6D"/>
        <field name="output_int_register_24" type="INT32"/>
        <field name="output_bit_register_64" type="BOOL"/>
    </recipe>
    <recipe key="in">
        <field name="input_bit_register_64" type="BOOL"/>
        <field name="input_bit_register_65" type="BOOL"/>
    </recipe>
</rtde_config>

To generate a good dataset, we want to follow the steps explained in Hand-Eye Calibration Process. Every waypoint, robot_pose_X, must be modified to fit the setup. The easiest way is to set the robot in free-drive and move it with your hands to the desired postures. Make sure that the Zivid Calibration Object is visible for the camera at each of these postures. If you are using ArUco markers, not all of them need to be visible for each capture. If you don’t get good point cloud quality and coverage on the calibration object (on both dark and light squares), modify camera settings in the following function:

def _camera_settings() -> zivid.Settings:
    """Set camera settings

    Returns:
        Zivid Settings
    """
    return zivid.Settings(
        acquisitions=[
            zivid.Settings.Acquisition(
                aperture=8.0,
                exposure_time=datetime.timedelta(microseconds=10000),
                brightness=1.0,
                gain=1,
            )
        ],
        processing=zivid.Settings.Processing(
            filters=zivid.Settings.Processing.Filters(
                smoothing=zivid.Settings.Processing.Filters.Smoothing(
                    gaussian=zivid.Settings.Processing.Filters.Smoothing.Gaussian(enabled=True)
                )
            )
        ),
    )

How To Get Good Quality Data On Zivid Calibration Object 은 최적의 3D 이미지 품질을 위해 파라미터를 조정하는 방법을 설명합니다.

조심

If the captured images of the calibration object are not exposed well, hand-eye calibration will not work.

웨이포인트를 추가하거나 제거하는 경우, 모든 웨이포인트 다음에 capture_hand_eye 를 호출하는 것을 잊지 마십시오. 정확한 핸드-아이 변환을 얻으려면 10-20개의 웨이포인트를 사용하는 것이 좋습니다.

Before we run the Python script, it is helpful to manually go through all the robot positions. This way, we can verify that the robot will avoid singularities while moving from one pose to the next.

조심

eye-in-hand 칼리브레이션을 수행하는 경우 Zivid 카메라가 로봇과 충돌하지 않는지 확인하십시오.

Run python script

이제 장면에 맞게 로봇 스크립트를 수정했으므로 데이터 세트를 생성하고 보정을 수행할 준비가 되었습니다!

It is recommended to Warm-up the camera and run Infield Correction before running hand-eye calibration. Use the same capture cycle during warmup, infield correction, and hand-eye calibration as in your application. To further reduce the impact of the temperature dependent performance factors, enable Thermal Stabilization.

First, run universal_robots_robot_motion_script.urp from the UR controller. When the program starts, it will wait for the Python script to set the camera_ready variable to True. Then, run the universal_robots_perform_hand_eye_calibration.py script from the command line.

For Eye-in-hand:

python universal_robots_perform_hand_eye_calibration.py --eih --ip 192.168.0.123

For Eye-to-hand:

python universal_robots_perform_hand_eye_calibration.py --eth --ip 192.168.0.123

For Eye-in-hand:

python universal_robots_perform_hand_eye_calibration.py --eih --ip 192.168.0.123 marker --dictionary aruco4x4_50 --ids 1 2 3

For Eye-to-hand:

python universal_robots_perform_hand_eye_calibration.py --eth --ip 192.168.0.123 marker --dictionary aruco4x4_50 --ids 1 2 3

192.168.0.123 을 로봇의 실제 IP 주소로 대체합니다. UR Teach Pendant 오른쪽 상단의 Hamburger menuSystem 으로 이동하여 로봇의 IP 주소를 확인하거나 설정합니다.

The different inputs required by the Python script are displayed by typing the following command in the command prompt:

python universal_robots_perform_hand_eye_calibration.py -h
../../../_images/hand-eye-full-hand-eye-sample-screenshot.png

스크립트가 완료되면 다음을 출력합니다.

  • 데이터를 저장한 디렉토리

  • 핸드-아이 변환 - 4x4 칼리브레이션 매트릭스

  • 각 로봇 포즈에 대한 회전 및 변환의 residual

Zivid가 잔차(residual)를 계산하는 방법에 대한 자세한 설명은 Hand-Eye Calibration Residuals 을 참조합니다.

Transformation matrix이 있으면 이를 사용하여 카메라 프레임에서 로봇 베이스 프레임으로 3D 포인트를 변환할 수 있습니다. 이 작업을 수행하는 방법에 대한 자세한 내용은 How To Use The Result Of Hand-Eye Calibration 을 참조합니다.

힌트

Python, C# and C++ samples of transforming a 3D point or the whole point cloud are available at our GitHub repo.