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_VERSION selects the communication protocol version used by the controller. The sample sets DRCF_VERSION to 2 unless the compiler defines it. For a DRCF v3 controller, pass -DDRCF_VERSION=3 to the compiler.

  • IP_ADDRESS is set to 127.0.0.1, assuming a local emulator (DART Platform / virtual controller).

  • For a real robot controller, set the actual controller IP.

  • get_control_access and is_standby are global flags that the callbacks will update.

#ifndef DRCF_VERSION
#define DRCF_VERSION 2 // Set 2 or 3 according to drcf version, or pass -DDRCF_VERSION=3.
#endif
// ...
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_connection must succeed before any other API can be used.

  • setup_monitoring_version(1) selects the newer monitoring context to avoid using deprecated callbacks.

  • get_system_version confirms 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 manage_access_control(MANAGE_ACCESS_CONTROL_FORCE_REQUEST) until get_control_access becomes true.

  • Turn Servo On with set_robot_control(CONTROL_SERVO_ON) until is_standby becomes true.

// 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.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;
}

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.