ROS订阅与发布话题

目录

一、新建一个ROS工作空间并创建功能包
二、创建一个msg消息
三、发布话题
四、订阅话题

前言

Ubuntu18.04
ROS Melodic

一、新建一个ROS工作空间并创建功能包

mkdir -p catkin_ws/src
cd ~/catkin_ws/src/
catkin_init_workspace
cd ~/catkin_ws/
catkin_make
echo "source ~/catkin_ws/devel/setup.bash">>~/.bashrc
source ~/.bashrc 
cd  ~/catkin_ws/src/
catkin_create_pkg topic roscpp rospy std_msgs

执行完毕后建立了工作空间catkin_ws,并创建了功能包topic。
在这里插入图片描述

二、创建一个msg消息

在topic包的目录下创建msg文件夹并在msg文件中添加消息成员

cd ~/catkin_ws/src/topic
mkdir msg
cd msg
gedit example.msg

在这里插入图片描述填入以下内容:

std_msgs/Header header
float32 test1
int32 test2

header是消息头,包含了序列号,时间戳,frame_id,一般每个消息都有这个成员,其他的成员可以根据需要随便取。

编辑package.xml文件

gedit ~/catkin_ws/src/topic/package.xml

确保它包含以下两行且没有被注释。如果没有,添加进去:

  <build_depend>message_generation</build_depend>
  <exec_depend>message_runtime</exec_depend>

在这里插入图片描述
修改topic包下面的CMakeLists.txt文件:

gedit ~/catkin_ws/src/topic/CMakeLists.txt

将message_generation添加到COMPONENTS列表中
在这里插入图片描述
添加运行时依赖关系CATKIN_DEPENDS message_runtime
在这里插入图片描述
添加msg文件

add_message_files(
  FILES
  example.msg
 )

在这里插入图片描述
确保generate_messages()函数被调用

generate_messages(
DEPENDENCIES
 std_msgs
  )

在这里插入图片描述
包含消息头文件路径

include_directories(
  include
  ${catkin_INCLUDE_DIRS}
)

添加完后无需编译使用rosmsg show example即可查看是否添加成功
在这里插入图片描述
在msg中使用其他msg类型
如果在定义msg时,想用其他的包定义好的msg消息类型
例如在package1中定义消息如下:

std_msgs/Header header
package2/msg2 test

其中test的类型为package2包中的msg2消息类型。则需要确保msg2消息正确定义并生成头文件,同时在package1的CmakeLists.txt中的generate_messages中加入package2,例如:

 generate_messages(
   DEPENDENCIES
   std_msgs
   package2
 )

如果引用的是当前包package1中定义的消息,则直接定义即可,无需修改generate_messages
如:

std_msgs/Header header
package1/msg1 test

如果修改了msg文件后编译出现报错:

The dependencies of the message/service ‘XXX’ have changed.
Please rerun cmake.

原因是MSG文件通过编译后变成头文件,但是之前的头文件仍然存在导致编译不通过,使用

catkin_make_isolated --force-cmake

直接强制覆盖编译即可
使用catkin_make_isolated --force-cmake编译后会生成下面两个文件夹
在这里插入图片描述
这是如果用catkin_make编译提示找不到消息头文件,可以将devel_isolated/package1/include/package1下的几个头文件复制覆盖到devel/package1/include/package1下再用catkin_make编译即可
如果删除devel和build文件夹重新编译时提示找不到定义的msg的头文件,这是由于编译时还没来得及生成,可以多编译几次就可以了

三、发布话题

进入catkin_ws/src/topic/src中新建节点程序

cd ~/catkin_ws/src/topic/src
gedit pub.cpp

一个简单的发布节点程序如下,可以直接复制到pub.cpp中

#include <ros/ros.h>
#include <std_msgs/String.h>
#include <sstream>
#include"topic/example.h"
int main(int argc, char **argv)
{
        ros::init(argc, argv,"pub");
        ros::NodeHandle nd;
        ros::Publisher publish = nd.advertise<topic::example>("/topic/example", 10);
        ros::Rate loop_rate(10);
        while (ros::ok())
        {
                topic::example example;
                example.test1 = 1.5;
                example.test2 = 2;
                publish.publish(example);
                loop_rate.sleep();
        }

        return 0;
}

