Writing C++ Subscriber in ROS2
There are three ways to to write a C++ publisher in ROS2, namely:
- Old-school approach
- Object-oriented (member-function) approach
- Local function (lambda) approach
Below is an example of each approach to write a C++ node listening to “Hello World” stream. The code is taken from here: https://github.com/ros2/examples/tree/foxy/rclcpp/topics/minimal_subscriber
Old-school (not-composable) approach:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#include "rclcpp/rclcpp.hpp" #include "std_msgs/msg/string.hpp" rclcpp::Node::SharedPtr g_node = nullptr; /* We do not recommend this style anymore, because composition of multiple * nodes in the same executable is not possible. Please see one of the subclass * examples for the "new" recommended styles. This example is only included * for completeness because it is similar to "classic" standalone ROS nodes. */ void topic_callback(const std_msgs::msg::String::SharedPtr msg) { RCLCPP_INFO(g_node->get_logger(), "I heard: '%s'", msg->data.c_str()); } int main(int argc, char * argv[]) { rclcpp::init(argc, argv); g_node = rclcpp::Node::make_shared("minimal_subscriber"); auto subscription = g_node->create_subscription("topic", 10, topic_callback); rclcpp::spin(g_node); rclcpp::shutdown(); // TODO(clalancette): It would be better to remove both of these nullptr // assignments and let the destructors handle it, but we can't because of // https://github.com/eProsima/Fast-RTPS/issues/235 . Once that is fixed // we should probably look at removing these two assignments. subscription = nullptr; g_node = nullptr; return 0; } |
Object-oriented (member-function) approach:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#include #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( "topic", 10, std::bind(&MinimalSubscriber::topic_callback, this, _1)); } 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::SharedPtr subscription_; }; int main(int argc, char * argv[]) { rclcpp::init(argc, argv); rclcpp::spin(std::make_shared()); rclcpp::shutdown(); return 0; } |
Local function (lambda) approach:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#include #include #include "rclcpp/rclcpp.hpp" #include "std_msgs/msg/string.hpp" class MinimalSubscriber : public rclcpp::Node { public: MinimalSubscriber() : Node("minimal_subscriber") { subscription_ = this->create_subscription( "topic", 10, [this](std_msgs::msg::String::UniquePtr msg) { RCLCPP_INFO(this->get_logger(), "I heard: '%s'", msg->data.c_str()); }); } private: rclcpp::Subscription::SharedPtr subscription_; }; int main(int argc, char * argv[]) { rclcpp::init(argc, argv); rclcpp::spin(std::make_shared()); rclcpp::shutdown(); return 0; } |