ROS教程(上) - RLi43/Baxter-Experimental-Guide GitHub Wiki

ROS文件系统介绍

文件系统介绍wiki: ROS文件系统介绍

1 预备工作

首先安装ros-tutorials程序包:

$ sudo apt-get install ros-indigo-ros-tutorials

$ sudo apt-get install ros-<distro>-ros-tutorials 将 <distro> 替换成你所安装的版本(比如Jade、Indigo、hydro、groovy、fuerte等)。ROS发行版本简介

2 文件系统概念

Packages: 软件包,是ROS应用程序代码的组织单元,每个软件包都可以包含程序库、可执行文件、脚本或者其它手动创建的东西。

Manifest : 清单,是对软件包相关信息的描述,用于定义软件包相关元信息之间的依赖关系,这些信息包括版本、维护者和许可协议等。

3 文件系统工具

程序代码是分布在众多ROS软件包当中,当使用命令行工具(比如ls和cd)来浏览时会非常繁琐,因此ROS提供了专门的命令工具来简化这些操作。

3.1 使用rospack

rospack允许你获取软件包的有关信息。rospack中find参数选项,该选项可以返回软件包的路径信息。

用法:

$ rospack find [包名称]

示例:

$ rospack find roscpp

如果你是在Ubuntu Linux操作系统上通过apt-get来安装ROS,你应该会准确地看到输出结果:

/opt/ros/indigo/share/roscpp

3.2 使用roscd

roscd是rosbash命令集中的一部分,它允许你直接切换(cd)工作目录到某个软件包或者软件包集当中。

用法:

$ roscd [本地包名称[/子目录]]

示例:

$ roscd roscpp

为了验证我们已经切换到了roscpp软件包目录下,现在我们可以使用Unix命令pwd来输出当前工作目录:

$ pwd

应该能够看到:

YOUR_INSTALL_PATH/share/roscpp

你可以看到YOUR_INSTALL_PATH/share/roscpp和之前使用rospack find得到的路径名称是一样的。

子目录:使用roscd也可以切换到一个软件包或软件包集的子目录中。

执行:

$ roscd roscpp/cmake
$ pwd

应该会看到:

YOUR_INSTALL_PATH/share/roscpp/cmake
roscd log

使用roscd log可以切换到ROS保存日记文件的目录下。需要注意的是,如果你没有执行过任何ROS程序,系统会报错说该目录不存在。

如果你已经运行过ROS程序,那么可以尝试:

$ roscd log

3.3 使用rosls

rosls是rosbash命令集中的一部分,它允许你直接按软件包的名称而不是绝对路径执行ls命令(罗列目录)。

用法:

$ rosls [本地包名称[/子目录]]

示例:

$ rosls roscpp_tutorials

应输出:

cmake package.xml srv

3.4 Tab 自动完成输入

当要输入一个完整的软件包名称时会变得比较繁琐。在之前的例子中roscpp tutorials是个相当长的名称,幸运的是,一些ROS工具支持 TAB 自动完成输入的功能。

输入:

$ roscd roscpp_tut<<< 现在请按TAB键 >>>

当按TAB键后,命令行中应该会自动补充剩余部分:

$ roscd roscpp_tutorials/ 这应该有用,因为roscpp tutorials是当前唯一一个名称以roscpp tut作为开头的ROS软件包。

现在尝试输入:

$ roscd tur<<< 现在请按TAB键 >>>

按TAB键后,命令应该会尽可能地自动补充完整:

$ roscd turtle

但是,在这种情况下有多个软件包是以turtle开头,当再次按TAB键后应该会列出所有以turtle开头的ROS软件包:

turtle_actionlib/   turtlesim/   turtle_tf/

这时在命令行中你应该仍然只看到:

$ roscd turtle

现在在turtle后面输入s然后按TAB键:

$ roscd turtles<<< 请按TAB键 >>>

因为只有一个软件包的名称以turtles开头,所以你应该会看到:

$ roscd turtlesim/

4 回顾

ROS命令工具的的命名方式:

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

这种命名方式在许多ROS命令工具中都会用到。

创建ROS程序包

1 catkin程序包的组成

一个程序包要想称为catkin程序包必须符合以下要求:

  • 该程序包必须包含catkin compliant package.xml文件
  • 这个package.xml文件提供有关程序包的元信息。
  • 程序包必须包含一个catkin 版本的CMakeLists.txt文件,而Catkin metapackages中必须包含一个对CMakeList.txt文件的引用。
  • 每个目录下只能有一个程序包。
  • 在同一个目录下不能有嵌套的或者多个程序包存在。

