로봇이 스스로 목적지까지 이동한다고 하면, 얼핏 보기에는 단순해 보입니다.
지도 위에서 출발점과 도착점을 찍고, 그 사이를 따라가면 되는 것처럼 느껴지기 때문입니다.
그런데 실제 로봇의 주행은 그렇게 단순하지 않습니다.
지도 위에서 전체 경로를 찾는 일도 필요하고, 당장 눈앞에 갑자기 나타난 장애물을 피하는 일도 필요합니다. 센서 데이터도 계속 들어오고, 로봇의 현재 위치도 계속 변하고, 경우에 따라서는 길을 잃었을 때 복구 동작까지 해야 합니다.
즉, 자율주행 로봇의 내비게이션은 단순히 “길 찾기 알고리즘 하나”로 해결되지 않습니다.
전체 경로 계획, 실시간 경로 추종, 장애물 회피, 행동 제어, 환경 표현이 함께 돌아가는 하나의 시스템으로 봐야 합니다.
ROS 2에서 이 역할을 맡는 대표적인 내비게이션 프레임워크가 바로 Nav2입니다.
이번 글에서는 먼저 Nav2가 어떤 구조를 가지고 있는지 살펴보고, 그 안에서 Path Planning이 어떻게 이루어지는지까지 이어서 정리해보겠습니다.
ROS 1의 move_base와 ROS 2의 Nav2는 무엇이 다를까
ROS 1 시절 내비게이션 스택의 중심에는 move_base가 있었습니다.
이 패키지는 지도, 센서, TF, 오도메트리 정보를 받아서 결국 로봇의 속도 명령을 만들어주는 핵심 구성 요소였습니다.
반면 ROS 2의 Nav2는 같은 목적을 가지면서도 구조가 꽤 달라졌습니다.
가장 큰 차이는 하나의 큰 패키지가 모든 기능을 감싸는 구조에서, 여러 서버와 노드가 역할을 나누는 모듈형 구조로 바뀌었다는 점입니다.
이 차이는 생각보다 중요합니다.
ROS 1의 구조가 하나의 거대한 패키지 안에 기능이 모여 있는 형태였다면,
ROS 2의 Nav2는 Planner, Controller, Behavior, Costmap 같은 기능이 각각 독립적인 역할을 가지며 동작합니다.
이렇게 나누면 장점이 명확합니다.
- 특정 기능만 교체하거나 튜닝하기 쉬워집니다.
- 문제 발생 시 어느 부분이 원인인지 분리해서 보기 쉬워집니다.
- 전체 시스템을 더 유연하게 구성할 수 있습니다.
즉 Nav2는 단순한 “새 버전의 move_base”라기보다,
ROS 2에 맞게 다시 설계된 모듈형 내비게이션 프레임워크라고 보는 편이 더 정확합니다.

