3.12 ExtensionClient 플러그인
개요
Arm::extensionClient 은 플러그인 조회, 상세 정보 읽기, 활성화/비활성화 전환, EasyService 호출 기능을 제공합니다.
3.12.1 공개 메서드
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>| 메서드 | 설명 | 반환 |
|---|---|---|
GetRobotIp | 로봇 본체 측 실행 환경을 기준으로 로봇 IP 추론 | std::string |
GetList | 플러그인 목록 가져오기 | std::pair<std::vector<ExtensionInfo>, STATUS_CODE> |
Get | 단일 플러그인 상세 정보 가져오기 | std::pair<ExtensionInfo, STATUS_CODE> |
Toggle | 플러그인 활성화 상태 전환 | STATUS_CODE |
CallService | EasyService 플러그인 서비스 호출 | std::pair<std::string, STATUS_CODE> |
3.12.2 전제 조건 및 연결 의존성
| 항목 | 규칙 |
|---|---|
Connect | GetList / Get / Toggle / CallService 는 모두 먼저 Arm::Connect() 를 완료해야 합니다. |
teachPanelIp | ExtensionClient 은 Arm::Connect() 이후의 티치 펜던트 주소를 사용합니다. 연결이 완료되지 않았거나 바인딩에 실패하면 위 네 인터페이스는 NOT_CONNECTED 를 반환합니다. |
GetRobotIp | 로봇 본체 측이 Linux가 아닌 환경이면 빈 문자열을 바로 반환합니다. Linux 환경에서도 아직 연결되지 않았으면 빈 문자열을 반환합니다. |
3.12.3 GetRobotIp() 동작
- Linux가 아닌 환경에서는 빈 문자열을 바로 반환합니다.
- 로봇 본체 측 Linux 컨테이너 환경에서 호스트명이
tp-connect-robot*와 일치하면eth0IPv4를 읽으려고 시도합니다. - 로봇 본체 측 Linux
teachbox/forlinx환경에서는 로봇 본체 측 Pure Web 서비스를 통해 컨트롤러 주소를 조회합니다. 연결 정보가 바인딩되지 않았거나, HTTP가 실패했거나, 반환 내용이 유효하지 않으면 빈 문자열을 반환합니다. - 기타 식별되지 않은 환경에서는 빈 문자열을 반환합니다.
- 이 인터페이스는 상태 코드를 반환하지 않으므로, 호출자는 빈 문자열을 "현재 환경에서 추론할 수 없음"으로 간주해야 합니다.
3.12.4 파라미터 검증
| 항목 | 규칙 |
|---|---|
name / command | 비어 있을 수 없으며 A-Z a-z 0-9 . _ - 만 허용합니다. |
params | JSON 객체만 허용합니다. |
params 값 타입 | 문자열, 유한 숫자, bool만 지원합니다. 배열, null , 중첩 객체, NaN/Inf 는 INVALID_PARAMETER 를 반환합니다. |
Get / Toggle | name 이 유효하지 않으면 INVALID_PARAMETER 를 반환합니다. |
CallService | name / command 중 하나라도 유효하지 않으면 INVALID_PARAMETER 를 반환합니다. |
3.12.5 동작 규칙
GetRobotIp()는 직접 호출할 수 있습니다.Connect()전에는 환경에 따라 빈 문자열을 반환할 수 있습니다.GetList()/Get()는 HTTP가200이 아니거나 JSON 파싱이 실패하거나 반환 구조가 맞지 않으면OTHER_ERR를 반환합니다.GetList()/Get()는 누락된 필드를 기본값으로 채웁니다. 구조 기준은 2.4-extension-types를 참고하십시오.Toggle()은180sHTTP timeout을 사용하며, 나머지 플러그인 조회는 기본 timeout을 사용합니다.CallService()성공 시result의 compact JSON 텍스트를 반환합니다. 문자열 결과는 따옴표를 유지합니다.result가 누락되었거나null이면CallService()는OTHER_ERR를 반환합니다.params가 빈 객체{}이면 요청 경로는 query string이 없는GET /{name}/{command}입니다.params의 키-값은 query string으로 평탄화됩니다. 배열이나 중첩 객체는 지원하지 않습니다.
3.12.6 서버 포트
| 포트 | 용도 |
|---|---|
5613 | 로봇 본체 측 Pure Web 서비스. GetRobotIp() 환경 탐지에 사용 |
5615 | 로봇 본체 측 플러그인 목록 및 상세 정보 서비스 |
5616 | 로봇 본체 측 EasyService 호출 서비스 |
3.12.7 최소 호출 예제
cpp
#include <iostream> // 플러그인 조회 결과를 출력하기 위한 표준 출력 스트림을 포함합니다.
#include "arm_api.h" // Arm 주 진입점을 포함하며, 연결 후 arm.extensionClient으로 플러그인 인터페이스에 접근합니다.
#include "json/json.h" // EasyService 파라미터 구성을 위한 Json::Value를 포함합니다.
#include "status_code.h" // SDK 호출 결과 확인용 STATUS_CODE를 포함합니다.
int main() // 예제 프로그램 진입점입니다.
{ // 예제 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(); // 현재 실행 환경을 기준으로 로봇 IP를 추론합니다.
auto [items, listRet] = arm.extensionClient.GetList(); // 로봇 본체의 플러그인 목록을 가져옵니다.
if (listRet != STATUS_CODE::OK) { // 플러그인 목록 조회 실패 여부를 판단합니다.
return 1; // 조회 실패 시 오류 코드로 반환합니다.
} // 플러그인 목록 조회 판단을 종료합니다.
std::cout << "robot_ip=" << robotIp << "\n"; // 추론된 로봇 IP를 출력합니다.
std::cout << "extension_count=" << items.size() << "\n"; // 플러그인 수를 출력합니다.
if (items.empty()) { // 현재 플러그인이 없는지 판단합니다.
return 0; // 플러그인이 없으면 예제를 정상 종료합니다.
} // 플러그인 빈 목록 판단을 종료합니다.
Json::Value params(Json::objectValue); // EasyService 호출 파라미터 객체를 생성합니다.
params["example"] = "sdk"; // 예제 문자열 파라미터를 씁니다.
auto [result, callRet] = arm.extensionClient.CallService( // 첫 번째 플러그인의 EasyService 서비스를 호출합니다.
items[0].extension.name, // 플러그인 목록 첫 항목의 플러그인 이름을 사용합니다.
"echo", // echo라는 서비스 명령을 호출합니다.
params // JSON 객체 파라미터를 전달합니다.
); // EasyService 호출을 종료합니다.
if (callRet != STATUS_CODE::OK) { // 서비스 호출 실패 여부를 판단합니다.
return 1; // 호출 실패 시 오류 코드로 반환합니다.
} // 서비스 호출 결과 판단을 종료합니다.
std::cout << "echo_result=" << result << "\n"; // EasyService가 반환한 결과 텍스트를 출력합니다.
return 0; // 예제를 정상 종료합니다. Toggle은 플러그인 상태를 변경하므로 최소 예제에서는 실행하지 않습니다.
} // 예제 main 함수를 종료합니다.시나리오 예제
아래 조각들은 "환경 정보, 목록/상세 정보, 서비스 호출, 플러그인 활성화 전환" 흐름으로 이 페이지의 API를 교차해서 다룹니다. 조각들은 최소 호출 예제에서 이미 연결에 성공한 arm 객체를 이어받는다고 가정합니다. Toggle 은 플러그인 활성화 상태를 변경하므로 확인한 뒤 실행하십시오.
로봇 IP 및 플러그인 목록 조회
cpp
std::string robotIp = arm.extensionClient.GetRobotIp(); // 현재 환경의 로봇 IP를 추론합니다.
auto [extensions, listRet] = arm.extensionClient.GetList(); // 플러그인 목록을 가져옵니다.
if (listRet == STATUS_CODE::OK) { // 플러그인 목록 조회 성공 여부를 판단합니다.
std::cout << "robot_ip=" << robotIp << " extension_count=" << extensions.size() << "\n"; // 로봇 IP와 플러그인 수를 출력합니다.
} // 플러그인 목록 조회 판단을 종료합니다.플러그인 상세 정보 조회 및 서비스 호출
cpp
const std::string name = "demo_extension"; // 플러그인 이름을 준비합니다. 실제 사용 시 GetList가 반환한 플러그인 이름으로 교체합니다.
auto [detail, getRet] = arm.extensionClient.Get(name); // 단일 플러그인 상세 정보를 조회합니다.
Json::Value params(Json::objectValue); // CallService에서 사용할 JSON 파라미터 객체를 준비합니다.
params["example"] = "sdk"; // 예제 파라미터를 씁니다.
auto [result, callRet] = arm.extensionClient.CallService(name, "echo", params); // EasyService 서비스를 호출합니다.
if (getRet == STATUS_CODE::OK || callRet == STATUS_CODE::OK) { // 상세 조회 또는 서비스 호출 성공 여부를 판단합니다.
std::cout << "extension_name=" << detail.extension.name << " service_result=" << result << "\n"; // 상세 정보와 서비스 결과 요약을 출력합니다.
} // 플러그인 인터페이스 결과 판단을 종료합니다.플러그인 활성화 상태 전환
cpp
const std::string name = "demo_extension"; // 플러그인 이름을 준비합니다. 실제 사용 시 대상 플러그인 이름으로 교체합니다.
// STATUS_CODE toggleRet = arm.extensionClient.Toggle(name); // 플러그인 활성화 상태 전환은 플러그인 실행에 영향을 주므로 확인한 뒤 실행하십시오.예제 코드
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;
}