By ihsumlee , 9 June 2026
content

Position in the full course

This is the eighth step of the course.

The full learning order is:

1. ROS 2 node/topic/launch review
2. TF2 frame concept
3. Static sensor frames
4. Dynamic odometry frame
5. URDF + robot_state_publisher
6. SLAM mapping
7. AMCL localization
8. Nav2 path planning
9. RViz goal navigation
10. TF2 debugging in Nav2

In Step 7, you used AMCL to localize the robot on a saved map.

After AMCL works, the robot has this TF tree:

map
 └── odom
      └── base_link
            β”œβ”€β”€ base_laser
            β”œβ”€β”€ camera_link
            └── imu_link

In Step 8, you will learn how Nav2 plans a path from the current robot pose to a goal pose.

The main idea is:

AMCL tells Nav2 where the robot is.
Nav2 Planner Server computes a path to the goal.
Nav2 Controller Server follows the path.
Costmaps help Nav2 avoid obstacles.

1. Learning objectives

After this module, you should be able to:

  1. Explain what path planning means.
  2. Explain the difference between global planning and local control.
  3. Explain the role of the Nav2 Planner Server.
  4. Explain the role of the Nav2 Controller Server.
  5. Explain the role of global and local costmaps.
  6. Launch the Nav2 navigation stack after localization is ready.
  7. Check Nav2 lifecycle node status.
  8. Check whether the path planning action is available.
  9. Send a path-planning request from the command line.
  10. Visualize the planned path in RViz2.
  11. Understand common Nav2 path planning problems.

2. Suggested teaching duration

Suggested duration: 2 hours

| Time | Activity | | ----------- | --------------------------------------- | | 0–15 min | Review AMCL localization and TF tree | | 15–30 min | Explain path planning concept | | 30–45 min | Explain Nav2 servers | | 45–60 min | Explain global and local costmaps | | 60–80 min | Launch Nav2 navigation stack | | 80–95 min | Check Nav2 actions and lifecycle status | | 95–110 min | Send a path planning request | | 110–120 min | Summary and homework |


3. What is path planning?

Path planning means:

The robot computes a path from its current pose to a target goal pose.

For example:

Current robot pose: near the classroom door
Goal pose: near the teacher desk

Nav2 should compute a safe path:

from current pose
around obstacles
to the goal pose

A path is usually represented as many poses connected together.

In ROS 2, a planned path is usually published using:

nav_msgs/msg/Path

4. What Nav2 needs before planning

Before Nav2 can plan a path, you need:

1. A map
2. Localization
3. TF tree
4. Costmaps
5. Planner Server
6. Controller Server
7. BT Navigator

From Step 7, you should already have:

map topic: /map
LiDAR topic: /scan
odometry topic: /odom
TF: map β†’ odom β†’ base_link

Check these first:

ros2 topic echo /map --once
ros2 topic echo /scan --once
ros2 topic echo /odom --once
ros2 run tf2_ros tf2_echo map base_link

If these are not working, Nav2 path planning will usually fail.


5. Global planning and local control

Nav2 navigation can be explained using two major ideas:

global planning
local control

5.1 Global planning

Global planning computes a path from the robot’s current pose to the goal pose.

It uses the map and global costmap.

Example:

Start: robot current pose
Goal: target pose
Output: global path

The main Nav2 server is:

Planner Server

5.2 Local control

Local control makes the robot follow the planned path.

It uses the local costmap and robot motion controller.

Example:

Input: global path
Output: velocity command

The main Nav2 server is:

Controller Server

The controller usually publishes velocity commands to:

/cmd_vel

or sometimes:

/cmd_vel_nav

depending on your configuration.


6. Global costmap and local costmap

Costmaps are very important in Nav2.

A costmap is a 2D grid map where each cell has a cost.

Common cost values represent:

free space
unknown space
occupied space
inflated obstacle area

6.1 Global costmap

The global costmap is mainly used by the planner.

It helps answer:

Which global path should the robot take to reach the goal?

Usually, the global costmap uses:

static map
inflation layer
sometimes obstacle layer

