C++使用示例

代码使用示例

1. Modbus Rtu使用示例

C++
#include "cpp/interface/nrc_modbus.h"
#include "cpp/parameter/nrc_interface_parameter.h"

bool test_set_modbus_master_rtu(int id, int slaveId, int port, int baudrate, const std::string& checkBit = "None", int dataBit = 8, int stopBit = 1) {
    if (socket_fd_6001_ <= 0) return false;
    ModbusMasterParameter param;
    param.type = "RTU";
    param.startAddress = true;
    param.RTU.slaveId = slaveId;
    param.RTU.port = port;
    param.RTU.baudrate = baudrate;
    param.RTU.checkBit = checkBit;
    param.RTU.dataBit = dataBit;
    param.RTU.stopBit = stopBit;
    int ret = modbus_set_master_parameter(socket_fd_6001_, id, param);
    CHECK_RET(ret, "设置Modbus RTU主站 ID=" + std::to_string(id));
    return ret == SUCCESS;
}

bool test_open_modbus_master(int id) {
    if (socket_fd_6001_ <= 0) return false;
    int ret = modbus_open_master(socket_fd_6001_, id);
    CHECK_RET(ret, "打开Modbus主站 ID=" + std::to_string(id));
    return ret == SUCCESS;
}

bool test_modbus_write_multiple_registers(int id, int address, const std::vector<int>& data) {
    if (socket_fd_6001_ <= 0) return false;
    if (data.empty()) {
        std::cout << "[提示] 写入的寄存器数据不能为空" << std::endl;
        return false;
    }
    int ret = modbus_write_multiple_holding_registers(socket_fd_6001_, id, address, data);
    if (ret == SUCCESS) {
        std::cout << "[成功] Modbus ID=" << id << " 从地址 " << address
                  << " 开始成功写入 " << data.size() << " 个寄存器值" << std::endl;
        return true;
    } else {
        std::cout << "[失败] Modbus批量写入寄存器失败,错误码: " << ret << std::endl;
        return false;
    }
}

bool test_modbus_read_holding_registers(int id, int address, int quantity, std::vector<int>& out_data) {
    if (socket_fd_6001_ <= 0) return false;
    if (quantity <= 0) {
        std::cout << "[提示] 读取的寄存器数量必须大于0" << std::endl;
        return false;
    }
    out_data.resize(quantity);
    int ret = modbus_read_holding_registers(socket_fd_6001_, id, address, quantity, out_data);
    if (ret == SUCCESS) {
        std::cout << "[成功] Modbus ID=" << id << " 从地址 " << address
                  << " 开始成功读取了 " << quantity << " 个寄存器值" << std::endl;
        return true;
    } else {
        std::cout << "[失败] Modbus读取寄存器失败,错误码: " << ret << std::endl;
        out_data.clear();
        return false;
    }
}

int main() {
    RobotArmTest robot("192.168.1.13", "6001", "7000", 6);
    if (!robot.connect()) {
        std::cerr << "连接失败,程序退出" << std::endl;
        return -1;
    }

    // 步骤1:正在配置机械臂底层Modbus RTU串口参数
    bool config_ok = robot.test_set_modbus_master_rtu(arm_master_id, 2, 2, 115200, "None", 8, 1);
    if (config_ok) {
        std::cout << "[步骤2] 正在打开Modbus主站通道..." << std::endl;
        if (robot.test_open_modbus_master(arm_master_id)) {
            std::this_thread::sleep_for(std::chrono::seconds(1));
            const int arm_write_address = 1135;
            const std::vector<int> arm_control_data = {0, 0, 50000, 50000, 0};
            std::cout << "[步骤3] 正在向地址 " << arm_write_address << " 下发工具手控制指令..." << std::endl;
            if (robot.test_modbus_write_multiple_registers(arm_master_id, arm_write_address, arm_control_data)) {
                std::this_thread::sleep_for(std::chrono::seconds(1));
                const int arm_read_address = 1155;
                const int arm_quantity = 5;
                std::vector<int> read_result;
                std::cout << "[步骤4] 正在从地址 " << arm_read_address << " 读取反馈状态..." << std::endl;
                if (robot.test_modbus_read_holding_registers(arm_master_id, arm_read_address, arm_quantity, read_result)) {
                    std::cout << "[成功] 工具手当前寄存器状态数据: [ ";
                    for (int val : read_result) std::cout << val << " ";
                    std::cout << "]" << std::endl;
                }
            }
        }
    }
    std::cout << "\n[提示] 流程测试结束,正在断开机器人连接..." << std::endl;
    return 0;
}

2. 关节实时跟踪servoJ使用示例

