ROS(1)发布者-订阅者话题通信流程

目录

1 创建工作空间

2 创建功能包

3 创建ros节点

 4 创建发布者

5 创建订阅者

小技巧

1 避免每次都source

2 字符等可以使用中文输出

3 VScode工作空间设置

4 超级终端

5 VScode相关插件安装


内容大多是一些博主文章或者视频的汇总,如果遇到看不懂的地方建议去参看原链接。

机器人工匠阿杰:机器人工匠阿杰的个人空间-机器人工匠阿杰个人主页-哔哩哔哩视频 (bilibili.com)

ROS机器人入门教程文档:Introduction · Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程

下面开始正文:发布者-订阅者话题通信

         ros的相关操作都是多个节点完成的,模块化完成代码编写,尽管ros程序的基础单元是节点,但是不可以只安装单个节点,必须以包为单位安装。可以简单的理解为包是节点的容器。

        我们编写代码通常是为了完成一个相应的功能(节点),但是节点不能单独存在,所以要创建一个包。

整体流程如下:

1创建工作空间        2创建功能包        3创建ROS节点        4创建发布者        5创建订阅者


1 创建工作空间

ROS程序的编译等工作需要先创建工作空间以及src子目录

在终端输入指令:mkdir -p 自定义工作空间名/src

在主目录的文件夹也会多出来一个名字是learn的文件夹,并且里面有个空的src文件夹。

上面的操作也可以自己直接在主目录直接完成。


2 创建功能包

使用cd指令进入src工作目录,创建ROS包并添加依赖项

依赖项:在创建包时,通常将密切的节点放到一个包里面,但是总会存在一些通用性强的节点,会和其他包的节点发生关联,放在哪个包都不合适,只好把这些资源单独放一个包,谁要用,谁就依赖这个包。

cd 自定义工作空间名/src

catkin_create_pkg 自定义ROS包名 roscpp rospy std_msgs

自定义ROS包名后面的内容就是依赖项

 创建完成后的结构如上图所示,导入依赖项的包有include文件夹(里面包含一个自定义ROS包名的空文件夹)、src空文件夹、Cmakelists.txt和package.xml四个。


后续编译的节点都是在这个src目录下创建并编译完成,关于ROS系统的文件架构,我在下方放一个图片,理解结构会更加清楚。

C++文件编写的相关操作,我们都是在第二级src目录下编写的。我们现在来创建一个发布者-订阅者的话题通信来开启自己的第一个ROS流程。(写笔记这个电脑上没安装Ubuntu和ROS,目前的文章也只是方便自己回顾,如有需要请看文章开头附的资源链接)


3 创建ros节点

上文已经创建完成软件包,在自定义ROS包名中进入src目录,并创建节点1.cpp文件

在src目录下右键新建文件,创建发布者节点node_pub1

节点创建完成后我们开始发布者和订阅者代码内容的编写,下方给了一个较为完整的流程

我们先尝试基本的测试,再进行发布者节点具体代码的编写

 将Cmakelists.txt文件build章节的executable复制到文件末尾

两个参数,第一个参数为可执行文件名(尽量与节点名保持一致),第二个是文件的编译路径。

 在vscode中使用ctrl+shift+B编译失败(转到终端编译)VS中编译快捷键没设置好,很容易出问题

编写完成后在工作空间learn下打开终端窗口,执行catkin_make进行编译

在终端中先启动roscore,之后再使用rosrun启动自己创建的节点,启动中出错无法找到bao1。这是因为没有将环境的配置导入参数空间。之后就可以正常运行了。

source ~/自定义工作空间名/devel/setup.bash


 4 创建发布者

上面以及完成了基本的测试,下面开始创建发布者节点

首先将代码文件拷贝到.cpp文件,因为用到了ros的init函数,所以要在Cnakelists.txt文件添加链接库

 配置完成后在终端中打开了learn工作空间,执行catkin_make编译

运行结果示例:

发布者模板示例

#include<ros/ros.h>

#include<std_msgs/String.h>

int main(int argc, char *argv[])

{

        ros::init(argc,argv,"节点1");

        printf("测试1");

        //实例化句柄

        ros::NodeHandle nh;

        /*用上面实例的句柄实现发布者操作,<>内部的参数是消息类型,()里面两个参数,

        第一个是发布的话题名称,第二个是最大缓存的消息数目*/

        ros::Publisher pub = nh.advertise<std_msgs::String>("话题名",10);

        ros::Rate loop_rate(10);        //一秒发送10条消息,固定发送频率

        while(ros::ok())

        {

                printf("测试2\n");

                std_msgs::String msg;

                msg.data = "消息内容";

                pub.publish(msg);

                loop_rate.sleep();       //调用sleep形成短暂堵塞,保持设置的频率输出

        }

        return 0;

}

将代码里面可以自定义内容的相关选项进行了加粗操作,在编写自己代码时按功能命名修改,上面就简单实现了发布者的相关代码编写,编写完成后不要忘记保存ctrl+s。

为代码添加编译规则(修改的是对应包的CMakelists.txt文件)