Nav2는 왜 이렇게 여러 개로 나뉘어 있을까
Nav2를 처음 보면 구조가 조금 복잡해 보일 수 있습니다.
Planner Server, Controller Server, Behavior Server, BT Navigator, Costmap, Lifecycle Manager 같은 이름이 한꺼번에 나오기 때문입니다.
그런데 이걸 한 번 역할 중심으로 나눠서 보면 훨씬 단순해집니다.
Nav2는 크게 보면 다음 질문들을 각자 다른 컴포넌트가 맡고 있습니다.
- 어디로 가야 하는가 → Planner
- 지금 어떻게 움직여야 하는가 → Controller
- 막혔을 때 어떤 행동을 할 것인가 → Behavior
- 전체 내비게이션 흐름을 어떻게 조율할 것인가 → BT Navigator
- 지금 주변 환경을 어떻게 비용 지도 형태로 표현할 것인가 → Costmap
즉 Nav2는 하나의 알고리즘이 아니라,
주행에 필요한 질문들을 역할별로 분리한 아키텍처입니다.
그래서 오히려 구조가 분리되어 있을수록 전체 동작을 이해하기가 쉬워집니다.
Nav2를 이해하려면 먼저 알아야 하는 ROS 2 개념들
Nav2는 ROS 2의 특징적인 개념들을 꽤 적극적으로 활용합니다.
그중 특히 중요한 것이 Action Server, Lifecycle Node, 그리고 Behavior Tree입니다.
Action Server
내비게이션은 짧게 끝나는 작업이 아닙니다.
목표 지점을 주면 몇 초, 몇십 초, 때로는 더 오래 걸릴 수도 있습니다. 이런 긴 작업은 서비스처럼 “요청하고 바로 응답받는” 구조보다, 진행 중인 상태를 계속 확인할 수 있는 구조가 더 적합합니다.
그래서 Nav2는 많은 기능을 Action 형태로 구현합니다.
예를 들어 목표점까지 회전하거나, 이동하거나, 특정 동작을 수행하는 작업은 중간 피드백을 계속 보낼 수 있어야 합니다.
즉 Action은 Nav2에서 “장시간 동작을 안정적으로 관리하는 인터페이스”라고 이해하면 좋습니다.
Lifecycle Node
Nav2는 여러 노드가 함께 움직이는 시스템입니다.
이럴 때 중요한 것은 단순히 노드를 켜는 것이 아니라, 언제 configure하고, 언제 activate하고, 언제 멈추고, 언제 다시 살릴 것인가를 체계적으로 관리하는 일입니다.
Lifecycle Node는 이 상태 관리를 가능하게 해줍니다.
그래서 어떤 노드가 아직 준비되지 않았는데 다른 노드가 먼저 동작해버리는 문제를 줄일 수 있고, 특정 노드가 비정상 상태가 되었을 때도 시스템 차원에서 더 안전하게 다룰 수 있습니다. Nav2가 이 구조를 적극적으로 사용하는 이유도 바로 여기에 있습니다.
Behavior Tree
행동 트리는 복잡한 로봇 동작을 작은 행동 단위로 나눠서 조합하는 방식입니다.
예를 들어 “목표까지 이동한다 → 막히면 costmap을 지운다 → 그래도 안 되면 회전한다 → 다시 시도한다” 같은 흐름을 트리 구조로 표현할 수 있습니다.
Nav2에서는 이 Behavior Tree를 기반으로 전체 내비게이션 절차를 조율합니다.
그래서 단순히 “길 따라가기”뿐 아니라, 실패했을 때 어떤 복구 행동을 할지까지 포함한 흐름 제어가 가능해집니다.
Nav2의 핵심 서버들은 어떤 역할을 할까
이제 Nav2 내부의 핵심 구성 요소를 조금 더 직접적으로 보겠습니다.
Planner Server
Planner Server는 전역 경로를 생성하는 역할을 합니다.
현재 위치에서 목표 지점까지, 전체 지도 기준으로 어떤 길을 따라가면 좋은지를 계산합니다.
자동차 내비게이션으로 비유하면, “서울에서 부산까지 어떤 고속도로와 국도를 거칠 것인가”를 먼저 정하는 단계에 가깝습니다.
Controller Server
Controller Server는 Planner가 만든 경로를 실제로 따라가게 만드는 역할을 합니다.
즉, 당장 지금 속도를 얼마로 줄지, 어느 방향으로 회전할지, 센서 앞에 나타난 장애물을 어떻게 피할지를 결정합니다.
이쪽은 훨씬 실시간성이 강하고, 눈앞의 상황 변화에 민감합니다.
Smoother Server
Planner가 만든 경로는 때로 각이 져 있거나 부자연스러울 수 있습니다.
Smoother는 그 경로를 더 부드럽게 만들어, 로봇이 급격하게 꺾이지 않고 자연스럽게 움직일 수 있도록 도와줍니다.
Behavior Server
Behavior Server는 주행 중 발생하는 특수 상황에 대응하는 행동들을 담당합니다.
예를 들어 잠시 회전하거나, 뒤로 물러나거나, 기다리거나, 복구 행동을 수행하는 식입니다.
즉 “정상적인 경로 추종” 이외의 행동을 관리하는 역할입니다.
이 구조를 보면 Nav2는 단순히 길 하나를 계산하는 시스템이 아니라,
전역 계획, 지역 추종, 복구 행동, 상태 조율이 함께 들어 있는 주행 프레임워크라는 점이 분명해집니다.

