6.6.3 send_drl_script_sample.cpp
이 예제(3_send_drl_script_sample.cpp)는 C++ 문자열로 정의한 DRL 스크립트를 보내 실행하고, DRFLEx API로 실행(시작, 일시 정지, 재개, 정지)을 제어하는 방법을 보여 줍니다.
별도의 .drl 파일을 불러오는 대신 스크립트를 코드 안의 문자열로 정의하고 drl_start()로 컨트롤러에 전송합니다.
또한 이 예제는 다음 함수로 DRL 프로그램의 실행 흐름을 제어하는 방법을 보여 줍니다.
drl_start()drl_pause()drl_resume()drl_stop()
이 예제의 경로는 다음과 같습니다.
API-DRFL/example/Linux_64/3_send_drl_script_sample.cpp
예제는 다음에서 확인하세요. Doosan Robotics API-DRFL GitHub
전체 설명 영상은 다음에서 확인하세요. Doosan Robotics Official YouTube
설정 및 연결
DRL 스크립트를 실행하기 전에 프로그램은 컨트롤러에 연결하고, 제어권(GRANT)을 얻고, 로봇 상태가 STANDBY인지 확인해야 합니다.
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; // 로봇 상태가 대기 상태인지 확인하는 변수입니다.
열거형을 읽기 쉬운 문자열로 변환하는 도우미 함수:
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);
프로그램을 실행할 때 콘솔 출력을 보면 콜백이 올바르게 설정되었는지 확인할 수 있습니다. 이 출력은 제어권이 부여되었고 로봇이 한 번 이상 STANDBY에 도달했음을 나타냅니다.
Successfully Servo on !!
Got Control Access !!
Successfully Servo on !!
연결 및 버전 정보
콜백을 등록한 뒤 샘플은 연결을 열고 컨트롤러 버전 정보를 출력합니다.
// 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
제어권 및 STANDBY
다음 루프는 DRL 프로그램을 시작하기 전에 제어권이 GRANT이고 로봇 상태가 STANDBY인지 확인합니다.
// "제어권 획득"과 "대기(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번 재시도하는 동안 두 상태에 모두 도달하지 못하면 프로그램이 오류 메시지를 출력하고 종료합니다.
로봇 모드 설정
DRL 스크립트를 실행하기 전에 로봇은 AUTONOMOUS 모드여야 합니다.
// 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;
}
DRL 실행과 자동 모드 전용 모션 함수에는 AUTONOMOUS 모드가 필요합니다. 그 밖의 모션 명령은 MANUAL 모드에서도 감속된 속도로 실행됩니다. (교시와 설정은 보통 MANUAL 모드에서 합니다.)
DRL 스크립트 정의 및 실행
이 예제는 DRL 스크립트를 문자열 리터럴로 직접 포함합니다.
std::cout << "Press Enter to continue ..." ;
std::cin.get(); // 사용자가 Enter를 누를 때까지 대기
string strDrl =
"\r\n\
loop = 0\r\n\
while loop < 5:\r\n\
movej(posj(0,0,90,0,90,0), vel=60, acc=60)\r\n\
movej(posj(0,0,80,0,90,0), vel=60, acc=60)\r\n\
loop+=1\r\n";
robot.drl_start(ROBOT_SYSTEM_VIRTUAL, strDrl);
DRL 문법은
.drl프로그램을 작성할 때와 같습니다.drl_start()는 스크립트를 전송하고 실행을 시작합니다.이 샘플은 가상 컨트롤러를 대상으로 하므로
ROBOT_SYSTEM_VIRTUAL을 사용합니다.실제 모드에서는
ROBOT_SYSTEM_REAL을 대신 사용하세요.
프로그램 제어(일시 정지 / 재개 / 정지)
DRL 프로그램을 시작한 뒤 예제는 각 제어 동작 전에 사용자 입력을 기다립니다.
std::cout << "Press Enter to pause ..." ;
std::cin.get(); // 사용자가 Enter를 누를 때까지 대기
robot.drl_pause();
std::cout << "Press Enter to resume ..." ;
std::cin.get(); // 사용자가 Enter를 누를 때까지 대기
robot.drl_resume();
std::cout << "Press Enter to stop ..." ;
std::cin.get(); // 사용자가 Enter를 누를 때까지 대기
robot.drl_stop();
robot.close_connection();
return 0;
drl_pause()는 프로그램 실행을 일시 정지합니다.drl_resume()은 일시 정지한 지점부터 프로그램을 계속 실행합니다.drl_stop()은 DRL 프로그램을 완전히 종료합니다.
프로그램을 실행할 때 콘솔 출력을 보면 상태 콜백을 확인할 수 있습니다.
Successfully Servo on !!
open connection return value 1
Controller (DRCF) version: GF03020000
Library version: GL013300
Got Control Access !!
Successfully Servo on !!
Press Enter to continue ...
Press Enter to pause ...
Press Enter to resume ...
Press Enter to stop ...
이 로그를 보면 DRL 스크립트가 올바르게 시작되었고, 사용자가 제어한 일시 정지/재개가 동작했으며, DRL 프로그램이 안전하게 정지했음을 알 수 있습니다.