ROS学习笔记(一) 话题topic的定义与使用(publisher 和 subscriber)

ROS学习笔记(一) 话题topic的定义与使用(publisher 和 subscriber)

最近由于项目所需刚开始学习ros,学习自b站的古月 ROS入门21讲,做一个总结,仅为自己学习使用,可供参考。

topic的组成

《ROS机器人开发实践》一书中讲的十分清楚,这里只是我自己的一个通俗的理解。
实现一个publisher发送消息topic,subscriber从topic中接收消息。其中包含了四个部分:
1 . 发布者(publisher)
2. 订阅者(subscriber)。
3. 话题(topic): 发布者发布消息给话题,订阅者从指定话题订阅消息。
4. 消息(message):发送或接收的消息类型可以使用已有的消息类型,也可以自己定义消息类型。

消息
消息
发布者节点
话题topic
订阅者节点

以小乌龟程序为例,利用键盘对乌龟进行操作的指令如下

rosrun turtlesim turtle_teleop_key

节点关系如下:

/turtle1/cmd_vel
/teleop_turtle
/turtlesim

这里有两个节点/teleop_turtle和 /turtlesim,和一个话题/turtle1/cmd_vel组成。/teleop_turtle创建了一个发布者,用于发布键盘控制的指令;/turtlesim创建了一个订阅者,用于订阅速度指令,实现乌龟的运动;/turtle1/cmd_vel是话题。

建立topic通信

topic一共由发布者、订阅者、话题、消息组成。其中的发布者和订阅者是节点,需要通过C++或python来分别进行定义,话题和消息则是在这两个代码文件中进行调用,步骤如下:
1、创建功能包。一切的程序调用都需要在功能包中完成。
2、自定义话题消息。若使用已有的消息类型则不需要定义。
3、publisher源文件的创建。(C++或python)
4、subscriber源文件的创建。(C++或python)
5、编译生成可执行文件(python可省略该步骤)。
(6、测试执行)

详细步骤:

下面以一个发布和订阅人员信息的例子详细介绍每一个步骤:

learning_topic::person
learning_topic::person
person_publisher
/person_info
person_subscriber

一、创建功能包

(一)、没有工作空间先创建工作空间

1、创建工作空间
(1) 递归创建文件夹 mkdir -p ~/catkin_ws/src
(2) 进入/src路径 cd ~/catkin_ws/src
(3) 初始化工作空间 catkin_init_workspace
2、编译工作空间
(1) 进入工作空间根目录cd ~/catkin_ws
(2) 编译工作空间 catkin_make
3、设置环境变量
source devel/setup.bash

(二)、创建功能包:

1、cd ~/catkin_ws/src在src文件夹路径下建立功能包
2、catkin_create_pkg learning_topic roscpp rospy std_msgs创建功能包,其中learning_topic是功能包名称,roscpp、rospy、std_msgs是相关依赖。

二、自定义话题消息

(一)、定义msg文件(这里为Person.msg)

1、learning_topic功能包中建立名为“msg”文件夹,用以保存Person.msg文件。
2、在msg文件夹中用touch或gedit指令建立一个名为“Person.msg”文件,其文件内容如下:

string name
uint8 age
uint8 sex
uint8 unknown = 0
uint8 male    = 1
uint8 female  = 2

(二)、在package.xml中添加功能包依赖用以动态产生message

1、添加编译依赖:message_generation
2、添加执行依赖:message_runtime

(三)、修改CMakeLisk.txt文件

1、在“find_package”中添加

message_generation

2、将定义的Person.msg文件作为定义的消息接口,针对定义编译。
在“Declare ROS message, service and actions”中添加

add_message_files(FILES Person.msg)

3、说明编译Person.msg时所依赖的包。
在“Declare ROS message, service and actions”中添加

generate_messages(DEPENDENCIES std_msgs)

4、添加message运行的依赖。
在“catkin_package”中添加

CATKIN_DEPENDS roscpp rospy std_msgs message_runtime

