TRON 2 DOCS
产品文档/TRON 2/SDK · 底层运动控制
TRON 2 · 使用与开发

底层 · C++ 接口

全形态适用

2 底层运动控制接口

跨平台底层运动控制开发接口库提供统一的C++/Python API,兼容ROS1、ROS2及非ROS系统,实现运动控制算法的快速移植与部署。

2.1 C++ 运动控制开发接口

2.1.1 概述

底层运动控制开发接口通过硬件抽象层和标准化通信协议,开发者可无缝切换仿真与真实硬件环境,显著降低多平台适配成本。

2.1.2 安装运动控制开发库

  • Linux x86_64 环境
git clone https://github.com/limxdynamics/limxsdk-lowlevel.git
pip install limxsdk-lowlevel/python3/amd64/limxsdk-*-py3-none-any.whl
  • Linux aarch64 环境
  git clone https://github.com/limxdynamics/limxsdk-lowlevel.git
  pip install limxsdk-lowlevel/python3/aarch64/limxsdk-*-py3-none-any.whl

  • Windows 环境
git clone https://github.com/limxdynamics/limxsdk-lowlevel.git
pip install limxsdk-lowlevel/python3/win/limxsdk-*-py3-none-any.whl

2.1.3 getInstance 接口介绍

项目内容
函数名getInstance
函数原型static Tron2* getInstance();
功能概述获取 Tron2 机器人类单例实例的指针
参数无
返回值Tron2*,指向 Tron2 实例的指针
备注使用了单例模式,确保 Tron2 类只有一个实例存在于程序中

代码示例:

#include <thread>

// 包含 limxsdk::Tron2 头文件,用于引入 Tron2 类
#include "limxsdk/tron2.h"

// 使用 limxsdk 命名空间
using namespace limxsdk;

int main(int argc, char *argv[]){
    // 获取 Tron2 类的单例实例
    Tron2* robot = Tron2::getInstance();

    // 无限循环以保持程序运行
    while (true)
    {
        // 休眠 1000 毫秒
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }

    return 0;
}

2.1.4 init 接口介绍

项目内容
函数名init
函数原型bool init(const std::string& robot_ip_address = "127.0.0.1");
功能概述初始化lowlevel-sdk的通信运行环境,在主函数中调用其它接口之前调用,完成初始化工作。
参数robot_ip_address:机器人的 IP 地址。对于仿真,通常设置为 "127.0.0.1",而对于真实机器人,设置为 "10.192.1.2"。
返回值如果初始化成功,则返回 true;否则返回 false。
备注无

代码示例:

#include <thread>

// 包含 limxsdk::Tron2 头文件,用于引入 Tron2 类
#include "limxsdk/tron2.h"

// 使用 limxsdk 命名空间,简化对 Tron2 类的引用
using namespace limxsdk;

int main(int argc, char *argv[]){
    // 获取 Tron2 类的单例实例
    Tron2* robot = Tron2::getInstance();

    // 默认机器人 IP 地址
    std::string robot_ip = "10.192.1.2";

    if (argc > 1)
    {
        // 如果提供了命令行参数,则使用命令行参数作为机器人 IP 地址
        robot_ip = argv[1];
    }

    // 初始化运动控制算法程序的通信运行环境
    if (!robot->init(robot_ip))
    {
        // 如果初始化失败,则退出程序
        exit(1);
    }

    // 无限循环以保持程序运行
    while (true)
    {
        // 休眠 1000 毫秒
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }

    return 0;
}

2.1.5 getMotorNumber 接口介绍

项目内容
函数名getMotorNumber
函数原型uint32_t getMotorNumber();
功能概述获取机器人的电机数量。
参数无
返回值返回一个无符号整数,表示机器人中的总电机数量。
备注例如,双轮足形态下的电机数量为 10 个。

代码示例:

#include <thread>

// 包含 limxsdk::Tron2 头文件,用于引入 Tron2 类
#include "limxsdk/tron2.h"

// 使用 limxsdk 命名空间,简化对 Tron2 类的引用
using namespace limxsdk;

int main(int argc, char *argv[]){
    // 获取 Tron2 类的单例实例
    Tron2* robot = Tron2::getInstance();

    // 默认机器人 IP 地址
    std::string robot_ip = "10.192.1.2";

    if (argc > 1)
    {
        // 如果提供了命令行参数,则使用命令行参数作为机器人 IP 地址
        robot_ip = argv[1];
    }

    // 初始化运动控制算法程序的通信运行环境
    if (!robot->init(robot_ip))
    {
        // 如果初始化失败,则退出程序
        exit(1);
    }

    // 获取机器人中的电机数量
    uint32_t motor_num = robot->getMotorNumber();

    // 无限循环以保持程序运行
    while (true)
    {
        // 休眠 1000 毫秒
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }

    return 0;
}

