ROS速成之发送&接收消息

2023-05-16

人真的老了,扔了个周末,完全不记得干了什么...论纪录的重要性啊,当时觉得明白的很,你扔两天试试?扔一年试试?扔几年试试?

最近参加的各种项目脑疼眼乏,一天要同时推进三个项目,且都是技术一线,各项目之间相关性不强,往往是第一个项目上午干了记录下,下午又投入到第二个项目中去,纪录完了后晚上又投入第三个项目,这样将整段时间投入,尽量保证工作进度。因为如此的工作模式,而且也只能这样的工作模式,纪录就非常重要,可以迅速让你脱离当前项目,也可以迅速进入下一个项目快速回忆起上次进度,对于专注度是非常有用的。因此,内心充分认识到了文档的重要性。

从百度RAL首席杨老师那里也知道,中国制造和德国制造的差距——文档!现在的急功近利让人总是沉迷于快点完成任务,快点出产品,快点升级迭代;然而,大大忽视了文档的重要性。为什么一些经典的软件比如matlab,arcgis等等以及一些系统比如ROS,都是国外的?除了技术好,文档完善是其得以广泛应用和传播非常重要的因素!

最近速度看了下ROS的wiki文档,初级教程有中文的还不错,非常详细,很贴心的站到了初学者的角度,很多连环境变量等问题都解释了,这正是令很多初学者困惑的地方。我觉得这个文档非常棒!更新能做的更好就好了。

言归正传,老人还是得重视纪录....

概述:有一个运动平台作为主节点,我的视觉模块负责拍摄识别,将识别得到的障碍物发送给主平台,好指导其下一步行进路线。主平台订阅我的topic,然后我在这个topic上发送识别结果消息(message),然后主平台可以接收。

1. 基础工作

安装非常简单,请见wiki文档:http://wiki.ros.org/cn/ROS/Tutorials

以及:https://blog.csdn.net/okasy/article/details/79448623

sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.ustc.edu.cn/ros/ubuntu/ $DISTRIB_CODENAME main" > /etc/apt/sources.list.d/ros-latest.list'
sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 0xB01FA116^C
sudo apt-get update
sudo apt-get install ros-kinetic-desktop-full
sudo rosdep init
rosdep update
//以上完成了安装

//将启动设置写到系统的.bashrc文件里(位于当前系统用户的home目录下,为隐藏文件)。这样当你每次登录后系统已经帮你执行这些命令配置好环境
echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc 
source ~/.bashrc

//
sudo apt-get install python-rosinstall
export | grep ROS
export | grep python

以上安装完成。下面创建工作空间。

打开终端,记为终端1,创建catkin工作空间:

mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
pwd
//下面两句初次创建工作空间采用,第一句用于生成cmakelist
catkin_init_workspace
catkin_make

以上我们创建了一个名字叫做catkin_ws的工作空间,创建好了,可以进行后续工作了。ROS的东西都装在computer/opt目录下。上面创建的工作空间则在home路径下,用pwd命令可以查看到当前路径。

cd到工作空间路径下,进行初始化:

roscore

ROS就开始运转了。想要结束运转,ctrl+C这个终端,就ok了。

工作空间你可以类比matlab想象为一个大文件夹,可以在这个大文件夹下,建立一系列小文件夹,也就是程序包;matlab在运行这些小文件夹下的程序是,需要首先将工作路径切换到这个大文件下,或者将这个大文件夹地址写到PATH里面,类比ROS也是一样的,我们建立的这个工作空间catkin_ws,在下面自己写了很多包,如果让ROS的系统路径能包含它,有两种方法,一种是每次都source一下devel下面的setup.bash文件,另一中方法就是写到系统环境变量里面。否则下次ROS就找不到这个工作空间里的任何包了。下面是两种方法:

//方法1:每次source工作空间下的devel文件夹下面的setup.bash文件:
source ~/catkin_ws/devel/setup.bash

//方法2:将其写到系统环境变量里面:
echo “source ~/catkin_ws/devel/setup.bash” >> ~/.bashrc
source ~/.bashrc
//上面是代码添加,也可以自己手动添加

如何查看是否能识别了:

//方法1:查看ROS_PACKAGE_PATH变量是否包含我们创建工作空间下面的包路径:
 echo $ROS_PACKAGE_PATH