이제 Path Planning을 보자
Nav2의 전체 구조를 봤다면, 이제 그 안에서 가장 익숙하게 떠올릴 수 있는 기능인 Path Planning을 볼 차례입니다.
Path Planning은 말 그대로 로봇이 출발지에서 목적지까지 이동하는 경로를 계산하는 과정입니다.
그런데 여기서 중요한 것은 단순히 직선 거리를 가장 짧게 만드는 것이 아닙니다. 장애물을 피해야 하고, 로봇이 실제로 지나갈 수 있는 경로여야 하며, 경우에 따라서는 더 안전하고 부드러운 경로가 더 좋은 선택이 될 수도 있습니다.
즉, Path Planning은 단순한 길 찾기가 아니라
지도, 비용, 로봇의 움직임 제약, 장애물 회피를 함께 고려하는 경로 계산 문제입니다.
그리고 Nav2에서는 이 과정을 크게 두 단계로 나누어 봅니다.
- Global Planner: 전체 지도 기준의 큰 경로를 찾음
- Local Planner(Controller): 눈앞 상황에 맞게 실제 주행 명령을 계산함
이 구분을 이해하는 것이 Nav2를 이해하는 핵심입니다.
Global Planner는 무엇을 하는가
Global Planner는 정적 지도를 바탕으로, 현재 위치에서 목표 지점까지의 전역 경로를 계산합니다.
즉 전체 맵을 보고 “어느 복도를 지나고 어느 문을 통과해서 목적지로 갈 것인가”를 정하는 역할입니다.
이 단계에서는 보통 비용이 가장 적은 경로를 찾습니다.
여기서 말하는 비용은 대체로 거리, 통과 가능성, 위험도 같은 것들이 반영된 값입니다.
즉 Global Planner는 최종 목적지까지 가기 위한 긴 궤적을 만들어 Local Planner에게 넘겨주는 역할을 합니다.
자동차 내비게이션에 비유하면,
Global Planner는 “서울에서 부산까지 큰 길을 어떻게 탈지”를 결정하는 단계이고,
실제 운전대 조작은 아직 시작되지 않은 상태라고 볼 수 있습니다.
Dijkstra와 A*는 왜 자주 같이 등장할까
Global Planner를 이야기할 때 빠지지 않고 등장하는 두 알고리즘이 있습니다.
바로 Dijkstra와 A* 입니다.
Dijkstra
Dijkstra는 시작점에서부터 가능한 경로를 넓게 퍼져나가며 탐색하는 방식입니다.
목표 방향을 특별히 우선시하지 않고, 모든 방향으로 비용을 확장해가며 결국 최단 경로를 찾습니다.
이 방식의 강점은 분명합니다.
- 경로가 존재하면 반드시 찾을 수 있고
- 찾은 경로는 최단 경로임이 보장됩니다
하지만 단점도 명확합니다.
목표가 어디 있는지를 특별히 고려하지 않다 보니, 큰 맵에서는 필요 이상으로 많은 영역을 탐색하게 됩니다. 즉 정확하지만 비효율적일 수 있습니다.
A*
A*는 이 비효율성을 줄이기 위해 등장한 방식입니다.
핵심은 단순히 “지금까지 온 비용”만 보는 것이 아니라,
“목표까지 얼마나 더 남았을지”에 대한 추정치까지 함께 고려한다는 점입니다.
즉 A*는 목표 방향을 어느 정도 의식하면서 탐색을 진행합니다.
그래서 보통 Dijkstra보다 훨씬 적은 영역을 보고도 빠르게 경로를 찾을 수 있습니다.
다만 그 성능은 휴리스틱 설계에 영향을 받습니다.
정리하면 이렇습니다.
- Dijkstra는 느리지만 확실하고 정직한 탐색
- A*는 목표 방향을 의식하는 더 빠른 탐색
실제 Nav2 설정에서는 플래너 파라미터를 통해 이 둘을 선택적으로 사용할 수 있습니다.

