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로 설정합니다. DRCF v3 컨트롤러에서는 컴파일러에-DDRCF_VERSION=3을 전달하세요.IP_ADDRESS는 로컬 에뮬레이터(DART Platform / 가상 컨트롤러)를 가정해127.0.0.1로 설정되어 있습니다.실제 로봇 컨트롤러를 사용할 때는 실제 컨트롤러 IP를 설정하세요.
get_control_access와is_standby는 콜백이 갱신하는 전역 플래그입니다.
#ifndef DRCF_VERSION
#define DRCF_VERSION 2 // DRCF 버전에 따라 2 또는 3으로 설정하거나, -DDRCF_VERSION=3을 전달합니다.
#endif
// ...
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가 될 때까지manage_access_control(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.manage_access_control(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로 돌아왔음을 알 수 있습니다.