@toc
1 ROS的安装
2 ROS的文件系统命令rosls、roscd、rospack find的快速使用
首先说明(本节参考),rosls、roscd、rospack find
命令和我们平时使用的ls、cd、find
功能几乎是一样的,唯一的区别就是能够快速定位到ros系统文件的位置,下面来快速学习一下吧!
2.1 rosls:快速列举ros文件目录下的文件
1、rosls <要查看的目录名>
(base) shl@zhihui-mint:~$ rosls roscpp_tutorials/
cmake launch package.xml srv
(base) shl@zhihui-mint:~$
注意:
目录名如果记不太清楚,可以通过按tab键进行补全
2.2 roscd:快速切换到ros文件系统的指定目录
roscd有两种用法:
1、roscd不加参数:不带参数时roscd直接进入环境变量 $ROS_ROOT定义的目录
.
(base) shl@zhihui-mint:~$ roscd
(base) shl@zhihui-mint:/opt/ros/melodic$
2、roscd <目录名>
:切换到指定的目录下
(base) shl@zhihui-mint:/opt/ros/melodic$ roscd roscpp_tutorials/
(base) shl@zhihui-mint:/opt/ros/melodic/share/roscpp_tutorials$
注意:
目录名如果记不太清楚,可以通过按tab键进行补全
2.3 rospack find <文件名/目录名>查找指定文件或目录的路径
(base) shl@zhihui-mint:~$ rospack find roscpp_tutorials
/opt/ros/melodic/share/roscpp_tutorials
(base) shl@zhihui-mint:~$
rospack find
命令和rosstack find
命令的使用是差不多的,也是快速查找ros文件系统中的文件或目录的路径:
(base) shl@zhihui-mint:~$ rosstack find roscpp_tutorials
/opt/ros/melodic/share/roscpp_tutorials
(base) shl@zhihui-mint:~$
注意:
目录名如果记不太清楚,可以通过按tab键进行补全
3 创建ROS程序包
本教程介绍如何使用roscreate-pkg
或catkin
创建一个新程序包
,并使用rospack
查看程序包的依赖关系
。
3.1 一个catkin程序包有哪些文件组成?
一个程序包要想称为catkin程序包必须符合以下要求:
1)该程序包必须包含catkin compliant package.xml文件,这个
package.xml文件
提供有关程序包的元信息
。2)程序包必须包含一个
catkin 版本
的CMakeLists.txt文件
,而Catkin metapackages中必须包含一个对CMakeList.txt文件的引用。3)每个目录下
只能有一个程序包
。这意味着在同一个目录下不能
有嵌套的或者多个程序包存在。
my_package/
├── CMakeLists.txt
└── package.xml
3.2 在catkin工作空间中的程序包
开发catkin程序包
的一个推荐方法是使用catkin工作空间
,一个简单的工作空间也许看起来像这样:
(base) shl@zhihui-mint:~$ tree catkin_ws/
catkin_ws/ # 工作空间
└── src # 源码目录
├── package_1
│ ├── CMakeLists.txt
│ └── package.xml
├── package_2
│ ├── CMakeLists.txt
│ └── package.xml
└── package_n
├── CMakeLists.txt
└── package.xml
4 directories, 6 files
(base) shl@zhihui-mint:~$
3.3 创建一个catkin程序包
本部分教程将演示如何使用catkin_create_pkg命令
来创建一个新的catkin程序包
以及创建之后都能做些什么。
1、首先把路径切换到源码目录下
cd ~/catkin_ws/src
2、现在使用catkin_create_pkg命令
来创建一个名为beginner_tutorials
的新程序包
,这个程序包依赖于std_msgs
、roscpp
和rospy
这三个package:
catkin_create_pkg beginner_tutorials std_msgs rospy roscpp
其中:
- rospy:rospy是Python的客户端库
- roscpp:roscpp是C++的客户端库
执行上面的命令:
- 会创建一个名为beginner_tutorials的文件夹
- 这个文件夹里面包含一个package.xml文件和一个CMakeLists.txt文件
- 这两个文件都已经自动包含了部分你在执行catkin_create_pkg命令时提供的信息。
- 如果你还需要其他的
程序包依赖
,可以在后面继续添加
创建新的程序包后,生成的文件目录结果如下:
(base) shl@zhihui-mint:~$ tree catkin_ws/
catkin_ws/
└── src
1 directory, 0 files
(base) shl@zhihui-mint:~$ cd ~/catkin_ws/src/
(base) shl@zhihui-mint:~/catkin_ws/src$ catkin_create_pkg beginner_tutorials std_msgs rospy roscpp
Created file beginner_tutorials/package.xml
Created file beginner_tutorials/CMakeLists.txt
Created folder beginner_tutorials/include/beginner_tutorials
Created folder beginner_tutorials/src
Successfully created files in /home/shl/catkin_ws/src/beginner_tutorials. Please adjust the values in package.xml.
(base) shl@zhihui-mint:~/catkin_ws/src$ tree ~/catkin_ws/
/home/shl/catkin_ws/
└── src
└── beginner_tutorials
├── CMakeLists.txt
├── include
│ └── beginner_tutorials
├── package.xml
└── src
5 directories, 2 files
(base) shl@zhihui-mint:~/catkin_ws/src$
可以看到生成了程序包beginner_tutorials
,下面我们来看一下CMakeLists.txt
和package.xml
文件中有哪些内容:
- 1)
CMakeLists.txt
文件中的内容:
(base) shl@zhihui-mint:~/catkin_ws/src$ cat beginner_tutorials/CMakeLists.txt
cmake_minimum_required(VERSION 3.0.2)
project(beginner_tutorials)
## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)
## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
)
## System dependencies are found with CMake's conventions
# find_package(Boost REQUIRED COMPONENTS system)
## Uncomment this if the package has a setup.py. This macro ensures
## modules and global scripts declared therein get installed
## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
# catkin_python_setup()
################################################
## Declare ROS messages, services and actions ##
################################################
## To declare and build messages, services or actions from within this
## package, follow these steps:
## * Let MSG_DEP_SET be the set of packages whose message types you use in
## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
## * In the file package.xml:
## * add a build_depend tag for "message_generation"
## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
## but can be declared for certainty nonetheless:
## * add a exec_depend tag for "message_runtime"
## * In this file (CMakeLists.txt):
## * add "message_generation" and every package in MSG_DEP_SET to
## find_package(catkin REQUIRED COMPONENTS ...)
## * add "message_runtime" and every package in MSG_DEP_SET to
## catkin_package(CATKIN_DEPENDS ...)
## * uncomment the add_*_files sections below as needed
## and list every .msg/.srv/.action file to be processed
## * uncomment the generate_messages entry below
## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
## Generate messages in the 'msg' folder
# add_message_files(
# FILES
# Message1.msg
# Message2.msg
# )
## Generate services in the 'srv' folder
# add_service_files(
# FILES
# Service1.srv
# Service2.srv
# )
## Generate actions in the 'action' folder
# add_action_files(
# FILES
# Action1.action
# Action2.action
# )
## Generate added messages and services with any dependencies listed here
# generate_messages(
# DEPENDENCIES
# std_msgs
# )
################################################
## Declare ROS dynamic reconfigure parameters ##
################################################
## To declare and build dynamic reconfigure parameters within this
## package, follow these steps:
## * In the file package.xml:
## * add a build_depend and a exec_depend tag for "dynamic_reconfigure"
## * In this file (CMakeLists.txt):
## * add "dynamic_reconfigure" to
## find_package(catkin REQUIRED COMPONENTS ...)
## * uncomment the "generate_dynamic_reconfigure_options" section below
## and list every .cfg file to be processed
## Generate dynamic reconfigure parameters in the 'cfg' folder
# generate_dynamic_reconfigure_options(
# cfg/DynReconf1.cfg
# cfg/DynReconf2.cfg
# )
###################################
## catkin specific configuration ##
###################################
## The catkin_package macro generates cmake config files for your package
## Declare things to be passed to dependent projects
## INCLUDE_DIRS: uncomment this if your package contains header files
## LIBRARIES: libraries you create in this project that dependent projects also need
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent projects also need
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES beginner_tutorials
# CATKIN_DEPENDS roscpp rospy std_msgs
# DEPENDS system_lib
)
###########
## Build ##
###########
## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
# include
${
catkin_INCLUDE_DIRS}
)
## Declare a C++ library
# add_library(${PROJECT_NAME}
# src/${PROJECT_NAME}/beginner_tutorials.cpp
# )
## Add cmake target dependencies of the library
## as an example, code may need to be generated before libraries
## either from message generation or dynamic reconfigure
# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
# add_executable(${PROJECT_NAME}_node src/beginner_tutorials_node.cpp)
## Rename C++ executable without prefix
## The above recommended prefix causes long target names, the following renames the
## target back to the shorter version for ease of user use
## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
## Add cmake target dependencies of the executable
## same as for the library above
# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
## Specify libraries to link a library or executable target against
# target_link_libraries(${PROJECT_NAME}_node
# ${catkin_LIBRARIES}
# )
#############
## Install ##
#############
# all install targets should use catkin DESTINATION variables
# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
## Mark executable scripts (Python etc.) for installation
## in contrast to setup.py, you can choose the destination
# catkin_install_python(PROGRAMS
# scripts/my_python_script
# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )
## Mark executables for installation
## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html
# install(TARGETS ${PROJECT_NAME}_node
# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )
## Mark libraries for installation
## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html
# install(TARGETS ${PROJECT_NAME}
# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
# RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
# )
## Mark cpp header files for installation
# install(DIRECTORY include/${PROJECT_NAME}/
# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
# FILES_MATCHING PATTERN "*.h"
# PATTERN ".svn" EXCLUDE
# )
## Mark other files for installation (e.g. launch and bag files, etc.)
# install(FILES
# # myfile1
# # myfile2
# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
# )
#############
## Testing ##
#############
## Add gtest based cpp test target and link libraries
# catkin_add_gtest(${PROJECT_NAME}-test test/test_beginner_tutorials.cpp)
# if(TARGET ${PROJECT_NAME}-test)
# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
# endif()
## Add folders to be run by python nosetests
# catkin_add_nosetests(test)
(base) shl@zhihui-mint:~/catkin_ws/src$
- 2)
package.xml
文件中的内容:
(base) shl@zhihui-mint:~/catkin_ws/src$ cat beginner_tutorials/package.xml
<?xml version="1.0"?>
<package format="2">
<name>beginner_tutorials</name>
<version>0.0.0</version>
<description>The beginner_tutorials package</description>
<!-- One maintainer tag required, multiple allowed, one person per tag -->
<!-- Example: -->
<!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
<maintainer email="shl@todo.todo">shl</maintainer>
<!-- 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>
<!-- Url tags are optional, but multiple are allowed, one per tag -->
<!-- Optional attribute type can be: website, bugtracker, or repository -->
<!-- Example: -->
<!-- <url type="website">http://wiki.ros.org/beginner_tutorials</url> -->
<!-- Author tags are optional, multiple are allowed, one per tag -->
<!-- Authors do not have to be maintainers, but could be -->
<!-- Example: -->
<!-- <author email="jane.doe@example.com">Jane Doe</author> -->
<!-- The *depend tags are used to specify dependencies -->
<!-- Dependencies can be catkin packages or system dependencies -->
<!-- Examples: -->
<!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
<!-- <depend>roscpp</depend> -->
<!-- Note that this is equivalent to the following: -->
<!-- <build_depend>roscpp</build_depend> -->
<!-- <exec_depend>roscpp</exec_depend> -->
<!-- Use build_depend for packages you need at compile time: -->
<!-- <build_depend>message_generation</build_depend> -->
<!-- Use build_export_depend for packages you need in order to build against this package: -->
<!-- <build_export_depend>message_generation</build_export_depend> -->
<!-- Use buildtool_depend for build tool packages: -->
<!-- <buildtool_depend>catkin</buildtool_depend> -->
<!-- Use exec_depend for packages you need at runtime: -->
<!-- <exec_depend>message_runtime</exec_depend> -->
<!-- Use test_depend for packages you need only for testing: -->
<!-- <test_depend>gtest</test_depend> -->
<!-- Use doc_depend for packages you need only for building documentation: -->
<!-- <doc_depend>doxygen</doc_depend> -->
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>std_msgs</build_depend>
<build_export_depend>roscpp</build_export_depend>
<build_export_depend>rospy</build_export_depend>
<build_export_depend>std_msgs</build_export_depend>
<exec_depend>roscpp</exec_depend>
<exec_depend>rospy</exec_depend>
<exec_depend>std_msgs</exec_depend>
<!-- The export tag contains other, unspecified, tags -->
<export>
<!-- Other tools can request additional information be placed here -->
</export>
</package>
(base) shl@zhihui-mint:~/catkin_ws/src$
3.4 查看程序包的直接依赖关系(一级依赖)
1、上面我们已经创建了一个新的程序包beginner_tutorials
,然后我们开始编译这个程序包
先把目录切换到程序的工作目录
下,然后使用catkin_make
进行程序的编译:
(base) shl@zhihui-mint:~/catkin_ws$ source /opt/ros/melodic/setup.bash
(base) shl@zhihui-mint:~/catkin_ws$ catkin_make
Base path: /home/shl/catkin_ws
Source space: /home/shl/catkin_ws/src
Build space: /home/shl/catkin_ws/build
Devel space: /home/shl/catkin_ws/devel
Install space: /home/shl/catkin_ws/install
Creating symlink "/home/shl/catkin_ws/src/CMakeLists.txt" pointing to "/opt/ros/melodic/share/catkin/cmake/toplevel.cmake"
####
#### Running command: "cmake /home/shl/catkin_ws/src -DCATKIN_DEVEL_PREFIX=/home/shl/catkin_ws/devel -DCMAKE_INSTALL_PREFIX=/home/shl/catkin_ws/install -G Unix Makefiles" in "/home/shl/catkin_ws/build"
####
-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - 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
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Using CATKIN_DEVEL_PREFIX: /home/shl/catkin_ws/devel
-- Using CMAKE_PREFIX_PATH: /opt/ros/melodic
-- This workspace overlays: /opt/ros/melodic
-- Found PythonInterp: /usr/bin/python2 (found suitable version "2.7.17", minimum required is "2")
-- Using PYTHON_EXECUTABLE: /usr/bin/python2
-- Using Debian Python package layout
-- Using empy: /usr/bin/empy
-- Using CATKIN_ENABLE_TESTING: ON
-- Call enable_testing()
-- Using CATKIN_TEST_RESULTS_DIR: /home/shl/catkin_ws/build/test_results
-- Found gtest sources under '/usr/src/googletest': gtests will be built
-- Found gmock sources under '/usr/src/googletest': gmock will be built
-- Found PythonInterp: /usr/bin/python2 (found version "2.7.17")
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE
-- Using Python nosetests: /usr/bin/nosetests-2.7
-- catkin 0.7.29
-- BUILD_SHARED_LIBS is on
-- BUILD_SHARED_LIBS is on
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~ traversing 1 packages in topological order:
-- ~~ - beginner_tutorials
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- +++ processing catkin package: 'beginner_tutorials'
-- ==> add_subdirectory(beginner_tutorials)
-- Configuring done
-- Generating done
-- Build files have been written to: /home/shl/catkin_ws/build
####
#### Running command: "make -j12 -l12" in "/home/shl/catkin_ws/build"
####
(base) shl@zhihui-mint:~/catkin_ws$ ls
2、编译好之后,可以在工作目录下看到生成两个新的目录:
- build目录
- devel目录
(base) shl@zhihui-mint:~/catkin_ws$
build devel src
(base) shl@zhihui-mint:~/catkin_ws$
3、把编译后的环境添加到系统中
source devel/setup.bash
(base) shl@zhihui-mint:~/catkin_ws$ source devel/setup.bash
注意:
如果要切换到新的终端下,还要再次source添加一次!!!
4、 使用rospack查看创建的程序包中有哪些依赖
之前在使用catkin_create_pkg命令
时提供了几个程序包作为依赖包
,下面是查看程序包中的一级依赖
rospack depends1 beginner_tutorials
(base) shl@zhihui-mint:~/catkin_ws$ rospack
cflags-only-I depends1 depends-msgsrv depends-why help libs-only-L list-duplicates profile vcs
cflags-only-other depends-indent depends-on export langs libs-only-other list-names rosdep vcs0
depends depends-manifests depends-on1 find libs-only-l list plugins rosdep0
(base) shl@zhihui-mint:~/catkin_ws$ rospack depends1 beginner_tutorials
roscpp
rospy
std_msgs
(base) shl@zhihui-mint:~/catkin_ws$
从上面可以知道创建的程序包依赖的一级依赖
有:
- roscpp
- rospy
- std_msgs
这些依赖都被保存到了: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>
注意:
可以先输入
rospack
,然后tab补全查看rospack有哪些参数,也可以使用:rospack -h
查看
3.5 查看程序包的间接依赖关系
我们知道一级依赖
有rospy,然后通过rospack depends1 rospy
就可以查看rospy依赖的包有哪些,就相当与是间接依赖:
(base) shl@zhihui-mint:~/catkin_ws$ rospack depends1 rospy
genpy
roscpp
rosgraph
rosgraph_msgs
roslib
std_msgs
(base) shl@zhihui-mint:~/catkin_ws$
3.6 查看所有的依赖
一个程序包可能有多个间接的依赖,rospack可以递归的检测出所有的依赖
:
rospack depends 程序包名
(base) shl@zhihui-mint:~/catkin_ws$ rospack depends beginner_tutorials
cpp_common
rostime
roscpp_traits
roscpp_serialization
catkin
genmsg
genpy
message_runtime
gencpp
geneus
gennodejs
genlisp
message_generation
rosbuild
rosconsole
std_msgs
rosgraph_msgs
xmlrpcpp
roscpp
rosgraph
ros_environment
rospack
roslib
rospy
(base) shl@zhihui-mint:~/catkin_ws$
3.7 自定义自己的程序包
本部分教程将剖析catkin_create_pkg
命令生成的每个文件并详细描述这些文件的组成部分
以及如何自定义这些文件
。这里自定义主要是包括:
自定义 CMakeLists.txt
自定义 package.xml
3.8 自定义:package.xml
在自定义之前,我们再来看一下:package.xml
文件中的内容以及每一个需要你注意的标签元素
:
(base) shl@zhihui-mint:~/catkin_ws$ cat src/beginner_tutorials/package.xml
<?xml version="1.0"?>
<package format="2">
<name>beginner_tutorials</name>
<version>0.0.0</version>
<description>The beginner_tutorials package</description>
<!-- One maintainer tag required, multiple allowed, one person per tag -->
<!-- Example: -->
<!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
<maintainer email="shl@todo.todo">shl</maintainer>
<!-- 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>
<!-- Url tags are optional, but multiple are allowed, one per tag -->
<!-- Optional attribute type can be: website, bugtracker, or repository -->
<!-- Example: -->
<!-- <url type="website">http://wiki.ros.org/beginner_tutorials</url> -->
<!-- Author tags are optional, multiple are allowed, one per tag -->
<!-- Authors do not have to be maintainers, but could be -->
<!-- Example: -->
<!-- <author email="jane.doe@example.com">Jane Doe</author> -->
<!-- The *depend tags are used to specify dependencies -->
<!-- Dependencies can be catkin packages or system dependencies -->
<!-- Examples: -->
<!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
<!-- <depend>roscpp</depend> -->
<!-- Note that this is equivalent to the following: -->
<!-- <build_depend>roscpp</build_depend> -->
<!-- <exec_depend>roscpp</exec_depend> -->
<!-- Use build_depend for packages you need at compile time: -->
<!-- <build_depend>message_generation</build_depend> -->
<!-- Use build_export_depend for packages you need in order to build against this package: -->
<!-- <build_export_depend>message_generation</build_export_depend> -->
<!-- Use buildtool_depend for build tool packages: -->
<!-- <buildtool_depend>catkin</buildtool_depend> -->
<!-- Use exec_depend for packages you need at runtime: -->
<!-- <exec_depend>message_runtime</exec_depend> -->
<!-- Use test_depend for packages you need only for testing: -->
<!-- <test_depend>gtest</test_depend> -->
<!-- Use doc_depend for packages you need only for building documentation: -->
<!-- <doc_depend>doxygen</doc_depend> -->
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>std_msgs</build_depend>
<build_export_depend>roscpp</build_export_depend>
<build_export_depend>rospy</build_export_depend>
<build_export_depend>std_msgs</build_export_depend>
<exec_depend>roscpp</exec_depend>
<exec_depend>rospy</exec_depend>
<exec_depend>std_msgs</exec_depend>
<!-- The export tag contains other, unspecified, tags -->
<export>
<!-- Other tools can request additional information be placed here -->
</export>
</package>
(base) shl@zhihui-mint:~/catkin_ws$
3.8.1 修改描述标签
用一句话简单介绍一下package.xml文件,如果一行不够,可以换行
!
<description>The beginner_tutorials package</description>
3.8.2 修改维护者标签
在package.xml中定义维护者标签,方便维护和联系到程序包的相关人员:
<!-- One maintainer tag required, multiple allowed, one person per tag -->
<!-- Example: -->
<!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
<maintainer email="shl@todo.todo">shl</maintainer>
3.8.3 修改许可标签
选择许可协议:
你应该选择一种许可协议并将它填写到这里。一些常见的开源许可协议有BSD、MIT、Boost Software License、GPLv2、GPLv3、LGPLv2.1和LGPLv3。
<!-- 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
<license>BSD</license>
3.8.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 depend as a shortcut for packages that are both build and exec dependencies -->
<!-- <depend>roscpp</depend> -->
<!-- Note that this is equivalent to the following: -->
<!-- <build_depend>roscpp</build_depend> -->
<!-- <exec_depend>roscpp</exec_depend> -->
<!-- Use build_depend for packages you need at compile time: -->
<!-- <build_depend>message_generation</build_depend> -->
<!-- Use build_export_depend for packages you need in order to build against this package: -->
<!-- <build_export_depend>message_generation</build_export_depend> -->
<!-- Use buildtool_depend for build tool packages: -->
<!-- <buildtool_depend>catkin</buildtool_depend> -->
<!-- Use exec_depend for packages you need at runtime: -->
<!-- <exec_depend>message_runtime</exec_depend> -->
<!-- Use test_depend for packages you need only for testing: -->
<!-- <test_depend>gtest</test_depend> -->
<!-- Use doc_depend for packages you need only for building documentation: -->
<!-- <doc_depend>doxygen</doc_depend> -->
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>std_msgs</build_depend>
<build_export_depend>roscpp</build_export_depend>
<build_export_depend>rospy</build_export_depend>
<build_export_depend>std_msgs</build_export_depend>
1、buildtool_depend
标签,指定编译的工具为:catkin_make
2、build_depend
标签,这些标签中添加的是程序的一级依赖包
3、run_depend标签
,在编译
和运行
时我们需要用到所有指定的依赖包
,因此还需要将每一个依赖包分别添加到run_depend标签
中
<run_depend>roscpp</run_depend>
<run_depend>rospy</run_depend>
<run_depend>std_msgs</run_depend>
从上面的标签元素
中可以看到:除了catkin
中默认提供的buildtool_depend
,所有我们列出的依赖包都已经被添加到build_depend标签
中
3.9 自定义:CMakeLists.txt
catkin_create_pkg命令
生成的CMakeLists.txt文件
将在后续关于编译ROS程序代码
的教程中讲述。
4 编译ROS程序包
在介绍编译ROS程序包之前,我们先来说一下CMake的标准编译流程
:
# 在一个CMake项目里
$ mkdir build
$ cd build
$ cmake ..
$ make
$ make install # (可选)
编译ROS的程序包有两种方式:
- rosmake
- catkin_make
4.1 rosmake编译ROS程序包
4.2 catkin_make编译程序包
catkin_make
是一个命令行工具,它简化了catkin的标准工作流程
。你可以认为catkin_make是在CMake标准工作流程中依次调用了cmake和 make。
使用方法 :在catkin工作空间下
$ catkin_make [make_targets] [-DCMAKE_VARIABLES=...]
1、进入到工作空间下
cd ~/catkin_ws/src
2、开始编译(源码在默认的工作空间下)
catkin_make
如果编译的源码不在catkin_ws/src
目录下,则可以通过加上--source
参数,比如源码放在my_src
目录下,此时的编译命令为:
catkin_make --source my_src
或catkin_make install --source my_src # (optionally)
3、编译好之后会查看到三个目录:
(base) shl@zhihui-mint:~/catkin_ws$ ls
build devel src
(base) shl@zhihui-mint:~/catkin_ws$
build目录
:是build space的默认所在位置,同时cmake和make
也是在这里被调用来配置并编译
你的程序包。devel目录
:是devel space的默认所在位置, 同时也是在你安装程序包之前存放可执行文件
和库文件
的地方。
4、编译好后,添加到当前终端环境
source devel/setup.bash
5 理解ROS节点(Node)
本教程主要介绍 ROS 图
(graph)概念 并讨论roscore
、rosnode
和 rosrun
命令行工具的使用。
5.1 先决条件
在本教程中我们将使用到一个轻量级的模拟器
,请使用以下命令来安装:
$ sudo apt-get install ros-<distro>-ros-tutorials
用你使用的ROS发行版本名称
(例如electric、fuerte、groovy、hydro等)替换掉。
我的系统是:Ubuntu18.04
,对应的ROS的发行版本号为:melodic
,因此安装命令为:
$ sudo apt-get install ros-melodic-ros-tutorials
5.2 ros图(graph)概念描述
Nodes:节点
,一个节点
即为一个可执行文件
,它可以通过ROS与其它节点进行通信
。Messages:消息
,消息
是一种ROS数据类型
,用于订阅
或发布
到一个话题
。Topics:话题
,节点
可以发布消息
到话题
,也可以订阅话题以接收消息
。Master:节点管理器
,ROS名称服务 (比如帮助节点找到彼此
)。rosout
:ROS中相当于stdout/stderr
。roscore
:主机
+rosout
+参数服务器
(参数服务器会在后面介绍)。
1、如下,我在的机器上连接了单线激光雷达
和网络摄像头
之后,通过rostopic list
查看有话题topic
rostopic list
(base) shl@zhihui-mint:~$ rostopic list
/LiDAR/LD06
/clicked_point
/image_view/output
/image_view/parameter_descriptions
/image_view/parameter_updates
/initialpose
/move_base_simple/goal
/reprojection
/rosout
/rosout_agg
/tf
/tf_static
/usb_cam/camera_info
/usb_cam/image_raw
/usb_cam/image_raw/compressed
/usb_cam/image_raw/compressed/parameter_descriptions
/usb_cam/image_raw/compressed/parameter_updates
/usb_cam/image_raw/compressedDepth
/usb_cam/image_raw/compressedDepth/parameter_descriptions
/usb_cam/image_raw/compressedDepth/parameter_updates
/usb_cam/image_raw/theora
/usb_cam/image_raw/theora/parameter_descriptions
/usb_cam/image_raw/theora/parameter_updates
(base) shl@zhihui-mint:~$
2、然后可以通过rqt_graph
查看ros的图是什么样的
$rqt_graph
5.3 节点 Node
一个节点
其实只不过是ROS程序包
中的一个可执行文件
。ROS节点
可以使用ROS客户库与其他节点通信
。节点
可以发布或接收一个话题
。- 节点也可以提供或使用某种服务。
5.4 ROS客户端库
ROS客户端库
允许使用不同编程语言
编写的节点之间互相通信
:
-rospy
= python 客户端库
-roscpp
= c++ 客户端库
rosjs
= javascripts客户端库rosjava
= java客户端库
5.5 roscore
roscore是你在运行所有ROS程序前首先要运行的命令
$roscore
运行roscore命令会看到如下输出:
(base) shl@zhihui-mint:~$ roscore
... logging to /home/shl/.ros/log/1018130a-9bff-11eb-902e-e0d55e449b44/roslaunch-zhihui-mint-18822.log
Checking log directory for disk usage. This may take a while.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.
started roslaunch server http://zhihui-mint:39045/
ros_comm version 1.14.9
SUMMARY
========
PARAMETERS
* /rosdistro: melodic
* /rosversion: 1.14.9
NODES
auto-starting new master
process[master]: started with pid [18832]
ROS_MASTER_URI=http://zhihui-mint:11311/
setting /run_id to 1018130a-9bff-11eb-902e-e0d55e449b44
process[rosout-1]: started with pid [18873]
started core service [/rosout]
注意:
如果不能够正确初始化roscore,可能原因如下:
- 很有可能是存在网络配置问题。
- 如果roscore不能初始化并提示缺少权限,这可能是因为~/.ros文件夹归属于root用户(只有root用户才能访问)
$ sudo chown -R <your_username> ~/.ros
5.6 rosnode的使用
先查看一下rosnode有哪些命令参数:
(base) shl@zhihui-mint:~$ rosnode -h
rosnode is a command-line tool for printing information about ROS Nodes.
Commands:
rosnode ping test connectivity to node
rosnode list list active nodes
rosnode info print information about node
rosnode machine list nodes running on a particular machine or list machines
rosnode kill kill a running node
rosnode cleanup purge registration information of unreachable nodes
Type rosnode <command> -h for more detailed usage, e.g. 'rosnode ping -h'
(base) shl@zhihui-mint:~$
1、rosnode节点介绍
- 打开一个新的终端, 可以使用 rosnode 像运行roscore一样看看在 运行什么...
- 注意: 当打开一个新的终端时,你的运行环境会复位,同时你的~/.bashrc文件会复原。
- 如果你在运行类似于rosnode的指令时出现一些问题
- 也许你需要添加一些环境设置文件到你的~/.bashrc或者手动重新配置他们。
-rosnode
显示当前运行
的ROS节点信息
。 rosnode list
指令列出活跃的节点
2、rosnode节点有哪些命令参数
(base) shl@zhihui-mint:~$ rosnode -h
rosnode is a command-line tool for printing information about ROS Nodes.
Commands:
rosnode ping test connectivity to node
rosnode list list active nodes
rosnode info print information about node
rosnode machine list nodes running on a particular machine or list machines
rosnode kill kill a running node
rosnode cleanup purge registration information of unreachable nodes
Type rosnode <command> -h for more detailed usage, e.g. 'rosnode ping -h'
(base) shl@zhihui-mint:~$
3、使用rosnode list
查看当前正在运行的节点
(base) shl@zhihui-mint:~$ rosnode list
/LD06
/image_view
/reprojection
/rosout
/rviz
/usb_cam
(base) shl@zhihui-mint:~$
因此,我连接了激光雷达
和网络摄像头
,因此能看到的激活节点比较多,你自己能看到的节点可能只有rosout
- 因为
rosout
这个节点用于收集
和记录
节点调试输出信息
,所以它总是在运行的
。
4、rosnode info命令返回的是关于一个特定节点的信息。
$ rosnode info /rosout
这给了我们更多的一些有关于rosout的信息,
(base) shl@zhihui-mint:~$ rosnode info /rosout
--------------------------------------------------------------------------------
Node [/rosout]
Publications:
* /rosout_agg [rosgraph_msgs/Log]
Subscriptions:
* /rosout [rosgraph_msgs/Log]
Services:
* /rosout/get_loggers
* /rosout/set_logger_level
contacting node http://zhihui-mint:35585/ ...
Pid: 18873
Connections:
* topic: /rosout
* to: /LD06 (http://zhihui-mint:42629/)
* direction: inbound (52012 - zhihui-mint:46679) [13]
* transport: TCPROS
* topic: /rosout
* to: /image_view (http://zhihui-mint:45923/)
* direction: inbound (45082 - zhihui-mint:35753) [17]
* transport: TCPROS
* topic: /rosout
* to: /usb_cam (http://zhihui-mint:39995/)
* direction: inbound (44188 - zhihui-mint:35259) [16]
* transport: TCPROS
* topic: /rosout
* to: /rviz (http://zhihui-mint:38439/)
* direction: inbound (39514 - zhihui-mint:54301) [18]
* transport: TCPROS
* topic: /rosout
* to: /reprojection (http://zhihui-mint:42737/)
* direction: inbound (48372 - zhihui-mint:40099) [19]
* transport: TCPROS
(base) shl@zhihui-mint:~$
单线激光雷达的节点/LD06
的更多信息:
(base) shl@zhihui-mint:~$ rosnode info /LD06
--------------------------------------------------------------------------------
Node [/LD06]
Publications:
* /LiDAR/LD06 [sensor_msgs/LaserScan]
* /rosout [rosgraph_msgs/Log]
Subscriptions: None
Services:
* /LD06/get_loggers
* /LD06/set_logger_level
contacting node http://zhihui-mint:42629/ ...
Pid: 20354
Connections:
* topic: /rosout
* to: /rosout
* direction: outbound (46679 - 127.0.0.1:52012) [12]
* transport: TCPROS
* topic: /LiDAR/LD06
* to: /reprojection
* direction: outbound (46679 - 127.0.0.1:60506) [11]
* transport: TCPROS
* topic: /LiDAR/LD06
* to: /rviz
* direction: outbound (46679 - 127.0.0.1:60516) [14]
* transport: TCPROS
(base) shl@zhihui-mint:~$
5.7 rosrun的使用
rosrun允许你使用包名
直接运行一个包内的节点
(而不需要知道这个包的路径)。
用法:
$ rosrun [package_name] [node_name]
现在我们可以运行turtlesim包中的 turtlesim_node。
1、下面我们启动一个turtlesim包
中的turtlesim_node
节点来说明
rosrun turtlesim turtlesim_node
2、此时再使用rosnode list
查看一下正在运行的节点有哪些
(base) shl@zhihui-mint:~$ rosnode list
/LD06
/image_view
/reprojection
/rosout
/rviz
/turtlesim
/usb_cam
(base) shl@zhihui-mint:~$
3、改变发布节点的名称
首先停止之前发布的/turtlesim
节点,在更改节点之前,先停止我们之前运行的turtlesim节点
- 关闭 turtlesim 窗口停止运行节点 (或者回到rosrun turtlesim终端并使用ctrl -C)。
- 现在让我们重新运行它,但是这一次使用Remapping Argument改变节点名称:
$ rosrun turtlesim turtlesim_node __name:=my_turtle
然后我们在使用rosnode list
查看一下发布的节点名称有没有变化:
(base) shl@zhihui-mint:~$ rosnode list
/LD06
/image_view
/my_turtle
/reprojection
/rosout
/rviz
/usb_cam
(base) shl@zhihui-mint:~$
4、如果你不能够关掉之前发布的/turtlesim节点,需要
1)先杀死之前的发布的节点
rosnode kill /turtlesim
2)然后再清楚杀掉的节点即可
rosnode cleanup
5、使用rosnode ping
进行测试
(base) shl@zhihui-mint:~$ rosnode ping /my_turtle
rosnode: node is [/my_turtle]
pinging /my_turtle with a timeout of 3.0s
xmlrpc reply from http://zhihui-mint:37485/ time=0.388861ms
xmlrpc reply from http://zhihui-mint:37485/ time=0.316858ms
xmlrpc reply from http://zhihui-mint:37485/ time=0.284195ms
xmlrpc reply from http://zhihui-mint:37485/ time=0.282049ms
6 理解ROS话题(Topic)
本教程介绍ROS话题(topics)
以及如何使用rostopic
和 rxplot
等 命令行工具。
6.1 通过键盘远程控制turtle
1、先启动roscore
roscore
2、启动turtlesim
节点
rosrun turtlesim turtlesim_node
3、启动turtle鼠标控制节点
rosrun turtlesim turtle_teleop_key
- 现在你可以使用键盘上的方向键来控制turtle运动了。
- 如果不能控制,请
选中turtle_teleop_key所在的终端窗口
以确保你的按键输入能够被捕获。
下面让我们来看看小乌龟移动的过程
的背后都发生了什么
6.2 ROS Topics
turtlesim_node节点
和turtle_teleop_key节点
之间是通过一个ROS话题
来互相通信
的。turtle_teleop_key
在一个话题上发布按键输入消息
,而turtlesim
则订阅该话题
以接收该消息
。- 下面让我们使用
rqt_graph
来显示当前运行的节点和话题。 - 注意:如果你使用的是electric或更早期的版本,那么rqt是不可用的,请使用rxgraph代替。
6.3 rqt_graph的使用
rqt_graph
能够创建
一个显示当前系统运行情况的动态图形
。rqt_graph
是rqt程序包
中的一部分。- 通过
鼠标滚轮
对图结构进行放大和缩小
如果你没有安装,请通过以下命令来安装:
$ sudo apt-get install ros-<distro>-rqt
$ sudo apt-get install ros-<distro>-rqt-common-plugins
更具你需要的版本,替换ros的发行版本号!
1、在一个新的终端中运行
rosrun rqt_graph rqt_graph
或者
rqt_graph
2、你会看到如下的图形
只显示节点Nodes
- 如果你将鼠标放在/turtle1/command_velocity上方,相应的
ROS节点(蓝色和绿色)
和话题(红色)
就会高亮显示。 - 正如你所看到的
turtlesim_node节点
和turtle_teleop_key节点
正通过一个名为/turtle1/cmd_vel
的话题来互相通信。
蓝色节点
和绿色节点
就相当与是两部手机,必须通过红色的话题
就相当于是基站,然后进行信息交互通信!
6.4 rostopic的使用
1、rostopic命令参数有哪些:
(base) shl@zhihui-mint:~$ rostopic -h
rostopic is a command-line tool for printing information about ROS Topics.
Commands:
rostopic bw display bandwidth used by topic
rostopic delay display delay of topic from timestamp in header
rostopic echo print messages to screen
rostopic find find topics by type
rostopic hz display publishing rate of topic
rostopic info print information about active topic
rostopic list list active topics
rostopic pub publish data to topic
rostopic type print topic or field type
Type rostopic <command> -h for more detailed usage, e.g. 'rostopic echo -h'
(base) shl@zhihui-mint:~$
2、rostopic echo
显示某个话题上发布的数据
rostopic echo [topic]
我们打印/turtle1/cmd_vel
话题的数据
$ rostopic echo /turtle1/cmd_vel
你可能看不到任何东西因为现在还没有数据发布到该话题上。
接下来我们通过按下方向键使turtle_teleop_key节点发布数据。
记住如果turtle没有动起来的话就需要你重新选中turtle_teleop_key节点运行时所在的终端窗口。
现在当你按下向上方向键时应该会看到下面的信息:
(base) shl@zhihui-mint:~$ rostopic echo /turtle1/cmd_vel
linear:
x: 0.0
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: -2.0
---
linear:
x: 2.0
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: 0.0
---
现在让我们再看一下rqt_graph(你可能需要刷新一下ROS graph)。
正如你所看到的rostopic echo(红色显示部分)现在也订阅
了turtle1/cmd_vel话题
。
蓝色节点发布小乌龟移动的信息到topic,然后一个绿色的节点从tipic订阅接受消息!
3、rostopic list
能够列出所有当前订阅
和发布
的话题
(base) shl@zhihui-mint:~$ rostopic list
/LiDAR/LD06
/clicked_point
/image_view/output
/image_view/parameter_descriptions
/image_view/parameter_updates
/initialpose
/move_base_simple/goal
/reprojection
/rosout
/rosout_agg
/tf
/tf_static
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose
/usb_cam/camera_info
/usb_cam/image_raw
/usb_cam/image_raw/compressed
/usb_cam/image_raw/compressed/parameter_descriptions
/usb_cam/image_raw/compressed/parameter_updates
/usb_cam/image_raw/compressedDepth
/usb_cam/image_raw/compressedDepth/parameter_descriptions
/usb_cam/image_raw/compressedDepth/parameter_updates
/usb_cam/image_raw/theora
/usb_cam/image_raw/theora/parameter_descriptions
/usb_cam/image_raw/theora/parameter_updates
(base) shl@zhihui-mint:~$
4、查看rostopic list -h的参数
(base) shl@zhihui-mint:~$ rostopic list -h
Usage: rostopic list [/namespace]
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
--host group by host name
(base) shl@zhihui-mint:~
在rostopic list中使用verbose选项,可以显示出有关所发布
和订阅
的话题及其类型的详细信息
(base) shl@zhihui-mint:~$ rostopic list -v
Published topics:
* /image_view/parameter_updates [dynamic_reconfigure/Config] 1 publisher
* /usb_cam/camera_info [sensor_msgs/CameraInfo] 1 publisher
* /usb_cam/image_raw/compressedDepth/parameter_updates [dynamic_reconfigure/Config] 1 publisher
* /clicked_point [geometry_msgs/PointStamped] 1 publisher
* /usb_cam/image_raw/compressed [sensor_msgs/CompressedImage] 1 publisher
* /turtle1/cmd_vel [geometry_msgs/Twist] 1 publisher
* /move_base_simple/goal [geometry_msgs/PoseStamped] 1 publisher
* /usb_cam/image_raw/compressedDepth/parameter_descriptions [dynamic_reconfigure/ConfigDescription] 1 publisher
* /usb_cam/image_raw/compressed/parameter_descriptions [dynamic_reconfigure/ConfigDescription] 1 publisher
* /LiDAR/LD06 [sensor_msgs/LaserScan] 1 publisher
* /usb_cam/image_raw/theora/parameter_descriptions [dynamic_reconfigure/ConfigDescription] 1 publisher
* /usb_cam/image_raw/compressedDepth [sensor_msgs/CompressedImage] 1 publisher
* /usb_cam/image_raw/compressed/parameter_updates [dynamic_reconfigure/Config] 1 publisher
* /rosout [rosgraph_msgs/Log] 8 publishers
* /usb_cam/image_raw/theora/parameter_updates [dynamic_reconfigure/Config] 1 publisher
* /initialpose [geometry_msgs/PoseWithCovarianceStamped] 1 publisher
* /rosout_agg [rosgraph_msgs/Log] 1 publisher
* /reprojection [sensor_msgs/Image] 1 publisher
* /usb_cam/image_raw [sensor_msgs/Image] 1 publisher
* /turtle1/color_sensor [turtlesim/Color] 1 publisher
* /usb_cam/image_raw/theora [theora_image_transport/Packet] 1 publisher
* /image_view/output [sensor_msgs/Image] 1 publisher
* /image_view/parameter_descriptions [dynamic_reconfigure/ConfigDescription] 1 publisher
* /turtle1/pose [turtlesim/Pose] 1 publisher
Subscribed topics:
* /usb_cam/image_raw [sensor_msgs/Image] 2 subscribers
* /rosout [rosgraph_msgs/Log] 1 subscriber
* /tf [tf2_msgs/TFMessage] 1 subscriber
* /tf_static [tf2_msgs/TFMessage] 1 subscriber
* /LiDAR/LD06 [sensor_msgs/LaserScan] 2 subscribers
* /turtle1/cmd_vel [geometry_msgs/Twist] 2 subscribers
(base) shl@zhihui-mint:~$
6.5 ROS Messages
话题之间
的通信是通过在节点之间发送ROS消息
实现的。- 对于
发布器(turtle_teleop_key)
和订阅器(turtulesim_node)
之间的通信,发布器和订阅器之间必须发送和接收相同类型
的消息。 - 这意味着
话题的类型
是由发布
在它上面的消息类型决定的。 - 使用
rostopic type命令
可以查看发布在某个话题上的消息类型
。
6.6 rostopic type命令用来查看所发布话题
的消息类型
rostopic type命令用来查看所发布话题
的消息类型
rostopic type [topic]
(base) shl@zhihui-mint:~$ rostopic type /turtle1/cmd_vel
geometry_msgs/Twist
(base) shl@zhihui-mint:~$
下面是我的激光雷达和相机发布消息类型
(base) shl@zhihui-mint:~$ rostopic type /LiDAR/LD06
sensor_msgs/LaserScan
(base) shl@zhihui-mint:~$ rostopic type /usb_cam/image_raw
sensor_msgs/Image
(base) shl@zhihui-mint:~$
也可以使用rosmsg show
查看发布消息的详细类型情况:
(base) shl@zhihui-mint:~$ 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
(base) shl@zhihui-mint:~$
可以看出,这个是和我们上面打印出消息的类型是对应的:
(base) shl@zhihui-mint:~$ rostopic echo /turtle1/cmd_vel
linear:
x: 0.0
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: -2.0
6.7 rostopic pub可以把数据发布到当前某个正在广播的话题上
先来看一下rostopic pub
有哪些参数
(base) shl@zhihui-mint:~$ rostopic pub -h
Usage: rostopic pub /topic type [args...]
Options:
-h, --help show this help message and exit
-v print verbose output
-r RATE, --rate=RATE publishing rate (hz). For -f and stdin input, this
defaults to 10. Otherwise it is not set.
-1, --once publish one message and exit
-f FILE, --file=FILE read args from YAML file (Bagy)
-l, --latch enable latching for -f, -r and piped input. This
latches the first message.
-s, --substitute-keywords
When publishing with a rate, performs keyword ('now'
or 'auto') substitution for each message
--use-rostime use rostime for time stamps, else walltime is used
(base) shl@zhihui-mint:~$
1、rostopic pub
可以把数据发布
到当前某个正在广播的话题
上
rostopic pub [topic] [msg_type] [args]
2、示例:
$ 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大小的角速度开始移动。
3、下面我们来深入说明一下上面的那条命令含义
$ rostopic pub -1 /turtle1/cmd_vel geometry_msgs/Twist -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]'
rostopic pub
将会发布消息到某个话题-1
:发布完一条消息之后马上就退出/turtle1/cmd_vel
:消息发布到的话题名称geometry_msgs/Twist
:发布消息的类型--
:(双破折号)这会告诉命令选项解析器接下来的参数部分都不是命令选项
正如之前提到的,在一个geometry_msgs/Twist消息
里面包含有两个浮点型元素:linear和angular。在本例中2.0是linear的值,1.8是angula的值。
4、可以使用-r
设置一个稳定的频率,保持一直移动的状态
这条命令以1Hz的频率发布速度命令到速度话题上
$ rostopic pub /turtle1/cmd_vel geometry_msgs/Twist -r 1 -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]'
然后就可以看到小王八一直在哪里转圈圈!
6.8 rostopic hz查看数据发布的频率
rostopic hz [topic]
rostopic hz /turtle1/pose
(base) shl@zhihui-mint:~$ rostopic hz /turtle1/pose
subscribed to [/turtle1/pose]
average rate: 62.502
min: 0.015s max: 0.017s std dev: 0.00048s window: 62
average rate: 62.515
min: 0.015s max: 0.017s std dev: 0.00049s window: 125
average rate: 62.503
min: 0.015s max: 0.017s std dev: 0.00049s window: 187
average rate: 62.506
min: 0.015s max: 0.017s std dev: 0.00049s window: 250
average rate: 62.500
min: 0.015s max: 0.017s std dev: 0.00049s window: 312
现在我们可以知道了turtlesim
正以大约60Hz的频率
发布数据给turtle
。
6.9 ros_plot实时显示一个发布到某个话题上的数据变化图形
这里我们将使用rqt_plot命令来绘制正在发布到/turtle1/pose话题上的数据变化图形。
首先,在一个新终端中运行rqt_plot命令:
$ rosrun rqt_plot rqt_plot
或rqt_plot
这会弹出一个新窗口,在窗口左上角的一个文本框里面你可以添加需要绘制的话题。
- 在里面输入/turtle1/pose/x后之前处于禁用状态的加号按钮将会被使能变亮。
- 按一下该按钮,并对/turtle1/pose/y重复相同的过程。
- 现在你会在图形中看到turtle的x-y位置坐标图。
注意:
你可能看不到曲线,这是由于总坐标的值太大,我们检测的值太小,导致只能看到一条直线几乎与横轴重合,因此可以通过设置纵轴的最大值范围,如下图,修改Top值即可(当然横、纵轴的左右和上下都是可以改的,快去试试吧)!
7 理解ROS服务和参数
本教程介绍了ROS 服务
和参数
的知识,以及命令行工具rosservice
和 rosparam
的使用方法
7.1 ROS Services
服务(services)
是节点之间通讯
的另一种方式
。- 服务允许
节点发送请求
(request) 并获得一个响应
(response)
7.2 rosservice的使用
先查看rosservice有哪些参数
(base) shl@zhihui-mint:~$ rosservice -h
Commands:
rosservice args print service arguments
rosservice call call the service with the provided args
rosservice find find services by service type
rosservice info print information about service
rosservice list list active services
rosservice type print service type
rosservice uri print service ROSRPC uri
Type rosservice <command> -h for more detailed usage, e.g. 'rosservice call -h'
(base) shl@zhihui-mint:~$
- rosservice可以很轻松的使用
ROS 客户端/服务器
框架提供的服务。 rosservice提供了很多可以在
topic
上使用的命令,如下所示:- rosservice list 输出可用服务的信息
- rosservice call 调用带参数的服务
- rosservice type 输出服务类型
- rosservice find 依据类型寻找服务find services by service type
- rosservice uri 输出服务的ROSRPC uri
(未完待续)
8 使用 rqt_console 和 roslaunch
8.1 rqt_console
(未完待续)
8.2 roslaunch的使用
roslaunch
可以用来启动定义在launch文件
中的多个节点
。
8.2.1 创建launch文件
1、roslaunch的使用法
$ roslaunch [package] [filename.launch]
2、先切换到beginner_tutorials程序包目录下:
$ roscd beginner_tutorials
(base) shl@zhihui-mint:~/catkin_ws$ ls
build devel src
(base) shl@zhihui-mint:~/catkin_ws$ roscd beginner_tutorials/
(base) shl@zhihui-mint:~/catkin_ws/src/beginner_tutorials$ ls
CMakeLists.txt include package.xml src
(base) shl@zhihui-mint:~/catkin_ws/src/beginner_tutorials$
3、创建一个名为turtlemimic.launch
的launch文件并复制粘贴以下内容到该文件里面
<launch>
<group ns="turtlesim1">
<node pkg="turtlesim" name="sim" type="turtlesim_node"/>
</group>
<group ns="turtlesim2">
<node pkg="turtlesim" name="sim" type="turtlesim_node"/>
</group>
<node pkg="turtlesim" name="mimic" type="mimic">
<remap from="input" to="turtlesim1/turtle1"/>
<remap from="output" to="turtlesim2/turtle1"/>
</node>
</launch>
8.2.2 Launch 文件解析
下面对上面turtlemimic.launch
文件中内容逐句解析l
1、标签开头,表明是一个launch文件
<launch>
2、创建两个节点分组
<group ns="turtlesim1">
<node pkg="turtlesim" name="sim" type="turtlesim_node"/>
</group>
<group ns="turtlesim2">
<node pkg="turtlesim" name="sim" type="turtlesim_node"/>
</group>
- 在这里我们创建了
两个节点分组
并以命名空间(namespace)标签
来区分,其中一个名为turtulesim1
,另一个名为turtlesim2
,两个组里面都使用相同的turtlesim节点
并命名为sim
。 - 这样可以让我们同时
启动两个turtlesim模拟器
而不会产生命名冲突。
3、启动模仿节点
<node pkg="turtlesim" name="mimic" type="mimic">
<remap from="input" to="turtlesim1/turtle1"/>
<remap from="output" to="turtlesim2/turtle1"/>
</node>
在这里我们启动模仿节点
,并将所有话题的输入和输出分别重命名为turtlesim1
和turtlesim2
,这样就会使turtlesim2模仿turtlesim1。
4、 结束标签
</launch>
8.2.3 启动launch文件
1、通过roslaunch命令来启动launch文件:
$ roslaunch beginner_tutorials turtlemimic.launch
现在将会有两个turtlesims被启动
2、然后我们在一个新终端中使用rostopic命令发送速度设定消息
$ rostopic pub /turtlesim1/turtle1/cmd_vel geometry_msgs/Twist -r 1 -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, -1.8]'
你会看到两个turtlesims会同时开始移动,虽然发布命令只是给turtlesim1发送了速度设定消息。
3、可以通过rqt_graph
来更好的理解在launch文件
中所做的事情。
9 编写简单的消息发布器和订阅器 (Python catkin)
本教程将通过Python编写一个发布器节点
和订阅器节点
。
9.1 python编写发布器节点
- “
节点”
是ROS术语,它连接到ROS网络的可执行文件
。在这里,我们将创建发布器("talker")节点不断广播消息。 - 进入之前创建的beginner_tutorials包
1、进入创建的beginner_tutorials包
(base) shl@zhihui-mint:~/catkin_ws$ source devel/setup.bash
(base) shl@zhihui-mint:~/catkin_ws$ roscd beginner_tutorials/
(base) shl@zhihui-mint:~/catkin_ws/src/beginner_tutorials$
2、首先创建scripts目录存放Python代码:
$ mkdir scripts
$ cd scripts
3、下载例子脚本talker.py到scripts目录,并修改权限为可执行:
$ wget https://raw.github.com/ros/ros_tutorials/kinetic-devel/rospy_tutorials/001_talker_listener/talker.py
$ chmod +x talker.py
4、浏览和编辑:
$ rosed beginner_tutorials talker.py
内容如下:
#!/usr/bin/env python
import rospy
from std_msgs.msg import String
def talker():
pub = rospy.Publisher('chatter', String, queue_size=10)
rospy.init_node('talker', anonymous=True)
rate = rospy.Rate(10) # 10hz
while not rospy.is_shutdown():
hello_str = "hello world %s" % rospy.get_time()
rospy.loginfo(hello_str)
pub.publish(hello_str)
rate.sleep()
if __name__ == '__main__':
try:
talker()
except rospy.ROSInterruptException:
pass
9.1.1 代码解释
下面开始对发布器节点的代码
逐行分析:
1、使用python执行该脚本
#!/usr/bin/env python
每个Python的ROS节点会在顶部描述,第一行确保你的脚本是使用Python执行的脚本
2、导入python的依赖库包
import rospy
from std_msgs.msg import String
- 需要导入
rospy客户端库
- 导入
std_msgs.msg
重用std_msgs/String消息类型
3、定义talker
接口
pub = rospy.Publisher('chatter', String, queue_size=10)
rospy.init_node('talker', anonymous=True)
- 定义talker接口,pub = rospy.Publisher("chatter", String, queue_size=10)表示
节点发布chatter话题
,使用String字符类型
,实际上就是类std_msgs.msg.String
。queue_size
表示队列的大小
(适合hydro以后版本),如果队列消息处理不够快,就会丢弃旧的消息。 rospy.init_node(NAME)
,初始化节点
,开始跟ROS master通讯
。- 注意:保持
节点名称在网络中是唯一
的,不能包含斜杠"/"
。
4、控制话题消息发布的频率
rate = rospy.Rate(10) # 10hz
- 创建Rate对象,与sleep()函数结合使用,
控制话题消息
的发布频率
。 - 10hz表示每秒发布10次。
5、发布消息
while not rospy.is_shutdown():
hello_str = "hello world %s" % rospy.get_time()
rospy.loginfo(hello_str)
pub.publish(hello_str)
rate.sleep()
loop
是ospy的标准结构
,检查rospy.is_shutdown()标识没返回值就会一直运行。- rospy.is_shutdown()返回false就会退出(例如按下Ctrl-C)
- 程序执行pub.publish(String(str)),
在chatter话题
发布String消息
rate.sleep()
通过睡眠来,保持消息发送频率- 你可以运行 rospy.sleep(),类似time.sleep()
- rospy.loginfo(str)函数在屏幕输出调试信息,同时写入到节点日志文件和rosout节点
- rosout节点对于调式来说是便利的方式。
- 可以通过rqt_console查看调式信息。
std_msgs.msg.string
是一个非常简单的消息类型
,所以你可能想知道它看起来像发布更复杂的类型。- 一般的规则是,构造函数的参数是在.msg文件有相同的顺序。
- 你也可以传递没有参数和直接初始化字段,例如:
msg = String()
msg.data = str
或者你能初始化某些字段,剩余保持默认值:
String(data=str)
6、开始运行发布器节点
if __name__ == '__main__':
try:
talker()
except rospy.ROSInterruptException:
pass
- 标准的Python main检查,这个会
捕获rospy.ROSInterruptException异常
,当按下Ctrl-C或节点关闭的话,即使在rospy.sleep()和rospy.Rate.sleep()函数里都会抛出异常。
9.2 编写python订阅器节点
1、同样切换到scripts目录,然后下载listener.py代码
$ roscd beginner_tutorials/scripts/
$ wget https://raw.github.com/ros/ros_tutorials/kinetic-devel/rospy_tutorials/001_talker_listener/listener.py
2、listener.py文件内容如下:
#!/usr/bin/env python
import rospy
from std_msgs.msg import String
def callback(data):
rospy.loginfo(rospy.get_caller_id() + 'I heard %s', data.data)
def listener():
# In ROS, nodes are uniquely named. If two nodes with the same
# name are launched, the previous one is kicked off. The
# anonymous=True flag means that rospy will choose a unique
# name for our 'listener' node so that multiple listeners can
# run simultaneously.
rospy.init_node('listener', anonymous=True)
rospy.Subscriber('chatter', String, callback)
# spin() simply keeps python from exiting until this node is stopped
rospy.spin()
if __name__ == '__main__':
listener()
9.2.1 代码解释
- listener.py的代码类似talker.py,除了新增加的
函数回调机制
。
rospy.init_node('listener', anonymous=True)
rospy.Subscriber('chatter', String, callback)
# spin() simply keeps python from exiting until this node is stopped
rospy.spin()
这表示
节点订阅话题chatter
,消息类型是 std_msgs.msgs.String
当
接受到新消息
,回调函数
就触发处理这些信息
,并把消息
作为第一个参数传递
到函数里
还改变了调用
rospy.init_node()
,增加anonymous=True关键词参数。ROS要求每个节点要有唯一名称,如果相同的名称,就会中止之前同名的节点。
anonymous=True标识
就会告诉rospy,要生成一个唯一的节点名称
,因此你可以有多个listener.py同时运行。最后
rospy.spin()
简单保持你的节点一直运行
,直到程序关闭。不像roscpp,rospy.spin()不影响到订阅的回调函数,因为他们有自己的独立线程。
构建节点
- 我们使用CMake作为构建系统,即使是Python节点也需要使用。
这确保针对消息和服务能自动生成Python代码 - 进入catkin工作空间,运行catkin_make:
$ cd ~/catkin_ws
$ catkin_make