# Nav2: the ROS 2 navigation stack, and what adopting it actually costs

> Nav2 is the ROS 2 navigation framework for mobile robots, split into planners, controllers, behavior trees and lifecycle-managed servers. It is the standard choice for ROS 2 robots and a heavy dependency for anything simpler.

**ros-navigation/navigation2** — ROS 2 Navigation Framework and System

- Repository: https://github.com/ros-navigation/navigation2
- Website: https://nav2.org/
- Stars: 4,758 · Forks: 1,966
- Language: C++
- License: NOASSERTION
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/ros-navigation-navigation2

## What Nav2 solves that a pathfinding library does not

A shortest-path function gives you a list of poses. A mobile robot needs more than that: it needs to know where it is on a map, keep that estimate current as wheels slip, turn the pose list into velocity commands, watch for obstacles that were not on the map, recover when it gets stuck, and expose all of this as something another process can call and cancel. Nav2 is the assembly of those parts for ROS 2. The repository is a set of packages rather than one binary, and the top-level layout makes the split visible: nav2_amcl for localization, nav2_map_server for maps, nav2_planner and nav2_navfn_planner and nav2_smac_planner and nav2_theta_star_planner for global planning, nav2_controller with nav2_mppi_controller, nav2_dwb_controller, nav2_regulated_pure_pursuit_controller and nav2_graceful_controller for local control, nav2_behavior_tree and nav2_bt_navigator for orchestration, nav2_costmap_2d and nav2_voxel_grid for the obstacle representation, plus nav2_collision_monitor, nav2_velocity_smoother, nav2_docking, nav2_route and nav2_waypoint_follower for the surrounding tasks. The intended user is a robotics engineer with a ROS 2 robot and a map, not someone who wants a function that returns a route through a grid. If your problem is the latter, the rest of this stack is overhead.

## How the servers, lifecycle manager and behavior tree fit together

Nav2 runs as a set of ROS 2 nodes that are managed rather than simply launched. nav2_lifecycle_manager brings the servers up and down in order, which is why a Nav2 process has distinct unconfigured, inactive and active states instead of a single running flag. The map server publishes the occupancy grid; AMCL consumes laser scans and the map to publish a map-to-odom transform; the costmap layers build the obstacle grid the planner and controller read. The planner server produces a path, the controller server follows it and publishes velocity commands, and the behavior server supplies recovery actions when following fails. What ties them together is the behavior tree: nav2_bt_navigator executes an XML tree whose nodes call the other servers as ROS 2 action clients. That is the mechanism worth understanding before you tune anything, because the tree decides what happens when a planner returns no path or a controller reports a stuck condition. The repository also ships nav2_simple_commander, a Python interface that wraps the action clients so you can request a navigation goal without writing tree XML. The default trees are provided by the project; changing recovery order or adding a custom node means editing that XML, not editing C++.

## Installing Nav2 and sending a first goal

The README does not put install commands in the repository root. It points to the documentation site, which has a First Time Setup Guide and a Build & Install page, and it links a Docker container published under the ros-navigation organization on GitHub Packages. The Dockerfile in the repository root shows how the image is assembled: it starts from ros:rolling, clones the underlay from tools/underlay.repos into /opt/underlay_ws, copies the repository into /opt/overlay_ws/src/navigation2, and builds with colcon. The build arguments UNDERLAY_MIXINS and OVERLAY_MIXINS are configurable, and the file's own example exports them before calling docker build:

```bash
export UNDERLAY_MIXINS="debug ccache lld"
export OVERLAY_MIXINS="debug ccache coverage-gcc lld"
docker build -t nav2:latest \
  --build-arg UNDERLAY_MIXINS \
  --build-arg OVERLAY_MIXINS ./
```

For a normal ROS 2 installation the documentation's setup guide is the path to follow, and nav2_bringup is the package that starts a complete system. The launch file name and its arguments are documented in the configuration and getting-started pages rather than in the README, so read those before copying any launch command. Once the stack is active, the Python entry point is nav2_simple_commander. The documentation's tutorial pages show the BasicNavigator pattern, and the shape of a first goal is a pose in the map frame handed to the navigator, which then returns when the goal succeeds or fails. Expect the robot to need a published map, a laser or depth source, and a correct transform tree before any of this produces motion.

## Where Nav2 stops being the right tool

The most common failure is not a bug in Nav2 but a mismatch between the robot and the assumption of a 2D map. The costmap and the AMCL localization are built around a planar occupancy grid, so a robot operating on unmodeled terrain, a drone, or a manipulator moving through free space has little to gain from the stack. A second limitation is operational: a Nav2 deployment is a parameter file per robot, a behavior tree, and a set of lifecycle transitions. Teams that only need to drive between waypoints on a known floor plan often find the behavior tree layer harder to debug than the navigation itself, because a failure can originate in the tree, in a server's state, or in the transform timing. There is also the plugin surface. Swapping the controller or planner means implementing an interface from nav2_core and registering it, which is real C++ work, not a configuration change. Finally, the README does not document rollback or version pinning for the Docker image, and the build arguments change what lands in the image, so a container built with coverage mixins is not the artifact you want on a robot.

