Nav2를 하나의 주행 함수로 보지 않는다
Nav2는 이동 로봇의 탐색 과업을 여러 서버와 자료 흐름으로 구성하는 체계다. 지도와 현재 pose, 주변 장애물, 경로와 제어 명령이 서로 맞아야 한다. 서버는 요청을 받아 역할을 수행하는 노드이고 plugin은 서버가 선택해 사용하는 알고리즘 구현이다. 노드 이름이 보이거나 프로세스가 실행됐다는 사실만으로 목표까지 주행할 준비가 끝난 것은 아니다.
그림 M18.01-1. 각 칸은 서로 다른 역할/근거다. 아래 방향은 자료/처리의 연결이며 실제 성공을 자동으로 보장하지 않는다. 직접 제작한 개념도이며 본문의 조건과 함께 읽는다.
이 단위는 ROS 2 Jazzy/Ubuntu 24.04 기준 문서를 사용하되 실제 설치와 실행을 요구하지 않는다. 예제 구성은 저장된 지도를 Map Server가 제공하고 AMCL이 알려진 지도와 2D laser로 위치를 추정하는 경우다. SLAM으로 지도와 pose를 함께 갱신하는 구성에서는 자료 생산자가 달라질 수 있다. 같은 map→odom 변환을 두 추정기가 제각각 발행하도록 만들지 말고 어떤 노드가 책임지는지 정한다.
지도, 비용 지도, 위치 추정은 다른 역할이다
Map Server는 저장된 지도 자료를 로딩해 제공한다. 지도 파일에 현재 로봇 위치가 들어 있는 것은 아니다. AMCL은 지도와 관측에서 pose를 추정하고 선택한 구성의 map·odom 관계를 제공한다. 바퀴 등에서 얻은 odom→base_link와 센서 장착 TF도 함께 필요하다. map, odom, base_link는 각각 좌표 기준의 이름이며 토픽 이름과 구별한다. 지도 이름이 map이라고 위치가 참값이라는 뜻도 아니다.
costmap은 경로·제어 판단을 위해 공간의 비용과 장애물 정보를 격자에 표현한 것이다. 정적 지도와 실시간 센서, 로봇 형상 및 설정을 반영할 수 있으며 저장 점유 지도와 동일한 값 체계라고 가정하지 않는다. 이 예의 global costmap은 map 기준으로 넓은 계획을, local costmap은 odom 기준으로 주변 제어 판단을 담당한다고 설정한다. 실제 frame과 범위는 구성에서 확인해야 하며 두 이름만으로 모든 구현의 좌표가 고정되지는 않는다.
Planner와 Controller의 입력과 출력을 연결한다
Planner Server는 시작과 목표 pose, 계획에 필요한 costmap 및 선택한 planner plugin을 사용해 경로를 생성한다. Jazzy ComputePathToPose action 정의는 목표·시작·planner_id와 시작 사용 여부를 구별하고 결과에 path, 계획 시간과 오류를 담는다. '요청을 수락했다'와 '유효 경로를 반환했다'를 별도 사건으로 기록한다.
Controller Server는 경로를 따라갈 명령 속도를 계산하는 역할이다. FollowPath action은 경로 및 controller·goal checker·progress checker 선택을 담는다. goal checker는 도착 조건, progress checker는 진행 조건을 판단하는 plugin 역할이다. Controller는 이 선택과 현재 pose·속도, 주변 자료를 사용하지만 모터 자체나 실제 이동 결과와 같은 계층은 아니다.
명령 속도는 구동 adapter를 통해 로봇의 바퀴·구동 계약으로 연결된다. adapter는 주행 명령을 해당 구동계가 이해하는 형태로 옮기는 연결 계층이다. 경로 생성 성공, FollowPath 수락, cmd_vel 발행, 구동 적용, 실제 pose 변화와 도착 판정은 각각 근거가 다르다. 그중 하나만 확인한 로그로 마지막 성과를 채우지 않는다.
BT는 과업의 순서와 분기를 구성한다
Behavior Tree(BT)는 과업의 순서·조건·재시도 같은 제어 흐름을 나무 형태로 표현하는 방법이다. BT Navigator Jazzy 설명은 NavigateToPose와 NavigateThroughPoses 과업을 BT로 구성한다고 설명한다. 트리는 계획·경로 추종·실패 처리를 조직하지만 지도·센서와 유효한 제어 명령을 대신하지 않는다.
사용한 BT와 planner·controller plugin을 기록한다. 파일 이름만 같아도 내용이나 요청 대상이 달라지면 같은 계약이 아니다. 관리 상태와 과업 상태, 로봇의 물리 상태도 구분한다.
Lifecycle은 준비 과정을 제어하지만 성공을 대신하지 않는다
Lifecycle의 주요 상태는 Unconfigured, Inactive, Active, Finalized다. configure가 성공하면 필요한 자원을 준비한 Inactive로, activate가 성공하면 기능 운용을 시작하는 Active로 간다. Active에서 deactivate하면 Inactive, 그 뒤 cleanup을 통해 Unconfigured로 돌아가는 흐름을 사용할 수 있다. 전이는 요청과 callback 결과를 확인해야 하며 activate라는 문자열을 보냈다고 성공한 것은 아니다.
Jazzy Lifecycle Manager는 관리 대상 노드 목록의 configure와 activate를 순서 있게 처리한다. 목록 밖의 센서 드라이버나 다른 프로세스까지 자동으로 정상화하는 기능은 아니다. ROS lifecycle 설계의 관리 인터페이스와 실제 기능 callback은 구별하며, 모든 타이머·외부 I/O가 상태 이름만으로 멈춘다고 가정하지 않는다.
활성 상태는 현재 센서·시각별 TF·costmap의 준비를 증명하지 않는다. 이후 장치 단절이나 clock reset도 가능하므로 상태와 자료를 함께 점검한다. lifecycle 정지나 재시작도 로봇의 실제 정지·재개 관측을 대신하지 않는다.
합성 로그로 준비 실패의 층위를 찾는다
같은 clock 세대의 현재 시각은 12.05 s다. 정해진 점검 정책은 동적 scan·odom 표본 나이가 0.2 s 이하여야 한다는 것이다. known-map 구성에서 Map Server, Planner, Controller와 BT Navigator는 Active이고 AMCL만 Inactive다. 지도 v7은 제공 중이며 scan 취득 시각은 11.90 s, odom은 12.00 s다. odom→base_link와 base_link→laser TF는 있지만 map→odom은 없고 대체 위치 추정기도 없다고 입력을 제공한다.
scan 나이는 0.15 s로 허용보다 0.05 s 여유가 있고 odom 나이는 0.05 s다. 따라서 이 두 나이 검사는 통과한다. 그러나 map 기준 목표와 로봇 pose를 연결할 TF가 없어 전체 준비는 실패다. Planner가 Active라는 사실로 연결을 만들어 낼 수 없다. AMCL 활성화만 요구하고 끝내지 말고 관측·초기 위치 조건과 실제 변환 출력이 형성되는지 확인한다.
변형에서 AMCL 활성화와 map→odom 연결이 실제 기록으로 확인됐고 scan만 11.70 s라면 나이는 0.35 s로 정책을 0.15 s 초과한다. 이번에는 같은 활성 상태라도 동적 관측 준비가 실패한다. 반면 정적 지도 v7의 로딩 시각이 오래됐다는 이유만으로 동적 scan과 같은 나이 제한을 그대로 적용하지 않는다. 지도는 버전·환경 유효성과 제공 상태를 확인하고 자료 종류에 맞는 갱신 계약을 쓴다.
메시지 타입과 실행 결과를 마지막까지 구분한다
Jazzy TwistPublisher 구현은 enable_stamped_cmd_vel 기본값 false에서 Twist를 사용하고 true일 때 TwistStamped를 선택한다. 현재 main/rolling 문서의 다른 기본값을 Jazzy에 소급하지 않는다. 생산자와 adapter가 같은 토픽 이름을 써도 메시지 타입이 다르면 기대한 연결이 아니다. Twist에는 header가 없어 시각·프레임·만료 규칙을 별도 계약으로 정해야 한다.
이후 준비 자료가 모두 확인되고 경로와 명령이 나왔다고 해도 이동·최종 도착 관측이 없다면 과업 결과는 미상이다. 현재 pose와 목표·허용 오차, progress와 Action 결과 및 필요한 작업별 조건을 대조한다. 기존 1.4 ROS 2 Jazzy 통신 모델와 6.5 End-to-End Pick & Place 배포로 연결해 자료·실행 계층을 나누자. 아래 활동은 Nav2 bringup이나 실제 주행을 실행한 것이 아니다.