Skip to content

3.12 ExtensionClient

Overview

Arm::extension provides plugin list queries, plugin detail retrieval, enable/disable toggling, and EasyService calls.

3.12.1 Public Methods

cpp
GetRobotIp() -> std::string
GetList() -> std::pair<std::vector<ExtensionInfo>, STATUS_CODE>
Get(const std::string& name) -> std::pair<ExtensionInfo, STATUS_CODE>
Toggle(const std::string& name) -> STATUS_CODE
CallService(const std::string& name, const std::string& command, const Json::Value& params = {}) -> std::pair<std::string, STATUS_CODE>
MethodDescriptionReturn
GetRobotIpInfers the robot IP from the runtime environment on the robot body sidestd::string
GetListGets the plugin liststd::pair<std::vector<ExtensionInfo>, STATUS_CODE>
GetGets details for one pluginstd::pair<ExtensionInfo, STATUS_CODE>
ToggleToggles the plugin enabled stateSTATUS_CODE
CallServiceCalls an EasyService plugin servicestd::pair<std::string, STATUS_CODE>

3.12.2 Prerequisites and Connection Dependencies

ItemRule
ConnectGetList / Get / Toggle / CallService all require Arm::Connect() to complete first
teachPanelIpExtensionClient uses the teach pendant address after Arm::Connect() . If the connection has not completed or binding fails, the four APIs above return NOT_CONNECTED
GetRobotIpIn non-Linux environments on the robot body side, returns an empty string directly. In Linux environments, it also returns an empty string if no connection is bound yet

3.12.3 GetRobotIp() Behavior

  • Non-Linux environments return an empty string directly.
  • In robot-body Linux container environments, if the host name matches tp-connect-robot* , the SDK tries to read the IPv4 address of eth0 .
  • In robot-body Linux teachbox / forlinx environments, the SDK queries the controller address through the robot-body Pure Web service. If connection information is not bound, HTTP fails, or the returned content is invalid, an empty string is returned.
  • Other unrecognized environments return an empty string.
  • This API does not return a status code. Callers should treat an empty string as "the current environment cannot infer the address."

3.12.4 Parameter Validation

ItemRule
name / commandMust not be empty, and may contain only A-Z a-z 0-9 . _ -
paramsMust be a JSON object
params value typesOnly strings, finite numbers, and booleans are supported. Arrays, null , nested objects, and NaN/Inf return INVALID_PARAMETER
Get / ToggleReturns INVALID_PARAMETER when name is invalid
CallServiceReturns INVALID_PARAMETER when either name or command is invalid

3.12.5 Behavior Conventions

  • GetRobotIp() can be called directly, but not every environment can return a valid IP before Connect() .
  • GetList() / Get() return OTHER_ERR when the HTTP status is not 200 , JSON parsing fails, or the returned structure does not match expectations.
  • GetList() / Get() fill missing fields with default values. For the structure layout, see 2.4-extension-types .
  • Toggle() uses a 180s HTTP timeout. Other plugin queries use the default timeout.
  • On success, CallService() returns compact JSON text for result ; string results keep their quotes.
  • If result is missing or null , CallService() returns OTHER_ERR .
  • When params is an empty object {} , the request path is GET /{name}/{command} without a query string.
  • Keys and values in params are flattened into the query string. Arrays and nested objects are not supported.

3.12.6 Server Ports

PortPurpose
5613Robot-body Pure Web service, used by GetRobotIp() environment detection
5615Robot-body plugin list and detail service
5616Robot-body EasyService call service

3.12.7 Minimal Call Example

cpp
#include <iostream>       // Standard output stream for printing plugin query results
#include "arm_api.h"     // Arm entry point; after connection, plugin APIs are accessed through arm.extensionClient
#include "json/json.h"   // Json::Value for building EasyService parameters
#include "status_code.h" // STATUS_CODE for checking SDK call results

int main()
{
    Arm arm;
    STATUS_CODE connectRet = arm.Connect("192.168.110.2", "");
    if (connectRet != STATUS_CODE::OK) {
        return 1;
    }

    const std::string robotIp = arm.extensionClient.GetRobotIp();
    auto [items, listRet] = arm.extensionClient.GetList();
    if (listRet != STATUS_CODE::OK) {
        return 1;
    }

    std::cout << "robot_ip=" << robotIp << "\n";
    std::cout << "extension_count=" << items.size() << "\n";
    if (items.empty()) {
        return 0;
    }

    Json::Value params(Json::objectValue);
    params["example"] = "sdk";
    auto [result, callRet] = arm.extensionClient.CallService(
        items[0].extension.name,
        "echo",
        params
    );
    if (callRet != STATUS_CODE::OK) {
        return 1;
    }

    std::cout << "echo_result=" << result << "\n";
    return 0;
}