修改topic包下面的CMakeLists.txt文件:

gedit ~/catkin_ws/src/topic/CMakeLists.txt

在文件的最后加上:

add_executable(pub src/pub.cpp)
target_link_libraries(pub ${catkin_LIBRARIES})

然后编译

cd ~/catkin_ws
catkin_make
. ~/catkin_ws/devel/setup.bash

运行:

roscore
rosrun topic pub

然后执行:

rostopic echo /topic/example

出现下面的信息说明发布成功
在这里插入图片描述

四、订阅话题

进入catkin_ws/src/topic/src中新建节点程序

cd ~/catkin_ws/src/topic/src
gedit sub.cpp

一个简单的发布节点程序如下,可以直接复制到sub.cpp中

#include <ros/ros.h>
#include <std_msgs/String.h>
#include <sstream>
#include"topic/example.h"

void subscriberCallback(const topic::example::ConstPtr& msg)
{
printf("test1=%f,test2=%d\n",msg->test1,msg->test2);
}
int main(int argc, char **argv)
{
        ros::Subscriber subscriber;
        ros::init(argc, argv,"sub");
        ros::NodeHandle nd;
        subscriber = nd.subscribe("topic/example", 5, &subscriberCallback);
        ros::Rate loop_rate(10);
        while (ros::ok())
        {
               loop_rate.sleep();
                ros::spinOnce();
        }

        return 0;
}

修改topic包下面的CMakeLists.txt文件:

gedit ~/catkin_ws/src/topic/CMakeLists.txt

在文件的最后加上:

add_executable(sub src/sub.cpp)
target_link_libraries(sub ${catkin_LIBRARIES})

然后编译

cd ~/catkin_ws
catkin_make
. ~/catkin_ws/devel/setup.bash

运行:

rosrun sub sub

可以看到打印出了订阅到的话题
在这里插入图片描述
运行rqt_graph结果如下:
在这里插入图片描述

新开一个终端:
1.输入:rostopic list 查看此时有多少话题。
2.输入:rostopic echo 话题名 查看发送的话题消息。(注意:如果消息是自定义的msg,输入 rostopic echo之前,先执行source devel/setup.bash将工作空间加进去,以便rosmaster可以识别。)

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ROS1中的话题发布订阅是一种常用的通信机制,允许节点之间通过特定的话题(topics)进行数据交换和信息传递。发布者(publisher)节点负责发布数据到特定话题,而订阅者(subscriber)节点则负责订阅话题并接收发布发布的数据。 在ROS1中,话题是一种基于消息(message)的通信方式。发布者和订阅者通过特定的消息类型进行通信。在给定的话题上进行订阅发布之前,需要先定义该话题的消息类型。 例如,我们可以使用ROS的消息定义语言(msg)来定义一个名为"example"的消息类型,该消息类型具有两个字段"test1"和"test2"(引用和)。然后,我们可以使用这个消息类型来创建发布者和订阅者节点。 发布者节点的工作是在指定的话题发布特定消息。在示例代码中,pub.cpp(引用)中的发布者节点定义了一个名为"/topic/example"的话题,并将消息类型设置为"example"。通过调用ros::Publisher对象的publish()函数,发布者可以将消息发送到该话题上。 订阅者节点的工作是在指定的话题订阅并接收发布发布的消息。在示例代码中,sub.cpp(引用)中的订阅者节点通过调用ros::Subscriber对象的subscribe()函数来订阅名为"topic/example"的话题,并且指定了一个名为subscriberCallback的回调函数来处理接收到的消息。在回调函数中,可以对接收到的消息进行相应的处理。 综上所述,ROS1中的话题发布订阅是通过定义消息类型、创建发布者和订阅者节点,并在特定的话题上进行发布订阅来实现的。发布者负责发布消息到话题,而订阅者则负责订阅话题并接收发布发布的消息。这种通信机制可以方便地实现节点之间的数据交换和信息传递。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值