最简单的程序包:

my_package/
  CMakeLists.txt
  package.xml

2 在catkin工作空间中的程序包

开发catkin程序包的一个推荐方法是使用catkin工作空间,但是你也可以单独开发(standalone)catkin 软件包。

简单的例子:

workspace_folder/        -- WORKSPACE
  src/                   -- SOURCE SPACE
    CMakeLists.txt       -- 'Toplevel' CMake file, provided by catkin
    package_1/
      CMakeLists.txt     -- CMakeLists.txt file for package_1
      package.xml        -- Package manifest for package_1
    ...
    package_n/
      CMakeLists.txt     -- CMakeLists.txt file for package_n
      package.xml        -- Package manifest for package_n

3 创建catkin程序包

如何使用catkin_create_pkg命令来创建一个新的 catkin 程序包以及创建之后都能做些什么?

首先切换到之前通过创建 catkin 工作空间教程创建的 catkin 工作空间中的 src 目录下:

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

使用catkin_create_pkg命令来创建一个名为'beginner_tutorials'的新程序包,这个程序包依赖于std_msgs、roscpp和rospy:

$ catkin_create_pkg beginner_tutorials std_msgs rospy roscpp

这将会创建一个名为beginner_tutorials的文件夹,这个文件夹里面包含一个package.xml文件和一个CMakeLists.txt文件,这两个文件都已经自动包含了部分你在执行catkin_create_pkg命令时提供的信息。

catkin_create_pkg命令会要求你输入package_name,如果有需要你还可以在后面添加一些需要依赖的其它程序包:

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

catkin_create_pkg命令也有更多的高级功能,这些功能catkin/commands/catkin_create_pkg中有描述。

4 程序包依赖关系

4.1 一级依赖

之前在使用catkin_create_pkg 命令时提供了几个程序包作为依赖包,现在我们可以使用rospack命令工具来查看一级依赖包。

(Jan 9, 2013) There is a bug reported and already fixed in rospack in groovy, which takes sometime until the change gets reflected on your computer. If you see a similar issue like this with the next command, you can skip to the next command.

$ rospack depends1 beginner_tutorials 

可以看见

std_msgs
rospy
roscpp

然后就可以看到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>

4.2 间接依赖

在很多情况中,一个依赖包还会有它自己的依赖包,比如,rospy还有其它依赖包。

$ rospack depends1 rospy
genpy
rosgraph
rosgraph_msgs
roslib
std_msgs

一个程序包还可以有好几个间接的依赖包,幸运的是使用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

5 自定义你的程序包

本部分将剖析catkin_create_pkg命令生成的每个文件并详细描述这些文件的组成部分以及如何自定义这些文件。

5.1 自定义 package.xml

自动生成的package.xml文件应该在你的新程序包中。

5.1.1 描述标签

首先更新描述标签: 切换行号显示

 <description>The beginner_tutorials package</description>

将描述信息修改为任何你喜欢的内容,但是按照约定第一句话应该简短一些,因为它覆盖了程序包的范围。如果用一句话难以描述完全那就需要换行了。

5.1.2 维护者标签

接下来是维护者标签:

     <!-- One maintainer tag required, multiple allowed, one person per tag --> 
     <!-- Example:  -->
     <!-- <maintainer email="[email protected]">Jane Doe</maintainer> -->
     <maintainer email="[email protected]">user</maintainer>

这是package.xml中要求填写的一个重要标签,因为它能够让其他人联系到程序包的相关人员。至少需要填写一个维护者名称,但如果有需要的话你可以添加多个。除了在标签里面填写维护者的名称外,还应该在标签的email属性中填写邮箱地址:

    <maintainer email="[email protected]">Your Name</maintainer>
5.1.3 许可标签

再接下来是许可标签,同样的也需要:

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

应该选择一种许可协议并将它填写到这里。一些常见的开源许可协议有BSD、MIT、Boost Software License、GPLv2、GPLv3、LGPLv2.1和LGPLv3。你可以在Open Source Initiative中阅读其中的若干个许可协议的相关信息。对于本教程我们将使用BSD协议,因为ROS核心组件的剩余部分已经使用了该协议:

   <license>BSD</license>