//方法2:直接查看包或者包下面的文件如msg
rospack find beginner_tutorials
rosmsg type v_m.msg

2. 创建程序包和message

概述:首先创建程序包,然后在其下建立msg文件夹,然后写需要的消息文档,然后设置路径等,然后build程序包,让ROS可以找到你写的这些msg。

2.1 创建程序包

在ROS非运转状态下(要不然创建完了不认,应该是因为正在运转被占用所以向相关文件写不入路径的原因,这些文件可能是:/home/y/catkin_ws/build下面的cmake_install.cmake和Makefile,待验证)。因此如果ROS正在运转,先Ctrl+C关闭,然后用下面代码创建程序包beginner_tutorials。我们先让它依赖后面这三个文件。

cd ~/catkin_ws/src
catkin_create_pkg beginner_tutorials std_msgs rospy roscpp

首先创建程序包beginner_tutorials,

用rospack list命令查看是否我们创建的程序包可以被ROS识别了。(如果在ROS运转状态下用另一个终端创建程序包,不管结束ROS与否,用这个命令都看不到新创建的这个程序包)。

可以用下面两个命令来分别查看这个程序包的一级依赖关系,所有依赖关系。

rospack depends1 beginner_tutorials
rospack depends beginner_tutorials

到工作空间路径下,编译:

cd ~/catkin_ws
catkin_make

可以看到在build和devel文件夹下会生成有关这个程序包的文件。

2.2 创建程序包下消息文件

根据wiki文档的说明:msg文件存放在package的msg目录下,srv文件则存放在srv目录下。

其实可以创建一个程序包专门用来放消息文件,参见ROS自己的std_msgs就是这种。

alright,lets start! 我们跟文档一致,一是为了规范,二是初学为了方便设置。

在/home/y/catkin_ws/src/beginner_tutorials路径下,建立msg文件夹,创建了三个消息文件:

t_d_m, v_i_m, v_m

在/home/y/catkin_ws/src/beginner_tutorials下面的package.xml文件里,加入下面两句话(注意此处与官方文档不同,官方的为旧版,kinetic应采用以下的语句):

//build 依赖。下面两句任选其1均可,也可以都写上 
 <build_depend>message_generation</build_depend>
 <build_export_depend>message_generation</build_export_depend>

//执行依赖,必须加上以下这句:
 <exec_depend>message_runtime</exec_depend>

打开/home/y/catkin_ws/src/beginner_tutorials下面的CMakeLists.txt,在find_packages里面添加message_generation,添加完了后应该为:

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
)

然后找到如下代码块(默认被注释掉了,放开注释),修改后如下:

## Generate messages in the 'msg' folder
add_message_files(
   FILES
   t_d_m.msg
   v_i_m.msg
   v_m.msg
)

然后找到下面的代码块添加如下(不需要添加我们新写的msg,因为这个是当前包的依赖,我们的msg就位于当前包中。ps:std_msgs是程序包名称)(注意此处和中文wiki教程不同,中文的不知为什么这里括号里面是空的,但看英文版里面是如下内容。事实证明英文版正确):

generate_messages(
   DEPENDENCIES
   std_msgs
 )

使用rosmsg查看ROS是否可以识别我们新添加的消息(不需要重新catkin_make就可以查看得到):

rosmsg show beginner_tutorials/t_d_m

添加了新的消息如果需要被使用,是需要生成一系列文件,即被ROS所支持语言的源代码。因此需要重新编译工作空间:

catkin_make

