Skip to content

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
CallServiceEasyService 플러그인 서비스 호출std::pair<std::string, STATUS_CODE>

3.12.2 전제 조건 및 연결 의존성

항목규칙
ConnectGetList / Get / Toggle / CallService 는 모두 먼저 Arm::Connect() 를 완료해야 합니다.
teachPanelIpExtensionClientArm::Connect() 이후의 티치 펜던트 주소를 사용합니다. 연결이 완료되지 않았거나 바인딩에 실패하면 위 네 인터페이스는 NOT_CONNECTED 를 반환합니다.
GetRobotIp로봇 본체 측이 Linux가 아닌 환경이면 빈 문자열을 바로 반환합니다. Linux 환경에서도 아직 연결되지 않았으면 빈 문자열을 반환합니다.

3.12.3 GetRobotIp() 동작

  • Linux가 아닌 환경에서는 빈 문자열을 바로 반환합니다.
  • 로봇 본체 측 Linux 컨테이너 환경에서 호스트명이 tp-connect-robot* 와 일치하면 eth0 IPv4를 읽으려고 시도합니다.
  • 로봇 본체 측 Linux teachbox / forlinx 환경에서는 로봇 본체 측 Pure Web 서비스를 통해 컨트롤러 주소를 조회합니다. 연결 정보가 바인딩되지 않았거나, HTTP가 실패했거나, 반환 내용이 유효하지 않으면 빈 문자열을 반환합니다.
  • 기타 식별되지 않은 환경에서는 빈 문자열을 반환합니다.
  • 이 인터페이스는 상태 코드를 반환하지 않으므로, 호출자는 빈 문자열을 "현재 환경에서 추론할 수 없음"으로 간주해야 합니다.

3.12.4 파라미터 검증

항목규칙
name / command비어 있을 수 없으며 A-Z a-z 0-9 . _ - 만 허용합니다.
paramsJSON 객체만 허용합니다.
params 값 타입문자열, 유한 숫자, bool만 지원합니다. 배열, null , 중첩 객체, NaN/InfINVALID_PARAMETER 를 반환합니다.
Get / Togglename 이 유효하지 않으면 INVALID_PARAMETER 를 반환합니다.
CallServicename / command 중 하나라도 유효하지 않으면 INVALID_PARAMETER 를 반환합니다.

3.12.5 동작 규칙

  • GetRobotIp() 는 직접 호출할 수 있습니다. Connect() 전에는 환경에 따라 빈 문자열을 반환할 수 있습니다.
  • GetList() / Get() 는 HTTP가 200 이 아니거나 JSON 파싱이 실패하거나 반환 구조가 맞지 않으면 OTHER_ERR 를 반환합니다.
  • GetList() / Get() 는 누락된 필드를 기본값으로 채웁니다. 구조 기준은 2.4-extension-types를 참고하십시오.
  • Toggle()180s HTTP 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);  // 플러그인 활성화 상태 전환은 플러그인 실행에 영향을 주므로 확인한 뒤 실행하십시오.

예제 코드

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;
}