代码编写完成后还需要对编译规则进行配置,打开Cmakelists文件,1 将build章节的最后一行指令复制到文本末尾,2 将specify library 下方的内容同样复制到文件末尾 ,两部分修改完成后Ctrl+S保存。

//add_executeable(自己编辑的节点名 文件的执行路径)

//第一项可执行文件名(尽量和节点名一致,防止错乱)   第二项从那个代码文件编译

add_executeable(节点1    src/节点1.cpp)

//将函数的库文件链接,代码不要遗漏

target_link_libraries(节点1

        ${catkin_LIBRARIES}

)

Ctrl+shift+B 编译(或者终端执行catkin_make),编译完成后可以尝试运行该节点。

打开终端先启动        roscore

再打开终端将程序送进终端         source ~/自定义工作空间名工作空间/devdl/setup.bash

再打开终端        rosrun 自定义ROS包名 节点1

经过上文的操作就已经完成发布者的节点实现

通过终端开启命令,第一个终端执行roscore,第二个终端执行rosrun bao1 node_pub1

第三个终端执行rostopic list列出目前运行的话题,使用rostopic echo /topic1,查看话题内容。英文的字符串不会存在看不明白输出内容是什么这种问题

第四个终端echo -e 复制第三个终端双引号里面的内容进行解析,可以看到实际内容。


5 创建订阅者

订阅者的实现跟发布者类似,因为节点不能单独存在,所以按照上文的流程在一级src目录下创建软件包再创建发布者节点,也可以在之前的软件包中创建新节点。

在工作空间打开终端执行catkin_make

 第一个终端启动roscore,第二个终端rosrun bao1 node_pub1 启动发布者节点1

第三个终端rosrun bao2 node_sub1 启动订阅者节点1

成功接收到发布者节点1的msg消息。

#include<ros/ros.h>

#include<std_msgs/String.h>

//发布者的消息类型

void hui(std_msgs::String msg)

{

//msg的data内容

printf(msg.data.c_str());

}

int main(int argc, char *argv[])

{

        ros::init(argc,argv,"节点1");

        //实例化句柄

        ros::NodeHandle nh;

        /*用上面实例的句柄实现订阅操作,()里面三个参数, 第一个是订阅的话题名称,

        第二个是最大缓存的消息数目,第三个是回调函数名*/

       ros::Subscriber sub = nh.subscribe("话题名",10,回调函数名);

        //保持节点运行

        while(ros::ok())

        {

                //新来的消息包内容能够被回调函数接收

                 ros::spinOnce();

        }

        return 0;

}

代码的编写完成后Ctrl+S保存,再仿照发布者节点在Cmakelists文件添加编译规则,Ctrl+S保存,Ctrl+shift+B编译。

回调函数中用到data,是因为string消息类型有data,所以在上文.data


到目前为止我们就完成了发布者-订阅者消息通信,发布的消息相关内容可通过下列指令实现

rostopic list                           列出当前系统中所有活跃的话题

rostopic echo 主题名称        显示指定话题中发送的消息包内容

rostopic hz 主题名称            统计指定话题中消息包的发送频率

通过上文的操作我新建2个发布者,1个订阅者来接受这两个发布者的消息,在之前接受的消息里,不知道是一直在发送还是终止了,将回调函数的printf改为ROS_INFO,并在ros::init上方加上setlocale(LC_ALL,"") ,这样接受到的消息将会是准确的信息。

 订阅2个发布者

两个订阅者不能重名


小技巧

 新建的工作空间目录就将下方的设置重新来一遍

1 避免每次都source

在上文运行节点时,如果没有source那条指令,将会出现错误,为了避免每次执行前都执行该指令可以将这条语句写进.bashrc里面,后面再运行节点就可以省略这个语句,需要安装VScode。

code ~/.bashrc (或者gedit ~/.bashrc)

将下面的指令添加到文件末尾

source ~/自定义工作空间名/devel/setup.bash

2 字符等可以使用中文输出

在ros::init的前一行加上

setlocale(LC_ALL,"zh_CN.UTF-8")        //英文版Ubuntu

setlocale(LC_ALL,"")                              //中文版Ubuntu

3 VScode工作空间设置

在VScode中将第一级src目录当根目录导入,后续的具体工程将不会放错src文件夹

操作流程:file——add folder to workspace——主目录———自定义工作空间名—src

4 超级终端

系统自带的终端每次只能执行一个指令,需要多次重复打开,下载terminator更便捷

sudo apt install terminator

常用操作:

Ctrl+shift+E横向分屏         Ctrl+shift+O纵向分屏        Ctrl+shift+W取消分屏

alt+方向键 移动焦点

横向分屏Ctrl+shift+E无法使用:

ibus-setup打开输入法标签窗口,选择表情符号一栏,将表情符号的快捷键修改

5 VScode相关插件安装

 中文显示

点击左侧的几个小方块,在搜索栏输入chinese点击下载就可以将vscode设置为中文

 ros工具

对vscode的一些设置功能进行扩充,添加一些ros专用的菜单项,并且代码提示和拼写检查都会加入ros的编程接口。

cmake插件

在没安装这个插件前,创建的Camkelists.txt文件编译器不认识。安装的是Cmake tools,安装完这个之后Cmake会自动安装。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值