2.1.6 subscribeImuData 接口介绍

项目内容
函数名subscribeImuData
函数原型void subscribeImuData(std::function<void(const ImuDataConstPtr&)> cb);
功能概述订阅机器人的 IMU 数据,并在接收到新的 IMU 数据时调用指定的回调函数。
参数cb:用于处理新 IMU 数据的回调函数。
返回值无

备注:
ImuData 数据结构原型如下:


/**
 * @struct ImuData
 *
 * @brief 表示基于传感器反馈的机器人 IMU 数据的结构体。
 *
 * 此结构体封装了 IMU 数据,包括加速度计、陀螺仪和四元数。
 */
struct ImuData {
  uint64_t stamp; // 时间戳,以纳秒为单位,表示记录此数据时的时间。
  float acc[3];   // 用于存储 IMU 加速度计数据,采集沿三个轴(X、Y、Z)的线性加速度。
  float gyro[3];  // 用于存储 IMU 陀螺仪数据,采集沿三个轴(X、Y、Z)的角速度。
  float quat[4];  // 用于存储 IMU 四元数数据,使用四元数表示在三维空间中的方向(w、x、y、z)。
};

// 智能指针类型别名
typedef std::shared_ptr<ImuData> ImuDataPtr;
typedef std::shared_ptr<ImuData const> ImuDataConstPtr;

代码示例:

#include <thread>

// 包含 limxsdk::Tron2 头文件,用于引入 Tron2 类
#include "limxsdk/tron2.h"

// 使用 limxsdk 命名空间,简化对 Tron2 类的引用
using namespace limxsdk;

int main(int argc, char *argv[]){
    // 获取 Tron2 类的单例实例
    Tron2* robot = Tron2::getInstance();

    // 默认机器人 IP 地址
    std::string robot_ip = "10.192.1.2";

    if (argc > 1)
    {
        // 如果提供了命令行参数,则使用命令行参数作为机器人 IP 地址
        robot_ip = argv[1];
    }

    // 初始化运动控制算法程序的通信运行环境
    if (!robot->init(robot_ip))
    {
        // 如果初始化失败,则退出程序
        exit(1);
    }

    // 订阅机器人 IMU 数据,并指定回调函数
    robot->subscribeImuData([](const ImuDataConstPtr& msg) {
        // 在这里处理接收到的 IMU 数据
        // 例如:可以进行姿态结算等工作
    });

    // 无限循环以保持程序运行
    while (true)
    {
        // 休眠 1000 毫秒
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }

    return 0;
}

2.1.7 subscribeRobotState 接口介绍

项目内容
函数名subscribeRobotState
函数原型void subscribeRobotState(std::function<void(const RobotStateConstPtr&)> cb);
功能概述订阅并接收关于机器人状态的更新。
参数cb:回调函数,当接收到机器人状态更新时将被调用。回调函数参数指向 RobotState 对象的常量指针。
返回值无

备注
RobotState 数据结构原型如下:

/**
 * @struct RobotState
 *
 * @brief 代表基于传感器反馈的机器人状态的结构体。
 *
 * 此结构封装了各种数据点,可用于监控和控制机器人,包括 IMU 数据(加速度计、陀螺仪、四元数)、输出扭矩、当前角度和速度等。
 */
struct RobotState {
  // 默认构造函数
  RobotState() { } 
  // 带参数的构造函数,用于初始化向量大小为 motor_num 的 tau、q、dq 向量,初始值均为 0.0
  RobotState(int motor_num)
  : tau(motor_num, 0.0)
  , q(motor_num, 0.0)
  , dq(motor_num, 0.0) { }
  uint64_t stamp;              // 时间戳,通常表示记录或生成这些数据的时间,以纳秒为单位
  std::vector<float> tau;      // 用于存储当前估计的输出扭矩(以牛顿米为单位)的向量
  std::vector<float> q;        // 用于存储当前角度(以弧度为单位)的向量
  std::vector<float> dq;       // 用于存储当前速度(以弧度每秒为单位)的向量
};

// 智能指针类型别名
typedef std::shared_ptr<RobotState> RobotStatePtr;
typedef std::shared_ptr<RobotState const> RobotStateConstPtr;

代码示例:

#include <thread>

// 包含 limxsdk::Tron2 头文件,用于引入 Tron2 类
#include "limxsdk/tron2.h"

// 使用 limxsdk 命名空间,简化对 Tron2 类的引用
using namespace limxsdk;

