0% found this document useful (0 votes)
48 views

Writing - A - Simple - Publisher - and - Subscriber in C++

This document provides instructions for writing a simple ROS 2 publisher and subscriber node in C++. It describes creating a publisher node class that publishes string messages on a timer, and a subscriber node class that subscribes to and prints those messages. It also explains editing the CMakeLists.txt file to build and install the nodes so they can communicate by running the talker and listener executables.

Uploaded by

Shenni
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
48 views

Writing - A - Simple - Publisher - and - Subscriber in C++

This document provides instructions for writing a simple ROS 2 publisher and subscriber node in C++. It describes creating a publisher node class that publishes string messages on a timer, and a subscriber node class that subscribes to and prints those messages. It also explains editing the CMakeLists.txt file to build and install the nodes so they can communicate by running the talker and listener executables.

Uploaded by

Shenni
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

😺

Writing a simple publisher and


subscriber (C++)
Nodes are executable processes that communicate over the ROS graph. In this tutorial,
the nodes will pass information in the form of string messages to each other over
a topic.

cd ~/ros2_ws/src
ros2 pkg create --build-type ament_cmake cpp_pubsub

Write publisher node: publisher_member_function.cpp

#include <chrono>
#include <functional>
#include <memory>
#include <string>

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"

using namespace std::chrono_literals;

/* This example creates a subclass of Node and uses std::bind() to register a


* member function as a callback from the timer. */

//creates the node class MinimalPublisher by inheriting from rclcpp::Node


class MinimalPublisher : public rclcpp::Node
{
public:
MinimalPublisher()
: Node("minimal_publisher"), count_(0)
{
publisher_ = this->create_publisher<std_msgs::msg::String>("topic", 10);
timer_ = this->create_wall_timer(
500ms, std::bind(&MinimalPublisher::timer_callback, this));

Writing a simple publisher and subscriber (C++) 1


}

private:
void timer_callback()
{
auto message = std_msgs::msg::String();
message.data = "Hello, world! " + std::to_string(count_++);
RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.data.c_str());
publisher_->publish(message);
}
rclcpp::TimerBase::SharedPtr timer_;
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
size_t count_;
};

int main(int argc, char * argv[])


{
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<MinimalPublisher>());
rclcpp::shutdown();
return 0;
}

rclcpp/rclcpp.hppinclude which allows you to use the most common pieces of the ROS
2 system. Last is std_msgs/msg/string.hpp , which includes the built-in message type you
will use to publish data.
Every this in the code is referring to the node.

Write subscriber node: subscriber_member_function.cpp

#include <memory>

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
using std::placeholders::_1;

class MinimalSubscriber : public rclcpp::Node


{
public:
MinimalSubscriber()
: Node("minimal_subscriber")
{
subscription_ = this->create_subscription<std_msgs::msg::String>(
"topic", 10, std::bind(&MinimalSubscriber::topic_callback, this, _1));
}

Writing a simple publisher and subscriber (C++) 2


private:
void topic_callback(const std_msgs::msg::String::SharedPtr msg) const
{
RCLCPP_INFO(this->get_logger(), "I heard: '%s'", msg->data.c_str());
}
rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscription_;
};

int main(int argc, char * argv[])


{
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<MinimalSubscriber>());
rclcpp::shutdown();
return 0;
}

Now the node is named minimal_subscriber , and the constructor uses the
node’s create_subscription class to execute the callback.

Editing CMakelists
Below the existing dependency find_package(ament_cmake REQUIRED) , add the lines:

find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)

add the executable and name it talker so you can run your node using ros2 run :

add_executable(talker src/publisher_member_function.cpp)
ament_target_dependencies(talker rclcpp std_msgs)

add_executable(listener src/subscriber_member_function.cpp)
ament_target_dependencies(listener rclcpp std_msgs)

add the install(TARGETS...) section so ros2 run can find your executable:

Writing a simple publisher and subscriber (C++) 3


install(TARGETS
talker
listener
DESTINATION lib/${PROJECT_NAME})

Finally looks like this:

cmake_minimum_required(VERSION 3.5)
project(cpp_pubsub)

# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")


add_compile_options(-Wall -Wextra -Wpedantic)
endif()

find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)

add_executable(talker src/publisher_member_function.cpp)
ament_target_dependencies(talker rclcpp std_msgs)

add_executable(listener src/subscriber_member_function.cpp)
ament_target_dependencies(listener rclcpp std_msgs)

install(TARGETS
talker
listener
DESTINATION lib/${PROJECT_NAME})

ament_package()

Build and run


run rosdep in the root of your workspace ( ros2_ws ) to check for missing dependencies
before building:

Writing a simple publisher and subscriber (C++) 4


rosdep install -i --from-path src --rosdistro foxy -y

build:

rosdep install -i --from-path src --rosdistro foxy -y

source:

. install/setup.bash

run:

ros2 run cpp_pubsub talker


ros2 run cpp_pubsub listener

Writing a simple publisher and subscriber (C++) 5

You might also like