6.2 Local costmap

The local costmap is mainly used by the controller.

It helps answer:

How should the robot move right now while avoiding nearby obstacles?

Usually, the local costmap uses:

LiDAR scan
obstacle layer
inflation layer
rolling window

7. Nav2 path planning architecture

A simplified Nav2 architecture is:

RViz2 Goal
   ↓
BT Navigator
   ↓
Planner Server
   ↓
Global Path
   ↓
Controller Server
   ↓
/cmd_vel
   ↓
Robot moves

In this step, focus on the planning part:

Planner Server computes the global path.
Costmaps provide obstacle information.

8. Important Nav2 nodes

When the Nav2 navigation stack is running, you may see nodes such as:

bt_navigator
planner_server
controller_server
behavior_server
smoother_server
velocity_smoother
waypoint_follower
global_costmap
local_costmap
lifecycle_manager_navigation

For beginners, remember these four first:

| Node | Main role | | ------------------- | ----------------------------------------------- | | bt_navigator | Receives navigation task and runs behavior tree | | planner_server | Computes global path | | controller_server | Follows path and outputs velocity | | behavior_server | Provides recovery behaviors |


9. Install required packages

Open a terminal:

source /opt/ros/jazzy/setup.bash

Install Nav2 packages:

sudo apt update
sudo apt install ros-jazzy-navigation2 \
                 ros-jazzy-nav2-bringup \
                 ros-jazzy-nav2-planner \
                 ros-jazzy-nav2-controller \
                 ros-jazzy-nav2-bt-navigator \
                 ros-jazzy-nav2-behavior-tree \
                 ros-jazzy-nav2-costmap-2d \
                 ros-jazzy-rviz2 \
                 ros-jazzy-tf2-tools

For keyboard teleoperation:

sudo apt install ros-jazzy-teleop-twist-keyboard

10. Practice option A: Use TurtleBot simulation

This is the easiest classroom option.

You can launch TurtleBot simulation with localization and navigation together:

source /opt/ros/jazzy/setup.bash

ros2 launch nav2_bringup tb3_simulation_launch.py \
  headless:=False \
  slam:=False \
  map:=$HOME/ros2_ws/maps/classroom_map.yaml

Important:

The map must match the simulation world.
If the map does not match the world, AMCL and path planning will fail.

After launch, RViz2 should open.

Set the initial pose using:

2D Pose Estimate

Then you can test path planning and navigation.


11. Practice option B: Use your own robot or AMR interface

For your own robot, start the robot bringup first.

You need:

LiDAR driver
odometry publisher
robot_state_publisher
AMCL localization
map_server
TF tree
/cmd_vel support

Check:

ros2 topic echo /scan --once
ros2 topic echo /odom --once
ros2 topic echo /map --once
ros2 run tf2_ros tf2_echo map base_link

If all of these work, you can launch the Nav2 navigation stack.


12. Launch localization first

If you are not using the TurtleBot combined launch file, launch localization first.

For a real robot:

source /opt/ros/jazzy/setup.bash

ros2 launch nav2_bringup localization_launch.py \
  map:=$HOME/ros2_ws/maps/classroom_map.yaml \
  use_sim_time:=False

For simulation:

source /opt/ros/jazzy/setup.bash

ros2 launch nav2_bringup localization_launch.py \
  map:=$HOME/ros2_ws/maps/classroom_map.yaml \
  use_sim_time:=True

In RViz2, set the initial pose:

Use 2D Pose Estimate.
Click the robot position on the map.
Drag the arrow to set direction.

Then check:

ros2 run tf2_ros tf2_echo map base_link

If this transform works, localization is ready.


13. Launch Nav2 navigation stack

After localization is ready, launch the navigation stack.

For a real robot:

source /opt/ros/jazzy/setup.bash

ros2 launch nav2_bringup navigation_launch.py \
  use_sim_time:=False

For simulation:

source /opt/ros/jazzy/setup.bash

ros2 launch nav2_bringup navigation_launch.py \
  use_sim_time:=True

