Understanding Coordinate Transformations for Navigation

In this tutorial, we’ll dive into the world of coordinate frames, the backbone of mobile robot navigation using ROS 2. 

Imagine you’re a robot trying to move around in a room. To do that effectively, you need to understand where you are, where your sensors are, and how to translate the information they provide into a format you can use to navigate safely. That’s where coordinate transformations come in.

Different sensors (like LIDAR, cameras, and IMUs) provide data in their own coordinate frames. Coordinate transformations convert this data into a common frame, usually the robot base frame, making it easier to process and use for navigation.

Prerequisites

All my code for this project is located here on GitHub.

Why Coordinate Transformations Are Important

Why are coordinate transformations so important? Well, think about it like this: your robot is like a person with two “eyes”: a LIDAR and a depth camera. The LIDAR measures distances to objects, while the depth camera provides a 3D image of the environment. 

1-lidar-depth-camera

These sensors are located at different positions on the robot, so they have different perspectives.

To navigate safely in the world, the robot needs to combine the obstacle detection information from both sensors into a common understanding of its surroundings. This is where coordinate transformations come in. They act as a translator, converting the information from each sensor’s unique perspective into a shared language – the robot’s base coordinate frame.

By expressing the LIDAR and depth camera data in the same coordinate frame, the robot can effectively merge the information and create a unified obstacle map of its environment. This allows the robot to plan paths and avoid obstacles, taking into account its own dimensions and the location of objects detected by both sensors.

In essence, coordinate transformations enable the robot to make sense of the world by unifying the different perspectives of its sensors.

Launch the Mobile Robot

Let’s bring your robot to life. Open a terminal window, and type the following command:

x3 

or

bash ~/ros2_ws/src/yahboom_rosmaster/yahboom_rosmaster_bringup/scripts/rosmaster_x3_gazebo.sh

You should now see your robot in Gazebo as well as RViz.

Visualize the Coordinate Frames

Let’s take a look at the coordinate frames.

In RViz, find the Displays panel on the left-hand side. 

Untick the “Robot Model” so that you only see the coordinate frames. 

In the TF dropdown menu, tick “Show Axes” and “Show Names”.

2-show-axes-show-names

These frames are 3D coordinate systems that define the position and orientation of different parts of your robot.

3-show-axes-and-names

Each part of the robot, such as the base, LIDAR, or depth camera, has its own coordinate frame. A coordinate frame consists of three perpendicular axes. By convention:

  • The red arrows represent the x axes
  • The green arrows represent the y axes.
  • The blue arrows represent the z axes.

The origin of each coordinate frame is the point where all three axes intersect.

Right-Hand Rule of Robotics

The right-hand rule is a helpful method to remember the orientation of these axes:

  1. Take your right hand and point your index finger forward. That represents the x-axis (red).
  2. Now point your middle finger to the left. That represents the y-axis (green).
  3. Point your thumb towards the sky. Your thumb represents the z-axis (blue).
2-right-hand-rule-of-robotics

Visualize the Coordinate Frames

As a friendly reminder, if you ever want to see the hierarchy of the coordinate frames for your robot in a PDF file, you can do this.

Open a terminal window, and move to any directory. I will move to my Downloads folder.

cd ~/Downloads/

Type this command: 

ros2 run tf2_tools view_frames
4-coordinate-frame-hierarchy

In the current working directory, you will have a file called frames_20XX.pdf. Open that file.

evince frames_20XX.pdf

In my case, I will type:

evince frames_2024-11-27_16.53.36.pdf

You can see all your coordinate frames.

Coordinate Transformations in Nav2

How Nav2 Uses Coordinate Frames

The Nav2 package for ROS 2 makes extensive use of coordinate transformations to enable a robot to navigate autonomously through an environment. It uses coordinate transformations not just for obstacle detection, but also localization.

Imagine your robot as a character in a video game. Just like how the game keeps track of the character’s position in the game world, Nav2 uses coordinate transformations to keep track of the robot’s position in the real world.

