TRON 2 DOCS
产品文档/TRON 2/SDK · 上层任务控制
TRON 2 · 使用与开发

双臂 · C++ / Python 示例

仅双臂/移动双臂

3.7 双臂形态协议接口调用示例

3.7.1 C++ 示例实现

环境准备

以 Ubuntu 22.04 系统为例,安装 websocketpp、nlohmann/json 和 boost 依赖:

sudo apt-get install libboost-all-dev libwebsocketpp-dev nlohmann-json3-dev

编译代码

g++ -std=c++11 -o websocket_client websocket_client.cpp -lssl -lcrypto -lboost_system -lpthread

运行程序

./websocket_client

** websocket_client.cpp 实现**

#include <iostream>
#include <atomic>
#include <string>
#include <thread>
#include <chrono>
#include <websocketpp/client.hpp>
#include <websocketpp/config/asio.hpp>
#include <nlohmann/json.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>

using json = nlohmann::json;
using websocketpp::client;
using websocketpp::connection_hdl;

// Replace this value with the actual serial number (SN) of the robot.
static std::string ACCID = "";

// Replace it with the real IP address of the robot.
// Usually, for simulation, it is: 127.0.0.1
// for a real machine, it is: 10.192.1.2
const std::string ROBOT_IP = "10.192.1.2";

// WebSocket client instance
static client<websocketpp::config::asio> ws_client;

// Atomic flag for graceful exit
static std::atomic<bool> should_exit(false);

// Connection handle for sending messages
static connection_hdl current_hdl;

// Generate dynamic GUID
static std::string generate_guid()
{
    boost::uuids::random_generator gen;
    boost::uuids::uuid u = gen();
    return boost::uuids::to_string(u);
}

// Send WebSocket request with title and data
static void send_request(const std::string &title, const json &data = json::object())
{
    json message;

    message["accid"] = ACCID;
    message["title"] = title;
    message["timestamp"] = std::chrono::duration_cast<std::chrono::milliseconds>(
                               std::chrono::system_clock::now().time_since_epoch())
                               .count();
    message["guid"] = generate_guid();
    message["data"] = data;

    std::string message_str = message.dump();

    ws_client.send(current_hdl, message_str, websocketpp::frame::opcode::text);
}

// Handle user commands
void handle_commands()
{
    std::cout << "Enter command ('movej', 'movep', 'light', 'stop') or 'exit' to quit:\n";

    while (!should_exit)
    {
        std::string command;
        std::cin >> command;

        if (command == "exit")
        {
            should_exit = true;
            return;
        }
        else if (command == "movej")
        {
            json data = {
                {"joint", {-0.5, 0.3, -0.2, 0.2, 0.2, 0.2, 0.2,
                           -0.5, -0.3, -0.2, 0.2, 0.2, 0.2, 0.2}},
                {"time", 2}};
            send_request("request_movej", data);
        }
        else if (command == "movep")
        {
            json data = {
                {"pos", {0.3, 0.2, -0.3, 1, 0, 0, 0, 1, 0, 0, 0, 1,
                         0.3, -0.2, -0.3, 1, 0, 0, 0, 1, 0, 0, 0, 1}},
                {"time", 2}};
            send_request("request_movep", data);
        }
        else if (command == "light")
        {
            send_request("request_light_effect", {{"effect", 1}});
        }
        else if (command == "stop")
        {
            send_request("request_emgy_stop");
        }

        std::this_thread::sleep_for(std::chrono::seconds(1));

        std::cout << "Enter command ('movej', 'movep', 'light', 'stop') or 'exit' to quit:\n";
    }
}

// WebSocket open callback
static void on_open(connection_hdl hdl)
{
    std::cout << "Connected!" << std::endl;

    current_hdl = hdl;

    std::thread(handle_commands).detach();
}

// WebSocket TCP initialization handler
static void on_tcp_init(connection_hdl hdl)
{
    auto con = ws_client.get_con_from_hdl(hdl);
    auto &socket = con->get_socket().lowest_layer();

    try
    {
        boost::system::error_code ec;

        const size_t sendBufferSize = 2 * 1024 * 1024;
        socket.set_option(websocketpp::lib::asio::socket_base::send_buffer_size(sendBufferSize), ec);

        if (ec)
        {
            printf("Failed to set send buffer size: %s", ec.message().c_str());
        }

        const size_t recvBufferSize = 2 * 1024 * 1024;
        socket.set_option(websocketpp::lib::asio::socket_base::receive_buffer_size(recvBufferSize), ec);

        if (ec)
        {
            printf("Failed to set receive buffer size: %s", ec.message().c_str());
        }

        socket.set_option(websocketpp::lib::asio::ip::tcp::no_delay(true), ec);

        if (ec)
        {
            printf("Failed to disable Nagle's algorithm: %s", ec.message().c_str());
        }
    }
    catch (const std::exception &e)
    {
        printf("Socket configuration exception: %s", e.what());
    }
}

