Exploring ROS2 with wheeled robotic – #2 – Find out how to subscribe to ROS2 laser scan subject


By Marco Arruda

That is the second chapter of the sequence “Exploring ROS2 with a wheeled robotic”. On this episode, you’ll learn to subscribe to a ROS2 subject utilizing ROS2 C++.

You’ll study:

  • Find out how to create a node with ROS2 and C++
  • Find out how to subscribe to a subject with ROS2 and C++
  • Find out how to launch a ROS2 node utilizing a launch file

1 – Setup setting – Launch simulation

Earlier than anything, be sure you have the rosject from the earlier publish, you’ll be able to copy it from right here.

Launch the simulation in a single webshell and in a unique tab, checkout the matters now we have out there. It’s essential to get one thing just like the picture beneath:

2 – Create a ROS2 node

Our objective is to learn the laser information, so create a brand new file referred to as reading_laser.cpp:

contact ~/ros2_ws/src/my_package/reading_laser.cpp

And paste the content material beneath:

#embrace "rclcpp/rclcpp.hpp"
#embrace "sensor_msgs/msg/laser_scan.hpp"

utilizing std::placeholders::_1;

class ReadingLaser : public rclcpp::Node {

  ReadingLaser() : Node("reading_laser") {

    auto default_qos = rclcpp::QoS(rclcpp::SystemDefaultsQoS());

    subscription_ = this->create_subscription(
        "laser_scan", default_qos,
        std::bind(&ReadingLaser::topic_callback, this, _1));

  void topic_callback(const sensor_msgs::msg::LaserScan::SharedPtr _msg) {
    RCLCPP_INFO(this->get_logger(), "I heard: '%f' '%f'", _msg->ranges[0],
  rclcpp::Subscription::SharedPtr subscription_;

int foremost(int argc, char *argv[]) {
  rclcpp::init(argc, argv);
  auto node = std::make_shared();
  RCLCPP_INFO(node->get_logger(), "Howdy my buddies");
  return 0;

We’re creating a brand new class ReadingLaser that represents the node (it inherits rclcpp::Node). Crucial about that class are the subscriber attribute and the strategy callback. Within the foremost operate we’re initializing the node and preserve it alive (spin) whereas its ROS connection is legitimate.

The subscriber constructor expects to get a QoS, that stands for the middleware used for the high quality of service. You’ll be able to have extra details about it within the reference hooked up, however on this publish we’re simply utilizing the default QoS offered. Have in mind the next parameters:

  • subject identify
  • callback technique

The callback technique must be binded, which implies it won’t be execute on the subscriber declaration, however when the callback known as. So we move the reference of the strategy and setup the this reference for the present object for use as callback, afterall the strategy itself is a generic implementation of a category.

3 – Compile and run

So as to compile the cpp file, we should add some directions to the ~/ros2_ws/src/my_package/src/CMakeLists.txt:

  • Search for discover dependencies and embrace the sensor_msgs library
  • Simply earlier than the set up instruction add the executable and goal its dependencies
  • Append one other set up instruction for the brand new executable we’ve simply created
# discover dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(sensor_msgs REQUIRED)

add_executable(reading_laser src/reading_laser.cpp)
ament_target_dependencies(reading_laser rclcpp std_msgs sensor_msgs)

set up(TARGETS

Compile it:

colcon construct --symlink-install --packages-select my_package

4 – Run the node and mapping the subject

So as to run the executable created, you should utilize:

ros2 run my_package reading_laser

Though the the laser values received’t present up. That’s as a result of now we have a “arduous coded” subject identify laser_scan. No drawback in any respect, after we can map matters utilizing launch recordsdata. Create a brand new launch file ~/ros2_ws/src/my_package/launch/reading_laser.py:

from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():

    reading_laser = Node(
        package deal="my_package",
        output="display screen",
            ('laser_scan', '/dolly/laser_scan')

    return LaunchDescription([

On this launch file there may be an occasion of a node getting the executable as argument and it’s setup the remappings attribute in an effort to remap from laser_scan to /dolly/laser_scan.

Run the identical node utilizing the launch file this time:

ros2 launch my_package reading_laser.launch.py

Add some obstacles to the world and the outcome have to be just like:

Associated programs & additional hyperlinks:

The Constructsim Weblog