Skip to content

4.1 C99 Arm 根入口

概述

C99 的根入口是 ArmHandle* 。调用方通过 Arm_Create() 创建会话句柄,连接成功后把同一个句柄传给 Arm_Info_*Arm_Motion_*Arm_Program_* 等模块函数。

对应头文件:

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

接口签名

Arm_Create

c
ArmHandle* Arm_Create(void);
说明
描述创建 C99 会话句柄。
请求参数无参数
返回值ArmHandle* ;成功时返回非空会话句柄,失败时返回 NULL

Arm_Destroy

c
void Arm_Destroy(ArmHandle* h);
说明
描述销毁 C99 会话句柄并释放本地资源。
请求参数h : ArmHandle* ,C99 会话句柄,通常来自 Arm_Create()
返回值无返回值

Arm_Connect

c
int Arm_Connect(ArmHandle* h, const char* controllerIp, const char* teachPanelIp);
说明
描述连接控制器并初始化当前会话的业务能力。
请求参数h : ArmHandle* ,C99 会话句柄,通常来自 Arm_Create() ,业务接口需要先连接成功
controllerIp : const char* ,控制器、路由或现场指定入口地址
teachPanelIp : const char* ,示教器地址;传 NULL 或空字符串时使用默认连接规则
返回值STATUS_CODE 整数值; 0 表示成功,其他值按状态码处理

Arm_Disconnect

c
void Arm_Disconnect(ArmHandle* h);
说明
描述断开当前机器人连接。
请求参数h : ArmHandle* ,C99 会话句柄,通常来自 Arm_Create()
返回值无返回值

Arm_IsConnected

c
int Arm_IsConnected(ArmHandle* h);
说明
描述查询当前会话是否仍保持连接。
请求参数h : ArmHandle* ,C99 会话句柄,通常来自 Arm_Create()
返回值1 表示已连接, 0 表示未连接或句柄无效

调用约定

规则
controllerIp控制器、路由或现场指定入口地址,不能为 NULL
teachPanelIp可传 NULL 或空字符串,SDK 按地址归一化规则补默认地址
生命周期Arm_Create()Arm_Destroy() 成对使用
业务前置绝大多数 Arm_* 业务函数需要先 Arm_Connect() 成功
错误码Arm_Connect() 成功返回 0 ,其他值按 STATUS_CODE 判断

地址归一化

Arm_Connect() 对少量默认拓扑做兼容补全。已明确控制器和示教器地址时,建议两个参数都显式传入。

输入结果
controllerIp = "192.168.110.2"teachPanelIp = NULL 或空字符串自动把 teachPanelIp 补成 192.168.110.102
controllerIp = "192.168.110.102"teachPanelIp = NULL 或空字符串自动把 controllerIp 纠正为 192.168.110.2 ,同时把 teachPanelIp 设为 192.168.110.102
controllerIp 有值, teachPanelIp = NULL 或空字符串协作机器人会把空的 teachPanelIp 归一化为 controllerIp
controllerIpteachPanelIp 都显式传入使用调用方传入的地址

连接与线程语义

场景说明
连接成功后同一个 ArmHandle* 可继续传给 InfoMotionProgramRegistersSubPub 等模块函数
重复连接已连接到相同地址组合时再次调用 Arm_Connect() 返回成功;已连接到其他地址时会先断开再切换
断开连接Arm_Disconnect() 会使依赖当前连接的业务接口失效;再次调用业务接口前需要重新连接
销毁句柄Arm_Destroy() 可接收已断开或连接失败后的句柄;调用后不得继续使用该指针
线程模型同一 ArmHandle* 复用一个会话上下文;涉及网络请求的业务调用按会话串行执行

连接阶段会读取控制器版本、机器人型号和机器人类型;版本查询失败时,连接状态会回滚为未连接。 controllerIp 可以是控制器地址、路由地址或现场指定入口地址。

最小调用示例

c
#include <stdio.h>  // 引入标准输出,用于打印连接状态
#include "c_arm_api.h"  // 引入 C99 SDK 总头文件
int main(void)  // 示例程序入口
{  // 进入示例主函数
    ArmHandle* h = Arm_Create();  // 创建 C99 会话句柄
    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;  // 示例成功结束
}  // 结束示例主函数

场景化示例

留空示教器地址

c
ArmHandle* h = Arm_Create();  // 创建 C99 会话句柄
int ret = Arm_Connect(h, "10.27.1.2", NULL);  // 只传控制器地址,示教器地址交给 SDK 默认规则
(void)ret;  // 示例中保留连接结果
Arm_Disconnect(h);  // 断开连接
Arm_Destroy(h);  // 销毁句柄

失败时保证释放

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);  // 正常路径释放句柄

示例代码

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