5.1.4 依赖项标签

接下来的标签用来描述程序包的各种依赖项,这些依赖项分为build_depend、buildtool_depend、run_depend、test_depend。关于这些标签的更详细介绍请参考Catkin Dependencies相关的文档。在之前的操作中,因为我们将 std_msgs、 roscpp、 和 rospy作为catkin_create_pkg命令的参数,所以生成的依赖项如下:

     <!-- The *_depend tags are used to specify dependencies -->
     <!-- Dependencies can be catkin packages or system dependencies -->
     <!-- Examples: -->
     <!-- Use build_depend for packages you need at compile time: -->
     <!--   <build_depend>genmsg</build_depend> -->
     <!-- Use buildtool_depend for build tool packages: -->
     <!--   <buildtool_depend>catkin</buildtool_depend> -->
     <!-- Use run_depend for packages you need at runtime: -->
     <!--   <run_depend>python-yaml</run_depend> -->
     <!-- Use test_depend for packages you need only for testing: -->
     <!--   <test_depend>gtest</test_depend> -->
     <buildtool_depend>catkin</buildtool_depend>
     <build_depend>roscpp</build_depend>
     <build_depend>rospy</build_depend>
     <build_depend>std_msgs</build_depend>

除了catkin中默认提供的buildtool_depend,所有我们列出的依赖包都已经被添加到build_depend标签中。在本例中,因为在编译和运行时我们需要用到所有指定的依赖包,因此还需要将每一个依赖包分别添加到run_depend标签中: 此处官网已经更新(<run_depend>修改为<exec_depend>),具体信息查阅官网:

<?xml version="1.0"?>
<package format="2">
  <name>beginner_tutorials</name>
  <version>0.1.0</version>
  <description>The beginner_tutorials package</description>

  <maintainer email="[email protected]">Your Name</maintainer>
  <license>BSD</license>
  <url type="website">http://wiki.ros.org/beginner_tutorials</url>
  <author email="[email protected]">Jane Doe</author>

  <buildtool_depend>catkin</buildtool_depend>

  <build_depend>roscpp</build_depend>
  <build_depend>rospy</build_depend>
  <build_depend>std_msgs</build_depend>

  <exec_depend>roscpp</exec_depend>
  <exec_depend>rospy</exec_depend>
  <exec_depend>std_msgs</exec_depend>

</package>
     <buildtool_depend>catkin</buildtool_depend>

     <build_depend>roscpp</build_depend>
     <build_depend>rospy</build_depend>
     <build_depend>std_msgs</build_depend>

     <run_depend>roscpp</run_depend>
     <run_depend>rospy</run_depend>
     <run_depend>std_msgs</run_depend>
5.1.5 最后完成的 package.xml

现在看下面最后去掉了注释和未使用标签后的package.xml文件就显得更加简洁了:

    <?xml version="1.0"?>
    <package>
      <name>beginner_tutorials</name>
      <version>0.1.0</version>
      <description>The beginner_tutorials package</description>

      <maintainer email="[email protected]">Your Name</maintainer>
      <license>BSD</license>
      <url type="website">http://wiki.ros.org/beginner_tutorials</url>
      <author email="[email protected]">Jane Doe</author>

      <buildtool_depend>catkin</buildtool_depend>

      <build_depend>roscpp</build_depend>
      <build_depend>rospy</build_depend>
      <build_depend>std_msgs</build_depend>

      <run_depend>roscpp</run_depend>
      <run_depend>rospy</run_depend>
      <run_depend>std_msgs</run_depend>

    </package>

5 自定义你的程序包

本部分教程将剖析catkin_create_pkg命令生成的每个文件并详细描述这些文件的组成部分以及如何自定义这些文件。

5.1 自定义 package.xml

自动生成的package.xml文件应该在你的新程序包中。现在让我们一起来看看新生成的package.xml文件以及每一个需要你注意的标签元素。

5.1.1 描述标签

首先更新描述标签: 切换行号显示

 <description>The beginner_tutorials package</description>

将描述信息修改为任何你喜欢的内容,但是按照约定第一句话应该简短一些,因为它覆盖了程序包的范围。如果用一句话难以描述完全那就需要换行了。

5.1.2 维护者标签

接下来是维护者标签:

     <!-- One maintainer tag required, multiple allowed, one person per tag --> 
     <!-- Example:  -->
     <!-- <maintainer email="[email protected]">Jane Doe</maintainer> -->
     <maintainer email="[email protected]">user</maintainer>