C++
bool test_open_servoJ(const std::vector<double>& vmax, const std::vector<double>& amax, const std::vector<double>& jmax) {
    if (socket_fd_7000_ <= 0) return false;
    int ret = open_servoJ(socket_fd_7000_, vmax, amax, jmax);
    if (ret == SUCCESS) {
        std::cout << "[成功] 开启7000端口的servoJ关节跟踪模式" << std::endl;
        return true;
    } else {
        std::cout << "[失败] 开启servoJ实时伺服模式失败,错误码: " << ret << std::endl;
        return false;
    }
}

bool test_set_servoJ_pos(const std::vector<double>& q) {
    if (socket_fd_7000_ <= 0) return false;
    int ret = set_servoJ_pos(socket_fd_7000_, q);
    return ret == SUCCESS;
}

bool test_close_servoJ() {
    if (socket_fd_7000_ <= 0) return false;
    int ret = close_servoJ(socket_fd_7000_);
    if (ret == SUCCESS) {
        std::cout << "[成功] 关闭7000端口的servoJ实时伺服模式" << std::endl;
        return true;
    } else {
        std::cout << "[失败] 关闭servoJ实时伺服模式失败,错误码: " << ret << std::endl;
        return false;
    }
}

int main() {
    RobotArmTest robot("192.168.1.13", "6001", "7000", 6);
    if (!robot.connect()) {
        std::cerr << "连接失败,程序退出" << std::endl;
        return -1;
    }

    std::vector<double> max_vel = {60.0, 60.0, 60.0, 60.0, 60.0, 60.0};
    std::vector<double> max_acc = {120.0, 120.0, 120.0, 120.0, 120.0, 120.0};
    std::vector<double> max_jerk = {200.0, 200.0, 200.0, 200.0, 200.0, 200.0};

    if (robot.test_open_servoJ(max_vel, max_acc, max_jerk)) {
        std::cout << "[成功] 进入跟踪模式,开始高频下发轨迹..." << std::endl;
        std::vector<double> current_q = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
        for (int i = 0; i < 250; ++i) {
            current_q[0] += (10.0 / 250.0);
            current_q[1] += (20.0 / 250.0);
            robot.test_set_servoJ_pos(current_q);
            std::this_thread::sleep_for(std::chrono::milliseconds(20));
        }
        std::this_thread::sleep_for(std::chrono::seconds(1));
        robot.test_close_servoJ();
    }
    return 0;
}

3. 关节运动到目标点robot_movej使用示例

C++
bool test_move_joint(const std::vector<double>& angles, int vel = 20, int acc = 50, int dec = 50) {
    if (socket_fd_6001_ <= 0) return false;
    MoveCmd cmd;
    cmd.coord = 0;
    cmd.targetPosValue.resize(7, 0.0);
    for (size_t i = 0; i < angles.size() && i < 6; ++i) cmd.targetPosValue[i] = angles[i];
    cmd.velocity = vel;
    cmd.acc = acc;
    cmd.dec = dec;
    cmd.pl = 0;
    int ret = robot_movej(socket_fd_6001_, cmd);
    CHECK_RET(ret, "实时关节运动");
    return ret == SUCCESS;
}

int main() {
    RobotArmTest robot("192.168.1.13", "6001", "7000", 6);
    if (!robot.connect()) {
        std::cerr << "连接失败,程序退出" << std::endl;
        return -1;
    }
    std::vector<double> angles(6, 0.0);
    angles[0] = 0.0; angles[1] = 0.0;
    robot.test_move_joint(angles, 20);
    std::this_thread::sleep_for(std::chrono::seconds(10));
    return 0;
}

4. 直线运动到目标位置robot_movel使用示例

C++
bool test_move_linear(const std::vector<double>& coords, int vel = 20, int acc = 50, int dec = 50) {
    if (socket_fd_6001_ <= 0) return false;
    MoveCmd cmd;
    cmd.coord = 1;
    cmd.targetPosValue.resize(7, 0.0);
    for (size_t i = 0; i < coords.size() && i < 6; ++i) cmd.targetPosValue[i] = coords[i];
    cmd.velocity = vel;
    cmd.acc = acc;
    cmd.dec = dec;
    cmd.pl = 0;
    int ret = robot_movel(socket_fd_6001_, cmd);
    CHECK_RET(ret, "实时直线运动");
    return ret == SUCCESS;
}

5. 点动使用示例

C++
bool test_start_jogging(int axis, bool dir) {
    if (socket_fd_6001_ <= 0) return false;
    int ret = robot_start_jogging(socket_fd_6001_, axis, dir);
    std::string dir_msg = dir ? "正方向 (+)" : "负方向 (-)";
    CHECK_RET(ret, "启动单轴点动 [轴号: " + std::to_string(axis) + ", 方向: " + dir_msg + "]");
    return ret == SUCCESS;
}