int main(int argc, char *argv[]){
    // 获取 Tron2 类的单例实例
    Tron2* robot = Tron2::getInstance();

    // 默认机器人 IP 地址
    std::string robot_ip = "10.192.1.2";

    if (argc > 1)
    {
        // 如果提供了命令行参数,则使用命令行参数作为机器人 IP 地址
        robot_ip = argv[1];
    }

    // 初始化运动控制算法程序的通信运行环境
    if (!robot->init(robot_ip))
    {
        // 如果初始化失败,则退出程序
        exit(1);
    }

    // 订阅机器人状态更新,并指定回调函数
    robot->subscribeRobotState([](const RobotStateConstPtr& msg) {
        // 在这里处理接收到的 RobotState 数据
        // 例如:读取关节角度、速度、力矩、IMU 等状态信息
    });

    // 无限循环以保持程序运行
    while (true)
    {
        // 休眠 1000 毫秒
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }

    return 0;
}

2.1.8 publishRobotCmd 接口介绍

项目内容
函数名publishRobotCmd
函数原型bool publishRobotCmd(const RobotCmd& cmd);
功能概述发布一个命令来控制机器人的关节。
参数cmd:表示所需机器人命令的 RobotCmd 对象。
返回值无
备注

代码示例:

#include <thread>

// 包含 limxsdk::Tron2 头文件,用于引入 Tron2 类
#include "limxsdk/tron2.h"

// 使用 limxsdk 命名空间,简化对 Tron2 类的引用
using namespace limxsdk;

int main(int argc, char *argv[]){
    // 获取 Tron2 类的单例实例
    Tron2* robot = Tron2::getInstance();

    // 默认机器人 IP 地址
    std::string robot_ip = "10.192.1.2";

    if (argc > 1)
    {
        // 如果提供了命令行参数,则使用命令行参数作为机器人 IP 地址
        robot_ip = argv[1];
    }

    // 初始化运动控制算法程序的通信运行环境
    if (!robot->init(robot_ip))
    {
        // 如果初始化失败,则退出程序
        exit(1);
    }

    // 获取机器人中的电机数量
    uint32_t motor_num = robot->getMotorNumber();

    // 创建一个包含机器人电机数量的 RobotCmd 对象
    RobotCmd cmd(motor_num);

    // 发布控制指令
    robot->publishRobotCmd(cmd);

    // 无限循环以保持程序运行
    while (true)
    {
        // 休眠 1000 毫秒
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }

    return 0;
}

2.1.9 subscribeSensorJoy 接口介绍

项目内容
函数名subscribeSensorJoy
函数原型void subscribeSensorJoy(std::function<void(const SensorJoyConstPtr&)> cb);
功能概述在真机部署中,该方法用于订阅来自机器人遥控器的数据。当机器人接收到遥控器数据时,将会调用指定的回调函数,并传递包含遥控器数据的 SensorJoy 结构体常量指针给回调函数进行处理。
参数cb:表示回调函数,用于接收机器人遥控器的数据。回调函数的参数类型为 SensorJoyConstPtr,即指向 SensorJoy 结构体常量的共享指针。
返回值无
备注

代码示例:

#include <thread>

// 包含 limxsdk::Tron2 头文件,用于引入 Tron2 类
#include "limxsdk/tron2.h"

// 使用 limxsdk 命名空间,简化对 Tron2 类的引用
using namespace limxsdk;

int main(int argc, char *argv[]){
    // 获取 Tron2 类的单例实例
    Tron2* robot = Tron2::getInstance();

    // 默认机器人 IP 地址
    std::string robot_ip = "10.192.1.2";

    if (argc > 1)
    {
        // 如果提供了命令行参数,则使用命令行参数作为机器人 IP 地址
        robot_ip = argv[1];
    }

    // 初始化运动控制算法程序的通信运行环境
    if (!robot->init(robot_ip))
    {
        // 如果初始化失败,则退出程序
        exit(1);
    }

    // 订阅机器人遥控器数据
    robot->subscribeSensorJoy([](const SensorJoyConstPtr& joy) {
        // L1 和 R1 按下
        if (joy->buttons[4] == 1 && joy->buttons[7] == 1)
        {
            // 在这里执行相关操作
        }

        // 处理摇杆数据
        double axes_left_horizontal = joy->axes[0];
        double axes_left_vertical = joy->axes[1];
        double axes_right_horizontal = joy->axes[2];
        double axes_right_vertical = joy->axes[3];
    });

    // 无限循环以保持程序运行
    while (true)
    {
        // 休眠 1000 毫秒
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }

    return 0;
}

2.1.10 subscribeDiagnosticValue 接口介绍

项目内容
函数名subscribeDiagnosticValue
函数原型void subscribeDiagnosticValue(std::function<void(const DiagnosticValueConstPtr&)> cb);
功能概述在真机部署中,该方法用于订阅机器人的诊断值和状态信息。当机器人发出诊断值时,系统会调用指定的回调函数,并传递包含诊断值的 DiagnosticValue 结构体常量指针给回调函数进行处理。这可以帮助实时监控机器人的健康状态,并及时做出反应以处理可能的问题。
参数cb:用于接收机器人诊断值的回调函数,其参数类型为 DiagnosticValueConstPtr,即指向 DiagnosticValue 结构体常量的共享指针。DiagnosticValue 结构体包含机器人诊断值的信息,包括时间戳、级别、名称、代码和消息字段。
返回值无
备注