ROS Enhancement Proposals (REPs) Relevant to Nav2

When it comes to configuring your robot for autonomous navigation, ROS has some guidelines to make sure everyone’s robots can play nicely with Nav2. These guidelines are called “REP,” which stands for “ROS Enhancement Proposals.” 

Two important REPs for Nav2 are:

1. REP 105: This guideline explains how to name and describe the different coordinate frames (think of them as different perspectives) for mobile robots.

2. REP 103: This guideline talks about using standard units of measurement (like meters for distance) and following certain rules for describing positions and orientations.

Nav2 follows these guidelines to ensure it can work well with other ROS packages.

Key Coordinate Frames in Nav2

coordsystems_img

The four most important coordinate frames in Nav2 are as follows:

  • base_link 
    • The base_link is usually the center point of your robot’s base. No matter how much the robot moves or turns, the base_link stays put, and is the unifying reference point for the car’s movement and sensors.
  • base_footprint
    • This coordinate frame is a projection of the base_link frame onto the ground plane. Nav2 uses the base_footprint link to determine the robot’s position relative to the ground and nearby obstacles.
  • odom:
    • The odom frame is the robot’s “starting point.” Think of the odom frame like the odometer on your car that measures the distance the car has traveled from some starting point.
    • The odom frame in Nav2 keeps track of the robot’s position and orientation relative to its starting position and orientation. The data from the odom frame is usually based on wheel encoders or other sensors.
    • Like an odometer for your car, the odom frame can drift over time due to small errors accumulating (e.g. slippage of the wheels), making it unreliable for making a long-term estimate of how far the robot has traveled and which way the robot is turned.
  • map:
    • The map frame provides a global, long-term reference for the robot’s position and orientation in an environment. It is constantly updated by a localization system that uses sensor data to correct any drift in the robot’s estimated position.
    • The map frame is like a car’s GPS system. It shows the car’s location on a global map, ensuring that the car’s position remains accurate over long distances. However, just like a GPS update, the robot’s position in the map frame can sometimes jump suddenly when the localization system makes corrections.

Key Coordinate Transformations in Nav2

For Nav2 to do its job, it needs to know how these coordinate frames relate to each other. Nav2 requires the following specific transformations between coordinate frames to be published over ROS 2:

  1. map => odom: This transform connects the global map frame to the robot’s odometry frame. It’s usually provided by a localization or mapping package such as AMCL, which continuously updates the robot’s estimated position in the map.
  2. odom => base_link: This transform relates the robot’s odometry frame to its base frame. It’s typically published by the robot’s odometry system, which combines data from sensors like wheel encoders and IMUs using packages like robot_localization. We will see how to do this in a future tutorial.
  3. base_link => sensor_frames: These transforms describe the relationship between the robot’s base frame and its sensor frames, such as laser_frame for your LIDAR. If your robot has multiple sensors, each sensor frame needs a transform to the base_link frame.

Publishing Transforms in Nav2

To provide the necessary transforms to Nav2, you’ll typically use two methods:

  • Static Transforms: These are fixed transforms that define the relationship between the robot’s base and its sensors. They are usually specified in the robot’s URDF file and published by the Robot State Publisher package.
  • Dynamic Transforms: These transforms change over time, like the map => odom transform, which is updated as the robot moves through the environment. Dynamic transforms are usually published by packages responsible for localization, mapping, or odometry.

Why Transformations Matter in Nav2

Transformations are important for several aspects of Nav2’s functionality:

  1. Localization: By combining sensor data with transform information, Nav2 can estimate the robot’s pose (position and orientation) in the environment.
  2. Path Planning: Nav2’s path planner uses transforms to create a path from the robot’s current position to its goal in the map frame. The planned path is then transformed into the robot’s base frame for execution.
  3. Recovery Behaviors: When the robot encounters issues during navigation, Nav2’s recovery behaviors use transform information to help the robot get back on track.