int main() {
    RobotArmTest robot("192.168.1.13", "6001", "7000", 6);
    if (!robot.connect()) {
        std::cerr << "连接失败,程序退出" << std::endl;
        return -1;
    }
    robot.test_start_jogging(4, true);
    std::this_thread::sleep_for(std::chrono::milliseconds(5000));
    return 0;
}

6. 作业文件插入指令使用示例

C++
#include "cpp/interface/nrc_job_operate.h"
#include "cpp/parameter/nrc_interface_parameter.h"

bool test_create_job(const std::string& job_name) {
    if (socket_fd_6001_ <= 0) return false;
    int ret = job_create(socket_fd_6001_, job_name);
    CHECK_RET(ret, "新建作业 " + job_name);
    return ret == SUCCESS;
}

bool test_open_job(const std::string& job_name) {
    if (socket_fd_6001_ <= 0) return false;
    int ret = job_open(socket_fd_6001_, job_name);
    CHECK_RET(ret, "打开作业 " + job_name);
    return ret == SUCCESS;
}

bool test_insert_moveJ(int line, const std::vector<double>& angles, int vel = 20, int acc = 20, int dec = 20, const std::string& pos_name = "P0001") {
    if (socket_fd_6001_ <= 0) return false;
    MoveCmd cmd;
    cmd.targetPosType = PosType::PType;
    cmd.targetPosName = pos_name;
    cmd.coord = 0;
    cmd.velocity = vel;
    cmd.acc = acc;
    cmd.dec = dec;
    cmd.pl = 0;
    cmd.targetPosValue = angles;
    int ret = job_insert_moveJ(socket_fd_6001_, line, cmd);
    CHECK_RET(ret, "在第" + std::to_string(line) + "行插入MoveJ");
    return ret == SUCCESS;
}

bool test_insert_moveL(int line, const std::vector<double>& pos, int vel = 20, int acc = 20, int dec = 20, const std::string& pos_name = "P0002") {
    if (socket_fd_6001_ <= 0) return false;
    MoveCmd cmd;
    cmd.targetPosType = PosType::PType;
    cmd.targetPosName = pos_name;
    cmd.coord = 1;
    cmd.velocity = vel;
    cmd.acc = acc;
    cmd.dec = dec;
    cmd.pl = 0;
    cmd.targetPosValue = pos;
    int ret = job_insert_moveL(socket_fd_6001_, line, cmd);
    CHECK_RET(ret, "在第" + std::to_string(line) + "行插入MoveL");
    return ret == SUCCESS;
}

bool test_insert_moveC(int line, const std::vector<double>& pos, int vel = 20, int acc = 20, int dec = 20, const std::string& pos_name = "P0003") {
    if (socket_fd_6001_ <= 0) return false;
    MoveCmd cmd;
    cmd.targetPosType = PosType::PType;
    cmd.targetPosName = pos_name;
    cmd.coord = 1;
    cmd.velocity = vel;
    cmd.acc = acc;
    cmd.dec = dec;
    cmd.pl = 0;
    cmd.targetPosValue = pos;
    int ret = job_insert_moveC(socket_fd_6001_, line, cmd);
    CHECK_RET(ret, "在第" + std::to_string(line) + "行插入MoveC");
    return ret == SUCCESS;
}

bool test_run_job(const std::string& job_name) {
    if (socket_fd_6001_ <= 0) return false;
    int ret = job_run(socket_fd_6001_, job_name);
    CHECK_RET(ret, "运行作业 " + job_name);
    return ret == SUCCESS;
}

int main() {
    RobotArmTest robot("192.168.1.13", "6001", "7000", 6);
    if (!robot.connect()) {
        std::cerr << "连接失败,程序退出" << std::endl;
        return -1;
    }
    robot.test_create_job("TEST_CPP");
    robot.test_open_job("TEST_CPP");
    std::vector<double> angles(6, 0.0);
    angles[0] = 10.0; angles[1] = 10.0;
    robot.test_insert_moveJ(1, angles, 10);
    std::vector<double> target_pos = {300.0, 100.0, 200.0, 0.0, 0.0, 0.0};
    robot.test_insert_moveL(2, target_pos, 15);
    std::vector<double> target_pos2 = {350.0, 150.0, 250.0, 0.0, 0.0, 0.0};
    robot.test_insert_moveC(1, target_pos2, 20);
    robot.test_run_job("TEST_CPP");
    std::this_thread::sleep_for(std::chrono::seconds(20));
    robot.test_get_all_jobfile_name();
    return 0;
}

7. 队列运动指令使用示例

