ROS话题的发布与订阅

  1. 创建工作空间
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
catkin_init_workspace	#初始化工作空间 
cd ~/catkin_ws catkin_make	#编译工作空间

执行catkin_make命令后,catkin文件夹下有三个文件夹:build、devel和src。build文件为编译空间(The Build Space),其中的CMake*和catkin文件为工作包和项目保存缓存信息、配置和其他中间文件;devel文件为开发空间(The Development Space),该文件夹保存编译后的程序,这些程序不需要安装就可以进行测试运行。

source devel/setup.bash	#将该工作空间加入环境变量
  1. 创建功能包

创建工作空间后,工作空间可以顺利通过编译吧,但此时工作空间不存在功能包,即还没有功能实现。因此需要使用catkin_create_pkg创建功能包。

cd ~/catkin_ws/src
catkin_create_pkg	ROS_Test1    std_msgs    roscpp

catkin_create_pkg命令行格式:catkin_create_pkg [package_name] [depend1] [depend2]。因此上述命令行中的std_msgs和roscpp分别为功能包ROS_Test1的依赖项。

std_msgs:包含了常见的消息类型,表示基本数据类型和其他基本的消息构造。
roscpp:表示该功能包通过c++实现ROS的各种功能。提供了一个客户端库,c++开发者可以调用接口迅速完成主题、服务等相关工作。

此时执行以下命令可以查看功能包的依赖项。

rospack depends ROS_Test1(查看功能包依赖项)
rospack depends1 ROS_Test1(查看功能包1级依赖项)
  1. 编译功能包
cd ~/catkin_ws
catkin_make
  1. 创建数据发布节点
    roscd ROS_Test1/src

创建文件node_a.cpp,内容如下所示:

#include "ros/ros.h"	//包含了使用ROS节点的必要文件
#include "std_msgs/String.h"	//包含了使用的数据类型
#include <sstream>     
int main(int argc, char **argv)
{
	ros::init(argc, argv, "node_a");	//初始化ROS,节点名命名为node_a,节点名必须保持唯一
    ros::NodeHandle n;	//实例化节点, 节点进程句柄
    ros::Publisher pub = n.advertise<std_msgs::String>("str_message", 1000);	//告诉系统要发布话题了,话题名为“str_message”,类型为std_msgs::String,缓冲队列为1000。
    ros::Rate loop_rate(10);	//设置发送数据的频率为10Hz

   while(ros::ok())
    {
    	std_msgs::String msg;
    	std::stringstream ss;
    	ss<<"Hello World";
    	msg.data = ss.str();
    	ROS_INFO("node_a is publishing %s", msg.data.c_str());
    	pub.publish(msg);	//向话题“str_message”发布消息
    	ros::spinOnce();	//不是必须,若程序中订阅话题则必须,否则回掉函数不起作用。
    	loop_rate.sleep();	//按前面设置的10Hz频率将程序挂起
    } 
    return 0;
}
  1. 创建数据订阅节点

roscd ROS_Test1/src

创建文件node_b.cpp,内容如下所示:

#include "ros/ros.h"
#include "std_msgs/String.h"
//话题回调函数
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
	ROS_INFO("node_b is receiving [%s]", msg->data.c_str());
}
int main(int argc, char **argv)
{
	ros::init(argc, argv, "node_b");	//初始化ROS,节点命名为node_b,节点名必须唯一。
	ros::NodeHandle n;	//节点句柄实例化
	ros::Subscriber sub = n.subscribe("str_message", 1000, chatterCallback);	//向话题“str_message”订阅,一旦发布节点(node_a)在该话题上发布消息,本节点就会调用chatterCallbck函数。
	ros::spin();	//程序进入循环,直到ros::ok()返回false,进程结束。
	return 0;
}

同时发布可创建多个实例化节点句柄,创建多个发布函数,创建多个订阅回调函数。

  1. 编译节点
roscd ROS_Test1 CMakeLists.txt(或vim  ~/catkin_ws/src/ROS_Test1/CMakeLists.txt)

在文件尾部添加内容如下:

add_executable(Test1_node_a src/node_a.cpp)	#将node_a.cpp文件编译成可执行文件Test1_node_a
add_executable(Test1_node_b src/node_b.cpp)

add_dependencies(Test1_node_a ROS_Test1_generate_message_cpp)	#添加可执行文件的消息依赖项
add_dependencies(Test1_node_b ROS_Test1_generate_message_cpp)

target_link_libraries(Test1_node_a ${catkin_LIBRARIES})	#为可执行文件Test_node_a添加链接库
target_link_libraries(Test1_node_b ${catkin_LIBRARIES})

以上内容编辑完成以后,进行节点编译:

cd ~/catkin_ws
catkin_make

在终端上运行命令:

roscore

另外开两个终端,分别运行命令行(若无法运行,先执行命令行source devel/setup.bash):

rosrun ROS_Test1 Test1_node_a
rosrun ROS_Test1 Test1_node_b

此时,则可以在终端上输出订阅的信息。

补充
ros::ok()返回false的条件:

SIGINT收到(Ctrl-C)信号
另一个同名节点启动,会先中止之前的同名节点
ros::shutdown()被调用
所有的ros::NodeHandles被销毁

spinOnce()与spin()区别:
spinOnce()与spin()是兄弟函数,学名叫做消息回调处理函数。区别如下:

spinOnce()函数调用后,会继续执行后续的代码段。例如node_a中,执行该函数后会继续执行loop_rate.sleep()。
spin()调用后,程序不会返回,不会执行后续的代码段。例如node_b中,执行该函数后,程序不会返回。


转载至:https://blog.csdn.net/liuxiaodong400/article/details/89011284

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ROS1中的话题发布订阅是一种常用的通信机制,允许节点之间通过特定的话题(topics)进行数据交换和信息传递。发布者(publisher)节点负责发布数据到特定话题,而订阅者(subscriber)节点则负责订阅话题并接收发布发布的数据。 在ROS1中,话题是一种基于消息(message)的通信方式。发布者和订阅者通过特定的消息类型进行通信。在给定的话题上进行订阅发布之前,需要先定义该话题的消息类型。 例如,我们可以使用ROS的消息定义语言(msg)来定义一个名为"example"的消息类型,该消息类型具有两个字段"test1"和"test2"(引用和)。然后,我们可以使用这个消息类型来创建发布者和订阅者节点。 发布者节点的工作是在指定的话题发布特定消息。在示例代码中,pub.cpp(引用)中的发布者节点定义了一个名为"/topic/example"的话题,并将消息类型设置为"example"。通过调用ros::Publisher对象的publish()函数,发布者可以将消息发送到该话题上。 订阅者节点的工作是在指定的话题订阅并接收发布发布的消息。在示例代码中,sub.cpp(引用)中的订阅者节点通过调用ros::Subscriber对象的subscribe()函数来订阅名为"topic/example"的话题,并且指定了一个名为subscriberCallback的回调函数来处理接收到的消息。在回调函数中,可以对接收到的消息进行相应的处理。 综上所述,ROS1中的话题发布订阅是通过定义消息类型、创建发布者和订阅者节点,并在特定的话题上进行发布订阅来实现的。发布者负责发布消息到话题,而订阅者则负责订阅话题并接收发布发布的消息。这种通信机制可以方便地实现节点之间的数据交换和信息传递。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值