网上博彩论坛
你的位置:网上博彩论坛 > 博彩问答 >

博彩平台 我的ROS入门教程(一)

博彩平台 我的ROS入门教程(一)

前言
于2021年6月17日
最近学的东西比较杂、也比较散乱,感觉这么学下去不是个办法,于是萌生了把最近的学习经历记录一下的想法,主要包括ROS安装和ROS入门学习两大部分。
作为一个本科学了4年车辆工程的研究生,刚刚接触ROS,体验非常不好。一是ROS要在Linux系统中运行,在习惯了windows的图形化操作后,一下子转到Linux很不适应。二是缺乏编程基础,再加上ROS本身的架构需要消化一段时间,就更加提高了ROS的学习难度。
最初学习ROS是通过黑马无人小车的配套视频,这套视频大概有七八十个小时。由于当时啥也不会,既要补充python基础知识,又要快速地看完视频,了解无人小车的大概,因此学完之后感觉并没有掌握什么东西。再之后学习ROS是通过古月居的ROS入门21讲,配合着几本介绍ROS的书籍,其中就包括古月(胡春旭)自己编写的《ROS机器人开发实践》。但是学习体验也比较差,主要问题是一些奇奇怪怪的bug,例如python版本差异导致某些demo无法运行。
在一度放弃学习ROS的同时,我在捣鼓用于硕士课题的simulink模型。诚然,matlab很方便很好用,但是在多轴车辆这一小众领域却十分捉襟见肘。方便好用的前提是很多东西都已经由matlab官方封装好了,拿来就可以用,但这也同时意味着封闭性。拿可视化仿真来说,simulink本身提供两轴、三轴的车辆模型,既可以2D可视化,又可以结合虚幻4引擎实现3D可视化(高版本matlab)。另外,simulink也可以与其他仿真软件联合使用,如CarSim、TruckSim等,在这类成熟的商业软件平台上,需要考虑的仅仅是算法功能的实现。而对于我的课题而言,研究对象是六轴车辆,没有任何商业软件能够提供这种可视化模型。最开始为了实现可视化,费了很多工夫在Adams中搭建了一个六轴车辆模型。但Adams本身作为一款基于结构的动力学仿真软件,一是仿真速度极慢,二是整车模型搭建极为繁琐,非常容易出现各种各样奇奇怪怪的bug,完全不具备用于自动驾驶研究的条件。因此,我的目光转向了市面上的各类自动驾驶仿真平台,其中国内应用最多的应该是百度的Apollo平台。而Apollo平台本身就是基于ROS开发的。再包括国外的Autoware平台,也是基于ROS开发的。当然,Apollo平台和Autoware平台都针对ROS本身存在的一些问题进行了优化。换句话说,掌握了ROS,也就意味着在很大程度上掌握了市面上大部分的自动驾驶仿真平台。目前ROS 1存在无法构建多机器人系统、只能在Linux下使用、实时性差、稳定性差等问题,随着ROS 2版本的更迭,实时性、跨平台等问题也会随之解决。实时性、稳定性等问题一经解决,就意味着基于ROS 2的自动驾驶仿真平台有可能实现原型机的工程落地。而跨平台问题解决之后,用户就可以直接在windows下使用ROS,这在相当程度上降低了学习难度和学习成本。
1 ROS安装步骤
1.1 下载Ubuntu镜像文件
由于ROS 1需要跑在Linux系统上,因此首先需要在电脑上安装Linux系统。目前对ROS支持最好的Linux系统是Ubuntu。安装的方法主要有两种:1)双系统;2)虚拟机。在前期的学习中,很可能因为误操作导致系统出现奇奇怪怪的bug,因此先选择在虚拟机中安装Ubuntu的方法。
每一代ROS都有与之对应的Ubuntu版本。目前在ROS官网上主要存在3个版本的ROS,最新的是ROS 2,但由于ROS 2目前还在发展,网络上教程也很少,因此需要从另外两个版本中选择。其余两个版本都是ROS 1,其中noetic版本作为最后一代ROS 1,使用的人数比较少,因此选择安装melodic版本的ROS 1即可。
在ROS melodic安装介绍页面上面,点击documentation,在Software中找到Distributions,点击进入后,下拉在Distribution Details中找到Target Platforms(REP 3),点击进入。在Contents中点击Melodic Morenia(May 2018 – May 2023),页面自动跳转至melodic版本ROS所支持的Linux系统版本。可以看到melodic版本支持Ubuntu 17.10和Ubuntu 18.04。
Ubuntu的偶数版本号是长期支持版,因此选择安装Ubuntu 18.04即可。搜索并打开Ubuntu官方下载页面,下载Ubuntu 18.04.5 LTS(Long Term Support, 长期支持版)博彩平台,下载完成后会得到一个约2 GB的.iso文件。
1.2 安装虚拟机
安装虚拟机VMware Workstation。安装完成后打开VMware,创建新的虚拟机即可,镜像文件选择刚才下载得到的.iso文件,用户名等可自行设置,语言一定要选择英语。内存、处理器、硬盘等可根据自己的电脑配置进行调整。一般来说,内存不要超过物理内存的一半,硬盘约50 GB即可满足使用。
注:我刚开始选的20GB,后来因为装的软件比较多,硬盘满了。之后我在虚拟机中把硬盘扩大到50GB,但仍然提示我硬盘空间快满了。查了一下才知道,在虚拟机中分配硬盘空间后,还需要到Ubuntu中再进行分区操作。linux系统本身提供分区命令行,但是比较繁琐。百度了一下,可以安装gparted,键入
sudo apt-get install gparted 采用该软件可以非常容易地扩展Ubuntu虚拟机硬盘空间。
虚拟机装完之后,即可打开。首先点击左下角,找到并打开Software Updates,在Download from中选择others,在China中选择一个源,例如清华的源或者中科大的源。这一步是为了提高软件的下载速度。刚才安装选择英语的原因是,在命令行中经常需要键入文件目录,如果选择中文,文件目录默认是汉语,这会产生很多问题,例如切换目录繁琐、某些软件不识别中文路径等。但是依然可以将Ubuntu语言设置为简体中文,首先在右上角打开设置,在左侧找到Region Language,点击Manager Installed Language,首次打开时会自动更新。更新完成后,点击进入Install/Remove Languages,找到并添加Chinese(Simplified),等待下载完成后,记得将汉语(中国)拖到最上方。关机重启,界面变为简体中文。这里需要注意,重启进入桌面后,会弹出窗口,是否要将原文件夹名称变更到当前语言,这里一定要选择“保留旧的名称”,并勾选“不要再次询问我”。这样操作完成后,我们就可以在汉化界面下使用英文路径了。
这里额外提一下如何设置中文输入法。如果对输入法没什么要求,可以使用Ubuntu自带的输入法。打开设置,在区域和语言中,点击输入源左下角的+,选择汉语,并添加汉语(Intelligent Pinyin)。通过win+空格即可切换输入法。注:切换输入法的快捷键可能跟windows下的输入法切换设置有关系。 ​ 我用了一会后感觉自带的输入法太卡了,还是决定重新安装一个搜狗。
Ubuntu自带的火狐是英文版,没找到汉化方法。卸载然后重新安装,火狐便可自动变为简体中文版。到命令行中键入sudo apt-get remove firefox,即可卸载Ubuntu自带的火狐浏览器。再键入sudo apt install firefox,即可安装Firefox。
1.3 安装ROS
接下来我们就可以开始安装ROS了,其安装方式是通过终端命令行完成的。搜索ROS wiki中文(比其他途径的安装说明靠谱得多),并打开ROS melodic安装介绍页面,按照说明一步步操作即可。这里值得一提的是,平时复制、粘贴的快捷键是Ctrl+C、Ctrl+V,而在终端中复制、粘贴的快捷键是Ctrl+Shift+C、Ctrl+Shift+V。安装ROS的过程比较慢,需要耐心等待。 ​ 遇到一个小坑,中文wiki里,初始化rosdep之前,没有说明要先安装rosdep。首先需要在终端中键入sudo apt install python-rosdep,然后再继续按照介绍完成安装。 ​ 最后,测试ROS是否安装成功。首先打开一个终端,键入roscore,然后回车。再打开一个终端,键入rosrun turtlesim turtlesim_node,按回车之后,出现一只小海龟,证明ROS安装完成。注:tab键可以自动补全,Ctrl+C可以在终端中关闭小海龟。
1.4 安装IDE
在正式开始使用ROS之前,我们还需要做一件事——安装一款IDE(集成开发环境)。这里选择使用CLion,首先到官网下载CLion。采用官网命令行安装(采用命令行安装的好处是可以直接在终端中运行clion,不必再进行额外配置),我这里提示找不到sudo snap,于是先键入sudo apt-get install snapd,再键入sudo apt-get install snapcraft,重新安装snap。键入sudo snap list,敲击回车后出现列表,说明snap安装成功。
注:Ctrl+Alt+T可以快速打开终端。
等待CLion安装完成后,对其进行激活即可使用(你懂的...)。
注:可以通过教育邮箱或者学信网学籍报告获取学生版CLion授权码。
1.5 安装Markdown编辑器
最后再安装Typora,这是一款markdown编辑器,可以用于记录我们的学习心得,排版方便,代码显示清晰。
1.6 保存虚拟机环境
至此,学习ROS的环境和工具基本上准备完成。下面开始正式地学习ROS操作。建议把目前的虚拟机环境单独保存一下,当后续出现各种错误不好解决时,可以重新开始。
2 ROS学习
学习ROS一定要多逛ROS wiki,个人感觉比书、视频或者csdn上的一些东西都要好。
2.1 创建工作空间
与Linux有关的命令可以自行在ROS wiki上学习或直接百度。只需要掌握常用的几个命令就可以了,例如,创建文件,创建文件夹,切换工作目录等。
mkdir -p ~/catkin_ws/src cd ~/catkin_ws/ catkin_make 其中catkin_ws就是我们创建的工作空间的名称,src是放置功能包的文件夹,也就是我们编写的各类源代码文件就是放置在src下,catkin_make则是对创建的工作空间进行编译,具体原理可以不用管。唯一需要注意的是,目前我们的Ubuntu系统中python版本是python 2,而最新的python版本是python 3,如果我们升级到python 3的话,在catkin_make后面要加上一个python 3后缀,具体可以参见ROS wiki。这里为了避免python版本混乱,就不升级python 3了,同时也避免一些基于python 2的demo无法正常运行。
在编译完工作空间之后,需要source一下,来让工作空间中的环境变量生效。
source devel/setup.bash source完之后,仅对本次开启的终端窗口有效。以后每次打开一个终端需要重新source一下,因此下面在终端键入
echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc 这样环境变量就可以在所有终端中有效了。
为确保环境变量已经生效,键入一下命令检查
echo $ROS_PACKAGE_PATH 出现以下命令行,则说明环境变量已经生效
/home/lizh/catkin_ws/src:/opt/ros/melodic/share2.2 创建功能包
功能包一定要创建在工作空间下
cd ~/catkin_ws/src catkin_create_pkg beginner_tutorials std_msgs rospy roscpp 创建完包之后,回到工作空间根目录
cd ~/catkin_ws 进行编译
catkin_make在创建完功能包之后,打开我们的IDE-CLion就可以进行源代码的编写了,但是目前我们尚不清楚ROS平台的机制,还无法动手写代码。
2.3 小海龟
首先我们需要知道的一件事情是,在ROS中,所有的节点都需要通过ROS Master进行管理,节点其实就是进程,只不过在ROS 1中给它起了个名字叫节点。
打开一个终端,键入
roscore 如果没有报错的话,master已经启动起来了。需要注意的是,这个终端窗口不能关闭,关闭这个终端就等于终止了master。
再打开一个终端,键入
rosrun turtlesim turtlesim_node 如果没有出现意外的话,此时界面上应该出现了一只小海龟,这就是ROS的吉祥物。需要注意,每次启动小海龟,小海龟的样子都不一样,这是正常现象。
再开一个终端,键入
rosnode list 会出现如下结果
/rosout /turtlesim 先不必理会第一个节点,只需要关注第二个/turtlesim,这就是小海龟这个进程的节点名称。ROS提供了命名重映射功能
关闭之前的小海龟,重新键入
rosrun turtlesim turtlesim_node __name:=my_turtle 再次查看节点,会显示
/my_turtle /rosout /turtlesim /my_turtle的出现,说明我们成功使用了命名重映射功能,改变了小海龟节点的名称。但是我们还发现,之前的/turtlesim并没有消失,但明明我们已经关闭了刚才的第一只小海龟。这是ROS中节点的“假死”现象,即节点虽然已经关闭了,但是仍然能被搜索到,需要采用一下命令进行清理 rosnode cleanup 发现假死节点后,会提示是否继续,按Y并回车,再次查看节点,假死节点就消失不见了。
通过这个简单的例子,不难理解ROS中的节点所代表的含义。
2.4 话题topic
ROS提供了话题topic作为最主要的通讯机制。
还是通过小海龟来理解topic通讯机制。
首先启动ROS Master,再启动一只小海龟。
再打开一个新终端,键入
rosrun turtlesim turtle_teleop_key 把光标放在这个终端内,通过方向键就可以控制小海龟的运动。
查看当前节点,就可以发现,这个键盘控制也是一个节点。那么这两个节点之间是如何通讯的呢?我们可以通过ROS自带的一些工具来理解这件事。
打开一个新终端,键入
rosrun rqt_graph rqt_graph rqt是ROS自带的一种图形化工具,可以呈现节点之间的通讯关系。按回车之后,会弹出如下界面