This launch file starts the navigation servers, such as:

planner_server
controller_server
bt_navigator
behavior_server
waypoint_follower
lifecycle_manager_navigation

14. Check Nav2 nodes

Open a new terminal:

source /opt/ros/jazzy/setup.bash

List nodes:

ros2 node list

You should see nodes similar to:

 /planner_server
 /controller_server
 /bt_navigator
 /behavior_server
 /lifecycle_manager_navigation

If these nodes do not appear, the navigation stack did not start correctly.


15. Check lifecycle status

Nav2 nodes are lifecycle nodes.

This means they must be activated before they can work.

Check the planner server:

ros2 lifecycle get /planner_server

Check the controller server:

ros2 lifecycle get /controller_server

Check the BT navigator:

ros2 lifecycle get /bt_navigator

Expected state:

active

If a node is not active, planning or navigation may fail.


16. Check available Nav2 actions

List actions:

ros2 action list

You should see actions such as:

/compute_path_to_pose
/follow_path
/navigate_to_pose

Meaning:

| Action | Purpose | | ----------------------- | ------------------------------------------- | | /compute_path_to_pose | Ask Planner Server to compute a path | | /follow_path | Ask Controller Server to follow a path | | /navigate_to_pose | Ask BT Navigator to execute full navigation |

In this step, focus on:

/compute_path_to_pose

17. Check action type

Run:

ros2 action type /compute_path_to_pose

Expected type:

nav2_msgs/action/ComputePathToPose

You can inspect the action interface:

ros2 interface show nav2_msgs/action/ComputePathToPose

This shows what information the action needs.


18. Send a path planning request from command line

Before sending a goal, make sure:

Fixed Frame is map.
AMCL is localized.
map β†’ base_link works.
planner_server is active.

Check:

ros2 run tf2_ros tf2_echo map base_link
ros2 lifecycle get /planner_server

Now send a simple planning request:

ros2 action send_goal /compute_path_to_pose nav2_msgs/action/ComputePathToPose \
"{
  goal: {
    header: {
      frame_id: 'map'
    },
    pose: {
      position: {
        x: 1.0,
        y: 0.5,
        z: 0.0
      },
      orientation: {
        x: 0.0,
        y: 0.0,
        z: 0.0,
        w: 1.0
      }
    }
  },
  planner_id: 'GridBased'
}"

This asks Nav2:

Compute a path from the current robot pose to x = 1.0, y = 0.5 in the map frame.

If planning succeeds, you should see an action result containing a path.


19. Visualize the planned path in RViz2

Open RViz2:

rviz2

Set:

Fixed Frame = map

Add displays:

Map
TF
RobotModel
LaserScan
Odometry
Path
Global Costmap
Local Costmap

For the Path display, try topic:

/plan

Depending on your Nav2 configuration, the path topic may also appear under another name.

Check path-related topics:

ros2 topic list | grep plan
ros2 topic list | grep path

20. Understanding the planned path

A planned path is not the same as robot motion.

A planned path means:

Nav2 has computed a route.
The robot has not necessarily moved yet.

Robot motion happens when the controller follows the path and publishes velocity commands.

This is why Step 8 focuses on path planning, while Step 9 will focus more on sending a goal from RViz2 and observing full navigation behavior.


21. Check costmap topics

List costmap topics:

ros2 topic list | grep costmap

You may see topics such as:

 /global_costmap/costmap
 /global_costmap/costmap_updates
 /local_costmap/costmap
 /local_costmap/costmap_updates
 /global_costmap/published_footprint
 /local_costmap/published_footprint

Check global costmap:

ros2 topic echo /global_costmap/costmap --once

Check local costmap:

ros2 topic echo /local_costmap/costmap --once

If costmaps are not published, the planner or controller may not work.


22. Create your own Nav2 planning package

This is useful for a clean course structure.

Create a package:

mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src

ros2 pkg create --build-type ament_python --license Apache-2.0 amr_navigation

Create folders:

cd ~/ros2_ws/src/amr_navigation
mkdir launch config rviz

