mplib 경로 계획이 실패하면: move_group 관절과 IK·경로 탐색을 나눠 확인하기

mplib가 경로를 찾지 못했을 때는 먼저 목표 링크와 관절 배열의 의미를 확인하고, 그다음 목표 자세의 관절 해를 찾는 IK 단계와 그 해까지 이동하는 경로 탐색 단계를 나눠 봐야 합니다. IK 실패, 경로 탐색 실패, 제어기의 추종 실패는 다음에 확인할 값이 서로 다릅니다. 어느 하나를 곧바로 “로봇이 그 위치에 갈 수 없다”는 결론으로 바꾸면 원인을 놓칠 수 있습니다.

이 글은 2026년 10월 15일 확인한 mplib 0.2.1 stable 문서와 문서가 연결한 코드 revision 86376ca87d2c055b792d8cea4d15a38e861d866f를 기준으로 합니다. 설치, IK 계산, 경로 계획, 시뮬레이션 실행은 하지 않았습니다. 아래 예시는 입력과 결과를 읽는 방법을 설명하며, 실제 로봇의 도달성이나 충돌 안전성을 검증한 결과가 아닙니다.

목표 링크가 정하는 관절과 입력 배열을 맞추세요

Planner 설정 문서에서 move_group은 목표 자세를 지정할 링크 이름입니다. mplib는 루트에서 그 링크까지 이어지는 경로의 활성 관절을 계획 대상으로 삼습니다. 관절 이름 목록이나 로봇의 모든 자유도를 뜻하는 인자가 아닙니다.

문서의 Panda 예에서는 panda_hand 자세에 팔 관절 7개가 영향을 주고, 뒤의 손가락 관절 2개는 그 링크의 자세에 영향을 주지 않습니다. 그렇다고 손가락 상태가 충돌 모델이나 다음 작업에 무관하다는 뜻은 아닙니다. 팔 경로를 계획하는 범위와 로봇 전체의 현재 상태를 구분해야 합니다.

시뮬레이터가 내보내는 관절 배열 순서도 맞춰야 합니다. user_joint_names와 user_link_names는 사용자가 지정하는 순서를 전달하는 설정입니다. 두 배열의 길이가 같아도 첫 번째 값이 서로 다른 관절을 가리키면 출발 자세가 달라집니다. 이름과 값을 나란히 놓고, 고정 관절을 제외한 활성 관절 순서가 일치하는지 먼저 확인하세요.

현재 관절 입력에는 문서 안에서도 설명 수준의 차이가 있습니다. 경로 계획 튜토리얼은 전체 활성 관절의 현재 값을 전달하라고 안내하지만, API 설명은 전체 또는 move-group 관절 벡터를 받을 수 있다고 적습니다. 해당 revision의 planner.py의 보충 함수는 부분 벡터를 받으면 생략한 관절 값을 내부 로봇 모델의 현재 상태에서 가져옵니다.

따라서 부분 벡터를 쓸 때는 생략한 관절이 어떤 값으로 채워지는지까지 확인해야 합니다. 선택한 plan_pose 코드에는 이 보충보다 먼저 관절 제한에 맞추는 배열 연산도 있습니다. API 주석만 보고 모든 축소 배열과 호출 조건이 그대로 통과한다고 단정하지 마세요. 문제를 재현할 첫 기록에는 튜토리얼처럼 전체 현재 관절 벡터와 이름 순서를 함께 남기는 편이 명확합니다.

IK가 실패했는지, 연결 경로가 실패했는지 구분합니다

경로 계획 문서는 plan_pose()가 먼저 목표 링크 자세에 대한 IK를 풀고, 얻은 관절 해를 향해 RRTConnect로 경로를 찾은 뒤 시간 정보를 붙인다고 설명합니다. 실제 코드에서도 IK가 성공하지 않으면 그 상태를 즉시 반환하므로 경로 탐색까지 진행됐다고 볼 수 없습니다.

