For information on the latest version, please have a look at 1.33.5.
6.6.1 minimal_motion_sample.cpp
This example (1_minimal_motion_sample.cpp) demonstrates the minimal procedure required to ensure safe robot movement using the API:
connect to the controller,
acquire control authority (GRANT),
wait until the robot state becomes STANDBY,
configure the system/mode,
and then execute a short joint motion using
movej.
This example is located in the following path:
API-DRFL/example/Linux_64/1_minimal_motion_sample.cpp.
See the example on the Doosan Robotics API-DRFL GitHub.
Watch the full walk-through on the Doosan Robotics Official YouTube.
Setup & Connection
DRCF_VERSIONselects the communication protocol version used by the controller. The sample definesDRCF_VERSIONas 2 on its first line. Edit that line to match the controller, or delete it and pass-DDRCF_VERSION=2or-DDRCF_VERSION=3to the compiler; while the line is present, it overrides the compiler option.IP_ADDRESSis set to127.0.0.1, assuming a local emulator (DART Platform / virtual controller).For a real robot controller, set the actual controller IP.
get_control_accessandis_standbyare global flags that the callbacks will update.
#define DRCF_VERSION 2 // Set 2 or 3 according to drcf version.
// ...
const std::string IP_ADDRESS = "127.0.0.1";
CDRFLEx robot; // Instance for APIs
bool get_control_access = false; // Variable to check control authority
bool is_standby = false; // Variable to check whether the robot state is standby.
The helper functions to_str(MONITORING_ACCESS_CONTROL) and to_str(ROBOT_STATE) convert enum values into human-readable strings for logging:
std::string to_str(const MONITORING_ACCESS_CONTROL x);
std::string to_str(const ROBOT_STATE x);
Access Control & State Monitoring
The OnMonitroingAccessControlCallback monitors for control authority (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);
The OnMonitoringStateCallback monitors for robot state.
This callback is invoked whenever the robot state changes (for example,
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);
You can confirm that the callbacks are set correctly by checking the console output when the program runs.
[OnMonitoringStateCB] Robot State : STATE_SAFE_OFF
[OnMonitoringStateCB] Robot State : STATE_STANDBY
Successfully Servo on !!
[OnMonitoringStateCB] Robot State : STATE_MOVING
[OnMonitoringStateCB] Robot State : STATE_STANDBY
Connection & Version Information
After registering callbacks, the sample opens the connection and prints controller version info.
open_connectionmust succeed before any other API can be used.setup_monitoring_version(1)selects the newer monitoring context to avoid using deprecated callbacks.get_system_versionconfirms which DRCF build you are connected to.
// Connect to the drcf cotnroller.
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;
}
// This function is for "compatibilty".
// e.g. In v2 drcf, 'set_on_monitoring_ctrl_io' will be invoked but which is depreciated.
// Generally, please set '1' to being in the newer context.
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
You can confirm the connection and version information by checking the console output when the program runs.
open connection return value 1
Controller (DRCF) version: GF03020000
Library version: GL013300
Access Control & STANDBY
This loop attempts up to 10 times (with a 1-second delay between iterations) to:
Request control authority using
ManageAccessControl(MANAGE_ACCESS_CONTROL_FORCE_REQUEST)untilget_control_accessbecomestrue.Turn Servo On with
set_robot_control(CONTROL_SERVO_ON)untilis_standbybecomestrue.
// We will make sure "getting control access" and "stand_by" state.
// This means, being done of "ready to movement".
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;
}
If the robot fails to reach both states within 10 retries, the program exits with an error message.
Robot Mode Configuration
Once the robot has control authority and is in STANDBY, the system and mode are configured:
if(!robot.set_robot_system(ROBOT_SYSTEM_VIRTUAL)) {
return 1;
}
// In API, we typically set 'ROBOT_MODE_MANUAL' or 'ROBOT_MODE_AUTONOMOUS'.
// Generally, user need to specify 'ROBOT_MODE_MANUAL' before setting robot configuration.
// and specify 'ROBOT_MODE_AUTONOMOUS' before movements.
// In thie example, we would like to move the robot. set 'ROBOT_MODE_AUTONOMOUS'.
if(!robot.set_robot_mode(ROBOT_MODE_AUTONOMOUS)) {
return 1;
}
The sample runs on the virtual robot. For a real robot, change ROBOT_SYSTEM_VIRTUAL to ROBOT_SYSTEM_REAL.
Motion commands also run in ROBOT_MODE_MANUAL, at the reduced Manual speed. Set ROBOT_MODE_AUTONOMOUS with set_robot_mode() to run motion at full speed and to use the Auto-only functions (servoj, servol, servoj_g, servol_g, speedj, speedl, drl_start, drl_resume, change_operation_speed and the state LED functions).
Motion Execution
If everything is ready, the program waits for user input and then performs a simple motion.
std::cout << "Press Enter to continue..." ;
std::cin.get(); // Waits for user to press 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;
The motion sequence is:
Wait for the user to press Enter -> Move all six joints to the absolute joint position (0, 0, 30, 0, 0, 0) deg -> Move joint 3 back to 0° -> Close the controller connection.
You can confirm the state callback by checking the console output when the program runs.
[OnMonitoringStateCB] Robot State : STATE_MOVING
[OnMonitoringStateCB] Robot State : STATE_STANDBY
Successfully Servo on !!
These logs confirm that motion started correctly (MOVING), and the robot safely returned to STANDBY after motion.