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) // 예제 프로그램 진입점
{ // 예제 main 함수 시작
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; // 조회 결과에 따라 반환합니다.
} // 예제 main 함수 종료시나리오 예제
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;
}