23. Create a beginner Nav2 parameter file

Create:

nano config/nav2_params.yaml

Paste this beginner configuration:

amcl:
  ros__parameters:
    use_sim_time: false
    global_frame_id: map
    odom_frame_id: odom
    base_frame_id: base_link
    scan_topic: scan
    min_particles: 500
    max_particles: 2000
    update_min_d: 0.25
    update_min_a: 0.20
    transform_tolerance: 1.0

map_server:
  ros__parameters:
    use_sim_time: false
    yaml_filename: ""

planner_server:
  ros__parameters:
    use_sim_time: false
    expected_planner_frequency: 20.0
    planner_plugins: ["GridBased"]

    GridBased:
      plugin: "nav2_navfn_planner::NavfnPlanner"
      tolerance: 0.5
      use_astar: false
      allow_unknown: true

controller_server:
  ros__parameters:
    use_sim_time: false
    controller_frequency: 20.0
    min_x_velocity_threshold: 0.001
    min_y_velocity_threshold: 0.5
    min_theta_velocity_threshold: 0.001
    progress_checker_plugins: ["progress_checker"]
    goal_checker_plugins: ["general_goal_checker"]
    controller_plugins: ["FollowPath"]

    progress_checker:
      plugin: "nav2_controller::SimpleProgressChecker"
      required_movement_radius: 0.5
      movement_time_allowance: 10.0

    general_goal_checker:
      plugin: "nav2_controller::SimpleGoalChecker"
      xy_goal_tolerance: 0.25
      yaw_goal_tolerance: 0.25
      stateful: true

    FollowPath:
      plugin: "dwb_core::DWBLocalPlanner"
      debug_trajectory_details: false
      min_vel_x: 0.0
      min_vel_y: 0.0
      max_vel_x: 0.26
      max_vel_y: 0.0
      max_vel_theta: 1.0
      min_speed_xy: 0.0
      max_speed_xy: 0.26
      min_speed_theta: 0.0
      acc_lim_x: 2.5
      acc_lim_y: 0.0
      acc_lim_theta: 3.2
      decel_lim_x: -2.5
      decel_lim_y: 0.0
      decel_lim_theta: -3.2
      vx_samples: 20
      vy_samples: 1
      vtheta_samples: 20
      sim_time: 1.7
      linear_granularity: 0.05
      angular_granularity: 0.025
      transform_tolerance: 0.2
      xy_goal_tolerance: 0.25
      trans_stopped_velocity: 0.25
      short_circuit_trajectory_evaluation: true
      stateful: true
      critics: [
        "RotateToGoal",
        "Oscillation",
        "BaseObstacle",
        "GoalAlign",
        "PathAlign",
        "PathDist",
        "GoalDist"
      ]
      BaseObstacle.scale: 0.02
      PathAlign.scale: 32.0
      PathAlign.forward_point_distance: 0.1
      GoalAlign.scale: 24.0
      GoalAlign.forward_point_distance: 0.1
      PathDist.scale: 32.0
      GoalDist.scale: 24.0
      RotateToGoal.scale: 32.0
      RotateToGoal.slowing_factor: 5.0
      RotateToGoal.lookahead_time: -1.0

bt_navigator:
  ros__parameters:
    use_sim_time: false
    global_frame: map
    robot_base_frame: base_link
    odom_topic: odom
    bt_loop_duration: 10
    default_server_timeout: 20
    wait_for_service_timeout: 1000
    navigators: ["navigate_to_pose", "navigate_through_poses"]

    navigate_to_pose:
      plugin: "nav2_bt_navigator::NavigateToPoseNavigator"

    navigate_through_poses:
      plugin: "nav2_bt_navigator::NavigateThroughPosesNavigator"

behavior_server:
  ros__parameters:
    use_sim_time: false
    local_costmap_topic: local_costmap/costmap_raw
    global_costmap_topic: global_costmap/costmap_raw
    local_footprint_topic: local_costmap/published_footprint
    global_footprint_topic: global_costmap/published_footprint
    cycle_frequency: 10.0
    behavior_plugins: ["spin", "backup", "wait"]

    spin:
      plugin: "nav2_behaviors::Spin"

    backup:
      plugin: "nav2_behaviors::BackUp"

    wait:
      plugin: "nav2_behaviors::Wait"

