Navigation2, also known as Nav2: a framework for robotic ground navigation.
One of the principal tasks for any mobile robot is being able to move in its environment without colliding with walls, people or obstacles in general. To solve this, robots navigate using their sensors, generating maps and detecting potential obstacles. This task is quite complex, as it involves several concepts in robotics like mapping, localization, sensor fusion, system modeling and more. In addition, there is no single solution to these individual tasks; sensor fusion can vary depending on the types of sensors implemented. This situation means that instead of having a single package, a complete framework of several packages is needed to adapt and integrate all possible situations.
Navigation2, also known as Nav2, is a framework for robotic ground navigation. Originally created by Steve Macenski, it is currently maintained by his company Open Navigation. Fully built around ROS 2, it is considered one of the most important frameworks in ground robotics. It integrates a series of (action) servers that allow a ground robot to plan and move to a desired position.
Navigating from point A to point B starts with a plan. Think of this plan as the route that your preferred map app shows on your smartphone when you want to go somewhere. It connects point A to point B using the available map information; in particular, the drivable area (the roads). However, things can get complicated when the robot moves in an open area with lots of free space and scattered obstacles or walls. The robot has to process a lot free space in the map to create a plan.
Nav2 implements this process as the planner server. The planner uses information such as the current location of the robot, the goal position, the available map and the sensors to compute the plan.
Once the plan is established, the robot must follow it. However, sometimes the planner does not take into account potential obstacles in the path it has created. Think of this when you are driving a car and the GPS informs you the roads to take but it does not know about the other cars on the road. You are the controller of the car in charge of steering to avoid obstacles at the same time that you follow the path.
This task is done by the controller server. Using the available data coming from sensors, the current robot position and the plan, it will calculate the desired output velocities (linear and angular) to keep the robot close to the planned path while avoiding obstacles.
Now that we have talked about the planner and the controller and their tasks, it is important to understand the costmaps. Costmaps are a special type of occupancy grid maps that represent the available area to move around. Each cell in the grid has a cost (hence the name costmap), which qualifies how difficult it is to move in that cell. Depending on the cost value, the cell can be free, inflated, occupied or unknown. A typical 2D costmap will use 8-bit integers to represent costs with the following values:
There are two costmaps: global and local. The first one is used by the planner, whereas the second is used by the controller. On one hand, the global costmap is usually large, contains static map information and sensor data and has a lower refresh frequency. On the other hand, the local costmap is formed using sensor data and has a much smaller size, which allows for a quicker refresh rate. This is important to detect and avoid dynamic objects.
Costmaps are built by stacking layers. Each of these layers brings information from different sources. The two most typical are static maps and sensor data.
The planner and controller servers cover the normal situations of a robot's navigation: thinking how to get to a place and then doing it. However, there are situations that are not covered by this. This usually occurs when the planner cannot create a feasible plan or the controller is unable to follow an established plan. In these situations, a special behavior is needed.
These behaviors are implemented in the behavior server. Some examples of behaviors are spinning in place, waiting some time or backing up a little.
Understanding the basic blocks used in Nav2 is the first step. The second step is knowing how and when these servers are called. The process in charge of coordinating all these action calls is called a navigator. In particular, Nav2 comes with a Behavior-Tree based navigator called bt_navigator. Keep in mind that this Behavior-Tree is not the same as the behaviors we talked in the last section.
A Behavior-Tree is a method of planning and executing tasks. Frequently used in video-games for NPCs, it has also been used in robotics for some time. Nav2 uses the BehaviorTree.CPP library to implement the navigator.
The basic concept needed to understand the navigator is that each tree has leaf nodes that when “ticked” can call action servers. These action servers can be the planner server, the controller server or a behavior server.
Nav2 is an extensive framework that includes many other plugins, servers and tools. For example, a velocity smoother to avoid sporadic jumps in velocities, packages with tools for managing maps created with SLAM and much more! We encourage you to start with the basic concepts and always keep on learning.
We will be posting a follow-up tutorial on how to use Nav2 where you will learn how to integrate the basic concepts of this framework using a simulated robot.
In addition, you’ll be able to learn more about Navigation 2 and much more about robotics at the The Actuate Summit on September 18th. We're hosting this conference for robotics and embodied AI to share ideas and further advance autonomous robotics. Oh, and Steven Macenski will be giving a talk on Nav2, so get your tickets today — don't miss out!