callback 的使用

一、简介

在使用SDK操作机器人时,机器人常常会遇到奇异点、碰撞告警等问题,导致运行暂停,这时候,可以使用回调处理这类问题

二、操作流程

1、实例化EliteDriverConfig类,指定robot_ip,以及script_file_path
2、将实例化的EliteDriverConfig对象,作为参数传递给EliteDriver类,实例化driver对象
3、创建异常处理函数,用于处理不同异常时的处理逻辑
4、调用EliteDriver的实例化对象的registerRobotExceptionCallback接口函数,将第三步创建的函数作为参数传递

三、常见问题

1、Q:异常处理逻辑里有哪些type?分别代表什么
A:elite_cs_sdk里有一个类RobotExceptionType,其中定义了三种类型的异常,分别是ROBOT_DISCONNECTED、ROBOT_ERROR、SCRIPT_RUNTIME。
  • ROBOT_DISCONNECTED : 表示与机器人断开了连接
  • ROBOT_ERROR:表示机器人运行错误。
  • SCRIPT_RUNTIME:表示运行时异常,如语法错误、脚本执行错误等。
可以在异常处理函数里,对参数进行getType方法获取异常类型,进行匹配后处理异常
2、Q:如何判断是否是我想要处理的异常呢?
A:异常类有各自的成员变量和成员函数。比如ROBOT_ERROR提供了getErrorCode和getSubErrorCode接口,用来拿到对应的错误码和子错误码,然后查找下方的机器人状态报文手册里异常码章节,找到异常码和子码后,进行匹配和处理。再或者针对SCRIPT_RUNTIME类型,找到运行时异常章节,调用getMessage接口后进行匹配

四、代码和附件

在示例代码里,onRobotException是自定义的异常处理函数,这里分别针对三种异常类型进行了不同处理,
#include <iostream>
#include <memory>
#include <thread>
#include <chrono>
#include <Elite/EliteDriver.hpp>
#include <Elite/DashboardClient.hpp>
#include <Elite/PrimaryPortInterface.hpp>
#include <Elite/DataType.hpp>

using namespace ELITE;

// =============================================================================
// 初始化与连接
// =============================================================================

class CsRobot {
public:
    EliteDriver driver;
    std::string robot_ip;
    std::string local_ip;

    CsRobot(const std::string& ip, const std::string& local_ip)
        : robot_ip(ip), local_ip(local_ip)
    {
        // ---- Dashboard:设置速度缩放、上电、解刹 ----
        std::unique_ptr<DashboardClient> dashboard(new DashboardClient());
        if (!dashboard->connect(robot_ip, 29999)) {
            throw std::runtime_error("Dashboard connect failed");
        }

        int new_scaling = 75;  // 速度缩放 75%
        dashboard->setSpeedScaling(new_scaling);
        dashboard->powerOn();
        dashboard->brakeRelease();

        dashboard->disconnect();

        // ---- EliteDriver:外部控制实时伺服 ----
        EliteDriverConfig config;
        config.robot_ip = robot_ip;
        config.local_ip = local_ip;
        config.script_file_path = "./external_control.script";
        config.headless_mode = true;
        config.reverse_port = 50011;
        config.script_sender_port = 50012;
        config.trajectory_port = 50013;
        config.script_command_port = 50014;
        config.servoj_time = 0.004f;
        config.servoj_gain = 2000;
        config.servoj_lookahead_time = 0.3f;

        driver = EliteDriver(config);

        // 等待连接稳定
        std::this_thread::sleep_for(std::chrono::seconds(1));

        // ---- 注册异常回调 ----
        driver.registerRobotExceptionCallback(
            [this](RobotExceptionSharedPtr ex) -> bool {
                return onRobotException(ex);
            });
    }

    // =============================================================================
    // 异常回调处理(类方法)
    // =============================================================================
private:
    bool onRobotException(RobotExceptionSharedPtr robot_exception)
    {
        RobotExceptionType type = robot_exception->getType();

        if (type == RobotExceptionType::SCRIPT_RUNTIME) {
            std::string msg = robot_exception->getMessage();
            if (msg == "inv_kin_singularity") {
                driver.closeSafetyDialog();
                driver.sendExternalControlScript();
                return true;
            }
        }

        if (type == RobotExceptionType::ROBOT_DISCONNECTED) {
            driver.primaryReconnect();
            return true;
        }

        if (type == RobotExceptionType::Robot_Error) {
            if (robot_exception->getErrorCode() == 12 &&
                robot_exception->getSubErrorCode() == 101) {
                driver.unlockProtectiveStop();
                driver.closeSafetyDialog();
                driver.sendExternalControlScript();
                return true;
            }
        }

        std::cout << "[Callback] 机器人异常, 未处理异常 [type="
            << static_cast<int>(type) << "]" << std::endl;
        return false;
    }

public:
    EliteDriver& getDriver() { return driver; }
};