这是package.xml中要求填写的一个重要标签,因为它能够让其他人联系到程序包的相关人员。至少需要填写一个维护者名称,但如果有需要的话你可以添加多个。除了在标签里面填写维护者的名称外,还应该在标签的email属性中填写邮箱地址:

    <maintainer email="[email protected]">Your Name</maintainer>

5.1.3 许可标签

再接下来是许可标签,同样的也需要:

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

你应该选择一种许可协议并将它填写到这里。一些常见的开源许可协议有BSD、MIT、Boost Software License、GPLv2、GPLv3、LGPLv2.1和LGPLv3。你可以在Open Source Initiative中阅读其中的若干个许可协议的相关信息。对于本教程我们将使用BSD协议,因为ROS核心组件的剩余部分已经使用了该协议:

   <license>BSD</license>

5.1.4 依赖项标签

接下来的标签用来描述程序包的各种依赖项,这些依赖项分为build_depend、buildtool_depend、run_depend、test_depend。关于这些标签的更详细介绍请参考Catkin Dependencies相关的文档。在之前的操作中,因为我们将 std_msgs、 roscpp、 和 rospy作为catkin_create_pkg命令的参数,所以生成的依赖项看起来如下:

     <!-- The *_depend tags are used to specify dependencies -->
     <!-- Dependencies can be catkin packages or system dependencies -->
     <!-- Examples: -->
     <!-- Use build_depend for packages you need at compile time: -->
     <!--   <build_depend>genmsg</build_depend> -->
     <!-- Use buildtool_depend for build tool packages: -->
     <!--   <buildtool_depend>catkin</buildtool_depend> -->
     <!-- Use run_depend for packages you need at runtime: -->
     <!--   <run_depend>python-yaml</run_depend> -->
     <!-- Use test_depend for packages you need only for testing: -->
     <!--   <test_depend>gtest</test_depend> -->
     <buildtool_depend>catkin</buildtool_depend>
     <build_depend>roscpp</build_depend>
     <build_depend>rospy</build_depend>
     <build_depend>std_msgs</build_depend>

除了catkin中默认提供的buildtool_depend,所有我们列出的依赖包都已经被添加到build_depend标签中。在本例中,因为在编译和运行时我们需要用到所有指定的依赖包,因此还需要将每一个依赖包分别添加到run_depend标签中: 此处官网已经更新(<run_depend>修改为<exec_depend>),具体信息查阅官网:

<?xml version="1.0"?>
<package format="2">
  <name>beginner_tutorials</name>
  <version>0.1.0</version>
  <description>The beginner_tutorials package</description>

  <maintainer email="[email protected]">Your Name</maintainer>
  <license>BSD</license>
  <url type="website">http://wiki.ros.org/beginner_tutorials</url>
  <author email="[email protected]">Jane Doe</author>

  <buildtool_depend>catkin</buildtool_depend>

  <build_depend>roscpp</build_depend>
  <build_depend>rospy</build_depend>
  <build_depend>std_msgs</build_depend>

  <exec_depend>roscpp</exec_depend>
  <exec_depend>rospy</exec_depend>
  <exec_depend>std_msgs</exec_depend>

</package>
     <buildtool_depend>catkin</buildtool_depend>

     <build_depend>roscpp</build_depend>
     <build_depend>rospy</build_depend>
     <build_depend>std_msgs</build_depend>

     <run_depend>roscpp</run_depend>
     <run_depend>rospy</run_depend>
     <run_depend>std_msgs</run_depend>

5.1.5 最后完成的 package.xml

现在看下面最后去掉了注释和未使用标签后的package.xml文件就显得更加简洁了:

    <?xml version="1.0"?>
    <package>
      <name>beginner_tutorials</name>
      <version>0.1.0</version>
      <description>The beginner_tutorials package</description>

      <maintainer email="[email protected]">Your Name</maintainer>
      <license>BSD</license>
      <url type="website">http://wiki.ros.org/beginner_tutorials</url>
      <author email="[email protected]">Jane Doe</author>

      <buildtool_depend>catkin</buildtool_depend>

      <build_depend>roscpp</build_depend>
      <build_depend>rospy</build_depend>
      <build_depend>std_msgs</build_depend>

      <run_depend>roscpp</run_depend>
      <run_depend>rospy</run_depend>
      <run_depend>std_msgs</run_depend>

    </package>

