Skip to content

4.1 C99 Arm Root Entry

Overview

The C99 root entry is ArmHandle* . Callers create a session handle with Arm_Create() . After connection succeeds, pass the same handle to module functions such as Arm_Info_* , Arm_Motion_* , and Arm_Program_* .

Corresponding headers:

  • include/c_arm_core.h
  • include/c_arm_api.h

Interface Signatures

Arm_Create

c
ArmHandle* Arm_Create(void);
ItemDescription
DescriptionCreates a C99 session handle
Request ParametersNone
Return ValueArmHandle* ; returns a non-null session handle on success, or NULL on failure

Arm_Destroy

c
void Arm_Destroy(ArmHandle* h);
ItemDescription
DescriptionDestroys the C99 session handle and releases local resources
Request Parametersh : ArmHandle* , C99 session handle, usually from Arm_Create()
Return ValueNo return value

Arm_Connect

c
int Arm_Connect(ArmHandle* h, const char* controllerIp, const char* teachPanelIp);
ItemDescription
DescriptionConnects to the controller and initializes business capabilities for the current session
Request Parametersh : ArmHandle* , C99 session handle, usually from Arm_Create() ; business APIs require connection first
controllerIp : const char* , controller, router, or site-specific entry address
teachPanelIp : const char* , teach pendant address. Pass NULL or an empty string to use the default connection rules
Return ValueSTATUS_CODE integer value; 0 means success, other values should be handled as status codes

Arm_Disconnect

c
void Arm_Disconnect(ArmHandle* h);
ItemDescription
DescriptionDisconnects the current robot session
Request Parametersh : ArmHandle* , C99 session handle, usually from Arm_Create()
Return ValueNo return value

Arm_IsConnected

c
int Arm_IsConnected(ArmHandle* h);
ItemDescription
DescriptionQueries whether the current session is still connected
Request Parametersh : ArmHandle* , C99 session handle, usually from Arm_Create()
Return Value1 means connected; 0 means disconnected or the handle is invalid

Calling Conventions

ItemRule
controllerIpController, router, or site-specific entry address. Must not be NULL
teachPanelIpMay be NULL or an empty string. The SDK fills the default address according to address normalization rules
LifecycleUse Arm_Create() and Arm_Destroy() as a pair
Business preconditionMost Arm_* business functions require Arm_Connect() to succeed first
Error codeArm_Connect() returns 0 on success; other values should be interpreted as STATUS_CODE

Address Normalization

Arm_Connect() applies compatibility completion for a few default topologies. When both controller and teach pendant addresses are known, pass both explicitly.

InputResult
controllerIp = "192.168.110.2" , teachPanelIp = NULL or empty stringAutomatically fills teachPanelIp as 192.168.110.102
controllerIp = "192.168.110.102" , teachPanelIp = NULL or empty stringAutomatically corrects controllerIp to 192.168.110.2 and sets teachPanelIp to 192.168.110.102
controllerIp is set, teachPanelIp = NULL or empty stringFor collaborative robots, the SDK normalizes the empty teachPanelIp to controllerIp
Both controllerIp and teachPanelIp are passed explicitlyUses the caller-provided addresses

Connection and Thread Semantics

ScenarioDescription
After connection succeedsThe same ArmHandle* can continue to be passed to Info , Motion , Program , Registers , SubPub , and other module functions
Repeated connectionCalling Arm_Connect() again with the same address combination returns success. If already connected to another address, it disconnects first and then switches
DisconnectArm_Disconnect() invalidates business APIs that depend on the current connection. Reconnect before calling business APIs again
Destroy handleArm_Destroy() may receive a disconnected handle or a handle from a failed connection. Do not use the pointer again after calling it
Thread modelThe same ArmHandle* reuses one session context; business calls that involve network requests execute serially within the session

During connection, the SDK reads the controller version, robot model, and robot type. If version query fails, connection state is rolled back to disconnected. controllerIp may be a controller address, router address, or site-specific entry address.

Minimal Call Example

c
#include <stdio.h>     // printf for printing connection state
#include "c_arm_api.h" // C99 SDK umbrella header

int main(void)
{
    ArmHandle* h = Arm_Create();
    if (h == NULL) {
        return 1;
    }

    int ret = Arm_Connect(h, "10.27.1.2", "10.27.1.102");
    if (ret != 0) {
        Arm_Destroy(h);
        return 1;
    }

    printf("connected=%d\n", Arm_IsConnected(h));
    Arm_Disconnect(h);
    Arm_Destroy(h);
    return 0;
}

Scenario Examples

Leave the Teach Pendant Address Empty

c
ArmHandle* h = Arm_Create();
int ret = Arm_Connect(h, "10.27.1.2", NULL);
(void)ret;
Arm_Disconnect(h);
Arm_Destroy(h);

Always Release on Failure

c
ArmHandle* h = Arm_Create();
if (h == NULL) {
    return 1;
}
int ret = Arm_Connect(h, "10.27.1.2", "10.27.1.102");
if (ret != 0) {
    Arm_Destroy(h);
    return ret;
}
Arm_Disconnect(h);
Arm_Destroy(h);

Example code:

c99/arm_connect_disconnect/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.
    ArmHandle* handle = Arm_Create();
    if (handle == NULL) {
        printf("[c99_arm] 创建句柄失败 / Failed to create the handle\n");
        return 1;
    }

    // [ZH] 连接机器人。
    // [EN] Connect to the robot.
    int ret = Arm_Connect(handle, "10.27.1.2", "10.27.1.102");
    if (ret != 0) {
        printf("[c99_arm] 连接失败 / Connect failed, 状态码 / Status code: %d\n", ret);
        Arm_Destroy(handle);
        return 1;
    }
    printf("[c99_arm] 机器人连接成功 / Robot connected successfully\n");

    // [ZH] 查询当前连接状态。
    // [EN] Query the current connection state.
    ret = Arm_IsConnected(handle);
    printf("[c99_arm] 当前连接状态 / Current connection state: %d\n", ret);

    // [ZH] 断开机器人连接。
    // [EN] Disconnect from the robot.
    Arm_Disconnect(handle);
    printf("[c99_arm] 已断开连接 / Disconnected from the robot\n");

    // [ZH] 再次查询连接状态,确认已经断开。
    // [EN] Query the connection state again to confirm it is disconnected.
    ret = Arm_IsConnected(handle);
    printf("[c99_arm] 断开后的连接状态 / Connection state after disconnect: %d\n", ret);

    // [ZH] 销毁句柄并结束示例。
    // [EN] Destroy the handle and finish the example.
    Arm_Destroy(handle);
    printf("[c99_arm] 句柄销毁成功 / Handle destroyed successfully\n");
    return 0;
}
mingw_c99/gcc_capi_info_read/src/main.c
c
#include <stdio.h>

#include "c_arm_api.h"

int main(void)
{
    // [ZH] 本示例使用 MinGW/GCC 直接调用 C99 接口,并通过 libAgilebotCppSdk.dll.a 链接 DLL。
    // [EN] This example uses MinGW/GCC to call the C99 API directly and links the DLL through libAgilebotCppSdk.dll.a.
    const char* controller_ip = "10.27.1.2";
    const char* teach_panel_ip = "10.27.1.102";
    int ret = 0;

    ArmHandle* handle = Arm_Create();
    if (handle == NULL) {
        printf("[gcc_capi_info_read] 创建句柄失败 / Failed to create handle\n");
        return 1;
    }

    // [ZH] 连接前先查询一次状态,便于确认 import library、DLL 与基础句柄函数都可用。
    // [EN] Query once before connecting to validate the import library, DLL, and basic handle APIs.
    printf("[gcc_capi_info_read] 连接前状态 / State before connect: %d\n", Arm_IsConnected(handle));

    ret = Arm_Connect(handle, controller_ip, teach_panel_ip);
    if (ret != 0) {
        printf("[gcc_capi_info_read] 连接失败 / Connect failed, 状态码 / Status code: %d\n", ret);
        Arm_Destroy(handle);
        return 1;
    }
    printf("[gcc_capi_info_read] 连接后状态 / State after connect: %d\n", Arm_IsConnected(handle));

    // [ZH] 只调用读接口,适合作为客户 MinGW 环境的低风险联调模板。
    // [EN] Only read APIs are used, making this a low-risk integration template for customer MinGW environments.
    char version[128] = {0};
    ret = Arm_Info_GetControllerVersion(handle, version, sizeof(version));
    printf("[gcc_capi_info_read] GetControllerVersion 状态码 / Status code: %d, 版本 / Version: %s\n", ret, version);

    char model[128] = {0};
    ret = Arm_Info_GetArmModelInfo(handle, model, sizeof(model));
    printf("[gcc_capi_info_read] GetArmModelInfo 状态码 / Status code: %d, 型号 / Model: %s\n", ret, model);

    int op_mode = 0;
    ret = Arm_Info_GetOpMode(handle, &op_mode);
    printf("[gcc_capi_info_read] GetOpMode 状态码 / Status code: %d, 操作模式 / Operation mode: %d\n", ret, op_mode);

    int ctrl_status = 0;
    ret = Arm_Info_GetCtrlStatus(handle, &ctrl_status);
    printf("[gcc_capi_info_read] GetCtrlStatus 状态码 / Status code: %d, 控制器状态 / Controller status: %d\n", ret, ctrl_status);

    int robot_status = 0;
    ret = Arm_Info_GetRobotStatus(handle, &robot_status);
    printf("[gcc_capi_info_read] GetRobotStatus 状态码 / Status code: %d, 机器人状态 / Robot status: %d\n", ret, robot_status);

    int servo_status = 0;
    ret = Arm_Info_GetServoStatus(handle, &servo_status);
    printf("[gcc_capi_info_read] GetServoStatus 状态码 / Status code: %d, 伺服状态 / Servo status: %d\n", ret, servo_status);

    int soft_mode = 0;
    ret = Arm_Info_GetSoftMode(handle, &soft_mode);
    printf("[gcc_capi_info_read] GetSoftMode 状态码 / Status code: %d, 软模式 / Soft mode: %d\n", ret, soft_mode);

    // [ZH] 清理连接与句柄。
    // [EN] Clean up connection and handle.
    Arm_Disconnect(handle);
    printf("[gcc_capi_info_read] 断开后状态 / State after disconnect: %d\n", Arm_IsConnected(handle));
    Arm_Destroy(handle);
    printf("[gcc_capi_info_read] 示例结束 / Example finished\n");
    return 0;
}