Nav2 코스트맵은 SLAM 지도를 그대로 따라가는 화면이 아니라 static·obstacle·voxel·inflation layer와 keepout 같은 filter를 겹쳐 planner와 controller가 사용할 이동 비용으로 바꾼 격자입니다. 잘못된 장애물 누적은 marking·clearing·TF·센서 범위·레이어 결합 순서에서 찾아야 합니다.
아래에서는 용어의 차이를 실제 시스템 경계, 실패 조건과 검증 순서로 나눠 살펴봅니다.
코스트맵은 지도 위에 센서와 운영 규칙을 합친 주행 판단판이다
SLAM은 환경 지도를 만들지만 로봇이 지금 어디를 지나도 되는지까지 모두 결정하지는 않습니다. LiDAR·Visual SLAM 글과 달리 이 글은 Nav2가 지도·센서·로봇 크기·금지 구역을 비용 격자로 조합하는 과정에 집중합니다.
planner는 전역 코스트맵에서 경로를 찾고 controller는 로컬 코스트맵에서 가까운 장애물을 피하며 속도 명령을 계산합니다. 셀은 free·occupied만 아니라 미지 영역과 장애물 주변의 단계적 비용을 포함합니다.
전역 코스트맵과 로컬 코스트맵은 같은 레이어라도 역할이 다르다
전역 코스트맵은 map 프레임과 넓은 정적 지도를 바탕으로 목표까지의 경로를 계산하는 데 쓰입니다. 로컬 코스트맵은 odom 프레임의 rolling window로 로봇 주변을 자주 갱신해 동적 장애물과 짧은 제어 판단을 지원합니다.
두 코스트맵의 resolution, footprint, sensor source와 filter가 다르면 planner가 만든 길을 controller가 거부할 수 있습니다. 통로 폭과 금지 구역처럼 양쪽에 공통으로 필요한 규칙은 일관성을 확인해야 합니다.
static layer는 /map을 복사하는 것보다 해석 규칙이 중요하다
Nav2 Costmap 2D 공식 문서는 기본 plugin으로 static·obstacle·inflation layer를 제시합니다. static layer는 map server 또는 SLAM이 발행한 occupancy grid를 코스트맵의 기준으로 가져옵니다.
unknown space를 통과 가능하게 볼지, lethal threshold를 어디에 둘지, 지도 업데이트를 구독할지가 경로 결과를 바꿉니다. 회색 미지 영역을 단순한 빈 공간으로 오해하면 미관측 구역으로 경로가 들어갈 수 있습니다.
| 레이어 | 주요 입력 | 만드는 판단 |
|---|---|---|
| Static | /map occupancy grid | 고정 구조·미지 영역 |
| Obstacle | LaserScan·PointCloud2 | 현재 장애물·빈 공간 |
| Inflation | 장애물·footprint | 거리 기반 회피 비용 |
| Keepout filter | mask·filter info | 진입 금지·선호 경로 |
obstacle layer는 marking과 clearing을 서로 다른 조건으로 처리한다
Obstacle Layer 공식 설정 문서는 센서 관측을 표시하는 marking과 raycasting으로 비우는 clearing을 구분합니다. 장애물이 보일 때 셀을 채우는 것만큼 사라졌을 때 지우는 광선이 충분히 도달하는지가 중요합니다.
obstacle_max_range보다 raytrace_max_range가 짧거나 센서 최소·최대 거리와 맞지 않으면 장애물은 생기지만 지워지지 않을 수 있습니다. inf 값 처리, observation persistence와 예상 업데이트율도 유령 장애물의 잔류 시간을 바꿉니다.
voxel layer는 높이를 사용하지만 최종 판단은 2D로 투영된다
PointCloud2나 depth 센서를 쓰면 voxel layer가 z 방향 셀을 관리해 장애물 높이를 구분할 수 있습니다. 낮은 바닥 노이즈와 로봇이 통과할 수 없는 물체를 분리하는 데 도움이 되지만 z_resolution·z_voxels·mark threshold가 부적절하면 유효 물체를 놓칩니다.
선반 아래 빈 공간, 유리, 반사면과 사람 다리는 센서별 실패가 다릅니다. 3D 관측이 2D 코스트맵으로 어떤 기준에서 투영되는지 실제 장면과 RViz voxel 표시를 함께 확인합니다.
inflation layer는 장애물 크기가 아니라 통과 선호도를 만든다
Inflation은 lethal obstacle 주변에 거리별 비용을 퍼뜨려 경로와 controller가 벽에 붙지 않도록 합니다. robot_radius 또는 polygon footprint가 실제 외곽을 표현하고 inflation_radius와 cost_scaling_factor가 통로 요구에 맞아야 합니다.
radius를 과도하게 키우면 지나갈 수 있는 문을 막고, 작게 두면 벽과 너무 가까운 경로가 나옵니다. 빈 통로·모서리·회전·적재물 장착 상태에서 footprint와 inflation 조합을 시험해야 합니다.
금지 구역은 일반 레이어와 분리된 filter로 적용한다
Nav2 Keepout Filter 튜토리얼은 mask와 filter info를 사용해 진입 금지 구역과 선호 차선을 적용하는 방법을 설명합니다. 운영자가 지정한 규칙은 센서 장애물과 다른 근거이므로 별도 filter로 관리하는 편이 추적하기 쉽습니다.
global에만 적용하면 planner는 피하지만 local controller의 즉시 판단과 일치하지 않을 수 있고, local에만 적용하면 전역 경로가 금지 구역을 통과하려 할 수 있습니다. 두 코스트맵에 필요한 정책과 mask 좌표를 함께 검증합니다.
레이어 결합 방식은 나중 정보가 장애물을 덮는지 결정한다
Layered costmap은 각 plugin의 결과를 master grid에 합칩니다. overwrite와 maximum 같은 combination 방식이 다르면 static obstacle이나 다른 센서가 만든 lethal cost가 보존되거나 덮일 수 있습니다.
최종 costmap만 보면 어떤 레이어가 값을 만들었는지 알기 어렵습니다. 레이어별 topic과 debug 출력, 동일 셀의 전후 비용을 캡처해 결합 순서와 method가 의도한 보수성을 갖는지 확인합니다.
잘못된 장애물은 센서·시간·좌표 세 경계를 따라 추적한다
센서값이 정상이어도 timestamp가 오래됐거나 TF가 늦으면 관측이 잘못된 위치에 표시됩니다. TF2 프레임 진단과 센서 시간 정렬을 함께 적용해 message frame, transform age와 costmap update 시점을 비교합니다.
로봇이 움직일 때만 장애물이 번지면 odom·base·sensor 변환을, 정지 뒤에도 남으면 clearing과 persistence를, 특정 높이에서만 사라지면 obstacle height와 voxel 설정을 우선 의심할 수 있습니다.

