6.ROS的消息发布者与订阅者示例

前言

        Topic话题,是节点之间信息交换的方法,在向话题发生送消息的节点叫做发布者,接收消息的节点叫做订阅者。

        一个ROS程序中话题可以有很多个,一个话题中也可以有多个发布者和订阅者。一个订阅者可以订阅多个话题。同样 ,一个发布者也可以同时在多个话题中发送消息。

在ROSindex网站查看消息的类型有哪些

①进入ROSindex网站,在搜索栏搜索std_msgs,找到你使用的ROS版本。

②点击website

 ③下滑可以找到消息类型,我们点进Int16看看具体的内容

 

编写代码 

 我们编写代码,在同一个包中建立两个节点作为两个发布者。分别发送string类型和int16类型的消息到两个不同的话题中。而另一个包中只建立一个节点作为订阅者,同时接收两个话题中的内容。

目录结构如下:

 abc.cpp的代码

#include <ros/ros.h>
#include <std_msgs/String.h>
int main(int argc, char  *argv[])
{
    ros::init(argc,argv,"abc_node");//abc1_node节点
    ros::NodeHandle nh;
    ros::Publisher pub=nh.advertise<std_msgs::String>("abc_test",5);//string消息类型   发布到话题abc2_test中  缓冲区长度5
    ros::Rate loop_rate(10);//与loop_rate.sleep();配合实现一秒发十次
   
    while (ros::ok())
    {
             printf("adc_node running\n");//打印信息到所在的运行终端
             std_msgs::String msg;//创建消息变量
             msg.data="adc的消息";//给消息赋值
             pub.publish(msg);//发送
             loop_rate.sleep();
    }
    
    return 0;
}

  abc2.cpp的代码

#include <ros/ros.h>
#include <std_msgs/Int16.h>
int main(int argc, char  *argv[])
{
    ros::init(argc,argv,"abc2_node");//abc2_node节点
    ros::NodeHandle nh;
    ros::Publisher pub=nh.advertise<std_msgs::Int16>("abc2_test",5);//int16消息类型   发布到话题abc2_test中  缓冲区长度5
    ros::Rate loop_rate(10);//与loop_rate.sleep();配合实现一秒发十次
   
    while (ros::ok())
    {
             printf("adc2_node running\n");//打印信息到所在的运行终端
             std_msgs::Int16 msg;//创建消息变量
             msg.data=222;//给消息赋值
             pub.publish(msg);//发送
             loop_rate.sleep();
    }
    
    return 0;
}

 abc包的cmakelist添加的代码

 add_executable(abc_node src/abc.cpp)

 target_link_libraries(abc_node
   ${catkin_LIBRARIES}
 )

 add_executable(abc2_node src/abc2.cpp)

 target_link_libraries(abc2_node
   ${catkin_LIBRARIES}
 )

efg.cpp代码

#include <ros/ros.h>
#include <std_msgs/String.h>
#include <std_msgs/Int16.h>
void rc_callback1(std_msgs::String msg)//订阅者回调函数         参数为接收的消息类型
{
    ROS_INFO(msg.data.c_str());//字符转字符数组
}
void rc_callback2(std_msgs::Int16 msg)
{
   ROS_INFO("%d",msg.data);//相当于带时间戳的print

}
int main(int argc, char  *argv[])
{
    setlocale(LC_ALL,"zh_CN.UTF-8");//中文编码
    ros::init(argc,argv,"efg_node");//第三个参数是节点名
    ros::NodeHandle nh;
    ros::Subscriber sub=nh.subscribe("abc_test",5,rc_callback1);//订阅者1       订阅abc_test话题      缓冲区长度5   回调函数为rc_callback1
    ros::Subscriber sub2=nh.subscribe("abc2_test",5,rc_callback2); //订阅者2    订阅abc2_test话题
    while (ros::ok())
    {
        ros::spinOnce();//监听消息包
    }
    
    return 0;
}

 efg包的cmakelist添加的代码

add_executable(efg_node src/efg.cpp)

target_link_libraries(efg_node
  ${catkin_LIBRARIES}
)

运行

在程序运行时我们可以

用rostopic+list    来查看活跃的话题

用rostopic+echo+话题名     监听话题内容

用rostopic+hz+话题名  查看话题消息的频率

也可以用rqt_graph来查看正在运行的节点的网络情况 (椭圆形是节点,矩形或/是话题,箭头表示消息流通方向)

launch文件一次启动多个节点 

launch只要包含了节点的描述就会自动启动roscore

launch可存放在任意目录下,没有对源码和支持文件目录的依赖,但是放在包的目录下可以通过roslaunch 包名 launch文件名运行。如果放在其它目录下需要先在终端中进入这个目录再运行,否则会提示找不到launch文件。

<launch>
        <node pkg="abc_pkg" type="abc_node" name="abc_node"  launch-prefix="gnome-terminal -e"/>

        <node pkg="abc_pkg" type="abc2_node" name="abc2_node"/> 

        <node pkg="efg_pkg" type="efg_node" name="efg_node" output="screen"/>
</launch>

 其中launch-prefix="gnome-terminal 表示新建一个终端并运行。output="screen"表示在终端输出,否则ROS_INFO不会打印信息到launch运行的终端。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zx62365

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值