mplib에서 주변 장애물과 로봇이 운반하는 물체는 서로 다른 방식으로 표현합니다. 환경 포인트클라우드는 월드 좌표에 등록하고, 손에 든 물체는 로봇 링크에 대한 상대 자세로 붙입니다. 주변 상자를 피하는 팔 경로를 찾았더라도, 손에 든 상자의 부피를 모델에 넣지 않았다면 그 상자까지 고려한 경로가 되지는 않습니다.
이 구분은 센서 점군을 가져올 때도 중요합니다. 관측된 점에는 벽과 탁자뿐 아니라 로봇 자신의 팔이나 운반 물체가 섞일 수 있습니다. 어떤 점을 환경 장애물로 남기고, 어떤 형상을 로봇과 함께 움직이게 할지 정해야 충돌 모델이 의도한 장면을 표현합니다.
환경 점의 좌표와 소유 대상을 먼저 정한다
mplib Collision Avoidance 튜토리얼은 update_point_cloud()의 입력을 (n, 3) 형태의 NumPy 배열로 설명하며, 점의 좌표가 월드 프레임에 있어야 한다고 명시합니다. 센서 좌표에 있는 점을 사용한다면 촬영 시점의 센서 자세로 월드 좌표에 옮기는 단계가 앞에 필요합니다.
예를 들어 손목 카메라가 로봇과 함께 회전한다면 카메라 앞 0.5 m라는 좌표만으로는 장애물의 월드 위치가 정해지지 않습니다. 카메라 좌표의 점 p_C에 회전 R_WC와 이동 t_WC를 적용해 p_W = R_WC p_C + t_WC로 표현합니다. 여기서 회전과 이동은 그 점을 관측한 시점의 카메라 자세입니다.
튜토리얼은 센서 점군에서 로봇 팔의 점을 제거하라고 안내합니다. 이미 충돌 검사 대상인 로봇 형상이 환경 점군에도 들어가면 로봇이 자기 위치의 장애물과 겹치는 상황을 만들 수 있기 때문입니다. 이 문제에서는 플래너의 탐색 시간을 늘리기 전에, 등록한 점이 어느 물체에서 왔는지 확인하는 것이 직접적인 조치입니다.
운반 물체도 같은 소유 구분이 필요합니다. 상자를 링크에 붙여 이동시키면서 과거에 관측한 상자 점을 월드 장애물에 그대로 남기면, 이동하는 상자 모델과 이전 위치의 장애물 모델이 동시에 존재합니다. 물체를 집어 든 뒤에는 환경 점군에서 유지할 영역과 attached object로 표현할 영역을 함께 갱신하는 데이터 흐름이 필요합니다.
resolution은 충돌 점군을 표현하는 크기다
튜토리얼은 resolution을 점 주변에 충돌 버퍼를 만드는 데 사용할 수 있는 값으로 설명합니다. 현재 공개된 Planner 구현의 update_point_cloud() 주석은 더 구체적으로 point OcTree의 resolution이라고 적습니다. 이 함수는 이름·점·resolution을 planning_world.add_point_cloud()로 전달합니다.
따라서 이 값은 센서의 거리 측정 오차를 자동으로 계산한 결과가 아니라, 점군을 충돌 객체로 표현할 때 선택하는 공간 해상도입니다. 튜토리얼 예제는 0.02를 사용하지만, 그 숫자를 장면 전체에서 항상 확보되는 정확한 최소 이격 거리로 읽을 근거는 해당 코드에 없습니다. 실제 충돌 표현은 점의 분포와 공간 분할에도 영향을 받습니다.
가려진 영역에 점이 없거나 관측이 듬성듬성하면, 입력 점군이 담고 있는 환경 정보부터 달라집니다. 해상도를 바꾸는 일과 빠진 표면을 관측하는 일은 각각 충돌 표현과 센서 데이터의 문제입니다. 좁은 통로를 다룬다면 통로 벽이 충분히 관측됐는지와 선택한 resolution에서 그 공간이 어떻게 표현되는지를 함께 봐야 합니다.
현재 구현은 같은 이름의 점군을 다시 전달하면 그 객체를 갱신한다고 설명합니다. 환경이 그대로인 동안 모든 계획 호출에 같은 점군을 다시 넘길 필요는 없고, 관측이나 장면이 바뀌었을 때 등록된 충돌 객체를 갱신하는 구조입니다.
운반 상자는 링크와 함께 움직이는 변환으로 붙인다
현재 update_attached_box() 구현은 상자의 변 길이 size, 링크에서 물체로 가는 상대 자세 pose, 선택할 articulation과 link를 받습니다. link_id=-1이면 내부의 move_group_link_id를 사용하고, articulation 이름을 생략하면 해당 planner의 로봇에 붙입니다.
월드를 W, 부착 링크를 L, 상자를 B라고 쓰면 이 관계는 다음과 같습니다. T_WL은 링크 좌표를 월드 좌표로, T_LB는 상자 좌표를 링크 좌표로 옮기는 변환입니다.
상자의 월드 자세: T_WB = T_WL × T_LB
고정된 부착 관계: T_LB
로봇이 움직이며 바뀌는 값: T_WL
가상의 좌표 예로, 상자 중심이 링크의 로컬 z 방향으로 0.1 m 떨어져 있다고 가정하겠습니다. 처음에는 링크와 월드의 축이 같고 링크 위치가 (0.4, 0, 0.3) m입니다. 다음에는 링크가 (0.6, 0, 0.3) m로 이동하면서 월드 y축 주위로 +90도 회전합니다. 이 회전에서는 링크의 로컬 +z 방향이 월드 +x 방향을 향합니다.
| 상태 | 링크 위치와 방향 | 링크에 붙인 상자 중심 | 처음 위치에 고정한 월드 상자 중심 |
|---|---|---|---|
| 첫 시점 | (0.4, 0, 0.3) m, 축 정렬 |
(0.4, 0, 0.4) m |
(0.4, 0, 0.4) m |
| 다음 시점 | (0.6, 0, 0.3) m, y축 +90도 회전 |
(0.7, 0, 0.3) m |
(0.4, 0, 0.4) m |
첫 시점에는 두 모델의 위치가 같습니다. 이후 링크가 움직이면 attached box는 부착 관계를 유지하며 이동·회전하지만, 월드에 고정한 상자는 제자리에 남습니다. 손에 든 물체의 충돌 부피를 링크에 연결하는 이유가 이 차이에 있습니다.
튜토리얼과 현재 코드의 호출 형식을 구분하기
확인한 stable 문서 안에서도 인터페이스 설명이 완전히 일치하지는 않습니다. Collision Avoidance 튜토리얼은 pose를 위치 3값과 wxyz 쿼터니언을 합친 7값 목록으로 보여 주고, 자세 방향을 상자에서 링크로 설명합니다. 현재 Planner 소스는 인자 타입을 Pose로 쓰며, 주석에서 attached link에서 object로의 상대 자세라고 명시합니다. 위 변환 예는 이 소스의 정의를 따릅니다.
환경과 부착 물체를 활성화하는 설명에도 차이가 있습니다. 튜토리얼은 use_point_cloud=True와 use_attach=True를 함께 사용한다고 안내하지만, 현재 공개된 plan_pose()와 plan_screw()의 함수 선언에는 두 인자가 없습니다. 현재 소스에서는 점군과 부착 물체를 planning_world에 등록하며, plan_screw()는 후보 관절 상태를 그 world에 반영한 뒤 is_state_colliding()을 호출합니다.
따라서 구형 예제의 플래그를 현재 함수 호출에 그대로 덧붙이기보다, 설치한 버전의 인자와 planning world 등록 경로를 맞춰야 합니다. 충돌 모델의 역할은 환경 점군과 부착 형상으로 설명할 수 있고, 이를 켜고 갱신하는 실제 API는 해당 버전의 구현을 기준으로 연결해야 합니다.
주변 장애물, 로봇 형상, 운반 물체를 이렇게 구분하면 “어떤 몸체가 어떤 장애물과 겹쳤는가”를 기준으로 입력 모델을 살펴볼 수 있습니다. 목표 관절 해의 실패와 연결 경로의 실패를 구분하는 내용은 mplib move_group·IK·경로 탐색 설명에서, 이동 중 유지할 방향 조건은 mplib 경로 제약과 관절 고정에서 이어집니다.
2026년 10월 16일 확인한 공식 stable 튜토리얼과 Planner 소스를 해석했습니다. mplib 설치, 점군 등록, 경로 계획 또는 실제 로봇 실험은 수행하지 않았습니다.