Local Planner는 무엇을 하는가
Global Planner가 “지도 위의 큰 경로”를 만든다면,
Local Planner는 “지금 당장 어떻게 움직여야 하는가”를 결정합니다.
이 차이는 매우 중요합니다.
전역 경로는 지도상에서는 좋아 보여도,
실제 로봇 앞에는 갑자기 사람이 지나갈 수도 있고, 예기치 않은 장애물이 생길 수도 있습니다. 또한 로봇은 기구학적 제약을 가집니다. 예를 들어 어떤 로봇은 제자리 회전에 강하고, 어떤 로봇은 자동차처럼 회전 반경이 필요합니다.
그래서 Local Planner는 다음을 함께 고려합니다.
- 로봇의 구동 방식
- 현재 속도와 가속도
- 센서로 보이는 주변 장애물
- 전역 경로를 얼마나 잘 따라가고 있는지
- 지금 바로 만들어야 할 선속도와 각속도
즉 Local Planner는 단순한 길 찾기보다 훨씬 실시간적이고 동적인 문제를 다룹니다.
결국 이 단계에서 실제 v, ω 같은 속도 명령이 만들어집니다.
DWB와 TEB는 어떤 차이가 있을까
Nav2에서 Local Planner 후보로 자주 비교되는 것이 DWB와 TEB입니다.
둘 다 목적은 같지만, 경로를 만드는 방식이 꽤 다릅니다.
DWB
DWB는 전통적인 DWA 계열을 ROS 2에서 확장한 방식입니다.
핵심은 가능한 속도 조합들을 샘플링하고, 그 조합으로 조금 앞을 시뮬레이션해 본 뒤, 가장 점수가 좋은 경로를 선택하는 것입니다.
즉 DWB는
“지금 가능한 움직임 후보들을 여러 개 만들어 보고,
그중 목표를 잘 향하고 장애물과 충분히 멀고 속도도 괜찮은 것을 선택하는 방식”
이라고 볼 수 있습니다.
이 방식의 장점은 가볍고 빠르다는 점입니다.
그래서 비교적 단순한 환경이나 저사양 시스템에서도 잘 동작합니다.
반면 너무 좁은 공간이나 복잡한 구조에서는 다소 답답한 선택을 할 수 있고, 경로가 조금 투박하게 나올 수 있습니다.
TEB
TEB는 전역 경로를 일종의 고무줄처럼 생각하고,
장애물을 피하면서도 짧고 부드럽고 시간적으로도 무리가 없는 형태로 계속 최적화하는 방식입니다.
즉 단순히 “후보를 많이 찍어보고 선택”하는 것이 아니라,
경로 전체를 더 부드럽고 자연스럽게 바꿔나가는 접근에 가깝습니다.
그래서 TEB는 좁은 공간, 동적 장애물, 자동차형 구동 구조 등에서 더 유리한 경우가 많습니다.
다만 그만큼 계산량이 크고, 파라미터도 많아서 튜닝 난이도가 높습니다.
한마디로 말하면 잘 맞추면 굉장히 좋지만, 다루기가 쉽지는 않은 플래너입니다.
정리하면 이런 느낌입니다.
- DWB: 가볍고 직관적이지만 다소 보수적
- TEB: 부드럽고 강력하지만 튜닝이 어렵고 무거움
실제 시스템에서는 로봇의 구동 방식, CPU 여유, 환경 복잡도에 따라 선택이 달라집니다.
그런데 지도만 있으면 바로 경로 계획이 가능할까
여기서 중요한 오해가 하나 있습니다.
SLAM으로 만든 지도나 점유 격자 지도만 있으면, 곧바로 주행 경로를 계산할 수 있을 것처럼 느껴질 수 있습니다.
하지만 실제 내비게이션에서는 그걸 그대로 쓰기 어렵습니다.
왜냐하면 지도는 보통 “장애물이 있느냐, 없느냐, 아직 모르느냐” 정도를 담고 있을 뿐이고,
로봇 입장에서는 장애물 근처도 위험하다, 좁은 공간은 통과 비용이 높다, 내 몸체 크기를 고려해야 한다 같은 정보가 더 필요하기 때문입니다.
바로 여기서 등장하는 것이 Costmap입니다.
Costmap은 왜 필요한가
Costmap은 로봇이 주행할 공간을 단순한 장애물 지도보다 더 실용적인 형태로 바꿔줍니다.
각 셀에 단순 점유 여부가 아니라 이 위치를 통과하는 데 드는 비용을 부여하는 것입니다.
예를 들어 생각해보겠습니다.
벽 바로 옆을 스치듯 지나가는 경로도 물리적으로는 가능할 수 있습니다.
하지만 실제 로봇 주행에서는 꽤 위험합니다. 센서 오차나 제어 오차가 조금만 있어도 부딪힐 수 있기 때문입니다.
그래서 Costmap은 벽 자체뿐 아니라, 벽 주변도 비용이 높은 영역으로 만들어 줍니다.
결국 플래너는
“완전히 막힌 곳은 피하고,
갈 수는 있지만 위험한 곳은 가능하면 덜 지나가고,
안전한 곳을 더 선호하는 경로”
를 찾게 됩니다.
즉 Costmap은
장애물 지도에 안전 거리와 위험도를 반영해, 경로 계획에 더 적합한 형태로 바꾼 환경 표현이라고 볼 수 있습니다.
Global Costmap과 Local Costmap은 어떻게 다를까
Costmap도 하나만 있는 것이 아닙니다.
Nav2에서는 보통 Global Costmap과 Local Costmap을 함께 씁니다.
Global Costmap
Global Costmap은 전체 지도 기준의 비용 지도를 의미합니다.
전역 경로를 계산할 때 사용되며, 주로 정적인 장애물과 고정된 구조를 반영합니다.
범위가 넓고 업데이트는 상대적으로 느려도 괜찮습니다. 목적은 전체 길을 찾는 것이기 때문입니다.
Local Costmap
Local Costmap은 로봇 주변의 작은 영역만 다룹니다.
현재 위치 근처에서 빠르게 업데이트되며, 센서로 본 동적 장애물도 반영합니다.
즉 실제 회피와 실시간 경로 추종에는 이쪽이 훨씬 중요합니다.
이 둘의 관계를 보면 자연스럽습니다.
- Global Costmap은 “큰 그림”
- Local Costmap은 “지금 발앞 상황”
로봇은 큰 그림만 보고 달릴 수도 없고,
눈앞만 보고 전체 목적지를 잊을 수도 없습니다.
그래서 두 종류의 costmap이 함께 필요합니다.