global_costmap:
  global_costmap:
    ros__parameters:
      use_sim_time: false
      global_frame: map
      robot_base_frame: base_link
      update_frequency: 1.0
      publish_frequency: 1.0
      resolution: 0.05
      track_unknown_space: true
      robot_radius: 0.22
      plugins: ["static_layer", "obstacle_layer", "inflation_layer"]

      static_layer:
        plugin: "nav2_costmap_2d::StaticLayer"
        map_subscribe_transient_local: true

      obstacle_layer:
        plugin: "nav2_costmap_2d::ObstacleLayer"
        enabled: true
        observation_sources: scan
        scan:
          topic: /scan
          max_obstacle_height: 2.0
          clearing: true
          marking: true
          data_type: "LaserScan"
          raytrace_max_range: 3.0
          raytrace_min_range: 0.0
          obstacle_max_range: 2.5
          obstacle_min_range: 0.0

      inflation_layer:
        plugin: "nav2_costmap_2d::InflationLayer"
        cost_scaling_factor: 3.0
        inflation_radius: 0.55

      always_send_full_costmap: true

local_costmap:
  local_costmap:
    ros__parameters:
      use_sim_time: false
      global_frame: odom
      robot_base_frame: base_link
      update_frequency: 5.0
      publish_frequency: 2.0
      rolling_window: true
      width: 3
      height: 3
      resolution: 0.05
      robot_radius: 0.22
      plugins: ["obstacle_layer", "inflation_layer"]

      obstacle_layer:
        plugin: "nav2_costmap_2d::ObstacleLayer"
        enabled: true
        observation_sources: scan
        scan:
          topic: /scan
          max_obstacle_height: 2.0
          clearing: true
          marking: true
          data_type: "LaserScan"
          raytrace_max_range: 3.0
          raytrace_min_range: 0.0
          obstacle_max_range: 2.5
          obstacle_min_range: 0.0

      inflation_layer:
        plugin: "nav2_costmap_2d::InflationLayer"
        cost_scaling_factor: 3.0
        inflation_radius: 0.55

      always_send_full_costmap: true

lifecycle_manager_navigation:
  ros__parameters:
    use_sim_time: false
    autostart: true
    node_names:
      - controller_server
      - planner_server
      - behavior_server
      - bt_navigator

lifecycle_manager_localization:
  ros__parameters:
    use_sim_time: false
    autostart: true
    node_names:
      - map_server
      - amcl

Important:

This parameter file is a beginner template.
For a real AMR, you must tune robot_radius, velocity limits, acceleration limits, LiDAR range, and controller parameters.

24. Create a Nav2 launch file

Create:

nano launch/nav2_planning.launch.py

Paste:

import os

from ament_index_python.packages import get_package_share_directory

from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource


def generate_launch_description():

    package_name = 'amr_navigation'

    bringup_dir = get_package_share_directory('nav2_bringup')

    params_file = os.path.join(
        get_package_share_directory(package_name),
        'config',
        'nav2_params.yaml'
    )

    navigation_launch = IncludeLaunchDescription(
        PythonLaunchDescriptionSource(
            os.path.join(bringup_dir, 'launch', 'navigation_launch.py')
        ),
        launch_arguments={
            'use_sim_time': 'false',
            'params_file': params_file
        }.items()
    )

    return LaunchDescription([
        navigation_launch
    ])

This launch file starts the Nav2 navigation stack using your parameter file.


25. Modify setup.py

Open:

nano setup.py

Add imports at the top:

import os
from glob import glob

Modify data_files:

data_files=[
    ('share/ament_index/resource_index/packages',
        ['resource/' + package_name]),
    ('share/' + package_name, ['package.xml']),
    (os.path.join('share', package_name, 'launch'), glob('launch/*.py')),
    (os.path.join('share', package_name, 'config'), glob('config/*.yaml')),
    (os.path.join('share', package_name, 'rviz'), glob('rviz/*.rviz')),
],

