[ROS2] LiDAR
LiDAR data를 가공 없이 수신하는 코드에 대한 설명이다.
Dependencies
package.xml
<depend>rclcpp</depend>
<depend>sensor_msgs</depend>
- rclcpp : node를 생성하고 messgae를 subscribe 또는 publish할 때 필요하다.
- sensor_msgs : Laser data를 처리할 때 주로 사용하는 메시지 타입인 sensor_msgs/LaserScan이 포함되어 있다. LaserScan, PointCloud, Image 등 다양한 센서 데이터 타입을 포함하는 패키지이다.
CMakeLists.txt
# find dependencies
find_package(rclcpp REQUIRED)
find_package(sensor_msgs REQUIRED)
# Include Cpp "include" directory
include_directories(include)
# Create Cpp executable
add_executable(laser_processor_node src/laser_processor_node.cpp)
ament_target_dependencies(laser_processor_node rclcpp sensor_msgs)
# Install Cpp executables
install(TARGETS
laser_processor_node
DESTINATION lib/${PROJECT_NAME})
해당 패키지들을 CMakeLists.txt 파일에서 find_package로 설정해야 한다.
src/laser_processor_node.cpp
#include "rclcpp/rclcpp.hpp"
#include "sensor_msgs/msg/laser_scan.hpp"
해당 패키지들을 include 해야 한다.
Source Code
#include <string>
#include "rclcpp/rclcpp.hpp"
#include "sensor_msgs/msg/laser_scan.hpp"
class LaserProcessor : public rclcpp::Node {
public:
LaserProcessor() : Node("laser_processor_node")
{
subscription_ = this->create_subscription<sensor_msgs::msg::LaserScan>(
this->lidarscan_topic,
10,
std::bind(&LaserProcessor::scan_callback, this, std::placeholders::_1)
);
}
private:
// Topic
std::string lidarscan_topic = "/scan";
// Create ROS subscribers
rclcpp::Subscription<sensor_msgs::msg::LaserScan>::SharedPtr subscription_;
// Callback function to process the laser scan data
void scan_callback(const sensor_msgs::msg::LaserScan::ConstSharedPtr scan_msg)
{
print_laser_data(scan_msg);
}
// Function to print laser scan data
void print_laser_data(const sensor_msgs::msg::LaserScan::ConstSharedPtr scan_msg)
{
// Print some basic information
RCLCPP_INFO(this->get_logger(), "Received LaserScan data:");
RCLCPP_INFO(this->get_logger(), "Angle Min: %f, Angle Max: %f", scan_msg->angle_min, scan_msg->angle_max);
RCLCPP_INFO(this->get_logger(), "Range Min: %f, Range Max: %f", scan_msg->range_min, scan_msg->range_max);
// Print the range values
for (size_t i = 0; i < scan_msg->ranges.size(); ++i) {
RCLCPP_INFO(this->get_logger(), "Range[%zu]: %f", i, scan_msg->ranges[i]);
}
}
};
int main(int argc, char * argv[])
{
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<LaserProcessor>());
rclcpp::shutdown();
return 0;
}
생성자 함수
LaserProcessor() : Node("laser_processor_node")
{
subscription_ = this->create_subscription<sensor_msgs::msg::LaserScan>(
this->lidarscan_topic,
10,
std::bind(&LaserProcessor::scan_callback, this, std::placeholders::_1)
);
}
- 첫 번째 인자 : subscribe할 topic 이름
- 두 번째 인자 : Queue 사이즈 (queue로 관리할 때 사용할 수 있는 버퍼의 크기)
- 세 번째 인자 : subscribe 메시지가 들어올 때 호출할 콜백 함
토픽의 이름 : 이 이름으로 다른 노드들이 LiDAR 데이터를 구독할 수 있다.
// Topic
std::string lidarscan_topic = "/scan";
LiDAR 데이터를 구독하기 위한 구독자 객체를 가리키는 스마트 포인터 변수를 선언
// Create ROS subscribers
rclcpp::Subscription<sensor_msgs::msg::LaserScan>::SharedPtr subscription_;
- rclcpp::Subscription<sensor_msgs::msg::LaserScan> : ROS2에서 특정 메시지 타입을 구독할 때 사용하는 클래스
- sensor_msgs::msg::LaserScan : LiDAR 데이터가 전달될 메시지 형식
- SharedPtr : 스마트 포인터. subscription_ 이라는 변수가 구독자 객체를 가리키는 포인터.
- subscription_ : 실제 구독자 객체. /scan 토픽으로부터 발행된 LiDAR 데이터를 구독하고, 해당 데이터를 처리하는 콜백 함수에 전달하는 역할을 한다.
Function scan_callback
// Callback function to process the laser scan data
void scan_callback(const sensor_msgs::msg::LaserScan::ConstSharedPtr scan_msg)
{
print_laser_data(scan_msg);
}
Function print_laser_data
// Function to print laser scan data
void print_laser_data(const sensor_msgs::msg::LaserScan::ConstSharedPtr scan_msg)
{
// Print some basic information
RCLCPP_INFO(this->get_logger(), "Received LaserScan data:");
RCLCPP_INFO(this->get_logger(), "Angle Min: %f, Angle Max: %f", scan_msg->angle_min, scan_msg->angle_max);
RCLCPP_INFO(this->get_logger(), "Range Min: %f, Range Max: %f", scan_msg->range_min, scan_msg->range_max);
// Print the range values
for (size_t i = 0; i < scan_msg->ranges.size(); ++i) {
RCLCPP_INFO(this->get_logger(), "Range[%zu]: %f", i, scan_msg->ranges[i]);
}
}