In summary, transformations help the robot understand its surroundings, keep track of its position, and navigate safely. By following ROS guidelines and managing these transforms, Nav2 ensures your robot can explore the world with ease.

That’s it for the theory. In the next tutorials, you will get hands-on practice with these concepts.

Keep building!

How to Install ROS 2 Navigation (Nav2) – ROS 2 Jazzy

In this tutorial, I will walk you through the process of installing the ROS 2 Navigation (Nav2) stack. By the end of this tutorial, you will have Nav2 fully installed on your system, and you will be able to run this demo:

install-ros2-nav2-jazzy

We will use concepts both from the official Nav2 website as well as the official tutorials.

What is ROS 2 Navigation (Nav2)?

ROS 2 Navigation, or Nav2 for short, is a set of ROS 2 packages that provide a complete solution for autonomous robot navigation. It includes modules for localization, mapping, path planning, and control, allowing robots to navigate through their environment safely and efficiently. Nav2 is built on top of the ROS 2 framework, leveraging its modularity, scalability, and robustness.

Real-World Applications

Nav2 has numerous real-world applications across various industries. Some examples include:

  • Warehouse automation: Autonomous mobile robots (AMRs) equipped with Nav2 can navigate warehouses, pick up and deliver goods, and optimize inventory management.
  • Healthcare and hospitality: Robots powered by Nav2 can assist in hospitals, hotels, and restaurants, navigating through dynamic environments and interacting with humans.
  • Agricultural robotics: Nav2 enables autonomous tractors and harvesters to navigate fields, monitor crops, and perform precision farming tasks.

Types of Robots That Can Use ROS 2 Navigation

Nav2 is versatile and can be used with a wide range of robot platforms, including:

  • Differential drive robots: Robots with two independently driven wheels, such as the TurtleBot and the iRobot Create.
  • Holonomic robots: Robots that can move in any direction without changing their orientation, like the Yahboom ROSMASTER X3.
  • Ackermann steering robots: Robots with car-like steering, such as autonomous vehicles and some agricultural robots.

Prerequisites

All my code for this project is located here on GitHub.

Create Packages

Navigate to your workspace, and create the following packages. You can replace the maintainer-name and maintainer email with your own information.

cd ~/ros2_ws/src/yahboom_rosmaster/
ros2 pkg create --build-type ament_cmake \
                --license BSD-3-Clause \
                --maintainer-name ubuntu \
                --maintainer-email automaticaddison@todo.com \
                yahboom_rosmaster_localization
ros2 pkg create --build-type ament_cmake \
                --license BSD-3-Clause \
                --maintainer-name ubuntu \
                --maintainer-email automaticaddison@todo.com \
               yahboom_rosmaster_navigation

Update the package.xml files for all packages, including the metapackage. Be sure to add a good description line for each.

You can also update the metapackage with the new packages you just created.

cd yahboom_rosmaster
gedit package.xml
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>yahboom_rosmaster</name>
  <version>0.0.0</version>
  <description>ROSMASTER series robots by Yahboom (metapackage).</description>
  <maintainer email="automaticaddison@todo.todo">ubuntu</maintainer>
  <license>BSD-3-Clause</license>

  <buildtool_depend>ament_cmake</buildtool_depend>

  <exec_depend>yahboom_rosmaster_bringup</exec_depend>
  <exec_depend>yahboom_rosmaster_description</exec_depend>
  <exec_depend>yahboom_rosmaster_gazebo</exec_depend>
  <exec_depend>yahboom_rosmaster_localization</exec_depend>
  <exec_depend>yahboom_rosmaster_navigation</exec_depend>
  <exec_depend>yahboom_rosmaster_system_tests</exec_depend>

  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>

  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>

Edit package.xml

Now let’s make sure some key packages are installed.

Open a terminal window, and go to your package.xml folder inside the yahboom_rosmaster_navigation package.

cd ~/ros2_ws/src/yahboom_rosmaster/yahboom_rosmaster_navigation

Open the package.xml file.

Make sure it has these blocks:

…
 <description>Navigation package for ROSMASTER series robots by Yahboom</description>
…

  <depend>navigation2</depend>
  <depend>nav2_bringup</depend>
  <depend>nav2_simple_commander</depend>
  <depend>slam_toolbox</depend>
…

Open a terminal window, and go to your package.xml folder inside the yahboom_rosmaster_localization package.

cd ~/ros2_ws/src/yahboom_rosmaster/yahboom_rosmaster_localization

Open the package.xml file.

Make sure it has these blocks:

…
 <description>Localization package for ROSMASTER series robots by Yahboom</description>
…

  <depend>robot_localization</depend>

…

Edit CMakeLists.txt

Now open the CMakeLists.txt file of the yahboom_rosmaster_navigation package, and add this block:

find_package(navigation2 REQUIRED)
find_package(nav2_bringup REQUIRED)
find_package(slam_toolbox REQUIRED)

Now open the CMakeLists.txt file of the yahboom_rosmaster_localization package, and add this block:

find_package(robot_localization REQUIRED)

Build the Workspace

Now let’s build our workspace.

cd ~/ros2_ws/
rosdep install --from-paths src --ignore-src -r -y

Install any required dependencies. You should then see:

#All required rosdeps installed successfully

If you encounter errors installing the navigation and localization packages, type this:

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
sudo apt-get update -y
sudo apt-get upgrade -y

Then try building again:

cd ~/ros2_ws/
rosdep install --from-paths src --ignore-src -r -y
colcon build && source ~/.bashrc

Let’s add a shortcut alias to make building our workspace quicker:

echo "alias build='cd ~/dev_ws/ && colcon build && source ~/.bashrc'" >> ~/.bashrc

Now going forward, any time you want to build you workspace, just type:

build

Test Your Installation

To test your installation, type the following command in the terminal window:

ros2 launch nav2_bringup tb3_simulation_launch.py headless:=False

To move the robot around, first set the initial pose in RViz based on where you think the robot is located and the direction you think the robot is pointed. 

Click the 2D Pose Estimate button.

2-2d-pose-estimate

Click and hold where you think the robot is and then drag your mouse in the direction the robot is oriented.

Now click the Nav2 Goal button.

3-nav2-goal

Click and hold where you want to send the robot. And drag in the direction of your desired goal orientation.

The robot will move to the goal.

4-move-to-goal

Press CTRL + C to close everything.

To test mapping, open a terminal window, and type the following command:

ros2 launch nav2_bringup tb4_simulation_launch.py slam:=True headless:=False

Click and hold where you want to send the robot. And drag in the direction of your desired goal orientation.

5-creating-a-map

The robot will move to the goal and map in the process.

6-creating-a-map-2

Press CTRL + C when you’re done.

That’s it. Keep building!

How to Completely Uninstall ROS 2

In this tutorial, I will show you how to completely uninstall ROS 2 from your system.

Uninstall ROS 2

If you want to uninstall the current version of ROS 2 that you have on your computer, type the following commands in the terminal window:

sudo apt remove ~nros-${ROS_DISTRO}-* && sudo apt autoremove

Otherwise, if you want to completely uninstall ROS 2 from your system, type this command:

sudo apt remove ros-* && sudo apt autoremove

Remove ROS 2 References in the .bashrc

Remove all ROS 2-related lines from your ~/.bashrc file.

gedit ~/.bashrc

For example, you can remove:

source ~/ros2_ws/install/setup.bash

Save the file.

Delete the Workspace

Now delete your ROS 2 workspace. For example, if your workspace is named ros2_ws, type:

rm -rf ~/ros2_ws

Remove the Repository

Finally Remove the repository:

sudo apt-get update
sudo rm /etc/apt/sources.list.d/ros2.list
sudo apt-get update
sudo apt autoremove
sudo apt-get upgrade

Reboot Your Machine

sudo reboot

That is it! Now you are back to a fresh system with no ROS 2 installed.

Keep building!