注意:如果出现了 “The specified base path "/home/y/catkin_ws" contains a CMakeLists.txt but "catkin_make" must be invoked in the root of workspace” 这个错误。是因为catkin_init_workspacce的时候,出现下面这句:Creating symlink “/home/y/catkin_ws/CMakeLists.txt” pointing to “/opt/ros/indigo/share/catkin/cmake/toplevel.cmake”, 将当前工作空间下的CMakeLists.txt与/ros/下的cmake做了链接。解决方法是输入如下语句(参考:https://blog.csdn.net/u013294888/article/details/69696956):

unlink /home/ubuntu/catkin_ws/CMakeLists.txt 

然后在catkin_make就成功了。

所有在msg路径下的.msg文件都将转换为ROS所支持语言的源代码(部分参考:https://blog.csdn.net/wxz3wxz/article/details/71088098):

生成的C++头文件将会放置在~/catkin_ws/devel/include/beginner_tutorials/
Python脚本语言会在~/catkin_ws/devel/lib/python2.7/dist-packages/beginner_tutorials/msg目录下创建
lisp文件会出现在~/catkin_ws/devel/share/common-lisp/ros/beginner_tutorials/msg/路径下。
java文件会出现在/home/yexin/catkin_ws/devel/share/gennodejs/ros/beginner_tutorials/msg/路径下。
EusLips文件貌似出现在:/home/yexin/catkin_ws/devel/share/roseus/ros/beginner_tutorials/msg/路径下。

这样就可以在代码中使用我们自己定义的msg了。

3. 编写发布器和接收器节点们

发布器和接收器为两个节点,其实是两个可执行文件。我主要写发布,主节点来接收,因此实际上我不用管接收节点。但是为了自我测试我们的发布是否成功,写一个简单的接收器节点也是很必要的。这里主要参考了ROS的wiki帮助以及一些博客:

http://wiki.ros.org/cn/ROS/Tutorials/WritingPublisherSubscriber%28c%2B%2B%29

http://wiki.ros.org/cn/ROS/Tutorials/ExaminingPublisherSubscriber

https://blog.csdn.net/kokerf/article/details/51811835

https://blog.csdn.net/heyijia0327/article/details/41654963

http://wiki.ros.org/navigation/Tutorials/RobotSetup/Sensors

在写发布和接收之前,先说下,我自己写的message叫做v_m.msg,按照上面第2节的方法生成其h文件。我们用rosmsg show v_m看下是这样的:

y@y-Precision-Tower-7910:~$ rosmsg show v_m
[beginner_tutorials/v_m]:
std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
int8 tT
uint32 n
int64[] tA
float64[] iA

根据这个消息格式,现在我们建立发布器,在发布器内部命名一个topic,在该topic下发送该格式的message。

3.1 发布器节点及测试

在catkin_ws/src/beginner_tutorials文件夹下,有一个src文件夹,在这个文件夹下面建立一个cpp文件,叫做talker.cpp,即创立发布器节点并确定topic和发送消息,内容如下:

#include "ros/ros.h"
#include <beginner_tutorials/v_m.h>

int main(int argc, char **argv)
{
    ros::init(argc,argv, "beginner_tutorials");
    ros::NodeHandle n;
    //topic的名称为chatter,1000为缓冲区,缓冲区中的消息在大于 1000 个的时候就会开始丢弃先前发布的消息。 
    ros::Publisher chatter = n.advertise<beginner_tutorials::v_m>("chatter",1000);
    ros::Rate loop_rate(10); //发布频率为10FPS

    while(n.ok())
    {
        beginner_tutorials::v_m msg;
        //给消息里的变量赋值
        msg.tT = 1;
        msg.n = 2;
        msg.tA.resize(2);
        msg.iA.resize(2*4);
        for (int i = 0;i<msg.n;i++)
        {
            msg.tA[i] = i;
            msg.iA[i*4] = msg.iA[i*4+1] = msg.iA[i*4+2] = msg.iA[i*4+3] = 1.1*i;
        }
        //不能以以下方式放入[],会报错
        // msg.tA = {1,1};
        // msg.iA = {1.0,1.1,1.2,1.3,2.0,2.1,2.2,2.3,2.4};

        //发布消息
        chatter.publish(msg);
        ros::spinOnce(); //可用回调函数
        loop_rate.sleep();//休眠一段时间以使得发布频率为 10Hz。
    }
    return 0;
}

然后将以下几句,放在/home/y/catkin_ws/src/beginner_tutorials下面的CMakeLists.txt最后几行:

add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
//下面这一行可以不用加
add_dependencies(talker beginner_tutorials_generate_messages_cpp)

然后在catkin_ws路径下,输入catkin_make编译,可以看到在devel的lib下面有了一个talker执行文件。

我们先用终端来测试下:

打开终端1,输入roscore启动ros环境;

打开终端2,输入rosrun beginner_tutorials talker,启动了发布器,

打开终端3,输入rostopic list,可以看到已经列出了我们发布的chatter,

继续在终端3输入:rostopic echo /chatter

就可看到实时发送的消息内容了。

3.2 接收器节点及测试

我们再编写一个接收器节点,叫做listener。在catkin_ws/src/beginner_tutorials/src文件夹下,创建listener.cpp,内容如下:

#include "ros/ros.h"
#include <beginner_tutorials/v_m.h>

//回调函数,简单来说就是收到了这个消息,就做出什么反应在这里面定义。这里是打印一行东西
void chatterCallback(const beginner_tutorials::v_m::ConstPtr & msg)
{
    ROS_INFO("I heard: [%d]", msg->n);  
}

int main(int argc, char **argv)
{
    ros::init(argc,argv,"listener");
    ros::NodeHandle n;
    //订阅了“chatter”这个topic
    ros::Subscriber sub = n.subscribe("chatter",1000, chatterCallback);
    ros::spin();
    return 0;
}

然后将以下几句,放在/home/y/catkin_ws/src/beginner_tutorials下面的CMakeLists.txt最后几行:

add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener beginner_tutorials_generate_messages1_cpp)

该程序包的完整CMakeLists.txt里面的内容是这样的:

cmake_minimum_required(VERSION 2.8.3)
project(beginner_tutorials)

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
)