这张图说明的是,/teleop_turtle这个节点,通过/turtle1/cmd_vel这个话题,来实现了对/turtlesim节点的控制。这么说其实不太准确,更准确的说法是,/teleop_turtle这个节点将按下的方向键信息发布到/turtle1/cmd_vel这个话题,而/turtlesim节点订阅了/turtle1/cmd_vel这个话题。topic本质上是一种异步通讯,也就是说发布消息的节点并不在乎有没有其他节点接收到它发布的消息,而订阅消息的节点也同样不在乎接收到的消息来自于哪个节点。
同样的,我们可以键入如下命令,来查看当前存在的话题名称
rostopic list 可以通过如下命令,查看话题类型
rostopic type /turtle1/cmd_vel 结果显示
geometry_msgs/Twist 这个类型似乎跟我们预期的不太一样,看起来很奇怪。这其实是ROS自带的一种标准消息类型,有点类似于C语言中的结构体。通过一下命令,可以查看这个消息类型的具体形式
rosmsg show geometry_msgs/Twist 结果显示如下
geometry_msgs/Vector3 linear float64 x float64 y float64 z geometry_msgs/Vector3 angular float64 x float64 y float64 z 不难理解,这个消息类型其实定义的就是三个平动和三个转动。ROS还有很多标准格式的消息,当这些标准格式都不满足使用需求时,我们还可以自定义消息类型。
2.5 发送pub
了解了topic通讯机制后,不难理解,其实按下方向键就是发送了一些消息给指定的话题,那么不通过方向键而是直接发送消息给话题,可以实现小海龟的运动吗?显然是可以的,下面就让我们进行尝试。
运行roscore,再启动一只小海龟。再打开一个新终端,键入以下命令
rostopic pub /turtle1/cmd_vel geometry_msgs/Twist "linear: x: 0.0 y: 0.0 z: 0.0 angular: x: 0.0 y: 0.0 z: 2.0" 回车之后,会发现小乌龟原地转了一下,这说明我们发送的信息已经被小海龟接收到了。
如果我们想让小乌龟一直运动,就需要以固定频率发送消息,即
rostopic pub -r 1 /turtle1/cmd_vel geometry_msgs/Twist "linear: x: 0.0 y: 0.0 z: 0.0 angular: x: 0.0 y: 0.0 z: 2.0" 大家可能会觉得这种命令行输入的方式非常繁琐,效率不高。为此,ROS的rqt工具箱也提供了图形化的消息发送工具。
键入如下命令
rosrun rqt_publisher rqt_publisher 在弹出窗口中,选择对应topic和消息类型,设置发送频率,点击+即可。在下方窗口中,勾选刚刚创建的消息,消息就开始以设定频率发送到指定话题。
2.6 服务service
很多时候,我们并不强调数据之间的频繁交换,而是更注重数据之间的同步性。因此,ROS提供了service通讯机制。通讯的两方中,一方作为客户端,向服务端发送请求,而另一方的服务端收到请求后,就会进行数据处理,然后发送回应给客户端。例如,客户端发了2个数字给服务端,服务端根据接收到的数据,进行求和运算,并将结果返回给客户端。
以小海龟为例,启动roscore,启动一只小海龟,在新的终端里键入
rosservice call /spawn "x: 1.0 y: 0.0 theta: 0.0 name: ''" name: "turtle2"/> /> </launch> 在编写代码的时候需要注意,我们可以先将这个文件的后缀改为.xml,这样的好处是写代码时有自动代码补全,写完之后再将其后缀改回.launch。
新开一个终端,键入
roslaunch beginner_tutorials turtle_ctrl.launch 可以发现一只小海龟启动了起来,同时我们可以通过方向键控制小海龟的运动。此外,我们不需要单独启动roscore。
这就是一个非常简单的launch文件的实现,在launch文件中还有更多的格式、参数等可以定义,后面用到再具体学习。
2.9 自定义消息
在ROS中,话题通讯机制和服务通讯机制所用的消息类型是不同的,前者消息类型的后缀是.msg,而后者消息类型的后缀是.srv,下面分别介绍。
注:大部分入门例程是把msg(srv)文件夹建立在含有节点的功能包内的,即当前功能包调用该功能包下的头文件。而这样做其实并不好,当其他功能包需要调用该自定义消息的时候,会同时调用包含该自定义消息的功能包内的其他节点。因此,最好的做法是单独建一个功能包用来存放msg和srv文件夹。
2.9.1 自定义话题消息msg 首先创建一个功能包
cd ~/catkin_ws/src catkin_create_pkg my_msg_srv std_msgs rospy roscpp cd ~/catkin_ws catkin_make 自定义的msg单独保存在msg文件夹下,因此首先创建一个msg文件夹
roscd my_msg_srv mkdir msg cd msg 再创建一个Person_alone.msg
touch Person_alone.msg 需要注意,定义消息类型时,名称尽量首字母大写。
由于msg定义很简单,因此不需要通过IDE编辑,直接双击打开即可。
string name uint8 age msg中的类型格式是ROS独有的,跟编程语言无关,这里仅做简单演示,更多的格式可以再具体了解。
自定义msg的类型是很简单的,比较麻烦的是需要让ROS识别到自定义的msg,因此需要对package.xml和CMakeLists.txt进行修改。
2.9.1.1 修改package.xml 在package.xml中添加如下代码,注意添加的位置,放在<export>之前。
<build_depend>message_generation</build_depend> <exec_depend>message_runtime</exec_depend>2.9.1.2 修改CMakeLists.txt 在find_package中添加message_generation
find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation ) 取消add_message_files的注释,并把刚刚定义的消息文件添加进去
add_message_files( FILES Person_alone.msg ) 取消generate_messages的注释
generate_messages( DEPENDENCIES std_msgs ) 在catkin_package中添加CATKIN_DEPENDS message_runtime
catkin_package( # INCLUDE_DIRS include # LIBRARIES beginner_tutorials CATKIN_DEPENDS roscpp rospy std_msgs message_runtime # DEPENDS system_lib ) 完成以上工作后,编译整个工作空间
cd ~/catkin_ws catkin_make 在终端中键入
rosmsg show beginner_tutorials/Person 回车后,显示如下
string name uint8 age 证明自定义msg成功。
2.9.2 自定义服务消息srv 首先创建一个srv文件夹
roscd my_msg_srv mkdir srv cd srv 再创建一个AddTwoInts_alone.srv
touch AddTwoInts_alone.srv 需要注意,定义消息类型时,名称尽量首字母大写。
直接双击打开,需要注意的是在srv中采用--来分隔请求数据和响应数据,即A、B是客户端发送的数据,而Sum是服务端在接收到请求后返回的数据。
int64 A int64 B --- int64 Sum srv中的类型格式也是ROS独有的,跟编程语言无关,这里仅做简单实例,更多的格式可以再具体了解。
同自定义msg一样,需要让ROS识别到自定义的srv,也需要对package.xml和CMakeLists.txt进行修改。
2.9.2.1 修改package.xml 在package.xml中添加如下代码,注意添加的位置,放在<export>之前。(上一步自定义msg时已完成)
<build_depend>message_generation</build_depend> <exec_depend>message_runtime</exec_depend>2.9.2.2 修改CMakeLists.txt 在find_package中添加message_generation(已完成)
find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation ) 取消add_service_files的注释,并把刚刚定义的消息文件添加进去
add_service_files( FILES AddTwoInts_alone.srv ) 在catkin_package中添加CATKIN_DEPENDS message_runtime(已完成)
catkin_package( # INCLUDE_DIRS include # LIBRARIES beginner_tutorials CATKIN_DEPENDS roscpp rospy std_msgs message_runtime # DEPENDS system_lib ) 完成以上工作后,编译整个工作空间
cd ~/catkin_ws catkin_make 在终端中键入
rossrv show beginner_tutorials/AddTwoInts 回车后,显示如下
int64 A int64 B --- int64 Sum ​ 证明自定义srv成功。
2.10 动手编写发布者节点(C++)
2.8节我们自定义了一个Person_alone.msg,里面包含了姓名和年龄,让我们试着编写C++程序来实现这个消息的发布和订阅吧。
2.10.1 添加编译依赖 打开CLion,在src文件夹下创建一个名为talker.cpp文件。创建完成后,会发现IDE提示“This file does not belong to any project target;code insight features might not work properly”,这是因为我们没有把当前创建的这个cpp文件添加到CMakeLists.txt中。简单讲,就是这个cpp现在还没有办法编译。
为了不让这个恼人的提示一直出现,我们先不着急写代码,先去修改CMakeLists.txt。
首先在find_package中添加刚才自定义消息所在的功能包
find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs my_msg_srv ) 取消add_executable的注释,并将第二个参数修改为cpp文件名
add_executable(talker src/talker.cpp) 取消add_dependencies的注释
add_dependencies(talker my_msg_srv_generate_messages_cpp) 这句代码是为了确保自定义消息my_msg_srv先编译,防止找不到头文件。
取消target_link_libraries的注释
target_link_libraries(talker ${catkin_LIBRARIES} ) 注意到这三条语句的第一个参数都是talker,这个talker其实是真正的节点名称。也就是说我们刚才创建的cpp文件不管叫什么名字,只要我们在CMakeLists中将这三条语句的第一个参数都设为talker,那么编译完成后,就会生成一个名叫talker的节点。
注:将以上三条语句统一添加在最后也可以。
2.10.2 发布者节点代码 这里遇到一个bug,之前自定义的Person_alone.msg已经编译生成,并且可以通过rosmsg查看。然而,Person_alone.h却无法在头文件中引用。经确认,这个头文件确实已经通过编译生成,位于~/catkin_ws/devel/include/beginner_tutorials这个路径下。
结合黑马无人小车的教学视频,其解决方法就是关闭CLion,到工作空间中多次source,然后重新启动CLion。如果不行的话,可以删除工作空间中的devel和build文件夹,然后重新catkin_make,再次source,再次启动CLion,如此反复。
在解决了这个非常闹心的bug之后,我们终于可以开始动手编写代码了。
//引用ROS #include <ros/ros.h> //引用C++中的一些用法 #include <sstream> //引用自定义的消息类型 #include "my_msg_srv/Person_alone.h" ​ //main函数传入的两个参数暂时不用管 int main(int argc, char **argv){ //创建一个名为talker的节点 注意节点名称必须是唯一的 ros::init(argc, argv, "talker"); ​ //创建节点句柄n 可以简单理解为一个节点的控制器 节点的一切操作都可以通过这个句柄完成 ros::NodeHandle n; ​ //创建一个publisher 消息类型为刚才自定义的my_msg_srv::Person_alone 发布到话题person 队列长度为1000 ros::Publisher person_pub = n.advertise<my_msg_srv::Person_alone>("person", 1000); ​ //设置发送频率 单位是Hz ros::Rate loop_rate(10); ​ //开始循环发送 int count = 0; while(ros::ok()){ //创建自定义消息的类 my_msg_srv::Person_alone Person_alone; ​ //创建字符串流 std::stringstream ss; ​ //给ss赋值 ss << "Zhang San " << count; ​ //给要发送的消息赋值 Person_alone.name = ss.str(); Person_alone.age = count; ​ //在终端显示发送的信息 便于观察 ROS_INFO("%s", Person_alone.name.c_str()); ROS_INFO("%d", Person_alone.age); ​ //使用刚才创建的publisher把Person_alone发送出去 person_pub.publish(Person_alone); ​ //阻塞函数(一次) 用来处理节点订阅话题时的回调函数 //该节点没有订阅任何消息 因此这里的spinOnce并非是必要的 但为了程序完整性默认加入该函数 ros::spinOnce(); ​ //根据刚才设置的发送频率进行休眠 loop_rate.sleep(); ​ ++count; } return 0; } 编写完成后,来到工作空间目录下,打开终端进行编译
cd ~/catkin_ws catkin_make 编译正确完成后,就可以通过rosrun运行该节点了,别忘记启动roscore哦。如果忘记启动roscore也不要紧,talker节点会等待roscore启动。
rosrun beginner_tutorials talker 回车后,终端窗口开始滚动显示信息,证明消息已经成功发送。
2.11 动手编写订阅者节点(C++)
刚才我们编写了一个talker节点用来发来我们自定义的消息,现在我们再来编写一个订阅者节点用来接收talker节点发送的消息。
打开CLion,在src文件夹下新建一个listener.cpp文件,同之前的talker.cpp一样,IDE会提示当前文件不属于任何项目,因此我们首先需要添加编译依赖。
2.11.1 添加编译依赖 在CMakeLists.txt最后添加如下代码
add_executable(listener src/listener.cpp) add_dependencies(listener my_msg_srv_generate_messages_cpp) target_link_libraries(listener ${catkin_LIBRARIES} )2.11.2 订阅者节点代码//引用ROS #include <ros/ros.h> //引用自定义消息 #include "my_msg_srv/Person_alone.h" ​ //回调函数 void personCallback(const my_msg_srv::Person_alone::ConstPtr& person_alone){ ROS_INFO("Hello [%s]", person_alone->name.c_str()); } ​ //主函数 int main(int argc, char **argv){ //创建一个名为listener的节点,注意节点名称必须是唯一的 ros::init(argc, argv, "listener"); ​ //创建节点句柄 ros::NodeHandle n; ​ //创建一个subscriber 话题名称必须与刚才的发布者相同 队列长度为1000 第三个参数为回调函数 ros::Subscriber person_sub = n.subscribe("person", 1000, personCallback); ​ //阻塞函数 ros::spin(); ​ return 0; } ​ 跟之前的发布者节点一样,写完之后编译,然后启动roscore和该节点。会发现节点启动了,但是窗口上并没有消息显示。这是因为我们没有启动发布者节点,没有消息发送给话题。因此,再启动刚才的talker节点,很快就能看见订阅者节点成功接收到了消息。
2.12 动手编写客户端节点(C++)
2.8节中我们自定义了一个服务消息,下面让我们通过代码实现这个这个消息的传递。先创建一个client.cpp文件。
2.12.1 添加编译依赖 在CMakeLists.txt最后添加如下代码
add_executable(client src/client.cpp) add_dependencies(client my_msg_srv_generate_messages_cpp) target_link_libraries(client ${catkin_LIBRARIES} )2.12.2 客户端节点代码//引用ROS #include <ros/ros.h> //可能是C标准库 #include <cstdlib> //引用自定义服务类型 #include "my_msg_srv/AddTwoInts_alone.h" ​ int main(int argc, char **argv){ //创建节点 ros::init(argc, argv, "add_two_ints_client"); ​ if (argc != 3){ ROS_INFO("usage: add_two_ints_client X Y"); return 1; } ​ //创建句柄 ros::NodeHandle n; ​ //创建客户端 消息类型为my_msg_srv::AddTwoInts_alone 请求的服务名称为add_two_ints ros::ServiceClient client = n.serviceClient<my_msg_srv::AddTwoInts_alone>("add_two_ints"); ​ //创建自定义服务消息的类 my_msg_srv::AddTwoInts_alone TwoInts; TwoInts.request.A = atoll(argv[1]); TwoInts.request.B = atoll(argv[2]); ​ //服务调用 if (client.call(TwoInts)){ ROS_INFO("Sum: %ld", (long int)TwoInts.response.Sum); } else{ ROS_ERROR("Failed to call service add_two_ints"); return 1; } return 0; } 写完之后编译,通过rosrun运行一下,如果没报错就没问题。等我们写完服务端就可以验证客户端正确与否了。
2.13 动手编写服务端节点(C++)
先创建一个server.cpp文件。
2.13.1 添加编译依赖 在CMakeLists.txt中添加如下代码
add_executable(server src/server.cpp) add_dependencies(server my_msg_srv_generate_messages_cpp) target_link_libraries(server ${catkin_LIBRARIES} )2.13.2 服务端节点代码//引用ROS #include <ros/ros.h> //引用自定义的服务消息 #include "my_msg_srv/AddTwoInts_alone.h" ​ //回调函数 bool add(my_msg_srv::AddTwoInts_aloneRequest &req, my_msg_srv::AddTwoInts_aloneResponse &res){ ​ res.Sum = req.A + req.B; ​ ROS_INFO("request: x=%ld, y=%ld", (long int)req.A, (long int)req.B); ROS_INFO("senging back response: [%ld]", (long int)res.Sum); ​ return true; } ​ //主函数 int main(int argc, char **argv){ //创建一个节点 ros::init(argc, argv, "add_two_ints_server"); ​ //创建节点句柄 ros::NodeHandle n; ​ //创建一个service 服务名称为add_two_ints 回调函数名为add ros::ServiceServer server = n.advertiseService("add_two_ints", add); ROS_INFO("Ready to add two ints"); ​ //阻塞函数 ros::spin(); ​ return 0; } 完成之后,编译工作空间。我们先不着急打开客户端检验,可以通过rqt工具箱来检验我们写的服务端是否正确。
先启动roscore和服务端节点,再键入
rosrun rqt_service_caller rqt_service_caller 系统会弹出一个图形化窗口,输入A、B的值,点击Call,如果服务端节点正确输出,则说明服务端节点没有问题。这时候再启动客户端节点
rosrun beginner_tutorials client 1 2 服务端和客户端都正常输出结果3,说明我们编写的客户端和服务端节点都是正确的。
2.14 使用rosbag
不难理解的一件事情是,我们在车辆上使用的激光雷达、摄像头等传感器,本质上就是为我们的处理器提供了各种各样的数据。也就是说,如果我们直接输入数据给处理器,其效果是一样的。这也就是rosbag的意义。
做一次试验会获得很多数据,通过rosbag我们可以把这些数据记录下来,回到实验室后利用这些数据我们就可以进行模拟。除此之外,当我们缺少某些硬件设施时,可以利用别人采集到的传感器数据来完成我们的试验。
现在让我们启动一只小海龟,同时启动键盘控制(到目前为止,启动小海龟的命令应该能够掌握)。
下面我们创建一个文件夹,用于存放本次学习中产生的bag文件。
mkdir ~/bagfiles cd ~/bagfiles 在bagfiles下开启一个新终端,键入
rosbag record -a 回车之后,系统就开始记录小海龟的运动,回到键盘控制终端,随意移动小海龟几秒钟,然后回到运行rosbag的终端,按下ctrl+c退出。
现在关闭键盘控制节点,重新启动一只小海龟,在bagfiles文件夹下打开一个终端,键入以下命令
rosbag play 2021-06-22-13-11-18.bag ^C 可以发现小海龟会按照与刚才相同的轨迹运动。
结束语
至此,关于ROS的基础知识基本上学完啦!

 

