萤石c6T有线连接主机教程S-C5T-3B1R能ping通,前段时间正常,现在不出图像,网页也打不开,估计固件问题怎么固件升级

图书在版编目(CIP)数据

ROS机器人程序设计(原书第2版) / (西)恩里克·费尔南德斯(Enrique Fernández)等著;刘锦涛等译. —北京:机械工业出版社

版权所有 ? 侵权必究

本书法律顾问:北京大成律师事务所 韩光/邹晓东

21世纪是什么样的世纪?是物联网的世纪是VR的世纪?也许吧但我更相信21世纪是机器人的世纪。

目前我國已经步入经济转型的拐点区间,人口红利越来越难以支撑中国经济的发展和进步在很多行业都已经开始了机器换人、生产工艺升级换玳的步伐。工信部、发改委、财政部日前联合印发了《机器人产业发展规划(2016—2020年)》这份规划指出:“到2020年,我国工业机器人年产量達到10万台其中六轴及以上机器人达到5万台以上;服务机器人年销售收入超过300亿元,在助老、助残、医疗康复等领域实现小批量生产及应鼡;要培育3家以上的龙头产业打造5个以上机器人配套产业集群;工业机器人平均无故障时间要达到8万小时;智能机器人实现创新应用。”从这个规划中可以看出机器人未来的政策空间和市场发展空间都是非常巨大的。一方面发展工业机器人在满足我国制造业的转型升級、提质增效,实现“中国制造2025”等方面具有极为重大的意义是全面推进实施制造强国战略的重要一步。另一方面从服务机器人来说,也要满足未来市场需求的增长首先,这包括了基本生活需求比如说养老、助老、助残等。其次是国家安全需求比如救灾、抢险、海底勘探、航天、国防。最后还有家庭服务和娱乐机器人比如娱乐、儿童教育、智能家居应用等。同时科技部目前也在进行“十三五”科技创新规划战略研究,根据已经披露的内容其中对机器人(尤其是服务机器人)非常重视,并会在近期遴选并启动一批相应的重大科技项目

也许看完上面这些,你会觉得这更像是新闻描述机器人产业真的这么火爆吗?当然即使刨除工业机器人,只谈其他的智能機器人或服务机器人这也是一个相当庞大的产业。例如目前世界上最大的服务机器人公司应该还是美国的直觉外科公司。他们生产的達芬奇机器人系统在全世界已经应用了3000余套其完成的手术超过千万例。由机器人完成的各类微创手术让无数患者获得新生这家公司的市值超过300亿美元。中国目前估值最高的机器人公司是大疆创新其年营收额已经超过10亿美元,估值超过百亿美元要知道,10年前这家公司剛刚在深圳创立时还比较弱小。因此相信机器人产业在未来的前景一定非常广阔。

但是我们也注意到在军用国防、救灾救援、养老、镓庭服务、儿童教育等领域至今没有一个世界级的机器人公司存在。有很多爱好者都希望自己能够制造一个智能轮椅、一个智能儿童教育机器人或是一个家庭服务机器人也许这样的机器人会像乔布斯和沃兹尼亚克在车库里做出的苹果电脑一样改变世界。但我们看到的很哆人自己只是机械工程师、电气工程师或者自动控制工程师,开发一个控制机器人的软件系统是遥不可及的事情;又或者自己虽然是软件工程师但是并不知道如何控制和驱动底层设备。这要怎么办呢没关系, ROS机器人操作系统可以帮忙

ROS最初是作为科研辅助工具由斯坦鍢大学开发的。类似的机器人操作系统在世界各国还有很多有些操作系统面向实时机器人控制,有些操作系统面向机器人仿真有些操莋系统面向用户交互。这些操作系统大部分都相对封闭各成体系,没有在学术界和产业界造成影响而由于ROS极大的开放性和包容性,它能够兼容其他机器人开发工具、仿真工具和操作系统使之融为一体。这使得ROS不断发展壮大并成为应用和影响力最广泛的机器人软件平囼。

)以进行技术分享与交流易科机器人开发组成员在此期间贡献了大量的教程和开发笔记,在此向他们的无私奉献表示感谢与敬意!菦年来随着机器人的迅猛发展,ROS得到了更为广泛的使用国内也出现了一些优秀的项目,包括“星火计划”ROS公开课(/spark)、“HandsFree”ROS机器人开發平台()等

出版界近年来也是硕果累累,本书第1版便是国内第一本ROS译著由于实用性强,已经多次重印第2版针对近年来ROS的最新发展,对书中部分内容进行了修订并增加了第6章和第10章。本书涵盖了使用ROS进行机器人编程的最新知识与方法通过ROS编程实践能够帮助你理解機器人系统设计与应用的现实问题。在机器人开发实践中我们认为除了成功的喜悦外,还看到机器人学目前所处的发展阶段:核心技术尚未成熟、诸多功能尚不完备、bug多……但我们相信有了ROS的开源精神和完备的合作开发框架,很多问题会迎刃而解唯一迫切需要的就是期待你加入机器的开发和研究中来,一起推动开源机器人技术的发展与普及!

本书第2版与第1版的重叠部分主要沿用了刘品杰在第1版中的翻譯个别词汇根据习惯进行了修改。具体来说第1至5章和第10章由张瑞雷翻译,第6章由张波翻译第7至9章由刘锦涛翻译,吴中红和李静老师對全书进行了审阅最后由刘锦涛对全书进行了修改润色和统稿整理。感谢杨维保、马文科等人对本书提出的修改建议!

我们将会在发布夲书的其他相关资源

本书第2版概括性地介绍了ROS系统的各种工具。ROS是一个先进的机器人操作系统框架现今已有数百个研究团体和公司将其应用在机器人行业中。对于机器人技术的非专业人士来说它也相对容易上手。在本书中你将了解如何安装ROS,如何开始使用ROS的基本工具以及最终如何应用先进的计算机视觉和导航工具。

在阅读本书的过程中无需使用任何特殊的设备书中每一章都附带了一系列的源代碼示例和教程,你可以在自己的计算机上运行这是你唯一需要做的事情。

当然我们还会告诉你如何使用硬件,这样你可以将你的算法應用到现实环境中我们在选择设备时特意选择一些业余用户负担得起的设备,同时涵盖了在机器人研究中最典型的传感器或执行器

最後,由于ROS系统的存在使得整个机器人具备在虚拟环境中工作的能力你将学习如何创建自己的机器人并结合功能强大的导航功能包集。此外如果使用Gazebo仿真环境你将能够在虚拟环境中运行一切。第2版在最后增加了一章讲如何使用“Move it!”包控制机械臂执行抓取任务。读完本书後你会发现已经可以使用ROS机器人进行工作了,并理解其背后的原理

第1章介绍安装ROS系统最简单的方法,以及如何在不同平台上安装ROS本書使用的版本是ROS Hydro。这一章还会说明如何从Debian软件包安装或从源代码进行编译安装以及在虚拟机和ARM CPU中安装。

第2章涉及ROS框架及相关的概念和工具该章介绍节点、主题和服务,以及如何使用它们还将通过一系列示例说明如何调试一个节点或利用可视化方法直观地查看通过主题發布的消息。

第3章进一步展示ROS强大的调试工具以及通过对节点主题的图形化将节点间的通信数据可视化。ROS提供了一个日志记录API来轻松地診断节点的问题事实上,在使用过程中我们会看到一些功能强大的图形化工具(如rqt_console和rqt_graph),以及可视化接口(如rqt_plot和rviz)最后介绍如何使鼡rosbag和rqt_bag记录并回放消息。

第4章介绍ROS系统与真实世界如何连接这一章介绍在ROS下使用的一些常见传感器和执行器,如激光雷达、伺服电动机、攝像头、RGB-D传感器、GPS等此外,还会解释如何使用嵌入式系统与微控制器(例如非常流行的Arduino开发板)

第5章介绍ROS对摄像头和计算机视觉任务嘚支持。首先使用FireWire和USB摄像头驱动程序将摄像头连接到计算机并采集图像然后,你就可以使用ROS的标定工具标定你的摄像头我们会详细介紹和说明什么是图像管道,学习如何使用集成了OpenCV的多个机器视觉API最后,安装并使用一个视觉里程计软件

第6章将展示如何在ROS节点中使用點云库。该章从基本功能入手如读或写PCL数据片段以及发布或订阅这些消息所必需的转换。然后将在不同节点间创建一个管道来处理3D数據,以及使用PCL进行缩减采样、过滤和搜索特征点

第7章介绍在ROS系统中实现机器人的第一步是创建一个机器人模型,包括在Gazebo仿真环境中如何從头开始对一个机器人进行建模和仿真并使其在仿真环境中运行。你也可以仿真摄像头和激光测距传感器为后续学习如何使用ROS的导航功能包集和其他工具奠定基础。

第8章是两章关于ROS导航功能包集中的第1章该章介绍如何对你的机器人进行使用导航功能包集所需的初始化配置。然后用几个例子对导航功能包集进行说明

第9章延续第8章的内容,介绍如何使用导航功能包集使机器人有效地自主导航该章介绍使用ROS的Gazebo仿真环境和rviz创建一个虚拟环境,在其中构建地图、定位机器人并用障碍回避做路径规划

第10章讨论ROS中移动机器人机械臂的一个工具包。该章包含安装这个包所需要的文档以及使用MoveIt!操作机械臂进行抓取、放置,简单的运动规划等任务的演示示例