编译ROS程序包

1 编译程序包

安装完所需的系统依赖项,就可以开始编译创建的程序包。

事先source你的环境配置(setup)文件,在Ubuntu中的操作指令如下:

$ source /opt/ros/indigo/setup.zsh
1.1 使用catkin_make

catkin_make 是一个命令行工具,它简化了 catkin 的标准工作流程。你可以认为 catkin_make 是在 CMake 标准工作流程中依次调用了cmake 和 make。

使用方法:

# 在catkin工作空间下
$ catkin_make [make_targets] [-DCMAKE_VARIABLES=...]

CMake标准工作流程主要可以分为以下几个步骤:

注意: 如果你运行以下命令是无效的,因为它只是一个演示CMake工作流程的例子。

# 在一个CMake项目里
$ mkdir build
$ cd build
$ cmake ..
$ make
$ make install  # (可选)

每个CMake工程在编译时都会执行这个操作过程。相反,多个catkin项目可以放在工作空间中一起编译,工作流程如下:

# In a catkin workspace
$ catkin_make
$ catkin_make install  # (可选)

上述命令会编译src文件夹下的所有catkin工程。如果你的源代码不在默认工作空间中(~/catkin_ws/src),比如说存放在了my_src中,那么你可以这样来使用catkin_make:

注意: 运行以下命令时无效的,因为my_src不存在。

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

对于catkin_make更高级的使用方法,请参考:catkin/commands/catkin_make

1.2 开始编译程序包

对于正要马上编译自己代码的读者,请同时看一下后面的(C++)/(Python)教程,因为你可能需要修改CMakeLists.txt文件。

按照之前的创建一个ROS程序包教程,你应该已经创建好了一个catkin 工作空间 和一个名为beginner_tutorials的catkin 程序包。现在切换到catkin workspace 并查看src文件夹:

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

你可以看到一个名为beginner_tutorials的文件夹,这就是你在之前的 catkin_create_pkg教程里创建的。现在我们可以使用catkin_make来编译它了:

$ catkin_make

你可以看到很多cmake 和 make 输出的信息:

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/groovy
-- This workspace overlays: /opt/ros/groovy
-- 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"
####

catkin_make首先输出它所使用到的每个空间所在的路径。更多关于空间的信息,请参考REP128和catkin/workspaces。需要注意的是由于这些空间存在默认配置的原因,有几个文件夹已经在catkin工作空间自动生成了,使用ls查看:

$ ls
build
devel
src

build 目录是build space的默认所在位置,同时cmake 和 make也是在这里被调用来配置并编译你的程序包。devel 目录是devel space的默认所在位置, 同时也是在你安装程序包之前存放可执行文件和库文件的地方。

2 补充学习

img

img

img

img

1561648213235

理解ROS节点

本部分介绍 ROS 图(graph)概念 并讨论roscore、rosnode和 rosrun 命令行工具的使用。

1 先决条件

安装会使用到的轻量级模拟器,使用一下命令安装:

$ sudo apt-get install ros-indigo-ros-tutorials

2 图的概念概述

  • Nodes:节点,一个节点即为一个可执行文件,它可以通过ROS与其它节点进行通信。
  • Messages:消息,消息是一种ROS数据类型,用于订阅或发布到一个话题。
  • Topics:话题,节点可以发布消息到话题,也可以订阅话题以接收消息。
  • Master:节点管理器,ROS名称服务 (比如帮助节点找到彼此)。
  • rosout: ROS中相当于stdout/stderr。
  • roscore: 主机+ rosout + 参数服务器 (参数服务器会在后面介绍)。

3 节点

一个节点其实只不过是ROS程序包中的一个可执行文件。ROS节点可以使用ROS客户库与其他节点通信。节点可以发布或接收一个话题。节点也可以提供或使用某种服务。

4 客户端库

ROS客户端库允许使用不同编程语言编写的节点之间互相通信:

  • rospy = python 客户端库
  • roscpp = c++ 客户端库

5 roscore

roscore 是你在运行所有ROS程序前首先要运行的命令。

$ roscore

然后你会看到类似下面的输出信息:

... 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]

如果 roscore 运行后无法正常初始化,很有可能是存在网络配置问题。参见网络设置——单机设置 http://wiki.ros.org/ROS/NetworkSetup

如果 roscore 不能初始化并提示缺少权限,这可能是因为~/.ros文件夹归属于root用户(只有root用户才能访问),修改该文件夹的用户归属关系:

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

6 使用rosnode

rosnode 显示当前运行的ROS节点信息。rosnode list 指令列出活跃的节点:

$ rosnode list

你会看到:

/rosout

这表示当前只有一个节点在运行: rosout 。因为这个节点用于收集和记录节点调试输出信息,所以它总是在运行的。

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

$ rosnode info /rosout

这给了我们更多的一些有关于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

现在,让我们看看更多的节点。为此,我们将使用rosrun 弹出另一个节点。

7 使用rosrun

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

用法:

$ rosrun [package_name] [node_name]

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

然后, 在一个新的终端:

$ rosrun turtlesim turtlesim_node

会看到 一个turtlesim 窗口。

在一个新的终端:

$ rosnode list

你会看见类似于:

/rosout
/turtlesim

ROS的一个强大特性就是你可以通过命令行重新配置名称。

关闭 turtlesim 窗口停止运行节点 (或者回到rosrun turtlesim终端并使用ctrl-C)。现在让我们重新运行它,但是这一次使用Remapping Argument改变节点名称:

$ rosrun turtlesim turtlesim_node __name:=my_turtle

现在,我们退回使用 rosnode list:

$ rosnode list

你会看见如下:

/rosout
/my_turtle

我们可以看到新的/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

1561648704136

8 回顾

本节所涉及的内容:

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

理解ros话题

本部分介绍ROS话题(topics)以及如何使用rostopic 和 rqt_plot 命令行工具。

1 开始

1.1 roscore

首先确保roscore已经运行, 打开一个新的终端:

$ roscore

只需要有一个roscore在运行就够了,否则可能会出现下面的错误信息:

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

1.2 turtlesim

在一个新的终端运行:

$ rosrun turtlesim turtlesim_node

1.3 通过键盘远程控制turtle

通过键盘来控制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.

现在你可以使用键盘上的方向键来控制turtle运动了。如果不能控制,请选中turtle_teleop_key所在的终端窗口以确保你的按键输入能够被捕获。

1561649060675

这样就可以控制turtle运动了。

2 ros Topics

turtlesim_node 节点和 turtle_teleop_key 节点之间是通过一个 ROS 话题来互相通信的。turtle_teleop_key 在一个话题上发布按键输入消息,而 turtlesim 则订阅该话题以接收该消息。下面让我们使用 rqt_graph 来显示当前运行的节点和话题。

注意:如果你使用的是 electric 或更早期的版本,那么 rqt 是不可用的,请使用 rxgraph 代替。

2.1 使用 rqt_graph

rqt_graph能够创建一个显示当前系统运行情况的动态图形。rqt_graph是rqt程序包中的一部分。如果你没有安装,请通过以下命令来安装:

$ sudo apt-get install ros-indigo-rqt
$ sudo apt-get install ros-indigo-rqt-common-plugins

在一个新终端中运行:

$ rosrun rqt_graph rqt_graph

你会看到类似下图所示的图形:

1561649131518

如果你将鼠标放在/turtle1/command_velocity上方,相应的ROS节点(蓝色和绿色)和话题(红色)就会高亮显示。正如你所看到的,turtlesim_node和turtle_teleop_key节点正通过一个名为/turtle1/command_velocity的话题来互相通信。

1561649165877

2.2 rostopic介绍

rostopic命令工具能获取有关ROS话题的信息。

可以使用帮助选项查看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

2.3 使用rostopic echo

rostopic echo可以显示在某个话题上发布的数据。

用法:

$ rostopic echo [topic]

让我们在一个新终端中看一下turtle_teleop_key节点在/turtle1/command_velocity话题(非hydro版)上发布的数据。

$ rostopic echo /turtle1/cmd_vel

你可能看不到任何东西因为现在还没有数据发布到该话题上。接下来我们通过按下方向键使 turtle_teleop_key 节点发布数据。记住如果 turtle 没有动起来的话就需要你重新选中 turtle_teleop_key 节点运行时所在的终端窗口。

现在当你按下向上方向键时应该会看到下面的信息:

1561649277753

现在让我们再看一下rqt_graph(你可能需要刷新一下ROS graph)。正如你所看到的,rostopic echo(红色显示部分)现在也订阅了turtle1/cmd_vel话题。

