이 가이드는 인류와 AI가 함께 만드는 지식입니다.
이 콘텐츠는 Human + AI Partnership 철학 아래 모든 사람이 로봇·AI를 배울 수 있도록 무료로 제공됩니다. 당신의 질문과 기여가 다음 학생의 미래를 바꿉니다.
ROS 2 SLAM & Advanced Navigation Guide 2026
Implement real-time SLAM for autonomous mapping and localization. Master Cartographer and RTAB-Map, configure Nav2 for path planning, and deploy autonomous navigation systems.
1. SLAM Fundamentals in ROS 2
SLAM simultaneously localizes the robot and builds a map:
# Install SLAM packages
sudo apt-get install -y ros-humble-cartographer ros-humble-cartographer-ros ros-humble-rtabmap-ros ros-humble-nav2-bringup
# Launch Cartographer SLAM
ros2 launch cartographer_ros cartographer.launch.py use_sim_time:=false configuration_basename:=my_robot.lua
# Launch RTAB-Map
ros2 launch rtabmap_ros rtabmap.launch.py rtabmap_args:="-d" use_sim_time:=false2. Cartographer Configuration
Configure Cartographer for optimal SLAM:
-- my_robot.lua
include "map_builder.lua"
include "trajectory_builder.lua"
options = {
map_builder = MAP_BUILDER,
trajectory_builder = TRAJECTORY_BUILDER,
map_frame = "map",
tracking_frame = "imu_link",
published_frame = "odom",
odom_frame = "odom",
provide_odom_frame = true,
publish_frame_projected_to_2d = false,
use_pose_extrapolator = true,
use_odometry = true,
use_nav_sat = false,
use_landmarks = false,
num_laser_scans = 1,
num_multi_echo_laser_scans = 0,
num_subdivisions_per_laser_scan = 1,
num_point_clouds = 0,
lookup_transform_timeout_sec = 0.2,
submap_publish_period_sec = 0.3,
pose_publish_period_sec = 5e-2,
trajectory_publish_period_sec = 30e-3,
rangefinder_sampling_ratio = 1.,
odometry_sampling_ratio = 1.,
fixed_frame_pose_sampling_ratio = 1.,
imu_sampling_ratio = 1.,
landmarks_sampling_ratio = 1.,
}
return options3. RTAB-Map Configuration
Real-time appearance-based SLAM with loop closure:
# rtabmap.launch.py
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
DeclareLaunchArgument('use_sim_time', default_value='false'),
Node(
package='rtabmap_ros',
executable='rtabmap',
name='rtabmap',
output='screen',
parameters=[{
'frame_id': 'base_footprint',
'subscribe_depth': True,
'subscribe_rgb': True,
'subscribe_scan': True,
'approx_sync': True,
'use_sim_time': True,
'mem_cleaning_strategy': 0,
'memory_target_ratio': 0.8,
'register_intensity': False,
'wait_for_transform': 0.5,
'Rtabmap/TimeThr': 700,
'Rtabmap/LoopThr': 0.11,
'Rtabmap/MinLoopClosureDistance': 1.0,
'Rtabmap/MaxMemorySize': 2000,
}],
remappings=[
('rgb/image', 'camera/rgb/image_raw'),
('rgb/camera_info', 'camera/rgb/camera_info'),
('depth/image', 'camera/depth/image_raw'),
]
),
])4. Nav2 Stack Configuration
Configure Nav2 for autonomous navigation:
# nav2_params.yaml
amcl:
ros__parameters:
use_sim_time: false
alpha1: 0.2
alpha2: 0.2
alpha3: 0.2
alpha4: 0.2
alpha5: 0.2
base_frame_id: base_footprint
beam_search_angle: 0.0
max_beams: 60
max_particles: 2000
min_particles: 500
initial_pose_x: 0.0
initial_pose_y: 0.0
initial_pose_a: 0.0
local_costmap:
ros__parameters:
update_frequency: 5.0
publish_frequency: 2.0
global_frame: odom
robot_base_frame: base_footprint
use_sim_time: false
rolling_window: true
width: 3
height: 3
resolution: 0.05
robot_radius: 0.22
plugins:
- name: obstacle_layer
type: nav2_costmap_2d::ObstacleLayer
- name: inflation_layer
type: nav2_costmap_2d::InflationLayer
global_costmap:
ros__parameters:
update_frequency: 1.0
publish_frequency: 1.0
global_frame: map
robot_base_frame: base_footprint
use_sim_time: false
plugins:
- name: static_layer
type: nav2_costmap_2d::StaticLayer
- name: obstacle_layer
type: nav2_costmap_2d::ObstacleLayer
- name: inflation_layer
type: nav2_costmap_2d::InflationLayer
planner_server:
ros__parameters:
expected_planner_frequency: 20.0
plugins:
- name: GridBased
type: nav2_smac_planner/SmacPlanner2D5. Path Planning with Nav2
Send navigation goals to Nav2:
import rclpy
from geometry_msgs.msg import PoseStamped
from nav2_simple_commander.robot_navigator import BasicNavigator
def main():
rclpy.init()
nav = BasicNavigator()
# Wait for nav2 to fully load
nav.waitUntilNav2Active()
# Create goal pose
goal_pose = PoseStamped()
goal_pose.header.frame_id = 'map'
goal_pose.header.stamp = rclpy.Time(seconds=0, nanoseconds=0).to_msg()
goal_pose.pose.position.x = 3.0
goal_pose.pose.position.y = 4.0
goal_pose.pose.orientation.w = 1.0
# Send goal
nav.goToPose(goal_pose)
# Monitor navigation
i = 0
while not nav.isNavComplete():
i += 1
feedback = nav.getFeedback()
if i % 5 == 0:
print(f'Distance remaining: {feedback.distance_remaining:.2f}m')
result = nav.getResult()
if result == TaskResult.SUCCEEDED:
print('Navigation succeeded!')
else:
print('Navigation failed!')
rclpy.shutdown()
if __name__ == '__main__':
main()6. Costmap Inflation & Obstacle Avoidance
Configure costmaps for safe navigation:
# Costmap configuration
inflation_layer:
ros__parameters:
inflation_radius: 0.55
cost_scaling_factor: 2.58
obstacle_layer:
ros__parameters:
observation_sources: scan
scan:
topic: /scan
max_obstacle_height: 2.0
clearing: true
marking: true
data_type: LaserScan7. Loop Closure Detection
Detect and correct loop closures in SLAM:
// Loop closure detection callback
class SLAMLoopClosureHandler : public rclcpp::Node {
public:
SLAMLoopClosureHandler() : Node("loop_closure_handler") {
loop_closure_sub_ = create_subscription<std_msgs::msg::Bool>(
"rtabmap/loop_closure_detected", 10,
[this](const std_msgs::msg::Bool::SharedPtr msg) {
if (msg->data) {
RCLCPP_INFO(get_logger(), "Loop closure detected!");
// Trigger map optimization
optimize_map();
}
});
}
private:
void optimize_map() {
// Request map optimization from RTAB-Map
rtabmap_ros::srv::GetMap::Request req;
auto result = map_client_->async_send_request(req);
}
rclcpp::Subscription<std_msgs::msg::Bool>::SharedPtr loop_closure_sub_;
rclcpp::Client<rtabmap_ros::srv::GetMap>::SharedPtr map_client_;
};8. Multi-Robot SLAM
Coordinate SLAM across multiple robots:
# Multi-robot launch file
import os
from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
def generate_launch_description():
# Robot 1
robot1 = IncludeLaunchDescription(
'path/to/cartographer.launch.py',
launch_arguments={
'namespace': 'robot1',
'map_frame': 'map',
'domain_id': '0'
}
)
# Robot 2
robot2 = IncludeLaunchDescription(
'path/to/cartographer.launch.py',
launch_arguments={
'namespace': 'robot2',
'map_frame': 'map',
'domain_id': '1'
}
)
return LaunchDescription([robot1, robot2])9. Map Saving & Loading
Persist maps for reuse:
# Save map
ros2 service call /rtabmap/save_map rtabmap_ros/srv/SaveMap "{filename: '/home/robot/my_map.db'}"
# Load map for localization only
ros2 launch cartographer_ros cartographer.launch.py load_frozen_state:=true pbstream_map:=/home/robot/my_map.pbstream
# Export map as image
ros2 run nav2_map_server map_saver_cli -f my_map10. SLAM Performance Tuning
Optimize SLAM for real-time performance:
- Sampling: Adjust laser/odometry sampling ratios
- Loop closure: Tune loop detection thresholds
- Optimization: Balance map quality vs computation time
- Memory: Limit map size for embedded systems
- IMU: Integrate IMU for better localization
Key Takeaways
Implement SLAM with Cartographer or RTAB-Map for autonomous mapping. Configure Nav2 for robust path planning and obstacle avoidance. Tune costmaps and loop closure detection for your robot. Deploy multi-robot SLAM systems for collaborative mapping and navigation.