2 minute read

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]);
    }
}

Categories:

Updated: