이전 버전(1.33.4)의 문서를 보고 있습니다. 이 버전은 계속 지원됩니다.
최신 버전 정보는 1.33.5에서 확인하세요.

6.6.1 minimal_motion_sample.cpp

이 예제(1_minimal_motion_sample.cpp)는 API로 로봇을 안전하게 움직이는 데 필요한 최소 절차를 보여 줍니다.

  • 컨트롤러에 연결하고,

  • 제어권(Control Authority)을 얻고(GRANT),

  • 로봇 상태가 STANDBY가 될 때까지 기다리고,

  • 시스템과 모드를 설정한 다음,

  • movej로 짧은 조인트 모션을 실행합니다.

이 예제의 경로는 다음과 같습니다.
API-DRFL/example/Linux_64/1_minimal_motion_sample.cpp.

예제는 다음에서 확인하세요. Doosan Robotics API-DRFL GitHub

전체 설명 영상은 다음에서 확인하세요. Doosan Robotics Official YouTube

설정 및 연결

  • DRCF_VERSION은 컨트롤러가 사용하는 통신 프로토콜 버전을 선택합니다. 샘플은 첫 줄에서 DRCF_VERSION을 2로 정의합니다. 이 줄을 컨트롤러에 맞게 수정하거나, 이 줄을 지우고 컴파일러에 -DDRCF_VERSION=2 또는 -DDRCF_VERSION=3을 전달하세요. 이 줄이 있으면 컴파일러 옵션보다 우선합니다.

  • IP_ADDRESS는 로컬 에뮬레이터(DART Platform / 가상 컨트롤러)를 가정해 127.0.0.1로 설정되어 있습니다.

  • 실제 로봇 컨트롤러를 사용할 때는 실제 컨트롤러 IP를 설정하세요.

  • get_control_access와 is_standby는 콜백이 갱신하는 전역 플래그입니다.

#define DRCF_VERSION 2 // DRCF 버전에 따라 2 또는 3으로 설정합니다.
// ...
const std::string IP_ADDRESS = "127.0.0.1";
CDRFLEx robot; // API 호출용 인스턴스

bool get_control_access = false; // 제어권 확인용 변수
bool is_standby = false; // 로봇 상태가 대기 상태인지 확인하는 변수입니다.

도우미 함수 to_str(MONITORING_ACCESS_CONTROL)과 to_str(ROBOT_STATE)는 로그 기록을 위해 열거형 값을 사람이 읽을 수 있는 문자열로 변환합니다.

std::string to_str(const MONITORING_ACCESS_CONTROL x);
std::string to_str(const ROBOT_STATE x);

제어권 및 상태 모니터링

OnMonitroingAccessControlCallback은 제어권(GRANT/LOSS)을 모니터링합니다.

auto OnMonitroingAccessControlCB = [](const MONITORING_ACCESS_CONTROL access) {
    std::cout << "[OnMonitroingAccessControlCB] Control Access : " << to_str(access) << std::endl;
    if(MONITORING_ACCESS_CONTROL_GRANT == access) {
        get_control_access = true;
        std::cout << "Got Control Access !! " << std::endl;
    }
    if(MONITORING_ACCESS_CONTROL_LOSS == access) {
        get_control_access = false;
    }
};
robot.set_on_monitoring_access_control(OnMonitroingAccessControlCB);

OnMonitoringStateCallback은 로봇 상태를 모니터링합니다. 이 콜백은 로봇 상태가 바뀔 때마다(예: STATE_SAFE_OFF, STATE_STANDBY, STATE_MOVING) 호출됩니다.

auto OnMonitoringStateCB = [] (const ROBOT_STATE state) {
    std::cout << "[OnMonitoringStateCB] Robot State : " << to_str(state) << std::endl;
    if(STATE_STANDBY == state) {
        is_standby = true;
        std::cout << "Successfully Servo on !! " << std::endl;
    }else {
        is_standby = false;
    }
};
robot.set_on_monitoring_state(OnMonitoringStateCB);

프로그램을 실행할 때 콘솔 출력을 보면 콜백이 올바르게 설정되었는지 확인할 수 있습니다.

[OnMonitoringStateCB] Robot State : STATE_SAFE_OFF
[OnMonitoringStateCB] Robot State : STATE_STANDBY
Successfully Servo on !!
[OnMonitoringStateCB] Robot State : STATE_MOVING
[OnMonitoringStateCB] Robot State : STATE_STANDBY

연결 및 버전 정보

콜백을 등록한 뒤 샘플은 연결을 열고 컨트롤러 버전 정보를 출력합니다.

  • 다른 API를 사용하려면 먼저 open_connection이 성공해야 합니다.

  • setup_monitoring_version(1)은 더 이상 사용되지 않는 콜백을 쓰지 않도록 새 모니터링 컨텍스트를 선택합니다.

  • get_system_version으로 연결된 DRCF 빌드를 확인합니다.

// DRCF 컨트롤러에 연결합니다.
bool ret = robot.open_connection(IP_ADDRESS);
std::cout << "open connection return value " << ret << std::endl;
if (true != ret) {
    std::cout << "Cannot open connection to robot @ " << IP_ADDRESS
                << std::endl;
    return 1;
}