add_message_files(
   FILES
   v_m.msg
)

generate_messages(
   DEPENDENCIES
   std_msgs
)

catkin_package(
   CATKIN_DEPENDS message_runtime
)
include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)

${catkin_EXPORTED_TARGETS})

${catkin_EXPORTED_TARGETS})

add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
add_dependencies(talker beginner_tutorials_generate_messages_cpp)

add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener beginner_tutorials_generate_messages1_cpp)

然后在工作空间下catkin_make编译ok后,就可以测试了。

打开新终端1,roscore

打开新终端2,rosrun beginner_tutorials talker

打开新终端3, rosrun beginner_tutorials listener,可以看到打印的接收到消息的回应了。

思考:如果我用了外部(非工作空间内)的识别程序,怎么把数据实时传给这个talker节点呢?

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ROS速成之发送&接收消息 的相关文章

  • “段寄存器”的故事

    一 段寄存器的产生 段寄存器的产生源于Intel 8086 CPU体系结构中数据总线与地址总线的宽度不一致 数据总线的宽度 xff0c 也即是ALU 算数逻辑单元 的宽度 xff0c 平常说一个CPU是 16位 或者 32位 指的就是这个

随机推荐

  • 阿里面试官:为什么MySQL数据库索引选择使用B+树而不是跳表?

    来源 xff1a https www cnblogs com andydao p 12891690 html 作者 xff1a andydaopeng 在进一步分析为什么MySQL数据库索引选择使用B 43 树之前 xff0c 我相信很多小
  • AD生成bom表

    1 Report Bill of material 2 可通过点击右侧的Columns xff0c 更改导出属性 3 点击Preview 查看生成的excel文件 4 生成的 excel文件 注 xff1a 出bom表的原理图需要在工程里
  • 你对Linux下的实时性应该多点了解

    本文讲述一些有利于提高xenomai实时性的配置建议 xff0c 部分针对X86架构 xff0c 但它们的底层原理相通 xff0c 同样适用于其他CPU架构和系统 xff0c 希望对你有用 一 前言 1 什么是实时 实时 一词在许多应用领域
  • HTTP/3.0 ,它来了!

    HTTP 3 0 是 HTTP 协议的第三个主要版本 xff0c 前两个分别是 HTTP 1 0 和 HTTP 2 0 xff0c 但其实 HTTP 1 1 我认为才是真正的 HTTP 1 0 我们大家知道 xff0c HTTP 是应用层协
  • 简单聊聊从 nginx 到 kong 的进化

    在我们的传统业务中 xff0c Nginx 在七层网关场景中应用得很广 但是最近几年由于微服务的盛行 Nginx 上的这套生态链也在不断地进化 2007 年国人章亦春大神在 Nginx 的基础上开发出了 OpenResty 2009 年 m
  • golang中的缓存一致性、内存序、内存屏障与CAS原理

    CPU缓存架构 现代处理器一般是多核架构 xff0c 并且为了平衡CPU和内存的速度差距 xff0c 还引入了多级Cache CPU Cache 是由很多个 Cache Line 组成 xff0c 每个Cache Line大小为64KB C
  • HashMap与红黑树

    一 为什么需要HashMap 在我们写程序的时候经常会遇到数据检索等操作 xff0c 对于几百个数据的小程序而言 xff0c 数据的存储方式或是检索策略没有太大影响 xff0c 但对于大数据 xff0c 效率就会差很远 1 线性检索 xff
  • docker执行报错:no such file or directory: unknown

    在linux下编译的golang程序放到docker的busybox镜像里无法执行 xff0c 显示报错信息 xff1a exec No such file or directory 在Docker化的今天 xff0c 我们经常需要静态编译
  • 香烟价格

    上海地区报价 欢迎补漏 改错 有的价格过高或偏底是地域不同 品名 产地 批发 零售 白沙 xff08 硬盒 xff09 长沙卷烟厂 42 00 4 50 白沙 xff08 软盒 xff09 长沙卷烟厂 37 00 4 00 芙蓉 xff08
  • java关键字Transient

    Java的serialization提供了一种持久化对象实例的机制 当持久化对象时 xff0c 可能有一个特殊的对象数据成员 xff0c 我们不想用serialization机制来保存它 为了在一个特定对象的一个域上关闭serializat
  • 拨打国际电话的国际字冠和国家代码

    中国 字冠 代码 中国大陆 00 86 中国香港 001 852 中国澳门 01 853 中国台湾 002 886 其它国家或地区 序号 国家 国际字冠 国家代码 1 美国 011 1 2 加拿大 011 1 3 智利 0 56 4 秘鲁
  • VirtualBox Host-Only 连接设置

    1 VirtualBox连接方式选择 xff1a Host Only 在宿主机windows上会自动新建连接 xff1a VirtualBox Host Only Network 2 启用宿主机windows的连接共享 xff0c 此时Vi
  • 基于HHARM9-EDU的TCP/IP(UDP)协议的实现

    基于HHARM9 EDU的TCP IP UDP 协议的实现 摘 要 xff1a 嵌入式技术的发展日新月异 xff0c 现如今 xff0c 嵌入式设备已经广泛应用于各种网络 xff0c 本文简要地说明一下如何实现 PC 与 HHARM9 ED
  • 简单的linux c socket例子

    服务端代码 xff1a span style color 000000 span style color 0000cc span span style color ff0000 include span span style color 0
  • Mask R-CNN图像识别和分割实现步骤(二)

    一 搭建环境 xff08 widdows10 xff09 xff08 一 xff09 安装anaconda3 1 下载地址 xff1a Anaconda Individual Edition 2 安装步骤 xff1a 图上双击 xff0c
  • C++ STL

    C 43 43 STL vector 变长数组 xff0c 倍增的思想 size 返回元素个数 empty 返回是否为空 clear 清空 front back push back pop back begin end 支持比较运算 xff
  • 结构体对齐规则

    结构体对齐规则 xff1a 1 第一个成员在于结构体变量偏移量为0的地址处 2 其他成员变量要对齐到某个数字 xff08 对齐数 xff09 的整数倍的地址处 对齐数 61 编译器默认的一个对齐数 与 该成员大小的 较小值 3 结构体总大小
  • 串口通信数据位长度对传输数据的影响

    针对串口通信 xff0c 关于设置数据位长度对通信的影响 xff0c 如图 xff1a 在串口数据通信中 xff0c 会看到串口参数设置 其中 数据位 设置 xff0c 共有四档选项 xff0c 分别是8 7 6 5 那么改变这个参数会对数
  • 建议收藏丨你想了解的动捕内容全在这儿!

    导语 对于第一次听说动作捕捉的大多数人而言 xff0c 动作捕捉听起来是一个 34 高级 34 同时 摸不清门路 的词汇 它作为虚拟与现实的沟通桥梁 xff0c 被应用于科学研究 影视制作 虚拟主播 体育运动 步态分析等广泛领域 xff0c
  • ROS速成之发送&接收消息

    人真的老了 xff0c 扔了个周末 xff0c 完全不记得干了什么 论纪录的重要性啊 xff0c 当时觉得明白的很 xff0c 你扔两天试试 xff1f 扔一年试试 xff1f 扔几年试试 xff1f 最近参加的各种项目脑疼眼乏 xff0c