Costmap Layer는 무엇을 쌓는 걸까
Costmap은 하나의 단일 정보가 아니라, 여러 층의 정보를 겹쳐서 만듭니다.
이걸 Layered Costmap이라고 이해하면 좋습니다.
대표적으로 다음 레이어들이 자주 쓰입니다.
Static Layer
미리 만들어진 지도에서 고정된 장애물 정보를 가져옵니다.
벽이나 구조물처럼 원래부터 알고 있는 환경 정보가 여기에 해당합니다.
Obstacle Layer
센서로 새롭게 감지한 장애물을 반영합니다.
즉, 사람이나 임시 물체처럼 지도에는 없지만 현재 존재하는 장애물 정보를 여기에 올립니다.
Inflation Layer
장애물 그 자체만 막는 것이 아니라, 그 주변에도 비용을 퍼뜨립니다.
이게 바로 로봇이 장애물과 너무 가깝게 붙지 않도록 만드는 핵심입니다.
실제 경로 계획에서 체감이 큰 것은 이 inflation입니다. 경로가 너무 벽에 붙는지, 적절히 떨어지는지에 직접 영향을 주기 때문입니다.
즉 Costmap Layer는 단순한 구현 디테일이 아니라,
환경 정보를 의미별로 나누고 마지막에 합성하는 방식입니다.
그래서 튜닝할 때도 “문제가 static 쪽인지, obstacle 쪽인지, inflation 쪽인지”를 나눠서 볼 수 있습니다.
Nav2를 이해한다는 것은 무엇을 이해하는 걸까
Nav2를 처음 보면 서버도 많고, 파라미터도 많고, costmap도 두 개고, 행동 트리까지 있어서 복잡하게 느껴질 수 있습니다.
그런데 사실 핵심은 그렇게 복잡하지 않습니다.
Nav2를 이해한다는 것은 결국 다음 흐름을 이해하는 것입니다.
- 지도와 센서로 현재 환경을 표현하고
- Global Planner가 전체 경로를 만들고
- Local Planner가 눈앞 상황에 맞게 실제 주행을 만들고
- Behavior와 BT가 막혔을 때의 흐름까지 조율한다
즉 Nav2는
경로 계획 알고리즘 하나가 아니라,
자율주행 로봇이 목적지까지 안전하게 가기 위해 필요한 기능들을 역할별로 묶어 놓은 시스템입니다.
정리해보면
이번 글에서는 Nav2와 Path Planning을 한 흐름 안에서 정리해봤습니다.
ROS 2의 Nav2는 ROS 1의 move_base와 달리, Planner, Controller, Behavior, Costmap, Behavior Tree 같은 요소가 분리된 모듈형 내비게이션 프레임워크입니다.
이 구조 덕분에 각 기능의 역할이 더 명확해지고, 시스템도 더 유연하게 구성할 수 있습니다.
그리고 Path Planning은 이 Nav2 안에서 크게 두 부분으로 나뉩니다.
- Global Planner는 전체 지도 기준의 큰 경로를 계산하고
- Local Planner는 실시간 장애물과 로봇의 제약을 반영해 실제 속도 명령을 만듭니다.
또한 단순 occupancy map만으로는 주행이 부족하기 때문에, Nav2는 Costmap을 사용해 위험도와 안전 거리를 반영한 환경 표현을 만듭니다.
여기서 Global Costmap은 전체 경로를, Local Costmap은 눈앞의 회피를 담당합니다.
결국 핵심은 이것입니다.
Nav2는 길 하나를 찾는 도구가 아니라,
길을 찾고, 따라가고, 피하고, 복구하는 과정을 통합한 주행 시스템이다.
이 관점을 잡고 나면, 이후에 Dijkstra와 A*, DWB와 TEB, Costmap 파라미터 같은 세부 내용도 훨씬 덜 흩어져 보이게 됩니다.
'Study Archives > Robotics' 카테고리의 다른 글
| [로봇 학습의 이해 ②] 시뮬레이션과 Sim-to-Real (0) | 2026.04.10 |
|---|---|
| [로봇 학습의 이해 ①] 로봇 제어와 행동 생성 (0) | 2026.04.10 |
| [SLAM의 이해 ⑤] Mapping과 Localization (0) | 2026.04.10 |
| [SLAM의 이해 ④] URDF와 Xacro (0) | 2026.04.10 |
| [SLAM의 이해 ③] TF와 좌표 변환 (0) | 2026.04.10 |