26. Modify package.xml

Open:

nano package.xml

Add dependencies before the closing </package> tag:

<exec_depend>nav2_bringup</exec_depend>
<exec_depend>nav2_planner</exec_depend>
<exec_depend>nav2_controller</exec_depend>
<exec_depend>nav2_bt_navigator</exec_depend>
<exec_depend>nav2_behaviors</exec_depend>
<exec_depend>nav2_costmap_2d</exec_depend>
<exec_depend>rviz2</exec_depend>
<exec_depend>tf2_tools</exec_depend>

27. Build the navigation package

Run:

cd ~/ros2_ws
colcon build --packages-select amr_navigation
source install/setup.bash

28. Run your Nav2 planning launch file

Before launching, make sure localization is already running.

Check:

ros2 topic echo /map --once
ros2 topic echo /scan --once
ros2 topic echo /odom --once
ros2 run tf2_ros tf2_echo map base_link

Then run:

ros2 launch amr_navigation nav2_planning.launch.py

Check nodes:

ros2 node list

Check lifecycle:

ros2 lifecycle get /planner_server
ros2 lifecycle get /controller_server
ros2 lifecycle get /bt_navigator

Expected state:

active

29. Test path planning with your package

Send a planning request:

ros2 action send_goal /compute_path_to_pose nav2_msgs/action/ComputePathToPose \
"{
  goal: {
    header: {
      frame_id: 'map'
    },
    pose: {
      position: {
        x: 1.0,
        y: 0.5,
        z: 0.0
      },
      orientation: {
        w: 1.0
      }
    }
  },
  planner_id: 'GridBased'
}"

If successful, the planner returns a path.

You can change the goal pose:

x: 2.0
y: 1.0

or:

x: -1.0
y: 0.5

But the goal must be inside the known map and not inside an obstacle.


30. How Step 8 connects to Step 9

In Step 8, you learned how Nav2 computes a path.

In Step 9, you will send navigation goals using RViz2.

The difference is:

Step 8: Focus on Nav2 path planning and server checking.
Step 9: Focus on using RViz2 2D Goal Pose for full navigation.

Step 8 helps you understand what happens inside Nav2 before you use the RViz2 goal button.


31. Common problems and solutions

Problem 1: /compute_path_to_pose does not exist

Possible reasons:

planner_server is not running.
navigation_launch.py was not launched.
Nav2 lifecycle nodes are not active.

Check:

ros2 node list
ros2 action list
ros2 lifecycle get /planner_server

Solution:

Launch the Nav2 navigation stack.
Check lifecycle status.
Check terminal error messages.

Problem 2: Planner Server is not active

Check:

ros2 lifecycle get /planner_server

If it is not active, possible reasons are:

Parameter file has errors.
Costmap cannot start.
TF is missing.
Map is not available.

Solution:

ros2 topic echo /map --once
ros2 run tf2_ros tf2_echo map base_link
ros2 topic echo /scan --once

Problem 3: Path planning fails

Possible reasons:

Goal is outside the map.
Goal is inside an obstacle.
Robot is not localized.
Global costmap is not available.
TF map β†’ base_link is missing.

Check:

ros2 run tf2_ros tf2_echo map base_link
ros2 topic echo /global_costmap/costmap --once

Solution:

Set the initial pose again.
Choose a reachable goal.
Check the map and costmap in RViz2.

Problem 4: RViz2 does not show the path

Possible reasons:

Path display topic is wrong.
Planner did not successfully compute a path.
RViz2 Fixed Frame is wrong.

Solution:

Set Fixed Frame to map.
Check path topics using ros2 topic list.
Add a Path display with the correct topic.

Problem 5: Costmap is empty or wrong

Possible reasons:

Map is not loaded.
Scan topic is wrong.
Obstacle layer configuration is wrong.
Robot footprint or radius is wrong.
TF is missing.

Check:

