Skip to content

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_FRAME0사용자 좌표계입니다. 공작물, 작업 위치 등 사용자가 정의한 좌표를 설명합니다.
ARM_COORDINATE_SYSTEM_TOOL_FRAME1도구 좌표계입니다. 말단 도구의 TCP 좌표를 설명합니다.

ArmCoordinatePose

필드타입설명
xdoubleX 방향 위치
ydoubleY 방향 위치
zdoubleZ 방향 위치
adoubleA 자세각
bdoubleB 자세각
cdoubleC 자세각

ArmCoordinateInfo

필드타입설명
idint32_t좌표계 번호
namechar[128]좌표계 이름
commentchar[256]좌표계 비고
groupIdint32_t그룹 ID

ArmCoordinate

필드타입설명
idint32_t좌표계 번호
namechar[128]좌표계 이름
commentchar[256]좌표계 비고
groupIdint32_t그룹 ID
dataArmCoordinatePose좌표계 자세

사용 전제 및 실패 기준

시나리오반환
연결되지 않았거나 핸들이 유효하지 않음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;  // 예제에서 계산 상태 코드를 유지합니다.

예제 코드

c99/coordinate_system_basic/src/main.cpp
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;
}