C++
#include "c/interface/nrc_c_queue_operate.h"

bool test_enable_queue_motion(bool enable) {
    if (socket_fd_6001_ <= 0) return false;
    int ret = queue_motion_set_status_c(socket_fd_6001_, enable);
    CHECK_RET(ret, (enable ? "开启" : "关闭") + std::string("队列运动模式"));
    return ret == 0;
}

bool test_push_moveJ_queue(const std::vector<double>& angles, int vel = 30, int acc = 20, int dec = 20, int coord = 0) {
    if (socket_fd_6001_ <= 0) return false;
    double* arr = new double[angles.size()];
    for (size_t i = 0; i < angles.size(); ++i) arr[i] = angles[i];
    int ret = queue_motion_push_back_moveJ_c(socket_fd_6001_, coord, vel, acc, dec, 0, arr);
    delete[] arr;
    CHECK_RET(ret, "压入队列 MoveJ");
    return ret == 0;
}

bool test_push_moveL_queue(const std::vector<double>& pos, double vel = 30.0, double acc = 20.0, double dec = 20.0, int coord = 0, int pl = 0) {
    if (socket_fd_6001_ <= 0) return false;
    double* arr = new double[pos.size()];
    for (size_t i = 0; i < pos.size(); ++i) arr[i] = pos[i];
    int ret = queue_motion_push_back_moveL_c(socket_fd_6001_, coord, vel, acc, dec, pl, arr);
    delete[] arr;
    CHECK_RET(ret, "压入队列 MoveL");
    return ret == 0;
}

bool test_push_moveC_queue(const std::vector<double>& via_and_end_pos, double vel = 30.0, double acc = 20.0, double dec = 20.0, int coord = 0, int pl = 0) {
    if (socket_fd_6001_ <= 0) return false;
    if (via_and_end_pos.size() < 12) {
        std::cout << "[提示] MoveC圆弧运动需要传入中间点和终点,数据长度不足12位" << std::endl;
        return false;
    }
    double* arr = new double[via_and_end_pos.size()];
    for (size_t i = 0; i < via_and_end_pos.size(); ++i) arr[i] = via_and_end_pos[i];
    int ret = queue_motion_push_back_moveC_c(socket_fd_6001_, coord, vel, acc, dec, pl, arr);
    delete[] arr;
    CHECK_RET(ret, "压入队列 MoveC");
    return ret == 0;
}

bool test_push_moveS_queue(const std::vector<double>& pos, double vel = 30.0, double acc = 20.0, double dec = 20.0, int coord = 0, int pl = 0) {
    if (socket_fd_6001_ <= 0) return false;
    double* arr = new double[pos.size()];
    for (size_t i = 0; i < pos.size(); ++i) arr[i] = pos[i];
    int ret = queue_motion_push_back_moveS_c(socket_fd_6001_, coord, vel, acc, dec, pl, arr);
    delete[] arr;
    CHECK_RET(ret, "压入队列 MoveS");
    return ret == 0;
}

bool test_send_queue(int size, bool isContinue = false) {
    if (socket_fd_6001_ <= 0) return false;
    int ret = queue_motion_send_to_controller_c(socket_fd_6001_, size, isContinue);
    CHECK_RET(ret, "发送队列数据(size=" + std::to_string(size) + ")");
    return ret == 0;
}

int main() {
    RobotArmTest robot("192.168.1.13", "6001", "7000", 6);
    if (!robot.connect()) {
        std::cerr << "连接失败,程序退出" << std::endl;
        return -1;
    }
    robot.test_enable_queue_motion(true);
    std::this_thread::sleep_for(std::chrono::seconds(2));
    std::vector<double> joint_angles0 = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
    std::vector<double> joint_angles1 = {10.0, 10.0, 0.0, 0.0, 0.0, 0.0};
    std::vector<double> target_pos1 = {190.206, 33.536, 268.793, -3.078, 0.342, -0.185};
    std::vector<double> target_pos2 = {300.0, 50.0, 400.0, 180.0, 0.0, 0.0, 350.0, 0.0, 400.0, 180.0, 0.0, 0.0};
    std::vector<double> target_pos3 = {350.0, 50.0, 300.0, 180.0, 0.0, 0.0};
    robot.test_push_moveJ_queue(joint_angles0, 30);
    robot.test_push_moveJ_queue(joint_angles1, 30);
    robot.test_push_moveL_queue(target_pos1, 30);
    robot.test_push_moveC_queue(target_pos2, 30.0);
    robot.test_push_moveS_queue(target_pos3, 30.0);
    robot.test_send_queue(0, false);
    std::this_thread::sleep_for(std::chrono::seconds(20));
    robot.test_enable_queue_motion(false);
    return 0;
}