1561649295024

2.4 使用rostopic list

rostopic list能够列出所有当前订阅和发布的话题。

查看一下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

在rostopic list中使用verbose选项:

$ rostopic list -v

这会显示出有关所发布和订阅的话题及其类型的详细信息。

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 Messages

话题之间的通信是通过在节点之间发送ROS消息实现的。对于发布器(turtle_teleop_key)和订阅器(turtulesim_node)之间的通信,发布器和订阅器之间必须发送和接收相同类型的消息。这意味着话题的类型是由发布在它上面的消息类型决定的。使用rostopic type命令可以查看发布在某个话题上的消息类型。

3.1 使用 rostopic type

rostopic type 命令用来查看所发布话题的消息类型。

用法:

$ rostopic type [topic]
$ rostopic type /turtle1/cmd_vel

会看到:

geometry_msgs/Twist
$ 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

现在已经知道了turtlesim节点所期望的消息类型,接下来就可以给turtle发布命令了。

4 继续学习 rostopic

现在我们已经了解了什么是ROS的消息,接下来我们开始结合消息来使用rostopic。

4.1 使用 rostopic pub

rostopic pub可以把数据发布到当前某个正在广播的话题上。

用法:

$ rostopic pub [topic] [msg_type] [args]

示例:

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

以上命令会发送一条消息给turtlesim,告诉它以2.0大小的线速度和1.8大小的角速度开始移动。

1561649513293

这是一个非常复杂的例子,因此让我们来详细分析一下其中的每一个参数。

  • rostopic pub 这条命令将会发布消息到某个给定的话题。
  • -1 (单个破折号)这个参数选项使rostopic发布一条消息后马上退出。
  • /turtle1/cmd_vel 这是消息所发布到的话题名称。
  • geometry_msgs/Twist 这是所发布消息的类型。
  • -- (双破折号)这会告诉命令选项解析器接下来的参数部分都不是命令选项。这在参数里面包含有破折号-(比如负号)时是必须要添加的。
  • '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]' 正如之前提到的,在一个turtlesim/Velocity消息里面包含有两个浮点型元素:linear和angular。在本例中,2.0是linear的值,1.8是angular的值。这些参数其实是按照YAML语法格式编写的,这在YAML文档中有更多的描述。

你可能已经注意到turtle已经停止移动了。这是因为turtle需要一个稳定的频率为1Hz的命令流来保持移动状态。

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

这条命令以1Hz的频率发布速度命令到速度话题上。

1561649541309

我们也可以看一下rqt_graph中的情形,可以看到rostopic发布器节点(红色)正在与rostopic echo节点(绿色)进行通信:

1561649561836

正如你所看到的,turtle正沿着一个圆形轨迹连续运动。我们可以在一个新终端中通过rostopic echo命令来查看turtlesim所发布的数据。

1561649580650

4.2 使用 rostopic hz

rostopic hz命令可以用来查看数据发布的频率。

用法:

$ rostopic hz [topic]

我们看一下turtlesim_node发布/turtle/pose时有多快:

$ rostopic hz /turtle1/pose

你会看到:

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
$ rostopic type /turtle1/cmd_vel | rosmsg show

到此已经完成了通过rostopic来查看话题相关情况的过程,接下来可以使用另一个工具来查看turtlesim发布的数据。

5 使用rqt_plot

rqt_plot命令可以实时显示一个发布到某个话题上的数据变化图形。这里我们将使用rqt_plot命令来绘制正在发布到/turtle1/pose话题上的数据变化图形。首先,在一个新终端中运行rqt_plot命令:

$ rosrun rqt_plot rqt_plot

这会弹出一个新窗口,在窗口左上角的一个文本框里面你可以添加需要绘制的话题。在里面输入/turtle1/pose/x后之前处于禁用状态的加号按钮将会被使能变亮。按一下该按钮,并对/turtle1/pose/y重复相同的过程。现在你会在图形中看到turtle的x-y位置坐标图。

1561649647340按下减号按钮会显示一组菜单隐藏图形中指定的话题。现在隐藏掉刚才添加的话题并添加/turtle1/pose/theta,可以看到如下图所示的图形:

1561649719195

1561649749028

本部分内容到此为止,请使用Ctrl-C退出rostopic命令,但要保持turtlesim继续运行。

⚠️ **GitHub.com Fallback** ⚠️