在ROS工作空间ROS_ws的src文件夹目录下创建一个功能包,命名为test_pkg,并编译完成。
定义一个发布者Publisher,通过自定义的消息Person将消息数据name、sex及age等发送到订阅者Subscriber,同时订阅者将消息内容打印到终端界面。
在功能包目录下创建一个新的文件夹,命名为msg,并在此文件夹中创建一个空文件Person.msg。可以使用鼠标右键New Document>Empty Document,或在src路径下通过终端命令符touch创建空文件。
在Person.msg文件中输入以下代码,定义话题消息。
string name
uint8 sex
uint8 age
uint8 unknown = 0
uint8 male = 1
uint8 female = 2
在功能包下面的src文件夹目录下创建一个空文件Publisher_test.cpp。
打开上述创建的文件Publisher_test,输入以下代码。
#include "ros/ros.h"
#include "test_pkg/Person.h"
int main(int argc, char **argv)
{
//初始化ROS节点
ros::init(argc, argv, "Publisher_test");
//创建句柄
ros::NodeHandle n;
//创建一个发布者Publisher,发布名为/person_info的topic,消息类型为test_pkg::Person,队列长度为10
ros::Publisher person_info_pub = n.advertise("/person_info", 10);
//设置消息发布频率
ros::Rate loop_rate(1);
int count = 0;
while(ros::ok())
{
//初始化消息内容
test_pkg::Person person_msg;
person_msg.name = "Tom";
person_msg.age = 18;
person_msg.sex = test_pkg::Person::male;
//发布消息
person_info_pub.publish(person_msg);
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();
}
}
说明:
test_pkg::Person person_msg;
person_msg.name = "Tom";
person_msg.age = 18;
person_msg.sex = test_pkg::Person::male;
综上所述,实现一个话题发布者的步骤大致可分为以下几点:
在src文件夹下再创建一个空文件Subscriber_test.cpp,输入以下代码。
#include "ros/ros.h"
#include "test_pkg/Person.h"
//收到消息时进入回调函数
void personInfoCallback(const test_pkg::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)
{
//初始化ROS节点
ros::init(argc, argv, "Subscriber_test");
//创建句柄
ros::NodeHandle n;
//创建一个订阅者Subscriber
ros::Subscriber person_info_sub = n.subscribe("/person_info", 10, personInfoCallback);
//循环接收消息
ros::spin();
return 0;
}
说明:
综上所述,实现一个话题订阅者的步骤大致可分为以下几点:
附相关资料:
(1) Publishers and Subscribers
(2) Writing a Simple Publisher and Subscriber (C++)
打开功能包中的CMaKeLists.txt文件。在如下位置的find_package中添加message_generation功能包,以便于(节点)调用它们生成消息。
在如下位置添加相关的.msg文件,确保了CMake在重新配置时知道这些新添加的.msg文件,同时添加 .msg文件在生成消息时的所有依赖项(功能包)。
add_message_files(FILES Person.msg)
generate_messages(DEPENDENCIES std_msgs)
将如下位置中CATLIN_DEPENDS前面的“#”去掉。
在如下位置进行配置,add_executable(Publisher_test src/Publisher_test.cpp)的作用是将src文件夹下的Publisher_test.cpp文件编译成名为Publisher_test的可执行文件。target_link_libraries(Publisher_test ${catkin_LIBRARIES})的作用是将Publisher_test可执行文件与ROS相关的库链接。add_dependencies(Publisher_test ${PROJECT_NAME}_generate_messages_cpp)的作用是将Publisher_test可执行文件与一些动态生成的文件链接。
add_executable(Publisher_test src/Publisher_test.cpp)
target_link_libraries(Publisher_test ${catkin_LIBRARIES})
add_dependencies(Publisher_test ${PROJECT_NAME}_generate_messages_cpp)
add_executable(Subscriber_test src/Subscriber_test.cpp)
target_link_libraries(Subscriber_test ${catkin_LIBRARIES})
add_dependencies(Subscriber_test ${PROJECT_NAME}_generate_messages_cpp)
打开功能包中的package.xml文件,在如下位置添加功能包依赖。
message_generation
message_runtime
message_generation
这条语句表示在编译时会依赖一个动态产生message的功能包。
message_runtime
这条语句表示在运行时会依赖message_runtime的功能包。
在/ROS_ws文件夹路径下打开一个新的终端,输入以下代码进行编译。
$ catkin_make
$ roscore
打开一个新的终端,首先配置环境变量,然后输入以下代码运行节点。
$ rosrun test_pkg Publisher_test
打开一个新的终端,首先配置环境变量,然后输入以下代码运行节点。
$ rosrun test_pkg Subscriber_test
打开一个新的终端,输入以下代码。
$ rqt_graph
由此可以得到如下的基于Qt的GUI界面,直观地看到话题通信的发布订阅节点和消息。
$ rostopic list
使用上述指令能够列出所有当前正在订阅和发布的话题,效果如下图。
$ rostopic list -v
使用上述指令能够得到当前正在订阅和发布的话题的详细内容介绍,效果如下图。
更多关于rostopic指令的使用,可以通过以下代码获取。
$ rostopic --help