Scenario Examples

The snippets below cover environment information, list/detail queries, service calls, and plugin toggling. They assume the arm object from the minimal example is already connected. Toggle changes the plugin enabled state, so run it only after confirming the target.

Query Robot IP and Plugin List

cpp
std::string robotIp = arm.extensionClient.GetRobotIp();
auto [extensions, listRet] = arm.extensionClient.GetList();
if (listRet == STATUS_CODE::OK) {
    std::cout << "robot_ip=" << robotIp << " extension_count=" << extensions.size() << "\n";
}

Query Plugin Details and Call a Service

cpp
const std::string name = "demo_extension";
auto [detail, getRet] = arm.extensionClient.Get(name);
Json::Value params(Json::objectValue);
params["example"] = "sdk";
auto [result, callRet] = arm.extensionClient.CallService(name, "echo", params);
if (getRet == STATUS_CODE::OK || callRet == STATUS_CODE::OK) {
    std::cout << "extension_name=" << detail.extension.name << " service_result=" << result << "\n";
}

Toggle Plugin Enabled State

cpp
const std::string name = "demo_extension";
// STATUS_CODE toggleRet = arm.extensionClient.Toggle(name);

Example code:

cpp17/extension_basic/src/main.cpp
cpp
#include "query_extension_info/run.h"
#include "call_extension_service/run.h"

int main(void)
{
    // [ZH] 默认只调用一个门面方法;如需体验其他接口,请把下一行替换成下面任意一行。
    // [EN] The main function calls only one facade by default. Replace the next line with any line below to try other APIs.
    return RunExtensionBasicQueryExtensionInfo();
    // return RunExtensionBasicCallExtensionService();
}
c99/extension_basic/src/main.cpp
cpp
#include <stdio.h>

extern "C" {
#include "c_arm_api.h"
}

int main(void)
{
    // [ZH] 本示例直接在源码中写死连接地址,不解析命令行参数。
    // [EN] This example hard-codes the connection addresses in the source code and does not parse command-line arguments.
    // [ZH] 创建并连接 SDK 句柄。
    // [EN] Create the SDK handle and connect to the robot.
    ArmHandle* handle = Arm_Create();
    if (handle == NULL) {
        printf("[c99_extension] 创建句柄失败 / Failed to create the handle\n");
        return 1;
    }
    int ret = Arm_Connect(handle, "10.27.1.2", "10.27.1.102");
    if (ret != 0) {
        printf("[c99_extension] 连接失败 / Connect failed, 状态码 / Status code: %d\n", ret);
        Arm_Destroy(handle);
        return 1;
    }
    printf("[c99_extension] 机器人连接成功 / Robot connected successfully\n");

    // [ZH] 顺序执行全部插件接口。
    // [EN] Execute all extension APIs in sequence.
    char robotIp[256] = {0};
    char listJson[4096] = {0};
    char detailJson[4096] = {0};
    char resultJson[4096] = {0};
    ret = Arm_Extension_GetRobotIp(handle, robotIp, sizeof(robotIp));
    printf("[c99_extension] GetRobotIp 状态码 / GetRobotIp status code: %d, 机器人 IP / Robot IP: %s\n", ret, robotIp);
    ret = Arm_Extension_GetList(handle, listJson, sizeof(listJson));
    printf("[c99_extension] GetList 状态码 / GetList status code: %d, 列表 JSON / List JSON: %s\n", ret, listJson);
    ret = Arm_Extension_Get(handle, "demo", detailJson, sizeof(detailJson));
    printf("[c99_extension] Get 状态码 / Get status code: %d, 详情 JSON / Detail JSON: %s\n", ret, detailJson);
    ret = Arm_Extension_CallService(handle, "demo", "echo", "{\"example\":\"sdk\",\"count\":1}", resultJson, sizeof(resultJson));
    printf("[c99_extension] CallService 状态码 / CallService status code: %d, 返回值 / Result: %s\n", ret, resultJson);
    ret = Arm_Extension_Toggle(handle, "demo");
    printf("[c99_extension] Toggle 状态码 / Toggle status code: %d\n", ret);

    // [ZH] 断开连接并销毁句柄。
    // [EN] Disconnect and destroy the handle.
    Arm_Disconnect(handle);
    Arm_Destroy(handle);
    printf("[c99_extension] 示例结束 / Example finished\n");
    return 0;
}