결과가 나온 단계 확인할 내용 아직 결론 내릴 수 없는 것
IK 목표 좌표계·자세, 관절 제한, 사용한 초기값, 충돌 조건 물리적으로 가능한 자세가 전혀 없다는 증명
RRTConnect 경로 탐색 출발 상태, 목표 관절 해, 충돌 모델, 탐색 시간·설정 다른 조건이나 더 나은 탐색에서도 경로가 없다는 증명
경로 생성 뒤 제어 실행 관절 매핑, 위치·속도 참조, 제어기 설정과 추종 계획 성공만으로 실제 작업까지 완료됐다는 판단

IK는 단순히 말단 위치의 방정식만 맞추는 단계로 읽어서도 안 됩니다. 확인한 구현은 후보 해에 관절 제한과 충돌 검사를 적용합니다. 관절 해가 계산됐어도 이런 조건에서 탈락할 수 있습니다. 목표의 좌표계나 충돌 모델을 잘못 넣었다면 무작정 탐색 시간을 늘리는 것으로 입력 오류가 해결되지는 않습니다.

로그에서는 문서의 요약 이름과 코드의 실제 문자열을 구분하세요. 튜토리얼은 IK Failed, RRT Failed로 분류하지만, 이 revision은 IK 실패에 설명을 덧붙이고 경로 실패에는 RRTConnect Failed. 뒤에 내부 상태를 붙여 반환합니다. 실패 문자열을 지나치게 짧은 이름 하나와만 비교하면 분류가 빗나갈 수 있습니다. 원문 상태를 보존한 뒤 확인한 버전의 반환 규칙에 맞춰 분류하는 편이 좋습니다.

목표 자세의 기준도 로그에 남겨야 합니다. 문서는 기본 목표를 월드 좌표 기준으로 설명하고, wrt_world=False를 지정하면 로봇 베이스 기준으로 해석한다고 안내합니다. 같은 숫자라도 기준 좌표가 다르면 다른 목표입니다. 좌표를 맞추기 전에 알고리즘의 실패로 판단하지 마세요.

곧장 가는 screw motion은 장애물을 돌아가지 않습니다

plan_screw()는 현재 말단 자세에서 목표까지의 상대 변환을 이용해 이동을 계산하는 경로입니다. 문서에 따르면 이 방식은 장애물을 피해 우회하거나 다시 계획하지 않습니다. 확인한 코드에서도 충돌, 관절 제한 위반이나 충분히 진행하지 못하는 조건에서 실패를 반환합니다.

가령 팔의 시작점과 목표점 사이에 기둥이 있다고 가정해 보겠습니다. 직접 진행하는 방식은 기둥과 충돌해 실패하지만, 관절 공간을 탐색하면 옆으로 돌아가는 경로가 있을 수 있습니다. 이 예시는 두 계획 방식의 차이를 보여줄 뿐이며, 실제 기둥이나 로봇 모델로 계산한 결과는 아닙니다. 반대로 RRTConnect를 선택했다고 반드시 우회 경로를 찾는 것도 아닙니다.

또 하나 확인할 것이 환경 모델입니다. 기본 경로 계획 튜토리얼은 해당 예제에서 로봇의 자기 충돌만 피한다고 명시합니다. 화면에 물체가 보인다는 사실만으로 그 물체가 플래너의 장애물로 들어갔다고 볼 수 없습니다. 환경을 포함한 충돌 모델이 준비됐는지 확인한 뒤 결과를 해석해야 합니다.

실패 기록은 입력 모델·관절 순서·목표 좌표계, IK 반환값, 경로 탐색 반환값, 실제 추종 결과 순서로 나누어 남기면 다음 수정 지점이 분명해집니다. 모션 플래닝과 궤적 최적화의 차이가 전체 흐름을 설명한다면, 여기서는 그중 어느 단계가 실제로 수행됐고 어디서 멈췄는지를 확인하는 것이 먼저입니다.