rtsi 的使用

一、简介

rtsi类跑在 30004 端口,通信频率最高 250Hz,主要用于做实时数据交互+IO 控制具体的接口可以查看 CS机器人 C++ SDK 接口手册 章节,这里提供一个简单的使用案例

二、操作流程

1、跟随快速使用手册安装elite c++ sdk,确保sdk安装正确。
2、整体编译C++ sdk仓。
3、进入build/example文件夹下,执行编译好的可执行文件rtsi_example,传递ip等参数

三、常见问题

1、只能通过控制台执行这个文件吗?能否通过ide直接执行?
A:这里使用了argparse解析参数,所以只需要将这里参数解析部分删除,直接指定ip等参数即可

四、代码和附件

这段代码首先通过调用RtsiIOInterface("output_recipe.txt", "input_recipe.txt", 250) 构造 IO 接口,指定订阅配方和 250Hz 刷新频率,然后调用connect(robot_ip) 连接 RTSI,接着分别调用getControllerVersion() 读控制器版本信息、调用getDigitalOutputBits() 读当前数字输出位状态,调用setStandardDigital(0, false) / setStandardDigital(0, true) 控制 DIO[0] 拉低/拉高。最后disconnect() 断开连接。
// SPDX-License-Identifier: MIT
// Copyright (c) 2025, Elite Robots.
#include <Elite/Log.hpp>
#include <Elite/RtsiIOInterface.hpp>

#include <boost/program_options.hpp>
#include <iostream>
#include <memory>
#include <chrono>

using namespace ELITE;
namespace po = boost::program_options;

int main(int argc, char* argv[]) {
    // Parse the ip arguments if given
    std::string robot_ip;

    // Parser param
    po::options_description desc(
        "Usage:\n"
        "\t./rtsi_example <--robot-ip=ip>\n"
        "Parameters:");
    desc.add_options()
        ("help,h", "Print help message")
        ("robot-ip", po::value<std::string>(&robot_ip)->required(),
            "\tRequired. IP address of the robot.");

    po::variables_map vm;
    try {
        po::store(po::parse_command_line(argc, argv, desc), vm);

        if (vm.count("help")) {
            std::cout << desc << std::endl;
            return 0;
        }
        po::notify(vm);
    } catch (const po::error& e) {
        std::cerr << "Argument error: " << e.what() << "\n\n";
        std::cerr << desc << "\n";
        return 1;
    }

    std::unique_ptr<RtsiIOInterface> io_interface = std::make_unique<RtsiIOInterface>("output_recipe.txt", "input_recipe.txt", 250);

    if (!io_interface->connect(robot_ip)) {
        ELITE_LOG_FATAL("Couldn't connect RTSI server");
        return 1;
    }

    VersionInfo version = io_interface->getControllerVersion();
    ELITE_LOG_INFO("Controller is: %s", version.toString().c_str());

    if ((io_interface->getDigitalOutputBits() & 0x00000001)) {
        auto start_set_false = std::chrono::high_resolution_clock::now();
        io_interface->setStandardDigital(0, false);
        while (io_interface->getDigitalOutputBits() | 0x00000000) {
            ;
        }
        auto finish_set_false = std::chrono::high_resolution_clock::now();
        std::chrono::duration<double> elapsed_set_false = finish_set_false - start_set_false;
        ELITE_LOG_INFO("Setting low level cost time: %d", elapsed_set_false.count());
    }

    auto start_set_true = std::chrono::high_resolution_clock::now();
    io_interface->setStandardDigital(0, true);

    while (!(io_interface->getDigitalOutputBits() & 0x00000001)) {
        ;
    }
    auto finish_set_true = std::chrono::high_resolution_clock::now();

    std::chrono::duration<double> elapsed_set_true = finish_set_true - start_set_true;
    ELITE_LOG_INFO("Setting high level cost time: %d", elapsed_set_true.count());

    io_interface->disconnect();

    return 0;
}