6.5 RT 튜토리얼

실시간 튜토리얼 절에서는 두산 로봇 API의 실시간 제어(RT) 및 모니터링 기능을 소개합니다. 이 모드에서는 전용 UDP 기반 통신 채널로 조인트 명령이나 작업 공간(Task Space) 명령을 스트리밍하고 실시간 데이터를 받을 수 있습니다.

이 예제들은 RT 연결을 설정하고, 전송 매개변수를 구성하고, RT 제어를 시작 및 정지하고, 실시간 피드백 데이터를 처리하는 방법을 보여 줍니다.

튜토리얼 흐름

  1. RT 연결 설정: 실시간 제어 링크를 설정합니다.

  2. RT 출력 설정: 제어 주파수를 정의합니다.

  3. RT 제어 시작 / 정지: 실시간 명령 스트리밍을 활성화하고 비활성화합니다.

  4. RT 데이터 모니터링: 실시간 출력 데이터(위치, 속도, 토크)를 가져와 기록합니다.

  5. 속도 / 가속도 한계(확장): 실시간 명령이 사용하는 속도와 가속도 값을 설정합니다.

  6. 통합 안전 처리: RT 루프를 안전 정지 및 연결 끊김 복구와 결합합니다.

RT 연결 설정

목적
로봇 컨트롤러와 외부 PC 사이의 실시간 데이터 교환을 위한 전용 UDP 통신 채널을 설정합니다.

#include "DRFLEx.h"
#include <cstdio>
#include <atomic>
#include <thread>
#include <chrono>
using namespace DRAFramework;

CDRFLEx Drfl;

// 기본 IP와 포트로 연결
Drfl.connect_rt_control();

// 또는 사용자 지정 호스트와 포트 지정
// Drfl.connect_rt_control("192.168.137.100", 12348);

확인
시간 초과 없이 연결이 설정되고, 컨트롤러가 RT 연결 확인 응답을 보냅니다.

RT 출력 설정

목적
RT 통신의 갱신 주기를 정의합니다.

std::string version = "v1.0";
float period = 0.001f;   // 1 ms 갱신 주기
int loss_count = 4;      // 예약됨, 사용하지 않음

Drfl.set_rt_control_output(version, period, loss_count);

확인
로봇이 설정을 받아들이고 RT 명령 스트리밍을 준비합니다.

RT 제어 시작 / 정지

목적
명령 전송을 위한 실시간 제어 루프를 시작하고 정지합니다.

// 스트리밍 시작
Drfl.start_rt_control();

// RT 제어가 시작된 동안 여기에서 RT 명령과 set_*_rt 값을 전송

// 사용 후 RT 세션 종료
Drfl.disconnect_rt_control();

// 실시간 세션 종료
Drfl.disconnect_rt_control();

확인
RT 제어가 시작되고 로봇이 실시간 운전 모드로 전환됩니다. disconnect_rt_control()은 실시간 세션을 종료하고 컨트롤러를 일반 운전으로 되돌립니다.

RT 데이터 모니터링

목적
실시간 조인트 위치, 속도, 토크 데이터에 접근하고 기록합니다.

void OnRTMonitoringData(LPRT_OUTPUT_DATA_LIST tData) {
    static int count = 0;
    if (++count % 500 == 0) {
        printf("timestamp: %.3f\n", tData->time_stamp);
        printf("q = %.4f %.4f %.4f %.4f %.4f %.4f\n",
            tData->actual_joint_position[0], tData->actual_joint_position[1],
            tData->actual_joint_position[2], tData->actual_joint_position[3],
            tData->actual_joint_position[4], tData->actual_joint_position[5]);
        printf("q_dot = %.4f %.4f %.4f %.4f %.4f %.4f\n",
            tData->actual_joint_velocity[0], tData->actual_joint_velocity[1],
            tData->actual_joint_velocity[2], tData->actual_joint_velocity[3],
            tData->actual_joint_velocity[4], tData->actual_joint_velocity[5]);
    }
}

