최신 버전 정보는 1.33.5에서 확인하세요.
6.6.2 minimal_rt_monitoring_sample.cpp
이 예제(2_minimal_rt_monitoring_sample.cpp)는 DRFLEx API를 사용한 최소한의 실시간 모니터링 구성을 보여 줍니다.
connect_rt_control()로 실시간(RT) 모니터링 채널을 열고,set_rt_control_input()으로 RT 세션을 설정하고,RT 모니터링 콜백(
set_on_rt_monitoring_data)을 등록한 다음,간단한 콘솔 입력으로 RT 모니터링을 시작하고 정지합니다.
주의
실시간 모니터링과 제어는 실제 로봇 시스템에서만 지원합니다. 샘플은 IP_ADDRESS를 127.0.0.1로 설정하므로, 실행하기 전에 실제 컨트롤러의 IP 주소(예: 192.168.137.100)로 바꾸세요.
이 예제의 경로는 다음과 같습니다.
API-DRFL/example/Linux_64/2_minimal_rt_monitoring_sample.cpp
예제는 Doosan Robotics API-DRFL GitHub에서 확인하세요.
개요 및 전역 설정
샘플은 먼저 DRCF 프로토콜 버전을 선택하고 전역 DRFLEx 인스턴스를 생성합니다.
샘플은 첫 줄에서 DRCF_VERSION을 2로 정의합니다. 이 줄을 컨트롤러에 맞게 수정하거나, 이 줄을 지우고 컴파일러에 -DDRCF_VERSION=2 또는 -DDRCF_VERSION=3을 전달하세요. 이 줄이 있으면 컴파일러 옵션보다 우선합니다.
#define DRCF_VERSION 2 // DRCF 버전에 따라 2 또는 3으로 설정합니다.
#include "../../include/DRFLEx.h"
#include <cstring>
#include <iostream>
#include <thread>
using namespace DRAFramework;
// ...
const std::string IP_ADDRESS = "127.0.0.1";
CDRFLEx robot; // API 호출용 인스턴스
bool get_control_access = false; // 제어권 확인용 변수
bool is_standby = false; // 로봇 상태가 대기 상태인지 확인하는 변수입니다.
#define GREEN "\033[1;32m"
#define CYAN "\033[1;36m"
DRCF_VERSION: 컨트롤러 펌웨어와 일치해야 합니다(예: 2 또는 3).IP_ADDRESS: 샘플에서는127.0.0.1로 설정되어 있습니다. 실제 컨트롤러의 IP 주소로 바꾸세요.색상 매크로(
GREEN,CYAN)는 터미널에 색이 있는 출력을 표시할 때 사용합니다.
실시간 연결 설정
main 함수는 먼저 실시간 모니터링 연결을 엽니다.
int main(){
// DRCF 컨트롤러에 연결합니다.
bool ret = robot.connect_rt_control(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;
}
// RT 모니터링에는 "제어권 획득"이 필요하지 않습니다.
// 하지만 servoj_rt 같은 RT 쓰기에는 여전히 "제어권"과 "대기 상태"가 필요합니다.
connect_rt_control(IP_ADDRESS)는 컨트롤러와의 UDP 실시간 채널을 엽니다.연결에 실패하면(예: 잘못된 IP, 실제 컨트롤러 없음) 프로그램이 오류를 출력하고 종료합니다.
RT 모니터링만(읽기 전용) 할 때는 제어권(Control Authority)이 필요하지 않습니다.
RT 쓰기(예:
servoj_rt, 토크 명령)에도 제어권은 필요하지 않습니다. 다만 로봇이 STATE_STANDBY 또는 STATE_MOVING 상태여야 합니다. 샘플의 주석에는 RT 쓰기에 제어권이 필요하다고 적혀 있지만, 이는 오래된 내용입니다.
RT 모니터링 콜백
이 예제는 실시간 상태 데이터를 받기 위해 람다 콜백을 등록합니다.
robot.set_on_rt_monitoring_data([](LPRT_OUTPUT_DATA_LIST data)->void{
if (!data) return;
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
printf(GREEN "[%.3f] === Robot State ===\n", ms / 1000.0);
printf(CYAN "Joint Position: ");
for (int i = 0; i < 6; ++i) {
printf("%.3f%s", data->actual_joint_position[i], (i < 5) ? ", " : "\n");
}
printf(CYAN "Joint Velocity: ");
for (int i = 0; i < 6; ++i) {
printf("%.3f%s", data->actual_joint_velocity[i], (i < 5) ? ", " : "\n");
}
printf(CYAN "Joint Torque: ");
for (int i = 0; i < 6; ++i) {
printf("%.3f%s", data->actual_joint_torque[i], (i < 5) ? ", " : "\n");
}
printf(CYAN "Gravity Torque: ");
for (int i = 0; i < 6; ++i) {
printf("%.3f%s", data->gravity_torque[i], (i < 5) ? ", " : "\n");
}
// 행렬 보기 좋게 출력
auto print_matrix = [](const char* name, float mat[6][6]) {
printf(CYAN "%s:\n", name);
for (int i = 0; i < 6; ++i) {
printf(CYAN " [");
for (int j = 0; j < 6; ++j) {
printf(CYAN "%7.3f%s", mat[i][j], (j < 5) ? ", " : "");
}
printf(CYAN "]\n");
}
};
print_matrix(CYAN "Jacobian Matrix", data->jacobian_matrix);
print_matrix(CYAN "Mass Matrix", data->mass_matrix);
print_matrix(CYAN "Coriolis Matrix", data->coriolis_matrix);
});
콜백은 data가 null이면 바로 반환합니다. 그렇지 않으면 로컬 시스템 시계 기준 타임스탬프, 조인트 위치, 조인트 속도, 조인트 토크, 중력 토크, 동역학 행렬(자코비안, 질량, 코리올리)을 출력합니다.
RT 세션 설정 및 시작
콜백을 등록한 뒤 샘플은 set_rt_control_input()으로 RT 세션을 설정하고, Enter를 기다렸다가 start_rt_control()을 호출하고, 다시 Enter를 기다렸다가 disconnect_rt_control()을 호출합니다.
string version = "v1.0";
// float period = 0.002;
float hz = 100.0f;
int losscount = 4;
std::cout << "RT Result " << robot.set_rt_control_input(version, hz, losscount) << std::endl;
std::cout << "Press Enter to continue..." ;
std::cin.get(); // 사용자가 Enter를 누를 때까지 대기
robot.start_rt_control();
std::cout << "Press Enter to terminate..." ;
std::cin.get(); // 사용자가 Enter를 누를 때까지 대기
robot.disconnect_rt_control();
return 0;
RT 출력
RT 세션을 시작하기 전에 프로그램은 set_rt_control_input()을 호출합니다.
string version = "v1.0";
// float period = 0.002;
float hz = 100.0f;
int losscount = 4;
std::cout << "RT Result " << robot.set_rt_control_input(version, hz, losscount) << std::endl;
version = "v1.0": RT 프로토콜 버전을 선택합니다.hz = 100.0f: 통신 주기(초)인fPeriod인수로 전달됩니다.losscount = 4: 허용하는 연속 손실 횟수인nLossCnt인수로 전달됩니다.
매개변수는 set_rt_control_input을 참고하세요. 반환값은 콘솔에 출력됩니다. 반환값은 설정을 보냈다는 것만 알려 줄 뿐, 컨트롤러가 설정을 수락했다는 뜻은 아닙니다.
RT 모니터링 시작 및 정지
이 예제는 간단한 Enter 키 입력으로 RT 모니터링을 시작하고 정지합니다.
std::cout << "Press Enter to continue..." ;
std::cin.get(); // 사용자가 Enter를 누를 때까지 대기
robot.start_rt_control();
std::cout << "Press Enter to terminate..." ;
std::cin.get(); // 사용자가 Enter를 누를 때까지 대기
robot.disconnect_rt_control();
return 0;
첫 번째
Enter뒤에 샘플은start_rt_control()을 호출합니다.두 번째
Enter뒤에는disconnect_rt_control()이 실시간 모니터링 채널을 닫고 프로그램이 종료됩니다.