반응형
안녕하세요! ✨
앞서 Day 24에서는 EKF를 활용한 비선형 상태 추정 실습을 진행했습니다.
오늘은 자율주행차의 핵심 기술 중 하나인 LiDAR와 IMU 센서 융합을 실습해보겠습니다.

🔍 LiDAR + IMU 융합의 필요성
- LiDAR: 고정밀 3D 위치/거리 측정 가능, 하지만 순간적인 움직임(고속 회전/가속)에 약함
- IMU: 가속도·각속도 정보를 빠르게 제공, 하지만 장기적으로 드리프트(누적 오차) 발생
👉 따라서 두 센서를 융합하면: - LiDAR → 위치 안정화
- IMU → 실시간 반응성 보완
⚙️ ROS2에서 센서 융합 흐름
- LiDAR 노드 → /lidar_points 퍼블리시
- IMU 노드 → /imu_data 퍼블리시
- EKF Fusion 노드 → 두 데이터를 결합해 /fused_pose 퍼블리시
🧑💻 Python 예제 (ROS2 EKF 융합)
python
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import Imu, PointCloud2
from geometry_msgs.msg import PoseWithCovarianceStamped
class FusionNode(Node):
def __init__(self):
super().__init__('fusion_node')
self.sub_lidar = self.create_subscription(PointCloud2, '/lidar_points', self.lidar_callback, 10)
self.sub_imu = self.create_subscription(Imu, '/imu_data', self.imu_callback, 10)
self.pub_pose = self.create_publisher(PoseWithCovarianceStamped, '/fused_pose', 10)
self.lidar_data = None
self.imu_data = None
def lidar_callback(self, msg):
self.lidar_data = msg
self.fuse_data()
def imu_callback(self, msg):
self.imu_data = msg
self.fuse_data()
def fuse_data(self):
if self.lidar_data and self.imu_data:
fused_pose = PoseWithCovarianceStamped()
fused_pose.header.stamp = self.get_clock().now().to_msg()
fused_pose.header.frame_id = "map"
# 단순화된 예제: 실제로는 EKF 연산 필요
fused_pose.pose.pose.position.x = 1.0
fused_pose.pose.pose.position.y = 2.0
self.pub_pose.publish(fused_pose)
self.get_logger().info("Fused LiDAR + IMU data published!")
def main(args=None):
rclpy.init(args=args)
node = FusionNode()
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
from rclpy.node import Node
from sensor_msgs.msg import Imu, PointCloud2
from geometry_msgs.msg import PoseWithCovarianceStamped
class FusionNode(Node):
def __init__(self):
super().__init__('fusion_node')
self.sub_lidar = self.create_subscription(PointCloud2, '/lidar_points', self.lidar_callback, 10)
self.sub_imu = self.create_subscription(Imu, '/imu_data', self.imu_callback, 10)
self.pub_pose = self.create_publisher(PoseWithCovarianceStamped, '/fused_pose', 10)
self.lidar_data = None
self.imu_data = None
def lidar_callback(self, msg):
self.lidar_data = msg
self.fuse_data()
def imu_callback(self, msg):
self.imu_data = msg
self.fuse_data()
def fuse_data(self):
if self.lidar_data and self.imu_data:
fused_pose = PoseWithCovarianceStamped()
fused_pose.header.stamp = self.get_clock().now().to_msg()
fused_pose.header.frame_id = "map"
# 단순화된 예제: 실제로는 EKF 연산 필요
fused_pose.pose.pose.position.x = 1.0
fused_pose.pose.pose.position.y = 2.0
self.pub_pose.publish(fused_pose)
self.get_logger().info("Fused LiDAR + IMU data published!")
def main(args=None):
rclpy.init(args=args)
node = FusionNode()
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
👉 위 예시는 단순히 LiDAR + IMU 데이터를 받아 /fused_pose 토픽에 퍼블리시하는 구조입니다.
실제 구현에서는 EKF 알고리즘을 적용해 오차를 줄이고, LiDAR와 IMU 데이터를 보정합니다.
📊 RViz2에서 확인
- /lidar_points : LiDAR 점군
- /imu_data : IMU 자세/속도
- /fused_pose : 융합된 위치 추정 결과
👉 RViz2에서 세 가지 데이터를 동시에 확인하면, 센서 융합 효과를 직관적으로 이해할 수 있습니다.
🚘 자율주행 활용
- SLAM: 지도 작성 및 자기 위치 추정
- Navigation: GPS 불안정 구간(터널, 빌딩 숲)에서 안정적 주행
- 고속 주행 제어: IMU가 즉각적인 반응, LiDAR가 장기적 안정성 보완
📌 정리
- LiDAR → 위치 정확도 강점
- IMU → 순간 반응성 강점
- 두 센서를 EKF 기반으로 융합하면 정확하면서 안정적인 상태 추정 가능
- ROS2 환경에서 Python 노드로 손쉽게 구현 가능
반응형
🚀 다음 글 예고
다음 글에서는 [Day 26: Particle Filter 개념 학습] 을 다룹니다.
비선형·비가우시안 환경에서도 강력한 추정을 제공하는 Particle Filter 의 원리를 정리하겠습니다.
✅ 오늘 글이 도움이 되셨다면 좋아요와 공유 부탁드립니다.
반응형
'자율주행' 카테고리의 다른 글
| 🎯 Day 27: Particle Filter 구현 실습 (0) | 2025.09.23 |
|---|---|
| 🎯 Day 26: Particle Filter 개념 학습 (0) | 2025.09.22 |
| 🔄 Day 24: EKF로 비선형 상태 추정 실습 (0) | 2025.09.20 |
| 🔄 Day 23: 확장 칼만필터(EKF) 원리 (0) | 2025.09.19 |
| 🐍 Day 22: Python으로 1D 칼만필터 구현 (0) | 2025.09.18 |