(四)、编译产生消息Person.h

进入工作空间根目录进行编译

cd ~/catkin_ws
catkin_make

在路径~/catkin_ws/devel/include中会产生Person.h文件,里面就是定义的消息类型

三、publisher源文件的创建

~/catkin_ws/src/learning_topic/src路径下创建publisher源文件:person_publisher.cpp
其源代码如下:

//添加所依赖的头文件
#include
#include
//主函数
int main(int argc,char **argv)
{
	//初始化节点,"person_publisher"为发布者节点
	ros::init(argc,argv,"person_publisher");
	
	//设置句柄
	ros::NodeHandle n;
	
	//创建发布者,发布者名字为person_info_pub;消息类型为learning_topic::Person;话题节点为/person_info;10代表缓冲队列大小
	ros::Publisher person_info_pub = n.advertise<learning_topic::Person>("/person_info",10);
	
	//设置循环频率,单位是HZ
	ros::Rate loop_rate(1);

	//进入循环
	int count = 0;
	while(ros::ok())
	{
		//初始化learning_topic::Person类型消息
		learning_topic::Person person_msg; //声明Person类的一个对象person_msg
		person_msg.name = "Tom";
		person_msg.age = 18;
		person_msg.sex = learning_topic::Person::male; //调用预定义的宏
		
		//发布消息
		person_info_pub.publish(person_msg); //发布者person_info_pub发布消息		
		
		//显示发布信息
		ROS_INFO("publish Person Info:name:%s,age:%d,sex:%d",person_msg.name.c_str(),person_msg.age,person_msg.sex);
		
		loop_rate.sleep();
	}
}

四、subscriber源文件的创建

~/catkin_ws/src/learning_topic/src路径下创建subscriber源文件:person_sbscriber.cpp
其源代码如下:

//添加所依赖的头文件
#include
#include

//回调函数
void PersonInfoCallback(const learning_topic::Person::ConstPtr& msg)
{
	//显示接收到的信息
	ROS_INFO("subscribe Person Info:name:%s,age:%d,sex:%d",msg->name.c_str(),msg->age,msg->sex);
}

//主函数
int main(int argc,char **argv)
{
	//初始化节点,"person_subscriber"为订阅节点
	ros::init(argc,argv,"person_subscriber");

	//设置句柄
	ros::NodeHandle n;

	//创建订阅者,person_info_sub是订阅者,从话题“/person_info”订阅
	ros::Subscriber person_info_sub = n.subscribe("/person_info",10,PersonInfoCallback);

	//循环等待
	ros::spin();
	return 0;
}

五、修改CMakeList.txt,编译生成可执行文件

(一)、在CMakeList.txt文件添加以下内容

1、生成可执行文件

add_executable (person_publisher src/person_publisher.cpp)
add_executable (person_subscriber src/person_subscriber.cpp)

2、设置链接

target_link_libraries(person_publisher ${catkin_LIBRARIES})
target_link_libraries(person_subscriber ${catkin_LIBRARIES})

3、添加依赖

add_dependencies(person_publisher ${PROJECT_NAME}_generate_message_cpp)
add_dependencies(person_subscriber ${PROJECT_NAME}_generate_message_cpp)

(二)、编译

~/catkin_ws路径下执行

catkin_make

六、测试

测试之前记得先要source devel/setup.bash,创建环境变量。
打开三个终端分别输入以下命令:

roscore
rosrun learning_topic person_publisher
rosrun learning_topic person_subscriber

执行成功后打开新的终端执行rqt_graph查看节点关系如下:
ROS学习笔记(一) 话题topic的定义与使用(publisher 和 subscriber)_第1张图片
其中/person_publisher是发布者节点,发送消息给/person_info话题,/person_subscriber是订阅者节点,从person_info话题订阅消息。消息类型为learning_topic::Person。

你可能感兴趣的:(ROS学习笔记(一) 话题topic的定义与使用(publisher 和 subscriber))