(Perception → Planning → Control 노드 구조 이해하기)
대상: ROS2로 자율주행 시스템을 구성하고자 하는 개발자
환경: Ubuntu 22.04 + ROS2 Humble/Foxy, Autoware.universe 또는 커스텀 자율주행 스택
1. 문제/주제 요약
ROS2 기반 자율주행 시스템은 여러 센서, 알고리즘, 제어기를 조합하여
“인식 → 예측 → 계획 → 제어” 의 전체 파이프라인을 구성합니다.
하지만 처음 접하면 다음과 같은 의문이 생깁니다:
- 어떤 노드가 어떤 역할을 하는가?
- Perception과 Planning은 어디서 데이터를 주고받는가?
- 제어 명령은 최종적으로 어디로 가는가?
이 글에서는 ROS2 자율주행 스택의 전체 구조를
Perception–Planning–Control 세 단계로 나누어 큰 그림을 정리합니다.
2. 전체 구조 한눈에 보기
ROS2 자율주행 시스템은 보통 다음과 같은 계층 구조로 구성됩니다:
┌───────────────────────────────────────────────┐
│ Sensors │
│ Camera, LiDAR, Radar, GPS, IMU │
└───────────────────────────────────────────────┘
↓
┌───────────────────────────────────────────────┐
│ Perception Layer │
│ - Object Detection / Tracking │
│ - Lane & Traffic Signal Recognition │
│ - Free Space Detection │
└───────────────────────────────────────────────┘
↓
┌───────────────────────────────────────────────┐
│ Prediction Layer │
│ - Object Trajectory Prediction │
│ - Behavior Estimation │
└───────────────────────────────────────────────┘
↓
┌───────────────────────────────────────────────┐
│ Planning Layer │
│ - Global Route Planning │
│ - Behavior Planning │
│ - Local Trajectory Generation │
└───────────────────────────────────────────────┘
↓
┌───────────────────────────────────────────────┐
│ Control Layer │
│ - Longitudinal (Speed) Control │
│ - Lateral (Steering) Control │
│ - MPC or PID Controller │
└───────────────────────────────────────────────┘
↓
┌───────────────────────────────────────────────┐
│ Vehicle Interface │
│ - CAN bus, drive-by-wire ECU │
└───────────────────────────────────────────────┘
3. Perception Layer — “세상을 인식하는 단계”
목적:
센서 데이터를 이용해 도로 환경과 객체를 인식하고, 차량 주변의 상황을 추출
주요 입력
/camera/*(Image)/lidar/points_raw(PointCloud2)/imu/data,/gps/fix
주요 구성 노드
| 노드 | 역할 | 출력 |
|---|---|---|
| object_detection | 차량·보행자 등 객체 검출 | /perception/object_recognition/objects |
| object_tracker | 프레임 간 객체 추적 | /perception/tracked_objects |
| lane_detector | 차선, 도로 구조 인식 | /perception/lane_markings |
| freespace_detector | 주행 가능 영역 계산 | /perception/freespace |
| sensor_fusion | LiDAR + Camera 결합 | /perception/fused_objects |
출력 데이터
- 주변 객체의 위치·속도·ID
- 차선/도로 형태
- 주행 가능한 영역
이 결과는 다음 단계인 Prediction 으로 전달됩니다.
4. Prediction Layer — “주변 객체의 미래 예측”
목적:
주변 차량이나 보행자가 앞으로 어떻게 움직일지(trajectory) 예측
주요 입력
/perception/tracked_objects
주요 구성 노드
| 노드 | 역할 | 출력 |
|---|---|---|
| trajectory_predictor | 주변 객체 궤적 예측 | /prediction/objects |
| behavior_predictor | 객체의 의도(직진/회전 등) 추정 | /prediction/behavior |
예시 출력:
object_id: 34
predicted_paths:
- probability: 0.7
path: [[x:23.1,y:4.2],[x:24.0,y:4.4],[x:25.3,y:4.8]]
5. Planning Layer — “안전하고 부드러운 주행 경로 생성”
목적:
지도 정보 + 예측 결과를 활용해 차량이 따라가야 할 전역/지역 경로 생성
세부 구성
| 하위 모듈 | 설명 |
|---|---|
| Global Planner | 목적지까지 도로 단위 경로 탐색 (A*, D*) |
| Behavior Planner | 상황에 따른 행동 결정 (정지, 차선 변경 등) |
| Local Trajectory Planner | 실제 주행 가능한 곡선 궤적 생성 (Polynomial, MPC 등) |
주요 노드와 토픽
| 노드 | 출력 | 설명 |
|---|---|---|
/planning/global_route_planner | /planning/global_path | 목적지까지의 전체 루트 |
/planning/behavior_path_planner | /planning/behavior_cmd | 현재 행동 (Follow, Stop 등) |
/planning/trajectory_generator | /planning/trajectory | 시계열 궤적 (x, y, v, a) |
6. Control Layer — “궤적을 실제로 따르기 위한 제어”
목적:
Planning 단계에서 생성된 궤적을 따라 차량이 실제로 움직이도록 조향·가속·감속 제어
주요 제어기
| 제어 축 | 알고리즘 | 제어 신호 |
|---|---|---|
| 횡방향(Lateral) | Pure Pursuit, Stanley, MPC | Steering |
| 종방향(Longitudinal) | PID, MPC, ACC | Throttle, Brake |
주요 노드
| 노드 | 입력 | 출력 |
|---|---|---|
/control/trajectory_follower | /planning/trajectory | /vehicle_cmd |
/vehicle_interface | /vehicle_cmd | CAN 신호 송출 |
예시 /vehicle_cmd:
steering_angle: 0.15
throttle: 0.35
brake: 0.0
gear: DRIVE
7. 실제 ROS2 노드 흐름 예시 (Autoware Universe)
/sensing/lidar/points_raw
/sensing/camera/image_raw
↓
/perception/object_recognition/objects
↓
/prediction/obstacle_trajectory_predictor
↓
/planning/behavior_path_planner
↓
/planning/motion_trajectory_optimizer
↓
/control/mpc_trajectory_follower
↓
/vehicle_cmd → CAN bus (throttle/steering/brake)
🔍
rviz2나foxglove에서 이 전체 토픽 흐름을 시각화하면
자율주행 파이프라인의 데이터 흐름을 명확히 볼 수 있습니다.
8. 계층 간 데이터 연결 요약
| From | To | 주고받는 데이터 |
|---|---|---|
| Perception → Prediction | 객체 위치·속도 | |
| Prediction → Planning | 미래 궤적 (trajectory) | |
| Planning → Control | 목표 궤적 (x, y, yaw, v, a) | |
| Control → Vehicle Interface | 조향, 가속, 제동 명령 |
이 구조 덕분에 ROS2 자율주행 스택은
모듈 간 독립성과 확장성을 유지하면서 다양한 알고리즘 교체가 가능합니다.
9. 추가 팁 / 자주 하는 실수
- frame_id 불일치 (
map,base_link) → 각 계층 간 좌표 변환 오류 - 센서 동기화 실패 → Perception → Prediction 단계 불안정
- Planning과 Control 주기 불일치 → 차량 떨림(jitter) 발생
- topic 이름 중복 → launch 구성 시 노드 충돌
⚙️ Tip: 각 노드의 주기를 맞추고,
tf2좌표 변환을 확실히 설정해야
Planning–Control 간 연결이 자연스럽게 작동합니다.
10. 정리
ROS2 기반 자율주행 스택은 다음과 같은 계층적 구조로 설계됩니다:
1️⃣ Perception — 센서로 세상을 인식
2️⃣ Prediction — 주변 객체의 미래 행동 예측
3️⃣ Planning — 차량이 따라야 할 안전한 경로 생성
4️⃣ Control — 실제 차량을 조향·가감속으로 제어
이 흐름이 ROS2의 토픽·노드 구조를 통해 유기적으로 연결되며,
각 계층은 독립적으로 개발·교체 가능한 모듈 형태로 구성됩니다.