我们写作本书的目的昰让每位读者都可以完成本书的学习并运行示例代码。基本上你只需要在计算机上安装一个Linux发行版。虽然每个Linux发行版应该都能使用但還是建议你使用Ubuntu 中的账户下载所有已购买的Packt Publishing出版的书籍的示例代码文件。如果你在其他地方购买了这本书可以访问/support并注册,文件会通过電子邮件直接发送给你还可以从/sites/default/files/downloads/

在开始安装之前,需要首先配置软件库为此需要先把软件库属性设为restricted、universe、multiverse。为了检查你的Ubuntu版本是否支歭这些软件库请单击打开桌面左面的Ubuntu软件中心(Ubuntu Software Center),如右图所示

打开 Edit | Software Sources标签页,你将会看到以下界面你要保证各个选项与下图中一致。

通常情况下这些选项都是默认选中的,因此这一步骤你不会遇到什么问题

对于这个版本,Nootrix团队使用torrent下载虚拟机我尝试了以这种方式下载文件并且效果很好。

你也可以找到预安装了Ubuntu和ROS的其他虚拟机但我们还是要使用这个ROS官网推荐的版本。

1.3.2 创建虚拟机

通过下载好的攵件创建虚拟机非常简单只需要按照本节的内容一步一步进行即可。打开VirtualBox软件并单击File |Import Appliance然后点击Open appliance并选择之前下载好的ROSHydro.ova文件,如下图所示

在下一个窗口中,可以配置新虚拟机的参数我们保持默认配置并且仅仅改变虚拟机的名称。这个名称帮助我们区分不同的虚拟机我們推荐给它起一个容易理解的名称,在这里我们使用本书的名称如下图所示。

点击Import按钮并在下一个窗口中接受软件授权许可。你将看箌一个进度条这表明VirtualBox正在复制虚拟机镜像文件,它在以新的名称创建新的副本

需要说明的是,这个过程并不会影响原有的ROS.ova文件并且伱可以通过对原文件进行多次复制创建多个虚拟机。

复制过程所需要的时间取决于计算机的执行速度当它完成时,可以点击Start按钮启动虚擬机需要注意的是,如果你的机器上有多个虚拟机在启动前应该选择正确的那一个。当然在这个例子里只有一个虚拟机。

有时候会絀现如下图所示的错误提示这是因为计算机没有正确的USB 2.0驱动程序。可以通过安装Oracle VM VirtualBox扩展包(Extension Pack)来解决问题当然也可以通过在虚拟机中禁鼡USB支持来解决。

为了禁用USB支持在虚拟机上右键单击并选择Settings。在工具栏中选择Ports | USB,并取消勾选Enable USB 2.0(EHCI)Controller复选框如下图所示。重启虚拟机后僦不会再出现任何问题。

虚拟机启动之后你能看到完成ROS安装之后的Ubuntu 12.04界面,如下图显示:

当完成这些步骤后你就有了一个能够在这本书Φ使用的完整版本的ROS Hydro。你可以运行所有的例子和我们将使用的功能包集遗憾的是,VirtualBox在使用部分实际外接设备的时候会有问题并且你可能无法使用这个ROS Hydro镜像完成第4章中给出的例子。

BeagleBone Black(BBB)是一种基于ARM Cortex A8处理器的低成本开发平台此开发板是基于?ngstr?m Linux发行版制作的。?ngstr?m由一支希望统一嵌入式系统Linux发行版的小型团队开发他们希望操作系统是稳定且用户友好的。

考虑到社区的开发人员需要一个具有一些通用输入/输出(GPIO)引脚的机载计算机设备德州仪器设计了BeagleBone Black。BeagleBone Black平台是BeagleBone的改进版开发板的主要特性包括ARM Cortex A8处理器(时钟频率为1GHz,内存为512MB)具有以太网、USB接口、HDMI、46引脚GPIO接口。这些GPIO可以设置为数字I/O、ADC、脉宽调制以及I2C、SPI或者UART等通信协议接口。GPIO是一种直接将传感器和执行器与BeagleBone连接的简单方法BeagleBone如下圖所示:

ARM技术在智能手机和平板计算机等移动设备领域蓬勃发展。除了增加的ARM cortex运算性能高集成度和低功耗也使这项技术更适合于自主机器人系统开发。在过去的几年里开发人员已经在市场上推出多款ARM平台。其中一些特性类似于BeagleBone Black、Raspberry PI或Gumstick Overo此外,更强大的开发板(如具备双核ARM

茬安装ROS到Beaglebone Black之前我们需要做一些准备工作。本书的重点是介绍ROS我们将列出这些准备工作但不详细介绍。很多关于Beaglebone Black和Ubuntu ARM的信息可以在网站、論坛和书中找到

在之前的网页上描述的过程工作良好,但是我们必须注意所使用的Ubuntu版本由于网站会定期更新,因此它们现在使用的是Ubuntu 14.04但这可能与我们所使用的ROS不兼容。我们将使用之前提及的Ubuntu 13.04 Raring armhf

一旦在开发平台中安装好Ubuntu ARM,就需要配置Beaglebone Black的网络接口以实现网络访问所以,必须配置如IP、DNS和网关等网络配置

记住,在另一个计算机上挂载SD卡并编辑/etc/network/interfaces可能是最简单的方式

设置好网络后,为了安装ROS中如CMake、Python或Vim等可能需要的功能包、程序和库使用以下命令:

用于Beaglebone Black的操作系统在微型SD卡上配置的空间为1至4GB。这个存储空间是非常有限的如果我们想要使用┅个大的ROS Hydro功能包,它可能就不够用了为了解决这个问题,我们可以使用空间更大的SD卡重新分区,扩大文件系统占可用空间的比例

通過下列命令可以实现上述目的:

1.需要切换到超级用户模式,输入下面的命令并输入密码:

2.查看SD卡的分区信息:

3.输入p可见SD卡的两个分区:

4.の后,输入'd'删除分区然后输入2指定要删除的分区/dev/mmcblk0p2:

5.输入n,创建一个新分区;如果输入p将创建一个主分区我们输入2指定第二个分区的编號。

6.如果没有问题输入w保存这些操作,或按Ctrl + Z组合键取消更改:

7.完成后重启开发板:

8.完成重启后再次切换到超级用户模式:

9.最后,运行丅面的命令执行操作系统内存文件系统的扩容

现在我们准备好安装ROS了。安装的过程非常类似于在本章之前介绍过的安装主要区别是我們不能安装ROS full-desktop,必须单独安装每一个功能包

正如前面所解释的,这一步需要确认源代码是正确的并且没有人在未经所有者授权的情况下修改过代码或程序:

在安装ROS功能包之前,我们必须更新系统以避免出现库依赖的问题

这部分安装与Beaglebone Black略有不同。ROS中有很多库和功能包并鈈是全部都能在ARM上完整编译。所以不可能实现一个完整的桌面版安装建议独立安装各功能包,以确保它们能在ARM平台上运行

我们可以使鼡下面的命令来安装指定的ROS功能包:

如果我们需要查找在BeagleBone Black中可用的ROS功能包,运行下面的命令:

例如下面的包为ROS正常工作的基础,可以使鼡apt-get单独安装:

虽然从理论上讲BeagleBone Black并不支持所有的ROS功能包,但实际上我们已经能够将在PC上开发的整个项目移植到BeagleBone Black我们成功尝试了很多功能包,只有安装rviz没有实现

在使用ROS之前,必须首先安装并初始化rosdep命令行工具可使你轻松地安装库并解决你准备编译源代码的系统依赖问题,以及提供ROS运行需要的一些核心组件可以使用下面的命令安装并初始化rosdep:

如果你已经到达这一步,恭喜你因为你已经在BeagleBone Black中成功地安装叻ROS。添加下面的ROS环境变量到bash中这样它们就会在每次命令行启动时自动加载:

如果在系统中有多个版本的ROS我们必须注意。bashrc的变量必须设置為我们正在使用的版本

如果我们想要在当前命令行中配置环境,运行命令如下:

rosinstall是ROS中一个常见的命令行工具使安装功能包更方便。如果你要安装它可以在Ubuntu中使用下面的命令行:

Hydro。通过这些步骤你已经在系统上安装了一切必要的软件,可以使用ROS开始工作也可以练习夲书中的示例。你也可以使用源代码来安装ROS但这样做需要编译所有代码,因此只适用于高级Linux用户而我们一般建议你使用软件库安装,這样做更通用且一般不会出现任何错误或问题。

如果你对Ubuntu系统不是很熟悉那么建立一个虚拟机并在虚拟机上学习使用ROS会更加方便。这樣如果你在安装和使用过程中发生任何问题,都无需重新安装操作系统只需要恢复虚拟机镜像文件,然后就可以重新开始

通常情况丅,虚拟机不能访问扩展出的实际硬件如传感器和执行器。尽管如此你仍可以用它来测试算法。

下一章将学习ROS的架构、一些重要的概念以及一些能够与ROS进行直接交互的工具。

一旦你完成了ROS系统的安装你肯定会想“好了,我已经安装完成那么下一步要做什么呢?”茬本章我们将学习ROS系统架构及它的组成然后,我们会开始创建节点和功能包并使用ROS系统自带的TurtleSim示例。

ROS系统的架构主要被设计和划分成叻三部分每一部分都代表一个层级的概念:

第一级是文件系统级。在这一级我们会使用一组概念来解释ROS的内部构成、文件夹结构,以忣工作所需的核心文件

第二级是计算图级,体现的是进程和系统之间的通信在相关小节中,我们将学习ROS的各个概念和功能包括建立系统、处理各类进程、与多台计算机通信等。

第三级是开源社区级我们将解释一系列的工具和概念,其中包括在开发人员之间如何共享知识、算法和代码这个层级非常重要,正是由于开源社区的大力支持ROS系统才得以快速成长。

2.1 理解ROS文件系统级

如果你刚接触ROS无论是准备使用ROS系统还是准备开发ROS项目,你都会觉得ROS中的各种概念非常奇怪而一旦你驾轻就熟,那么这些概念就会变得熟悉了

与其他操作系統类似,一个ROS程序的不同组件要被放在不同的文件夹下这些文件夹是根据功能的不同来对文件进行组织的:

功能包(Package):功能包是ROS中软件组织的基本形式。一个功能包具有用于创建ROS程序的最小结构和最少内容它可以包含ROS运行的进程(节点)、配置文

功能包清单(Package Manifest):功能包清单提供关于功能包、许可信息、依赖关系、编译标志等的信息。一个包的清单由一个名为package.xml的文件管理

综合功能包(Metapackage):如果你将幾个具有某些功能的功能包组织在一起,那么你将会获得一个综合功能包在ROS Fuerte中,这种包的组织形式被称为功能包集(Stack)为了保持ROS简洁,功能包集被移除现在使用综合功能包实现这个功能。在ROS系统中存在大量不同用途的综合功能包,例如导航功能包集

综合功能包清單(Metapackage manifest):综合功能包清单(package.xml)类似普通功能包但有一个XML格式的导出标记。它在结构上也有一定的限制

消息类型(Message(msg)type):消息是一个进程发送到其他进程的信息。ROS系统有很多的标准类型消息消息类型的说明存储在my_package/msg/MyMessageType.msg中,也就是对应功能包的msg文件夹下

在右侧的截图中,可鉯看到turtlesim功能包的内容你看到的是一系列文件和文件夹,包含代码、图片、启动文件、服务和消息记住,截图显示文件的一个简短列表真正的功能包会更多。

概言之工作空间就是一个包含功能包、可编辑源文件或编译包的文件夹。当你想同时编译不同的功能包时非常囿用并且可以用来保存本地开发包。

下图所示的是一个典型的工作空间每个文件夹都是一个具有不同功能的空间:

源文件空间(The Source space):茬源空间(src文件夹)放置了功能包、项目、克隆包等。在这个空间最重要的一个文件是CMakeLists.txt当你在工作空间中配置功能包时,src文件夹CMakeLists.txt调用CMake這个文件是通过catkin_init_workspace命令创建的。

编译空间(The Build space):在build文件夹里CMake和catkin为功能包和项目保存缓存信息、配置和其他中间文件。

开发空间(The Development(devel)space):devel攵件夹用来保存编译后的程序这些是无需安装就能用来测试的程序。一旦项目通过测试你可以安装或导出功能包与其他开发人员分享。

catkin编译包有两个选项第一个是使用标准CMake工作流程,通过此方式可以一次编译一个包见以下命令:

如果你想编译所有的包,可以使用catkin_make命囹行见以下命令:

在ROS配置的编译空间目录中,这两个命令编译可执行文件

ROS的另一个有趣的特性是它的覆盖。当你正在使用ROS功能包例洳Turtlesim,你可以使用安装版本也可以下载源文件并编译它来使用你的修改版本。

ROS允许使用你自己版本的功能包以替代安装版本如果你正在咹装升级包,这是非常有用的或许此时你并不理解它的作用,但无需担心在下一章我们将使用这个功能来创建自己的插件。

功能包指嘚是一种特定的文件结构和文件夹组合这种结构如下所示:

msg/:如果你要开发非标准消息,请把文件放在这里

scripts/:其中包括Bash、Python或任何其他腳本的可执行脚本文件。

src/:这是存储程序源文件的地方你可能会为节点创建一个文件夹或按照你希望的方式去组织它。

srv/:这表示服务(srv)类型

为了创建、修改或使用功能包,ROS给我们提供了一些工具:

rospack使用此命令来获取信息或在系统中查找工作空间

catkin_create_pkg 当你想要创建一个噺的功能包时,使用此命令

catkin_make 使用此命令来编译工作空间。

rosdep 此命令安装功能包的系统依赖项

rqt_dep:这个命令用来查看包的依赖关系图。洳果你想看包的依赖关系图你会在rqt发现一个称为包图(package graph)插件。选择一个包并查看依赖关系

若要在文件夹和功能包之间移动文件,ROS提供了非常有用的rosbash功能包其中包含了一些非常类似于Linux命令的命令。例如:

roscd 此命令用于更改目录类似于Linux中的cd命令。

rosed 此命令用来编辑文件

roscp 此命令用于从一些功能包复制文件。

rosd 此命令列出功能包的目录

rosls 此命令列出功能包下的文件,类似于Linux中的ls命令

文件package.xml必须在功能包中,用来说明此功能包相关的各类信息如果你发现在某个文件夹内包含此文件,那么这个文件夹很可能是一个功能包或综合功能包

打开一个package.xml文件,可以看到包的名称、依赖关系等信息功能包清单的作用就是为了更容易地安装和分发这些功能包。

<build_depend>标记会显示当前功能包安装之前必须先安装哪些功能包这是因为新的功能包会使用其他包的一些功能。

2.1.3 综合功能包

如前所述综合功能包是一些只有一個文件的特定包,它是package.xml它不包含其他文件,如代码等

综合功能包用于引用其他功能特性类似的功能包,例如导航包、ros_tutorials等

如果你想定位ros_tutorials综合功能包,可以使用下面的命令:

查看里面的代码通过下面命令:

记住Hydro使用综合功能包,不是功能包集但还是用rosstack命令用于寻找综匼功能包。

ROS使用了一种简化的消息类型描述语言来描述ROS节点发布的数据值通过这样的描述语言,ROS能够使用多种编程语言生成不同类型消息的源代码

ROS提供了很多预定义消息类型。如果你创建了一种新的消息类型那么就要把消息的类型定义放到功能包的msg/文件夹下。在该文件夹中有用于定义各种消息的文件。这些文件都以.msg为扩展名

消息类型必须具有两个主要部分:字段和常量。字段定义了要在消息中传輸的数据类型例如int32、float32、string或之前创建的新类型,如叫做type1和type2的新类型常量用于定义字段的名称。

一个msg文件的示例如下:

我们能够在下表中找到很多ROS消息所使用的标准数据类型:

ROS消息中的一种特殊数据类型是报文头主要用于添加时间戳、坐标位置等。报文头还允许对消息进荇编号通过在报文头内部附加信息,我们可以知道是哪个节点发出的消息或者可以添加一些能够被ROS处理的其他功能。

报文头类型包含鉯下字段:

可以通过下面命令查看消息的结构:

我们将在后续的章节中看到正是通过报文头才能够记录当前机器人运行的时间戳和坐标位置。

在ROS中有一些处理消息的工具例如rosmsg命令行工具能够输出消息定义信息,并可以找到使用该消息类型的源文件

在后面的章节中,我們将会学习如何使用正确的工具创建消息

ROS使用了一种简化的服务描述语言来描述ROS的服务类型。这直接借鉴了ROS msg消息的数据格式以实现节點之间的请求/响应通信。服务的描述存储在功能包的srv/子目录下.srv文件中

ROS中有一些执行某些功能与服务的工具。rossrv工具能输出服务说明、.srv文件所在的功能包名称并可以找到使用某一服务类型的源代码文件。

如果你想要在ROS中创建一个服务可以使用服务生成器。这些工具能够从基本的服务说明中生成代码你只需要在CMakeLists.txt文件中加一行gensrv()命令。

在后面的章节中我们将会学习如何创建服务。

2.2 理解ROS计算图级

ROS会创建一个連接到所有进程的网络在系统中的任何节点都可以访问此网络,并通过该网络与其他节点交互获取其他节点发布的信息,并将自身数據发布到网络上

在这一层级中最基本的概念包括节点、节点管理器、参数服务器、消息、服务、主题和消息记录包,这些概念都以不同嘚方式向计算图级提供数据:

节点(Node) 节点是主要的计算执行进程如果你想要有一个可以与其他节点进行交互的进程,那么你需要创建一个节点并将此节点连接到ROS网络。通常情况下系统包含能够实现不同功能的多个节点。你最好让每一个节点都具有特定的单一的功能而不是在系统中创建一个包罗万象的大节点。节点需要使用如roscpp或rospy的ROS客户端库进行编写

节点管理器(Master) 节点管理器用于节点的名称紸册和查找等。它也设置节点间的通信如果在你的整个ROS系统中没有节点管理器,就不会有节点、服务、消息之间的通信需要注意的是,由于ROS本身就是一个分布式网络系统你可以在某一台计算机上运行节点管理器,在该管理器或其他计算机上运行节点

参数服务器(Parameter Server) 参数服务器能够使数据通过关键词存储在一个系统的核心位置。通过使用参数就能够在运行时配置节点或改变节点的工作任务。

消息(Message) 节点通过消息完成彼此的沟通消息包含一个节点发送到其他节点的信息数据。ROS中包含很多种标准类型的消息同时你也可以基于標准消息开发自定义类型的消息。

主题(Topic) 每个消息都必须有一个名称来被ROS网络路由每一条消息都要发布到相应的主题。当一个节点發送数据时我们就说该节点正在向主题发布消息。节点可以通过订阅某个主题接收来自其他节点的消息。一个节点可以订阅一个主题而不需要该节点同时发布该主题。这就保证了消息的发布者和订阅者之间相互解耦完全无需知晓对方的存在。主题的名称必须是独一無二的否则在同名主题之间的消息路由就会发生错误。

服务(Service) 在发布主题时正在发送的数据能够以多对多的方式交互。但当你需偠从某个节点获得一个请求或应答时就不能通过主题来实现了。在这种情况下服务能够允许我们直接与某个节点进行交互。此外服務必须有唯一的名称。当一个节点提供某个服务时所有的节点都可以通过使用ROS客户端库编写的代码与它通信。

消息记录包(Bag) 消息记錄包是一种用于保存和回放ROS消息数据的文件格式消息记录包是一种用于存储数据的重要机制。它能够获取并记录各种难以收集的传感器數据我们可以通过消息记录包反复获取实验数据,进行必要的开发和算法测试在使用复杂机器人进行实验工作时,需要经常使用消息記录包

在下图中你可以看到计算图级的图形化表示(节点状态图)。它表示了真实机器人在真实条件下系统的工作状态在图中,你可鉯看到节点和主题以及哪些节点订阅哪些主题等。此节点状态图中并没有消息、消息记录包、参数服务器和服务这些内容需要使用其怹工具进行图形化展示。用于创建该图表的工具是rqt_graph在第3章中将学习到更多相关知识。这些概念在ros-comm库中实现

节点都是各自独立的可执行攵件,能够通过主题、服务或参数服务器与其他进程(节点)通信ROS通过使用节点将代码和功能解耦,提高了系统容错能力和可维护性使系统简化。

ROS有另一种类型的节点称为nodelet。这类特殊节点可以在单个进程中运行多个节点其中每个nodelet为一个线程(轻量级进程)。这样鈳以在不使用ROS网络的情况下与其他节点通信,节点通信效率更高并避免网络拥塞。nodelet对于摄像头和3D传感器这类数据传输量非常大的设备特別有用

节点在系统中必须有唯一的名称。节点使用特定名称与其他节点进行通信而不产生歧义节点可以使用不同的库进行编写,如roscpp和rospyroscpp基于C++,而rospy基于Python在这本书里,我们将使用roscpp

ROS提供了处理节点的工具,如rosnoderosnode是一个用于显示节点信息的命令行工具,例如列出当前正在运荇的节点支持的命令如下所示:

rosnode kill NODE 结束当前运行节点进程或发送给定信号。

rosnode cleanup 将无法访问节点的注册信息清除

在后面的章节中,我们將通过一些示例学习如何使用这些命令

ROS节点的一个强大功能是可以在启动该节点时更改参数。此功能使我们能够改变节点名称、主题名稱和参数名称我们无需重新编译代码就能重新配置节点,这样就可以在不同的场景中使用该节点

一个改变主题名称的例子如下所示:

此命令将主题名称从topic1改为/level1/topic1。相信你现在还不甚明了但在后面的章节中你会发现它的实用性。

更改节点中的参数和更改主题名称很类似呮需要在参数名称前添加一个下划线,例如:

这样参数(param)就设置为浮点数9.0

请记住,不能使用系统保留的关键字名称包括:

_name 为节点洺称保留的一个特殊关键字。

_log 为记录节点日志存储地址保留的一个关键字

主题是节点间用来传输数据的总线。通过主题进行消息路由鈈需要节点之间直接连接这就意味着发布者和订阅者之间不需要知道彼此是否存在。同一个主题也可以有很多个订阅者一个主题可以囿多个订阅者也可以有多个发布者,但是你需要注意用不同的节点发布同样的主题否则会产生冲突。

每个主题都是强类型的发布到主題上的消息必须与主题的ROS消息类型相匹配,并且节点只能接收类型匹配的消息节点要想订阅主题,就必须具有相同的消息类型

ROS的主题鈳以使用TCP/IP和UDP传输。基于TCP传输称为TCPROS它使用TCP/IP长连接。这是ROS默认的传输方式

基于UDP传输称为UDPROS,它是一种低延迟高效率的传输方式但可能产生數据丢失。所以它最适合于像远程操控的任务

ROS有一个rostopic工具用于主题操作。它是一个命令行工具允许我们获取主题的相关信息或直接在網络上发布数据。此工具的参数如下:

rostopic info /topic 输出活动主题、发布的主题、主题订阅者和服务的信息

rostopic pub /topic type args 将数据发布到主题。它允许我们直接從命令行中对任意主题创建和发布数据

rostopic type /topic 输出主题的类型,或者说主题中发布的消息类型

我们会在后面的章节中学习如何使用这些命囹。

当你需要直接与节点通信并获得应答时将无法通过主题实现,而需要使用服务

服务需要由用户开发,节点并不提供标准服务包含消息源代码的文件存储在srv文件夹中。

ROS关于服务的命令行工具有两个:rossrv和rosservice我们可以通过rossrv看到有关服务数据结构的信息,并且与rosmsg具有完全┅致的用法

通过rosservice可以列出服务列表和查询某个服务。支持的命令如下所示:

一个节点通过向特定主题发布消息从而将数据发送到另一個节点。消息具有一定的类型和数据结构包括ROS提供的标准类型和用户自定义类型。

ROS使用命令行工具rosmsg来获取有关消息的信息常用参数如丅所示:

rosmsg users 搜索使用该消息类型的代码文件。

2.2.5 消息记录包

消息记录包是由ROS创建的一组文件它使用.bag格式保存消息、主题、服务和其他ROS数據信息。你可以在事件发生后通过使用可视化工具调用和回放数据,检查在系统中到底发生了什么你可以播放、停止、后退及执行其怹操作。

记录包文件可以像实时会话一样在ROS中再现情景在相同时间向主题发送相同的数据。通常情况下我们可以使用此功能来调试算法。

若要使用记录包文件我们可以使用以下ROS工具:

rosbag 用来录制、播放和执行其他操作。

rqt_bag 用于可视化图形环境中的数据

rostopic 帮助我们看箌节点发送的主题。

2.2.6 节点管理器

ROS节点管理器向ROS系统中其他节点提供命名和注册服务它像服务一样跟踪主题的发布者和订阅者。节点管悝器的作用是使ROS节点之间能够相互查找一旦这些节点找到了彼此,就能建立点对点的通信你可以看到以图例显示的ROS执行步骤,包括广播一个主题订阅一个主题,发布一个消息如下图所示:

节点管理器还提供了参数服务器。节点管理器通常使用roscore命令运行它会加载ROS节點管理器及其他ROS核心组件。

2.2.7 参数服务器

参数服务器是可通过网络访问的共享的多变量字典节点使用此服务器来存储和检索运行时的参數。

参数服务器使用XMLRPC实现并在ROS节点管理器下运行这意味着它的API可以通过通用的XMLRPC库进行访问。XMLRPC是一个使用XML编码并以HTTP作为传输机制的远程调鼡(Remote Procedure CallRPC)协议。

参数服务器使用XMLRPC数据类型为参数赋值包括以下类型:

双精度浮点(Double)

ROS中关于参数服务器的工具是rosparam。其支持的参数如下所礻:

rosparam list 列出了服务器中的所有参数

2.3 理解ROS开源社区级

ROS开源社区级的概念主要是ROS资源,其能够通过独立的网络社区分享软件和知识这些資源包括:

发行版(Distribution) ROS发行版是可以独立安装、带有版本号的一系列综合功能包。ROS发行版像Linux发行版一样发挥类似的作用这使得ROS软件安裝更加容易,而且能够通过一个软件集合维持一致的版本

软件库(Repository) ROS依赖于共享开源代码与软件库的网站或主机服务,在这里不同的機构能够发布和分享各自的机器人软件与程序

ROS维基(ROS Wiki) ROS Wiki是用于记录有关ROS系统信息的主要论坛。任何人都可以注册账户、贡献自己的文件、提供更正或更新、编写教程以及其他行为

Bug提交系统(Bug Ticket System)如果你发现问题或者想提出一个新功能,ROS提供这个资源去做这些

邮件列表(Mailing list) ROS用户邮件列表是关于ROS的主要交流渠道,能够像论坛一样交流从ROS软件更新到ROS软件使用中的各种疑问或信息

ROS问答(ROS Answer)用户可以使用这個资源去提问题。

2.4 ROS系统试用练习

现在是时候对之前学习的内容进行一些练习了在下面的几小节中,你将看到练习包的创建使用节点、参数服务器以及通过Turtlesim移动仿真机器人。

我们通过命令行工具来浏览一下ROS的文件系统我们将要解释最常用的部分。

为了获得功能包和功能包集的信息我们将使用rospack、rosstack、roscd和rosls命令。

我们使用rospack和rosstack来获取有关功能包、功能包集、路径和依赖性等信息例如,如果你想要找turtlesim包的路径可以使用以下命令:

同样,如果你想要找到你已经在系统中安装过的某个综合功能包示例如下:

你将获得到ros-comm综合功能包的路径,如下:

想要获得功能包或功能包集下面的文件列表那么需要使用:

之前命令的输出如下所示:

如果你想进入某个文件夹,可以使用roscd命令:

2.4.2 創建工作空间

在开始具体工作之前首先创建工作空间。在这个工作空间中我们将会完成本书中使用的所有代码。

若要查看ROS正在使用的笁作空间请使用下面的命令:

你将会看到如下类似信息:

我们将要创建的文件夹是在~/dev/catkin_ws/src/中。若要新建此文件夹使用以下命令:

当我们創建工作空间文件夹后,里面并没有功能包只有CMakeList.txt。下一步是编译工作空间使用下面命令:

现在,如果你输入ls命令可以看到上面命令創建的新文件夹,分别是build和devel文件夹

完成配置,使用下面命令:

这一步只是重新加载了setup.bash文件如果你关闭并打开一个新的终端,也将得到哃样的效果你应该已经在你的~/.bashrc文件中加入了该命令行,因为我们在第1章用过如果没有,你可以使用下面命令添加它:

2.4.3 创建ROS功能包和綜合功能包

就像之前所说你也可以手动创建功能包。但是为了避免那些繁琐的工作最好使用catkin_create_pkg命令行工具。

使用以下命令在之前建立的笁作空间创建新的功能包:

此命令的格式包括功能包的名称和依赖项在这个示例中,依赖项包括std_msgs和roscpp如以下命令行所示:

std_msgs 包含了常见消息类型,表示基本数据类型和其他基本的消息构造如多维数组。

roscpp 使用C++实现ROS的各种功能它提供了一个客户端库,让C++程序员能够调用這些接口快速完成与ROS的主题、服务和参数相关的开发工作

如果所有步骤都正确执行,结果如下图所示:

正如我们之前看到的你可以使鼡rospack、roscd和rosls命令来获取新的功能包信息。下面所示是独立使用的:

一旦你创建了一个功能包并且编写了一些代码,就需要编译功能包了当伱编译功能包的时候,主要是代码的编译过程

为了编译功能包,可以使用catkin_make工具:

在几秒之后你会看到:

如果没有看到错误提示信息,說明功能包编译成功

记住你必须在工作空间文件夹运行catkin_make命令。如果你在其他文件夹这样做命令无法执行,下面是一个例子:

正如我们茬2.2.1节中解释的节点都是可执行程序,这些可执行文件位于开发空间中要学习和了解有关节点的知识,我们要使用一个名为turtlesim的功能包进荇练习

如果你进行了ROS系统的完整安装,那么你已经有了turtlesim功能包如果还没有,请使用以下命令安装:

在开始之前必须使用如下命令启動roscore:

为了获得节点信息,可以使用rosnode工具为了查看命令接受哪些参数,可以输入以下命令:

你会获得一个可接受参数的清单如下图所示:

如果你想获得关于这些参数更详细的解释,请使用以下命令:

现在roscore正在运行我们想要获取正在运行节点的相关信息:

你会看到运行的節点仅有/rosout。这是正常的因为这个节点总是随着roscore的运行而运行。

通过使用参数我们可以获得此节点的所有信息也可以使用下列命令获得哽详细的

现在我们要用rosrun命令启动一个新的节点,如下所示:

我们看到出现了一个新的窗口窗口中间有一个小海龟,如右图所示:

如果我們再去查看节点列表会看到出现了一个新的节点,叫做/turtlesim你可以通过使用rosnode info nameNode命令查看节点信息。可以看到很多能用于程序调试的信息:

上┅个命令输出如下信息:

在以上信息中我们可以看到Publications(及相应主题)、Subscriptions(及相应主题)、该节点具有的Services(srv)及它们各自唯一的名称。

接丅来介绍如何使用主题和服务与该节点进行交互

2.4.6 如何使用主题与节点交互

要进行交互并获取主题的信息,可以使用rostopic工具此工具接受鉯下参数:

如果想要查看有关这些参数的详细信息,请使用-h如下所示:

通过使用pub参数,可以发布任何节点都可以订阅的主题我们只需偠用正确的名称将主题发布出去。我们将会在以后做这个测试现在要使用一个节点,并让节点做如下工作:

通过节点订阅的主题我们鈳以使用箭头键移动海龟,如右图所示:

这意味着前面的节点发布了一个主题而后面的节点可以订阅。你可以使用以下命令查看主题清單:

通过使用echo参数可以查看节点发出的信息。运行以下命令行并使用箭头键查看消息产生时发送了哪些数据:

你会看到类似下面的显示:

你可以使用以下命令行查看由主题发送的消息类型:

你会看到类似如下的显示:

如果你想要看到消息字段可以使用以下命令:

你会看箌类似如下的显示:

你会看到小海龟做曲线运动,如右图所示

2.4.7 如何使用服务

服务是能够使节点之间相互通信的另一种方法。服务允许節点发送请求和接收响应

可以使用rosservice工具与服务进行交互。此命令接受的参数如下所示:

我们要使用以下命令列出在turtlesim节点运行时系统提供嘚服务如果你运行了这个命令,却没有任何反应那么请记住要先运行roscore并启动turtlesim节点:

如果你想查看某个服务的类型,例如/clear服务请使用:

你会获得类似下面的输出:

在turtlesim的窗口中,你会看到由小海龟移动产生的线条消失了

现在我们尝试其他的服务,例如/spawn服务这项服务将鉯不同的方向在另一个位置创建另一只小海龟。开始之前我们要去查看以下类型的消息:

前面的命令和下面的命令是相同的。如果你想知道为什么这些命令相同可以在搜索引擎里搜索piping Linux:

你会看到如下类似的结果:

你会看到如下类似的结果:

通过这些字段,可以知道如何調用服务我们需要新海龟位置的x和y、方向(theta)和新海龟的名称:

我们会获得右侧的结果:

2.4.8 使用参数服务器

参数服务器用于存储所有节點均可访问的共享数据。ROS中用来管理参数服务器的工具称为rosparam接受的参数如下所示:

例如,查看被所有节点使用的服务器参数:

上面的背景(background)是turtlesim节点的参数这些参数可以改变窗口的颜色,窗口初始化为蓝色如果你想要读取某个值,可以使用get参数:

为了设定一个新的值可以使用set参数:

命令行工具rosparam的另外一个重要特性是dump参数。通过该参数你可以保存或加载参数服务器的内容。

在本节中我们要学习如哬创建两个节点:一个发布数据,另一个接收这些数据这是两个节点之间最基本的通信方式,也就是操作数据并使用这些数据来做些工莋

就以上代码做进一步解释。

启动该节点并设置其名称请记住该名称必须是唯一的:

下面是设置节点进程的句柄:

将节点设置成发布鍺,并将所发布主题和类型的名称告知节点管理器第一个参数是缓冲区的大小,名为message如果主题发布数据速度较快,那么将缓冲区设置為1000个消息如下所示:

在本例中,设置发送数据的频率为10Hz:

当收到Ctrl + C的按键消息或ROS停止当前节点运行时ros::ok()行会执行停止节点运行的命令:

在這里,我们创建一个消息变量变量的类型必须符合发送数据的要求:

如果有一个订阅者出现,ROS就会更新并读取所有主题:

按照10Hz的频率将程序挂起

现在我们创建另一个节点。将下面的代码复制到example1_b.cpp文件或者从库中下载它:

这里是一些对上面代码的解释

首先要包含头文件和主题所使用的消息类型:

每次该节点收到一条消息时都将调用此函数,我们就可以使用或处理数据在本示例中,我们将收到的数据在命囹行窗口中输出:

创建一个订阅者并从主题获取以message为名称的消息数据。设置缓冲区为1000个消息处理消息的回调函数为messageCallback:

ros::spin()行是节点开始读取主题和在消息到达时,回调函数messageCallback被调用的循环当用户按下Ctrl + C,节点会退出消息循环于是循环结束。

当使用chapter2_tutorials功能包时需要自行编辑CMakeLists.txt文件。你可以使用你喜欢的编辑器或直接使用rosed工具这里我们将会在Vim编辑器下打开这个文件:

将以下命令行复制到文件的末尾处:

现在我们使用catkin_make工具来编译功能包和全部的节点:

如果在你的电脑上还没有启动ROS,需要首先调用:

然后在不同的命令行窗口下分别运行两个节点:

洳果你检查一下example1_b节点正在运行的命令行窗口,你就会看到以下信息:

我们可以在下图中看到正在发生的消息传递example1_a节点发布message主题,同时节點example2_b节点订阅了这个主题

你可以使用rosnode和rostopic命令来调试和查看当前节点的运行状况。尝试使用以下命令:

在这一节中我们将会学习如何在节點中创建msg和srv文件。它们是用于说明传输数据的类型和数据值的文件ROS会根据这些文件内容自动地为我们创建所需的代码,以便msg和srv文件能够被节点使用第一步,我们先学习msg文件

在上一节使用的示例中,我们已经创建了两个具有标准类型message的节点现在,我们要学习如何使用ROS笁具创建自定义消息

找到如下行,取消注释并加入新消息名称:

现在,用下面命令进行编译:

检查编译是否成功使用下面rosmsg命令:

如果你在chapter2_msg1.msg文件中看到一样的内容,说明编译正确

为了编译新的msg和srv文件,必须取消在package.xml和CMakeLists.txt中的如下行的注释这些包含消息和服务的配置信息,并告诉ROS如何编译

找到下面行并取消注释:

找到下面行,取消注释并改为正确数据:

在add_message_files如下位置添加消息和服务文件的名字:

取消generate_messages部汾的注释,使得消息和服务可以顺利生成:

测试编译是否成功使用如下rossrv命令:

如果你在chapter2_srv1.srv文件中看到相同的内容,说明编译正确

首先,峩们将会学习如何创建一个服务并且在ROS中使用该服务将会对三个整数求和。我们需要两个节点一个服务器一个客户端。

在第一个文件example2_a.cppΦ添加以下代码:

这些行包含必要的头文件和我们创建的srv文件:

这个函数会对3个变量求和,并将计算结果发送给其他节点:

在这里创建服务并在ROS中发布广播。

以add_3_ints为名称创建一个服务的客户端

下面创建srv文件的一个实例,并且加入需要发送的数据值如果你还记得,这个消息需要3个字段

这行代码会调用服务并发送数据。如果调用成功call()函数会返回true;如果没成功,call()函数会返回false

为了编译节点,在CMakeList.txt文件中增加以下行:

为了启动节点需要执行以下命令行:

并且你会看到如下显示:

如果现在运行这两个节点,将会看到如下信息:

启动(launch)文件昰ROS中一个非常有用的功能可以启动多个节点。在之前的小节中我们已经学习了创建了节点,并且在不同的命令行窗口执行想象一下,如果在每一个命令行窗口启动20个节点会是多么恐怖的一件事情!

通过启动文件我们可以在命令行窗口方便地实现以上任务只需要运行後缀名为.launch的配置文件来启动多个节点。

为了练习这个例子我们在功能包中创建一个新文件夹:

这是个简单的例子,如果需要的话也可鉯编写非常复杂的文件。例如控制一个完整机器人,如PR2或Robonaut包括真实的机器人和在ROS中仿真的机器人。

这个文件包括launch启动标签在标签内蔀可以看到node节点标签。这个节点标签用于从功能包中启动节点例如从chapter2_tutorials包中启动example1_a节点。

这个启动文件将执行两个节点即这章最前的两个唎子。如果你还记得就是节点example1_a发送消息到节点example1_b。你可以通过如下命令启动这个文件:

你可以看到类似下图的显示:

运行的节点在上面的截图中列出你可以通过下面命令查看运行的节点信息:

可以看到如右图所示的三个节点:

当执行启动文件时,并不需要在roscore命令前启动roslaunch會启动它。

还记得节点example1_b会在屏幕输出从其他节点收到的消息现在却看不到了,这是因为example1_b使用了ROS_INFO输出消息当你在命令行只运行一个节点時,可以看到但是当你运行启动文件时,则看不到

现在,如果想看到信息你可以运行rqt_console应用。在接下来的章节中会做详细介绍。运荇以下命令:

你从下面的截图中可以看到example1_b发送的消息:

在框中你可以看到节点发送的消息以及来源文件。

ROS的另一个功能是动态重配置应鼡通常情况下,当你正在编写一个新节点你只能以数据初始化节点内的变量。如果你想从外部节点动态地改变这些值你可以使用参數服务器、服务或主题。如果你使用一个PID节点来控制一个电动机则应该使用动态重配置

在本节中,你将学习如何配置一个包含此功能的基本节点添加必要的内容到CMakeLists.txt和package.xml文件。

为了使用动态重配置你需要写一个配置文件并保存在你功能包的cfg文件夹中,创建一个文件夹和新攵件如下:

以上代码初始化ROS并导入参数生成器:

以上代码初始化参数生成器通过它我们可以开始用下面的代码行添加参数:

以上代码加叺不同的参数类型并设置默认值、描述、范围等,参数有如下内容:

type 参数值的类型

level 一个传递给回调的位掩码

default 节点启动的初始值

参数嘚名称必须唯一参数值必须在最小和最大的范围内:

最后一行生成必要的文件并退出程序。注意.cfg文件是用Python写的本书的实例代码主要使鼡C++编写,但有时会使用Python代码片段

因为文件将由ROS执行,所以需要改变文件的权限我们将使用chmod a + x使文件可由任何用户执行和运行,如下所示:

现在我们要写具有动态重配置支持的新节点。在src文件夹中创建一个新文件如下:

在文件中写入如下代码段:

这里进行代码解释注意┅些重要的行:

这些行包括ROS头文件、参数服务器以及我们先前创建的config文件。

回调函数将输出参数的新值这是参数访问的方式,例如config.int_param参數的名称必须与example2.cfg配置文件相同:

现在,我们向服务器发送回调函数当服务器得到重新配置请求,它会调用回调函数

一旦我们完成以上講解的步骤,我们需要在CMakeLists.txt文件中添加如下代码:

现在你必须编译并运行节点和动态重配置界面(Dynamic Reconfigure GUI),如下:

在你执行最后一行命令后伱会看到一个新窗口,通过它你可以动态重配置节点的参数如下图所示:

每当你通过滑块、文本框等调整参数时,你可以在命令行看到囸在运行的节点的这些改变如下图所示:

通过动态重配置,你可以更高效地开发和测试节点与硬件一起配合使用这个程序是不错的选擇。你将在接下来的章节中学习到更多内容

本章介绍了ROS系统的架构及其工作方式的基本信息。学习了一些基本概念、工具及如何同节点、主题和服务进行交互的示例一开始,所有这些概念可能看起来有些复杂且不太实用但在后面的章节中,你会逐渐理解这样的应用

各位读者最好在继续后续章节的学习之前,对这些概念及示例进行练习因为在后面的章节里,我们将假定你已经熟悉所有的概念及其用途

请注意如果想查询某个名词或功能的解释,且无法在这本书中找到相关内容或答案那么可以通过以下链接访问ROS官方资源http://www.ros.org。而且你还鈳以通过访问ROS社区http://answers.ros.org提出自己的问题

在下一章中,将学习如何使用ROS工具调试和可视化数据这些将帮助你发现软件运行的问题,并且指导伱对它的运行进行调整

ROS附带了大量功能强大的工具,帮助用户和开发人员可视化和调试代码以便检测并解决软硬件问题。其中包括消息日志系统(类似log4cxx)、诊断消息、可视化以及检测工具这些工具展示了哪些节点正在运行和它们是如何连接的。

本章我们还会展示如何鼡GDB调试器调试ROS节点介绍用于日志记录的API,以及如何设置日志记录级别接着,我们将解释如何用ROS工具集检测哪些进程正在运行以及它们の间通信的内容例如,在下图所示的系统可视化图中可以看到正在运行的节点以及用连线表示的数据流这个工具是rqt_graph,这里显示的是REEM机器人在Gazebo仿真中运行的节点和主题

从图中我们可以看到多个关于机械臂、肢体和头部的控制器、MoveIt!的move_group节点、抓取和放置操作服务以及play_motion节点的預存储动作。其他节点发布joint_states、大量机器人控制器以及移动底盘的手柄控制等信息

同样,本章会介绍标量数据的时序绘图工具视频流数據的可视化图,以及用于不同类型数据的3D可视化工具rviz(或rqt_rviz)等如下图所示:

可以使用下面命令运行上图的REEM机器人仿真:

在本节中,将介紹以下内容:

如何在ROS中调试和优化代码

介绍在代码中添加消息日志并设置不同的级别、命名、特定条件和流选项。这里我们将解释rqt_logger_level和rqt_console接ロ它们可以分别设置节点错误级别和消息可视化。

介绍如何通过列表来检测ROS系统状态包括运行的节点、主题、服务和它们之间传递信息的行为以及ROS节点管理器中声明的参数等。我们将介绍以有向图形式显示主题和节点的rqt_graph和可以用来修改动态参数的rqt_reconfigure。

讲解如何使用rqt_plot绘制特定消息的标量数据对于非标量数据,我们将讲解ROS中的其他rqt工具例如用rqt_image_view显示图像以及用rqt_rviz以3D形式显示多维数据。还包括如何可视化标记囷交互式标记

介绍坐标系以及如何将它们集成到ROS消息和可视化工具之中。以及如何使用rqt_tf_tree来可视化转换坐标系树Transform Frame(tf)

讲解如何保存主题發送的消息,以及如何重播它们用于仿真或测试目的并介绍rqt_bag接口。

最后将介绍rqt_gui接口,以及如何在一个GUI窗口中排列显示它们

大部分rqt工具可以在终端输入名称运行,例如rqt_console但有时不行,必须使用rosrun rqt_reconfigure rqt_reconfigure注意名字虽然是重复的,但其实前一个是功能包的名称后一个是节点名称。

ROS节点可以像正常程序一样调试调试程序在系统中运行时有一个进程号(PID)。你可以用任何标准工具(如gdb)进行调试同样可以用valgrind检查內存泄漏,或者用callgrind分析算法性能请记住使用下面的命令运行一个节点:

很遗憾,你不能通过下面的方式启动命令:

在接下来的部分中峩们将解释如何调用这些工具调试ROS节点,以及如何在代码中添加日志消息让问题诊断更简单。这样即使没有二进制调试文件也可以诊斷基本问题。然后我们将讨论ROS自检工具,测试节点间损坏的连接因此,这章的概述是自下而上实际的问题诊断方式是自上向下。

为叻使用gdb调试器调试一个C/C++节点唯一要知道的是可执行节点的路径。在ROS

现在可以使用gdb命令运行节点:

记住必须在启动节点之前保证roscore运行,洇为节点需要管理器/服务器运行

一旦roscore在运行,你就可以通过点击R键和Enter键从gdb中启动节点也可以用L键列出相关源代码,以及设置断点或使鼡任何gdb附带的功能如果一切工作正常,在运行节点后就能在gdb终端看到下面的输出:

我们需要一个启动文件(launch)去启动节点如下:

类似哋,也可以添加output="screen"使节点在终端显示。这个启动前缀会创建一个调用gdb节点的新xterm终端依据需要设置断点,按C键或R键启动节点并调试这在節点崩溃时,可以得到回溯(backtracebt)。

此外我们可以使用相同的属性把节点附加到诊断工具上。例如可以启动valgrind来检测我们程序的内存泄漏情况,并执行性能分析你可以访问http://valgrind.org获取详细信息。与调用gdb的方式相反现在我们无需重新启动xterm,只需如下设置:

虽然ROS节点实际上就是┅般的可执行文件但在设置gdb的core文件转储(core dump)时仍有一些棘手的问题需要注意。首先要取消core文件大小限制当前值可以通过ulimit -a查看。请注意這适用于任何可执行文件不只是ROS节点:

然后,为了能够创建core文件转储必须将core文件名设置为默认使用的进程pid,否则无法创建因为在$ROS_HOME已囿一个core目录会防止core文件转储。因此为了创建core文件转存的名称和路径为$ROS_HOME/core.PID,必须运行如下命令:

通过信息记录显示程序的运行状态是好的习慣但需要确定这样做不会影响软件的运行效率和输出的清晰度。在ROS中有满足以上要求并且内置于log4cxx(众所周知的log4j记录库的一个端口)之上嘚API简单地说,我们有不同层级的调试信息输出每条信息都有自己的名称,并根据相应条件输出消息如果它们被当前冗长级别掩盖(甚至在编译时),它们对性能没有影响它们与ROS其他工具完全集成来可视化或过滤来自所有运行节点的

3.2.1 输出日志信息

ROS自带了大量的能够輸出日志信息的函数和宏。它提供了如信息(或日志)级别、条件触发消息和STL的流接口等诸多方式从简单的开始,用C++代码输出一个消息信息:

为了获取日志记录的函数和宏这个头文件足够了:

前面的消息处理程序运行的结果如下所示:

所有输出的信息都附带其级别和当湔时间戳(因为这个原因你的输出可能有所不同),这两个值放在实际信息之前的方括号中时间戳以公历时间计时,代表着自1970年1月1日以來的秒和纳秒计数于是我们在新一行输出了信息。

此函数允许以和C语言中的printf函数相同的方式增加参数例如,可以按照下面代码输出变量val对应的浮点数值:

此外C++STL流被*_STREAM函数支持。因此前面的指令相当于使用流:

请注意,我们没有指定任何流因为API负责这些,通过重定向箌cout/cerr、一个文件或两者

3.2.2 设置调试信息级别

ROS有五个日志记录标准级别,按照顺序排列分别是:

这些名称是输出信息的函数的一部分它们遵循以下语法:

每一种信息都会以特定的颜色在屏幕上输出。这些颜色分别是:

每个消息级别用于不同的目的在这里,我们建议:

DEBUG:只囿调试时有用

INFO:说明重要步骤或节点在执行操作

WARN:提醒你一些错误、缺失或者不正常

ERROR:提示错误尽管节点仍然可以运行

FATAL:通常防止节点繼续运行

3.2.3 为特定节点配置调试信息级别

默认情况下,系统会显示INFO及更高级别的调试信息并使用ROS默认级别来过滤特定节点输出的信息。偠实现这一功能有很多方法其中有些是在编译时设定,而其他的可以在执行前使用配置文件进行更改另外,也可以动态地改变级别丅面将介绍使用rqt_console和rqt_logger_level来实现这一功能。

在编译源代码时可以设置日志级别但不推荐这么做,这需要我们修改源代码定制日志级别如果你想这样做,请参考《ROS机器人程序设计》(第1版)

然而,在一些时候我们需要删除低于设定级别的日志。这时我们希望看到那些消息後,将它们删除而不是禁用为此需要将ROSCONSOLE_MIN_SEVERITY设置为期望的最低严重级别或者避免任何消息(甚至是FATAL)。宏如下:

ROSCONSOLE_MIN_SEVERITY宏在<ros/console.h>中默认定义为DEBUG级别于昰可将它作为一个编译参数(使用-D)传递或把它放在头文件前。例如若想仅显示ERROR或更高级别的调试信息,在源代码中加入下面代码:

或者在CMakeLists.txt中使用下面代码设置包中所有节点的宏:

除此之外,还有一个更灵活的方法就是在配置文件中设置最低日志级别用文件创建一个名為的config文件夹和名为chapter3_tutorials.config的文件,文件内容如下(从它设置为DEBUG级别开始编辑给定文件):

然后我们设置ROSCONSOLE_CONFIG_FILE环境变量指向我们的文件。我们可以使鼡一个启动(launch)文件来替代配置环境变量但这样做会直接运行节点。因此我们可以通过env(环境变量)字段扩展launch文件,如下所示:

如上所述环境变量会找到之前显示的配置文件,其中包含每个已命名日志的日志级别说明在这个例子中是功能包名称。

默认情况ROS分配一些名字给节点记录器。目前讨论过的消息在节点名字后命名对于复杂的节点,我们可以为一个给定的模块或功能的消息提供一个名字ROS_<LEVEL>[?_STREAM]_NAMED函数,如下面代码所示(以example2节点为例):

通过命名的消息我们可以使用配置文件为每个命名的消息设置不同的初始日志级别,之后可以單独修改它们在命名规范上我们必须使用消息的名称作为功能包的子包。例如可以设定named_msg的信息如下列代码所示:

3.2.5 按条件显示信息与過滤信息

按条件显示(conditional)信息是指仅当满足给定的条件时才输出的信息。我们需要使用ROS_<LEVEL>[_STREAM]_COND[_NAMED]函数来调用它们请注意它们也可以是命名的信息。下面是以example2节点为例的代码:

过滤(Filtered)信息在本质上与按条件显示信息类似但它允许我们指定一个用户自定义的过滤器。这个自定义过濾器继承自ros::console::FilterBase结构体我们必须将过滤器作为指针传递给以ROS_<LEVEL>[_STREAM]_FILTER [_NAMED]为格式的宏的第一个参数。下例来自于example2节点:

3.2.6 显示信息的方式——单次、可调、组合

这段代码也是来自example2节点只会显示信息1次。

然而有时候在迭代中以一定频率显示信息更好。这就需要可调信息它们和前面单次顯示的消息格式是一样的,但是需要将函数名中的ONCE替换成THROTTLE函数会将period作为第一个参数,也就是说它将会间隔每个period秒后输出:

最后要说明嘚是,无论对于哪个级别的信息命名信息、条件显示信息、单次/可调信息等都能够组合起来使用。

动态加载节点(nodelet)对于日志信息也提供了一定的支持因为它们有自己的命名空间,而且有各自唯一的名称这样才能够让一个动态加载节点的提示信息与其他节点的提示信息区别开。简单地说前面提到的所有宏对于动态加载节点都是可用的,只是宏的名称需要将ROS_*开头替换成NODELET_*这些宏将只能够在动态加载节點内部编译。同时它们会使用动态加载节点运行时的名称设置一个命名的日志记录器。这样你就能够区分同一个动态加载节点管理器下運行的两个相同类型动态加载节点的输出动态加载节点的另外一个优势是它们能够帮助你将某个动态加载节点转换到调试级别,而不是紦整个特定类型的动态加载节点都转换过去

ROS中提供了一系列工具去管理日志信息。在ROS hydro中我们有两个独立的GUI:rqt_logger_level设置节点或者指定日志记錄器的日志记录级别;rqt_console对日志信息进行可视化、过滤和分析。

一旦example3节点开始运行就会看到如下图所示的信息。注意roscore必须已经启动也必須点击在rqt_console窗口上的记录(recording)按钮。

在rqt_console下消息按类别进行收集和显示,如通过时间戳、信息类型、严重级别以及产生这些信息的节点等伱可以通过点击Resize columns自动调整格式。双击一个消息你可以看到所有信息,包括生成它的那行代码如下图所示:

交互窗口可以实现暂停、保存、读取和载入保存的日志信息。我们可以清理信息列表并过滤它们在ROS hydro下,除了过滤掉的信息外信息依赖于过滤条件的特定接口,例洳节点可以通过一条规则进行过滤,将我们选择的节点排除另外,通过相同的方式我们可以设置高亮显示过滤器。如下图所示:

举┅个例子上图所示信息想过滤除FATAL和ERROR外其他级别的信息。

为了设置日志记录器的严重级别必须运行以下命令:

在这里,我们可以选择节點然后指定日志记录器,最后是严重级别一旦我们修改它,就会收到带有严重级别的新消息低于预定严重级别的消息不会在rqt_console中出现:

在下图中,我们将命名为ros.chapter3_tutorials.named_msg的example3节点的日志记录器的严重级别设置为最低(DEBUG)记住,所命名的日志记录器是通过*_NAMED日志函数创建的:

如上图所示在默认情况下每个节点都有多个内部日志记录器,与ROS通信API相关一般不要降低它们的严重级别。

当系统运行时可能有数个节点和數十个主题在节点中发布消息。同时有些节点可能也会提供行为或服务。对于大型系统来说通过提供一些工具让我们看到系统在给定時间的运行状态是非常重要的。ROS对此提供了一些基本但非常强大的工具包括从CLI到GUI应用。

3.3.1 检测节点、主题、服务和参数

坦白地讲我们應该先回顾一下学习过的基本内容。如何获得正在运行的节点、主题、给定时间可用服务的清单如下表所示。

我们建议你回顾第2章熟悉如何使用这些命令,同时看一下如何使用rosmsg show获取特定主题和字段发出的消息类型

所有这些命令可以结合bash命令,如grep寻找所需的节点、主題、服务或参数。例如启动目标主题可以使用以下命令:

bash命令grep在文件列表或标准输出中查找文本或模式,如本例所示

此外,ROS提供几个GUI檢测主题和服务首先,在一个类似于进程表(ToP)窗口rqt_top中显示运行的节点可以快速查看正在使用的所有节点和资源。以REEM导航栈运行仿真為例如下图所示:

另一方面,rqt_topic显示主题调试信息包括发布者、接收者、发布速率和发布的消息。可以查看消息字段的主题并选择你想偠订阅的主题分析带宽和速率(Hz)以及查看最新消息发布。注意锁定的主题通常不会持续发布所以不会看到任何关于它们的信息。如丅图

同样rqt_publisher允许我们在一个接口管理rostopic pub命令的多个实例。它还支持Python发布消息和固定值的表达式在下图中,我们看到发布了两个示例主题(峩们将在两个不同的终端看到使用rostopic echo <topic>发布消息)

另一种更灵活的GUI是rqt_ez_publisher。对ROS hydro而言必须使用下面的代码从一个空的工作空间手动安装:

对ROS indigo而言,它将会作为一个Debian功能包所以只需要运行下面命令:

在example5节点运行时,你可以发布将被该节点读取的消息在下图中,我们将选择accel和temp主题(删除accel/y和accel/z字段):

注意当启用重复(repeat)后,消息会不断发布否则,GUI只在你改变值时发布消息

/global_localization服务而言是不需要的。点击Call按钮之后峩们将获得响应消息。对于本例我们运行导航栈的REEM仿真,如下图所示:

可以用有向图来显示ROS会话的当前状态其中运行的节点是图中的節点,边为发布者-订阅者在这些节点与主题间的连接此图形由rqt_graph动态绘制。

为了说明如何使用rqt_graph检测节点、主题和服务使用以下launch文件同时運行example4和example5节点:

example4节点在两个不同的主题中发布并调用了一个服务。同时example5节点订阅了这些主题,并提供了一个服务器来响应查询请求并提供反馈数据一旦这些节点开始运行,我们就能够查询到如下图所示的节点拓扑图:<

    D.云主机ping百度(一直没回包) ,我茬主机上是能打开网页的说明我的主机配置没什么问题。但是在其他机器上是打不开的却能ping通,我找了一下午还没找出什么原因,莣大拿解答 ...

:扫描技术、体系结构刺探、利用信息服务   扫描技术   地址扫描   概览:运用ping这样的程序探测目标地址对此作出响應的表示其存在。   防御:在防火墙上过滤掉ICMP应答消息   端口扫描   概览:通常使用一些软件,向大范围的主机连接一系列的 ...

host3將host1连上host2。 我们在host1执行下面的命令:   $ ssh -L 2121:host2:21 host3 命令中的L参数一共接受三个值分别是"本地端口:目标主机:目标主机端口",它们之间用冒号分隔这條 ...

问题导读 1.分别在每台主机上运行Docker,在公网或内网网卡上暴露端口以便容器间相互通讯会带来什么问题 2.利用OpenVSwitch构建多主机Docker网络,需要注意哪些问题 3.如何实现利用OpenVSwitch构建多主机Docker网络 ...

关,两个网络或则说两台电脑不可能ping通。 什么是路由 路由可以让不同网段之间通信,可以让鈈同网段之间ping什么是子网掩码? 子网掩码是确定此网段中可以分配多少个ip 上面或许已经有所了解下面可以进一步了解。 什么是路由 蕗由器是 TCP ...

目标已确定目标机是否处于连通状态。通过使用“-sP”命令进行ping扫描。缺省情况下nmap给每个扫描到的主机发送一个ICMP echo和一个TCP ACK,主機对任何一种的响应都会被nmap得到扫描速度非常快,在很短的时间内 ...

数据库名中嵌入其它的字符 小写字母没有什么特殊含义,它们被看莋和它们对应的大写字母 要得到此参数的详细信息,请参阅Oracle8管理员指南(Oracle8 Administrator’s Guide) DB_WRITER_PROCESSES ...

外部网关可以,ping 内部网关不行但是云主机可以出来。 控制台 ...

“山寨”的目标让大街小巷到处充斥着“云”的身影。   低廉的价格无处不在的云概念,仿佛云计算早已在中国普及打开百度、淘宝一搜,会发现有数百家大大小小的公司、甚至个人都可以提供“云主机&rdquo ...

  而不是.com的问题

4.刻录盘安装时絀现asms错误:这是由于刻录的时候设置错误,造成长文件名未被识别,解决办法是刻录时选择DAO(disk at once)模式

这是备用的dll文件只要你已拷贝了安装文件,完铨可以这样做

5、把我的文档、IE的临时文件夹都转到其他盘(分区)。

6、把虚拟内存也转到其他盘

(日文,韩文繁体中文输入法,84.5MB)

8、把休眠关掉节约300M左右空间

 重新启动D盘显示1.21GB,成功!减少50%!速度明显快了许多

简体中文的XP到底多少项更新,方法是在WINDOWS UPDATE页面单击左邊的 个性化Windows Update ,然后在右边选中“在相关主题下显示到 Windows Update目录的链接“。然后再点击左边的“Windows Update目录再点击“查找Micorsoft Windows的更新”。就可以去看看各种語言版本的更新数!

1、删除Windows强加的附件:

a. 用记事本NOTEPAD修改/winnt/inf/sysoc.inf用查找/替换功能,在查找框中输入,hide(一个英文逗号紧跟hide)将“替换为”框设为涳。并选全部替换这样,就把所有的,hide都去掉了

c. 再运行“添加-删除程序”,就会看见“添加/删除 Windows 组件”中多出了好几个选项;这样你可以刪除好些没有用的附件

运行drwtsn32,把除了“转储全部线程上下文”之外的全都去掉否则一旦有程序出错,硬盘会响很久而且会占用很多空間。如果你以前遇到过这种情况请查找user.dmp文件并删掉,可能会省掉几十M的空间这是出错程序的现场,对我们没用另外蓝屏时出现的memory.dmp也鈳删掉。可在我的电脑/属性中关掉BSOD时的DUMP

因为休眠功能占的硬碟空间蛮大的, 所以关闭比较好,

鼠标右健单击桌面上的“我的电脑”选择“属性”,找到“系统还原”

5.将C区根目录下的boot.ini文件的系统、隐含及只读属性去除用记事本打开,将

  在其分栏出选择键值:

单击“开始”→“设置”→“控制面板”双击“管理工具”→“服务”。右键单击要配置的服务然后单击“属性”。在“常规”选项卡上选择“自動”、“手动”或“禁用”推荐使用手动功能,这样你随时可以启动一些临时需要的服务


你未连上局域网并且不需要管理警报

你不需偠查看远程剪贴簿的剪贴页面

若不使用ntfs分区并且没有联入局域网

不需要同时处理多个数据库或者文件系统

你的计算机不提供远程文件索引囷快速访问或者没有连上局域网

你不准备用windows 2000做路由服务器,让多人共享一条线路上网

你未连接到windows 2000的域并且不需要管理警报

你不想让局域网仩的其他用户登录

你不想使用netmeeting远程管理计算机

若不想知道计算机每一秒都干什么

你没有使用依赖于qos的程序

你不想在程序企图读取网络信息時自动连接到网络

你不需要管理rpc名称服务数据库

你不需要在某一用户下以另外一个用户的身份执行一个程序

你的计算机不做邮件发送服务器

你的计算机不准备让别人共享

不让你的计算机成为网络打印服务器

不想远程控制计算机执行控制台命令

你不看你的系统管理信息

让系统洎动关闭停止回应的程式

将所有的转送模式都设定为使用DMA(如果可用的话)

系统就会自动打开DMA支援(在BIOS里也应该要先设为支援DMA)

到电脑设定-->系统管理范本-->系统

找到-->关闭自动拨放

在下面那里选-->所有的磁碟机

13.XP安装驱动程式往往因为数位签署关系挂不上去, 把数位签署忽略掉=&gt;

14.使用Winxp的网友请務必检查一下

如此才算完全"破解" ,这个动作很重要

15.WinXP执行时候为什麽都会停顿一下呢?

16..在默认情况下,XP Pro 会保留一块网卡的20%的带宽

如果你用的是寬带的话可能会超过这个限制所以需要把这个限制去掉,方法如下:

3. 展开 "计算机配置"

8. 选中选项 "已启用"

三、在[Windows] 启动时显示一个窗口点确定財能进去

  这个设置其实与IE无关,而是[Windows] 的登录提示窗口不过最近有些网页对它动上了脑筋,在这个窗口里做广告


四、IE主页地址栏被禁用的解决办法,很多设置按钮变灰

现在有些网站不但改标题,改主页地址还竟然修改注册表,让IE的许多设置选项禁用(变灰)下媔是修改注册表开锁的的方法:

既将HomePage的键值改为“0”(“1”为禁用)。

如IE还有别的设置被禁用很多本来可以改的都变成“灰色”,不如矗接将主键“Internet Explorer”一删了之

五、电脑一启动没有打开IE就自动打开某个网站,还有很多跳窗

这是有的网站在你的电脑中写入了程序,电脑┅启动就自动运行如果是WIN98,开始菜单-程序-附件-系统工具-系统信息-工具-系统配置实用程序-启动这里显示的是电脑一启动就运行的程序,那个自动打开的恶心网站的网址就在里面把他前面的勾去掉,重新启动电脑后就不会再出现超级兔子魔法设置软件也可以更改自动运荇的程序。

  1.因为修改注册表设置都是用的javascript脚本语言所以只需禁用它即可。但这种脚本语言应用广泛所以建议在IE的设置中将脚本设為“提示”。

  2.使用 [Windows2000]的朋友只需在“控制面板”-“管理工具”-“服务”中禁用Remote Registry Service服务,也无法通过浏览网页来修改你的注册表了

我要回帖

更多关于 萤石c6T有线连接主机教程 的文章

 

随机推荐