代码示例:

#include <thread>
#include <iostream>

// 包含 limxsdk::Tron2 头文件,用于引入 Tron2 类
#include "limxsdk/tron2.h"

// 使用 limxsdk 命名空间,简化对 Tron2 类的引用
using namespace limxsdk;

int main(int argc, char *argv[]){
    // 获取 Tron2 类的单例实例
    Tron2* robot = Tron2::getInstance();

    // 默认机器人 IP 地址
    std::string robot_ip = "10.192.1.2";

    if (argc > 1)
    {
        // 如果提供了命令行参数,则使用命令行参数作为机器人 IP 地址
        robot_ip = argv[1];
    }

    // 初始化运动控制算法程序的通信运行环境
    if (!robot->init(robot_ip))
    {
        // 如果初始化失败,则退出程序
        exit(1);
    }

    // 订阅机器人诊断数据
    robot->subscribeDiagnosticValue([](const DiagnosticValueConstPtr& msg) {
        // 在这里处理机器人诊断值
        // 例如,可以根据诊断级别和消息内容进行打印或处理

        std::cout << "Diagnostic Value: " << msg->name << std::endl;
        std::cout << "Level: " << msg->level << std::endl;
        std::cout << "Code: " << msg->code << std::endl;
        std::cout << "Message: " << msg->message << std::endl;
    });

    // 无限循环以保持程序运行
    while (true)
    {
        // 休眠 1000 毫秒
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }

    return 0;
}

2.1.11 setRobotLightEffect 接口介绍

项目内容
函数名setRobotLightEffect
函数原型bool setRobotLightEffect(int effect);
功能概述在真机部署中,该方法用于设置机器人的灯光效果。
参数effect:一个整数,表示所需的机器人灯光效果,具体定义见 Tron2::LightEffect 枚举。
返回值bool:指示机器人灯光效果是否成功设置。

备注 - 灯光效果枚举说明:

enum LightEffect : int {
    STATIC_RED = 0,        // 静态红光
    STATIC_GREEN,          // 静态绿光
    STATIC_BLUE,           // 静态蓝光
    STATIC_CYAN,           // 静态青光
    STATIC_PURPLE,         // 静态紫光
    STATIC_YELLOW,         // 静态黄光
    STATIC_WHITE,          // 静态白光

    LOW_FLASH_RED,         // 红光闪烁(慢闪)
    LOW_FLASH_GREEN,       // 绿光闪烁(慢闪)
    LOW_FLASH_BLUE,        // 蓝光闪烁(慢闪)
    LOW_FLASH_CYAN,        // 青光闪烁(慢闪)
    LOW_FLASH_PURPLE,      // 紫光闪烁(慢闪)
    LOW_FLASH_YELLOW,      // 黄光闪烁(慢闪)
    LOW_FLASH_WHITE,       // 白光闪烁(慢闪)

    FAST_FLASH_RED,        // 红光闪烁(快闪)
    FAST_FLASH_GREEN,      // 绿光闪烁(快闪)
    FAST_FLASH_BLUE,       // 蓝光闪烁(快闪)
    FAST_FLASH_CYAN,       // 青光闪烁(快闪)
    FAST_FLASH_PURPLE,     // 紫光闪烁(快闪)
    FAST_FLASH_YELLOW,     // 黄光闪烁(快闪)
    FAST_FLASH_WHITE       // 白光闪烁(快闪)
};

代码示例:

#include <thread>

// 包含 limxsdk::Tron2 头文件,用于引入 Tron2 类
#include "limxsdk/tron2.h"

// 使用 limxsdk 命名空间,简化对 Tron2 类的引用
using namespace limxsdk;

int main(int argc, char *argv[]){
    // 获取 Tron2 类的单例实例
    Tron2* robot = Tron2::getInstance();

    // 默认机器人 IP 地址
    std::string robot_ip = "10.192.1.2";

    if (argc > 1)
    {
        // 如果提供了命令行参数,则使用命令行参数作为机器人 IP 地址
        robot_ip = argv[1];
    }

    // 初始化运动控制算法程序的通信运行环境
    if (!robot->init(robot_ip))
    {
        // 如果初始化失败,则退出程序
        exit(1);
    }

    // 设置机器人灯光效果为静态红光
    robot->setRobotLightEffect(limxsdk::Tron2::STATIC_RED);

    // 无限循环以保持程序运行
    while (true)
    {
        // 休眠 1000 毫秒
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }

    return 0;
}
继续阅读底层 · Python 接口