一,什么是结ROS系统
ROS(Robot Operating System)机器人操作系统实际上是提供了多节点协同机制,使用了话题、服务、参数服务器、action等通信机制,同时ROS还提供了Gazebo、rviz、rqt、rosbag等工具,这些工具的本质也是对通信消息的收发。
ROS本身提供了点对点网络,共同处理数据,它的基本概念包括节点、主节点、参数服务器、消息、服务、话题、包等等。
1.1、ROS的主要特点
(1)分布式架构(每一个工作进程都看作一个节点,使用节点管理器统一管理),
(2)多语言支持(如C++、Python等),
(3)良好的伸缩性(既可以写一个节点,也可以通过roslaunch将很多节点组织成一个更大的工程),
(4)源码开放(ROS遵循BSD协议,对个体和商业应用及修改完全免费)。
1.2 ROS常用命令
rospack-获取软件包有关信息:查看软件包依赖,
roscd-切换到软件包目录
rosls-查看软件包包含文件
rosnode-查看ros节点相关信息:查看节点列表,查看节点消息属性
rosrun-运行软件包-某一节点功能:rqt-graph
rostopic-获取话题相关信息
rosservice-获取服务相关信息
rosparam-获取参数相关信息
roslaunch-启动launch文件
rosmsg-查看消息有关信息
可以使用Tab
补全代码
二、ROS中的计算图级
图概念描述
· Nodes:节点,一个节点即为一个可执行文件,它可以通过ROS与其它节点进行通信。
· Messages:消息,消息是一种ROS数据类型,用于订阅或发布到一个话题。
· Topics:话题,节点可以发布消息到话题,也可以订阅话题以接收消息。
· Master:节点管理器,ROS名称服务 (比如帮助节点找到彼此)。
· rosout: ROS中相当于stdout/stderr。
· roscore: 主机+ rosout + 参数服务器 (参数服务器会在后面介绍)
2.1 节点
节点是主要的计算执行进程。ROS是有很多节点组成的。 一个节点其实只不过是ROS程序包中的一个可执行文件。ROS节点可以使用ROS客户库与其他节点通信。节点可以发布或接收一个话题。节点也可以提供或使用某种服务。
(节点是ros中非常重要的一个概念,为了帮助初学者理解这个概念,这里举一个通俗的例子:
例如,咱们有一个机器人,和一个遥控器,那么这个机器人和遥控器开始工作后,就是两个节点。遥控器起到了下达指 令的作用;机器人负责监听遥控器下达的指令,完成相应动作。从这里我们可以看出,节点是一个能执行特定工作任 务的工作单元,并且能够相互通信,从而实现一个机器人系统整体的功能。在这里我们把遥控器和机器人简单定义为两个节点,实际上在机器人中根据控制器、传感器、执行机构等不同组成模块,还可以将其进一步细分为更多的节点,这个是根据用户编写的程序来定义的。)
启动一个结点的方法,使用乌龟教程为例:
roscore
rosrun turtlesim turtlesim_node
//如果想查看结点的图,执行下面的命令
rqt_graph
ROS 命令行工具rosnode:
rosnode命令 | 作用 |
---|---|
rosnode list | 查询当前运行的所有节点 |
rosnode info node_name | 显示该节点的详细信息 |
rosnode kill node_name | 结束某个节点 |
rosnode ping | 测试该节点是否存活 |
rosnode machine | 列出在特定机器或列表机器上运行的节点 |
rosnode cleanup | 清除不可运行节点的注册信息 |
在开发调试时经常会需要查看当前node以及node信息,所以请记住这些常用命令。如果想不起来,也可以通过rosnode help
来查看rosnode
命令的用法。
2.2. 消息
节点之间通过消息实现彼此的逻辑联系与数据交换。
ROS 命令行工具rosmsg:
rosmsg命令 | 作用 |
---|---|
rosmsg show | 显示一条消息字段 |
rosmsg list | 列出所有消息 |
rosmsg package | 列出所有功能包消息 |
rosmsg packages | 列出所有具有该消息的功能包 |
rosmsg md5 | 显示一条消息的MD5检验值 |
2.3 话题
话题是一种传递消息(发布/订阅)的方式。每一条消息都要发布到相应的主题上,每一个话题都是强类型的。
ROS的话题消息可以使用TCP/IP或UDP传输,ROS默认使用的传输方式是TCP/IP。基于TCP传输成为TCPROS,是一种长连接方式;基于UDP传输的成为UDPROS,是一种低延迟、高效率的传输方式,但容易丢失数据,适合于远程操作。
rostopic命令 | 作用 |
---|---|
rostopic bw /topic | 显示主题所使用的带宽 |
rostopic echo /topic | 将主题对应的消息输出到屏幕 |
rostopic find message_type | 按照类型查找主题 |
rostopic hz /topic | 显示主题的发布频率 |
rostopic info /topic | 输出关于该主题的信息 |
rostopic list | 输出活动主题列表 |
rostopic pub /topic type args | 将数据发布到主题 |
rostopic type /topic | 输出主题类型 |
2.4 服务
服务用于请求应答模型,也必须有一个唯一的名称。当一个节点提供某个服务时,所有的节点都可以通过使用ROS客户端所编写的代码与之通讯。
rosservice 命令 | 作用 |
---|---|
rosservice args /service | 显示服务参数 |
rosservice call /service | 用输入的参数请求服务 |
rosservice find /service | 按照类型查找主题 |
rosservice info /service | 显示指定服务的信息 |
rosservice list | 显示活动的服务信息 |
rosservice uri /service | 显示ROSRPC URI服务 |
rosservice type /service | 显示服务类型 |
2.5 消息记录包
消息记录包是一种用于保存和回放ROS消息数据的文件格式,保存在.bag文件中。是一种用于存储数据的重要机制。
rosbag命令 | 作用 |
---|---|
check | 确定一个包是否可以在当前系统中进行,或者是否可以迁移。 |
decompress | 压缩一个或多个包文件。 |
filter | 解压一个或多个包文件。 |
fix | 在包文件中修复消息,以便在当前系统中播放。 |
help | 获取相关命令指引帮助信息。 |
info | 总结一个或多个包文件的内容。 |
play | 以一种时间同步的方式回放一个或多个包文件的内容。 |
record | 用指定话题的内容记录一个包文件。 |
reindex | 重新索引一个或多个包文件。 |
2.6 参数服务器
参数服务器是可通过网络访问的共享的多变量字典,通过关键字存储在节点管理器上。
ROS 命令行工具rosparam:
rosparam命令 | 作用 |
---|---|
rosparam delete parameter | 删除参数 |
rosparam dump file | 将参数服务器中的参数写入到文件 |
rosparam get parameter | 获得参数值 |
rosparam list | 列出参数服务器中的参数 |
rosparam load file | 从文件中加载参数到参数服务器 |
rosparam set parameter value | 设置参数 |
2.7 节点管理器(Master)
节点管理器用于主题、服务名称的注册和查找等。在整个ROS系统中如果没有节点管理器,就不会有节点之间的通讯。
3,在虚拟机上创建一个基于ros的项目文件
3.1 项目文件结构
ROS的文件结构,并非每个文件夹都是必须的,根据业务需求设计。
打开虚拟机后,有时候提示网络激活失败,修复方法参考以下链接:
3.2、工作空间
工作空间就是管理和组织ROS工程项目文件的地方,直观的形容就是一个仓库,里面装载着ROS的各种项目工程,便于系统组织管理调用。在可视化图形界面里是一个文件夹。我们自己写的ROS代码通常就放在工作空间中。其下主要的一级目录有四个:
- src:源空间;ROS的catkin软件包(源代码包)
- build:编译空间;catkin(CMake)的缓存信息和中间文件
- devel:开发空间;生成的目标文件(包括头文件,动态链接库,静态链接库,可执行文件等)、环境变量
- install:安装空间
最顶层的工作空间(可以任意命名)和 src (必须为src)文件夹是需要自己创建;
- build 和 devel 文件夹由 catkin_make 命令自动创建;
- install 文件夹由 catkin_make install 命令自动创建,几乎不怎么使用,一般不创建。
注意:使用 catkin_make 编译之前一定要回到最顶层的工作空间。同一个工作空间下,不允许存在同名功能包;不同工作空间下,允许存在同名功能包。
mkdir -p ~/catkin_ws/src # 创建
cd catkin_ws/ # 进入工作空间
catkin_make # 编译
source devel/setup.bash # 更新工作空间环境
3.3、package功能包
package是一种特定的文件结构和文件夹组合。通常将实现同一个具体功能的程序代码放到一个package中。只有 CMakeLists.txt 和 package.xml 是【必须】的,其余路径根据软件包是否需要来决定。
创建功能包
cd ~/catkin_ws/src
catkin_create_pkg my_pkg rospy rosmsg roscpp
【rospy】、【rosmsg】、【roscpp】是依赖库,可根据业务需求添加,也可加其他的,创建时加上就不需要再配置,忘记添加需要自己配置。
文件结构:
|-- CMakeLists.txt # (必须)当前package的编译规则。通常需要为c++代码添加编译时的依赖,执行等操作。
|—— package.xml # (必须)package的描述信息。通常添加一些ros库的支持。
|—— include文件夹 # 存放c++ 头文件的
|—— config文件夹 # 存放参数配置文件
|—— launch文件夹 # 存放launch文件(.launch或.xml)
|—— meshes文件夹 # 存放机器人或仿真场景的3D模型(.sda, .stl, .dae等) ;
|—— urdf文件夹 # 存放机器人的模型描述(.urdf或.xacro) ;
|—— rviz文件夹 # rviz文件
|—— src文件夹 # c++源代码
|—— scripts文件夹 # 可执行脚本;例如shell脚本(.sh)、Python脚本(.py) ;
|—— srv文件夹 # 自定义service
|—— msg文件夹 # 自定义topic
|—— action文件夹 # 自定义action
3.4、CMakeLists.txt介绍
CMakeLists.txt
原本是Cmake编译系统的规则文件,而Catkin编译系统基本沿用了CMake的编译风格,只是针对ROS工程添加了一些宏定义。所以在写法上,catkin的CMakeLists.txt
与CMake的基本一致。
这个文件直接规定了这个package要依赖哪些package,要编译生成哪些目标,如何编译等等流程。所以CMakeLists.txt
非常重要,它指定了由源码到目标文件的规则,catkin编译系统在工作时首先会找到每个package下的CMakeLists.txt
,然后按照规则来编译构建。
CMakeLists.txt
的基本语法都还是按照CMake,而Catkin在其中加入了少量的宏,总体的结构如下:
cmake_minimum_required() # 所需CMake版本
project() # 软件包名称
find_package() # 找到编译需要的其他CMake/Catkin package
catkin_python_setup() # 启用Python模块支持
add_message_files() # message生成器
add_service_files() # service生成器
add_action_files() # action生成器
generate_message() # 生成不同语言版本的msg/srv/action接口
catkin_package() # 生成当前package的cmake配置,供依赖本包的其他软件包调用
add_library() # 用来指定编译产生的库。默认的catkin编译产生共享库。
add_executable() # 生成可执行二进制文件
add_dependencies() # 定义目标文件依赖于其他目标文件,确保其他目标已被构建
target_link_libraries() # 指定可执行文件链接的库。这个要用在add_executable()后面。
catkin_add_gtest() # 测试建立
install() # 安装至本机
根据上面的操作步骤操作后,生成的CMakeLists.txt
文件的内容为:
cmake_minimum_required(VERSION 3.0.2)
project(my_pkg)
## 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
rosmsg
rospy
)
## 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 # Or other packages containing 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 my_pkg
# CATKIN_DEPENDS roscpp rosmsg rospy
# 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}/my_pkg.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/my_pkg_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_my_pkg.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)
重要的语法使用说明:
1)catkin_package()
catkin_package()是一个catkin提供的CMake宏。这是为构建系统指定catkin特定信息所必需的,后者又用于生成pkg-config和CMake文件。
在使用add_library()
或add_executable()
声明任何目标之前,必须调用此函数。该函数有5个可选参数:
INCLUDE_DIRS
- 包的导出包含路径LIBRARIES
- 从项目导出的库CATKIN_DEPENDS
- 该项目依赖的其他catkin
项目DEPENDS
- 该项目所依赖的非catkin
CMake项目。CFG_EXTRAS
- 其他配置选项
3.5 、package.xml介绍
该软件包清单是一个XML文件名为package.xml
中必须包括与任何兼容包的根文件夹。package.xml
也是一个catkin的package必备文件,它是这个软件包的描述文件,在较早的ROS版本(rosbuild编译系统)中,这个文件叫做manifest.xml
,用于描述pacakge的基本信息。如果你在网上看到一些ROS项目里包含着manifest.xml
,那么它多半是hydro版本之前的项目了。pacakge.xml
包含了package的名称、版本号、内容描述、维护人员、软件许可、编译构建工具、编译依赖、运行依赖等信息。
package.xml
文件build_depend必须包含 message_generation,run_depend必须包含 message_runtime。
<pacakge> # 根标记文件
<name> # 包名
<version> # 版本号
<description> # 内容描述
<maintainer> # 维护者
<license> # 软件许可证
<buildtool_depend> # 编译构建工具,通常为catkin
<depend> # 指定依赖项为编译、导出、运行需要的依赖,最常用
<build_depend> # 编译依赖项
<build_export_depend> # 导出依赖项
<exec_depend> # 运行依赖项
<test_depend> # 测试用例依赖项
<doc_depend> # 文档依赖项