// 이 함수는 "호환성"을 위한 것입니다.
// 예: DRCF v2에서는 'set_on_monitoring_ctrl_io'가 호출되지만, 이 함수는 더 이상 사용되지 않습니다.
// 일반적으로 최신 방식을 사용하도록 '1'로 설정하세요.
robot.setup_monitoring_version(1);

SYSTEM_VERSION tSysVerion = {
    '\0',
};
robot.get_system_version(&tSysVerion);
cout << "Controller (DRCF) version: " << tSysVerion._szController << endl;
cout << "Library version: " << robot.get_library_version() << endl; // 예: GLXXXXXX

프로그램을 실행할 때 콘솔 출력을 보면 연결과 버전 정보를 확인할 수 있습니다.

open connection return value 1
Controller (DRCF) version: GF03020000
Library version: GL013300

제어권 및 STANDBY

이 루프는 다음 작업을 최대 10번(반복 사이에 1초 지연) 시도합니다.

  • get_control_access가 true가 될 때까지 ManageAccessControl(MANAGE_ACCESS_CONTROL_FORCE_REQUEST)로 제어권을 요청합니다.

  • is_standby가 true가 될 때까지 set_robot_control(CONTROL_SERVO_ON)으로 서보 온 상태로 전환합니다.

// "제어권 획득"과 "대기(stand_by)" 상태를 확인합니다.
// 즉, "모션 준비"가 완료된 상태입니다.
for (size_t retry = 0; retry < 10; ++retry, std::this_thread::sleep_for(std::chrono::milliseconds(1000))) {
    if(!get_control_access) {
            robot.ManageAccessControl(MANAGE_ACCESS_CONTROL_FORCE_REQUEST);
            continue;
    }
    if(!is_standby) {
            robot.set_robot_control(CONTROL_SERVO_ON);
            continue;
    }
    if(get_control_access && is_standby)   break;
}


if(!(get_control_access && is_standby)) {
    std::cout << "Failed Setting intended states" << std::endl;
    return 1;
}

10번 재시도하는 동안 두 상태에 모두 도달하지 못하면 프로그램이 오류 메시지를 출력하고 종료합니다.

로봇 모드 설정

로봇이 제어권을 얻고 STANDBY 상태가 되면 시스템과 모드를 설정합니다.

if(!robot.set_robot_system(ROBOT_SYSTEM_VIRTUAL)) {
    return 1;
}


// API에서는 보통 'ROBOT_MODE_MANUAL' 또는 'ROBOT_MODE_AUTONOMOUS'로 설정합니다.
// 일반적으로 로봇 설정을 변경하기 전에는 'ROBOT_MODE_MANUAL'을 지정하고,
// 모션 전에는 'ROBOT_MODE_AUTONOMOUS'를 지정해야 합니다.
// 이 예제에서는 로봇을 움직이므로 'ROBOT_MODE_AUTONOMOUS'로 설정합니다.
if(!robot.set_robot_mode(ROBOT_MODE_AUTONOMOUS)) {
    return 1;
}

샘플은 가상 로봇에서 실행됩니다. 실제 로봇에서는 ROBOT_SYSTEM_VIRTUAL을 ROBOT_SYSTEM_REAL로 바꾸세요.

모션 명령은 ROBOT_MODE_MANUAL에서도 수동 모드의 감속된 속도로 실행됩니다. 최대 속도로 모션을 실행하고 자동 모드 전용 함수(servoj, servol, servoj_g, servol_g, speedj, speedl, drl_start, drl_resume, change_operation_speed, 상태 LED 함수)를 사용하려면 set_robot_mode()로 ROBOT_MODE_AUTONOMOUS를 설정하세요.

모션 실행

모든 준비가 끝나면 프로그램은 사용자 입력을 기다린 뒤 간단한 모션을 실행합니다.

std::cout << "Press Enter to continue..." ;
std::cin.get();  // 사용자가 Enter를 누를 때까지 대기

float targetPos[6] = {0.,0.,30.,0.,0.,0.};
float targetVel = 50;
float targetAcc = 50;
robot.movej(targetPos, targetVel, targetAcc);

targetPos[2] = 0;
robot.movej(targetPos, targetVel, targetAcc);


robot.close_connection();
return 0;

모션 순서는 다음과 같습니다.
사용자가 Enter를 누를 때까지 대기 -> 6개 조인트를 모두 절대 조인트 위치 (0, 0, 30, 0, 0, 0) deg로 이동 -> 3번 조인트를 0°로 되돌림 -> 컨트롤러 연결 닫기

프로그램을 실행할 때 콘솔 출력을 보면 상태 콜백을 확인할 수 있습니다.

[OnMonitoringStateCB] Robot State : STATE_MOVING
[OnMonitoringStateCB] Robot State : STATE_STANDBY
Successfully Servo on !!

이 로그를 보면 모션이 올바르게 시작되었고(MOVING), 모션 후 로봇이 안전하게 STANDBY로 돌아왔음을 알 수 있습니다.