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>| Method | Description | Return |
|---|---|---|
GetRobotIp | Infers the robot IP from the runtime environment on the robot body side | std::string |
GetList | Gets the plugin list | std::pair<std::vector<ExtensionInfo>, STATUS_CODE> |
Get | Gets details for one plugin | std::pair<ExtensionInfo, STATUS_CODE> |
Toggle | Toggles the plugin enabled state | STATUS_CODE |
CallService | Calls an EasyService plugin service | std::pair<std::string, STATUS_CODE> |
3.12.2 Prerequisites and Connection Dependencies
| Item | Rule |
|---|---|
Connect | GetList / Get / Toggle / CallService all require Arm::Connect() to complete first |
teachPanelIp | ExtensionClient uses the teach pendant address after Arm::Connect() . If the connection has not completed or binding fails, the four APIs above return NOT_CONNECTED |
GetRobotIp | In 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 ofeth0. - In robot-body Linux
teachbox/forlinxenvironments, 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
| Item | Rule |
|---|---|
name / command | Must not be empty, and may contain only A-Z a-z 0-9 . _ - |
params | Must be a JSON object |
params value types | Only strings, finite numbers, and booleans are supported. Arrays, null , nested objects, and NaN/Inf return INVALID_PARAMETER |
Get / Toggle | Returns INVALID_PARAMETER when name is invalid |
CallService | Returns 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 beforeConnect().GetList()/Get()returnOTHER_ERRwhen the HTTP status is not200, JSON parsing fails, or the returned structure does not match expectations.GetList()/Get()fill missing fields with default values. For the structure layout, see2.4-extension-types.Toggle()uses a180sHTTP timeout. Other plugin queries use the default timeout.- On success,
CallService()returns compact JSON text forresult; string results keep their quotes. - If
resultis missing ornull,CallService()returnsOTHER_ERR. - When
paramsis an empty object{}, the request path isGET /{name}/{command}without a query string. - Keys and values in
paramsare flattened into the query string. Arrays and nested objects are not supported.
3.12.6 Server Ports
| Port | Purpose |
|---|---|
5613 | Robot-body Pure Web service, used by GetRobotIp() environment detection |
5615 | Robot-body plugin list and detail service |
5616 | Robot-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:
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();
}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;
}