文章目录
- ros2 node 之间的通信方式之 Topic通信
- Topic 通信案例
- 1、创建工作空间
- 2、创建功能包
- 3、编写发布者和订阅者代码
- 3.1 topic_helloworld_pub.cpp
- 3.2 topic_helloworld_sub.cpp
- 4、编写CMakeLists.txt
- 5、编译工作空间下的功能包
- 6、运行结果
ros2 node 之间的通信方式之 Topic通信
ROS 2 将复杂系统分解为许多模块化node。Topic是ROS的重要组成部分,充当node交换消息的总线。
一个节点可以将数据发布到任意数量的主题,并同时订阅任意数量的主题。
Topic是在node之间移动数据的主要方式之一,因此也是在系统的不同部分之间移动数据的主要方式之一。
Topic 通信案例
1、创建工作空间
如果没有创建工作空间,创建工作空间,反之则不用,进入目录src/下
$ mkdir -p ~/devnode_ws/src
$ cd ~/devnode_ws/src
2、创建功能包
$ ros2 pkg create --build-type ament_cmake topic_helloworld_cpp
3、编写发布者和订阅者代码
进入topic_helloworld_cpp功能包路径下的src文件,新键topic_helloworld_pub.cpp和topic_helloworld_sub.cpp
$ cd topic_helloworld_cpp/src
$ vim topic_helloworld_pub.cpp
$ vim topic_helloworld_sub.cpp
3.1 topic_helloworld_pub.cpp
#include<chrono>
#include<functional>
#include<memory>
#include<string>#include"rclcpp/rclcpp.hpp" //ROS2C++接口
#include"std_msgs/msg/string.hpp" //字符串消息类型using namespace std::chrono_literals;class PublisherNode:public rclcpp::Node
{
public:PublisherNode():Node("topic_helloword_pub") //构造函数初始化{//创建发布者对象publisher_ = this->create_publisher<std_msgs::msg::String>("chatter",10);//创建一个定时器,执行回调函数timer_ = this->create_wall_timer(500ms,std::bind(&PublisherNode::timer_callback,this));}
private://创建定时器周期执行回调函数void timer_callback(){auto msg = std_msgs::msg::String();//创建一个String类型的对象msg.data = "Hello World ROS2"; //添加消息对象中的数据//发布Topic信息RCLCPP_INFO(this->get_logger(),"Publishing: '%s'" ,msg.data.c_str());publisher_->publish(msg);}rclcpp::TimerBase::SharedPtr timer_;rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
};int main(int argc,char* argv[])
{rclcpp::init(argc,argv);rclcpp::spin(std::make_shared<PublisherNode>());rclcpp::shutdown();return 0;
}
3.2 topic_helloworld_sub.cpp
#include<memory>
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"using std::placeholders::_1;class SubscriberNode:public rclcpp::Node
{
public:SubscriberNode():Node("topic_helloworld_sub"){subscription_ = this->create_subscription<std_msgs::msg::String>("chatter",10,std::bind(&SubscriberNode::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<std_msgs::msg::String>::SharedPtr subscription_; //订阅者指针
};int main(int argc,char*argv[])
{rclcpp::init(argc,argv);rclcpp::spin(std::make_shared<SubscriberNode>());rclcpp::shutdown();return 0;
}
4、编写CMakeLists.txt
在# find_package( REQUIRED)行后加入
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)add_executable(topic_helloworld_pub src/topic_helloworld_pub.cpp)
ament_target_dependencies(topic_helloworld_pub rclcpp std_msgs)add_executable(topic_helloworld_sub src/topic_helloworld_sub.cpp)
ament_target_dependencies(topic_helloworld_sub rclcpp std_msgs)install(TARGETS topic_helloworld_pub topic_helloworld_sub DESTINATION lib/${PROJECT_NAME})
5、编译工作空间下的功能包
$ cd ~/devnode_ws/
$ colcon build
6、运行结果
启动第一个终端运行Topic 发布者node
$ source install/local_setup.bash
$ ros2 run topic_helloworld_cpp topic_helloworld_pub
启动第二个终端运行Topic 订阅者node
$ source install/local_setup.bash
$ ros2 run topic_helloworld_cpp topic_helloworld_sub