Figure 1: Beluga and Nav2 logos

TL; DR Beluga AMCL is a drop-in replacement for Nav2 AMCL on all ROS (2) LTS distributions and a gateway to more advanced localization solutions for robotics
applications using Monte Carlo methods.

And that’s pretty much it. Are you crawling the web in hopes you can get your wheeled robot going using open source ROS 2 packages that are easy to understand and deploy, preferably well-maintained and active? And you need them right now? I feel you. Here’s another datapoint. Keep going. You may want to check Fuse, KISS-ICP, SLAM Toolbox, Cartographer ROS, and RTAB Map too if you haven’t already.

Have 5 more minutes? Cool, let me explain what Beluga meeting Nav2 means, and why you should care about it.


Nav2 is the de facto standard autonomy framework in ROS 2. It covers the planning, control, and decision making needs of a wide range of robotics applications, typically but not limited to those leveraging mobile robots, from simple differential driven circular bases to legged humanoids. In all cases, some degree of spatial awareness is required. To define a goal, to plan and execute a route, to avoid collisions, a robot needs to know where it is in relation to its surroundings and the objects and people in it. Owing to its ROS (1) Navigation Stack legacy, the nature of successful robotics use cases in industry, and the overall direction of the project. It so happens that Nav2 bundles a variety of environment representations but a single localization solution: a 2D lidar-based AMCL implementation. Despite its age – the original codebase is from the early 2000s –, AMCL is a relatively simple and robust algorithm to improve on dead-reckoning estimates that continues to find its way into production.

There are high hopes for what robotics and AI can deliver. That drives funding and market demand for promising research avenues and new business opportunities, to which research labs and companies are forced to adapt, further increasing the rate of innovation. That prototype you are building may soon become too small, too slow, too expensive, or too dumb to stand up to the competition, or plain inadequate if circumstances force a transition to another market niche. These perturbations take up a lot of time and resources to weather. A flexible, modular system is easier to bend than a monolithic one. This puts ROS (2) in a great position to serve the robotics industry. The same applies to Nav2: its plugin-based architecture and a plethora of open source plugins afford sudden course corrections. Well, almost. Localization and mapping have to be dealt with separately.

And that takes us to Beluga. Beluga is an open-source toolkit for Monte Carlo Localization (MCL) that started out as a ground-up (re)implementation of Nav2 AMCL [TODO: add link to previous article], having seen many private forks in production over the years. Its 2D lidar-based AMCL variant is equally easy to use with Nav2, but unlike its predecessor, it is modular and extensible by design. This translates into a well-defined path to change. A path, not the path. Beluga does not and will not exhaust all possible approaches to localization. It is only a structured approach to apply Bayesian ideas to state estimation in robotics. No more, no less.

Enough with generalities. Let me show you how easily you can use Beluga on a ROS 2 + Nav2 powered AMR.


If you are already using Nav2 AMCL, you can just switch from nav2_amcl to beluga_amcl on launch. In most cases, no other changes are necessary. Taking nav2_bringup as an example, the patch amounts to a grand total of 4 lines.

--- a/nav2_bringup/launch/localization_launch.py
+++ b/nav2_bringup/launch/localization_launch.py
@@ -149,8 +149,8 @@ def generate_launch_description():
                 remappings=remappings,
             ),
             Node(
-                package='nav2_amcl',
-                executable='amcl',
+                package='beluga_amcl',
+                executable='amcl_node',
                 name='amcl',
                 output='screen',
                 respawn=use_respawn,
@@ -215,8 +215,8 @@ def generate_launch_description():
                 target_container=container_name_full,
                 composable_node_descriptions=[
                     ComposableNode(
-                        package='nav2_amcl',
-                        plugin='nav2_amcl::AmclNode',
+                        package='beluga_amcl',
+                        plugin='beluga_amcl::AmclNode',
                         name='amcl',
                         parameters=[configured_params],
                         remappings=remappings,

That roughly summarizes Beluga’s Nav2 integration tutorial, and what you’ll find in the Beluga Nav2 integration demo. It is also how we got these fancy recordings.

Video 1: Kobuki robot navigating at Ekumen HQ in Buenos Aires, Argentina
Video 2: Kobuki robot navigating the Gazebo Classic sim twin of Ekumen HQ

If you are not, yet or ever, head over to Beluga’s user guide. To localize an AMR you will need an odometry source and a 2D lidar, first to build a 2D map, then to localize on it. For other means of locomotion and sensing modalities you will have to wait a bit. An outline is there, but out-of-the-box support is not yet.

Hope Beluga can help you and your team bootstrap your up and coming robot. If you run into issues, report them ASAP. We are always on the lookout. If you need more features, you can ask and you can build. And if you don’t have a use for it right now, you can follow the project on Github. It’s under active development – you might find it useful later.