이전 버전(1.33.4)의 문서를 보고 있습니다. 이 버전은 계속 지원됩니다.
최신 버전 정보는 1.33.5에서 확인하세요.

calc_coord (수동 모드)

이 절에서는 수동(교시) 작업 중에 calc_coord를 사용하는 방법을 설명합니다. 이 함수는 측정한 몇 개의 포즈(점/벡터)로 사용자 좌표계(포즈)를 계산합니다. 따라서 작업물 좌표계를 영구적으로 저장하지 않고도 검증하거나 다듬을 수 있습니다.

일반적으로 표면에서 2~4개의 점을 측정해 정규 직교 좌표계를 계산한 다음, 위치를 변환하고 비교해 검증합니다.

일반적인 사용법

  • 3개의 점(원점, X 방향 점, XY 평면 점)으로 임시 작업 좌표계를 빠르게 구합니다.

  • 2-벡터 방식(X 벡터 + Y 벡터 + 원점)으로 TCP를 알려진 지그 방향에 맞춥니다.

  • 저장하기 전에 기존 좌표계를 다시 계산하고 coord_transform과 비교해 검증합니다.

참고

  • 모든 입력 포즈는 [X, Y, Z, Rx, Ry, Rz] 순서의 배열이며, eTargetRef(예: BASE)를 기준으로 해석됩니다.

  • 반환된 포인터는 CDRFLEx 객체 안의 저장 공간을 가리키며, 이 공간은 다른 DRFL 호출과 재연결 때마다 다시 사용됩니다. 다른 DRFL 함수를 호출하기 전에 구조체를 복사해 두세요. 인수가 3개인 ikin은 프로세스 안의 모든 CDRFLEx 객체가 공유하는 저장 공간에 결과를 반환합니다. ikin을 참고하세요. get_user_home을 제외하면 포인터는 NULL이 아닙니다. 실패 여부를 NULL 검사로 판단하지 마세요.

예제: 3점 평면 측정 → 좌표계 계산

// 헬퍼: ROBOT_TASK_POSE를 float[6] 버퍼로 복사
static void copy_pos6(float out[6], const LPROBOT_TASK_POSE p) {
    out[0] = p->_fTargetPos[0];  out[1] = p->_fTargetPos[1];  out[2] = p->_fTargetPos[2];
    out[3] = p->_fTargetPos[3]; out[4] = p->_fTargetPos[4]; out[5] = p->_fTargetPos[5];
}

// 가정: 연결됨, 수동 모드, 서보 온, 안전한 작업 영역.

// --- 1단계. 평평한 작업물 위의 세 점 터치(BASE 좌표계) ---
// O: 좌표계 원점으로 삼을 모서리, Xp: +X 방향의 점, Yp: XY 평면 안의 점
float O[6], Xp[6], Yp[6], Zz[6] = {0};  // 3점 방식에서는 Zz 사용 안 함
{
    // 작업자가 모서리(원점)로 조그 이동한 후 기록
    // (GUI에서는 버튼에 현재 위치 저장 기능을 연결하세요)
    auto pO  = drfl.get_current_posx(COORDINATE_SYSTEM_BASE);
    copy_pos6(O, pO);
    printf("Captured Origin O: (%.3f, %.3f, %.3f)\n", O[0], O[1], O[2]);

    // +X를 정의하는 모서리를 따라 조그 이동
    // (여기의 짧은 조그는 설명용이며, 실제로는 티치펜던트로 조그합니다)
    drfl.jog(JOG_AXIS_TASK_X, MOVE_REFERENCE_BASE, 5.0f);
    std::this_thread::sleep_for(std::chrono::milliseconds(600));
    drfl.stop(STOP_TYPE_SLOW); drfl.mwait();
    auto pXp = drfl.get_current_posx(COORDINATE_SYSTEM_BASE);
    copy_pos6(Xp, pXp);
    printf("Captured X-edge Xp: (%.3f, %.3f, %.3f)\n", Xp[0], Xp[1], Xp[2]);

    // 표면 안에서 이동해 XY 평면(+Y 방향) 정의
    drfl.jog(JOG_AXIS_TASK_Y, MOVE_REFERENCE_BASE, 5.0f);
    std::this_thread::sleep_for(std::chrono::milliseconds(600));
    drfl.stop(STOP_TYPE_SLOW); drfl.mwait();
    auto pYp = drfl.get_current_posx(COORDINATE_SYSTEM_BASE);
    copy_pos6(Yp, pYp);
    printf("Captured Y-plane Yp: (%.3f, %.3f, %.3f)\n", Yp[0], Yp[1], Yp[2]);
}

// --- 2단계. 기록한 세 점으로 좌표계 계산 ---
// nCnt = 3, nInputMode = (3점 방식, 열거형 참고), eTargetRef = BASE
unsigned short nCnt = 3;
unsigned short nInputMode = /* INPUT_MODE_3POINT */ 0; // 상수 참고
LPROBOT_POSE pFrame = drfl.calc_coord(
    nCnt, nInputMode, COORDINATE_SYSTEM_BASE,
    O, Xp, Yp, Zz /* 3점 방식에서는 사용 안 함 */
);

printf("\nComputed Frame (pose in BASE):\n");
printf("X: %.3f  Y: %.3f  Z: %.3f  Rx: %.3f  Ry: %.3f  Rz: %.3f\n",
       pFrame->_fPosition[0], pFrame->_fPosition[1], pFrame->_fPosition[2],
       pFrame->_fPosition[3], pFrame->_fPosition[4], pFrame->_fPosition[5]);

// --- 3단계. (선택 사항) 결과가 적절하면 set_user_cart_coord2/3으로 저장 ---
// 예: set_user_cart_coord2({O, Xp, Yp}, O, COORDINATE_SYSTEM_BASE);

팁

  • 3점 방식: 점 사이 간격을 충분히 두고 선택하세요. 수치 오차를 줄이려면 거의 일직선에 놓인 점은 피하세요.

  • 2-벡터 방식: 원본 벡터를 정규화하고 두 벡터가 거의 평행하지 않은지 확인하세요.

  • 저장하기 전에 get_current_rotm과 get_orientation_error로 직교성과 정렬 편차를 확인하세요.

  • 이 좌표계를 저장하려면 먼저 calc_coord로 계산하고 검증한 다음, set_user_cart_coord2 / set_user_cart_coord3로 저장하세요.