写在前面, 请参照最新的参考资料进行学习,权威的资料为:ROS开源团队维护的维基百科:
http://wiki.ros.org/cn/kinetic/Installation/Ubuntu
http://wiki.ros.org/cn/ROS/Tutorials/CreatingPackage
上述资料资比较权威,网上大多具有自己系统的片面认识(包括此文)。
但是网上的资料为我们提供了一些参考,对于维基百科提供的部分不详细的地方是一个很好的补充。同时,也有一些参考十分经典,部分解决问题的做法也能够给出官方没有说明的地方,可以相互印证,学习。
其中可能会出现许多问题,请不要气馁,多查查网上的资料,重点参考上述的网站,同时可以参考《机器人操作系统(ROS)浅析》(《a general introduction to ROS》的翻译版,以下称ROS简介)。
一、下载并安装ROS
源设置命令,打开源文件命令:
sudo gedit /etc/apt/sources.list (Ubuntu源)
sudo gedit /etc/apt/sources.list.d/ros-latest.list (第三方软件源)
1.设置ROS源,可采用以下方式设置::
(1)ros官方源:
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
(2)国内中科大源:
sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.ustc.edu.cn/ros/ubuntu/ $DISTRIB_CODENAME main" > /etc/apt/sources.list.d/ros-latest.list'
若上面执行有问题则使用下列方式:
sudo sh -c 'echo "deb http://mirrors.ustc.edu.cn/ros/ubuntu/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
(若此源提示有问题--一个参考解决https://blog.csdn.net/xiangxianghehe/article/details/78483799)
(3)此外还有清华源等
其中首先看一下自己的Ubunutu源是否正常,不正常请选择一个最合适的源。
2.配置key:
udo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116
3.获取并安装ROS:
sudo apt-get update
sudo apt-get install ros-kinetic-desktop-full
sudo apt-get install python-rosinstall
其中:
sudo apt-get update(更新全部的软件源)
sudo apt-get install ros-kinetic-desktop-full(安装ros)
以及sudo apt-get install python-rosinstall
等待ROS安装完成;本人在官方源(14min多一点下载完)下载。
4.初始化与更新rosdep:
sudo rosdep init
rosdep update
5.配置ROS环境:
echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc
source ~/.bashrc
上述两条命令将命令写入根目录下的.bashrc文件,并立即生效。使得bash能正常找到ROS的配置文件,以后就可以正常使用ROS。
如果你安装有多个ROS版本(kinetic等), ~/.bashrc 必须只能 source 你当前使用版本所对应的 setup.bash。
如果你只想改变当前终端下的环境变量,可以执行以下命令:source /opt/ros/kinetic/setup.bash
6.安装building package的依赖:
sudo apt-get install python-rosinstall python-rosinstall-generator python-wstool build-essential
7.测试ros是否安装成功:
roscore -h
显示正常安装的信息,则表示安装成功。或者使用以下方法测试:
1)打开Termial,输入以下命令,初始化ROS环境:
roscore
2) 打开新的Termial,输入以下命令,弹出一个小乌龟窗口:
rosrun turtlesim turtlesim_node
3) 打开新的Termial,输入以下命令,可以在Termial中通过方向键控制小乌龟的移动(不关闭前面的乌龟窗口):
rosrun turtlesim turtle_teleop_key
4) 打开新的Termial,输入以下命令,弹出新的窗口查看ROS节点信息:
rosrun rqt_graph rqt_graph
前面的几个命令需要在相应的终端下活动才能正常运行(特别是控制乌龟移动)。
可使用Ctrl+C停止终端。
二、ROS实现Hello,World!
可参考中文维基百科:http://wiki.ros.org/cn/ROS/Tutorials/CreatingPackage
1.创建工作区:
$ mkdir -p ~/test_ros/src
网上还有人给出以下两步(工作区间初始化),其实可不做(系统后期会默认进行--建包的时候):
cd ~/test_ros/src/
catkin_init_workspace
上述命令创建一个名为test_ros的ROS工作区,其实就是创建目录。这是个ROS工作区的标准目录,ROS工作区下包含一个子文件夹src,用于保存将要编写的源代码等。
2.创建ROS功能包
参考:ROS简介(a )
(1)进入ROS工作区下的src目录:
cd ~/test_ros/src/
(2)在工作区下src目录建立功能包:agitr
(《a gentle introduction to ROS》的首字母。这本书有中文版,但是里面的部分内容不是针对kinetic,如果不小心会有报错误。如果参考其中的内容,出现了问题 ,请以维基百科为准。顺便一提,网上大多数是参考此书的,其中笔者也参考了,但是发现一些问题,故在此提一下。其实不是书本上的问题,而是自己没有仔细地编写程序和命令引发的。)
catkin_create_pkg agitr
这个命令会在工作区下src目录中建立agitr功能包,并在包中生成两个重要文件:
第一个配置文件,叫做 package.xml;这个文件需要修改一点内容,后续会讲到。
第二个文件,叫做 CMakeLists.txt,是一个 Cmake 的脚本文件,Cmake 是一个符合工业标准的跨平台编译系统。这个文件包
含了一系列的编译指令,包括应该生成哪种可执行文件,需要哪些源文件,以及在哪里可以找到所需的头文件和链接库。当然,这个文件表明 catkin 在内部使用了 Cmake。
注意:ROS 包的命名遵循一个命名规范,只允许使用小写字母、数字和下划线,而且首字符必须是一个小写字母。
3.此时可以编译看看有没有错误。请注意此时并没有编程,只是看是否能通过编译具备,编译环境
(1)回到ROS工作区(是工作区!)下使用catkin编译:
(也可以在创建工作区间时就编译,不过当时需要初始化一下工作区间)
cd ~/test_ros/
catkin_make
如果编译应该会通过,如果不通过则说明ROS有问题,请重新安装或根据问题解决。
如果编译正常通过,会在工作区间下生成两个文件夹:devel,build;在devel文件夹下能看到几个setup.*sh文件其中是包含本工作区间的配置文件命令;
(2)需要将其写入之前说的~/.bashrc文件中:
echo "source ~/test_ros/devel/setup.bash" >> ~/.bashrc
source ~/.bashrc
今后终端就可以识别这个工作区间,或者也可以采用:source devel/setup.bash 命令,但该名令只是对此工作区间有用,没有将命令写入.bashrc文件;有反应说重启电脑后会出现不识别等问题。
当完成功能包的相关工作后(即完成了编写、调试、测试等一系列工作后,此时代码基本定型),可以放心地删除 devel 和 build两个子目录。
(3)查看是否已经在bash中注册:(只是显示包地址写入了环境变量)
echo $ROS_PACKAGE_PATH
在环境变量中如果已经注册,会出现自己建立的工作区间的包地址目录。
4.终于到了重点了:建立hello.cpp,并编写源代码
(1)转到src目录下:
cd ~/test_ros/src/
(2)创建hello.cpp,也可以直接创建,不用命令
touch hello.cpp
(3)编写hello.cpp源代码:
//"hello.world" program for ros.
// This header defines the standard ROS classes.
#include<ros/ros.h>
int main( int argc,char **argv){
// Initialize the ROS system
ros::init(argc,argv,"hello_ros");
// Enable ish this program as a ROS node.
ros::NodeHandle nh;
// Send some output as a log message.
ROS_INFO_STREAM("Hello,World!");
}
5.修改makefile:CMakelists.txt里的内容改为
cmake_minimum_required(VERSION 2.8.3)
project(agitr)
find_package(catkin REQUIRED COMPONENTS
roscpp
)
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES agitr
# CATKIN_DEPENDS other_catkin_pkg
# DEPENDS system_lib
)
include_directories(
include
${catkin_INCLUDE_DIRS}
)
add_executable(hello hello.cpp)
target_link_libraries(hello ${catkin_LIBRARIES})
为了给出依赖库,编辑包目录下的 CMakeLists.txt 文件。该文件的默认版本含有如下行:
find_package(catkin REQUIRED)
所依赖的其他 catkin 包可以添加到这一行的 COMPONENTS 关键字
后面,如下所示::
find_package(catkin REQUIRED COMPONENTS package-names)
并在其中添加两行以声明可执行文件及其依赖:
add_executable(hello hello.cpp)
target_link_libraries(hello ${catkin_LIBRARIES})
6.清单文件package.xml的内容改为:(特别注意)
<?xml version="1.0"?>
<package format="2">
<name>agitr</name>
<version>0.0.0</version>
<description>The agitr package</description>
<maintainer email="liu@todo.todo">liu</maintainer>
<license>TODO</license>
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<!-- <run_depend>roscpp</run_depend> -->
<!-- This is an error, the follow is ture.-->
<exec_depend>roscpp</exec_depend>
<!-- The export tag contains other, unspecified, tags -->
<export>
<!-- Other tools can request additional information be placed here -->
</export>
</package>
我们同样需要在包的清单文件中列出依赖库,通过使用build_depend (编译依赖)和 run_depend(运行依赖)两个关键
字实现:
<build_depend>package-name</build_depend>
<run_depend>package-name</run_depend>
其注意,其中的run_depend元可改成exec_depend元(参考维基百科)。由于上述提到的ROS简介一书中使用的是run_depend;故在此给出。在笔者第一次运行时,会报错ros / ros.h错误(非ros/ros.h,没有空格),主要是使用时复制了其中的代码而有空格错误。这里参考了最新的维基百科, 上面采用的是exec_depend。上述的xml实测可用,无误。如果报错ros/ros.h错误,原因一般是依赖项没有设置对。
6.编译工作区间,与之前一样:
cd ~/test_ros/
catkin_make
如果到此都正常,那么就完成了90%了。
如果有编译错误,会在执行此步骤时看见它们。在更正它们以后,可以重新运行 catkin_make 来完成编译工作。
如果看到来自catkin_make的错误 , 提 示 无 法 找 到ros/ros.h 头文件,或者 ros::init 等 ROS 函数未定义的错误,
最大的可能性是你的 CMakeLists.txt 没有正确声明对 roscpp的依赖。
本来还需要执行setup.bash 的脚本,但是由于前面将其写入.bashrc文件了,所以不需要执行了。值得一提的是,这个自动生成的脚本文件设置了若干环境变量,从而使 ROS 能够找到创建的功能包和新生成的可执行文件。除非目录结构发生变化,否则你只需要在每个终端执行此命令一次,即使你修改了代码并且用 catkin_make 执行了重编译。如果感觉不妥,执行的代码为:
source devel/setup.bash(先转到工作区间)
7.执行hello程序
(1)一个 新终端里执行:
roscore
(2)打开另外一个终端,运行rosrun agitr hello
rosrun agitr hello
(3)将会出现如下信息,表示执行成功,说明大功告成:
[ INFO] [1546072659.372736726]: Connected to master at [localhost:11311]
[ INFO] [1546072659.375831122]: Hello,World!
注意:不要忘了首先要启动 roscore:这个程序是一个节点,节点需要一个节点管理器才可以正常运行。顺便说一下,这行输出中的
数字代表时间,从 1970 年 1 月 1 日开始以秒计数,这一时间是ROS_INFO_STREAM 开始执行的时间。
这个 rosrun 命令,以及其他一些 ROS 命令,可能会产生如下所示的错误:
[rospack] Error: stack/package package-name not found
此错误的两个可能的原因是:
(1)错误地拼写了功能包名;
(2)没有成功运行你的工作区中的 setup.bash。
如果其中出现任何问题,请优先参考博文前面的参考资料,那里是比较权威的。此外可以百度一下别人的解决办法。总会有办法解决的,请耐心寻找解决办法(o^o),锲而不舍,锲而不舍,锲。。。
上述是笔者实践过程中的一些感悟与理解,由于是首次写这么长的博文,且学习ROS时间较短,难免可能出错。如果有误, 请大家多多包涵,指正。同时吐槽一下CSDN的编辑器,老是出问题,莫名跳转和恼人的界面显示功能。如果觉得有参考价值,希望大家多点赞收藏,能帮到大家是本人的荣幸。