ros2 topic echo /map --once
ros2 topic echo /scan --once
ros2 topic echo /global_costmap/costmap --once
ros2 topic echo /local_costmap/costmap --once

Problem 6: Robot footprint is too large or too small

If the robot radius is too large:

Nav2 may think narrow paths are blocked.

If the robot radius is too small:

Nav2 may plan too close to obstacles.

In the parameter file, check:

robot_radius: 0.22

For a real AMR, this value should match your robot size.


Problem 7: Duplicate Nav2 nodes

Problem example:

You launch tb3_simulation_launch.py and also launch navigation_launch.py separately.

This may start duplicate Nav2 servers.

Solution:

Use one bringup method at a time.
For TurtleBot simulation, tb3_simulation_launch.py may already start Nav2.
For your own robot, launch localization and navigation carefully without duplicates.

32. Practice assignment

Assignment title

Check and Test Nav2 Path Planning

Task 1: Check localization readiness

Submit screenshots of:

ros2 topic echo /map --once
ros2 topic echo /scan --once
ros2 run tf2_ros tf2_echo map base_link

Task 2: Launch Nav2 navigation stack

Run:

ros2 launch nav2_bringup navigation_launch.py use_sim_time:=False

For simulation:

ros2 launch nav2_bringup navigation_launch.py use_sim_time:=True

Submit a screenshot of the terminal output.


Task 3: Check Nav2 nodes

Submit screenshots of:

ros2 node list
ros2 action list

You should find:

/compute_path_to_pose
/follow_path
/navigate_to_pose

Task 4: Check lifecycle status

Submit screenshots of:

ros2 lifecycle get /planner_server
ros2 lifecycle get /controller_server
ros2 lifecycle get /bt_navigator

Expected result:

active

Task 5: Send a planning request

Run:

ros2 action send_goal /compute_path_to_pose nav2_msgs/action/ComputePathToPose \
"{
  goal: {
    header: {
      frame_id: 'map'
    },
    pose: {
      position: {
        x: 1.0,
        y: 0.5,
        z: 0.0
      },
      orientation: {
        w: 1.0
      }
    }
  },
  planner_id: 'GridBased'
}"

Submit a screenshot of the action result.


Task 6: Visualize in RViz2

In RViz2, add:

Map
TF
RobotModel
LaserScan
Global Costmap
Local Costmap
Path

Set:

Fixed Frame = map

Submit a screenshot showing the map, robot, costmap, and planned path.


Task 7: Explain the result

Write a short explanation:

The map topic is:
The scan topic is:
The robot base frame is:
The global frame is:
The planner action is:
The planner plugin is:
The global costmap topic is:
The local costmap topic is:
The goal pose I tested was:
The path planning result was:
One problem I observed was:
How I fixed or would fix it:

33. Mini quiz

  1. What is path planning?
  2. What is the difference between global planning and local control?
  3. What does the Planner Server do?
  4. What does the Controller Server do?
  5. What does the BT Navigator do?
  6. What is a costmap?
  7. What is the difference between global costmap and local costmap?
  8. What action is used to request only path computation?
  9. What action is used for full navigation to a goal pose?
  10. Why must AMCL localization work before Nav2 path planning?
  11. Why must map β†’ base_link be available?
  12. What may happen if the robot radius is configured incorrectly?

34. Key summary

In this module, you learned how Nav2 path planning works.

Before path planning, you need:

map
localization
TF: map β†’ odom β†’ base_link
scan topic
odometry topic
costmaps

The Planner Server computes:

a global path from current robot pose to goal pose

The Controller Server follows:

the planned path and outputs velocity commands

The BT Navigator manages:

the full navigation behavior

You checked:

Nav2 nodes
Nav2 lifecycle state
Nav2 actions
costmap topics
path planning request
RViz2 visualization

The most important idea is:

AMCL tells Nav2 where the robot is.
Planner Server computes where the robot should go.
Controller Server commands how the robot should move.

In the next module, you will learn:

RViz goal navigation

You will use RViz2 2D Goal Pose to send a full navigation task to Nav2.

Tags