赞
踩
提示:一定要在工作空间中的src目录下,创建一个功能包,依赖是roscpp rospy std_msgs,然后在生成的功能包中的src文件夹下创建本文中的代码,代码创建后需要修改Cmakelist.txt文件后方可正常运行.
这篇内容主要是介绍一下ROS通讯方式中最常用的一种:话题通信.然后通过一个示例来巩固学习效果,最后做一个进阶,订阅ROS下小乌龟的位置信息,并在终端中显示出来.
提示:以下是本篇文章正文内容,下面案例可供参考
个人理解是 :
#include "ros/ros.h" #include"std_msgs/String.h" #include<sstream> /* 发布方实现: 1 包含头文件 2.初始化ROS节点 3.创建节点句柄 4.创建发布对象 5.编写发布逻辑并发布数据 code */ int main(int argc, char *argv[]) { //初始化节点 ros::init(argc,argv,"pub_node"); //创建节点句柄 ros::NodeHandle nh; //创建发布者对象 advertise语句格式 <消息类型>("话题",缓存数量(缓存机制,先进显出,超过后最先进得被删除)) ros::Publisher pub=nh.advertise<std_msgs::String>("pub_topic",10); //编写发布逻辑并发布消息 //先创建被发布的消息 std_msgs::String msg; //设置发布数据频率 10hz,并在消息后添加编号, //添加计数器 int count; ros::Rate rate(10); ros::Duration(3.0).sleep(); //休眠延迟消息发布 //编写循环,循环发布消息数据 while (ros::ok()) { setlocale(LC_ALL,""); count++; //实现字符串与编号拼接 std::stringstream ss; //创建一个ss对象 ss <<"hello ---->"<<count; msg.data=ss.str(); pub.publish(msg); //在终端中添加发布日志 ROS_INFO("发布的数据是:%s",ss.str().c_str()); rate.sleep(); } return 0; }
完成代码后,修改功能包中的Cmakelist.txt代码,修改的第一个位置是在# add_executable(${PROJECT_NAME}_node src/com_test_pub_node.cpp)
后面添加
add_executable(pub src/pub.cpp)
这里面的pub是编译好的项目名,后面的pub.cpp是写的发布者程序名.
修改的第二个位置是:在
#target_link_libraries(${PROJECT_NAME}_node #${catkin_LIBRARIES} #)
后面添加
target_link_libraries(pub
${catkin_LIBRARIES}
)
然后保存Cmakelist.txt文件,返回工作空间,编译之后,在工作空间中输入
source ./devel/setup.bash
rosrun com_test_pub pub
这里的com_test_pub是创建的功能包,pub是创建的发布者项目名
即可看到如下
运行效果:
订阅者的架构与发布者架构相似:
1.包含头文件
2. 初始化ROS节点
3. 创建ROS句柄
4. 创建订阅者话题
5. 处理订阅到的话题中的数据
6. 创建一个spin()函数
7.
订阅者代码如下(示例):
#include"ros/ros.h" #include"std_msgs/String.h" /* 1 包含头文件 2 初始化ROS节点 3 创建节点句柄 4 创建订阅者对象 5 订阅数据处理 6 声明一个spin函数 */ void doMsg(const std_msgs::String::ConstPtr &msg){ //通过msg参数获取并操作订阅到的数据 setlocale(LC_ALL,""); ROS_INFO("订阅的数据:%s",msg->data.c_str()); } int main(int argc, char *argv[]) { //初始化ROS节点 ros::init(argc,argv,"listen"); // 创建ROS 句柄 ros::NodeHandle nh; //创建订阅者对象 使用subscribe句式进行话题订阅(需要订阅的话题名称,缓存数两,回调函数(处理接收到的话题数据)) ros::Subscriber listen= nh.subscribe("pub_topic",10,doMsg);// ros::spin(); //语句执行完之后回头一下 处理回调函数 return 0; }
同样,订阅者创建完以后,也要在Cmakelist.txt文件中的对应位置添加:(可以写在发布者的add_executable和target_link_libraries的后面)
add_executable(listen src/listen.cpp)
target_link_libraries(listen
${catkin_LIBRARIES}
)
然后保存Cmakelist.txt文件,返回工作空间,编译之后,在工作空间中输入
source ./devel/setup.bash
rosrun com_test_pub pub
在新开一个终端进入同一个工作空间中输入
source ./devel/setup.bash
rosrun com_test_pub listen
这里的com_test_pub是创建的功能包,listen是创建的订阅者项目名
即可看到如下
运行效果:
注意:
先启动订阅者,在启动发布者,这时订阅者终端在接受数据时,可能会出现前几条数据接受不到原因是发布者已经发布出来了数据,但是这时候还没有在master里面注册成功,所以订阅者收不到前几条消息.
解决方法是:在发布者里面加入休眠
注册后,加入休眠 ros::Duration(3.0).sleep(); 延迟第一条数据的发送
然后进阶一下,订阅一个小乌龟的位置节点,并在终端中显示位置节点中的数据,废话不多说,上代码:
#include "ros/ros.h" #include"std_msgs/String.h" #include"turtlesim/Pose.h" void doMsg(const turtlesim::PoseConstPtr &Msg){ float x,y,theta,line_ve; x=Msg->x; y=Msg->y; theta=Msg->theta; line_ve=Msg->linear_velocity; ROS_INFO("I heard pose x:[%f] y:[%f] theta:[%f] ve:[%f]",x, y, theta, line_ve); } int main(int argc, char *argv[]) { //初始化节点 定义turtle_pos为设置订阅的节点名 ros::init(argc,argv,"turtle_pos"); //创建ROS句柄 ros::NodeHandle nh; //创建订阅话题 ros::Subscriber pos = nh.subscribe("turtle1/pose",100,doMsg); ros::spin(); return 0; }
同样,也要在Cmakelist.txt文件中的对应位置添加:(可以写在发布者的add_executable和target_link_libraries的后面)
add_executable(turtlesimPos src/turtlesim_pos_lis.cpp)
target_link_libraries(turtlesimPos
${catkin_LIBRARIES}
)
然后编译工作空间,在终端中输入
source ./devel/setup.bash
接下来的操作步骤:
roscore
ctrl+shift+T
,打开一个新终端,启动小乌龟节点,在终端中输入rosrun turtlesim turtlesim_node
rosrun turtlesim turtle_teleop_key
,这个时候可以用键盘控制小乌龟了,rosrun com_test_pub turtlesimPos
就可以在终端中看到下图
至此,ROS的话题通讯已经完成,可以订阅想要的到的话题数据了.
此文中的代码已经上传,可以直接通过传送门下载:传送门
<- - - 如有侵权,请联系删除- - ->
<每天进步一点点>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。