## Nav2 against a from-scratch planner, and against other ROS 2 options

The honest alternative is writing your own node: subscribe to a map and a scan, run A* or a lattice planner, and publish a Twist. That gives you a system you can read end to end, with no lifecycle manager and no behavior tree, and for a fixed route in a fixed building it can be less work than configuring Nav2. The difference is what you give up: recovery behaviors, a costmap that fuses multiple sensor layers, a velocity smoother, a collision monitor, and the plugin boundary that lets you replace one algorithm without touching the rest. Within ROS 2, the choice is usually between Nav2's controllers rather than between Nav2 and something else. The repository ships several with different approaches: nav2_regulated_pure_pursuit_controller follows a path geometrically, nav2_dwb_controller uses the Dynamic Window approach, and nav2_mppi_controller formulates control as an optimization over sampled trajectories. Picking among them is a tuning exercise in the controller server's parameters, and the configuration guide is where that decision is documented.

## Maintenance, release cadence and the licence question

The last push to the default branch was on 2026-09-22, and the most recent release listed is 1.5.2 on 2026-09-16, with 1.3.13 and 1.5.1 before it. Two release lines are being maintained at once, which matters for upgrade planning: the README's build status table tracks humble, jazzy and lyrical across source and Debian builds for navigation2 and individual packages such as nav2_amcl and nav2_behavior_tree. That table is the practical answer to whether your ROS 2 distribution is supported. Upgrades between distributions are not drop-in; the repository carries a doc/ directory and the documentation site has a Migration Guides section, which is the place to look before moving a working robot to a newer release. On licensing, the repository's license is recorded as NOASSERTION, so the LICENSE file at the root is the authoritative text, not this description or the README. Nav2 is developed with sponsorship and Open Navigation LLC provides commercial support and professional services, which is a separate arrangement from the licence and worth knowing if you need a support contract.

## Conclusion

Adopt Nav2 if you are already on ROS 2 and need a maintained navigation stack with swappable planners and controllers, and you accept the cost of a behavior tree, a lifecycle manager and a parameter file per robot. Do not adopt it as a general pathfinding library or for a robot that is not a ROS 2 node graph. Before committing, check the distribution status table in the documentation for your ROS 2 release, confirm the LICENSE file's exact terms for the packages you ship, and run the bringup launch file against your own map and URDF.

## FAQ

### How do I install Nav2?

The README does not give install commands itself; it links a First Time Setup Guide and a Build & Install page on the documentation site, plus a Docker container published under the ros-navigation organization. The repository's Dockerfile shows the image build, starting from ros:rolling and building the underlay and overlay workspaces with colcon.

### What is Nav2 used for?

It is the ROS 2 navigation framework for mobile robots, covering localization, mapping, global planning, local control, recovery behaviors and the servers that expose them as ROS 2 actions. The repository splits these into packages such as nav2_amcl, nav2_planner, nav2_controller and nav2_bt_navigator.

### Is Nav2 still maintained?

Yes. The last push to the default branch was on 2026-09-22, and the most recent release listed is 1.5.2 on 2026-09-16. The README's build status table tracks humble, jazzy and lyrical builds, and the project states that Open Navigation LLC provides leadership, maintenance and support.

### Which ROS 2 distributions does Nav2 support?

The README's build status table lists humble, jazzy and lyrical, with source and Debian build columns for navigation2 and for individual packages such as nav2_amcl and nav2_behavior_tree. The documentation site has a ROS Distribution Statuses section linked from the README.

### How do I send a navigation goal without writing a behavior tree?

The repository includes nav2_simple_commander, a Python interface that wraps the action clients, and the documentation's tutorials cover it. It lets you request a goal programmatically while the default behavior tree still handles recovery.

### What licence does Nav2 use?

The repository's licence is recorded as NOASSERTION, so the LICENSE file in the repository root is the text to read. This article does not interpret it; check that file for the terms that apply to the packages you redistribute.

## Sources

- [Issues](https://github.com/ros-navigation/navigation2/issues)
- [Project website](https://nav2.org/)
- [README](https://github.com/ros-navigation/navigation2/blob/main/README.md)
- [Releases](https://github.com/ros-navigation/navigation2/releases)
- [ros-navigation/navigation2 on GitHub](https://github.com/ros-navigation/navigation2)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ros-navigation-navigation2