해상도와 갱신률은 정확도·계산량·신선도를 맞바꾼다
작은 resolution은 얇은 장애물과 좁은 통로를 더 세밀하게 표현하지만 셀 수와 planner·controller 계산량을 늘립니다. update_frequency가 센서와 주행 속도에 비해 낮으면 로봇이 오래된 장애물 지도를 보고 움직입니다.
publish_frequency는 시각화·외부 소비 빈도이고 update_frequency와 같을 필요는 없습니다. 계산 주기, sensor rate, transform tolerance와 controller deadline을 같이 측정해 한 값만 높여 CPU 포화를 만들지 않습니다.
코스트맵 시험은 한 장면씩 레이어를 켜며 진행한다
정적 지도만 켜 기준 셀을 확인한 뒤 obstacle 또는 voxel을 추가하고, inflation, filter 순서로 올립니다. 벽·문·사람·팔레트·유리·낮은 장애물과 센서 가림을 하나씩 넣어 marking과 clearing을 관찰합니다.
합격 기준에는 경로 성공뿐 아니라 실제 장애물 대비 표시 오차, 장애물 제거 시간, 최소 통과 폭, CPU와 update deadline을 포함합니다. 그래야 주행 성공률이 낮을 때 지도·센서·레이어 중 원인을 분리할 수 있습니다.
| 시험 | 장면 | 판정 |
|---|---|---|
| 기준 | static map만 | 벽·unknown 일치 |
| 표시 | 장애물 등장 | 위치·높이·범위 |
| 삭제 | 장애물 제거·가림 | 허용 시간 내 clearing |
| 통과 | 문·모서리·적재 상태 | footprint·inflation 여유 |
운영 코스트맵은 로봇 형태와 현장 규칙 변화까지 추적한다
AMR은 적재물과 부착 장치에 따라 footprint가 달라질 수 있습니다. AMR과 AGV 비교 글에서 다룬 자율 경로 선택이 안전하려면 현재 형태, 금지 구역과 통로 조건이 코스트맵에 반영돼야 합니다.
지도·mask·센서 캘리브레이션·파라미터 버전을 함께 배포하고 변경 뒤 회귀 장면을 반복합니다. 현장 장애물 신고에는 최종 화면뿐 아니라 레이어별 입력과 timestamp를 보존해야 재현 가능한 진단이 됩니다.

Nav2 코스트맵 레이어에서 자주 묻는 질문
SLAM 지도가 있으면 obstacle layer는 필요 없나요?
정적 지도는 고정 구조를 보여주지만 사람·팔레트처럼 현재 변하는 장애물을 반영하려면 센서 기반 레이어가 필요합니다.
유령 장애물은 코스트맵을 지우면 해결되나요?
일시적으로 사라질 수 있지만 clearing 범위, TF, timestamp, persistence와 센서 노이즈 원인을 고치지 않으면 다시 생깁니다.
Inflation radius는 로봇 반지름과 같은 값인가요?
같은 개념이 아닙니다. footprint는 실제 외곽이고 inflation은 장애물 주변의 추가 비용 여유입니다. 통로와 제어 특성으로 함께 조정합니다.
Keepout filter는 global costmap에만 넣어도 되나요?
전역 경로만 피하게 할 목적이라면 가능하지만 로컬 제어까지 금지 규칙을 지키게 하려면 두 코스트맵의 적용을 함께 검토해야 합니다.
코스트맵 해상도는 작을수록 좋은가요?
세밀해지지만 메모리와 계산량이 늘어 update deadline을 놓칠 수 있습니다. 장애물 크기와 주행 속도, CPU 예산으로 선택해야 합니다.
Nav2 costmap plugin과 파라미터는 배포판별로 달라질 수 있습니다. 실제 로봇의 안전 기능과 충돌 방지는 costmap 하나에만 의존하지 않아야 합니다.