// 콜백 함수 등록
Drfl.set_on_rt_monitoring_data(OnRTMonitoringData);

확인
RT 콜백이 1 ms 간격으로 조인트 위치, 속도, 토크 데이터를 계속 출력합니다.

속도 / 가속도 한계(확장)

목적
실시간 명령이 사용하는 조인트 및 작업 공간 속도와 가속도 값을 설정합니다.

float vel[6] = {0.2, 0.0, 0.0, 0.0, 0.0, 0.0};
float acc[6] = {0.5, 0.5, 0.5, 0.5, 0.5, 0.5};

// start_rt_control() 이후에 호출하세요. 그 전에 보낸 값은 무시됩니다
// 실시간으로 조인트 속도와 가속도 설정
Drfl.set_velj_rt(vel);
Drfl.set_accj_rt(acc);

// 선택 사항: 직교 좌표 공간 속도 제어
Drfl.set_velx_rt(0.2f, 0.2f);
Drfl.set_accx_rt(0.5f, 0.5f);

확인
컨트롤러는 RT 제어가 시작된 동안에만 각 값을 사용하며, 각 값의 용도는 해당 페이지에 설명되어 있습니다: set_velj_rt, set_accj_rt, set_velx_rt, set_accx_rt. set_velj_rt와 set_accj_rt는 servoj_rt 궤적(Trajectory)을 제한하지 않습니다. 조인트 속도를 제한하려면 안전 설정의 조인트 속도 한계를 사용하세요.

통합 안전 처리

목적
장시간 안정적으로 운전할 수 있도록 RT 제어를 안전 정지 및 재연결 로직과 통합합니다.

std::atomic<bool> g_bDisconnected(false);

void OnDisconnected() {
    // 이벤트만 기록하고, 재연결은 콜백 함수 밖에서 합니다
    printf("[TCP] Disconnected from controller.\n");
    g_bDisconnected = true;
}

std::atomic<int> g_nRecoverState(-1);

void OnMonitoringStateCB(const ROBOT_STATE eState) {
    // 상태만 기록하고, 복구는 콜백 함수 밖에서 합니다
    if (eState == STATE_SAFE_STOP || eState == STATE_SAFE_OFF)
        g_nRecoverState = (int)eState;
}

// 메인 루프 이전
Drfl.set_on_disconnected(OnDisconnected);
Drfl.set_on_monitoring_state(OnMonitoringStateCB);

// 메인 루프 내부
if (g_bDisconnected.exchange(false)) {
    printf("[TCP] Reconnecting...\n");
    while (!Drfl.open_connection("192.168.137.100"))
        std::this_thread::sleep_for(std::chrono::seconds(1));
    // 연결 해제 콜백 함수를 제외한 콜백 함수는 다시 등록해야 합니다
    Drfl.set_on_monitoring_state(OnMonitoringStateCB);
}

int nState = g_nRecoverState.exchange(-1);
if (nState == STATE_SAFE_STOP || nState == STATE_SAFE_OFF) {
    Drfl.stop_rt_control();
    if (nState == STATE_SAFE_STOP)
        Drfl.set_robot_control(CONTROL_RESET_SAFE_STOP);
    else
        Drfl.set_robot_control(CONTROL_SERVO_ON);
    Drfl.start_rt_control();
}

확인
연결이 끊기면 open_connection()이 컨트롤러 연결을 복구합니다. 실시간 세션을 다시 설정하려면 애플리케이션을 재시작해야 합니다. open_connection과 set_robot_control은 콜백 밖에서 호출하세요. 콜백 함수 규칙을 참고하세요.

참고

  • 실시간 제어를 사용하려면 네트워크가 안정적이어야 하고, UDP 기반 RT API를 지원하는 컨트롤러 버전이 필요합니다.

  • RT 모드를 실행하기 전에 반드시 6.2 기본 튜토리얼로 연결을 확인하고 6.3 고급 튜토리얼의 복구 로직을 확인해야 합니다.