3.15 CoordinateSystemManager 坐标系管理
概述
Arm::coordinateSystemManager 用于管理用户坐标系和工具坐标系。 公开能力包括:
- 查询坐标系列表
- 查询单个坐标系详情
- 新增、更新、删除坐标系
- 计算坐标系位姿
公开方法
cpp
GetCoordinateList(coordinate_system_model::COORDINATE_SYS_TYPE coordinateSysType) -> std::pair<std::vector<coordinate_system_model::CoordinateInfo>, STATUS_CODE>
Get(coordinate_system_model::COORDINATE_SYS_TYPE coordinateSysType, int32_t id) -> std::pair<coordinate_system_model::Coordinate, STATUS_CODE>
Add(coordinate_system_model::COORDINATE_SYS_TYPE coordinateSysType, coordinate_system_model::Coordinate coordinate) -> STATUS_CODE
Update(coordinate_system_model::COORDINATE_SYS_TYPE coordinateSysType, coordinate_system_model::Coordinate coordinate) -> STATUS_CODE
Delete(coordinate_system_model::COORDINATE_SYS_TYPE coordinateSysType, int32_t id) -> STATUS_CODE
Calculate(coordinate_system_model::COORDINATE_SYS_TYPE coordinateSysType, std::vector<coordinate_system_model::Coordinate> coordinate) -> std::pair<CartesianPosition, STATUS_CODE>| 方法 | 输入 | 输出 | 说明 |
|---|---|---|---|
GetCoordinateList | 坐标系类型 | std::pair<std::vector<coordinate_system_model::CoordinateInfo>, STATUS_CODE> | 获取列表 |
Get | 坐标系类型、ID | std::pair<coordinate_system_model::Coordinate, STATUS_CODE> | 获取详情 |
Add | 坐标系类型、坐标系对象 | STATUS_CODE | 新增 |
Update | 坐标系类型、坐标系对象 | STATUS_CODE | 更新 |
Delete | 坐标系类型、ID | STATUS_CODE | 删除 |
Calculate | 坐标系类型、标定点列表 | std::pair<CartesianPosition, STATUS_CODE> | 计算坐标系位姿 |
类型口径
coordinate_system_model::COORDINATE_SYS_TYPE
头文件: include/coordinate_sys_type.h
coordinate_system_model::COORDINATE_SYS_TYPE 用来告诉坐标系接口当前操作的是用户坐标系还是工具坐标系。所有 Get / Add / Update / Delete / Calculate 接口都需要它。
| 枚举 | 值 | 说明 |
|---|---|---|
USER_FRAME | 0 | 用户坐标系,描述工件、工位等用户定义坐标 |
TOOL_FRAME | 1 | 工具坐标系,描述末端工具 TCP 坐标 |
coordinate_system_model::CoordinateInfo
| 字段 | 类型 | 说明 |
|---|---|---|
id | int32_t | 坐标系编号 |
name | std::string | 坐标系名称 |
comment | std::string | 备注 |
groupId | int32_t | 分组 ID,默认 1 |
coordinate_system_model::Coordinate
| 字段 | 类型 | 说明 |
|---|---|---|
id | int32_t | 坐标系编号 |
name | std::string | 坐标系名称 |
comment | std::string | 备注 |
groupId | int32_t | 分组 ID,默认 1 |
data | CartesianPosition | 坐标系位姿,按 x/y/z/a/b/c 表示 |
使用前提
- 需要先完成
Arm::Connect()。 Calculate()依赖连接后回填的机器人型号信息;未完成连接或型号不可用时会失败。- 同一个
Arm会话上的坐标系请求仍按统一网络线程串行执行。
失败口径
| 场景 | 返回 |
|---|---|
| 未连接或接口模块未初始化 | OTHER_ERR |
| 坐标系类型非法 | INVALID_PARAMETER |
Calculate 缺少型号信息 | INVALID_PARAMETER |
注意事项:笛卡尔角度环绕
Calculate() 返回的 CartesianPosition 中,姿态分量 a / b / c (欧拉角)的取值范围为 [-180°, 180°]。同一物理姿态可能被表示为 -180° 或 180°,两者等价。
在比较两个位姿是否 "接近" 时,位置分量( x / y / z )可以直接做差取绝对值,但姿态分量必须先做 360° 环绕归一化,否则会出现 360° 的虚假偏差。
推荐的比较方式:
cpp
double posDiff = std::abs(pose1.x - pose2.x); // 位置分量可以直接比较差值
double angleDiff = std::fmod(std::abs(pose1.a - pose2.a), 360.0); // 姿态分量先折算到 360 度周期内
if (angleDiff > 180.0) { // 判断角度差是否跨过 180 度
angleDiff = 360.0 - angleDiff; // 使用较短方向上的角度差
} // 结束角度差归一化判断此规则适用于所有返回笛卡尔位姿的接口,包括 MotionControl 、 TrajectoryManager 、 CoordinateSystemManager 等模块。
场景化示例
下面几组片段按 “查询、计算、新增更新、删除” 交叉覆盖本页 API。片段默认承接已经连接成功的 arm 对象;新增、更新和删除会改变控制器坐标系配置,确认后再执行。
查询坐标系列表和详情
cpp
auto [userList, listRet] = arm.coordinateSystemManager.GetCoordinateList( // 查询用户坐标系列表
coordinate_system_model::COORDINATE_SYS_TYPE::USER_FRAME // 指定用户坐标系类型
); // 结束坐标系列表查询调用
auto [userCoord, getRet] = arm.coordinateSystemManager.Get( // 查询指定用户坐标系详情
coordinate_system_model::COORDINATE_SYS_TYPE::USER_FRAME, // 指定用户坐标系类型
1 // 指定坐标系 ID
); // 结束坐标系详情查询调用
if (listRet == STATUS_CODE::OK || getRet == STATUS_CODE::OK) { // 判断坐标系查询是否成功
std::cout << "coordinate_count=" << userList.size() << " name=" << userCoord.name << "\n"; // 打印坐标系查询摘要
} // 结束坐标系查询判断计算坐标系位姿
cpp
coordinate_system_model::Coordinate point; // 创建标定点对象
point.data = CartesianPosition{0, 0, 0, 0, 0, 0}; // 设置标定点位姿示例
std::vector<coordinate_system_model::Coordinate> samplePoints = {point, point, point}; // 准备用于计算坐标系的标定点示例
auto [calculatedPose, calculateRet] = arm.coordinateSystemManager.Calculate( // 根据标定点计算坐标系位姿
coordinate_system_model::COORDINATE_SYS_TYPE::USER_FRAME, // 指定用户坐标系类型
samplePoints // 传入标定点列表
); // 结束坐标系计算调用新增和更新坐标系
cpp
coordinate_system_model::Coordinate coord; // 创建待新增或更新的坐标系对象
coord.id = 1; // 设置坐标系 ID 示例
coord.name = "sdk_user_frame"; // 设置坐标系名称
coord.comment = "created by sdk example"; // 设置坐标系备注
coord.groupId = 1; // 设置坐标系分组 ID
coord.data = CartesianPosition{0, 0, 0, 0, 0, 0}; // 设置坐标系位姿
// STATUS_CODE addRet = arm.coordinateSystemManager.Add(coordinate_system_model::COORDINATE_SYS_TYPE::USER_FRAME, coord); // 新增坐标系会改变控制器配置,确认后再执行
coord.comment = "updated by sdk example"; // 修改备注字段,准备展示更新调用
// STATUS_CODE updateRet = arm.coordinateSystemManager.Update(coordinate_system_model::COORDINATE_SYS_TYPE::USER_FRAME, coord); // 更新坐标系会改变控制器配置,确认后再执行删除坐标系
cpp
// STATUS_CODE deleteRet = arm.coordinateSystemManager.Delete(coordinate_system_model::COORDINATE_SYS_TYPE::USER_FRAME, 1); // 删除坐标系会改变控制器配置,确认后再执行示例
cpp
#include "query_coordinate_systems/run.h"
#include "calculate_user_frame/run.h"
#include "write_coordinate_systems/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 RunCoordinateSystemBasicQueryCoordinateSystems();
// return RunCoordinateSystemBasicCalculateUserFrame();
// return RunCoordinateSystemBasicWriteCoordinateSystems();
}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;
}