4.15 C99 CoordinateSystem 坐标系接口
概述
C99 CoordinateSystem 管理用户坐标系和工具坐标系,支持列表查询、详情查询、新增、更新、删除和根据示教点计算坐标系位姿。
对应头文件:
include/c_arm_coordinate.h
接口签名
Arm_CoordinateSystem_GetList
c
int Arm_CoordinateSystem_GetList(ArmHandle* h, int coordinateSystemType, ArmCoordinateInfo* outArray, size_t maxCount, size_t* outCount);| 项 | 说明 |
|---|---|
| 描述 | 查询坐标系列表。 |
| 请求参数 | h : ArmHandle* ,C99 会话句柄,通常来自 Arm_Create() ,业务接口需要先连接成功coordinateSystemType : int ,坐标系类型,用户坐标系或工具坐标系outArray : ArmCoordinateInfo* ,输出数组,由调用方分配maxCount : size_t ,输出数组容量,表示调用方最多可接收多少个元素outCount : size_t* ,输出数量指针,成功时写入实际数量 |
| 返回值 | STATUS_CODE 整数值; 0 表示成功,其他值按状态码处理 |
| 备注 | 数组输出由调用方分配, maxCount 表示容量, outCount 返回实际数量。 |
Arm_CoordinateSystem_Get
c
int Arm_CoordinateSystem_Get(ArmHandle* h, int coordinateSystemType, int32_t id, ArmCoordinate* outCoordinate);| 项 | 说明 |
|---|---|
| 描述 | 查询坐标系详情。 |
| 请求参数 | h : ArmHandle* ,C99 会话句柄,通常来自 Arm_Create() ,业务接口需要先连接成功coordinateSystemType : int ,坐标系类型,用户坐标系或工具坐标系id : int32_t ,坐标系编号outCoordinate : ArmCoordinate* ,坐标系详情输出结构体指针 |
| 返回值 | STATUS_CODE 整数值; 0 表示成功,其他值按状态码处理 |
Arm_CoordinateSystem_Add
c
int Arm_CoordinateSystem_Add(ArmHandle* h, int coordinateSystemType, const ArmCoordinate* coordinate);| 项 | 说明 |
|---|---|
| 描述 | 新增坐标系。 |
| 请求参数 | h : ArmHandle* ,C99 会话句柄,通常来自 Arm_Create() ,业务接口需要先连接成功coordinateSystemType : int ,坐标系类型,用户坐标系或工具坐标系coordinate : const ArmCoordinate* ,坐标系详情结构体指针 |
| 返回值 | STATUS_CODE 整数值; 0 表示成功,其他值按状态码处理 |
Arm_CoordinateSystem_Update
c
int Arm_CoordinateSystem_Update(ArmHandle* h, int coordinateSystemType, const ArmCoordinate* coordinate);| 项 | 说明 |
|---|---|
| 描述 | 更新坐标系。 |
| 请求参数 | h : ArmHandle* ,C99 会话句柄,通常来自 Arm_Create() ,业务接口需要先连接成功coordinateSystemType : int ,坐标系类型,用户坐标系或工具坐标系coordinate : const ArmCoordinate* ,坐标系详情结构体指针 |
| 返回值 | STATUS_CODE 整数值; 0 表示成功,其他值按状态码处理 |
Arm_CoordinateSystem_Delete
c
int Arm_CoordinateSystem_Delete(ArmHandle* h, int coordinateSystemType, int32_t id);| 项 | 说明 |
|---|---|
| 描述 | 删除坐标系。 |
| 请求参数 | h : ArmHandle* ,C99 会话句柄,通常来自 Arm_Create() ,业务接口需要先连接成功coordinateSystemType : int ,坐标系类型,用户坐标系或工具坐标系id : int32_t ,坐标系编号 |
| 返回值 | STATUS_CODE 整数值; 0 表示成功,其他值按状态码处理 |
Arm_CoordinateSystem_Calculate
c
int Arm_CoordinateSystem_Calculate(ArmHandle* h, int coordinateSystemType, const ArmCoordinate* coordinates, size_t count, ArmCoordinatePose* outPose);| 项 | 说明 |
|---|---|
| 描述 | 根据示教点计算坐标系位姿。 |
| 请求参数 | h : ArmHandle* ,C99 会话句柄,通常来自 Arm_Create() ,业务接口需要先连接成功coordinateSystemType : int ,坐标系类型,用户坐标系或工具坐标系coordinates : const ArmCoordinate* ,用于计算坐标系的示教点数组count : size_t ,数组元素数量outPose : ArmCoordinatePose* ,位姿输出结构体指针 |
| 返回值 | STATUS_CODE 整数值; 0 表示成功,其他值按状态码处理 |
类型与规则
ArmCoordinateSystemType
| 枚举值 | 值 | 说明 |
|---|---|---|
ARM_COORDINATE_SYSTEM_USER_FRAME | 0 | 用户坐标系,描述工件、工位等用户定义坐标 |
ARM_COORDINATE_SYSTEM_TOOL_FRAME | 1 | 工具坐标系,描述末端工具 TCP 坐标 |
ArmCoordinatePose
| 字段 | 类型 | 说明 |
|---|---|---|
x | double | X 方向位置 |
y | double | Y 方向位置 |
z | double | Z 方向位置 |
a | double | A 姿态角 |
b | double | B 姿态角 |
c | double | C 姿态角 |
ArmCoordinateInfo
| 字段 | 类型 | 说明 |
|---|---|---|
id | int32_t | 坐标系编号 |
name | char[128] | 坐标系名称 |
comment | char[256] | 坐标系备注 |
groupId | int32_t | 分组 ID |
ArmCoordinate
| 字段 | 类型 | 说明 |
|---|---|---|
id | int32_t | 坐标系编号 |
name | char[128] | 坐标系名称 |
comment | char[256] | 坐标系备注 |
groupId | int32_t | 分组 ID |
data | ArmCoordinatePose | 坐标系位姿 |
使用前提与失败口径
| 场景 | 返回 |
|---|---|
| 未连接或句柄无效 | OTHER_ERR |
| 坐标系类型非法 | INVALID_PARAMETER |
Arm_CoordinateSystem_Calculate() 缺少机器人型号信息 | INVALID_PARAMETER |
| 必填输入或输出指针为空 | INVALID_PARAMETER |
Arm_CoordinateSystem_GetList() 的 outArray == NULL | 只查询数量,成功时写入 outCount |
Arm_CoordinateSystem_GetList() 缓冲区容量不足 | BUFFER_TOO_SMALL |
Arm_CoordinateSystem_Calculate() 依赖连接后获得的机器人型号信息。调用方需要先完成 Arm_Connect() ,并传入用于标定的坐标点数组。
笛卡尔角度环绕
Arm_CoordinateSystem_Calculate() 返回的 ArmCoordinatePose 中,姿态分量 a / b / c 的取值范围为 [-180, 180] 。同一物理姿态可能表示为 -180 或 180 ,两者等价。
比较两个位姿是否接近时, x / y / z 可以直接比较差值; a / b / c 需要先按 360 度周期归一化,避免出现跨越边界导致的虚假偏差。
c
double posDiff = fabs(pose1.x - pose2.x); // 位置分量可以直接比较差值
double angleDiff = fmod(fabs(pose1.a - pose2.a), 360.0); // 姿态角按 360 度周期折算
if (angleDiff > 180.0) { // 跨过 180 度时取较短方向
angleDiff = 360.0 - angleDiff;
}最小调用示例
c
#include <stdio.h> // 引入 printf,用于打印坐标系数量
#include "c_arm_api.h" // 引入 C99 SDK 总头文件
int main(void) // 示例程序入口
{ // 进入示例主函数
ArmHandle* h = Arm_Create(); // 创建 C99 会话句柄
ArmCoordinateInfo infos[8] = {0}; // 准备坐标系列表数组
size_t count = 0U; // 准备坐标系数量输出
if (h == NULL) { // 判断句柄是否创建失败
return 1; // 创建失败时退出
} // 结束句柄判断
if (Arm_Connect(h, "10.27.1.2", "10.27.1.102") != 0) { // 连接控制器
Arm_Destroy(h); // 连接失败时释放句柄
return 1; // 返回错误
} // 结束连接判断
int ret = Arm_CoordinateSystem_GetList(h, ARM_COORDINATE_SYSTEM_USER_FRAME, infos, 8, &count); // 查询用户坐标系列表
printf("coordinate_count=%zu\n", count); // 打印坐标系数量
Arm_Disconnect(h); // 断开连接
Arm_Destroy(h); // 销毁句柄
return ret == 0 ? 0 : 1; // 根据查询结果返回
} // 结束示例主函数场景化示例
c
ArmCoordinateInfo infos[8] = {0}; // 准备坐标系列表数组
ArmCoordinate coord = {0}; // 准备坐标系详情结构
ArmCoordinatePose pose = {0}; // 准备计算结果位姿
size_t coordCount = 0U; // 准备坐标系数量输出
int listRet = Arm_CoordinateSystem_GetList(h, ARM_COORDINATE_SYSTEM_USER_FRAME, infos, 8, &coordCount); // 查询用户坐标系列表
int getRet = Arm_CoordinateSystem_Get(h, ARM_COORDINATE_SYSTEM_USER_FRAME, 1, &coord); // 查询 1 号用户坐标系
int calcRet = Arm_CoordinateSystem_Calculate(h, ARM_COORDINATE_SYSTEM_USER_FRAME, &coord, 1, &pose); // 根据示教点计算坐标系
/* int addRet = Arm_CoordinateSystem_Add(h, ARM_COORDINATE_SYSTEM_USER_FRAME, &coord); */ // 新增坐标系会修改配置,确认后再执行
/* int updateRet = Arm_CoordinateSystem_Update(h, ARM_COORDINATE_SYSTEM_USER_FRAME, &coord); */ // 更新坐标系会修改配置,确认后再执行
/* int deleteRet = Arm_CoordinateSystem_Delete(h, ARM_COORDINATE_SYSTEM_USER_FRAME, 1); */ // 删除坐标系会修改配置,确认后再执行
(void)listRet; // 示例中保留列表状态码
(void)getRet; // 示例中保留详情状态码
(void)calcRet; // 示例中保留计算状态码示例代码
cpp
#include <stdio.h>
#include <string.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_coordinate] 创建句柄失败 / 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_coordinate] 连接失败 / Connect failed, 状态码 / Status code: %d\n", ret);
Arm_Destroy(handle);
return 1;
}
printf("[c99_coordinate] 机器人连接成功 / Robot connected successfully\n");
// [ZH] 读取工具坐标系列表与第一个坐标系详情。
// [EN] Read the tool-frame list and the first frame detail.
ArmCoordinateInfo infoList[8] = {0};
size_t infoCount = 0U;
ret = Arm_CoordinateSystem_GetList(handle, ARM_COORDINATE_SYSTEM_TOOL_FRAME, infoList, 8U, &infoCount);
printf("[c99_coordinate] GetList 状态码 / GetList status code: %d, 数量 / Count: %zu\n", ret, infoCount);
if (infoCount > 0U) {
ArmCoordinate detail = {0};
ret = Arm_CoordinateSystem_Get(handle, ARM_COORDINATE_SYSTEM_TOOL_FRAME, infoList[0].id, &detail);
printf("[c99_coordinate] Get 状态码 / Get status code: %d, id=%d, name=%s\n", ret, detail.id, detail.name);
}
// [ZH] 构造 3 点并计算用户坐标系。
// [EN] Build three points and calculate a user frame.
ArmCoordinate calculatePoints[3] = {0};
for (int index = 0; index < 3; ++index) {
calculatePoints[index].id = index + 1;
calculatePoints[index].groupId = 1;
snprintf(calculatePoints[index].name, sizeof(calculatePoints[index].name), "p%d", index + 1);
snprintf(calculatePoints[index].comment, sizeof(calculatePoints[index].comment), "sdk example");
calculatePoints[index].data.x = 1.0 + index * 3.0;
calculatePoints[index].data.y = 2.0 + index * 3.0;
calculatePoints[index].data.z = 3.0 + index * 3.0;
calculatePoints[index].data.a = 10.0 + index * 30.0;
calculatePoints[index].data.b = 20.0 + index * 30.0;
calculatePoints[index].data.c = 30.0 + index * 30.0;
}
ArmCoordinatePose pose = {0};
ret = Arm_CoordinateSystem_Calculate(handle, ARM_COORDINATE_SYSTEM_USER_FRAME, calculatePoints, 3U, &pose);
printf("[c99_coordinate] Calculate 状态码 / Calculate status code: %d, 位姿 / Pose: [%.6f, %.6f, %.6f, %.6f, %.6f, %.6f]\n",
ret,
pose.x,
pose.y,
pose.z,
pose.a,
pose.b,
pose.c);
// [ZH] 顺序执行新增、更新和删除接口。
// [EN] Execute the add, update, and delete APIs in sequence.
ArmCoordinate userFrame = {0};
userFrame.id = 10;
userFrame.groupId = 1;
snprintf(userFrame.name, sizeof(userFrame.name), "user_demo");
snprintf(userFrame.comment, sizeof(userFrame.comment), "sdk example");
userFrame.data = pose;
ret = Arm_CoordinateSystem_Add(handle, ARM_COORDINATE_SYSTEM_USER_FRAME, &userFrame);
printf("[c99_coordinate] Add 状态码 / Add status code: %d\n", ret);
ret = Arm_CoordinateSystem_Update(handle, ARM_COORDINATE_SYSTEM_USER_FRAME, &userFrame);
printf("[c99_coordinate] Update 状态码 / Update status code: %d\n", ret);
ret = Arm_CoordinateSystem_Delete(handle, ARM_COORDINATE_SYSTEM_USER_FRAME, userFrame.id);
printf("[c99_coordinate] Delete 状态码 / Delete status code: %d\n", ret);
// [ZH] 断开连接并销毁句柄。
// [EN] Disconnect and destroy the handle.
Arm_Disconnect(handle);
Arm_Destroy(handle);
printf("[c99_coordinate] 示例结束 / Example finished\n");
return 0;
}