• ROS教程


    Learning ROS 学习ROS

    Depending on your learning style and preferences, you can take two approaches to learning ROS: 根据你的学习风格和喜好,你可以采取两种方法来学习ROS:

    • Start the Tutorials - Dive in right away and start working with ROS.  一种是直接开始上手操作ROS (教程:http://wiki.ros.org/ROS/Tutorials)

    • Get an Overview - Read through this written overview of ROS and its capabilities. 另一种是先学习概念再上手(ROS简介:http://wiki.ros.org/ROS/Introduction)

    To get an immediate start with a pre-prepared ROS virtual machine, please see here: http://www.clearpathrobotics.com/blog/how-to-guide-ros-101/

    要想使用ROS虚拟机快速开始,请看这里:http://www.clearpathrobotics.com/blog/how-to-guide-ros-101/

    For more detailed information on the ROS framework, see the core ROS documentation.

    对于ROS框架的更多详细信息,请看ROS内核教程:http://wiki.ros.org/ROS

    以上内容翻译自:http://wiki.ros.org/ROS/StartGuide

    Finding Answers 找答案

    There are three places to look for answers to your questions and problems. The first is this wiki. Try the Search feature located at the top right.

    有三个地方可以寻找问题的答案。第一个就是这里wiki.ros.org。试着使用右上角的Search搜索功能。

    If you can't find a solution to your problem, then try searching http://answers.ros.org or the archived mailing list. Ask a question on http://answers.ros.org/ask

    如果你在wiki.ros.org搜索不到,那么试一下到http://answers.ros.org搜索一下,或者在archived mailing list(http://lists.ros.org/lurker/list/ros-users.en.html)搜索一下。或着在http://answers.ros.org/ask提问。

    Check out the Support page for more information.

    看一下支持页面寻找更多信息。

    Finding Code 寻找代码

    Wondering if there is already a ROS package out there that does what you need? The Browse Software tool also lets search for useful packages. You can also browse the list of public ROS repositories to look for groups doing similar work.  

    想知道是否已经有你所想要的ROS package开发包了?“浏览软件”工具允许你搜索有用的源码包:http://www.ros.org/browse/。你还可以浏览公共ROS资料库列表查找做相同工作的群体:http://wiki.ros.org/RecommendedRepositoryUsage/CommonGitHubOrganizations。

    How to use this wiki 如何使用该wiki

    See navigating the wiki tutorial for more information.

    看wiki教程导航查看更多信息:http://wiki.ros.org/ROS/Tutorials/NavigatingTheWiki。

    ROS Tutorials ROS教程

    Non-Beginners: If you're already familiar enough with ROS fuerte or earlier versions and only want to explore the new build system introduced in groovy and used in hydro and later, called catkin, you can go through more in-depth catkin tutorial here. However, going over all basic Beginner Level tutorials is still recommended for all users to get exposed to new features.  非新手:如果你已经很熟悉ROS fuerte(第5版ROS系统)或者早先的版本了,只是希望探索groovy(第6版ROS系统)介绍的、在hydro(第7版ROS系统)及其后使用的新的建立系统,叫做catkin,你可以浏览更多深度解析的catkin教程:http://wiki.ros.org/catkin/Tutorials。但是,仍然建议所有的使用者可以浏览所有基本的初学级别的教程,从而掌握所有的新功能:http://wiki.ros.org/ROS/Tutorials#Beginner_Level。

    If you are new to Linux: You may find it helpful to first do a quick tutorial on common command line tools for linux. A good one is here.

    如果你是一个Linux新手:首先快速的学习基本的Linux命令行工具是有帮助的。一个好的教程请看这里:http://www.ee.surrey.ac.uk/Teaching/Unix/。

    以下内容来自:http://wiki.ros.org/ROS/Tutorials

    1. Core ROS Tutorials 内核ROS教程

    1.1 Beginner Level 新手水平

    1. Installing and Configuring Your ROS Environment 建立并配置你的ROS环境

    This tutorial walks you through installing ROS and setting up the ROS environment on your computer.

    该教程将带你建立ROS并配置你电脑中的ROS环境。

    (1)Install ROS 安装ROS

    Note:If you installed ROS from a package manager like apt, then those packages will not be write accessible and should not be edited by you the user. When working with ROS packages from source or when creating a new ROS package, you should always work in a directory that you have access to, like your home folder.

    注意:如果你通过像apt这样的包管理器建立ROS的话,那么这些包将不能被写而且不能被使用者所编辑。当跟源ROS包工作或者当创建一个新的 ROS包时,你应该总是在能够接触到的路径中工作,比如你的home文件夹中。

    (2)Managing Your Environment管理你的环境

    During the installation of ROS, you will see that you are prompted to source one of several setup.*sh files, or even add this 'sourcing' to your shell startup script. This is required because ROS relies on the notion of combining spaces using the shell environment. This makes developing against different versions of ROS or against different sets of packages easier.

    在安装ROS过程中,你会看到你被建议建立几个启动.*sh文件中的一个,或者甚至添加这个sourcing到你的shell开始脚本中。这个是因为ROS依赖于使用shell环境来将多个空间结合起来的思想。这使得开发违背ROS的不同版本,或者违背不同包的集合更加容易。

    If you are ever having problems finding or using your ROS packages make sure that you have your environment properly setup. A good way to check is to ensure that environment variables like ROS_ROOT and ROS_PACKAGE_PATH are set:

    $ printenv | grep ROS

    如果对查找和使用ROS包有问题的话,情确保你已经将你的环境恰当地建立起来了。一个好的检查方式确保环境变量像ROS_ROOT和ROS_PACKAGE_PATH已经设置:

    $ printenv | grep ROS

    If they are not then you might need to 'source' some setup.*sh files.

    如果它们还没有设置,那么你可能需要‘源’这些setup.*sh文件:

    Environment setup files are generated for you, but can come from different places: 环境设置文件是为你生成的,但是可能来自不同的地方:

     Note: Throughout the tutorials you will see references to rosbuild and catkin. These are the two available methods for organizing and building your ROS code. Generally, rosbuild is easy to use and simple, where as catkin uses more standard CMake conventions, so it is more sophisticated, but provides more flexibility especially for people wanting to integrate external code bases or who want to release their software. For a full break down visit catkin or rosbuild.

    注意:贯穿本教程你将会看到关于rosbuild和catkin的参考。这些是两个对于管理和建立你的ROS代码可用的方法。一般来讲,rosbuild是容易用而且简单的,而catkin使用了更加标准的CMake协议,所以它更加复杂,但是它提供了更多弹性的尤其是对于想要集成外部代码底层的人们或者是想要发布他们的软件的人们来说。对于完整的解析请看:catkin or rosbuild:http://wiki.ros.org/catkin_or_rosbuild。

    If you just installed ROS from apt on Ubuntu then you will have setup.*sh files in '/opt/ros/<distro>/', and you could source them like so:

    如果你只是通过apt在Ubuntu上安装ROS,那么你将会在“/opt/ros/<distro>/”中拥有setup.*sh文件,并且你可以将它们源起来像这样:

    $ source /opt/ros/<distro>/setup.bash

    Using the short name of your ROS distribution instead of <distro> 使用你的ROS版本的短名称代替<distro>,这里distro是Kinetic(第十版的ROS版本)

    If you installed ROS Kinetic, that would be:如果你安装了ROS Kinetic,那么将会是

    $ source /opt/ros/kinetic/setup.bash

    You will need to run this command on every new shell you open to have access to the ROS commands, unless you add this line to your .bashrc. This process allows you to install several ROS distributions (e.g. indigo and kinetic) on the same computer and switch between them.

    你将需要在每一个你打开的新的shell运行这个命令来运行ROS命令,除非你已经将这一行加进了你的.bashrc中了。这个过程允许你在一个电脑上安装多个ROS包(比如indigo和kinetic),并且在他们中间切换。

    On other platforms you will find these setup.*sh files wherever you installed ROS.

    在其它平台上,无论你在哪里安装ROS你都将发现这些setup.*sh文件。

    (3)Create a ROS Workspace 建立你的一个ROS工作空间

    These instructions are for ROS Groovy and later. For ROS Fuerte and earlier, select rosbuild.

    这些指导是为ROS Groovy及其以后的版本的。对于ROS Fuerte和早期版本,需要选择rosbuild。

    Let's create a catkin workspace: 让我们创建一个catkin工作空间:

     

    $ mkdir -p ~/catkin_ws/src  //主目录下创建一个catkin_ws/src目录
    $ cd ~/catkin_ws/src    //走到catkin_ws/src目录下
    $ catkin_init_workspace     //初始化该工作空间

    Even though the workspace is empty (there are no packages in the 'src' folder, just a single CMakeLists.txt link) you can still "build" the workspace: 尽管这个工作空间是空的(在这个'src'文件夹下没有任何的包,只有一个CMakeLists.txt链接),但是你依然可以“建立”这个工作空间:

     

      $ cd ~/catkin_ws/ //走到catkin_ws/目录下

      $ catkin_make //catkin_make建立该工作空间

     

    The catkin_make command is a convenience tool for working with catkin workspaces. If you look in your current directory you should now have a 'build' and 'devel' folder. Inside the 'devel' folder you can see that there are now several setup.*sh files. Sourcing any of these files will overlay this workspace on top of your environment. To understand more about this see the general catkin documentation: catkin. Before continuing source your new setup.*sh file:

    catkin_make命令是一个在catkin workspaces工作空间工作中方便的工具。如果你看一下你当前的目录你现在应该有了一个'build'和一个'devel'文件夹。在'devel'文件夹下你可以看到有几个setup.*sh文件。源这些文件中的任何一个将会将该工作空间铺盖到你环境的顶部。为了理解更多,你可以看一下通用的catkin参考资料:catkin:http://wiki.ros.org/catkin。在源你新建的setup.*sh文件之前:

     $ source devel/setup.bash

    To make sure your workspace is properly overlayed by the setup script, make sure ROS_PACKAGE_PATH environment variable includes the directory you're in.

    为了确保你的工作空间适当地由setup脚本覆盖起来,请确保ROS_PACKAGE_PATH环境变量包括你所在的目录。

    $ echo $ROS_PACKAGE_PATH
    /home/youruser/catkin_ws/src:/opt/ros/kinetic/share:/opt/ros/kinetic/stacks

    Now that your environment is setup, continue with the ROS file system tutorial.

    现在你的环境已经安装成功了,那么继续ROS文件系统的教程吧。

    
    

    2. Navigating the ROS Filesystem 浏览你的ROS文件系统

    This tutorial introduces ROS filesystem concepts, and covers using the roscd, rosls, and rospack commandline tools.

    该教程将介绍ROS文件系统的概念,并且覆盖使用roscd,rosls,和rospack命令行工具。

    (1)前提

    For this tutorial we will inspect a package in ros-tutorials, please install it using 要完成这个教程我们将检查ros-tutorials中的一个包,请使用以下方法安装它:

    $ sudo apt-get install ros-<distro>-ros-tutorials

    Replace '<distro>' with the name of your ROS distribution (e.g. hydro, groovy, electric, fuerte etc.)

    (2)文件系统概念快速浏览

    • Packages: Packages are the software organization unit of ROS code. Each package can contain libraries, executables, scripts, or other artifacts. 包:包是ROS代码的软件组织单元。每一个包都可能包含库文件、执行文件、脚本或者其他的工件。
    • Manifests (package.xml): A manifest is a description of a package. It serves to define dependencies between packages and to capture meta information about the package like version, maintainer, license, etc...  Manifest文件(package.xml):一个Manifest文件是对于包的描述。它用于定义包之间的依赖,以及抓捕关于包的元信息,比如版本号、保持者、版权等等

     

    Show    Note about stacks

    (3)文件系统工具

    Code is spread across many ROS packages. Navigating with command-line tools such as ls and cd can be very tedious which is why ROS provides tools to help you.

    代码是遍布许多ROS包的。使用命令行工具浏览比如ls和cd将可能是非常冗长的,所以ROS提供了工具来帮助你。

    1)使用rospack

    rospack allows you to get information about packages. In this tutorial, we are only going to cover the find option, which returns the path to package.

    rospack允许你获取关于包的信息。在该教程中,我们只是涉及find查找选项,用于返回包的路径。

    Usage:用法:

    $ rospack find [package_name]

    Example: 例子:

    $ rospack find roscpp

    would return: 将返回:(这里是:/opt/ros/kinetic/share/roscpp)

    YOUR_INSTALL_PATH/share/roscpp

    If you installed ROS from apt on Ubuntu Linux you would see exactly: 如果你通过apt在Ubuntu Linux上安装的ROS,那么你将看到:

    /opt/ros/kinetic/share/roscpp

    2)使用roscd

    roscd is part of the rosbash suite. It allows you to change directory (cd) directly to a package or a stack.

    roscd是rosbash包的一部分。它允许你更改目录(cd)直接到一个包或者一个集中。

    Usage: 用法

    $ roscd [locationname[/subdir]] 

    To verify that we have changed to the roscpp package directory, run this example:

    要验证我们已经更改到了roscpp包目录下,运行这个例子:

    $ roscd roscpp

    Now let's print the working directory using the Unix command pwd:现在让我们使用Unix命令pwd来打印工作目录:

    $ pwd

    You should see: 你将会看到:(这里是:/opt/ros/kinetic/share/roscpp)

    • YOUR_INSTALL_PATH/share/roscpp

    You can see that YOUR_INSTALL_PATH/share/roscpp is the same path that rospack find gave in the previous example.

    你可以看到YOUR_INSTALL_PATH/share/roscpp正是rospack find在之前的例子中给出的。

    Note that roscd, like other ROS tools, will only find ROS packages that are within the directories listed in your ROS_PACKAGE_PATH. To see what is in your ROS_PACKAGE_PATH, type: 注意roscd,像其他的ROS工具一样,将只能查找在你的ROS_PACKAGE_PATH中列出的目录中的ROS包。要查看在你的ROS_PACKAGE_PATH中有什么,请输入:

    $ echo $ROS_PACKAGE_PATH

    Your ROS_PACKAGE_PATH should contain a list of directories where you have ROS packages separated by colons. A typical ROS_PACKAGE_PATH might look like this:

    Usage:你的ROS_PACKAGE_PATH应该包括一系列的ROS包的目录,由冒号分隔。一个典型的ROS_PACKAGE_PATH可能像这样:

    /opt/ros/kinetic/base/install/share:/opt/ros/kinetic/base/install/stacks

    Similarly to other environment paths, you can add additional directories to your ROS_PACKAGE_PATH, with each path separated by a colon ':'.

    类似于其他的环境路径,你可以添加额外的路径到你的ROS_PACKAGE_PATH中,每个路径由分割符号“:”隔开。

    Subdirectories子路径

    roscd can also move to a subdirectory of a package or stack. roscd还能移动到一个包或者集的子路径。

    Try:尝试:

    $ roscd roscpp/cmake
    $ pwd

    You should see: 你应该可以看到:

    • YOUR_INSTALL_PATH/share/roscpp/cmake

    3)roscd log

    roscd log will take you to the folder where ROS stores log files. Note that if you have not run any ROS programs yet, this will yield an error saying that it does not yet exist.

    If you have run some ROS program before, try:

    roscd log将带你到ROS存储log文件的文件夹中。注意如果你还没有运行任何ROS程序的话,这个将发出一个讲它还不存在的错误。

    如果你之前已经运行了一些ROS程序的话,尝试:

    $ roscd log

    4)使用rosls

    rosls is part of the rosbash suite. It allows you to ls directly in a package by name rather than by absolute path.

    rosls是rosbash套件的一部分。它允许你在一个包中列出而不用绝对路径。

    Usage: 用法:

    $ rosls [locationname[/subdir]]

    Example: 例子:

    $ rosls roscpp_tutorials

    would return: 将会返回:

    cmake launch package.xml srv

    5)制表符完成

    It can get tedious to type out an entire package name. In the previous example, roscpp_tutorials is a fairly long name. Luckily, some ROS tools support TAB completion.

    它可以从一个完整的包名中得到冗长的类型。在之前的例子中,roscpp_tutorials是一个很长的名字。幸运的是,一些ROS工具支持“TAB完成”。

    Start by typing: 试着敲下:

    $ roscd roscpp_tut<<< now push the TAB key >>>

    After pushing the TAB key, the command line should fill out the rest:

    $ roscd roscpp_tutorials/

    This works because roscpp_tutorials is currently the only ROS package that starts with roscpp_tut. 这工作了,因为roscpp_tutorials是当前ROS包中唯一以roscpp_tut开始的包。

    Now try typing:现在试着敲下:

    $ roscd tur<<< now push the TAB key >>>

    After pushing the TAB key, the command line should fill out as much as possible:

    在你敲下TAB键时,命令行应该尽可能地填充:

    $ roscd turtle

    However, in this case there are multiple packages that begin with turtle. Try typing TAB another time. This should display all the ROS packages that begin with turtle: 但是,在这种情况下有多个包以turtle开头。试着敲下TAB键。这可能会显示出所有的以turtle开头的ROS包:

     

    turtle_actionlib/  turtlesim/         turtle_tf/

     On the command line you should still have:在命令行你应该仍有:

    $ roscd turtle

    Now type an s after turtle and then push TAB:现在在turtle后面键入一个s,然后按TAB键:

    $ roscd turtles<<< now push the TAB key >>>

    Since there is only one package that starts with turtles, you should see: 既然只有一个包以turtles开头,你应该会看到

    $ roscd turtlesim/

     (4)Review复习

    You may have noticed a pattern with the naming of the ROS tools: 你可能已经注意到ROS工具命名的模式:

    • rospack = ros + pack(age) 
    • roscd = ros + cd
    • rosls = ros + ls

    This naming pattern holds for many of the ROS tools. 这种命名模式支持很多的ROS工具。

    Now that you can get around in ROS, let's create a package. 现在你已经对ROS有了了解了,那让我们创建一个包吧。

     

    3. Creating a ROS Package 建立一个ROS包

    This tutorial covers using roscreate-pkg or catkin to create a new package, and rospack to list package dependencies.

    该教程包括使用roscreate-pkg或者catkin来创建一个新的包,或者使用rospack来列出包的依赖。

    (1)什么才能组成一个catkin包?

    For a package to be considered a catkin package it must meet a few requirements: 要使一个包被当成一个catkin包,它需要满足几个要求:

    • The package must contain a catkin compliant package.xml file. 这个包必须包含一个catkin compliant package.xml文件。

      • That package.xml file provides meta information about the package.  这个package.xml文件提供关于该包的元信息。
    • The package must contain a CMakeLists.txt which uses catkin. If it is a catkin metapackage it must have the relevant boilerplate CMakeLists.txt file. 该包必须包含一个使用catkin的CMakeLists.txt文件。如果这是一个catkin元包的话,它必须有相关的模板化CMakeLists.txt文件。

    • There can be no more than one package in each folder.在每个文件夹下不能有超过一个的包。
      • This means no nested packages nor multiple packages sharing the same directory. 这意味着不允许嵌套的包或者多个包共享一个目录。

    The simplest possible package might have a structure which looks like this: 最简单的包可能是有一个像这样的结构:

    my_package/
      CMakeLists.txt
      package.xml

    (2)在一个catkin工作空间中的包

    The recommended method of working with catkin packages is using a catkin workspace, but you can also build catkin packages standalone. A trivial workspace might look like this: 跟catkin包工作建议的方法是使用一个catkin工作空间,但是你也可以单独生成catkin包。一个一般的工作空间可能是像这样:

    • workspace_folder/        -- WORKSPACE  //工作空间
        src/                   -- SOURCE SPACE   //源空间
          CMakeLists.txt       -- 'Toplevel' CMake file, provided by catkin //顶层的CMake文件,由catkin提供
          package_1/
            CMakeLists.txt     -- CMakeLists.txt file for package_1 //包_1中的CMakeLists.txt
            package.xml        -- Package manifest for package_1 //包_1中的包manifest
          ...
          package_n/
            CMakeLists.txt     -- CMakeLists.txt file for package_n //包_n中的CMakeLists.txt
            package.xml        -- Package manifest for package_n //包_n中的包manifest

    Before continuing with this tutorial create an empty catkin workspace by following the Creating a workspace for catkin tutorial.在继续本教程之前创建一个空的catkin工作空间,按照创建一个catkin工作空间教程:http://wiki.ros.org/catkin/Tutorials/create_a_workspace。

    (3)创建一个catkin包

    This tutorial will demonstrate how to use the catkin_create_pkg script to create a new catkin package, and what you can do with it after it has been created.

    本教程将会阐述如何使用catkin_create_pkg脚本来创建一个新的包,以及创建之后你用它做什么。

    First change to the source space directory of the catkin workspace you created in the Creating a Workspace for catkin tutorial:

    首先更改到创建的catkin工作空间的源空间目录中。

    # You should have created this in the Creating a Workspace Tutorial
    $ cd ~/catkin_ws/src

    Now use the catkin_create_pkg script to create a new package called 'beginner_tutorials' which depends on std_msgs, roscpp, and rospy:

    现在使用catkin_create_pkg脚本来创建一个新的包叫做“beginner_tutorials”,它依赖于std_msgs, roscpp和rospy。

    $ catkin_create_pkg beginner_tutorials std_msgs rospy roscpp

    This will create a beginner_tutorials folder which contains a package.xml and a CMakeLists.txt, which have been partially filled out with the information you gave catkin_create_pkg. 这将会创建一个beginner_tutorials文件夹,其中包括一个package.xml和一个CMakeLists.txt文件,它们已经使用你给catkin_create_pkg的信息填充了一部分。

    catkin_create_pkg requires that you give it a package_name and optionally a list of dependencies on which that package depends:

    catkin_create_pkg要求你给它一个包的名字,可选择性地一列依赖(该包所依赖的依赖)。

    # This is an example, do not try to run this
    # catkin_create_pkg <package_name> [depend1] [depend2] [depend3]

    catkin_create_pkg also has more advanced functionalities which are described in catkin/commands/catkin_create_pkg.

    catkin_create_pkg还有更多高级的功能,在catkin/commands/catkin_create_pkg(http://wiki.ros.org/catkin/commands/catkin_create_pkg)中描述。

    (4)生成一个catkin工作空间,并且源setup文件

    Now you need to build the packages in the catkin workspace:

    现在你需要在catkin工作空间中生成包

    $ cd ~/catkin_ws
    $ catkin_make

    After the workspace has been built it has created a similar structure in the devel subfolder as you usually find under /opt/ros/$ROSDISTRO_NAME.

    在工作空间已经生成之后,它已经在devel子文件夹下创建了一个相似的结构,就像你经常在/opt/ros/$ROSDISTRO_NAME 下看到的一样。

    To add the workspace to your ROS environment you need to source the generated setup file:

    要将该工作空间添加到你的ROS环境中,你需要将这些生成的setup文件源起来:

     

    $ . ~/catkin_ws/devel/setup.bash

    (5)包依赖

    1)第一顺序依赖

    When using catkin_create_pkg earlier, a few package dependencies were provided. These first-order dependencies can now be reviewed with the rospack tool.

    在早些时候使用catkin_create_pkg时,有几个包依赖被提供了出来。这些第一顺序的依赖现在可以使用rospack工具回顾。

    $ rospack depends1 beginner_tutorials 
    • std_msgs
      rospy
      roscpp

    As you can see, rospack lists the same dependencies that were used as arguments when running catkin_create_pkg. These dependencies for a package are stored in the package.xml file: 就像你看到的一样,rospack列出了运行catkin_create_pkg时被当做参数使用的相同的依赖。一个包的这些依赖存储在package.xml文件中:

     

    $ roscd beginner_tutorials
    $ cat package.xml
    <package>
    ...
      <buildtool_depend>catkin</buildtool_depend>
      <build_depend>roscpp</build_depend>
      <build_depend>rospy</build_depend>
      <build_depend>std_msgs</build_depend>
    ...
    </package>

     2)间接依赖

    In many cases, a dependency will also have its own dependencies. For instance, rospy has other dependencies.

     在很多情况下,一个依赖也会有它自己的依赖。比如,rospy有其他的依赖。

    $ rospack depends1 rospy
    • genpy
      rosgraph
      rosgraph_msgs
      roslib
      std_msgs

    A package can have quite a few indirect dependencies. Luckily rospack can recursively determine all nested dependencies.

    一个包可能有好几个间接的依赖。幸运地是,rospack可以递归地决定所有嵌套的依赖。

    $ rospack depends beginner_tutorials
    cpp_common
    rostime
    roscpp_traits
    roscpp_serialization
    genmsg
    genpy
    message_runtime
    rosconsole
    std_msgs
    rosgraph_msgs
    xmlrpcpp
    roscpp
    rosgraph
    catkin
    rospack
    roslib
    rospy

    (6)自定义你的包

    This part of the tutorial will look at each file generated by catkin_create_pkg and describe, line by line, each component of those files and how you can customize them for your package.

    这部分教程将检查由catkin_create_pkg生成的每一个文件,然后一行一行地描述这些文件的每一个组件以及你如何才能为你的包自定义它们。

    1)自定义package.xml

    The generated package.xml should be in your new package. Now lets go through the new package.xml and touch up any elements that need your attention.

    生成的package.xml应该在你的新包里。现在让我们看一下新的package.xml,对元素做一点符合你要求的小修改。

    description tag 描述标签

    First update the description tag: 首先更新一下描述标签:

     

    Toggle line numbers
       5   <description>The beginner_tutorials package</description>
    

     

    Change the description to anything you like, but by convention the first sentence should be short while covering the scope of the package. If it is hard to describe the package in a single sentence then it might need to be broken up.

    将描述更改为你喜欢的任何内容,但是按照惯例第一行应该简短描述包的覆盖内容范围。如果很难一句话描述包的话,那么它可能需要断句。

    maintainer tags 维护者标签

    Next comes the maintainer tag:  接下来是维护者标签:

     

    Toggle line numbers
       7   <!-- One maintainer tag required, multiple allowed, one person per tag --> 
       8   <!-- Example:  -->
       9   <!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
      10   <maintainer email="user@todo.todo">user</maintainer>
    

     

    This is a required and important tag for the package.xml because it lets others know who to contact about the package. At least one maintainer is required, but you can have many if you like. The name of the maintainer goes into the body of the tag, but there is also an email attribute that should be filled out:

     这是对package.xml来说需要的而且是重要的标签,因为它让其他人知道向谁联系该包。至少需要一个维护者,但是你可以加你想加的任意多个。维护者的名称在标签的body内部,但是还有一个email属性你需要填写一下:

    Toggle line numbers
       7   <maintainer email="you@yourdomain.tld">Your Name</maintainer>
    

    license tags 许可标签

    Next is the license tag, which is also required: 接下来是许可标签,这也是需要的:

     

    Toggle line numbers
      12   <!-- One license tag required, multiple allowed, one license per tag -->
      13   <!-- Commonly used license strings: -->
      14   <!--   BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
      15   <license>TODO</license>
    

     

    You should choose a license and fill it in here. Some common open source licenses are BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, and LGPLv3. You can read about several of these at the Open Source Initiative. For this tutorial we'll use the BSD license because the rest of the core ROS components use it already:

    你应该选择一个许可将它填在这里。一些通常的开源许可有BSD,MIT,Boost Software License,GPLv2,GPLv3,LGPLv2.1,和LGPLv3。你可以在Open Source Initiative读到这几个: http://opensource.org/licenses/alphabetical。对于本教程我们将使用BSD许可因为核心的ROS组件已经使用了它:

    Toggle line numbers
       8   <license>BSD</license>
    

    dependencies tags 依赖标签

    The next set of tags describe the dependencies of your package. The dependencies are split into build_depend, buildtool_depend, run_depend, test_depend. For a more detailed explanation of these tags see the documentation about Catkin Dependencies. Since we passed std_msgs, roscpp, and rospy as arguments to catkin_create_pkg, the dependencies will look like this:

    下一个标签描述了你的包的依赖项。依赖项被分成了build_depend(生成依赖),buildtool_depend(生成工具_依赖),run_depend(运行依赖),test_depend(测试依赖)。要想更详细地了解这些标签请看Catkin Dependencies(Catkin依赖)参考资料:http://wiki.ros.org/catkin/package.xml#Build.2C_Run.2C_and_Test_Dependencies。既然我们传递了std_msgs, roscp,和rospy作为catkin_create_pkg的参数,那么依赖项将看上去像这个样子:

     

    Toggle line numbers
      27   <!-- The *_depend tags are used to specify dependencies -->
      28   <!-- Dependencies can be catkin packages or system dependencies -->
      29   <!-- Examples: -->
      30   <!-- Use build_depend for packages you need at compile time: -->
      31   <!--   <build_depend>genmsg</build_depend> -->
      32   <!-- Use buildtool_depend for build tool packages: -->
      33   <!--   <buildtool_depend>catkin</buildtool_depend> -->
      34   <!-- Use run_depend for packages you need at runtime: -->
      35   <!--   <run_depend>python-yaml</run_depend> -->
      36   <!-- Use test_depend for packages you need only for testing: -->
      37   <!--   <test_depend>gtest</test_depend> -->
      38   <buildtool_depend>catkin</buildtool_depend>
      39   <build_depend>roscpp</build_depend>
      40   <build_depend>rospy</build_depend>
      41   <build_depend>std_msgs</build_depend>
    

     

    All of our listed dependencies have been added as a build_depend for us, in addition to the default buildtool_depend on catkin. In this case we want all of our specified dependencies to be available at build and run time, so we'll add a run_depend tag for each of them as well:

    所有我们列出的依赖都已经作为build_depend(生成依赖)加进了,除了默认的buildtool_depend(生成工具依赖)填的是catkin。而因为我们希望所有的特殊的依赖项都可以获得在build和run期间,所以我们还要为每一个都加一个run_depend标签:

     

    Toggle line numbers
      12   <buildtool_depend>catkin</buildtool_depend>
      13 
      14   <build_depend>roscpp</build_depend>
      15   <build_depend>rospy</build_depend>
      16   <build_depend>std_msgs</build_depend>
      17 
      18   <run_depend>roscpp</run_depend>
      19   <run_depend>rospy</run_depend>
      20   <run_depend>std_msgs</run_depend>
    

    Final package.xml 最终的package.xml

    As you can see the final package.xml, without comments and unused tags, is much more concise:

    如你能看到的最终的package.xml,去掉了评论和没用到的标签之后,更加的简洁了:

     

    Toggle line numbers
       1 <?xml version="1.0"?>
       2 <package>
       3   <name>beginner_tutorials</name>
       4   <version>0.1.0</version>
       5   <description>The beginner_tutorials package</description>
       6 
       7   <maintainer email="you@yourdomain.tld">Your Name</maintainer>
       8   <license>BSD</license>
       9   <url type="website">http://wiki.ros.org/beginner_tutorials</url>
      10   <author email="you@yourdomain.tld">Jane Doe</author>
      11 
      12   <buildtool_depend>catkin</buildtool_depend>
      13 
      14   <build_depend>roscpp</build_depend>
      15   <build_depend>rospy</build_depend>
      16   <build_depend>std_msgs</build_depend>
      17 
      18   <run_depend>roscpp</run_depend>
      19   <run_depend>rospy</run_depend>
      20   <run_depend>std_msgs</run_depend>
      21 
      22 </package>
    

     2)自定义CMakeLists.txt

    Now that the package.xml, which contains meta information, has been tailored to your package, you are ready to move on in the tutorials. The CMakeLists.txt file created by catkin_create_pkg will be covered in the later tutorials about building ROS code.

    既然package.xml,其中包含元信息,已经裁剪到你的包了,你现在可以继续接下来的教程了。对于由catkin_create_pkg创建的CMakeLists.txt文件将会在后续关于生成ROS代码的时候涉及到。

    Now that you've made a new ROS package, let's build our ROS package.

    现在你已经制作了一个新的ROS包,那么让我们开始生成我们的ROS包吧。

    4. Building a ROS Package 生成一个ROS包

    This tutorial covers the toolchain to build a package.

    该教程是介绍使用toolchain来生成一个包。

    (1)生成包

    As long as all of the system dependencies of your package are installed, we can now build your new package. 只要包的系统依赖都安装了,那么就可以生成新包了。

     

    Note: If you installed ROS using apt or some other package manager, you should already have all of your dependencies.如果你使用apt或其他包管理器安装的ROS,那么依赖项均已经安装好了

    Before continuing remember to source your environment setup file if you have not already. On Ubuntu it would be something like this:

    继续之前记得源一下环境setup文件如果你还没有源的话。在Ubuntu上,它是这样的:

     

    $ source /opt/ros/%YOUR_ROS_DISTRO%/setup.bash
    $ source /opt/ros/kinetic/setup.bash             (For Kinetic for instance) 

     1)Using catkin_make使用catkin_make

    catkin_make is a command line tool which adds some convenience to the standard catkin workflow. You can imagine that catkin_make combines the calls to cmake and make in the standard CMake workflow. catkin_make是一个为标准catkin工作流带来方便的命令行工具。

    Usage: 用法:

     

    # In a catkin workspace
    $ catkin_make [make_targets] [-DCMAKE_VARIABLES=...]

    For people who are unfamiliar with the standard CMake workflow, it breaks down as follows:

    对于不熟悉标准CMake工作流的人来说,它可以分解成如下:

    Note: If you run the below commands it will not work, as this is just an example of how CMake generally works.

    注意:如果你运行以下命令它将不能工作,因为这只是一个关于CMake大概如何工作的例子。

     

    # In a CMake project
    $ mkdir build
    $ cd build
    $ cmake ..
    $ make
    $ make install  # (optionally)

    This process is run for each CMake project. In contrast catkin projects can be built together in workspaces. Building zero to many catkin packages in a workspace follows this work flow:

    这个过程适用于在每个CMake工程中进行。相比之下多个catkin工程能够在工作空间中一起生成。从一个工作空间中的0到许多catkin包生成来说可以遵循这个工作流程:

     

    # In a catkin workspace
    $ catkin_make
    $ catkin_make install  # (optionally)

    The above commands will build any catkin projects found in the src folder. This follows the recommendations set by REP128. If your source code is in a different place, say my_src then you would call catkin_make like this:

    以上命令将生成在src文件夹中的所能发现的任何catkin工程。这符合REP128的建议。如果你的源代码放在不同的地方,比如说my_src那么你可以像以下这样调用catkin_make:

    Note: If you run the below commands it will not work, as the directory my_src does not exist.

    注意:如果你运行以下命令它将不能工作,因为目录my_src并不存在。

     

    # In a catkin workspace
    $ catkin_make --source my_src
    $ catkin_make install --source my_src  # (optionally)

    For more advanced uses of catkin_make see the documentation: catkin/commands/catkin_make

    对于catkin_make的更多高级使用,请看资料:catkin/commands/catkin_make:http://wiki.ros.org/catkin/commands/catkin_make。

    2)Building Your Package 生成你的包

    For readers of this page who are about to build your own codes, please also take a look at later tutorial (C++)/(Python) since you may need to modify CMakeLists.txt.

    对于想要生成自己代码的文本的读者,请再看一下后面的教程(C++)/(Python),因为你可能需要修改CMakeLists.txt。

    You should already have a catkin workspace and a new catkin package called beginner_tutorials from the previous tutorial, Creating a Package. Go into the catkin workspace if you are not already there and look in the src folder:

    通过之前的教程(创建一个包)你应该已经有一个catkin工作空间和一个叫beginner_tutorials的catkin包了 。进入catkin工作空间,如果你还没有在那里的话,看一下src文件夹:

    $ cd ~/catkin_ws/
    $ ls src
    • beginner_tutorials/  CMakeLists.txt@  

    You should see that there is a folder called beginner_tutorials which you created with catkin_create_pkg in the previous tutorial. We can now build that package using catkin_make: 你应该看到有一个你之前用catkin_create_pkg创建的叫beginner_tutorials的文件夹。我们现在可以使用catkin_make生成那个包:

     

    $ catkin_make

    You should see a lot of output from cmake and them make, which should be similar to this:

    你应该看到从cmake生成并输出了很多内容, 它应该像这样的:

    Base path: /home/user/catkin_ws
    Source space: /home/user/catkin_ws/src
    Build space: /home/user/catkin_ws/build
    Devel space: /home/user/catkin_ws/devel
    Install space: /home/user/catkin_ws/install
    ####
    #### Running command: "cmake /home/user/catkin_ws/src
    -DCATKIN_DEVEL_PREFIX=/home/user/catkin_ws/devel
    -DCMAKE_INSTALL_PREFIX=/home/user/catkin_ws/install" in "/home/user/catkin_ws/build"
    ####
    -- The C compiler identification is GNU 4.2.1
    -- The CXX compiler identification is Clang 4.0.0
    -- Checking whether C compiler has -isysroot
    -- Checking whether C compiler has -isysroot - yes
    -- Checking whether C compiler supports OSX deployment target flag
    -- Checking whether C compiler supports OSX deployment target flag - yes
    -- Check for working C compiler: /usr/bin/gcc
    -- Check for working C compiler: /usr/bin/gcc -- works
    -- Detecting C compiler ABI info
    -- Detecting C compiler ABI info - done
    -- Check for working CXX compiler: /usr/bin/c++
    -- Check for working CXX compiler: /usr/bin/c++ -- works
    -- Detecting CXX compiler ABI info
    -- Detecting CXX compiler ABI info - done
    -- Using CATKIN_DEVEL_PREFIX: /tmp/catkin_ws/devel
    -- Using CMAKE_PREFIX_PATH: /opt/ros/kinetic
    -- This workspace overlays: /opt/ros/kinetic
    -- Found PythonInterp: /usr/bin/python (found version "2.7.1") 
    -- Found PY_em: /usr/lib/python2.7/dist-packages/em.pyc
    -- Found gtest: gtests will be built
    -- catkin 0.5.51
    -- BUILD_SHARED_LIBS is on
    -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    -- ~~  traversing packages in topological order:
    -- ~~  - beginner_tutorials
    -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    -- +++ add_subdirectory(beginner_tutorials)
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /home/user/catkin_ws/build
    ####
    #### Running command: "make -j4" in "/home/user/catkin_ws/build"
    ####

    Note that catkin_make first displays what paths it is using for each of the 'spaces'. The spaces are described in the REP128 and by documentation about catkin workspaces on the wiki: catkin/workspaces. The important thing to notice is that because of these default values several folders have been created in your catkin workspace. Take a look with ls:

    注意catkin_make首先展示了什么路径它用来为每一个空间。这些空间在REP128里以及在catkin wiki中关于catkin工作空间的参考资料中描述了。值得注意的重要事情是由于这些默认的值几个文件夹已经在你的catkin工作空间中创建了。使用ls来看一下吧:

     

    $ ls
    • build
      devel
      src

    The build folder is the default location of the build space and is where cmake and make are called to configure and build your packages. The devel folder is the default location of the devel space, which is where your executables and libraries go before you install your packages.

    build文件夹是生成空间的默认位置,是调用cmake和make来配置和生成你的包的地方。devel文件夹是devel空间的默认位置,是你的执行文件和类库在你安装你的包之前去的地方。

    Now that you have built your ROS package let's talk more about ROS Nodes.

    现在已经生成了你的ROS包,那么让我们谈论一下ROS节点吧。

    5. Understanding ROS Nodes 理解ROS节点

    This tutorial introduces ROS graph concepts and discusses the use of roscore, rosnode, and rosrun commandline tools.

    该教程介绍ROS图的概念,并且讨论了roscore, rosnode和rosrun命令工具的用法。

    (1)前提

    For this tutorial we will use a lightweight simulator, please install it using

    对于该教程我们将使用一个轻量的模拟器,情使用以下命令安装它:

    $ sudo apt-get install ros-<distro>-ros-tutorials

    Replace '<distro>' with the name of your ROS distribution (e.g. indigo, jade, kinetic)请用你的版本名称代替其中的'<distro>'。

    (2)快速浏览图的概念

    • Nodes: A node is an executable that uses ROS to communicate with other nodes. 节点:节点是一个执行过程,它使用ROS来跟其他节点交流。

    • Messages: ROS data type used when subscribing or publishing to a topic. 信息:当订阅或者发布到一个主题时使用的ROS数据类型。

    • Topics: Nodes can publish messages to a topic as well as subscribe to a topic to receive messages.  主题:节点除了可以订阅一个主题接收消息外还能够发布消息到一个主题上。

    • Master: Name service for ROS (i.e. helps nodes find each other) 管理者:ROS的名称服务。(比如,帮助节点寻找对方节点)

    • rosout: ROS equivalent of stdout/stderr  rosout:等同于stdout/stderr的ROS。

    • roscore: Master + rosout + parameter server (parameter server will be introduced later)  roscore:管理者+rosout+参数服务器(参数服务器后面会介绍)。

     (3)节点

    A node really isn't much more than an executable file within a ROS package. ROS nodes use a ROS client library to communicate with other nodes. Nodes can publish or subscribe to a Topic. Nodes can also provide or use a Service.

    一个节点实际上只是一个ROS包内的执行文件。ROS节点使用一个ROS用户类库来与其他节点交流。节点能够发布或者订阅主题。节点也可以提供或者使用一个服务。

    (4)用户类库

    ROS client libraries allow nodes written in different programming languages to communicate:

    ROS用户类库允许节点以不同的编程语言编写,从而实现交流:

    • rospy = python client library
    • roscpp = c++ client library

    (5)roscore ROS内核

    roscore is the first thing you should run when using ROS.

    roscore是你使用ROS时你应该运行的第一个事情

    Please run: 情运行:

    $ roscore

    You will see something similar to:你将会看到类似这样的事情:

    ... logging to ~/.ros/log/9cf88ce4-b14d-11df-8a75-00251148e8cf/roslaunch-machine_name-13039.log
    Checking log directory for disk usage. This may take awhile.
    Press Ctrl-C to interrupt
    Done checking log file disk usage. Usage is <1GB.
    
    started roslaunch server http://machine_name:33919/
    ros_comm version 1.4.7
    
    SUMMARY
    ======
    
    PARAMETERS
     * /rosversion
     * /rosdistro
    
    NODES
    
    auto-starting new master
    process[master]: started with pid [13054]
    ROS_MASTER_URI=http://machine_name:11311/
    
    setting /run_id to 9cf88ce4-b14d-11df-8a75-00251148e8cf
    process[rosout-1]: started with pid [13067]
    started core service [/rosout]

    If roscore does not initialize, you probably have a network configuration issue. See Network Setup - Single Machine Configuration

    如果roscore不能够初始化,你可能有一个网络配置问题。请看网络设置-单个机器配置:http://www.ros.org/wiki/ROS/NetworkSetup#Single_machine_configuration。

    If roscore does not initialize and sends a message about lack of permissions, probably the ~/.ros folder is owned by root, change recursively the ownership of that folder with:

    如果roscore不能够初始化,并且发送缺乏允许的消息,也许~/.ros文件夹是由root拥有的,递归地改变那个文件夹的拥有权:

     

    $ sudo chown -R <your_username> ~/.ros

    (6)使用rosnode

    Open up a new terminal, and let's use rosnode to see what running roscore did...

     打开一个新的终端,让我们使用rosnode来看一下运行roscore是做什么的...

    Note: When opening a new terminal your environment is reset and your ~/.bashrc file is sourced. If you have trouble running commands like rosnode then you might need to add some environment setup files to your ~/.bashrc or manually re-source them.

    注意:当打开一个新的终端时你的环境被重置了,你的~/.bashrc文件被源了。如果你运行像rosnode这样的命令遇到了问题,那么你可能需要添加一些环境setup文件到你的~/.bashrc中或者人工地重源它们。

    rosnode displays information about the ROS nodes that are currently running. The rosnode list command lists these active nodes:

    rosnode展示了你现在正在运行的ROS节点信息。

     

    $ rosnode list
    • You will see: 你将会看到:
    • /rosout

    This showed us that there is only one node running: rosout. This is always running as it collects and logs nodes' debugging output.

    这向我们展示了只有一个节点运行:rosout。这是总在运行着的,因为它收集并且将节点的调试输出记录到日志中。

    The rosnode info command returns information about a specific node.

    rosnode info命令返回关于一个特殊节点的信息。

     

    $ rosnode info /rosout

    This gave us some more information about rosout, such as the fact that it publishes /rosout_agg.

    这给我们一些更多的关于rosout的信息,比如它发布/rosout_agg的事情。

    ------------------------------------------------------------------------
    Node [/rosout]
    Publications:
     * /rosout_agg [rosgraph_msgs/Log]
    
    Subscriptions:
     * /rosout [unknown type]
    
    Services:
     * /rosout/set_logger_level
     * /rosout/get_loggers
    
    contacting node http://machine_name:54614/ ...
    Pid: 5092

    Now, let's see some more nodes. For this, we're going to use rosrun to bring up another node.

    现在,让我们看更多的节点。对于这个,我们将使用rosrun来带出另一个节点。

    (7)使用rosrun

    rosrun allows you to use the package name to directly run a node within a package (without having to know the package path).

    rosrun允许你使用包名来直接运行一个包中的一个节点(不需要知道包的路径)。

    Usage: 使用方法:

     

    $ rosrun [package_name] [node_name]

    So now we can run the turtlesim_node in the turtlesim package.

    所以现在我们可以运行turtlesim包的turtlesim_node。

    Then, in a new terminal:

    然后,在一个新的终端:

     

    $ rosrun turtlesim turtlesim_node

    You will see the turtlesim window: 你会看到turtlesim的窗口:

    • turtlesim.png

    NOTE: The turtle may look different in your turtlesim window. Don't worry about it - there are many types of turtle and yours is a surprise!

    In a new terminal:

    注意:乌龟可能在你的窗口中看上去不一样。不要担心,有很多类型的乌龟,你的只是一个惊喜!

    在新的终端:

     

    $ rosnode list

    You will see something similar to: 你会看到类似这样的:

    • /rosout
      /turtlesim

    One powerful feature of ROS is that you can reassign Names from the command-line.

    ROS一个强大的特点是你可以从命令行重命名名字。

    Close the turtlesim window to stop the node (or go back to the rosrun turtlesim terminal and use ctrl-C). Now let's re-run it, but this time use a Remapping Argument to change the node's name:

    关掉turtlesim窗口停止该节点(或者返回到rosrun turtlesim终端,使用ctrl-C)。现在让我们重启它,但是这一次使用一个Remapping Argument来更改节点的名字:

     

    $ rosrun turtlesim turtlesim_node __name:=my_turtle

    Now, if we go back and use rosnode list:现在,如果我们回去,使用rosnode list:

    $ rosnode list
    • You will see something similar to:
    • /rosout
      /my_turtle

     Note: If you still see /turtlesim in the list, it might mean that you stopped the node in the terminal using ctrl-C instead of closing the window, or that you don't have the $ROS_HOSTNAME environment variable defined as described in Network Setup - Single Machine Configuration. You can try cleaning the rosnode list with: $ rosnode cleanup

    注意:如果你还是能在列表里看到/turtlesim,那么可能意味着你是使用ctrl -C停止的该终端节点而没有关上窗口,或者你不具备“网络Setup-单机器配置”中所描述的$ROS_HOSTNAME环境变量。你可以试着使用$ rosnode cleanup清理rosnode列表。

    We see our new /my_turtle node. Let's use another rosnode command, ping, to test that it's up:

    我们看到我们新的/my_turtle节点。让我们使用另一个rosnode命令,ping,来测试是否打开着:

     

    $ rosnode ping my_turtle
    rosnode: node is [/my_turtle]
    pinging /my_turtle with a timeout of 3.0s
    xmlrpc reply from http://aqy:42235/     time=1.152992ms
    xmlrpc reply from http://aqy:42235/     time=1.120090ms
    xmlrpc reply from http://aqy:42235/     time=1.700878ms
    xmlrpc reply from http://aqy:42235/     time=1.127958ms

    (8)复习

    What was covered: 讲了以下内容:

    • roscore = ros+core : master (provides name service for ROS) + rosout (stdout/stderr) + parameter server (parameter server will be introduced later)
    • rosnode = ros+node : ROS tool to get information about a node.
    • rosrun = ros+run : runs a node from a given package.

    Now that you understand how ROS nodes work, let's look at how ROS topics work. Also, feel free to press Ctrl-C to stop turtlesim_node.

    现在你已经理解了ROS节点工作的原理,那么让我们来看一下ROS主题是如何工作的。而且,让我们尽管按Ctrl -C终止turtlesim_node吧。

    6. Understanding ROS Topics 理解ROS主题

    This tutorial introduces ROS topics as well as using the rostopic and rqt_plot commandline tools.

    该教程不仅介绍了使用rostopic和rqt_plot命令行工具,还介绍了ROS主题。

    (1)安装

    1)roscore

    Let's start by making sure that we have roscore running, in a new terminal:

    让我们首先确保roscore运行着,在新的终端:

    $ roscore

    If you left roscore running from the last tutorial, you may get the error message:

    如果你上一次教程遗留着roscore运行着的话,你可能会得到错误的信息:

    • roscore cannot run as another roscore/master is already running. 
      Please kill other roscore/master processes before relaunching

    This is fine. Only one roscore needs to be running.

    这是可以的。只有一个roscore需要运行着。

    2)turtlesim

    For this tutorial we will also use turtlesim. Please run in a new terminal:

    对于本教程我们还是使用turtlesim。所以请在新的终端运行以下命令:

    $ rosrun turtlesim turtlesim_node

    3)turtle键盘遥控操作

    We'll also need something to drive the turtle around with. Please run in a new terminal:

    我们还需要一点东西来使turtle启动。请在新的终端输入:

    $ rosrun turtlesim turtle_teleop_key
    • [ INFO] 1254264546.878445000: Started node [/teleop_turtle], pid [5528], bound on [aqy], xmlrpc port [43918], tcpros port [55936], logging to [~/ros/ros/log/teleop_turtle_5528.log], using [real] time
      Reading from keyboard
      ---------------------------
      Use arrow keys to move the turtle.

    Now you can use the arrow keys of the keyboard to drive the turtle around. If you can not drive the turtle select the terminal window of the turtle_teleop_key to make sure that the keys that you type are recorded.

    现在你可以使用键盘的箭头键来驱动来驱动乌龟运动。如果你不能驱动乌龟的话,请选择turtle_teleop_key的终端窗口来确保你输入的按键能够被记录下来。

    turtle_key.png

    Now that you can drive your turtle around, let's look at what's going on behind the scenes.

    现在你已经能够驱动乌龟运动了,让我们来看一下在画面背后的所进行的事情吧。

    (2)ROS主题

    The turtlesim_node and the turtle_teleop_key node are communicating with each other over a ROS Topic. turtle_teleop_key is publishing the key strokes on a topic, while turtlesim subscribes to the same topic to receive the key strokes. Let's use rqt_graph which shows the nodes and topics currently running.

    turtlesim_node和turtle_teleop_key节点之间是通过一个ROS主题进行交流的。turtle_teleop_key将键盘敲击发送到一个主题上,turtlesim订阅相同的主题来接收键盘敲击。让我们使用rqt_graph,它展示了当前正在运行着的节点和主题。

    Note: If you're using electric or earlier, rqt is not available. Use rxgraph instead.

    注意:如果你正在使用electric或早先使用过,rqt是不可用的。使用rxgraph作为替代。

    1)使用rqt_graph

    rqt_graph creates a dynamic graph of what's going on in the system. rqt_graph is part of the rqt package. Unless you already have it installed, run:

    rqt_graph创建了一个系统内如果进行的动态图。rqt_graph是rqt包的一部分。如果你还没有安装它,运行:

    • $ sudo apt-get install ros-<distro>-rqt
      $ sudo apt-get install ros-<distro>-rqt-common-plugins

    replacing <distro> with the name of your ROS distribution (indigo, jade, kinetic) 将<distro>替换为你的ROS包的版本如:kinetic.

    In a new terminal:在一个新的终端:

    $ rosrun rqt_graph rqt_graph

    You will see something similar to: 你将会看到类似这样的东西:

    rqt_graph_turtle_key.png

    If you place your mouse over /turtle1/command_velocity it will highlight the ROS nodes (here blue and green) and topics (here red). As you can see, the turtlesim_node and the turtle_teleop_key nodes are communicating on the topic named /turtle1/command_velocity.

    如果你将你的鼠标放到/turtle1/command_velocity,它将高亮显示ROS节点(这里是蓝和绿)和主题(这里是红)。正如你所看到的,turtlesim_node和turtle_teleop_key节点之间通过主题/turtle1/command_velocity来进行交流。

    rqt_graph_turtle_key2.png

     2)介绍rostopic

    The rostopic tool allows you to get information about ROS topics.

    rostopic工具允许你获取ROS主题的信息。

    You can use the help option to get the available sub-commands for rostopic

    你可以使用帮助help选项来获取可使用的rostopic子命令。

    $ rostopic -h
    • rostopic bw     display bandwidth used by topic  显示主题的带宽
      rostopic echo   print messages to screen   打印消息到屏幕
      rostopic hz     display publishing rate of topic    显示主题的发布频率
      rostopic list   print information about active topics   打印动态主题的信息
      rostopic pub    publish data to topic   将数据发布到主题
      rostopic type   print topic type   打印主题类型

    Let's use some of these topic sub-commands to examine turtlesim.

     让我们使用这些主题子命令中的一些来测试turtlesim吧。

     3)使用rostopic echo

    rostopic echo shows the data published on a topic.

    rostopic echo显示发布到主题上的数据。

    Usage: 用法:

    rostopic echo [topic]

    Let's look at the command velocity data published by the turtle_teleop_key node.

    让我们看一下由turtle_teleop_key节点发布的command velocity data。

    For ROS Hydro and later, this data is published on the /turtle1/cmd_vel topic. In a new terminal, run:

    对于ROS Hydro和之后的版本,数据是发布到/turtle1/cmd_vel主题的。在一个新的终端,运行:

    $ rostopic echo /turtle1/cmd_vel

    For ROS Groovy and earlier, this data is published on the /turtle1/command_velocity topic. In a new terminal, run:

    对于ROS Groovy和早先的版本,数据是发布到/turtle1/command_velocity主题的。在一个新的终端,运行:

    $ rostopic echo /turtle1/command_velocity

    You probably won't see anything happen because no data is being published on the topic. Let's make turtle_teleop_key publish data by pressing the arrow keys. Remember if the turtle isn't moving you need to select the turtle_teleop_key terminal again. 你可能看不到有任何事情发生,因为还没有数据发布到主题上呢。让我们通过按箭头键使turtle_teleop_key发布数据。

    For ROS Hydro and later, you should now see the following when you press the up key:

    对于ROS Hydro和之后的版本,当你按向上键的时候你现在应该看到以下的内容:

    linear: 
      x: 2.0
      y: 0.0
      z: 0.0
    angular: 
      x: 0.0
      y: 0.0
      z: 0.0
    ---
    linear: 
      x: 2.0
      y: 0.0
      z: 0.0
    angular: 
      x: 0.0
      y: 0.0
      z: 0.0
    ---

    For ROS Groovy and earlier, you should now see the following when you press the up key:

    对于ROS Groovy和早先的版本,当你按向上键的时候你现在应该看到以下的内容:

    ---
    linear: 2.0
    angular: 0.0
    ---
    linear: 2.0
    angular: 0.0
    ---
    linear: 2.0
    angular: 0.0
    ---
    linear: 2.0
    angular: 0.0
    ---
    linear: 2.0
    angular: 0.0

    Now let's look at rqt_graph again. Press the refresh button in the upper-left to show the new node. As you can see rostopic echo, shown here in red, is now also subscribed to the turtle1/command_velocity topic.

     现在让我们再次看一下rqt_graph。按一下左上方的刷新按钮显示新的节点。你能够看到rostopic echo,在这里红色显示的,现在也被订阅到了turtle1/command_velocity主题上。

    rqt_graph_echo.png

     4)使用rostopic list

    rostopic list returns a list of all topics currently subscribed to and published.

    rostopic list返回一列当前被订阅的和发布了的所有主题。

    Let's figure out what argument the list sub-command needs. In a new terminal run:

    让我们弄清楚list子命令需要什么参数。在一个新终端运行:

    $ rostopic list -h
    • Usage: rostopic list [/topic]
      
      Options:
        -h, --help            show this help message and exit
        -b BAGFILE, --bag=BAGFILE
                              list topics in .bag file
        -v, --verbose         list full details about each topic
        -p                    list only publishers
        -s                    list only subscribers

    For rostopic list use the verbose option: 对于rostopic list使用verbose选项:

    $ rostopic list -v

    This displays a verbose list of topics to publish to and subscribe to and their type. 它显示了一个详细的发布的和订阅的主题列表。

    Published topics:
     * /turtle1/color_sensor [turtlesim/Color] 1 publisher
     * /turtle1/command_velocity [turtlesim/Velocity] 1 publisher
     * /rosout [roslib/Log] 2 publishers
     * /rosout_agg [roslib/Log] 1 publisher
     * /turtle1/pose [turtlesim/Pose] 1 publisher
    
    Subscribed topics:
     * /turtle1/command_velocity [turtlesim/Velocity] 1 subscriber
     * /rosout [roslib/Log] 1 subscriber

     (3)ROS消息

    Communication on topics happens by sending ROS messages between nodes. For the publisher (turtle_teleop_key) and subscriber (turtlesim_node) to communicate, the publisher and subscriber must send and receive the same type of message. This means that a topic type is defined by the message type published on it. The type of the message sent on a topic can be determined using rostopic type.

    主题上的交流通过节点之间发送ROS消息产生。对于发布者(turtle_teleop_key)和订阅者(turtlesim_node)之间的交流,发布者和订阅者必须发送和接收同种类型的消息。这意味着一个主题类型是由发布的消息类型定义的。发布到一个主题的消息的类型可以通过使用rostopic type来决定。

    1)使用rostopic type

    rostopic type returns the message type of any topic being published.

    rostopic type返回发布的任何主题的消息类型。

    Usage: 用法:

    rostopic type [topic]

    For ROS Hydro and later,对于ROS Hydro和之后的版本,

    • Try: 尝试:
      $ rostopic type /turtle1/cmd_vel
      • You should get: 你应该得到:
        geometry_msgs/Twist

      We can look at the details of the message using rosmsg: 我们可以通过使用rosmsg看下消息的详细信息:

      $ 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

    For ROS Groovy and earlier, 对于ROS Groovy和早先的版本:

    • Try: 尝试:
      $ rostopic type /turtle1/command_velocity
      • You should get:
        turtlesim/Velocity

      We can look at the details of the message using rosmsg:

      $ rosmsg show turtlesim/Velocity
      • float32 linear
        float32 angular

    Now that we know what type of message turtlesim expects, we can publish commands to our turtle.

     现在我们已经知道了turtlesim所期望的消息的类型,我们可以将命令发布到我们的turtle上了。

     (4)补充rostopic

    Now that we have learned about ROS messages, let's use rostopic with messages.

    现在我们已经学习了ROS消息,让我们开始使用带有消息的rostopic吧。

     1)使用rostopic pub

    rostopic pub publishes data on to a topic currently advertised.

    rostopic pub发布数据到一个当前公布的主题上。

    Usage: 用法:

    rostopic pub [topic] [msg_type] [args]

    For ROS Hydro and later, example: 对于ROS Hydro和之后的版本,例子:

    $ rostopic pub -1 /turtle1/cmd_vel geometry_msgs/Twist -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]'

    For ROS Groovy and earlier, example: 对于ROS Groovy和早先的版本,例子:

    $ rostopic pub -1 /turtle1/command_velocity turtlesim/Velocity  -- 2.0  1.8

    The previous command will send a single message to turtlesim telling it to move with an linear velocity of 2.0, and an angular velocity of 1.8 .

    之前的命令将发送一个消息给turtlesim告诉它要以线速度2.0,角速度1.8的速度来运动。

    turtle(rostopicpub).png

    This is a pretty complicated example, so lets look at each argument in detail.

    这是一个相当复杂的例子,让我们仔细地看下每一个参数。

    For ROS Hydro and later, 对于ROS Hydro和之后的版本,

    • This command will publish messages to a given topic:  这个命令将消息发布到一个给定的主题上:

      rostopic pub
    • This option (dash-one) causes rostopic to only publish one message then exit: 这个选项(-1)让rostopic只发布一个消息然后退出:

       -1 
    • This is the name of the topic to publish to: 这个是发布到的主题的名字:

      /turtle1/cmd_vel
    • This is the message type to use when publishing to the topic: 这个是发布到主题时要使用的消息类型:

      geometry_msgs/Twist
    • This option (double-dash) tells the option parser that none of the following arguments is an option. This is required in cases where your arguments have a leading dash -, like negative numbers.这个选项(双破折号)告诉选项剖析器接下来的参数没有一个是一个选项。这在你的参数有一个先导破折号-时是需要的,比如说负数。

      --
    • As noted before, a geometry_msgs/Twist msg has two vectors of three floating point elements each: linear and angular. In this case, '[2.0, 0.0, 0.0]' becomes the linear value with x=2.0, y=0.0, and z=0.0, and '[0.0, 0.0, 1.8]' is the angular value with x=0.0, y=0.0, and z=1.8. These arguments are actually in YAML syntax, which is described more in the YAML command line documentation. 正如之前所提示的,一个geometry_msgs/Twist消息有两个各有三个浮点型点要素的矢量:线性的和角度的。在这个例子中,'[2.0, 0.0, 0.0]'变成了x=2.0,y=0.0和z=0.0的线性值,'[0.0, 0.0, 1.8]'是一个x=0.0, y=0.0和z=1.8的角度值。这些参数实际上是以YAML的语法写成的,这在YAML命令行参考资料中描述的更多:http://wiki.ros.org/ROS/YAMLCommandLine。

      '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]' 

    For ROS Groovy and earlier, 如果是ROS Groovy及早先的版本的话,

    • This command will publish messages to a given topic:

      rostopic pub
    • This option (dash-one) causes rostopic to only publish one message then exit:

       -1 
    • This is the name of the topic to publish to:

      /turtle1/command_velocity
    • This is the message type to use when publishing to the topic:

      turtlesim/Velocity
    • This option (double-dash) tells the option parser that none of the following arguments is an option. This is required in cases where your arguments have a leading dash -, like negative numbers.

      --
    • As noted before, a turtlesim/Velocity msg has two floating point elements : linear and angular. In this case, 2.0 becomes the linear value, and 1.8 is the angular value. These arguments are actually in YAML syntax, which is described more in the YAML command line documentation.

      2.0 1.8 

    You may have noticed that the turtle has stopped moving; this is because the turtle requires a steady stream of commands at 1 Hz to keep moving. We can publish a steady stream of commands using rostopic pub -r command:

    你可能发现乌龟停止移动了;这是因为乌龟需要一个稳定的命令流以1Hz保持运动。我们可以使用rostopic pub -r命令发布一个稳定命令流:

    For ROS Hydro and later, 对于ROS Hydro和之后的版本,

    • $ rostopic pub /turtle1/cmd_vel geometry_msgs/Twist -r 1 -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, -1.8]'

    For ROS Groovy and earlier,对于ROS Groovy和早先的版本,

    • $ rostopic pub /turtle1/command_velocity turtlesim/Velocity -r 1 -- 2.0  -1.8

    This publishes the velocity commands at a rate of 1 Hz on the velocity topic. 它在速率主题上以1Hz的频率发布速率命令。

    • turtle(rostopicpub)2.png

    We can also look at what is happening in rqt_graph, The rostopic pub node (here in red) is communicating with the rostopic echo node (here in green):

    我们可以在rqt_graph上看下发生了什么,rostopic pub node(这里是红色)与rostopic echo node(这里是绿色)交流。

    rqt_graph_pub.png

    As you can see the turtle is running in a continuous circle. In a new terminal, we can use rostopic echo to see the data published by our turtlesim:

    正如你可以看到乌龟是以持续的圆周运动。在一个新的节点上,我们可以使用rostopic echo来看下我们的turtlesim发布的数据:

    2)使用rostopic hz

    rostopic hz reports the rate at which data is published.

    rostopic hz报告数据发布的速率。

    Usage: 用法:

    rostopic hz [topic]

    Let's see how fast the turtlesim_node is publishing /turtle1/pose:  让我们看下turtlesim_node发布/turtle1/pose的速率多快:

    $ rostopic hz /turtle1/pose

    You will see: 你将会看到:

    • subscribed to [/turtle1/pose]
      average rate: 59.354
              min: 0.005s max: 0.027s std dev: 0.00284s window: 58
      average rate: 59.459
              min: 0.005s max: 0.027s std dev: 0.00271s window: 118
      average rate: 59.539
              min: 0.004s max: 0.030s std dev: 0.00339s window: 177
      average rate: 59.492
              min: 0.004s max: 0.030s std dev: 0.00380s window: 237
      average rate: 59.463
              min: 0.004s max: 0.030s std dev: 0.00380s window: 290

    Now we can tell that the turtlesim is publishing data about our turtle at the rate of 60 Hz. We can also use rostopic type in conjunction with rosmsg show to get in depth information about a topic: 现在我们可以看出来turtlesim打印出了我们的乌龟是以60Hz的速率的数据。我们还可以使用rostopic type结合rosmsg show来得到一个主题的深度信息:

    For ROS Hydro and later, 对于ROS Hydro和之后的版本,

    • $ rostopic type /turtle1/cmd_vel | rosmsg show

    For ROS Groovy and earlier,

    • $ rostopic type /turtle1/command_velocity | rosmsg show

    Now that we've examined the topics using rostopic let's use another tool to look at the data published by our turtlesim:

    现在我们已经通过使用rostopic测试了主题,让我们使用另一个工具来看一下我们的turtlesim所发布的数据吧:

     (6)使用rqt_plot

    Note: If you're using electric or earlier, rqt is not available. Use rxplot instead.

    注意:如果你使用electirc或早些时候使用过,rqt是不可用的。使用rxplot作为替代。

    rqt_plot displays a scrolling time plot of the data published on topics. Here we'll use rqt_plot to plot the data being published on the /turtle1/pose topic. First, start rqt_plot by typing

    rqt_plot显示了一个发布到主题上的数据的卷动时间图。这里我们使用rqt_plot来绘制发布到/turtle1/pose主题上的数据。首先,在一个新的终端通过输入以下内容来启动rqt_plot:

     

    $ rosrun rqt_plot rqt_plot

    in a new terminal. In the new window that should pop up, a text box in the upper left corner gives you the ability to add any topic to the plot. Typing /turtle1/pose/x will highlight the plus button, previously disabled. Press it and repeat the same procedure with the topic /turtle1/pose/y. You will now see the turtle's x-y location plotted in the graph. 在这个新弹出的窗口中,左上角的文本框给你可以向图上添加任何主题的选项。输入/turtle1/pose/x将会高亮显示添加按钮,之前是不可用的。按按钮,然后重复添加主题/turtle1/pose/y。你将会看到乌龟的x-y位置图。

    rqt_plot.png

    Pressing the minus button shows a menu that allows you to hide the specified topic from the plot. Hiding both the topics you just added and adding /turtle1/pose/theta will result in the plot shown in the next figure. 按减号按钮将允许你隐藏图上的特定的主题。同时隐藏这两个主题,添加/turtle1/pose/theta将出现下一个图。

    rqt_plot2.png

    That's it for this section, use Ctrl-C to kill the rostopic terminals but keep your turtlesim running.

    以上就是本教程的内容,使用Ctrl-C杀掉rostopic终端,但是保持你的turtlesim运行。

     

    Now that you understand how ROS topics work, let's look at how services and parameters work.

     现在你已经理解了ROS topic的工作原理,让我们看一下服务和参数是怎么工作的吧。

    Video Tutorial 视频教程

    The following video presents a small tutorial using turtlesim on ROS nodes and ROS topics.

     以下视频呈现了一个关于在ROS节点和ROS主题上使用turtlesim的小教程。

    7. Understanding ROS Services and Parameters

    This tutorial introduces ROS services, and parameters as well as using the rosservice and rosparam commandline tools.

    该教程除了介绍rosservice和rosparam命令工具的使用方法之外,还介绍了ROS服务,以及参数。

    Assuming your turtlesim_node is still running from the last tutorial, let's look at what services the turtlesim provides:

    假设你上一节的教程的turtlesim_node节点还在运行着,让我们看一下turtlesim提供的服务吧:

    (1)ROS服务

    Services are another way that nodes can communicate with each other. Services allow nodes to send a request and receive a response.

    服务是节点能够彼此之间交流的另一种方式。服务允许节点发送一个请求并接收一个回复。

    (2)使用rosservice

    rosservice can easily attach to ROS's client/service framework with services. rosservice has many commands that can be used on topics, as shown below:

    rosservice能够通过服务轻松地依附上ROS的客户端/服务框架。rosservice有很多用在主题的命令,如下面所显示的:

    Usage:用法:

    rosservice list         print information about active services 打印关于活动的服务的信息
    rosservice call         call the service with the provided args 呼叫指定参数的服务
    rosservice type         print service type 打印服务类型
    rosservice find         find services by service type 查找服务类型的服务
    rosservice uri          print service ROSRPC uri 打印服务RSRPC统一资源标识符

    1)rosservice list

     

    $ rosservice list

    The list command shows us that the turtlesim node provides nine services: resetclearspawnkillturtle1/set_pen,/turtle1/teleport_absolute/turtle1/teleport_relativeturtlesim/get_loggers, and turtlesim/set_logger_level. There are also two services related to the separate rosout node: /rosout/get_loggers and /rosout/set_logger_level.

    list命令向我们展示了turtlesim节点提供的九个服务:reset, clear, spawn, kill, turtle1/set_pen, /turtle1/teleport_absolute, /turtle1/teleport_relative, turtlesim/get_loggers,以及turtlesim/set_logger_level。

    还有两个跟分离rosout节点相关的服务:/rosout/get_loggers和/rosout/set_logger_level。

    • /clear
      /kill
      /reset
      /rosout/get_loggers
      /rosout/set_logger_level
      /spawn
      /teleop_turtle/get_loggers
      /teleop_turtle/set_logger_level
      /turtle1/set_pen
      /turtle1/teleport_absolute
      /turtle1/teleport_relative
      /turtlesim/get_loggers
      /turtlesim/set_logger_level

    Let's look more closely at the clear service using rosservice type:

     让我们使用rosservice type来更进一步看清clear服务。

     2)rosservice type

    Usage: 用法:

    rosservice type [service]

    Let's find out what type the clear service is: 让我们看一下clear服务是什么类型吧:

    $ rosservice type /clear
    • std_srvs/Empty

    This service is empty, this means when the service call is made it takes no arguments (i.e. it sends no data when making a request and receives no data when receiving a response). Let's call this service using rosservice call:

     这个服务是空的,这意味着当这个服务被调用时,它不需要任何参数(例如,当发出一个请求时它不发送任何数据,收到一个回复时不接收任何数据)。让我们使用rosservice call调用这个服务。

    3)rosservice call

    Usage: 用法

    rosservice call [service] [args]

    Here we'll call with no arguments because the service is of type empty: 现在我们将通过无参数调用,因为该服务是空类型:

    $ rosservice call /clear

    This does what we expect, it clears the background of the turtlesim_node.

    这将按照我们期望的做,它清理了turtlesim_node的背景。

    turtlesim.png

    Let's look at the case where the service has arguments by looking at the information for the service spawn:

    让我们通过service spawn查看信息看一下服务带有参数的情况。

    $ rosservice type /spawn| rossrv show
    • float32 x
      float32 y
      float32 theta
      string name
      ---
      string name

    This service lets us spawn a new turtle at a given location and orientation. The name field is optional, so let's not give our new turtle a name and let turtlesim create one for us.

    这个服务允许我们在一个给定的位置和方向上spawn(渲染)一个新的乌龟。名字域是可选的,所以让我们不给我们的新乌龟起名字,让turtlesim为我们创建一个。

    $ rosservice call /spawn 2 2 0.2 ""

    The service call returns with the name of the newly created turtle

    这个服务将返回新创建的乌龟的名字

    • name: turtle2

    Now our turtlesim should look like this:

    现在我们的turtlesim应该看上去像这个样子:

    turtle(service).png

    (3)使用rosparam

    rosparam allows you to store and manipulate data on the ROS Parameter Server. The Parameter Server can store integers, floats, boolean, dictionaries, and lists. rosparam uses the YAML markup language for syntax. In simple cases, YAML looks very natural: 1 is an integer, 1.0 is a float, one is a string, true is a boolean, [1, 2, 3] is a list of integers, and {a: b, c: d} is a dictionary. rosparam has many commands that can be used on parameters, as shown below:

    rosparam允许你在ROS参数服务器上存储并操纵数据。参数服务器能够存储整型,浮点型,布尔型,词典,以及列数据。rosparam使用YAML标志语言作为语法规则。在简单情况下,YAML看起来非常自然:1是一个整型,1.0是浮点型,one是字符型,true是一个布尔型,[1, 2, 3]是一个整数列,{a:b, c:d}是一个词典。rosparam有很多能够用在参数上的命令,如下所示。

    Usage:

    rosparam set            set parameter  设置参数
    rosparam get            get parameter  获取参数
    rosparam load           load parameters from file  从文件加载参数
    rosparam dump           dump parameters to file  将参数扔到文件中
    rosparam delete         delete parameter  删除参数
    rosparam list           list parameter names  列出参数名字

    Let's look at what parameters are currently on the param server:

    让我们看一下现在在参数服务器上有什么参数:

    1)rosparam list

     

    $ rosparam list

    Here we can see that the turtlesim node has three parameters on the param server for background color:

    这里我们能够看到turtlesim node在参数服务器上有三个关于背景色的参数:

    • /background_b
      /background_g
      /background_r
      /roslaunch/uris/aqy:51932
      /run_id

    Let's change one of the parameter values using rosparam set:

    让我们使用rosparam set更改其中的一个参数值:

    2)rosparam set与rosparam get

    Usage: 用法:

    rosparam set [param_name]
    rosparam get [param_name]

    Here will change the red channel of the background color:

    这里将会更改背景颜色的红色通道:

    $ rosparam set /background_r 150

    This changes the parameter value, now we have to call the clear service for the parameter change to take effect:

    这将会更改参数值,现在我们不得不调用clear服务使参数更改生效:

    $ rosservice call /clear

    Now our turtlesim looks like this:

    现在我们的turtlesim看起来是这样的:

    turtle(param).png

    Now let's look at the values of other parameters on the param server. Let's get the value of the green background channel:

    现在让我们看看参数服务器上的其他参数的值。让我们获取绿色背景通道的值:

    $ rosparam get /background_g 
    • 86

    We can also use rosparam get / to show us the contents of the entire Parameter Server.

    我们还能使用rosparam get /向我们展示整个参数服务器的内容:

    $ rosparam get /
    • background_b: 255
      background_g: 86
      background_r: 150
      roslaunch:
        uris: {'aqy:51932': 'http://aqy:51932/'}
      run_id: e07ea71e-98df-11de-8875-001b21201aa8

    You may wish to store this in a file so that you can reload it at another time. This is easy using rosparam:

    你可能希望将这个存储到一个文件中从而你能够在以后某个时间重载它。这通过使用rosparam可以很容易实现:

    3)rosparam dump和rosparam load

    Usage: 用法:

    rosparam dump [file_name] [namespace]
    rosparam load [file_name] [namespace]

    Here we write all the parameters to the file params.yaml

    这里我们将所有的参数写到params.yaml文件中

    $ rosparam dump params.yaml

    You can even load these yaml files into new namespaces, e.g. copy:

    你甚至可以将这些yaml文件加载到新的空间,比如copy:

    $ rosparam load params.yaml copy
    $ rosparam get /copy/background_b
    • 255

    Now that you understand how ROS services and params work, let's try using rqt_console and roslaunch

    现在你已经理解了ROS服务和参数是怎么工作的了,现在让我们试着使用rqt_console和roslaunch吧。

    8. Using rqt_console and roslaunch

    This tutorial introduces ROS using rqt_console and rqt_logger_level for debugging and roslaunch for starting many nodes at once. If you use ROS fuerte or ealier distros where rqt isn't fully available, please see this page with this page that uses old rx based tools.

    该教程介绍了使用rqt_console和rqt_logger_level来调试ROS,使用roslaunch来一次启动多个节点。如果你使用ROS fuerte或者更早的版本,那么rqt是不完全可用的,请查看这个页面使用老的rx开头的工具。

    1)前提rqt和turtlesim包

    The tutorial uses both the rqt and turtlesim packages. To do this tutorial, please install both packages, if you have not yet done so.

    该教程使用rqt和turtlesim包。要学该教程,请安装这两个包,如果还没安装的话。

     

    $ sudo apt-get install ros-<distro>-rqt ros-<distro>-rqt-common-plugins ros-<distro>-turtlesim

    Replace <distro> with the name of your ROS distribution (e.g. indigo, jade, kinetic). 将<distro>替换成你的ROS版本。

    NOTE: you may have already built rqt and turtlesim for one of the previous tutorials. If you are not sure, installing them again will not hurt anything.

    注意:你可能已经在前面的教程中建立了rqt和turtlesim。如果你不确定,再装一次没有任何害处。

    (2)使用rqt_console和rqt_logger_level

    rqt_console attaches to ROS's logging framework to display output from nodes. rqt_logger_level allows us to change the verbosity level (DEBUG, WARN, INFO, and ERROR) of nodes as they run.

    rqt_console依附ROS的logging框架来显示节点的输出。rqt_logger_level允许我们当它们运行时改变节点的冗长程度(DEBUG, WARN, INFO,和ERROR)。

    Now let's look at the turtlesim output in rqt_console and switch logger levels in rqt_logger_level as we use turtlesim. Before we start the turtlesim, in two new terminals start rqt_console and rqt_logger_level:

    现在让我们看一下rqt_console的turtlesim输出,并当我们使用turtlesim时切换rqt_logger_level的logger level。在我们启动turtlesim之前,在两个新的终端启动rqt_console和rqt_logger_level:

     

    $ rosrun rqt_console rqt_console

     

    $ rosrun rqt_logger_level rqt_logger_level

    You will see two windows popup:
    你将会看到两个弹出的窗口:

    rqt_console(start).png

    rqt_logger_level.png

    Now let's start turtlesim in a new terminal:

    现在让我们在一个新的终端开启一个新的turtlesim:

     

    $ rosrun turtlesim turtlesim_node

    Since the default logger level is INFO you will see any info that the turtlesim publishes when it starts up, which should look like:

    因为默认的logger level级别水平是INFO,你将会看到启动时turtlesim发布的任何信息,看上去就像这样:

    rqt_console(turtlesimstart).png

    Now let's change the logger level to Warn by refreshing the nodes in the rqt_logger_level window and selecting Warn as shown below:

    现在让我们在rqt_logger_level窗口刷新节点选择Warn更改logger level级别为Warn,如下图所示:

    rqt_logger_level(error).png

    Now let's run our turtle into the wall and see what is displayed in our rqt_console:

    现在让我们运行我们的乌龟到墙上,看看在我们的rqt_console显示的什么:

    For ROS Hydro and later,对于ROS Hydro和之后的版本,

       rostopic pub /turtle1/cmd_vel geometry_msgs/Twist -r 1 -- '{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0,y: 0.0,z: 0.0}}'

    For ROS Groovy and earlier,对于ROS Groovy和之前的版本,

    rostopic pub /turtle1/command_velocity turtlesim/Velocity -r 1 -- 2.0  0.0

    rqt_console(turtlesimerror).png

    1)关于logger levels级别快速笔记

    Logging levels are prioritized in the following order:

    Logging levels级别优先顺序按如下排序:

     

    Fatal
    Error
    Warn
    Info
    Debug

    Fatal has the highest priority and Debug has the lowest. By setting the logger level, you will get all messages of that priority level or higher. For example, by setting the level to Warn, you will get all Warn, Error, and Fatal logging messages.

    Fatal是最高级别的,Debug是最低级别的。通过设置logger level级别,你将会得到那个优先级或更高级别的所有信息。例如,将级别设置成Warn,你将会得到所有Warn,Error以及Fatal的记录信息。

    Let's Ctrl-C our turtlesim and let's use roslaunch to bring up multiple turtlesim nodes and a mimicking node to cause one turtlesim to mimic another:

    让我们按Ctrl-C终止我们的turtlesim,让我们使用roslaunch来开启多个turtlesim节点和一个模仿节点

    2)使用roslaunch

    roslaunch starts nodes as defined in a launch file.

    roslaunch开启一个launch文件中定义的节点。

    Usage: 用法:

     

    $ roslaunch [package] [filename.launch]

    First go to the beginner_tutorials package we created and built earlier:

    首先到我们之前创建并生成的beginner_tutorials包中:

     

    $ roscd beginner_tutorials

    If roscd says similar to roscd: No such package/stack 'beginner_tutorials' , you will need to source the environment setup file like you did at the end of the create_a_workspace tutorial:

    如果roscd说类似于roscd: No such package/stack 'beginner_tutorials',你需要像你在create_a_workspace教程结尾那样源一下环境setup设置文件:

     

    $ cd ~/catkin_ws
    $ source devel/setup.bash
    $ roscd beginner_tutorials

    Then let's make a launch directory: 然后让我们make一个launch目录:

     

    $ mkdir launch
    $ cd launch

    NOTE: The directory to store launch files don't necessarily have to be named as launch. In fact you don't even need to store them in a directory. roslaunch command automatically looks into the passed package and detect available launch files. However, it turned out to be a good practice.

    注意:这个存储launch文件的目录不需要一定要命名为launch。事实上你甚至不需要在一个路径中存储它们。roslaunch命令会自动查看过往的包检测launch文件。但是,它会是一个好的实践。

    3)Launch文件

    Now let's create a launch file called turtlemimic.launch and paste the following:

    现在让我们创建一个叫turtlemimic的launch文件,粘贴如下内容:

     

    Toggle line numbers
       1 <launch>
       2 
       3   <group ns="turtlesim1">
       4     <node pkg="turtlesim" name="sim" type="turtlesim_node"/>
       5   </group>
       6 
       7   <group ns="turtlesim2">
       8     <node pkg="turtlesim" name="sim" type="turtlesim_node"/>
       9   </group>
      10 
      11   <node pkg="turtlesim" name="mimic" type="mimic">
      12     <remap from="input" to="turtlesim1/turtle1"/>
      13     <remap from="output" to="turtlesim2/turtle1"/>
      14   </node>
      15 
      16 </launch>
    

    5)launch文件解释

    Now, let's break the launch xml down.

    现在,让我们将launch xml分解一下。

    Here we start the launch file with the launch tag, so that the file is identified as a launch file.

    这里我们以launch标签开始launch文件,从而该文件被定义为一个launch文件。

     

    Toggle line numbers
       3   <group ns="turtlesim1">
       4     <node pkg="turtlesim" name="sim" type="turtlesim_node"/>
       5   </group>
       6 
       7   <group ns="turtlesim2">
       8     <node pkg="turtlesim" name="sim" type="turtlesim_node"/>
       9   </group>
    

    Here we start two groups with a namespace tag of turtlesim1 and turtlesim2 with a turtlesim node with a name of sim. This allows us to start two simulators without having name conflicts.

    这里我们开始两个各有一个turtlesim节点命名为sim的带有turtlesim1和turtlesim2的命名空间标签的群。它允许我们开始两个模拟器而不会有名称冲突。

     

    Toggle line numbers
      11   <node pkg="turtlesim" name="mimic" type="mimic">
      12     <remap from="input" to="turtlesim1/turtle1"/>
      13     <remap from="output" to="turtlesim2/turtle1"/>
      14   </node>
    

    Here we start the mimic node with the topics input and output renamed to turtlesim1 and turtlesim2. This renaming will cause turtlesim2 to mimic turtlesim1.

    这里我们开始带有主题输入和输出重命名为turtlesim1和turtlesim2的模拟节点。这个重命名将引起turtlesim2模仿turtlesim1。

     

    This closes the xml tag for the launch file.

    这个关闭launch文件的xml标签。

    5)roslaunching

    Now let's roslaunch the launch file:

    现在让我们roslaunch加载这个launch文件:

     

    $ roslaunch beginner_tutorials turtlemimic.launch

    Two turtlesims will start and in a new terminal send the rostopic command:

    两个turtlesim将会启动,并且在一个新的终端发送rostopic命令:

     

    For ROS Hydro and later,对于ROS Hydro和之后的版本,

    • $ rostopic pub /turtlesim1/turtle1/cmd_vel geometry_msgs/Twist -r 1 -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, -1.8]'

    For ROS Groovy and earlier,

    • $ rostopic pub /turtlesim1/turtle1/command_velocity turtlesim/Velocity -r 1 -- 2.0  -1.8

    You will see the two turtlesims start moving even though the publish command is only being sent to turtlesim1.

    你将会看到两个turtlesim开始移动了虽然发布命令只送给了turtlesim1。

    mimic.png

    We can also use rqt_graph to better understand what our launch file did. Run rqt's main window and select rqt_graph:

    我们还可以使用rqt_graph来更好地理解我们的launch文件做的事情。启动rqt的主窗口,选择rqt_graph:

    $ rqt

    Or simply: 或者简单地:

     

    $ rqt_graph

    mimiclaunch.jpg

    Now that you have successfully used rqt_console and roslaunch, let's learn about editor options for ROS. You can Ctrl-C all your turtlesims, as you will not need them for the next tutorials.

    现在你已经成功地使用rqt_console和roslaunch了,让我们还是学习ROS的编辑器选项吧。你可以按Ctrl-C终止所有的turtlesim,因为你在接下来的教程中不需要用到它们了。

    9. Using rosed to edit files in ROS 使用rosed在ROS中编辑文件

    This tutorial shows how to use rosed to make editing easier.

    该教程展示了如何使用rosed来让编辑更加容易。

    (1)使用rosed

    rosed is part of the rosbash suite. It allows you to directly edit a file within a package by using the package name rather than having to type the entire path to the package.

    rosed是rosbash套件的一部分。它允许你使用包名直接编辑一个包中的文件,而不用输入包的整个路径。

    Usage: 用法:

     

    $ rosed [package_name] [filename]

    Example: 例子:

     

    $ rosed roscpp Logger.msg

    This example demonstrates how you would edit the Logger.msg file within the roscpp package.

    这个例子展示了你是怎么编辑roscpp包中的Loger.msg文件的。

    If this example doesn't work is probably because you don't have the vim editor installed. Please refer to Editor section. If you don't know how to get out of vim, click here.

    如果这个例子不能工作那可能是因为你还没有安装vim editor。请参考Editor一章。如果你不知道怎么摆脱vim,请点击这里。

     

    If the filename is not uniquely defined within the package, a menu will prompt you to choose which of the possible files you want to edit.

    如果文件名不是唯一的,将会跳出一个菜单供你选择你想编辑的哪个文件。

    (2)通过键入tab补全使用rosed

    This way you can easily see and optionally edit all files from a package without knowing its exact name.

    这种方式你能轻松地看到并且可选择性地编辑一个包中的所有文件而不用知道它的确切名字。

    Usage: 用法:

     

    $ rosed [package_name] <tab><tab>

    Example: 例子:

    $ rosed roscpp <tab><tab>
    Empty.srv                   package.xml
    GetLoggers.srv              roscpp-msg-extras.cmake
    Logger.msg                  roscpp-msg-paths.cmake
    SetLoggerLevel.srv          roscpp.cmake
    genmsg_cpp.py               roscppConfig-version.cmake
    gensrv_cpp.py               roscppConfig.cmake
    msg_gen.py                  

    (3)编辑器

    The default editor for rosed is vim. The more beginner-friendly editor nano is included with the default Ubuntu install. You can use it by editing your ~/.bashrc file to include:

    rosed默认的编辑器是vim。更适合初学者友好的编辑器nano在默认Ubuntu安装时就已经包括了。你可以通过编辑你的~/.bashrc文件加上这么一段话使用它:

    export EDITOR='nano -w'

    To set the default editor to emacs you can edit your ~/.bashrc file to include: 要设置默认的编辑器为emacs你可以编辑你的~/.bashrc文件加上这么一句:

    export EDITOR='emacs -nw'

    NOTE: changes in .bashrc will only take effect for new terminals. Terminals that are already open will not see the new environmental variable.

    注意:.bashrc中的更改将只对新的终端有效。已经打开的终端是无法看到新的环境变量的。

    Open a new terminal and see if EDITOR is defined:

    打开一个新的终端看一下编辑器是否已经已经设置了:

     

    $ echo $EDITOR
    • nano -w
      or
      emacs -nw

    Now that you have successfully configured and used rosed, let's create a Msg and Srv.

    现在你已经成功地设置和使用rosed了,让我们开始学习创建一个消息和服务吧。

    10. Creating a ROS msg and srv 创建一个ROS消息和服务

    This tutorial covers how to create and build msg and srv files as well as the rosmsg, rossrv and roscp commandline tools.

    该教程除了介绍rosmsg, rossrv和roscp命令行工具之外,还介绍了如何创建和生成msg消息和srv服务文件。

    (1)介绍msg和srv

    • msg: msg files are simple text files that describe the fields of a ROS message. They are used to generate source code for messages in different languages. msg文件是简单的text文件,描述ROS的消息域。它们用来生成不同语言的消息的源代码。

    • srv: an srv file describes a service. It is composed of two parts: a request and a response. 一个srv文件描述一个服务。它由两部分组成:一个是请求和一个是回复。

    msg files are stored in the msg directory of a package, and srv files are stored in the srv directory.

    msg文件存储在一个包的msg路径,srv文件存储在srv路径中。

    msgs are just simple text files with a field type and field name per line. The field types you can use are:

    msgs只是简单的每行带有域类型和域名的text文件。你能用的域类型有:

    • int8, int16, int32, int64 (plus uint*)
    • float32, float64
    • string
    • time, duration
    • other msg files
    • variable-length array[] and fixed-length array[C]

    There is also a special type in ROS: Header, the header contains a timestamp and coordinate frame information that are commonly used in ROS. You will frequently see the first line in a msg file have Header header.

    在ROS中还有一个特殊的类型:Header,header包含一个能够广泛用于ROS的时间戳和坐标轴信息。你将会频繁地看到msg文件的第一行有Header header。

    Here is an example of a msg that uses a Header, a string primitive, and two other msgs :

    这里是一个msg的例子,使用了一个Header,一个string基元,和两个其他msgs:

     

      Header header
      string child_frame_id
      geometry_msgs/PoseWithCovariance pose
      geometry_msgs/TwistWithCovariance twist

    srv files are just like msg files, except they contain two parts: a request and a response. The two parts are separated by a '---' line. Here is an example of a srv file:

     srv文件就像msg文件,除了它们包含两部分:一个请求和一个回复。这两部分是由一条“---”线分割开的。这里是一个srv文件的例子:

     

    int64 A
    int64 B
    ---
    int64 Sum

    In the above example, A and B are the request, and Sum is the response.

    在上面的例子中,A和B是请求,Sum是回复。

    (2)使用msg消息

    1)创建一个msg消息

    Let's define a new msg in the package that was created in the previous tutorial.

    让我们在之前教程中创建的包中定义一个新的msg消息。

     

     

    $ roscd beginner_tutorials
    $ mkdir msg
    $ echo "int64 num" > msg/Num.msg

    The example .msg file above contains only 1 line. You can, of course, create a more complex file by adding multiple elements, one per line, like this:

    上面的.msg例子中只包含一行。当然你可以通过添加多个元素创建一个更加复杂的文件,1行一个,像这样:

    string first_name
    string last_name
    uint8 age
    uint32 score

    There's one more step, though. We need to make sure that the msg files are turned into source code for C++, Python, and other languages:

    但是,要多一步。我们需要确保msg文件转换成源代码如C++,Python和其它语言:

    Open package.xml, and make sure these two lines are in it and uncommented:

    打开package.xml,确保这两行在其中然后消除注释:

      <build_depend>message_generation</build_depend>
      <run_depend>message_runtime</run_depend>

    Note that at build time, we need "message_generation", while at runtime, we only need "message_runtime".

    注意在生成的时候,我们需要“message_generation”,而在运行的时候,我们只需要“message_runtime”。

    Open CMakeLists.txt in your favorite text editor (rosed from the previous tutorial is a good option).

    在你喜欢的text编辑器(之前的教程中的rosed是一个好选择)中打开CMakeLists.txt。

    Add the message_generation dependency to the find_package call which already exists in your CMakeLists.txt so that you can generate messages. You can do this by simply adding message_generation to the list of COMPONENTS such that it looks like this:

    添加message_generation依赖到已经在你的CMakeLists.txt中存在的find_package call中,从而你能够产生消息。你可以通过简单地添加message_generation到你的COMPONENTS列表中实现,就像这样:

     

    # Do not just add this to your CMakeLists.txt, modify the existing text to add message_generation before the closing parenthesis 不要只是添加这个到你的CMakeLists.txt中,修改已存在的文本在右括号之前添加message_generation
    find_package(catkin REQUIRED COMPONENTS
       roscpp
       rospy
       std_msgs
       message_generation
    )

    You may notice that sometimes your project builds fine even if you did not call find_package with all dependencies. This is because catkin combines all your projects into one, so if an earlier project calls find_package, yours is configured with the same values. But forgetting the call means your project can easily break when built in isolation.

    你可能注意到有时候尽管你没有调用带有所有的依赖的find_package你的工程依然生成的很好。这是因为catkin将你的所有工程结合成了一个,所以如果一个早前的工程调用了find_package,你的也会使用相同的数值配置。但是省略调用意味着你的工程能够在单独生成时可以很容易地中断。

    Also make sure you export the message runtime dependency.

    另外还需要确保你输出消息运行时依赖。

    catkin_package(
      ...
      CATKIN_DEPENDS message_runtime ...
      ...)

    Find the following block of code:

    找到以下代码模块:

    # add_message_files(
    #   FILES
    #   Message1.msg
    #   Message2.msg
    # )

    Uncomment it by removing the # symbols and then replace the stand in Message*.msg files with your .msg file, such that it looks like this:

    去注释化,将#符号移除,然后用你的.msg文件取代替代品Message*.msg,看上去就像这样的:

     

    add_message_files(
      FILES
      Num.msg
    )

    By adding the .msg files manually, we make sure that CMake knows when it has to reconfigure the project after you add other .msg files.

    通过人工地添加.msg文件,我们可以确保CMake知道在你添加了其他了其他.msg文件后什么时候重新装配工程。

    Now we must ensure the generate_messages() function is called.

    现在我们必须确保generate_messages()函数被调用。

    For ROS Hydro and later, you need to uncomment these lines:

    对于ROS Hydro和之后的版本,你需要去注释化这些行:

    # generate_messages(
    #   DEPENDENCIES
    #   std_msgs
    # )
    • so it looks like:从而它看上去像:
      generate_messages(
        DEPENDENCIES
        std_msgs
      )

    In earlier versions, you may just need to uncomment one line: 在早期的版本,你可能需要去注释化一行:

    generate_messages()

     

     

    Now you're ready to generate source files from your msg definition. If you want to do so right now, skip next sections to Common step for msg and srv.

    现在你已经准备好从你的消息定义生成源文件了。如果你想现在就做这个话,跳过下一部分直接到msg和srv的一般步骤。

    (2)使用rosmsg

    That's all you need to do to create a msg. Let's make sure that ROS can see it using the rosmsg show command.

    以上就是创建一个msg所需要的所有内容。让我们确保ROS能够通过使用rosmsg show命令看到它。

    Usage: 用法:

     

    $ rosmsg show [message type]

    Example: 例子:

     

    $ rosmsg show beginner_tutorials/Num

    You will see: 你将会看到:

    • int64 num

    In the previous example, the message type consists of two parts: 在早前的例子中,消息类型包含两部分:

    • beginner_tutorials -- the package where the message is defined   消息定义的地方的包

    • Num -- The name of the msg Num.  消息的名字

    If you can't remember which Package a msg is in, you can leave out the package name. Try: 如果你不记得msg是在哪个包里,你能够忽略包名。试一下:

     

    $ rosmsg show Num

    You will see: 你将会看到:

    [beginner_tutorials/Num]:
    int64 num

    (4)使用srv

    1)创建一个srv

    Let's use the package we just created to create a srv:

    让我们使用为创建一个srv而创建的包:

     

    $ roscd beginner_tutorials
    $ mkdir srv

    Instead of creating a new srv definition by hand, we will copy an existing one from another package.

    不要手动创建一个新的srv定义,我们从另一个包中复制一个已存在的。

    For that, roscp is a useful commandline tool for copying files from one package to another.

    为了实现上述操作,roscp是一个有用的从一个包复制文件到另一个包的命令行工具。

    Usage: 用法:

     

    $ roscp [package_name] [file_to_copy_path] [copy_path]

    Now we can copy a service from the rospy_tutorials package:

    现在我们能从rospy_tutorials包中复制一个服务:

     

    $ roscp rospy_tutorials AddTwoInts.srv srv/AddTwoInts.srv

    There's one more step, though. We need to make sure that the srv files are turned into source code for C++, Python, and other languages.

    但是还有多一步。我们需要确保srv文件转换到源文件比如C++,Python和其他语言。

     

    Unless you have done so already, open package.xml, and make sure these two lines are in it and uncommented:

    除非你已经做好了,打开package.xml,确保这两行在其中,去注释化:

      <build_depend>message_generation</build_depend>
      <run_depend>message_runtime</run_depend>

    As before, note that at build time, we need "message_generation", while at runtime, we only need "message_runtime".

    如之前一样,注意在生成的时候,我们需要“message_generation”,而在运行的时候,我们只需要“message_runtime”。

    Unless you have done so already for messages in the previous step, add the message_generation dependency to generate messages in CMakeLists.txt:

    如果你在之前的步骤中还没有做好消息,在CMakeLists.txt中添加message_generation依赖生成消息:

     

    # Do not just add this line to your CMakeLists.txt, modify the existing line
    find_package(catkin REQUIRED COMPONENTS
      roscpp
      rospy
      std_msgs
     message_generation
    )

    (Despite its name, message_generation works for both msg and srv.) (尽管它的名称,message_generation在msg和srv中都工作。)

    Also you need the same changes to package.xml for services as for messages, so look above for the additional dependencies required.

    而且你需要对package.xml对services做对messages相同的改变,所以看上面所需的多余依赖。

    Remove # to uncomment the following lines:

    移除下面行的注释#:

    # add_service_files(
    #   FILES
    #   Service1.srv
    #   Service2.srv
    # )

    And replace the placeholder Service*.srv files for your service files:

    将占位的Service*.srv文件替换为你的service文件:

     

    add_service_files(
      FILES
      AddTwoInts.srv
    )

     

     

    Now you're ready to generate source files from your service definition. If you want to do so right now, skip next sections to Common step for msg and srv.

    现在已经准备好了生成源文件所需的服务定义。如果你想现在就想做的话,请跳过下面的环节直接到msg和srv的常用步骤。

    2)使用rossrv

    That's all you need to do to create a srv. Let's make sure that ROS can see it using the rossrv show command.

    以上是你创建一个srv所需的全部内容。让我们使用rossrv show命令确保ROS能看到它。

    Usage: 用法:

     

    $ rossrv show <service type>

    Example: 例子:

     

    $ rossrv show beginner_tutorials/AddTwoInts

    You will see: 你将会看到:

    • int64 a
      int64 b
      ---
      int64 sum

    Similar to rosmsg, you can find service files like this without specifying package name:

    类似于rosmsg,你能够不用特制包名也能找到服务文件:

     

    $ rossrv show AddTwoInts
    [beginner_tutorials/AddTwoInts]:
    int64 a
    int64 b
    ---
    int64 sum
    
    [rospy_tutorials/AddTwoInts]:
    int64 a
    int64 b
    ---
    int64 sum

    (5)msg和srv的一般步骤

     

    Unless you have already done this in the previous steps, change in CMakeLists.txt. :

    如果你之前的步骤还没完成,请更改CMakeLists.txt文件:

    # generate_messages(
    #   DEPENDENCIES
    # #  std_msgs  # Or other packages containing msgs
    # )

    Uncomment it and add any packages you depend on which contain .msg files that your messages use (in this case std_msgs), such that it looks like this:

    去注释化,添加你依赖的任何包括你的消息使用的.msg文件(在该情况下是std_msgs)的包,它看上去像这个样子:

     

    generate_messages(
      DEPENDENCIES
      std_msgs
    )

    Now that we have made some new messages we need to make our package again:

    现在我们已经制作了一些新消息我们需要重建我们的包:

     

    # In your catkin workspace
    $ roscd beginner_tutorials
    $ cd ../..
    $ catkin_make install
    $ cd -

     

    Any .msg file in the msg directory will generate code for use in all supported languages. The C++ message header file will be generated in ~/catkin_ws/devel/include/beginner_tutorials/. The Python script will be created in ~/catkin_ws/devel/lib/python2.7/dist-packages/beginner_tutorials/msg. The lisp file appears in ~/catkin_ws/devel/share/common-lisp/ros/beginner_tutorials/msg/.

    msg目录中的任何.msg文件都会生成所支持的语言可用的代码。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/。

    Similarly, any .srv files in the srv directory will have generated code in supported languages. For C++, this will generate header files in the same directory as the message header files. For Python and Lisp, there will be an 'srv' folder beside the 'msg' folders.

    类似地,srv目录中的任何.srv文件都会生成支持语言下的代码。对于C++,这个将生成如消息头文件相同目录中的头文件。对于Python和Lisp,将会在'msg'文件夹旁边有一个'srv'文件夹。

    The full specification for the message format is available at the Message Description Language page.

    消息格式的完整说明可以在消息描述语言页看到。

     

    If you are building C++ nodes which use your new messages, you will also need to declare a dependency between your node and your message, as described in the catkin msg/srv build documentation.

    如果你生成使用你新消息的C++节点,你还需要声明一个你的节点和你的消息之间依赖,正如在catkin msg/srv build参考资料描述的那样。

     (6)获取帮助

    We've seen quite a few ROS tools already. It can be difficult to keep track of what arguments each command requires. Luckily, most ROS tools provide their own help.

    我们已经看到好几个ROS工具了。可能很难记住每个命令所需要的参数。幸运地是,大多数ROS工具提供了它们自己的帮助。

    Try: 试一下:

     

    $ rosmsg -h
    • You should see a list of different rosmsg subcommands. 你将会看到不同的rosmsg子命令

      Commands:
        rosmsg show     Show message description
        rosmsg list     List all messages
        rosmsg md5      Display message md5sum
        rosmsg package  List messages in a package
        rosmsg packages List packages that contain messages

    You can also get help for subcommands 你还能获取子命令的帮助

     

    $ rosmsg show -h

    This shows the arguments that are needed for rosmsg show: 这个将会显示rosmsg show所需要的参数:

    Usage: rosmsg show [options] <message type>
    
    Options:
      -h, --help  show this help message and exit
      -r, --raw   show raw message text, including comments

     (7)复习

    Let's just list some of the commands we've used so far: 让我们列出我们目前使用过的一些命令:

    • rospack = ros+pack(age) : provides information related to ROS packages
    • roscd = ros+cd : changes directory to a ROS package or stack

    • rosls = ros+ls : lists files in a ROS package

    • roscp = ros+cp : copies files from/to a ROS package

    • rosmsg = ros+msg : provides information related to ROS message definitions
    • rossrv = ros+srv : provides information related to ROS service definitions
    • catkin_make : makes (compiles) a ROS package
      • rosmake = ros+make : makes (compiles) a ROS package (if you're not using a catkin workspace)

    (8)下一个教程

    Now that you've made a new ROS msg and srv, let's look at writing a simple publisher and subscriber (python) (c++).

    现在已经制作了一个新的ROS信息msg和服务srv,让我们写一个简单的发布者和订阅者(python)(c++)吧。

    11. Writing a Simple Publisher and Subscriber (C++)

    This tutorial covers how to write a publisher and subscriber node in C++.

    该教程是介绍如何使用C++写一个发布器和订阅器节点。

    (1)写发布器节点

    "Node" is the ROS term for an executable that is connected to the ROS network. Here we'll create a publisher ("talker") node which will continually broadcast a message.

     “节点”是指跟ROS网络有关的可执行文件的ROS术语。这里我们将创建一个发布器(“talker”)节点,它将持续地发布消息。

     

    Change directories to your beginner_tutorials package you created in your catkin workspace previous tutorials:

    更改目录到你在之前教程中的catkin工作空间所创建的beginner_tutorials包。

     

    roscd beginner_tutorials

    1)代码

     

    Create a src directory in the beginner_tutorials package directory:

    在beginner_tutorials包目录中创建一个src目录:

     

    mkdir src

    This directory will contain any source files for our beginner_tutorials package.

    这个目录将包含我们的beginner_tutorials包所需要的任何资源文件。

    Create the src/talker.cpp file within the beginner_tutorials package and paste the following inside it:

    创建在beginner_tutorials包中创建src/talker.cpp文件,并在其中粘贴如下内容:

    https://raw.github.com/ros/ros_tutorials/kinetic-devel/roscpp_tutorials/talker/talker.cpp

    Toggle line numbers
      27 #include "ros/ros.h"
      28 #include "std_msgs/String.h"
      29 
      30 #include <sstream>
      31 
      32 /**
      33  * This tutorial demonstrates simple sending of messages over the ROS system.
      34  */
      35 int main(int argc, char **argv)
      36 {
      37   /**
      38    * The ros::init() function needs to see argc and argv so that it can perform
      39    * any ROS arguments and name remapping that were provided at the command line.
      40    * For programmatic remappings you can use a different version of init() which takes
      41    * remappings directly, but for most command-line programs, passing argc and argv is
      42    * the easiest way to do it.  The third argument to init() is the name of the node.
      43    *
      44    * You must call one of the versions of ros::init() before using any other
      45    * part of the ROS system.
      46    */
      47   ros::init(argc, argv, "talker");
      48 
      49   /**
      50    * NodeHandle is the main access point to communications with the ROS system.
      51    * The first NodeHandle constructed will fully initialize this node, and the last
      52    * NodeHandle destructed will close down the node.
      53    */
      54   ros::NodeHandle n;
      55 
      56   /**
      57    * The advertise() function is how you tell ROS that you want to
      58    * publish on a given topic name. This invokes a call to the ROS
      59    * master node, which keeps a registry of who is publishing and who
      60    * is subscribing. After this advertise() call is made, the master
      61    * node will notify anyone who is trying to subscribe to this topic name,
      62    * and they will in turn negotiate a peer-to-peer connection with this
      63    * node.  advertise() returns a Publisher object which allows you to
      64    * publish messages on that topic through a call to publish().  Once
      65    * all copies of the returned Publisher object are destroyed, the topic
      66    * will be automatically unadvertised.
      67    *
      68    * The second parameter to advertise() is the size of the message queue
      69    * used for publishing messages.  If messages are published more quickly
      70    * than we can send them, the number here specifies how many messages to
      71    * buffer up before throwing some away.
      72    */
      73   ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
      74 
      75   ros::Rate loop_rate(10);
      76 
      77   /**
      78    * A count of how many messages we have sent. This is used to create
      79    * a unique string for each message.
      80    */
      81   int count = 0;
      82   while (ros::ok())
      83   {
      84     /**
      85      * This is a message object. You stuff it with data, and then publish it.
      86      */
      87     std_msgs::String msg;
      88 
      89     std::stringstream ss;
      90     ss << "hello world " << count;
      91     msg.data = ss.str();
      92 
      93     ROS_INFO("%s", msg.data.c_str());
      94 
      95     /**
      96      * The publish() function is how you send messages. The parameter
      97      * is the message object. The type of this object must agree with the type
      98      * given as a template parameter to the advertise<>() call, as was done
      99      * in the constructor above.
     100      */
     101     chatter_pub.publish(msg);
     102 
     103     ros::spinOnce();
     104 
     105     loop_rate.sleep();
     106     ++count;
     107   }
     108 
     109 
     110   return 0;
     111 }
    

    2)代码解释

    Now, let's break the code down.

     

    现在,让我们分解代码。 

     

     

    Toggle line numbers
      27 #include "ros/ros.h"
      28 

    ros/ros.h is a convenience include that includes all the headers necessary to use the most common public pieces of the ROS system.

    ros/ros.h是一个包括所有必须的ROS系统的公共部分的头文件的便利引用。

     

     

    Toggle line numbers
      28 #include "std_msgs/String.h"
      29 

    This includes the std_msgs/String message, which resides in the std_msgs package. This is a header generated automatically from the String.msg file in that package. For more information on message definitions, see the msg page.

    这包含了std_msgs/String消息,它是属于std_msgs包。这是一个那个包中的String.msg文件自动生成的文件头。要查看关于消息定义的更多的消息,请查看msg页:http://wiki.ros.org/msg。

     

     

    Toggle line numbers
      47   ros::init(argc, argv, "talker");
    

    Initialize ROS. This allows ROS to do name remapping through the command line -- not important for now. This is also where we specify the name of our node. Node names must be unique in a running system.

    初始化ROS。它允许ROS通过命令行做名称重映射——目前不重要。这也是我们指定我们的节点的名字的地方。节点的名字对于一个运行的系统必须是唯一的。

     

    The name used here must be a base name, ie. it cannot have a / in it.

    这里使用的名字必须是一个base name。它不能包含/号。

     

     

    Toggle line numbers
      54   ros::NodeHandle n;
    

    Create a handle to this process' node. The first NodeHandle created will actually do the initialization of the node, and the last one destructed will cleanup any resources the node was using.

    创建一个这个处理节点的句柄。第一个创建的NodeHandle将会做节点的初始化工作,最后一个销毁的NodeHandle将会清理该节点使用的任何资源。

     

     

    Toggle line numbers
      73   ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
    

    Tell the master that we are going to be publishing a message of type std_msgs/String on the topic chatter. This lets the master tell any nodes listening on chatter that we are going to publish data on that topic. The second argument is the size of our publishing queue. In this case if we are publishing too quickly it will buffer up a maximum of 1000 messages before beginning to throw away old ones.

    告诉管理器我们将在主题chatter上发布一个std_msgs/String类型的消息。这让管理器告诉监听chatter的任何节点我们将会在那个主题上发布数据。第二个参数是我们发布队列的尺寸大小。如果我们发布太快将会在开始扔掉旧的消息时缓冲最多1000个消息。

     

    NodeHandle::advertise() returns a ros::Publisher object, which serves two purposes: 1) it contains a publish() method that lets you publish messages onto the topic it was created with, and 2) when it goes out of scope, it will automatically unadvertise.

    NodeHandle::advertise()返回一个ros::Publisher对象,它有两个目的:1)它包含一个publish()方法让你发布消息到伴随它创建的主题上,以及2)当超出范围时它将自动取消通知。

     

     

    Toggle line numbers
      75   ros::Rate loop_rate(10);
    

    A ros::Rate object allows you to specify a frequency that you would like to loop at. It will keep track of how long it has been since the last call to Rate::sleep(), and sleep for the correct amount of time.

    一个ros:rate对象允许你指定一个你喜欢的循环频率。它将追踪自上次调用Rate::sleep()函数过去多长时间了,并且睡眠正确的时间长度。

     

    In this case we tell it we want to run at 10Hz.

    在本例中我们告诉它我们想运行在10Hz频率。

     

    Toggle line numbers
      81   int count = 0;
      82   while (ros::ok())
      83   {
    

    By default roscpp will install a SIGINT handler which provides Ctrl-C handling which will cause ros::ok() to return false if that happens.

    默认情况下roscpp将安装一个SIGINT(中断信号)句柄,它会提供Ctrl-C操作会触发ros::ok()返回否如果那个发生了。

    ros::ok() will return false if:

    ros::ok()在以下情况下将会返回否:

    • a SIGINT is received (Ctrl-C) 收到一个SIGINT中断信号(Ctrl-C)
    • we have been kicked off the network by another node with the same name 我们被另一个同名节点踢下网络
    • ros::shutdown() has been called by another part of the application. 应用程序的另一部分调用ros::shutdown()

    • all ros::NodeHandles have been destroyed 所有的ros::NodeHandle被销毁

    Once ros::ok() returns false, all ROS calls will fail. 一旦ros::ok()返回否,所有的ROS调用都会失败。

     

    Toggle line numbers
      87     std_msgs::String msg;
      88 
      89     std::stringstream ss;
      90     ss << "hello world " << count;
      91     msg.data = ss.str();
    

    We broadcast a message on ROS using a message-adapted class, generally generated from a msg file. More complicated datatypes are possible, but for now we're going to use the standard String message, which has one member: "data".

    我们通过使用一个由msg文件产生的消息调节类在ROS上广播消息。更多复杂的数据类型是可能的,但是现在我们使用标准String消息,它有一个成员:"data"。

     

    Toggle line numbers
     101     chatter_pub.publish(msg);
    

    Now we actually broadcast the message to anyone who is connected.

    现在我们实际地将消息广播给任何连接的对象。

     

    Toggle line numbers
      93     ROS_INFO("%s", msg.data.c_str());
    

    ROS_INFO and friends are our replacement for printf/cout. See the rosconsole documentation for more information.

    ROS_INFO和friends友们是我们对于printf/count的替代品。看一下rosconsole参考资料获取更多信息:http://wiki.ros.org/rosconsole。

     

    Toggle line numbers
     103     ros::spinOnce();
    

    Calling ros::spinOnce() here is not necessary for this simple program, because we are not receiving any callbacks. However, if you were to add a subscription into this application, and did not have ros::spinOnce() here, your callbacks would never get called. So, add it for good measure.

    这里调用ros::spinOnce()对于这个简单的程序并不是必须的,因为我们并没有接收任何回调。但是,如果你向你的程序添加一个订阅,而这里并没有ros::spinOnce(),你的回调将不会得到调用。所以,添加一个。

     

    Toggle line numbers
     105     loop_rate.sleep();
    

    Now we use the ros::Rate object to sleep for the time remaining to let us hit our 10Hz publish rate.

    现在我们使用ros::Rate对象,让它睡眠一段时间让我们达到10Hz发布率。

    Here's the condensed version of what's going on:

    这里是关于正在进行的简约版:

    • Initialize the ROS system 初始化ROS系统
    • Advertise that we are going to be publishing std_msgs/String messages on the chatter topic to the master 向管理器宣告我们将发布std_msgs/String类型的消息到chatter主题上

    • Loop while publishing messages to chatter 10 times a second 循环发布消息到chatter,1秒10次。

    Now we need to write a node to receive the messsages.

     现在我们需要写一个节点来接收消息。

    (2)写订阅者代码

    1)代码

    Create the src/listener.cpp file within the beginner_tutorials package and paste the following inside it:

    在beginner_tutorials包内创建src/listener.cpp文件,并在其中粘贴以下内容:

    https://raw.github.com/ros/ros_tutorials/kinetic-devel/roscpp_tutorials/listener/listener.cpp

    Toggle line numbers
      28 #include "ros/ros.h"
      29 #include "std_msgs/String.h"
      30 
      31 /**
      32  * This tutorial demonstrates simple receipt of messages over the ROS system.
      33  */
      34 void chatterCallback(const std_msgs::String::ConstPtr& msg)
      35 {
      36   ROS_INFO("I heard: [%s]", msg->data.c_str());
      37 }
      38 
      39 int main(int argc, char **argv)
      40 {
      41   /**
      42    * The ros::init() function needs to see argc and argv so that it can perform
      43    * any ROS arguments and name remapping that were provided at the command line.
      44    * For programmatic remappings you can use a different version of init() which takes
      45    * remappings directly, but for most command-line programs, passing argc and argv is
      46    * the easiest way to do it.  The third argument to init() is the name of the node.
      47    *
      48    * You must call one of the versions of ros::init() before using any other
      49    * part of the ROS system.
      50    */
      51   ros::init(argc, argv, "listener");
      52 
      53   /**
      54    * NodeHandle is the main access point to communications with the ROS system.
      55    * The first NodeHandle constructed will fully initialize this node, and the last
      56    * NodeHandle destructed will close down the node.
      57    */
      58   ros::NodeHandle n;
      59 
      60   /**
      61    * The subscribe() call is how you tell ROS that you want to receive messages
      62    * on a given topic.  This invokes a call to the ROS
      63    * master node, which keeps a registry of who is publishing and who
      64    * is subscribing.  Messages are passed to a callback function, here
      65    * called chatterCallback.  subscribe() returns a Subscriber object that you
      66    * must hold on to until you want to unsubscribe.  When all copies of the Subscriber
      67    * object go out of scope, this callback will automatically be unsubscribed from
      68    * this topic.
      69    *
      70    * The second parameter to the subscribe() function is the size of the message
      71    * queue.  If messages are arriving faster than they are being processed, this
      72    * is the number of messages that will be buffered up before beginning to throw
      73    * away the oldest ones.
      74    */
      75   ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
      76 
      77   /**
      78    * ros::spin() will enter a loop, pumping callbacks.  With this version, all
      79    * callbacks will be called from within this thread (the main one).  ros::spin()
      80    * will exit when Ctrl-C is pressed, or the node is shutdown by the master.
      81    */
      82   ros::spin();
      83 
      84   return 0;
      85 }
    

    2)代码解释

    Now, let's break it down piece by piece, ignoring some pieces that have already been explained above.

    现在,让我们一片一片分解它,忽略之前已经解释过的部分。

     

    Toggle line numbers
      34 void chatterCallback(const std_msgs::String::ConstPtr& msg)
      35 {
      36   ROS_INFO("I heard: [%s]", msg->data.c_str());
      37 }
    

    This is the callback function that will get called when a new message has arrived on the chatter topic. The message is passed in a boost shared_ptr, which means you can store it off if you want, without worrying about it getting deleted underneath you, and without copying the underlying data.

    这是回调函数,它将会在当一个新消息到chatter主题时得到调用。该消息传递到一个boost shared_ptr,这意味着只要你喜欢你可以存储起来,不需要担心它会不小心被删除掉,不需要拷贝下层的数据。

     

    Toggle line numbers
      75   ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
    

    Subscribe to the chatter topic with the master. ROS will call the chatterCallback() function whenever a new message arrives. The 2nd argument is the queue size, in case we are not able to process messages fast enough. In this case, if the queue reaches 1000 messages, we will start throwing away old messages as new ones arrive.

    向管理器订阅chatter主题。每当一个新的消息到来时ROS将会调用chatterCallback()函数。第二个参数是序列尺寸大小,以防我们不能足够快地处理消息。在该情况下,如果序列到达1000个消息的话,当新消息到来时我们将开始扔掉旧消息。

    NodeHandle::subscribe() returns a ros::Subscriber object, that you must hold on to until you want to unsubscribe. When the Subscriber object is destructed, it will automatically unsubscribe from the chatter topic.

    NodeHandle::subscribe()将返回一个ros::Subscriber对象,你必须要坚持抓住它直到你想要取消订阅。当订阅对象被销毁时,它将自动地从chatter主题上取消订阅。

    There are versions of the NodeHandle::subscribe() function which allow you to specify a class member function, or even anything callable by a Boost.Function object. The roscpp overview contains more information.

    有多个版本的NodeHandle::subscribe()函数,它允许你指定一个类成员函数,或者甚至是一个Boost.Function对象的任何可调用的东西。更多信息请看roscpp概况:http://wiki.ros.org/roscpp/Overview。

     

    ros::spin() enters a loop, calling message callbacks as fast as possible. Don't worry though, if there's nothing for it to do it won't use much CPU. ros::spin() will exit once ros::ok() returns false, which means ros::shutdown() has been called, either by the default Ctrl-C handler, the master telling us to shutdown, or it being called manually.

    ros::spin()尽可能快地输入一个循环、调用消息回调。不要担心是否没有足够的CPU,它用不了太多。ros::spin()将会退出一旦ros::ok()返回否,那意味着ros::shutdown()被调用了,或者是由默认的Ctrl-C句柄,是管理器告诉我们关掉的,或者是人工调用的。

    There are other ways of pumping callbacks, but we won't worry about those here. The roscpp_tutorials package has some demo applications which demonstrate this. The roscpp overview also contains more information.

    也有其他方法引起回调,但是我们这里不用担心这些。在roscpp_tutorials包有一些demo应用阐述这个:http://wiki.ros.org/roscpp_tutorials。在roscpp概览有更多的消息:http://wiki.ros.org/roscpp/Overview。

    Again, here's a condensed version of what's going on: 再一次,让我们看一下我们进行的简洁版:

    • Initialize the ROS system  初始化ROS系统
    • Subscribe to the chatter topic  订阅chatter主题

    • Spin, waiting for messages to arrive  循环,等待消息的到来
    • When a message arrives, the chatterCallback() function is called  当一个消息到来时,chatterCallback()函数被调用。

    (3)生成你的代码

    You used catkin_create_pkg in a previous tutorial which created a package.xml and a CMakeLists.txt file for you.

    你使用前面教程中的catkin_create_pkg,它曾为你生成了package.xml和CMakeLists.txt文件。

    The generated CMakeLists.txt should look like this (with modifications from the Creating Msgs and Srvs tutorial and unused comments and examples removed):

    生成的CMakeLists.txt应该看上去像这样(从Creating Msgs and Srvs教程做了更改,移除了无用的注释和例子):

    https://raw.github.com/ros/catkin_tutorials/master/create_package_modified/catkin_ws/src/beginner_tutorials/CMakeLists.txt

    Toggle line numbers
       1 cmake_minimum_required(VERSION 2.8.3)
       2 project(beginner_tutorials)
       3 
       4 ## Find catkin and any catkin packages
       5 find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs genmsg)
       6 
       7 ## Declare ROS messages and services
       8 add_message_files(DIRECTORY msg FILES Num.msg)
       9 add_service_files(DIRECTORY srv FILES AddTwoInts.srv)
      10 
      11 ## Generate added messages and services
      12 generate_messages(DEPENDENCIES std_msgs)
      13 
      14 ## Declare a catkin package
      15 catkin_package()
    

     

    Don't worry about modifying the commented (#) examples, simply add these few lines to the bottom of your CMakeLists.txt:

    不要担心修改注释的例子,只要添加几行到底部就可以了:

     

    include_directories(include ${catkin_INCLUDE_DIRS})
    
    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_messages_cpp)

    Your resulting CMakeLists.txt file should look like this:

    你的结果CMakeLists.txt文件应该看上去像这样:

    https://raw.github.com/ros/catkin_tutorials/master/create_package_pubsub/catkin_ws/src/beginner_tutorials/CMakeLists.txt

    Toggle line numbers
       1 cmake_minimum_required(VERSION 2.8.3)
       2 project(beginner_tutorials)
       3 
       4 ## Find catkin and any catkin packages
       5 find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs genmsg)
       6 
       7 ## Declare ROS messages and services
       8 add_message_files(FILES Num.msg)
       9 add_service_files(FILES AddTwoInts.srv)
      10 
      11 ## Generate added messages and services
      12 generate_messages(DEPENDENCIES std_msgs)
      13 
      14 ## Declare a catkin package
      15 catkin_package()
      16 
      17 ## Build talker and listener
      18 include_directories(include ${catkin_INCLUDE_DIRS})
      19 
      20 add_executable(talker src/talker.cpp)
      21 target_link_libraries(talker ${catkin_LIBRARIES})
      22 add_dependencies(talker beginner_tutorials_generate_messages_cpp)
      23 
      24 add_executable(listener src/listener.cpp)
      25 target_link_libraries(listener ${catkin_LIBRARIES})
      26 add_dependencies(listener beginner_tutorials_generate_messages_cpp)
    

     

    This will create two executables, talker and listener, which by default will go into package directory of your devel space, located by default at ~/catkin_ws/devel/lib/<package name>.

    这将会生成2个执行文件,talker和listener,它们默认会进入你的devel space包路径,位置默认在~/catkin_ws/devel/lib/<package name>。

    Note that you have to add dependencies for the executable targets to message generation targets:

    注意你必须添加消息生成目标的执行目标依赖。

    add_dependencies(talker beginner_tutorials_generate_messages_cpp)

    This makes sure message headers of this package are generated before being used. If you use messages from other packages inside your catkin workspace, you need to add dependencies to their respective generation targets as well, because catkin builds all projects in parallel. As of *Groovy* you can use the following variable to depend on all necessary targets:

    这将保证该包的消息头在使用之前就生成了。如果你使用你的catkin工作空间中的其他包消息,你还需要添加它们的相应的生成目标依赖,因为catkin平行地生成所有的工程。对于Groovy版本你可以使用如下的变量添加所有必须的目标的依赖。

    target_link_libraries(talker ${catkin_LIBRARIES})

    You can invoke executables directly or you can use rosrun to invoke them. They are not placed in '<prefix>/bin' because that would pollute the PATH when installing your package to the system. If you wish for your executable to be on the PATH at installation time, you can setup an install target, see: catkin/CMakeLists.txt

    你可以直接invoke执行文件,或者你可以使用rosrun来invoke它们。它们不放在'<prefix>/bin',因为那样的话当安装你的包到系统时会污染路径。如果你希望你的执行文件当安装时在路径中,你可以设置一个安装目标,看一下:catkin/CMakeLists.txt:http://wiki.ros.org/catkin/CMakeLists.txt。

    For more detailed discription of the CMakeLists.txt file see: catkin/CMakeLists.txt

    对于CMakeLists.txt文件的更多详细描述请看:catkin/CMakeLists.txt:http://wiki.ros.org/catkin/CMakeLists.txt。

    Now run catkin_make: 现在运行catkin_make:

    # In your catkin workspace
    $ catkin_make  

    Note: Or if you're adding as new pkg, you may need to tell catkin to force making by --force-cmake option. See catkin/Tutorials/using_a_workspace#With_catkin_make.

    注意:或者如果你作为新的pkg添加,你可能需要告诉catkin来通过--force-cake选项强制生成。看一下catkin/Tutorials/using_a_workspace#With_catkin_make:http://wiki.ros.org/catkin/Tutorials/using_a_workspace#With_catkin_make。

    Now that you have written a simple publisher and subscriber, let's examine the simple publisher and subscriber.

     现在你已经写了一个简单的发布者和订阅者了,让我们测试一下这个简单的发布器和订阅器吧。

     (4)额外的资源

    Here are some additional resources contributed by the community:

     这里是一些由社区贡献的额外的资源。

    1)视频教程

    The following video presents a small tutorial explaining how to write and test a publisher and subscriber in ROS with C++ and Python based on the talker/listener example above

    以下的视频呈现了一个小教程,解释了如何在ROS上用C++和Python基于上述的talker/listener例子写并测试一个发布器和订阅器。

    12. Writing a Simple Publisher and Subscriber (Python)

    This tutorial covers how to write a publisher and subscriber node in python.

    本教程介绍了如何使用Python写一个发布器和订阅器节点。

    13. Examining the Simple Publisher and Subscriber

    This tutorial examines running the simple publisher and subscriber.

    本教程测试了运行简单的发布器和订阅器。

    (1)运行发布器

    Make sure that a roscore is up and running: 确保roscore已经启动并运行:

    $ roscore

    catkin specific If you are using catkin, make sure you have sourced your workspace's setup.sh file after calling catkin_make but before trying to use your applications: catkin确定你是否使用catkin,确保你在你尝试使用你的程序之前已经调用catkin_make源了你的工作空间的setup.sh文件。

     

    # In your catkin workspace
    $ cd ~/catkin_ws
    $ source ./devel/setup.bash

    In the last tutorial we made a publisher called "talker". Let's run it: 在上一教程中我们已经生成了一个发布器叫“talker”。让我们运行它:

    $ rosrun beginner_tutorials talker      (C++)
    $ rosrun beginner_tutorials talker.py   (Python) 

    You will see something similar to: 你将会看到类似于这样的东西:

    • [INFO] [WallTime: 1314931831.774057] hello world 1314931831.77
      [INFO] [WallTime: 1314931832.775497] hello world 1314931832.77
      [INFO] [WallTime: 1314931833.778937] hello world 1314931833.78
      [INFO] [WallTime: 1314931834.782059] hello world 1314931834.78
      [INFO] [WallTime: 1314931835.784853] hello world 1314931835.78
      [INFO] [WallTime: 1314931836.788106] hello world 1314931836.79

    The publisher node is up and running. Now we need a subscriber to receive messages from the publisher.发布器节点已经开启并运行了。现在我们需要一个订阅器接收发布器传来的消息。

    (2)运行订阅器

    In the last tutorial we made a subscriber called "listener". Let's run it: 在上一节教程中我们创建了一个订阅器叫“listener"。让我们运行它:

    $ rosrun beginner_tutorials listener     (C++)
    $ rosrun beginner_tutorials listener.py  (Python) 

    You will see something similar to: 你将会看到类似于这样的东西:

    • [INFO] [WallTime: 1314931969.258941] /listener_17657_1314931968795I heard hello world 1314931969.26
      [INFO] [WallTime: 1314931970.262246] /listener_17657_1314931968795I heard hello world 1314931970.26
      [INFO] [WallTime: 1314931971.266348] /listener_17657_1314931968795I heard hello world 1314931971.26
      [INFO] [WallTime: 1314931972.270429] /listener_17657_1314931968795I heard hello world 1314931972.27
      [INFO] [WallTime: 1314931973.274382] /listener_17657_1314931968795I heard hello world 1314931973.27
      [INFO] [WallTime: 1314931974.277694] /listener_17657_1314931968795I heard hello world 1314931974.28
      [INFO] [WallTime: 1314931975.283708] /listener_17657_1314931968795I heard hello world 1314931975.28

    Now that you have examined the simple publisher and subscriber, let's write a simple service and client (python) (c++).

    现在你已经测试了简单的发布器和订阅器,让我们写一个简单的服务和客户端吧(Python)(C++)。

    14. Writing a Simple Service and Client (C++)

    This tutorial covers how to write a service and client node in C++.

    这个教程介绍的是如何使用C++写一个服务和客户端节点。

    (1)写一个服务节点

    Here we'll create the service ("add_two_ints_server") node which will receive two ints and return the sum.

    这里我们将创建一个服务节点("add_two_ints_server"),它将会接收两个int整数,然后返回一个和。

     

    Change directories to your beginner_tutorials package you created in your catkin workspace previous tutorials:

    更改路径到之前教程你在你的catkin工作空间创建的beginner_tutorials包

     

    roscd beginner_tutorials

    Please make sure you have followed the directions in the previous tutorial for creating the service needed in this tutorial, creating the AddTwoInts.srv (be sure to choose the right version of build tool you're using at the top of wiki page in the link).

    请确保你已经遵照之前的教程的指导创建了本教程所需要的服务,请参考:creating the AddTwoInts.srv(请在wiki页顶部链接上确保选择了正确的build工具版本)。

    1)代码

    Create the src/add_two_ints_server.cpp file within the beginner_tutorials package and paste the following inside it:

    在beginner_tutorials包中创建src/add_two_ints_server.cpp文件,并在其中粘贴以下内容:

     

    Toggle line numbers
       1 #include "ros/ros.h"
       2 #include "beginner_tutorials/AddTwoInts.h"
       3 
       4 bool add(beginner_tutorials::AddTwoInts::Request  &req,
       5          beginner_tutorials::AddTwoInts::Response &res)
       6 {
       7   res.sum = req.a + req.b;
       8   ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
       9   ROS_INFO("sending back response: [%ld]", (long int)res.sum);
      10   return true;
      11 }
      12 
      13 int main(int argc, char **argv)
      14 {
      15   ros::init(argc, argv, "add_two_ints_server");
      16   ros::NodeHandle n;
      17 
      18   ros::ServiceServer service = n.advertiseService("add_two_ints", add);
      19   ROS_INFO("Ready to add two ints.");
      20   ros::spin();
      21 
      22   return 0;
      23 }
    

    2)代码解释

    Now, let's break the code down.

    现在,让我们分解代码。

     

    Toggle line numbers
       1 #include "ros/ros.h"
       2 #include "beginner_tutorials/AddTwoInts.h"
       3 

    beginner_tutorials/AddTwoInts.h is the header file generated from the srv file that we created earlier.

    beginner_tutorials/AddTwoInts.h是我们早些时候创建的srv文件产生的头文件。

     

    Toggle line numbers
       4 bool add(beginner_tutorials::AddTwoInts::Request  &req,
       5          beginner_tutorials::AddTwoInts::Response &res)
    

    This function provides the service for adding two ints, it takes in the request and response type defined in the srv file and returns a boolean.

    该方法提供了添加两个int的服务,它吸收srv文件中定义的请求和回复类型,返回一个布尔型。

     

    Toggle line numbers
       6 {
       7   res.sum = req.a + req.b;
       8   ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
       9   ROS_INFO("sending back response: [%ld]", (long int)res.sum);
      10   return true;
      11 }
    

    Here the two ints are added and stored in the response. Then some information about the request and response are logged. Finally the service returns true when it is complete.

    这里两个int整数相加并存储在回复中。然后一些关于请求和回复的信息记录了下来。最终当完成时服务返回真。

     

    Toggle line numbers
      18   ros::ServiceServer service = n.advertiseService("add_two_ints", add);
    

    Here the service is created and advertised over ROS.

    这里服务被创建了并且在ROS上展现了出来。

    (2)写客户端代码

    1)代码

    Create the src/add_two_ints_client.cpp file within the beginner_tutorials package and paste the following inside it:

    在beginner_tutorials包中创建src/add_two_ints_client.cpp文件,并在其中粘贴以下内容:

     

    Toggle line numbers
       1 #include "ros/ros.h"
       2 #include "beginner_tutorials/AddTwoInts.h"
       3 #include <cstdlib>
       4 
       5 int main(int argc, char **argv)
       6 {
       7   ros::init(argc, argv, "add_two_ints_client");
       8   if (argc != 3)
       9   {
      10     ROS_INFO("usage: add_two_ints_client X Y");
      11     return 1;
      12   }
      13 
      14   ros::NodeHandle n;
      15   ros::ServiceClient client = n.serviceClient<beginner_tutorials::AddTwoInts>("add_two_ints");
      16   beginner_tutorials::AddTwoInts srv;
      17   srv.request.a = atoll(argv[1]);
      18   srv.request.b = atoll(argv[2]);
      19   if (client.call(srv))
      20   {
      21     ROS_INFO("Sum: %ld", (long int)srv.response.sum);
      22   }
      23   else
      24   {
      25     ROS_ERROR("Failed to call service add_two_ints");
      26     return 1;
      27   }
      28 
      29   return 0;
      30 }
    

    2)代码解释

    Now, let's break the code down.

    现在,让我们分解代码。

     

    Toggle line numbers
      15   ros::ServiceClient client = n.serviceClient<beginner_tutorials::AddTwoInts>("add_two_ints");
    

    This creates a client for the add_two_ints service. The ros::ServiceClient object is used to call the service later on.

    这个创建一个相加两个整数(”add_two_ints“)服务的客户端。ros::ServiceClient对象用来晚些时候调用服务。

     

    Toggle line numbers
      16   beginner_tutorials::AddTwoInts srv;
      17   srv.request.a = atoll(argv[1]);
      18   srv.request.b = atoll(argv[2]);
    

    Here we instantiate an autogenerated service class, and assign values into its request member. A service class contains two members, request and response. It also contains two class definitions, Request and Response.

    这里我们实例化一个自动生成的服务类,并把值赋给它的请求成员。一个服务类包含两个成员,请求和回复。它还包括两个类定义,请求和回复。

     

    Toggle line numbers
      19   if (client.call(srv))
    

    This actually calls the service. Since service calls are blocking, it will return once the call is done. If the service call succeeded, call() will return true and the value in srv.response will be valid. If the call did not succeed, call() will return false and the value in srv.response will be invalid.

    这个实际上是调用服务。如果服务调用正占用着,它将在调用完成后返回。如果服务调用成功了,call()将返回真以及srv中的值。回复将是有效的。如果调用不成功,call()将返回否以及srv中的值。回复将是无效的。

    (3)生成你的代码

    Again edit the beginner_tutorials CMakeLists.txt located at ~/catkin_ws/src/beginner_tutorials/CMakeLists.txt and add the following at the end:

    再一次编辑位于~/catkin_ws/src/beginner_tutorials/CMakeLists.txt的beginner_tutorials CMakeLists.txt,在尾部添加如下内容:

    https://raw.github.com/ros/catkin_tutorials/master/create_package_srvclient/catkin_ws/src/beginner_tutorials/CMakeLists.txt

    Toggle line numbers
      27 add_executable(add_two_ints_server src/add_two_ints_server.cpp)
      28 target_link_libraries(add_two_ints_server ${catkin_LIBRARIES})
      29 add_dependencies(add_two_ints_server beginner_tutorials_gencpp)
      30 
      31 add_executable(add_two_ints_client src/add_two_ints_client.cpp)
      32 target_link_libraries(add_two_ints_client ${catkin_LIBRARIES})
      33 add_dependencies(add_two_ints_client beginner_tutorials_gencpp)
    

     

    This will create two executables, add_two_ints_server and add_two_ints_client, which by default will go into package directory of your devel space, located by default at ~/catkin_ws/devel/lib/<package name>. You can invoke executables directly or you can use rosrun to invoke them. They are not placed in '<prefix>/bin' because that would pollute the PATH when installing your package to the system. If you wish for your executable to be on the PATH at installation time, you can setup an install target, see: catkin/CMakeLists.txt

    这将会生成两个可执行文件,add_two_ints_server和add_two_ints_client,它们默认情况下将会进入你的devel space包目录中,默认路径为~/catkin_ws/devel/lib/<package name>。你可以直接invoke可执行文件,或者你也可以使用rosrun来invoke它们。它们并不放在'<prefix>/bin',因为那样会在将你的包安装到系统时污染路径。如果你希望你的可执行文件在安装时存在在该路径中,你可以设置一个安装目标,看:

    For more detailed description of the CMakeLists.txt file see: catkin/CMakeLists.txt

    对于CMakeLists.txt文件的更多详细描述请看:catkin/CMakeLists.txt:http://wiki.ros.org/catkin/CMakeLists.txt。

    Now run catkin_make: 现在运行catkin_make:

    # In your catkin workspace
    cd ~/catkin_ws
    catkin_make

    If your build fails for some reason: 如果你因为某些原因生成失败:

    • make sure you have followed the directions in the previous tutorial: creating the AddTwoInts.srv. 请保证你遵循之前教程的步骤:创建AddTwoInts.srv。

     

    Now that you have written a simple service and client, let's examine the simple service and client.

     现在你已经写了一个简单的服务和客户端,让我们测试一下简单服务和客户端吧。

    15. Writing a Simple Service and Client (Python)

    This tutorial covers how to write a service and client node in python.

    16. Examining the Simple Service and Client

    This tutorial examines running the simple service and client.

    该教程测试了运行简单的服务和客户端。

    (1)运行服务

    Let's start by running the service: 让我们开始运行服务:

    $ rosrun beginner_tutorials add_two_ints_server     (C++)
    $ rosrun beginner_tutorials add_two_ints_server.py  (Python) 

    You should see something similar to: 你将会看到类似于这样的内容:

    Ready to add two ints.

     (2)运行客户端

    Now let's run the client with the necessary arguments: 现在让我们运行客户端:

    $ rosrun beginner_tutorials add_two_ints_client 1 3     (C++)
    $ rosrun beginner_tutorials add_two_ints_client.py 1 3  (Python) 

    You should see something similar to: 你应该会看到类似这样的东西:

    Requesting 1+3
    1 + 3 = 4

    Now that you've successfully run your first server and client, let's learn how to record and play back data.

    现在你已经成功地运行你的第一个服务器和客户端了,让我们开始学习如何记录和重放数据。

    (3)关于服务和客户端节点的更多的例子

    If you want to investigate further and get a hands-on example, you can get one here. A simple Client and Service combination shows the use of custom message types. The Service node is written in C++ while the Client is available in C++, Python and LISP.

    如果你想要探究的更远并有一个可以动手操作的例子, 那么你在这里可以获得一个:https://github.com/fairlight1337/ros_service_examples/。一个简单的客户端和服务相结合展现了用户消息类型的使用。服务节点是用C++写的,而客户端是可以用C++,Python和LISP实现。

    17. Recording and playing back data 记录和回放数据

    This tutorial will teach you how to record data from a running ROS system into a .bag file, and then to play back the data to produce similar behavior in a running system.

    该教程将教给你如何从一个运行的ROS系统记录数据到一个.bag文件,然后回放数据从而在运行系统中产生相似的行为。

    (1)记录数据(创建一个bag文件)

    This section of the tutorial will instruct you how to record topic data from a running ROS system. The topic data will be accumulated in a bag file.

    这部分教程将指导你如何从一个运行的ROS系统中记录主题数据。主题数据将收集在一个bag文件中。

    First, execute the following two commands:

    首先,执行下面的两个命令:

     

    roscore
    rosrun turtlesim turtlesim_node 
    rosrun turtlesim turtle_teleop_key

    This will start two nodes - the turtlesim visualizer and a node that allows for the keyboard control of turtlesim using the arrows keys on the keyboard. If you select the terminal window from which you launched turtle_keyboard, you should see something like the following:

    这将会启动两个节点 - turtlesim可视化器和一个允许使用键盘箭头键键盘控制turtlesim的节点。如果你选择了启动turtle_keyboard的终端窗口,你将会看到类似以下内容的东西:

     

    Reading from keyboard
    ---------------------------
    Use arrow keys to move the turtle.

    Pressing the arrow keys on the keyboard should cause the turtle to move around the screen. Note that to move the turtle you must have the terminal from which you launched turtlesim selected and not the turtlesim window.

    按键盘上的箭头键将引发乌龟在屏幕上移动。注意要让乌龟移动你必须是在启动turtlesim选择的终端,而不是turtlesim窗口。

    1)记录发布的主题

    First lets examine the full list of topics that are currently being published in the running system. To do this, open a new terminal and execute the command:

    首先让我们测试一下目前发布在运行系统的所有主题列表。要做这个,请打开一个新终端然后执行命令:

     

    rostopic list -v

    This should yield the following output:

    这将产生如下的输出:

    Published topics:
     * /turtle1/color_sensor [turtlesim/Color] 1 publisher
     * /turtle1/cmd_vel [geometry_msgs/Twist] 1 publisher
     * /rosout [rosgraph_msgs/Log] 2 publishers
     * /rosout_agg [rosgraph_msgs/Log] 1 publisher
     * /turtle1/pose [turtlesim/Pose] 1 publisher
    
    Subscribed topics:
     * /turtle1/cmd_vel [geometry_msgs/Twist] 1 subscriber
     * /rosout [rosgraph_msgs/Log] 1 subscriber

    The list of published topics are the only message types that could potentially be recorded in the data log file, as only published messages are recorded. The topic /turtle1/cmd_vel is the command message published by teleop_turtle that is taken as input by the turtlesim process. The messages /turtle1/color_sensor and /turtle1/pose are output messages published by turtlesim.

    已发布的主题列表是唯一的能够可能被记录在数据log文件中的消息类型,因为只有已发布的消息被记录下来。主题/turtle1/cmd_vel是由teleop_turtle发布的命令消息,作为turtlesim处理的输入。消息/turtle1/color_sensor和/turtle1/pose是由turtlesim发布的输出消息。

    We now will record the published data. Open a new terminal window. In this window run the following commands:

    我们现在将记录已发布数据。打开一个新的终端窗口。在该窗口中运行如下命令:

     

    mkdir ~/bagfiles
    cd ~/bagfiles
    rosbag record -a

    Here we are just making a temporary directory to record data and then running rosbag record with the option -a, indicating that all published topics should be accumulated in a bag file.

    这里我们只是创建一个临时的目录用来记录数据,然后运行带有-a选项的rosbag record命令,表明所有已发布主题都应该被收集到一个bag文件中。

    Move back to the terminal window with turtle_teleop and move the turtle around for 10 or so seconds.

    回到turtle_teleop终端窗口,移动乌龟10秒钟左右。

    In the window running rosbag record exit with a Ctrl-C. Now examine the contents of the directory ~/bagfiles. You should see a file with a name that begins with the year, data, and time and the suffix .bag. This is the bag file that contains all topics published by any node in the time that rosbag record was running.

    在运行rosbag record的窗口中使用Ctrl-C退出。现在测试目录~/bagfiles中的内容。你应该看到一个以年,数据和时间以及.bag后缀命名的文件。这是包含所有在rosbag record运行期间任何节点已发布主题的包文件。

    (2)测试并回放bag文件

    Now that we've recorded a bag file using rosbag record we can examine it and play it back using the commands rosbag info and rosbag play. First we are going to see what's recorded in the bag file. We can do the info command -- this command checks the contents of the bag file without playing it back. Execute the following command from the bagfiles directory:

    现在我们已经使用rosbag record记录了一个bag文件。我们从而可以使用命令rosbag info和rosbag play来测试它并回放它。首先我们将看到在bag文件中记录的是什么。我们可以使用info命令--这个命令检查bag文件中的内容,并没有回放。从bag文件目录执行以下命令:

    rosbag info <your bagfile>

    You should see something like:

     

    path:        2014-12-10-20-08-34.bag
    version:     2.0
    duration:    1:38s (98s)
    start:       Dec 10 2014 20:08:35.83 (1418270915.83)
    end:         Dec 10 2014 20:10:14.38 (1418271014.38)
    size:        865.0 KB
    messages:    12471
    compression: none [1/1 chunks]
    types:       geometry_msgs/Twist [9f195f881246fdfa2798d1d3eebca84a]
                 rosgraph_msgs/Log   [acffd30cd6b6de30f120938c17c593fb]
                 turtlesim/Color     [353891e354491c51aabe32df673fb446]
                 turtlesim/Pose      [863b248d5016ca62ea2e895ae5265cf9]
    topics:      /rosout                    4 msgs    : rosgraph_msgs/Log   (2 connections)
                 /turtle1/cmd_vel         169 msgs    : geometry_msgs/Twist
                 /turtle1/color_sensor   6149 msgs    : turtlesim/Color    
                 /turtle1/pose           6149 msgs    : turtlesim/Pose

    This tells us topic names and types as well as the number (count) of each message topic contained in the bag file. We can see that of the topics being advertised that we saw in the rostopic output, four of the five were actually published over our recording interval. As we ran rosbag record with the -a flag it recorded all messages published by all nodes.

    这个除了告诉我们在bag文件中包含的每个消息主题的数目之外,还告诉了我们主题名字和类型。我们可以看到我们在rostopic输出中看到的展示的主题,5个中的4个都在我们的记录间隔内实际地发布。当我们运行带有-a标签的rosbag record时它记录了所有节点发布的所有消息。

    The next step in this tutorial is to replay the bag file to reproduce behavior in the running system. First kill the teleop program that may be still running from the previous section - a Ctrl-C in the terminal where you started turtle_teleop_key. Leave turtlesim running. In a terminal window run the following command in the directory where you took the original bag file:

    该教程的下一步就是回放bag文件来重制运行系统中的行为。首先终止在之前部分可能还在运行着的teleop程序-在你启动turtle_teleop_key的终端使用Ctrl-C。

    rosbag play <your bagfile>

    In this window you should immediately see something like: 在窗口你应该很快会看到类似这样的东西:

     

    [ INFO] [1418271315.162885976]: Opening 2014-12-10-20-08-34.bag
    
    Waiting 0.2 seconds after advertising topics... done.
    
    Hit space to toggle paused, or 's' to step.

    In its default mode rosbag play will wait for a certain period (.2 seconds) after advertising each message before it actually begins publishing the contents of the bag file. Waiting for some duration allows any subscriber of a message to be alerted that the message has been advertised and that messages may follow. If rosbag play publishes messages immediately upon advertising, subscribers may not receive the first several published messages. The waiting period can be specified with the -d option.

    在默认模式下rosbag play将在它真正开始发布bag文件内容之前在宣布每个消息之后等待一段时间(0.2秒)。等待一段时间允许任何消息的订阅者注意消息已经被宣布了而且消息将会追踪。如果rosbag play公布时立即发布消息,订阅者可能没有收到开始的几个发布的消息。等待阶段可以使用-d选项指定。

    Eventually the topic /turtle1/cmd_vel will be published and the turtle should start moving in turtlesim in a pattern similar to the one you executed from the teleop program. The duration between running rosbag play and the turtle moving should be approximately equal to the time between the original rosbag record execution and issuing the commands from the keyboard in the beginning part of the tutorial. You can have rosbag play not start at the beginning of the bag file but instead start some duration past the beginning using the -s argument. A final option that may be of interest is the -r option, which allows you to change the rate of publishing by a specified factor. If you execute:

    最后主题/turlte1/cmd_vel将被发布乌龟将开始在turtlesim中以类似于你teleop程序中执行的模式移动。运行rosbag play和乌龟移动之间的持续时间应该大约等于原来在开始教程中的rosbag record执行以及开始从键盘发出命令之间的时间。你可以让rosbag play不从bag文件的开始端开始而是使用-s参数从开始端过去一些时间开始。一个可能感兴趣的终止选项会是-r选项,它允许你通过一个特定的元素更改发布频率。如果你执行:

     

    rosbag play -r 2 <your bagfile>

     

    You should see the turtle execute a slightly different trajectory - this is the trajectory that would have resulted had you issued your keyboard commands twice as fast.

    你应该会看到乌龟执行有点不同的轨道 - 这是一个让你键盘命令加快一倍的运行轨道。

     (3)记录数据的子集

    When running a complicated system, such as the pr2 software suite, there may be hundreds of topics being published, with some topics, like camera image streams, potentially publishing huge amounts of data. In such a system it is often impractical to write log files consisting of all topics to disk in a single bag file. The rosbag record command supports logging only particular topics to a bag file, allowing a user to only record the topics of interest to them.

    当运行一个复杂的系统,比如pr2软件套件,将会有数百个主题被发布,带有一些主题比如相机图像流,可能会发布大量的数据。在这样的系统中将包含所有主题的日志文件写到单个bag文件中是不现实的。rosbag record命令支持只记录部分的主题到一个bag文件中,允许一个用户只记录他们感兴趣的主题。

    If any turtlesim nodes are running exit them and relaunch the keyboard teleop launch file:

    如果turtlesim节点还在运行着退出它们然后重新运行键盘遥控启动文件:

     

    rosrun turtlesim turtlesim_node 
    rosrun turtlesim turtle_teleop_key

    In your bagfiles directory, run the following command:

    在你的bag文件目录中,运行如下的命令:

     

    rosbag record -O subset /turtle1/cmd_vel /turtle1/pose

    The -O argument tells rosbag record to log to a file named subset.bag, and the topic arguments cause rosbag record to only subscribe to these two topics. Move the turtle around for several seconds using the keyboard arrow commands, and then Ctrl-C the rosbag record.

    -O参数告诉rosbag record记录到一个叫subset.bag的文件中,而主题参数调用rosbag record只订阅这两个主题。使用键盘箭命令移动乌龟几秒钟,然后使用Ctrl-C结束记录。

    Now check the contents of the bag file (rosbag info subset.bag). You should see something like this, with only the indicated topics:

    现在检查一下bag文件的内容(rosbag info subset.bag)。你应该会看到像这样的一些东西,只带有指示的主题:

     

    path:        subset.bag
    version:     2.0
    duration:    12.6s
    start:       Dec 10 2014 20:20:49.45 (1418271649.45)
    end:         Dec 10 2014 20:21:02.07 (1418271662.07)
    size:        68.3 KB
    messages:    813
    compression: none [1/1 chunks]
    types:       geometry_msgs/Twist [9f195f881246fdfa2798d1d3eebca84a]
                 turtlesim/Pose      [863b248d5016ca62ea2e895ae5265cf9]
    topics:      /turtle1/cmd_vel    23 msgs    : geometry_msgs/Twist
                 /turtle1/pose      790 msgs    : turtlesim/Pose

     (4)rosbag record/play的限制

    In the previous section you may have noted that the turtle's path may not have exactly mapped to the original keyboard input - the rough shape should have been the same, but the turtle may not have exactly tracked the same path. The reason for this is that the path tracked by turtlesim is very sensitive to small changes in timing in the system, and rosbag is limited in its ability to exactly duplicate the behavior of a running system in terms of when messages are recorded and processed by rosrecord, and when messages are produced and processed when using rosplay. For nodes like turtlesim, where minor timing changes in when command messages are processed can subtly alter behavior, the user should not expect perfectly mimicked behavior.

     在之前的小节你可能已经注意到了乌龟的路径可能并不能准确地映射到原始的键盘输入 - 大致的图形应该是相同的,但是乌龟可能并不能够追踪到相同的路径。这个情况的原因是乌龟追踪的路径在系统中是对于定时的小改变很细微的。而rosbag在对于消息记录并由rosrecord记录、并当消息保存并由rosplay处理的严格复制运行系统的行为能力上是有局限性的。对于像turtlesim的节点,当命令消息处理时小的定时改变可能会改变行为,用户应该不能期望完美地复制行为。

     

     

    Now that you've learned how to record and play back data, let's learn how to troubleshoot with roswtf.

     现在你已经学会了如何记录并回放数据,让我们学习如何使用roswtf进行故障排除。

    18. Getting started with roswtf 开始roswtf的使用

    Basic introduction to the roswtf tool.

    关于roswtf工具的基本使用

    Before you start this tutorial, please make sure your roscore is NOT running.

    开始学习本教程之前,请确保你的roscore不在运行中。

    (1)检查你的安装

    roswtf examines your system to try and find problems. Let's try it out:

    roswtf能测试你的系统,努力查找错误。让我们试一下吧:

    $ roscd
    $ roswtf

    You should see (detail of the output varies):

    Stack: ros
    ======================================================
    Static checks summary:
    
    No errors or warnings
    ======================================================
    
    Cannot communicate with master, ignoring graph checks

    If your installation ran correctly you should output similar to the above. The output is telling you:

    如果你的安装运行良好你应该会输出类似于上面的东西。这个输出是在告诉你:

    • "Stack: ros": roswtf uses whatever your current directory is to determine what checks it does. This is telling us that you started roswtf in the ros stack.你当前的路径决定了roswtf使用什么样的检查。这个是在告诉我们你在ros stack启动roswtf。

    • "Static checks summary": this is a report on any filesystem issues. It's telling us that there were no errors. 这是一个关于文件系统问题的报告。这是在告诉我们没有错误。
    • "Cannot communicate with master, ignoring graph checks": the roscore isn't running, so roswtf didn't do any online checks.roscore不在运行,所以roswtf不会做什么在线检查。

    (2)在线尝试

    For this next step, we want a Master to be up, so go ahead and start a roscore.

    对于下一步,我们希望一个管理器上来,所以我们开启一个roscore。

    Now, try running the same sequence again:

    $ roscd
    $ roswtf

    You should see:

    Stack: ros
    ======================================================
    Static checks summary:
    
    No errors or warnings
    ======================================================
    Beginning tests of your ROS graph. These may take awhile...
    analyzing graph...
    ... done analyzing graph
    running graph rules...
    ... done running graph rules
    
    Online checks summary:
    
    Found 1 warning(s).
    Warnings are things that may be just fine, but are sometimes at fault
    
    WARNING The following node subscriptions are unconnected:
     * /rosout:
       * /rosout

    roswtf did some online examination of your graph now that your roscore is running. Depending on how many ROS nodes you have running, this can take a long time to complete. As you can see, this time it produced a warning:

    WARNING The following node subscriptions are unconnected:
     * /rosout:
       * /rosout

    roswtf is warning you that the rosout node is subscribed to a topic that no one is publishing to. In this case, this is expected because nothing else is running, so we can ignore it.

    roswtf是一个警告,是说rosout节点被订阅到一个并没有人发布东西的主题上了。在这种情况下,是合乎情理的因为还没有任何东西运行,所以我们可以忽略它。

    (3)错误

    roswtf will warn you about things that look suspicious but may be normal in your system. It can also report errors for problems that it knows are wrong.

    roswtf将警告你那些系统中看上去有怀疑但是可能是正常的。它还能报告它所知道是错误的问题错误。

    For this part, we are going to set your ROS_PACKAGE_PATH to a bad value. We're also going to stop our roscore to simplify the output that you see.

    对于这一部分,我们将设置你的ROS_PACKAGE_PATH一个错误值。我们将终止我们的roscore来简化你能看到的输出。

     

    $ roscd
    $ ROS_PACKAGE_PATH=bad:$ROS_PACKAGE_PATH roswtf

    This time we see: 这一次我们将看到:

    Stack: ros
    ======================================================
    Static checks summary:
    
    Found 1 error(s).
    
    ERROR Not all paths in ROS_PACKAGE_PATH [bad] point to an existing directory: 
     * bad
    
    ======================================================
    
    Cannot communicate with master, ignoring graph checks

    As you can see, roswtf now gives us an error about the ROS_PACKAGE_PATH setting.

    正如你看到的,roswtf现在给我们一个关于ROS_PACKAGE_PATH设置的错误提示。

    There are many other types of problems that roswtf can find. If you find yourself stumped by a build or communication issue, try running it and seeing if it can point you in the right direction.

    有很多roswtf能找到的其他类型的问题。如果你发现你自己被一个生成或交流问题难倒了,试着运行它看一下是否它能指给你正确的方向。

    Now that you know how to use roswtf, take sometime to learn more about how ros.org is structured and navigating the wiki.

     现在你知道了如何使用roswtf,花点时间学习ros.org是如何架构的,浏览wiki:http://wiki.ros.org/ROS/Tutorials/NavigatingTheWiki。

    19. Navigating the ROS wiki 浏览ROS wiki

    This tutorial discusses the layout of the ROS wiki (ros.org) and talks about how to find what you want to know.

     这个教程讨论了ROS wiki的布局,讨论了关于如何找到你想要知道的东西。

    This tutorial will look at the different headers, links, and sidebars through out the wiki to help you understand how ROS.org is laid out.

    本教程将看一下wiki不同的头、链接和边栏帮助你理解ROS.org是如何摆设的。

    (1)基本的

    1) ROS.org登录界面

    The landing page is where you are directed to when you type www.ros.org into you browser. Let's look at the ROS wiki header that is displayed at the top of every wiki page.

    这个登录界面是你输入www.ros.org进入的页面。让我们看一下ROS wiki头部,它是显示在每一个wiki页面的头部。


    descriptive_ros_header.png

    As you can see each package contains tutorials and troubleshooting specific to the package.

     正如你看到的,每一个包都包含着教程和该包特有的故障检修。

    2)ROS包页面

    Let's look at ros-pkg package wiki page for tf (www.ros.org/wiki/tf). The package header for each package is auto generated from the stack and package manifest.

    让我们看一下tf的ros-pkg包wiki页面:tf(www.ros.org/wiki/tf).每个包的包头是从栈和包的manifest元清单自动生成的。

    tf_package_detail.png

    3)ROS栈页面

    Let's look at ros stack wiki page for ROS (www.ros.org/wiki/ROS). The stack header for each stack is auto generated from the stack manifest.

    让我们ROS的ros栈wiki页面(www.ros.org/wiki/ROS)。每个栈的栈头是由栈manifest自动生成的。

    stack_header_detail.png

    As you can see each stack contains tutorials and troubleshooting specific to the stack.

     正如你看到的,每个栈都包含该栈特有的教程和故障检修。

     (2)高级

    Beginners can skip this section.

    初学者可以略过这一节。

     

    To create tutorial pages under your package 在你的包下创建教程页

    1. Once you have created your package page, open the URL with /tutorials at the tail of the URL of your package. For example, suppose your package is located at http://wiki.ros.org/foo_pkg. You should open http://wiki.ros.org/foo_pkg/tutorials. This way the wiki will create a new page. 在你的包的URL末尾加/tutorials。

    2. The page will say This page does not exist yet. What type of page are you trying to create?. The wiki is correct, because there's no (hopefully) such page. ROS wiki now shows a list of templates, choose TutorialIndexTemplate. 这个页面会说这个页面不存在。你需要创建什么类型的页面?。这个wiki是正确的,因为还没有这样的页面。ROS wiki现在展示了一系列的模板,选择TutorialIndexTemplate。

    3. Now you are redirected to the wiki page editor. Add whatever change you think you need, and save it at the end. Using Preview often to check how it looks is a great idea. Notice that, however, there are some ROS wiki macros that do not get activated until you save the page (in that case you just have to pray that your edition works, but it's okay to try and error!). 现在你被重定向一个wiki页面编辑器。添加你需要的任何更改,在尾部保存它。使用Preview预览检查一下它的样子是个很好的主意。但是,主意,有一些ROS wiki macros不需要激活直到你保存这个页面(那种情况下你只是祈祷你的编辑起作用了,但是没关系尝试试错)。

     1]排序你的教程

    By default, TutorialIndexTemplate uses a macro FullSearchWithDescriptionsCS, which searches all available tutorials under the URL hierarchy you chose (http://wiki.ros.org/foo_pkg/tutorials in this case). There the order of tutorials are based on the "links" between tutorials (next.0 attribute in each page's tutorial header).

    默认情况下,TutorialIndexTemplate使用一个宏FullSearchWithDescriptionsCS,它将在你选择的URL层级之下(在本例子中是http://wiki.ros.org/foo_pkg/tutorials)搜索所有可用的教程。那样教程的顺序是基于教程之间的"links"(每个页面的教程头中的next.0属性)。

    Often, you want to sort the tutorial in your own way, like ROS' basic tutorial top page does. To do so you use TutorialChain macro. See the example in ROS basic tutorials.

    很多情况下,你希望按照自己的方式排序教程,像ROS的基本教程顶页那样。要实现这个你需要使用TutorialChain宏。看ROS基础教程的例子。

    20. Where Next? 下一步是什么?

    This tutorial discusses options for getting to know more about using ROS on real or simulated robots.

     该教程讨论了在真实或者模拟的机器人中使用ROS的更多知识。

     

    At this point in the beginner's tutorials you should have an understanding of the core concepts of ROS.

    到这里你应该已经对ROS的核心概念有了一个理解了。

    Given a robot that runs ROS, you could use this understanding to list topics published and subscribed by the robot, to identify the messages consumed by these topics and then write your own nodes that process sensor data and act in the world.

    假设一个机器人运行ROS,你可以使用这种理解:列出由机器人发布和订阅的主题,识别这些主题使用的消息,然后写出你自己的节点来处理传感器数据并且实际运行。

    The real attraction of ROS is not the publish/subscribe middle-ware itself but that ROS provides a standard mechanism for developers around the world to share their code. The best "feature" of ROS is its enormous community.

    ROS的真正的魅力并不是发布/订阅中间件,而是ROS为世界各地的开发者提供了一个标准的机械结构来共享他们的代码。ROS最好的功能是它庞大的社区。

    The number of packages available can be overwhelming. This tutorial attempts to give you an idea of what to explore next.

    可用的包的数量可能很惊人的。本教程告诉你下一步如何挖掘。

    (1)启动一个模拟器

    Even if you have a real robot, it is good to get started using a simulator so that if something goes wrong you don't injure yourself or damage an expensive robot.

    虽然你有了一个真实的机器人,但是以一个模拟器开始是很好的,从而避免如果出现了某些错误你不会伤到自己或者伤害到一个昂贵的机器人。

    You can get started with the PR2 Simulator or the Turtlebot Simulator. Alternately, you might search for your robot and check whether it has a simulator of its own.

    你可以用PR2模拟器(http://wiki.ros.org/pr2_simulator/Tutorials)开始或者是Turtlebot模拟器(http://wiki.ros.org/turtlebot_simulator/Tutorials)开始。另外,你可以查找一个你的机器人(http://wiki.ros.org/Robots)检查一下是否它有个它自己的模拟器。

    At this point, you might try to control the simulated robot using a 'teleop' package (e.g., turtlebot_teleop) or use your understanding of ROS to find a topic and write code that sends an appropriate message to drive your robot.

    到这里,你可以尝试着使用一个'teleop'包(遥控器,例如turtlebot_teleop:http://wiki.ros.org/turtlebot_teleop/Tutorials/Teleoperation)控制模拟机器人,或者使用你自己对于ROS的理解查找一个主题或者写一个节点能够发送一个合适的消息来驱动你的机器人。

    (2)探索RViz

    RViz is a powerful visualization tool that allows you to view the robot's sensors and internal state. The user guide will help you get started.

    RViz是一个强大的可视化工具它能允许你查看机器人的传感器以及内部状态。用户手册将帮助你开始:http://wiki.ros.org/rviz/UserGuide。

    (3)理解TF

    The TF package transforms between different coordinate frames used by your robot and keeps track of these transforms over time. A good understanding of TF is essential when working with any real robot. It is worthwhile to work through the tutorials.

    TF包可以在由你的机器人使用的不同坐标框架之间改变,并且随时间追踪这些改变。当协同任何真实的机器人工作时一个对TF好的理解是必要的。所以看一下该教程值得的。

    If you're building your own robot, you might at this point consider constructing a URDF model for your robot. If you're using a "standard" robot then one has probably already being built for you. Nevertheless, it may be worthwhile to briefly familiarize yourself with the URDF package.

    如果你是在建立你自己的机器人,你可能这个时候考虑为你的机器人构建一个URDF模型:http://wiki.ros.org/urdf/Tutorials。如果你使用一个“标准的”机器人,那么你可能已经有一个为你建好的机器人模型了。不管怎样,自己简单地熟悉一下URDF包是值得的。

     (4)深入学习

    At this point, you're probably ready to start getting your robot to perform more sophisticated tasks. The following pages may help you:

    到这一步,你差不多可以准备开始让你的机器人执行复杂一些的任务了。以下页面将会帮助你:

    1. actionlib - The actionlib package provides a standardized interface for interfacing with preemptible tasks. This is widely used by "higher-level" packages in ROS. 该actionlib包为你提供了一个标准和预置的任务j交接的接口。这在ROS中由“更高水平”的包广泛使用。

    2. navigation - 2D navigation: map-building and path planning. 2D导航:地图建立和路径规划。

    3. MoveIt - To control the arms of your robot. 控制机器人的手臂。

     

    Now that you have completed the beginner level tutorials please answer this short questionnaire.

    现在你已经完成了初学者水平的教程,请回答这个简单的问卷。

  • 相关阅读:
    WebActivatorEx
    autofac
    svn: E230001: Server SSL certificate verification failed
    uml 关系
    PowerDesigner生成PHP代码 UML
    linux 命令
    jQuery ajax跨域调用出现No Transport
    2015年终总结
    php+apache配置
    Memcached
  • 原文地址:https://www.cnblogs.com/2008nmj/p/5980387.html
Copyright © 2020-2023  润新知