热点资讯

相关资讯



Powered by 网上博彩论坛 @2013-2022 RSS地图 HTML地图

网站统计——

  • 谷歌搜索留痕推广
  • 谷歌搜索留痕排名技术
  • 谷歌快速排名
  • 留痕方法
  • 谷歌搜索快速方法
  • google搜索留痕程序
  • 谷歌快速排名
  • 澳门太阳城
  • 最大博彩公司
  • 谷歌搜索关键词排名
  • 搜索留痕程序
  • 谷歌排名出售
  • 谷歌蜘蛛池排名
  • 搜索留痕软件
  • 缅甸果敢赌场
  • 电子游艺规则
  • 谷歌留痕推广
  • google引流程序
  • 谷歌快速排名
  • google引流程序
  • 留痕推广
  • 大西洋城赌场
  • 买球地址
  • 搜索留痕
  • 搜索留痕程序出售
  • 谷歌蜘蛛池排名技术
  • 留痕程序
  • 如何提高google搜索排名
  • 数字币博彩
  • 洗钱方法
  • Google留痕收录
  • 最新谷歌搜索留痕排名
  • 搜索留痕
  • Google留痕收录
  • google搜索留痕
  • 数字币博彩网站
  • 足球投注平台
  • 博彩推广话术
  • 推广引流方法
  • 引流方法
  • 博彩推广话术
  • 网上博彩推广引流
  • 数字币赌场
  • 皇冠现金网
  • 蜘蛛池排名
  • 谷歌蜘蛛池
  • 留痕程序出售
  • google搜索留痕程序
  • 比特币网上赌场
  • 洗钱平台
  • 搜索留痕
  • 博彩推广方式
  • 网上博彩推广
  • 快速排名
  • 搜索留痕程序
  • bbin平台大全
  • 体育博彩公司排名
  • 留痕排名技术
  • 最新谷歌关键词排名
  • 推广渠道
  • 谷歌快速排名
  • 博彩推广
  • 世界杯赌球地址
  • 皇冠博彩公司
  • 谷歌排名出售
  • 博彩引流渠道
  • 搜索留痕程序
  • google搜索留痕
  • 引流渠道
  • 果敢网上赌场
  • 世界杯赌球
  • 搜索留痕方法
  • 博彩搜索留痕
  • 博彩引流
  • 博彩引流
  • 搜索留痕
  • 缅甸网上赌场
  • 欧洲杯赌球
  • 谷歌搜索排名
  • 留痕程序
  • 网上博彩推广引流
  • 留痕技术
  • 搜索留痕技术出售
  • 澳门威尼斯人网上赌场
  • 外围博彩
  • 博彩网站推广
  • 推广引流
  • 留痕程序出售
  • 谷歌推广引流技术
  • 推广引流方法
  • 美国在线赌场
  • 沙巴体育投注平台
  • 最新谷歌搜索留痕
  • 谷歌蜘蛛池排名技术
  • 网站推广方法
  • 留痕程序出售
  • 博彩推广方法
  • 菠菜论坛
  • 买球平台
  • 谷歌搜索留痕
  • 蜘蛛池排名
  • 博彩公司推广渠道
  • 谷歌搜索留痕
  • 博彩公司推广渠道
  • 真钱游戏
  • 网上赌球地址
  • 赌球平台推荐
  • 赌球网址
  • 博彩包网
  • 买球app
  • 澳门博彩公司
  • 威尼斯人赌场
  • 博彩平台推荐
  • 美国博彩网站
  • 缅甸实体赌场
  • 柬埔寨网上赌场
  • 柬埔寨在线赌场
  • 韩国博彩
  • 支持人民币的博彩公司
  • 世界五大比特币交易所
  • 欧易是哪个国家的
  • 中币跑路
  • 亚洲博彩公司
  • 合法网上赌场
  • 马尼拉赌场
  • 支持人民币的博彩公司
  • 大陆博彩平台
  • 澳门新葡京娱乐城
  • 老挝赌场
  • 世界赌场排名
  • 网上博彩公司排行
  • 菠菜论坛
  • 东南亚赌博网站
  • 虚拟币博彩
  • 澳门百家乐网址
  • 网上博彩导航
  • 区块链百家乐游戏
  • 马来西亚博彩公司
  • 越南赌场
  • 区块链百家乐
  • 香港娱乐场
  • 澳大利亚赌博网站
  • 足球赔率
  • 菲律宾网上赌场
  • 数字币博彩网站
  • 足球投注网站
  • 百家乐论坛
  • 皇冠体育博彩公司
  • 网上赌博网站
  • 网上博彩推广话术
  • 谷歌搜索快速方法
  • 网上博彩推广话术
  • 数字币赌场
  • 皇冠博彩公司
  • 世界杯博彩公司
  • 英国博彩公司
  • 网上博彩合法化
  • 新加坡赌场
  • 比特币网上赌场
  • 怎么洗钱
  • 加密货币博彩平台
  • 世界杯赌球网址
  • 网上赌球地址
  • 博彩推广方式
  • 印度尼西亚博彩公司
  • 国际包网
  • bbin平台直营
  • 亚洲体育博彩平台
  • 越南博彩公司
  • 百家乐路单
  • 澳门博彩官网
  • 博彩网推荐
  • 澳门太阳城网址
  • 百家乐网址
  • 世界杯赌球网址
  • 皇冠博彩网址
  • 洗钱方法
  • 买球网站
  • 欧洲杯赌球平台
  • 皇冠现金网
  • 外围赌球平台
  • 果敢赌场
  • 买球技巧
  • 全球最大博彩公司
  • 电子游艺
  • 真人电子游戏
  • 骰宝游戏规则
  • 亚洲体育博彩平台
  • 澳门在线赌场
  • 缅甸赌场地址
  • 赌球平台
  • 赌场如何赢钱
  • 世界杯买球网站
  • 真人牌九游戏
  • 世界杯买球官网
  • 时时彩平台
  • 六合彩预测
  • 威尼斯人网上赌场
  • 外围赌球网站
  • 赌博网址
  • 彩票群
  • 微信赌博群
  • 韩国首尔赌场
  • 赌钱游戏
  • 美国网上赌场
  • bbin官网
  • 沙巴体育官网
  • 博彩平台推荐
  • 数字币博彩网站
  • 比特币网上赌场
  • 世界赌场名单
  • 美国赌场攻略
  • 菠菜论坛排名
  • 菠菜论坛排名
  • 缅甸网上赌场
  • 支持人民币的博彩公司