安装好了ROS过后就可以开始下面ROS的工作环境了
主要参考下面文档:CSDN ROS入门教程(一)
一、ROS的工作环境
1.1 管理ROS环境
确保ROS的环境变量已经被设置
# bash 中输入下面的信息,会输出一大串关于ROS的环境信息
printenv | grep ROS
1.2 创建ROS工作空间
ROS Groovy发布于2012年,在这版本以及之后的都使用catkin进行创建ROS工作空间的工作。
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/
catkin_make
在工作空间首次运行 catkin_make 命令后,它会在 ./src 目录下创建一个 CMakeLists.txt 文件。
jet@jet-vm:~/catkin_ws$ ls
# 输出如下
build devel src
在 devel 文件夹中会有几个 setup.sh* 文件。source 命令执行其中的文件会覆盖工作空间顶层的环境。
source devel/setup.bash
# 因为我这里使用的是默认的bash环境,如果是zsh则是另外一个
查看是否修改了环境变量:
$echo $ROS_PACKAGE_PATH
jet@jet-vm:~/catkin_ws$ printenv | grep ROS
通过对比输出可以发现环境变量中 ROS_PACKAGE_PATH 和ROSLISP_PACKAGE_DIRECTORIES 发生了变化。
二、ROS文件系统
因为一开始安装ROS的时候选项是 ros-kinetic-desktop-full 所以下面需要的文件系统已经安装完毕了。
2.1 文件系统的概念
Packages:Packages是ROS代码的软件单元的一种组织方式,每个Package可以包含库,可执行程序,脚本等。
Manifests(Package.xml):manifest是一个package的描述文件,它定义了包之间的依赖,并用来捕获包的元信息(meta information,元数据是关于数据的组织、数据域及其关系的信息,简言之,元数据就是关于数据的数据。),例如版本,维护者,证书等等。
2.3 文件系统工具
ROS代码有独有的包管理命令
-
rospack = ros+package
rospack 可以获取有关packages的信息,帮助命令是 rospack help
jet@jet-vm:~/catkin_ws$ rospack find roscpp # 会输出相关信息
-
roscd = ros+cd
roscd 是 rosbash 的一部分,此命令可以切换到包的相关目录中。
jet@jet-vm:~/catkin_ws$ roscd roscpp jet@jet-vm:~/catkin_ws$ pwd
注:ROS工具只寻找 ROS_PACKAGE_PATH 所列出路径,其中的每个路径用 ”:“ 进行分隔。
-
roscd log
此命令会进入ROS的log文件夹,如果之前没有运行过ROS程序则会报错。
rosls = ros+ls
ROS工具中很多都是 ROS+XX组合的命令。
三、创建ROS Package
此章节使用 roscreate-pkg 或 catkin 创建一个新的package,并用rospack列出包的依赖关系。
3.1 一个catkin package的组成
必须包含一个catkin兼容的package.xml文件
必须包含一个使用catkin的CMakeLists.txt
-
每个package必须有自己的文件夹:这意味着没有嵌套的包,也没有共享同一目录的多个包。
最简单的package如下:
my_package/ CMakeLists.txt package.xml
3.2 catkin工作空间中的package
使用catkin packages工作的推荐方式的是使用catkin工作空间,当然也可以单独建立一个catkin package。一个普通的工作空间大概如下:
jet@jet-vm:~/catkin_ws$ tree
.
├── build
│ ├── atomic_configure
│ │ ├── env.sh
│ │ ├── local_setup.bash
│ │ ├── local_setup.sh
│ │ ├── local_setup.zsh
│ │ ├── setup.bash
│ │ ├── setup.sh
│ │ ├── _setup_util.py
│ │ └── setup.zsh
│ ├── catkin
│ │ └── catkin_generated
│ │ └── version
│ │ └── package.cmake
│ ├── catkin_generated
│ │ ├── env_cached.sh
│ │ ├── generate_cached_setup.py
│ │ ├── installspace
│ │ │ ├── env.sh
│ │ │ ├── local_setup.bash
│ │ │ ├── local_setup.sh
│ │ │ ├── local_setup.zsh
│ │ │ ├── setup.bash
│ │ │ ├── setup.sh
│ │ │ ├── _setup_util.py
│ │ │ └── setup.zsh
│ │ ├── order_packages.cmake
│ │ ├── order_packages.py
│ │ ├── setup_cached.sh
│ │ └── stamps
│ │ └── Project
│ │ ├── interrogate_setup_dot_py.py.stamp
│ │ ├── order_packages.cmake.em.stamp
│ │ ├── package.xml.stamp
│ │ └── _setup_util.py.stamp
│ ├── CATKIN_IGNORE
│ ├── catkin_make.cache
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ │ ├── 3.5.1
│ │ │ ├── CMakeCCompiler.cmake
│ │ │ ├── CMakeCXXCompiler.cmake
│ │ │ ├── CMakeDetermineCompilerABI_C.bin
│ │ │ ├── CMakeDetermineCompilerABI_CXX.bin
│ │ │ ├── CMakeSystem.cmake
│ │ │ ├── CompilerIdC
│ │ │ │ ├── a.out
│ │ │ │ └── CMakeCCompilerId.c
│ │ │ └── CompilerIdCXX
│ │ │ ├── a.out
│ │ │ └── CMakeCXXCompilerId.cpp
│ │ ├── clean_test_results.dir
│ │ │ ├── build.make
│ │ │ ├── cmake_clean.cmake
│ │ │ ├── DependInfo.cmake
│ │ │ └── progress.make
│ │ ├── cmake.check_cache
│ │ ├── CMakeDirectoryInformation.cmake
│ │ ├── CMakeError.log
│ │ ├── CMakeOutput.log
│ │ ├── CMakeRuleHashes.txt
│ │ ├── CMakeTmp
│ │ ├── download_extra_data.dir
│ │ │ ├── build.make
│ │ │ ├── cmake_clean.cmake
│ │ │ ├── DependInfo.cmake
│ │ │ └── progress.make
│ │ ├── doxygen.dir
│ │ │ ├── build.make
│ │ │ ├── cmake_clean.cmake
│ │ │ ├── DependInfo.cmake
│ │ │ └── progress.make
│ │ ├── feature_tests.bin
│ │ ├── feature_tests.c
│ │ ├── feature_tests.cxx
│ │ ├── Makefile2
│ │ ├── Makefile.cmake
│ │ ├── progress.marks
│ │ ├── run_tests.dir
│ │ │ ├── build.make
│ │ │ ├── cmake_clean.cmake
│ │ │ ├── DependInfo.cmake
│ │ │ └── progress.make
│ │ ├── TargetDirectories.txt
│ │ └── tests.dir
│ │ ├── build.make
│ │ ├── cmake_clean.cmake
│ │ ├── DependInfo.cmake
│ │ └── progress.make
│ ├── cmake_install.cmake
│ ├── CTestConfiguration.ini
│ ├── CTestCustom.cmake
│ ├── CTestTestfile.cmake
│ ├── gtest
│ │ ├── CMakeFiles
│ │ │ ├── CMakeDirectoryInformation.cmake
│ │ │ ├── gmock.dir
│ │ │ │ ├── build.make
│ │ │ │ ├── cmake_clean.cmake
│ │ │ │ ├── DependInfo.cmake
│ │ │ │ ├── depend.make
│ │ │ │ ├── flags.make
│ │ │ │ ├── link.txt
│ │ │ │ ├── progress.make
│ │ │ │ ├── src
│ │ │ │ └── usr
│ │ │ │ └── src
│ │ │ │ └── gtest
│ │ │ │ └── src
│ │ │ ├── gmock_main.dir
│ │ │ │ ├── build.make
│ │ │ │ ├── cmake_clean.cmake
│ │ │ │ ├── DependInfo.cmake
│ │ │ │ ├── depend.make
│ │ │ │ ├── flags.make
│ │ │ │ ├── link.txt
│ │ │ │ ├── progress.make
│ │ │ │ ├── src
│ │ │ │ └── usr
│ │ │ │ └── src
│ │ │ │ └── gtest
│ │ │ │ └── src
│ │ │ └── progress.marks
│ │ ├── cmake_install.cmake
│ │ ├── CTestTestfile.cmake
│ │ ├── gtest
│ │ │ ├── CMakeFiles
│ │ │ │ ├── CMakeDirectoryInformation.cmake
│ │ │ │ ├── gtest.dir
│ │ │ │ │ ├── build.make
│ │ │ │ │ ├── cmake_clean.cmake
│ │ │ │ │ ├── DependInfo.cmake
│ │ │ │ │ ├── depend.make
│ │ │ │ │ ├── flags.make
│ │ │ │ │ ├── link.txt
│ │ │ │ │ ├── progress.make
│ │ │ │ │ └── src
│ │ │ │ ├── gtest_main.dir
│ │ │ │ │ ├── build.make
│ │ │ │ │ ├── cmake_clean.cmake
│ │ │ │ │ ├── DependInfo.cmake
│ │ │ │ │ ├── depend.make
│ │ │ │ │ ├── flags.make
│ │ │ │ │ ├── link.txt
│ │ │ │ │ ├── progress.make
│ │ │ │ │ └── src
│ │ │ │ └── progress.marks
│ │ │ ├── cmake_install.cmake
│ │ │ ├── CTestTestfile.cmake
│ │ │ └── Makefile
│ │ └── Makefile
│ ├── Makefile
│ └── test_results
├── devel
│ ├── cmake.lock
│ ├── env.sh
│ ├── lib
│ ├── local_setup.bash
│ ├── local_setup.sh
│ ├── local_setup.zsh
│ ├── setup.bash
│ ├── setup.sh
│ ├── _setup_util.py
│ └── setup.zsh
└── src
└── CMakeLists.txt -> /opt/ros/kinetic/share/catkin/cmake/toplevel.cmake
43 directories, 123 files
jet@jet-vm:~/catkin_ws$
3.3 创建一个catkin Package
创建工作空间的方法在章节:1.2 创建ROS的工作环境
-
创建package代码:
# 示例 catkin_create_pkg <package_name> [depend1][depend2][depend3] #具体命令 $ cd ~/catkin_ws/src jet@jet-vm:~/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/jet/catkin_ws/src/beginner_tutorials. Please adjust the values in package.xml. jet@jet-vm:~/catkin_ws/src$
3.4 编译catkin工作空间并source
//主要命令如下
$ cd ~/catkin_ws
$ catkin_make
$ . ~/catkin_ws/devel/setup.bash
jet@jet-vm:~/catkin_ws/src$ cd ..
jet@jet-vm:~/catkin_ws$ catkin_make
Base path: /home/jet/catkin_ws
Source space: /home/jet/catkin_ws/src
Build space: /home/jet/catkin_ws/build
Devel space: /home/jet/catkin_ws/devel
Install space: /home/jet/catkin_ws/install
####
#### Running command: "cmake /home/jet/catkin_ws/src -DCATKIN_DEVEL_PREFIX=/home/jet/catkin_ws/devel -DCMAKE_INSTALL_PREFIX=/home/jet/catkin_ws/install -G Unix Makefiles" in "/home/jet/catkin_ws/build"
####
-- Using CATKIN_DEVEL_PREFIX: /home/jet/catkin_ws/devel
-- Using CMAKE_PREFIX_PATH: /opt/ros/kinetic
-- This workspace overlays: /opt/ros/kinetic
-- Using PYTHON_EXECUTABLE: /usr/bin/python
-- Using Debian Python package layout
-- Using empy: /usr/bin/empy
-- Using CATKIN_ENABLE_TESTING: ON
-- Call enable_testing()
-- Using CATKIN_TEST_RESULTS_DIR: /home/jet/catkin_ws/build/test_results
-- Found gmock sources under '/usr/src/gmock': gmock will be built
-- Found gtest sources under '/usr/src/gmock': gtests will be built
-- Using Python nosetests: /usr/bin/nosetests-2.7
-- catkin 0.7.18
-- 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/jet/catkin_ws/build
####
#### Running command: "make -j2 -l2" in "/home/jet/catkin_ws/build"
####
jet@jet-vm:~/catkin_ws$ . ~/catkin_ws/devel/setup.bash
jet@jet-vm:~/catkin_ws$
3.5 package依赖
-
一级依赖
jet@jet-vm:~/catkin_ws$ rospack depends1 beginner_tutorials roscpp rospy std_msgs jet@jet-vm:~/catkin_ws$ # 此命令的输出与创建package时传入的参数一致,这些对packages的依赖存储在package.xml 中
-
间接依赖
jet@jet-vm:~/catkin_ws$ rospack depends1 rospy genpy roscpp rosgraph rosgraph_msgs roslib std_msgs jet@jet-vm:~/catkin_ws$ #一般情况下,一个依赖项目都有自己的依赖项,rospack可以递归检测所有的嵌套依赖。
3.6 定制package
-
定制package.xml
包括description,maintainer,lincense,dependencies(包括了 buildtool_depend,build_depend,exec_depend)
定制CMakeLists.txt
四、编译Package
4.1 编译package
-
catkin_make 可以看做是标准的cmake工作流程:cmake,make
# In a CMake Project $ mkdir build $ cd build $ cmake .. $ make $ make install #(optionally) # In a catkin workspace $ catkin_make $ catkin_make install #(optionally)
catkin_make 命令将编译 src 目录下的所有工程。对于源码不再当前目录下的使用方法为:
# In a catkin workspace $ catkin_make --source my_src $ catkin_make install --source my_src #(optionally)
-
编译package
在当前工作空间中(~/catkin_ws): catkin_make
五、ROS Nodes
本节引入ROS Graph的概念,并探讨roscore,rosnode,rosrun的使用。
5.1 Graph的概念
Nodes:一个node表示一个使用ROS来与其他nodes进行通讯的可执行程序。
Messages:ROS的数据类型
Topics:Nodes可以向topic发布消息,也可以订阅topic来接收消息。
Master:Name sevice for ROS(帮助节点找到彼此)
rosout:ROS下的stdout/stderr。
roscore:Master + rosout + parameter server
5.2 Nodes
在ROS package中,一个Node实际上只不过是一个可执行文件。ROS Nodes使用ROS client library与其他nodes进行通信。Nodes可以发布和订阅一个Topic。Nodes也可以提供或使用一个sevice。
5.3 Client Libraries
ROS client library 允许使用不同编程语言写出来的Nodes进行通信。
rospy = python client library
roscpp = C plus plus client library
5.4 roscore
roscore 是当你使用ROS时第一个应该运行的核心程序。
5.5 使用rosnode
rosnode显示当前正在运行的有关ROS nodes的信息
# 列出活跃状态的nodes
jet@jet-vm:~$ rosnode list
/rosout
jet@jet-vm:~$ rosnode info /rosout
--------------------------------------------------------------------------------
Node [/rosout]
Publications:
* /rosout_agg [rosgraph_msgs/Log]
Subscriptions:
* /rosout [unknown type]
Services:
* /rosout/get_loggers
* /rosout/set_logger_level
contacting node http://jet-vm:41897/ ...
Pid: 2381
jet@jet-vm:~$
5.6 使用rosrun
rosrun 允许使用package名来直接运行一个package中的node(不必知道package的路径)。
# usage : rosrun [package_name] [nodename]
jet@jet-vm:~$ rosrun turtlesim turtlesim_node
[ INFO] [1565093878.731080946]: Starting turtlesim with node name /turtlesim
[ INFO] [1565093878.747198414]: Spawning turtle [turtle1] at x=[5.544445], y=[5.544445], theta=[0.000000]
# 弹出一个乌龟的窗口
ROS支持为node重新指定名字
$ rosrun turtlesim turtlesim_node __name:=my_turtle
jet@jet-vm: ~ $ rosnode list
/my_turtle
/rosout
可以使用 rosnode 的 ping 参数来测试是否node正常运行。
jet@jet-vm:~$ rosnode ping turtlesim
rosnode: node is [/turtlesim]
pinging /turtlesim with a timeout of 3.0s
xmlrpc reply from http://jet-vm:36863/ time=0.334024ms
xmlrpc reply from http://jet-vm:36863/ time=2.504826ms
xmlrpc reply from http://jet-vm:36863/ time=1.864910ms
xmlrpc reply from http://jet-vm:36863/ time=1.274824ms
xmlrpc reply from http://jet-vm:36863/ time=1.255035ms
^Cping average: 1.446724ms
jet@jet-vm:~$
如果出现上面的输出代表已经成功运行了。
5.7 总结
roscore 是所有运行的核心 = ros + core: master(prodives name service for ROS) + rosout(stdout/stderr) +parameter server.
rosnode = ros + node : ROS tool to get Information about a node.
rosrun = ros + run: runs a node from a given package
六、ROS Topics
本节引入ROS topics,与此同时使用rostopic和rqt_plot工具
6.1 准备工作
确保roscore在运行,在一个新打开的终端输入roscore可进行测试。
-
运行如下命令
$ rosrun turtlesim turtlesim_node
-
运行如下命令
$ rosrun turtlesim turtle_teleop_key # 之后可以使用方向按键控制乌龟动起来了
6.2 ROS Topics
-
使用 rqt-graph
rqt-graph 创建系统的一个动态范围。rqt-graph 是 rqt package 的一部分,安装方法如下:
# 按照正常安装全部的方法都是已经安装好了 $ sudo apt-get install ros-kinetic-rqt $ sudo apt-get install ros-kinetic-rqt-common-plugins
在终端中输入以下命令会出现一个可视化窗口显示nodes之间的关系。
$ rosrun rqt_graph rqt_graph
-
引入 rostopic
rostopic 工具用来获取 ROS topics。
-
使用 rostopic echo
rostopic echo 显示发布在一个topic上的数据,只有在运行之后有新的消息发布到topic上时才会有输出
# Usage $ rostopic echo [topic] $ rostopic echo /turtle1/cmd_vel
-
使用**rostopic list **
使用 $ rostopic list -v 列出所有的 topics
jet@jet-vm:~$ rostopic list -v Published topics: * /turtle1/color_sensor [turtlesim/Color] 1 publisher * /turtle1/cmd_vel [geometry_msgs/Twist] 1 publisher * /rosout [rosgraph_msgs/Log] 3 publishers * /rosout_agg [rosgraph_msgs/Log] 1 publisher * /turtle1/pose [turtlesim/Pose] 1 publisher Subscribed topics: * /turtle1/cmd_vel [geometry_msgs/Twist] 2 subscribers * /rosout [rosgraph_msgs/Log] 1 subscriber jet@jet-vm:~$
6.3 ROS Messages
ropics上的通讯是通过在nodes之间发送 ROS messages进行的。发布者和订阅者必须发哦是那个和接收同种类型的消息。这意味着,topic的类型是由发布在其上的message类型定义的。message的类型可通过 rostopic type [topic] 来查询。可以使用 rosmsg show type 查看信息格式。
jet@jet-vm:~$ rostopic list -v
Published topics:
* /turtle1/color_sensor [turtlesim/Color] 1 publisher
* /turtle1/cmd_vel [geometry_msgs/Twist] 1 publisher
* /rosout [rosgraph_msgs/Log] 3 publishers
* /rosout_agg [rosgraph_msgs/Log] 1 publisher
* /turtle1/pose [turtlesim/Pose] 1 publisher
Subscribed topics:
* /turtle1/cmd_vel [geometry_msgs/Twist] 2 subscribers
* /rosout [rosgraph_msgs/Log] 1 subscriber
jet@jet-vm:~$ rostopic type /turtle1/cmd_vel
geometry_msgs/Twist
jet@jet-vm:~$ 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
jet@jet-vm:~$
6.4 rostopic 续
-
rostopic pub可以在一个topic上发布数据
# Usage: rostopic pub [topic] [msg_type] [args] # 双短线表示后边的不是命令选项而是参数 jet@jet-vm:~$ rostopic pub -l /turtle1/cmd_vel geometry_msgs/Twist -- '[2.0,0.0,0.0]' '[0.0,0.0,1.0]' publishing and latching message. Press ctrl-C to terminate # 此时可以看到乌龟动了,几次执行下来可以看到乌龟走了一个纯圆。
- rostopic hz 报告数据发布速率: $ rostopic hz [topic]
jet@jet-vm:~$ rostopic hz /turtle1/cmd_vel
subscribed to [/turtle1/cmd_vel]
no new messages
no new messages
average rate: 4.828
min: 0.144s max: 0.288s std dev: 0.04833s window: 6
average rate: 5.999
min: 0.099s max: 0.288s std dev: 0.04975s window: 13
average rate: 7.209
min: 0.042s max: 0.298s std dev: 0.06797s window: 23
当有数据变动的时候也就是有数据传输。
6.5 使用 rqt_plot
使用指令 $ rosrun rqt_plot rqt_plot ,添加需要查看的topic。
七、ROS Services and Parameters
本节介绍ROS Services and Parameters,与此同时使用使用 rosservice 和 rosparam 命令行工具。services 是nodes间进行通信的另一种方式,services 允许nodes发送一个请求(request)和接收一个响应(response)。
#Usage:
$ rosservice list [topic] #列出[topic]锁提供的服务
$ rosservice type [service] # 显示服务类型
$ rosservice call [service] [args] # 调用服务
# 查看带参数的示例
rosservice find #find service by service type
rosservice uri #print service ROSRPC uri
jet@jet-vm:~/work$ rosservice type /spawn | rossrv show
float32 x
float32 y
float32 theta
string name
---
string name
jet@jet-vm:~/work$ rosservice call /spawn 2 2 0.2 "" # name field is optional
name: "turtle2"
rosparam 循序我们存储和操作 ROS parameter Server 上的数据,Parameter Server
可以存储整型,浮点型,布尔型,字典,列表。rosparam 使用 YAML 标记语言语法。
#Usage:
rosparam set [param_name] #set parameter
# 设置参数过后使用 /clear 服务刷新操作
$ rosservice call /clear
rosparam get [param_name] # get parameter
rosparam load # load parameter from file
rosparam dump # dump parameters to file
rosparam delete # delete parameter
rosparam list # list parameter names
# Usage
rosparam dump [file_name] [namespace]
rosparam load [file_name] [namespace]
# write all the parameters to the file params.yaml
$ rosparam dump params.yaml
# load these yaml files into new namespaces, e.g. copy
$ rosparam load params.yaml copy
$ rosparam get /copy/background_b