// WebSocket message callback
static void on_message(connection_hdl hdl, client<websocketpp::config::asio>::message_ptr msg)
{
    json data = json::parse(msg->get_payload());

    if (data.contains("accid") && data["accid"].is_string() && ACCID.empty())
    {
        ACCID = data["accid"].get<std::string>();
    }

    if (msg->get_payload().find("notify_robot_info") == std::string::npos)
    {
        std::cout << "Received message: " << msg->get_payload() << std::endl;
    }
}

// WebSocket close callback
static void on_close(connection_hdl hdl)
{
    std::cout << "Connection closed." << std::endl;
}

// Close WebSocket connection
static void close_connection(connection_hdl hdl)
{
    ws_client.close(hdl, websocketpp::close::status::normal, "Normal closure");
}

int main()
{
    ws_client.init_asio();

    ws_client.set_access_channels(websocketpp::log::alevel::none);

    ws_client.set_open_handler(&on_open);
    ws_client.set_message_handler(&on_message);
    ws_client.set_close_handler(&on_close);
    ws_client.set_tcp_init_handler(&on_tcp_init);

    std::string server_uri = "ws://" + ROBOT_IP + ":5000";

    websocketpp::lib::error_code ec;
    client<websocketpp::config::asio>::connection_ptr con = ws_client.get_connection(server_uri, ec);

    if (ec)
    {
        std::cout << "Error: " << ec.message() << std::endl;
        return 1;
    }

    ws_client.connect(con);

    std::cout << "Press Ctrl+C to exit." << std::endl;

    ws_client.run();

    return 0;
}

3.7.2 Python 示例实现

环境准备

以 Ubuntu 22.04 系统、Python 3.10.4 版本为例,安装下面依赖:

sudo apt install python3-dev python3-pip
pip3 install websocket-client

运行脚本

python3 websocket_client.py

websocket_client.py 实现


import json
import uuid
import threading
import time
import websocket

# Replace this ACCID value with your robot's actual serial number (SN)
ACCID = None

# Replace it with the real IP address of the robot.
# for a real machine, it is: 10.192.1.2
ROBOT_IP = "10.192.1.2"

# Atomic flag for graceful exit
should_exit = False

# WebSocket client instance
ws_client = None

# Generate dynamic GUID
def generate_guid():
    return str(uuid.uuid4())

# Send WebSocket request with title and data
def send_request(title, data=None):
    global ACCID

    if data is None:
        data = {}

    message = {
        "accid": ACCID,
        "title": title,
        "timestamp": int(time.time() * 1000),
        "guid": generate_guid(),
        "data": data
    }

    message_str = json.dumps(message)

    if ws_client:
        ws_client.send(message_str)

# Handle user commands
def handle_commands():
    global should_exit

    while not should_exit:
        command = input("Enter command ('movej', 'movep', 'light', 'stop') or 'exit' to quit:\n")

        if command == "exit":
            should_exit = True
            break

        elif command == "movej":
            send_request("request_movej", {
                "joint": [
                    0,0,0,-1.6,0,0,0,0,0,0,-1.6,0,0,0
                ],
                "time": 5
            })
        elif command == "movep":
            send_request("request_movep", {
                "pos": [
                    0.5,  0.2, -0.3, 0.7, 0,  -0.7,  0,  0.5,-0.2, -0.3,  0.7,   0,  -0.7,  0 
                ],
                "time": 5
            })

        elif command == "light":
            send_request("request_light_effect", {
                "effect": 1
            })

        elif command == "stop":
            send_request("request_emgy_stop", {})

# WebSocket on_open callback
def on_open(ws):
    print("Connected!")
    threading.Thread(target=handle_commands, daemon=True).start()

# WebSocket on_message callback
def on_message(ws, message):
    global ACCID

    root = json.loads(message)
    title = root.get("title", "")

    if ACCID is None:
        ACCID = root.get("accid", None)

    if title != "notify_robot_info":
        print(f"Received message: {message}")

# WebSocket on_close callback
def on_close(ws, close_status_code, close_msg):
    print("Connection closed.")

# Close WebSocket connection
def close_connection(ws):
    ws.close()

def main():
    global ws_client

    ws_client = websocket.WebSocketApp(
        f"ws://{ROBOT_IP}:5000",
        on_open=on_open,
        on_message=on_message,
        on_close=on_close
    )

    print("Press Ctrl+C to exit.")
    ws_client.run_forever()

if __name__ == "__main__":
    main()




继续阅读上层 · 双足与双轮足控制