특정 튜토리얼용 로봇(터틀봇 등) 패키지에 의존하지 않고, 일반적인 커스텀 ROS2 모바일 로봇(AMR/AGV) 하드웨어 환경에서 **slam_toolbox**를 이용한 2D 점유 격자 지도(Occupancy Grid Map) 작성부터 nav2_bringup 표준 명령어를 이용한 자율주행 구동까지 전체 실기 절차를 가이드합니다.
1. 개요 및 실기 로봇 사전 준비
로봇 하드웨어 필수 조건 (ROS2 인터페이스)
실제 로봇에서 SLAM 및 Nav2를 구동하려면 로봇 드라이버 및 센서 노드가 아래 ROS2 토픽과 TF(Transform)를 제공해야 합니다.
- 센서 데이터 (
/scan): 2D LiDAR 노드가sensor_msgs/msg/LaserScan타입 토픽 발행 - 오도메트리 (
/odom): 바퀴 인코더/IMU 기반 이동량nav_msgs/msg/Odometry발행 - 조종 명령 (
/cmd_vel): 로봇 모터 드라이버가geometry_msgs/msg/Twist속도 명령 수신 - TF 좌표계 (Robot State Publisher):
odom➔base_footprint➔base_link➔laser_frame(LiDAR 위치) 변환 제공
필수 패키지 설치 (Humble 버전 기준)
개발자 PC(Remote PC) 또는 로봇의 메인 컴퓨팅 장치(SBC/Industrial PC)에 표준 패키지를 설치합니다.
sudo apt update
sudo apt install -y \
ros-humble-navigation2 \
ros-humble-nav2-bringup \
ros-humble-slam-toolbox \
ros-humble-teleop-twist-keyboard \
ros-humble-rviz2
네트워크 및 ROS2 Domain ID 설정
로봇 온보드 컴퓨터와 Remote PC 간 다중 기기 통신 시, 동일한 Wi-Fi 네트워크에 접속하고 ROS_DOMAIN_ID를 동일하게 맞춰줍니다.
# [로봇 및 Remote PC 공통] ~/.bashrc 등록 권장
export ROS_DOMAIN_ID=30 # 네트워크 통신 분리를 위한 Domain ID (0~232)
2. 로봇 하드웨어 실행 (Robot Bringup)
로봇 온보드 컴퓨터 터미널에서 모터 드라이버, LiDAR 센서, 로봇 URDF(robot_state_publisher)를 실행합니다.
# [로봇 온보드 PC] 로봇 커스텀 브링업 런치 파일 실행 (예시)
ros2 launch my_robot_bringup robot_hardware.launch.py
센서 및 TF 정상 수신 확인 (Remote PC)
Remote PC 터미널에서 센서 데이터 및 오도메트리가 정상적으로 발행되는지 확인합니다.
# [Remote PC] 토픽 목록 확인
ros2 topic list
# [Remote PC] LiDAR 및 Odom 데이터 정상 발행 여부 확인
ros2 topic echo /scan --once
ros2 topic echo /odom --once
3. SLAM을 이용한 2D 맵 생성 및 저장
Step 1: SLAM Toolbox 런치 실행
slam_toolbox 노드를 구동하여 실시간 SLAM 지도 작성을 시작합니다. 실기 환경이므로 use_sim_time:=false로 구동합니다.
# [Remote PC 또는 로봇 PC]
ros2 launch slam_toolbox online_async_launch.py use_sim_time:=false
Step 2: RViz2 시각화 실행
RViz2를 실행하여 생성되는 맵과 LiDAR 스캔 데이터, 로봇 모델을 실시간 모니터링합니다.
# [Remote PC] Nav2 기본 RViz 설정으로 실행
ros2 run rviz2 rviz2 -d /opt/ros/humble/share/nav2_bringup/rviz/nav2_default_view.rviz
Step 3: 키보드 조종 노드로 미지 영역 탐색
범용 키보드 조종 노드(teleop_twist_keyboard)를 실행하여 실제 로봇을 천천히 이동시키며 주행 구역 전체를 탐색합니다.
# [Remote PC] 범용 Twist 키보드 조종 실행
ros2 run teleop_twist_keyboard teleop_twist_keyboard
조종 팁: 로봇을 급격하게 회전시키면 LiDAR 스캔 매칭이 어긋날 수 있으므로 제자리에서 천천히 회전하며 벽면 및 장애물 데이터를 충분히 수집합니다.
Step 4: 작성된 맵 저장 (map_saver_cli)
탐색이 완료되면 nav2_map_server의 맵 세이버 CLI를 이용해 현재 지도를 파일로 저장합니다.
# ~/my_map 이름으로 저장 (.yaml 및 .pgm 파일 생성)
ros2 run nav2_map_server map_saver_cli -f ~/my_map
저장되는 맵 파일 구조
my_map.pgm: 2D 점유 격자 이미지 파일 (흰색: 이동 가능, 검은색: 벽/장애물, 회색: 미탐색).my_map.yaml: 지도의 메타데이터 파일 (해상도, 원점 위치, 점유 임계값 등 정의).
image: my_map.pgm
mode: trinary
resolution: 0.050000 # 픽셀 당 실제 거리 (0.05m = 5cm)
origin: [-2.000000, -0.500000, 0.000000] # 맵 좌측 하단 좌표 [x, y, yaw]
negate: 0
occupied_thresh: 0.65 # 장애물 판정 임계값
free_thresh: 0.25 # 통로 판정 임계값
4. Nav2 스택을 이용한 자율주행 구동
생성한 지도(my_map.yaml)를 불러와 실제 로봇에 Nav2 자율주행 파이프라인을 적용합니다.
Step 1: Nav2 스택 브링업 (bringup_launch.py)
Nav2 통합 런치 파일을 사용하여 AMCL, Costmap, Planner, Controller, Recovery 등 Nav2 전 노드를 실행합니다.
# [Remote PC 또는 로봇 PC] 기본 파라미터 파일로 구동
ros2 launch nav2_bringup bringup_launch.py \
use_sim_time:=false \
map:=$HOME/my_map.yaml
커스텀 파라미터 적용 시: 로봇 크기(Footprint)나 속도 제한에 맞춰 커스텀
nav2_params.yaml을 작성한 경우params_file인자를 추가로 전달합니다.ros2 launch nav2_bringup bringup_launch.py \ use_sim_time:=false \ map:=$HOME/my_map.yaml \ params_file:=$HOME/my_nav2_params.yaml
Step 2: RViz2에서 로봇 초기 위치 추정 (2D Pose Estimate)
- RViz2 상단 툴바의
2D Pose Estimate버튼을 클릭합니다. - 실제 맵 상에서 현재 로봇이 위치한 지점을 클릭하고, 로봇이 바라보는 실제 방향으로 드래그합니다.
- AMCL 파티클이 설정한 위치 주위로 모이면서 실제 LiDAR 스캔 데이터와 지도가 매칭되어 초기 위치가 확정됩니다.
Step 3: 자율주행 목표 지점 설정 (Nav2 Goal)
- RViz2 상단의
Nav2 Goal(또는2D Goal Pose) 버튼을 클릭합니다. - 로봇이 이동할 최종 목적지와 도착 시 바라볼 방향을 클릭 & 드래그합니다.
- Nav2 스택이 경로(Global Path)를 생성하고 로봇 모터 드라이버(
/cmd_vel)로 속도 명령을 전송하여 국소 장애물을 회피하며 목적지까지 이동합니다.
5. Nav2 디버깅 및 CLI 가이드
TF 좌표 변환 트리 검증
Nav2 구동 시 TF 연결 구조는 다음과 같아야 합니다.
# TF 트리를 그래픽 PDF로 생성하여 구성을 검증
ros2 run tf2_tools view_frames
# map -> base_link 실제 실시간 좌표 변환 확인
ros2 run tf2_ros tf2_echo map base_link
CLI 명령으로 이동 목표 전송 (NavigateToPose Action)
RViz2 GUI 없이 터미널 액션 클라이언트를 통해 직접 좌표 목표를 보낼 수 있습니다.
ros2 action send_goal /navigate_to_pose nav2_msgs/action/NavigateToPose "{
pose: {
header: {frame_id: 'map'},
pose: {
position: {x: 2.0, y: 1.0, z: 0.0},
orientation: {w: 1.0}
}
}
}"
Costmap 장애물 잔상 리셋 서비스
동적 장애물이 사라졌음에도 코스트맵 상에 잔상이 남아 경로 계획이 막히는 경우 클리어 서비스를 호출합니다.
# Global 및 Local Costmap 장애물 레이어 리셋
ros2 service call /global_costmap/clear_entirely_global_costmap nav2_msgs/srv/ClearEntireCostmap "{}"
ros2 service call /local_costmap/clear_entirely_local_costmap nav2_msgs/srv/ClearEntireCostmap "{}"
6. 실기 로봇 운용 튜닝 및 주의사항
- 시간 동기화 (NTP / Chrony 필수):
- 로봇 온보드 컴퓨터와 Remote PC 간 시계가 다르면
TF_OLD_DATA또는Lookup would require extrapolation into the past오류가 발생합니다.chrony패키지를 사용해 시간 동기화를 반드시 설정하세요.
- 로봇 온보드 컴퓨터와 Remote PC 간 시계가 다르면
- 로봇 크기(Footprint) 및 Inflation Radius 설정:
nav2_params.yaml내robot_radius또는footprint코스트맵 값을 실제 로봇 외형 물리 치수에 맞게 설정하고,inflation_radius를 적절히 넓혀 벽면에 부딪히지 않도록 안전 유격을 확보합니다.
- 오도메트리 드리프트 및 바퀴 슬립:
- 실제 로봇 바퀴 미끄러짐이 심할 경우 AMCL 파티클이 발산할 수 있습니다. 로봇 속도/가속도를 완화하거나 IMU 융합(EKF,
robot_localization)을 적용하여/odom품질을 향상시킵니다.
- 실제 로봇 바퀴 미끄러짐이 심할 경우 AMCL 파티클이 발산할 수 있습니다. 로봇 속도/가속도를 완화하거나 IMU 융합(EKF,
마무리
특정 예제 전용 패키지 없이도, 표준 **slam_toolbox**와 nav2_bringup 명령어를 이해하고 활용하면 모든 범용 ROS2 모바일 로봇에 SLAM 및 자율주행 파이프라인을 직접 구축할 수 있습니다.