ROS发布及订阅消息简单实践(二)

一.在catkin_ws/src/mypackage/src(工作空间/src/包名/src)下创建talker.cpp和listener.cpp(源程序)分别编辑三个文件(先使用catkin_create_pkg mypackage roscpp rospy 创建包名,再在包名下的src目录下创建.cpp文件):

1.你创建的publisher(talker.cpp):

#include<sstream> 

// C++引入了 ostringstream、istringstream、stringstream 三个类,要使用他们创建对象就必须包含sstream.h头文件。

#include<ros/ros.h> //包含ros节点所必须的文件

#include<std_msgs/String.h> //包含了我们要使用的消息类型

int main(int argc,char** argv)
{
ros::init(argc,argv,"talker");   //ros节点初始化,输入参数并为节点命名(与CMakeLists.txt中的节点名称相同,名称唯一)

ros::NodeHandle n;//设置节点进程的句柄

ros::Publisher chatter_pub=n.advertise<std_msgs::String>("chatter",1000); //将节点设置成发布者

//**ros::Publisher 对象=n.advertise<std_msgs::消息类型>("话题",缓冲区大小);** 
//在ros master端注册一个publisher,发布名为chatter的topic,消息类型为string,缓冲区可缓冲消息数量为1000)

ros::Rate loop_rate(10); //设置循环的频率,这里是10hz

int count=0;

// 当收到CTRL+C或ROS停止当前节点运行时,ros::ok( )库会执行停止节点运行的命令。

while(ros::ok())//在节点未发生异常的时候循环
{
std_msgs::String msg; //创建一个消息变量,变量的类型必须和节点发布的消息的类型相同

std::stringstream ss; //输入输出流 ss

ss<<"hello world"<<count; //将字符串hello world和int型count 输入到ss中

msg.data=ss.str(); //将字符串传递给msg.data

ROS_INFO("%s",msg.data.c_str());  //发布日志消息,类似于c语言中的printf

chatter_pub.publish(msg);//发布封装完毕的消息msg,master会查找订阅该话题的节点,帮助其建立连接,完成消息的传输。

//循环等待回调函数,用来处理节点订阅话题的所有回调函数
//如果有一个订阅者出现,ROS就会更新和读取所有主题

ros::spinOnce();

//按照循环频率(10Hz)延时

loop_rate.sleep();

++count;

}

return 0;

}

2.你的subscriber(listener.cpp):

#include<ros/ros.h>

#include<std_msgs/String.h>

//回调函数:每次节点接收到消息之后都将调用此函数,可使用或处理数据

void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
//在该例中,仅将接收到的消息打印出来,ROS_INFO()用于在命令行窗口输出数据

ROS_INFO("I heard :[%s].",msg->data.c_str());

}

//回调函数是订阅节点接收消息的基础机制,当有消息到达时会自动以**消息指针**作为参数
//再调用回调函数,完成对消息内容的处理

int main(int argc,char **argv)
{
ros::init(argc,argv,"listener"); //初始化节点,写入接收节点名称(listener)

ros::NodeHandle n;//设置节点进程句柄

ros::Subscriber sub=n.subscribe("chatter",1000,chatterCallback);

//订阅节点首先需要声明自己订阅的消息话题,该消息会在ros master中注册,master会关注系统中是否存在发布该话题的节点,
//如果存在则会帮助两个节点建立连接,完成数据的传输,NodeHandle::subscriber()用来创建一个Subscriber,
//第一个参数即为消息话题,第二个是消息队列的大小(缓存区),第三个参数是接收到话题消息后的回调函数。

ros::spin();//节点进入循环状态,有消息到达时调用回调函数完成处理

return 0;

}

3.在包名(我的是myros)目录下的cmakelist.txt末尾添加(也可以在文中修改):

include_directories(include ${catkin_INCLUDE_DIRS})
//在cmakelist.txt中存在, 用于设置头文件的相对路径,默认在include文件夹下

add_executable(talker src/talker.cpp)
//用于设置需要编译的代码和生成的可执行文件,第一个参数为期望生成的可执行文件名称(节点名称)
//第二个参数为参与编译的源码文件,多个文件则用空格隔开

target_link_libraries(talker ${catkin_LIBRARIES} ) 
//用于设置链接库,第一个参数同上,第二个为需要链接的库,这次使用默认库

add_dependencies(talker ${PROJECT_NAME}_generate_messages_cpp) 
//用于设置依赖,如果编译的可执行文件依赖这些动态生成的代码,则需要添加这个来配置

add_executable(listener src/listener.cpp)

target_link_libraries(listener ${catkin_LIBRARIES} )

add_dependencies(talker ${PROJECT_NAME}_generate_messages_cpp)

二.运行publisher和subscriber
1.在工作空间目录下:

$ catkin_make

2.启动roscore:

$ roscore

3.新建终端:

$ source ~/工作空间/包名/devel/setup.bash

启动publisher

$ rosrun 包名 发布节点的可执行文件名

3.新建终端:

$ source ~/工作空间/包名/devel/setup.bash

启动subscriber

$ rosrun 包名 订阅节点的可执行文件名

若运行成功,在终端将会出现接受和发布的消息内容

————————————————
版权声明:本文为CSDN博主「tao_sc」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/tao_sc/article/details/89072927

原创文章 15 获赞 8 访问量 929

猜你喜欢

转载自blog.csdn.net/weixin_39652282/article/details/103475569