Navigation · Theory · M9
M9-T1 — Nav2 Architecture
A navigation stack is a set of cooperating servers. Knowing who calls whom is half of debugging it.
When Scout is asked to deliver a tray to room 214, nothing in the robot “does navigation”. A request arrives at one server, which runs a small program that calls other servers, each of which owns one job and one piece of state. When something goes wrong, the skill is to know which server owns the failure. This lesson is the map of that system.
Learning objectives
After this lesson, you should be able to:
- Name the Nav2 servers and the job each owns: planner, controller, smoother, behaviour server, navigator, waypoint follower, velocity smoother and collision monitor.
- Trace a goal from the request to the velocity command, naming the action or topic at each hop.
- Read a behaviour tree built from RecoveryNode, PipelineSequence and RoundRobin, and say what it does when a step fails.
- Explain how plugins, lifecycle management, frames and parameter files tie the servers together.
The intuition
Picture a hospital porter’s office. A request comes in on a slip. A dispatcher (the navigator) does not carry anything herself: she checks that the route is known, asks the route planner for a path, asks the escort to follow it, and when the escort comes back with “blocked”, tries the standard fixes in order: clear the cart, back up, wait, and finally call for help. Each person has one job, a defined way to be asked, and a way to report success or failure.
Nav2 is organised the same way. The behaviour-tree navigator is the dispatcher. The planner server computes a path on the global costmap. The controller server turns that path into velocity commands using the local costmap. The behaviour server holds the recoveries. The servers talk through ROS 2 actions, which have a goal, feedback and a result, so “still working” and “failed” are first-class messages.
The mathematics
The parts
| Server / node | Owns | Interface | Typical plugins |
|---|---|---|---|
| bt_navigator | The behaviour tree that sequences a navigation task | Actions NavigateToPose and NavigateThroughPoses | Behaviour-tree nodes (action, condition, control, decorator) |
| planner_server | The global costmap and the global path | Action ComputePathToPose | NavfnPlanner, SmacPlanner2D, SmacPlannerHybrid, SmacPlannerLattice, ThetaStarPlanner |
| controller_server | The local costmap, path following, progress and goal checks | Action FollowPath; publishes velocity commands | DWB, RegulatedPurePursuit, MPPI |
| smoother_server | Smoothing a computed path | Action SmoothPath | Simple smoother and others |
| behavior_server | The recovery behaviours | Actions Spin, BackUp, DriveOnHeading, Wait | One plugin per behaviour |
| waypoint_follower | Visiting a list of poses | Action FollowWaypoints | Task-at-waypoint plugins |
| velocity_smoother | Limiting acceleration of the commands | Topic in, topic out | None |
| collision_monitor | A last safety check on the commanded velocity | Topic in, topic out | Polygons and sensor sources |
| lifecycle manager | Configure and activate the servers in order | Lifecycle services | None |
The set of servers and their names grow with releases (docking, route and others exist in newer ones), so treat this table as the stable core, not a complete list.
The path of a goal
- Request. A client (RViz, a script using the Simple Commander API, an application) sends a NavigateToPose goal to
bt_navigator: a pose in a frame, normallymap. - Plan. The tree’s
ComputePathToPosenode callsplanner_server. The planner plugin searches the global costmap and returns a path, written to the behaviour tree’s blackboard. - Follow. The tree’s
FollowPathnode callscontroller_serverwith that path. At the controller frequency, the controller plugin reads the local costmap and the robot pose and publishes a velocity command. - Condition the command. The velocity smoother limits acceleration; the collision monitor may slow or stop the command. The result reaches the base as
cmd_vel. - Monitor. The controller’s progress checker and goal checker decide whether the robot is moving and has arrived. The tree replans at a fixed rate and, on failure, runs recoveries.
A behaviour tree in one picture
Nav2’s default navigation tree has this shape (node names as in the Nav2 behaviour-tree documentation; check the version for your distribution):
- PipelineSequence
- A sequence that keeps ticking its earlier children while the later ones run: it plans again while following.
- RecoveryNode
- Runs its first child; if that fails, runs the second child (the recovery) and tries the first again, up to number_of_retries times. It has exactly two children.
- RoundRobin
- Each time it is run, it tries the next child: clear the costmaps, then spin, then wait, then back up.
- RateController
- A decorator that lets its child run at most hz times per second.
What ties it together
- Plugins. Planners, controllers, costmap layers, goal checkers and recoveries are plugins chosen by name in the parameter file. Changing the algorithm is a configuration change.
- Lifecycle. Servers are managed nodes: unconfigured → inactive → active. A lifecycle manager brings them up in order; a server that failed to configure stays down, and goals sent to the navigator fail.
- Frames. The map frame is fixed to the world,
odomis continuous but drifts, andbase_linkmoves with the robot (lesson M1-T4). Localization publishesmap → odom; odometry publishesodom → base_link. - Parameters. One YAML file configures every server under its name and a
ros__parameterskey. Parameter names change between releases, so read the documentation of your distribution before copying values.
A worked example
One goal, with numbers. Scout is asked to drive a 14.2 m path to the pharmacy. Assume a desired speed of 0.5 m/s, the controller at 20 Hz, the planner’s RateController at 1 Hz and a progress checker that expects 0.5 m of movement in 10 s (values you should read from your own file; these are common defaults at the time of writing).
So one successful goal is one action goal to the navigator, 29 action goals to the planner, one long-running action to the controller and 568 commands. When a bug appears “in navigation”, you now know where to look: if the path is wrong, the planner and the global costmap; if the path is right and the motion is wrong, the controller, the local costmap and the velocity chain.
When it gets stuck. Suppose a trolley blocks the corridor. The controller sees no progress for 10 s and fails. The inner RecoveryNode clears the local costmap and retries once: another 10 s. If it fails again, the outer node runs the recoveries, one per attempt: clear both costmaps, spin, wait, back up. With six retries, the tree can fail up to 7 times before it gives up. Roughly: 7 attempts × 2 tries × 10 s = 140 s of standing still, plus the time of the recoveries themselves, before the goal is aborted. That is a number worth checking against what the hospital considers acceptable for a blocked corridor, and it is set by three parameters you can read in the file.
Where the commands go. The controller’s output is typically published on a topic such as cmd_vel_nav, processed by the velocity smoother and the collision monitor, and arrives at the base as cmd_vel. Topic names are configured, and a wrong remap is the classic reason for “the plan is fine and the robot does not move” (project M9-L4).
Engineering implications and limitations
Debug by following the goal
Ask in order: is every server active? Is a transform from map to base_link available? Did the planner return a path? Is the controller publishing? Does the command reach the base? Each is one command (ros2 lifecycle get, tf2_echo, ros2 topic echo, ros2 topic info -v). A failure is almost always found at the first hop that says no.
Configuration is code
The parameter file and the behaviour-tree XML decide behaviour as much as any source file. They need review, version control and automatic checks, which is what the linters of this module do (labs M9-L2 and M9-L3).
Plugins and releases
Plugin class names, parameter names, default values and even the format of the behaviour-tree files change between Nav2 releases. When you copy a tutorial or a colleague’s file, check it against the documentation of your distribution. Pin the release you test, and re-run your tests when you upgrade.
Where the safety lives
The planner and controller optimise; the collision monitor and the base’s own limits protect. Do not rely on the planner’s costmap alone for safety: keep a final check that works from the latest sensor data and the commanded velocity (module 7).
Common misconceptions
“Nav2 is the planner.”
The planner is one server of several. Many failures people call “planning” are in the controller, the costmaps, the frames or the configuration.
“If the goal is accepted, navigation works.”
Acceptance only means the navigator is active. A path may still fail, the controller may produce no motion, or the command may never reach the base.
“The behaviour tree is just a config detail.”
It decides what happens on every failure: how many retries, which recovery, when to abort. It deserves the same attention as the algorithms.
“The same parameters work on every release.”
Names, plugin identifiers and defaults change. Always read the documentation for the release you run.
Engineering takeaways
- Nav2 is a set of lifecycle servers: navigator, planner, controller, smoother, behaviours, waypoint follower, velocity smoother and collision monitor.
- A goal travels from the client to bt_navigator, which calls the planner and the controller through actions; the velocity chain ends at the base.
- The behaviour tree decides retries and recoveries: RecoveryNode, PipelineSequence and RoundRobin are the building blocks.
- Plugins, lifecycle, frames and one parameter file tie the servers together, and all four are common sources of failure.
- Debug by following the goal hop by hop, and check the documentation of your release before copying parameters.
References and further reading
The Nav2 documentation and the papers that describe the system.
- S. Macenski, F. Martín, R. White and J. Ginés Clavero, “The Marathon 2: A Navigation System”, IEEE/RSJ IROS, 2020.
- S. Macenski, T. Foote, B. Gerkey, C. Lalancette and W. Woodall, “Robot Operating System 2: Design, architecture, and uses in the wild”, Science Robotics 7(66), 2022.
- Nav2 documentation, “Concepts”, “Configuration Guide” and “Behavior Tree Nodes”, docs.nav2.org (choose your distribution).
- M. Colledanchise and P. Ögren, “Behavior Trees in Robotics and AI: An Introduction”, CRC Press, 2018.
Knowledge check
Three conceptual questions. Write an answer, then reveal the explanation. Your answers stay in your browser.
Question 1
Scout’s goal is accepted by the navigator, a path appears in RViz, but the robot does not move. Name two servers or topics you would inspect first, and why.
Explanation
The controller server and the velocity chain. The path shows that the navigator and planner worked, so the question is whether the controller publishes commands and whether they reach the base: check the controller’s lifecycle state and log, then which velocity topics have publishers and subscribers.
Question 2
A RecoveryNode in a tree has three children. What is wrong, and what does the node normally do with two?
Explanation
RecoveryNode expects exactly two children: the action and its recovery. With two, it runs the first; if it fails, it runs the second and then tries the first again, up to the number of retries.
Question 3
The controller runs at 20 Hz and the robot drives 21 m at 0.7 m/s. How many velocity commands does the controller produce?
Explanation
30 s × 20 Hz = 600 commands (21 / 0.7 = 30 s).
What’s next
Next: how to change the numbers in that parameter file without breaking the robot.
Related content
Nothing below is required to finish this lesson.
- LabM9-L2: Lint a Nav2 Parameter File
Paste a parameter file and find the settings that contradict each other or the robot.
- LabM9-L3: Validate a Behavior Tree
Paste a behaviour-tree XML and find the missing recovery, the unreachable node and the infinite retry.
- LabM9-L4: Bring Up Nav2 in Simulation
Run Nav2 on a simulated robot on your own machine, send a goal, and diagnose what you see.
Get notified when the next lesson and new labs are released.
One email per new lesson or lab.