1 ROS简介
ROS诞生背景
机器人是一种高度复杂的系统性实现,机器人设计包含了机械加工、机械结构设计、硬件设计、嵌入式软件设计、上层软件设计…是各种硬件与软件集成,甚至可以说机器人系统是当今工业体系的集大成者。 机器人体系是相当庞大的,其复杂度之高,以至于没有任何个人、组织甚至公司能够独立完成系统性的机器人研发工作。
一种更合适的策略是:让机器人研发者专注于自己擅长的领域,其他模块则直接复用相关领域更专业研发团队的实现,当然自身的研究也可以被他人继续复用。这种基于"复用"的分工协作,遵循了不重复发明轮子的原则,显然是可以大大提高机器人的研发效率的,尤其是随着机器人硬件越来越丰富,软件库越来越庞大,这种复用性和模块化开发需求也愈发强烈。
在此大背景下,于 2007 年,一家名为 柳树车库(Willow Garage) 的机器人公司发布了 ROS(机器人操作系统),ROS是一套机器人通用软件框架,可以提升功能模块的复用性,并且随着该系统的不断迭代与完善,如今 ROS 已经成为机器人领域的事实标准。
1.1 ROS概念
ROS全称Robot Operating System(机器人操作系统)
ROS是适用于机器人的开源元操作系统;
ROS集成了大量的工具,库,协议,提供类似OS所提供的功能,简化对机器人的控制;
还提供了用于在多台计算机上获取,构建,编写和运行代码的工具和库,ROS在某些方面类似于“机器人框架”;
ROS设计者将ROS表述为“ROS = Plumbing + Tools + Capabilities + Ecosystem”,即ROS是通讯机制、工具软件包、机器人高层技能以及机器人生态系统的集合体。
1.2 ROS设计目标
机器人开发的分工思想,实现了不同研发团队间的共享和协作,提升了机器人的研发效率,为了服务“ 分工”,ROS主要设计了如下目标:
- 复用:ROS的目标不是成为具有最多功能的框架,ROS的主要目标是支持机器人技术研发中的代码重用。
- 分布式:ROS是进程(也称为Nodes)的分布式框架,ROS中的进程可分布于不同主机,不同主机协同工作,从而分散计算压力
- 松耦合:ROS中功能模块封装于独立的功能包或元功能包,便于分享,功能包内的模块以节点为单位运行,以ROS标准的IO作为接口,开发者不需要关注模块内部实现,只要了解接口规则就能实现复用,实现了模块间点对点的松耦合连接
- 精简:ROS被设计为尽可能精简,以便为ROS编写的代码可以与其他机器人软件框架一起使用。ROS易于与其他机器人软件框架集成:ROS已与OpenRAVE,Orocos和Player集成。
- 语言独立性:包括Java,C++,Python等。为了支持更多应用开发和移植,ROS设计为一种语言弱相关的框架结构,使用简洁,中立的定义语言描述模块间的消息接口,在编译中再产生所使用语言的目标文件,为消息交互提供支持,同时允许消息接口的嵌套使用
- 易于测试:ROS具有称为rostest的内置单元/集成测试框架,可轻松安装和拆卸测试工具。
- 大型应用:ROS适用于大型运行时系统和大型开发流程。
- 丰富的组件化工具包:ROS可采用组件化方式集成一些工具和软件到系统中并作为一个组件直接使用,如RVIZ(3D可视化工具),开发者根据ROS定义的接口在其中显示机器人模型等,组件还包括仿真环境和消息查看工具等
- 免费且开源:开发者众多,功能包多
1.3 ROS发展历程
ROS是一个由来已久、贡献者众多的大型软件项目。在ROS诞生之前,很多学者认为,机器人研究需要一个开放式的协作框架,并且已经有不少类似的项目致力于实现这样的框架。在这些工作中,斯坦福大学在2000年年中开展了一系列相关研究项目,如斯坦福人工智能机器人(STandford AI Robot, STAIR)项目、个人机器人(Personal Robots, PR)项目等,在上述项目中,在研究具有代表性、集成式人工智能系统的过程中,创立了用于室内场景的高灵活性、动态软件系统,其可以用于机器人学研究。
2007年,柳树车库(Willow Garage)提供了大量资源,用于将斯坦福大学机器人项目中的软件系统进行扩展与完善,同时,在无数研究人员的共同努力下,ROS的核心思想和基本软件包逐渐得到完善。
ROS的发行版本(ROS distribution) 指ROS软件包的版本,其与Linux的发行版本(如Ubuntu)的概念类似。推出ROS发行版本的目的在于使开发人员可以使用相对稳定的代码库,直到其准备好将所有内容进行版本升级为止。因此,每个发行版本推出后,ROS开发者通常仅对这一版本的bug进行修复,同时提供少量针对核心软件包的改进。
版本特点: 按照英文字母顺序命名,ROS 目前已经发布了ROS1 的终极版本: noetic,并建议后期过渡至 ROS2 版本。noetic 版本之前默认使用的是 Python2,noetic 支持 Python3。
建议版本: noetic 或 melodic 或 kinetic
2 ROS安装
我使用的是 ROS 版本是 Melodic,那么可以在 ubuntu18.04、Mac 或 windows10 系统上安装,虽然一般用户平时使用的操作系统以windows居多,但是ROS之前的版本基本都不支持windows,所以当前我们选用的操作系统是 ubuntu,以方便向历史版本过渡。ubuntu安装常用方式有两种:
两种方式比较,各有优缺点:
- 方案1可以保证性能,且不需要考虑硬件兼容性问题,但是和windows系统交互不便;
- 方案2可以方便的实现 windows 与 ubuntu 交互,不过性能稍差,且与硬件交互不便。
🍑在 ROS 中,一些仿真操作是比较耗费系统资源的,且经常需要和一些硬件(雷达、摄像头、imu、STM32、arduino…)交互,因此,原则上建议采用方案1,不过如果只是出于学习目的,那么方案2也基本够用,且方案2在windows与ubuntu的交互上更为方便,对于学习者更为友好。当然,具体采用哪种实现方案,请按需选择。我选择的是安装双系统。🍎
如果采用虚拟机安装 ubuntu,再安装 ROS 的话,大致流程如下:
安装虚拟机软件(比如:virtualbox 或 VMware); 使用虚拟机软件虚拟一台主机; 在虚拟主机上安装 ubuntu 18.04; 在 ubuntu 上安装 ROS; 测试 ROS 环境是否可以正常运行。 虚拟机软件选择上,对于我们学习而言 virtualbox 和 VMware 都可以满足需求,二者比较,前者免费,后者收费,所以尽量选用 virtualbox。
2.1安装ubuntu
对应于ROS melodic版本,我们需要安装的是ubuntu18.04,具体安装教程网上有很多,建议选择访问量最高的那个。还有,不管是虚拟机还是双系统,ubuntu18.04的镜像文件一定要选好,这个影响到后面很多东西,有的镜像文件缺少东西,会出各种错误,什么都需要自己手动配置,为了减少不必要的麻烦,还是选择权威些的镜像文件。
2.2 安装 ROS
Ubuntu 安装完毕后,就可以安装 ROS 操作系统了,大致步骤如下:
- 配置ubuntu的软件和更新;
- 设置安装源;
- 设置key;
- 安装;
- 配置环境变量。
1.配置ubuntu的软件和更新
配置ubuntu的软件和更新,允许安装不经认证的软件。
首先打开“软件和更新”对话框,具体可以在 Ubuntu 搜索按钮中搜索。
打开后按照下图进行配置(确保勾选了"restricted", “universe,” 和 “multiverse.”) 2.设置安装源
官方默认安装源:
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
或来自国内清华的安装源
sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.tuna.tsinghua.edu.cn/ros/ubuntu/ `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list'
或来自国内中科大的安装源
sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.ustc.edu.cn/ros/ubuntu/ `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list'
PS: 回车后,可能需要输入管理员密码;建议使用国内资源,安装速度更快。
3.设置key
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
4.安装 首先需要更新 apt(以前是 apt-get, 官方建议使用 apt 而非 apt-get),apt 是用于从互联网仓库搜索、安装、升级、卸载软件或操作系统的工具。
sudo apt update
等待…
然后,再安装所需类型的 ROS:ROS 多个类型:Desktop-Full、Desktop、ROS-Base。这里介绍较为常用的Desktop-Full(官方推荐)安装: ROS, rqt, rviz, robot-generic libraries, 2D/3D simulators, navigation and 2D/3D perception
sudo apt install ros-melodic-desktop-full
等待…(比较耗时)
友情提示: 由于网络原因,导致连接超时,可能会安装失败,如下所示:
可以多次重复调用 更新 和 安装命令,直至成功。
5.环境设置 配置环境变量,方便在任意 终端中使用 ROS。
echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc
source ~/.bashrc
6.安装构建依赖 首先安装构建依赖的相关工具
sudo apt install python-rosdep python-rosinstall python-rosinstall-generator python-wstool build-essential
然后安装rosdep(可以安装系统依赖)
sudo apt install python-rosdep
初始化rosdep
sudo rosdep init
rosdep update
当执行到最后 sudo rosdep init 和rosdep时,绝大多数人都会抛出异常。因为境外资源被屏蔽,而且墙在今年4月份时候还被加高了,所以翻墙也很困难了。 这里给出解决方法:rosdep报错最有效方法 我参考这篇博客成功rosdep update!
卸载 如果需要卸载ROS可以调用如下命令:
sudo apt remove ros-melodic-*
另请参考:ROS wiki
2.3 测试 ROS
ROS 内置了一些小程序,可以通过运行这些小程序以检测 ROS 环境是否可以正常运行
- 首先启动三个命令行(ctrl + alt + T)
- 命令行1键入:roscore
- 命令行2键入:rosrun turtlesim turtlesim_node(此时会弹出图形化界面)
- 命令行3键入:rosrun turtlesim turtle_teleop_key(在3中可以通过上下左右控制2中乌龟的运动)
最终结果如下所示: 注意:光标必须聚焦在键盘控制窗口,否则无法控制乌龟运动。
3 ROS快速体验
编写 ROS 程序,在控制台输出文本: Hello World,分别使用 C++ 和 Python 实现。
3.1 HelloWorld实现简介
ROS中涉及的编程语言以C++和Python为主,ROS中的大多数程序两者都可以实现,在本系列教程中,每一个案例也都会分别使用C++和Python两种方案演示,大家可以根据自身情况选择合适的实现方案。
ROS中的程序即便使用不同的编程语言,实现流程也大致类似,以当前HelloWorld程序为例,实现流程大致如下:
- 先创建一个工作空间;
- 再创建一个功能包;
- 编辑源文件;
- 编辑配置文件;
- 编译并执行。
上述流程中,C++和Python只是在步骤3和步骤4的实现细节上存在差异,其他流程基本一致。本节先实现C++和Python程序编写的通用部分步骤1与步骤2,3.2节和3.3节再分别使用C++和Python编写HelloWorld。
1.创建工作空间并初始化
mkdir -p 自定义空间名称/src
cd 自定义空间名称
catkin_make
上述命令,首先会创建一个工作空间以及一个 src 子目录,然后再进入工作空间调用 catkin_make命令编译。
2.进入 src 创建 ros 包并添加依赖
cd src
catkin_create_pkg 自定义ROS包名 roscpp rospy std_msgs
上述命令,会在工作空间下生成一个功能包,该功能包依赖于 roscpp、rospy 与 std_msgs,其中roscpp是使用C++实现的库,而rospy则是使用python实现的库,std_msgs是标准消息库,创建ROS功能包时,一般都会依赖这三个库实现。
注意: 在ROS中,虽然实现同一功能时,C++和Python可以互换,但是具体选择哪种语言,需要视需求而定,因为两种语言相较而言:C++运行效率高但是编码效率低,而Python则反之,基于二者互补的特点,ROS设计者分别设计了roscpp与rospy库,前者旨在成为ROS的高性能库,而后者则一般用于对性能无要求的场景,旨在提高开发效率。
3.2 HelloWorld(C++版)
本节内容基于3.1,假设你已经创建了ROS的工作空间,并且创建了ROS的功能包,那么就可以进入核心步骤了,使用C++编写程序实现: 1.进入 ros 包的 src 目录编辑源文件
cd 自定义的包
C++源码实现(文件名自定义)
#include "ros/ros.h"
int main(int argc, char *argv[])
{
ros::init(argc,argv,"hello");
ros::NodeHandle n;
ROS_INFO("hello world!");
return 0;
}
2.编辑 ros 包下的 Cmakelist.txt文件
add_executable(步骤3的源文件名
src/步骤3的源文件名.cpp
)
target_link_libraries(步骤3的源文件名
${catkin_LIBRARIES}
)
3.进入工作空间目录并编译
cd 自定义空间名称
catkin_make
生成 build devel …
4.执行 先启动命令行1:
roscore
再启动命令行2:
cd 工作空间
source ./devel/setup.bash
rosrun 包名 C++节点
PS:source ~/工作空间/devel/setup.bash可以添加进.bashrc文件,使用上更方便
添加方式1: 直接使用 gedit 或 vi 编辑 .bashrc 文件,最后添加该内容
添加方式2:echo “source ~/工作空间/devel/setup.bash” >> ~/.bashrc
3.3 HelloWorld(Python版)
本节内容基于3.1,假设你已经创建了ROS的工作空间,并且创建了ROS的功能包,那么就可以进入核心步骤了,使用Python编写程序实现:
1.进入 ros 包添加 scripts 目录并编辑 python 文件
cd ros包
mkdir scripts
新建 python 文件: (文件名自定义)
"""
Python 版 HelloWorld
"""
import rospy
if __name__ == "__main__":
rospy.init_node("Hello")
rospy.loginfo("Hello World!!!!")
2.为 python 文件添加可执行权限
chmod +x 自定义文件名.py
3.编辑 ros 包下的 CamkeList.txt 文件
catkin_install_python(PROGRAMS scripts/自定义文件名.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
4.进入工作空间目录并编译
cd 自定义空间名称
catkin_make
5.进入工作空间目录并执行 先启动命令行1:
roscore
再启动命令行2:
cd 工作空间
source ./devel/setup.bash
rosrun 包名 自定义文件名.py
4 ROS集成开发环境搭建
和大多数开发环境一样,理论上,在 ROS 中,只需要记事本就可以编写基本的 ROS 程序,但是工欲善其事必先利其器,为了提高开发效率,可以先安装集成开发工具和使用方便的工具:终端、IDE…
4.1 安装终端
在 ROS 中,需要频繁的使用到终端,且可能需要同时开启多个窗口,推荐一款较为好用的终端:Terminator。效果如下: 1.安装
sudo apt install terminator
2.添加到收藏夹
显示应用程序 —> 搜索 terminator —> 右击 选择 添加到收藏夹
3.Terminator 常用快捷键
第一部分:关于在同一个标签内的操作
Alt+Up ???????????????????????????????????????????????????? //移动到上面的终端 Alt+Down ???????????????????????????????????????????????? //移动到下面的终端 Alt+Left ??????????????????????????????????????????????????? //移动到左边的终端 Alt+Right ????????????????????????????????????????????????? //移动到右边的终端 Ctrl+Shift+O ??????????????????????????????????????????????//水平分割终端 Ctrl+Shift+E ???????????????????????????????????????????????//垂直分割终端 Ctrl+Shift+Right ??????????????????????????????????????????//在垂直分割的终端中将分割条向右移动 Ctrl+Shift+Left ??????????????????????????????????????????? //在垂直分割的终端中将分割条向左移动 Ctrl+Shift+Up ?????????????????????????????????????????????//在水平分割的终端中将分割条向上移动 Ctrl+Shift+Down ????????????????????????????????????????//在水平分割的终端中将分割条向下移动 Ctrl+Shift+S ??????????????????????????????????????????????//隐藏/显示滚动条 Ctrl+Shift+F ??????????????????????????????????????????????//搜索 Ctrl+Shift+C ?????????????????????????????????????????????? //复制选中的内容到剪贴板 Ctrl+Shift+V ?????????????????????????????????????????????? //粘贴剪贴板的内容到此处 Ctrl+Shift+W ?????????????????????????????????????????????? //关闭当前终端 Ctrl+Shift+Q ???????????????????????????????????????????????//退出当前窗口,当前窗口的所有终端都将被关闭 Ctrl+Shift+X ???????????????????????????????????????????????//最大化显示当前终端 Ctrl+Shift+Z ???????????????????????????????????????????????//最大化显示当前终端并使字体放大 Ctrl+Shift+N or Ctrl+Tab ?????????????????????????????//移动到下一个终端 Ctrl+Shift+P or Ctrl+Shift+Tab ????????????????????//移动到之前的一个终端
第二部分:有关各个标签之间的操作
F11 ?????????????????????????????????????????????? //全屏开关 Ctrl+Shift+T ??????????????????????????????????//打开一个新的标签 Ctrl+PageDown ????????????????????????????//移动到下一个标签 Ctrl+PageUp ?????????????????????????????????//移动到上一个标签 Ctrl+Shift+PageDown ????????????????????//将当前标签与其后一个标签交换位置 Ctrl+Shift+PageUp ???????????????????????? //将当前标签与其前一个标签交换位置 Ctrl+Plus (+) ?????????????????????????????????? //增大字体 Ctrl+Minus (-) ???????????????????????????????? //减小字体 Ctrl+Zero (0) ???????????????????????????????? ? //恢复字体到原始大小 Ctrl+Shift+R??????????????????????????????????? //重置终端状态 Ctrl+Shift+G ??????????????????????????????????? //重置终端状态并clear屏幕 Super+g ??????????????????????????????????????????//绑定所有的终端,以便向一个输入能够输入到所有的终端 Super+Shift+G ????????????????????????????????//解除绑定 Super+t ????????????????????????????????????????? //绑定当前标签的所有终端,向一个终端输入的内容会自动输入到其他终端 Super+Shift+T???????????????????????????????? //解除绑定 Ctrl+Shift+I?????????????????????????????????????//打开一个窗口,新窗口与原来的窗口使用同一个进程 Super+i?????????????????????????????????????????? //打开一个新窗口,新窗口与原来的窗口使用不同的进程
4.2 安装VScode
VSCode 全称 Visual Studio Code,是微软出的一款轻量级代码编辑器,免费、开源而且功能强大。它支持几乎所有主流的程序语言的语法高亮、智能代码补全、自定义热键、括号匹配、代码片段、代码对比 Diff、GIT 等特性,支持插件扩展,并针对网页开发和云端应用开发做了优化。软件跨平台支持 Win、Mac 以及 Linux。 1.下载 vscode 下载:https://code.visualstudio.com/docs?start=true 历史版本下载链接: https://code.visualstudio.com/updates
2.vscode 安装与卸载
🍖2.1 安装
方式1:双击安装即可(或右击选择安装)
方式2:sudo dpkg -i xxxx.deb
🍗2.2 卸载
sudo dpkg --purge code
3.vscode 集成 ROS 插件 使用 VScode 开发 ROS 程序,需要先安装一些插件,根据个人编程习惯下载。
4.vscode 使用_基本配置 🍔4.1 创建 ROS 工作空间
mkdir -p xxx_ws/src(必须得有 src)
cd xxx_ws
catkin_make
🍟 4.2 启动 vscode
进入 xxx_ws 启动 vscode
cd xxx_ws
code .
🌭4.3 vscode 中编译 ros
快捷键 ctrl + shift + B 调用编译,选择:catkin_make:build 可以点击配置设置为默认,修改.vscode/tasks.json 文件
{
// 有关 tasks.json 格式的文档,请参见
// https://go.microsoft.com/fwlink/?LinkId=733558
"version": "2.0.0",
"tasks": [
{
"label": "catkin_make:debug", //代表提示的描述性信息
"type": "shell", //可以选择shell或者process,如果是shell代码是在shell里面运行一个命令,如果是process代表作为一个进程来运行
"command": "catkin_make",//这个是我们需要运行的命令
"args": [],//如果需要在命令后面加一些后缀,可以写在这里,比如-DCATKIN_WHITELIST_PACKAGES=“pac1;pac2”
"group": {"kind":"build","isDefault":true},
"presentation": {
"reveal": "always"//可选always或者silence,代表是否输出信息
},
"problemMatcher": "$msCompile"
}
]
}
🍕4.4 创建 ROS 功能包 选定 src 右击 —> create catkin package 设置包名 添加依赖
🍝4.5 C++ 实现 在功能包的 src 下新建 cpp 文件
#include "ros/ros.h"
int main(int argc, char *argv[])
{
setlocale(LC_ALL,"");
ros::init(argc,argv,"HelloVSCode");
ROS_INFO("Hello VSCode!!!哈哈哈哈哈哈哈哈哈哈");
return 0;
}
🐶PS1: 如果没有代码提示
修改 .vscode/c_cpp_properties.json
设置 “cppStandard”: “c++17”
🐭PS2: main 函数的参数不可以被 const 修饰
🐱PS3: 当ROS__INFO 终端输出有中文时,会出现乱码
INFO: ????????????????????????
解决办法:在函数开头加入下面代码的任意一句
setlocale(LC_CTYPE, "zh_CN.utf8");
setlocale(LC_ALL, "");
🌮4.6 python 实现 在 功能包 下新建 scripts 文件夹,添加 python 文件,并添加可执行权限
#! /usr/bin/env python
"""
Python 版本的 HelloVScode,执行在控制台输出 HelloVScode
实现:
1.导包
2.初始化 ROS 节点
3.日志输出 HelloWorld
"""
import rospy
if __name__ == "__main__":
rospy.init_node("Hello_Vscode_p")
rospy.loginfo("Hello VScode, 我是 Python ....")
🍜4.7 配置 CMakeLists.txt C++ 配置:
add_executable(节点名称
src/C++源文件名.cpp
)
target_link_libraries(节点名称
${catkin_LIBRARIES}
)
Python 配置:
catkin_install_python(PROGRAMS scripts/自定义文件名.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
🍛 4.8 编译执行 编译: ctrl + shift + B
执行: 和之前一致,只是可以在 VScode 中添加终端,首先执行:source ./devel/setup.bash
PS:如果不编译直接执行 python 文件,会抛出异常。
1.第一行解释器声明,可以使用绝对路径定位到 python3 的安装路径 #! /usr/bin/python3,但是不建议
2.建议使用 #!/usr/bin/env python 但是会抛出异常 : /usr/bin/env: “python”: 没有那个文件或目录
3.解决1: #!/usr/bin/env python3 直接使用 python3 但存在问题: 不兼容之前的 ROS 相关 python 实现
4.解决2: 创建一个链接符号到 python 命令:sudo ln -s /usr/bin/python3 /usr/bin/python
5.其他 IDE ROS 开发可以使用的 IDE 还是比较多的,除了上述的 VScode,还有 Eclipse、QT、PyCharm、Roboware …,详情可以参考官网介绍:http://wiki.ros.org/IDEs
QT Creator Plugin for ROS,参考教程:https://ros-qtc-plugin.readthedocs.io/en/latest/ Roboware 参考:http://www.roboware.me/#/
4.3 launch文件演示
1.需求
一个程序中可能需要启动多个节点,比如:ROS 内置的小乌龟案例,如果要控制乌龟运动,要启动多个窗口,分别启动 roscore、乌龟界面节点、键盘控制节点。如果每次都调用 rosrun 逐一启动,显然效率低下,如何优化?
官方给出的优化策略是使用 launch 文件,可以一次性启动多个 ROS 节点。 2.实现
- 选定功能包右击 —> 添加 launch 文件夹
- 选定 launch 文件夹右击 —> 添加 launch 文件
- 编辑 launch 文件内容
<launch>
<node pkg="helloworld" type="demo_hello" name="hello" output="screen" />
<node pkg="turtlesim" type="turtlesim_node" name="t1"/>
<node pkg="turtlesim" type="turtle_teleop_key" name="key1" />
</launch>
🐹node —> 包含的某个节点
🐰pkg -----> 功能包
🐻type ----> 被运行的节点文件
🐼name --> 为节点命名
🐨output-> 设置日志的输出目标
- 运行 launch 文件
roslaunch 包名 launch文件名
- 运行结果: 一次性启动了多个节点
5 ROS架构
到目前为止,我们已经安装了ROS,运行了ROS中内置的小乌龟案例,并且也编写了ROS小程序,对ROS也有了一个大概的认知,当然这个认知可能还是比较模糊并不清晰的,接下来,我们要从宏观上来介绍一下ROS的架构设计。
立足不同的角度,对ROS架构的描述也是不同的,一般我们可以从设计者、维护者、系统结构与自身结构4个角度来描述ROS结构:
1.设计者 ROS设计者将ROS表述为“ROS = Plumbing + Tools + Capabilities + Ecosystem”
-
Plumbing: 通讯机制(实现ROS不同节点之间的交互) -
Tools :工具软件包(ROS中的开发和调试工具) -
Capabilities :机器人高层技能(ROS中某些功能的集合,比如:导航) -
Ecosystem:机器人生态系统(跨地域、跨软件与硬件的ROS联盟)
2.维护者 立足维护者的角度: ROS 架构可划分为两大部分
- main:核心部分,主要由Willow Garage和一些开发者设计、提供以及维护。它提供了一些分布式计算的基本工具,以及整个ROS的核心部分的程序编写。
- universe:全球范围的代码,有不同国家的ROS社区组织开发和维护。一种是库的代码,如OpenCV、PCL等;库的上一层是从功能角度提供的代码,如人脸识别,他们调用下层的库;最上层的代码是应用级的代码,让机器人完成某一确定的功能。
3.系统架构 立足系统架构: ROS 可以划分为三层
-
OS 层,也即经典意义的操作系统 ROS 只是元操作系统,需要依托真正意义的操作系统,目前兼容性最好的是 Linux 的 Ubuntu,Mac、Windows 也支持ROS 的较新版本。 -
中间层 是 ROS 封装的关于机器人开发的中间件,比如: 基于 TCP/UDP 继续封装的 TCPROS/UDPROS 通信系统 用于进程间通信 Nodelet,为数据的实时性传输提供支持 另外,还提供了大量的机器人开发实现库,如:数据类型定义、坐标变换、运动控制… -
应用层 功能包,以及功能包内的节点,比如: master、turtlesim的控制与运动节点…
4.自身结构 就 ROS 自身实现而言: 也可以划分为三层
-
文件系统 ROS文件系统级指的是在硬盘上面查看的ROS源代码的组织形式 -
计算图 ROS 分布式系统中不同进程需要进行数据交互,计算图可以以点对点的网络形式表现数据交互过程,计算图中的重要概念: 节点(Node)、消息(message)、通信机制_主题(topic)、通信机制_服务(service) -
开源社区 ROS的社区级概念是ROS网络上进行代码发布的一种表现形式
5.1 ROS文件系统
ROS文件系统级指的是在硬盘上ROS源代码的组织形式,其结构大致可以如下图所示:
WorkSpace --- 自定义的工作空间
|--- build:编译空间,用于存放CMake和catkin的缓存信息、配置信息和其他中间文件。
|--- devel:开发空间,用于存放编译后生成的目标文件,包括头文件、动态&静态链接库、可执行文件等。
|--- src: 源码
|-- package:功能包(ROS基本单元)包含多个节点、库与配置文件,包名所有字母小写,只能由字母、数字与下划线组成
|-- CMakeLists.txt 配置编译规则,比如源文件、依赖项、目标文件
|-- package.xml 包信息,比如:包名、版本、作者、依赖项...(以前版本是 manifest.xml)
|-- scripts 存储python文件
|-- src 存储C++源文件
|-- include 头文件
|-- msg 消息通信格式文件
|-- srv 服务通信格式文件
|-- action 动作格式文件
|-- launch 可一次性运行多个节点
|-- config 配置信息
|-- CMakeLists.txt: 编译的基本配置
ROS 文件系统中部分目录和文件前面编程中已经有所涉及,比如功能包的创建、src目录下cpp文件的编写、scripts目录下python文件的编写、launch目录下launch文件的编写,并且也配置了 package.xml 与 CMakeLists.txt 文件。其他目录下的内容后面教程将会再行介绍,当前我们主要介绍: package.xml 与 CMakeLists.txt 这两个配置文件。
1.package.xml
该文件定义有关软件包的属性,例如软件包名称,版本号,作者,维护者以及对其他catkin软件包的依赖性。请注意,该概念类似于旧版 rosbuild 构建系统中使用的manifest.xml文件。
?<?xml version="1.0"?>
<package format="2">
<name>demo01_hello_vscode</name>
<version>0.0.0</version>
<description>The demo01_hello_vscode package</description>
<maintainer email="xuzuo@todo.todo">xuzuo</maintainer>
<license>TODO</license>
<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>
<export>
</export>
</package>
2.CMakelists.txt
文件CMakeLists.txt是CMake构建系统的输入,用于构建软件包。任何兼容CMake的软件包都包含一个或多个CMakeLists.txt文件,这些文件描述了如何构建代码以及将代码安装到何处。
?cmake_minimum_required(VERSION 3.0.2) #所需 cmake 版本
project(demo01_hello_vscode) #包名称,会被 ${PROJECT_NAME} 的方式调用
## 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
# 启动 python 模块支持
# catkin_python_setup()
################################################
## Declare ROS messages, services and actions ##
## 声明 ROS 消息、服务、动作... ##
################################################
## 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 ##
## 声明 ROS 动态参数配置 ##
################################################
## 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 ##
## catkin 特定配置##
###################################
## 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 demo01_hello_vscode
# 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
# 声明 C++ 库
# add_library(${PROJECT_NAME}
# src/${PROJECT_NAME}/demo01_hello_vscode.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
# 添加库的 cmake 目标依赖
# 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
# 声明 C++ 可执行文件
add_executable(Hello_VSCode src/Hello_VSCode.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"
#重命名c++可执行文件
# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
## Add cmake target dependencies of the executable
## same as for the library above
#添加可执行文件的 cmake 目标依赖
add_dependencies(Hello_VSCode ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
## Specify libraries to link a library or executable target against
#指定库、可执行文件的链接库
target_link_libraries(Hello_VSCode
${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/Hi.py
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_demo01_hello_vscode.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)
5.2 ROS文件系统相关命令
ROS 的文件系统本质上都还是操作系统文件,我们可以使用Linux命令来操作这些文件,不过,在ROS中为了更好的用户体验,ROS专门提供了一些类似于Linux的命令,这些命令较之于Linux原生命令,更为简介、高效。文件操作,无外乎就是增删改查与执行等操作,接下来,我们就从这五个维度,来介绍ROS文件系统的一些常用命令。 1.增
catkin_create_pkg 自定义包名 依赖包 === 创建新的ROS功能包
sudo apt install xxx === 安装 ROS功能包
2.删
sudo apt purge xxx ==== 删除某个功能包
3.查
rospack list === 列出所有功能包
rospack find 包名 === 查找某个功能包是否存在,如果存在返回安装路径
roscd 包名 === 进入某个功能包
rosls 包名 === 列出某个包下的文件
apt search xxx === 搜索某个功能包
4.改
rosed 包名 文件名 === 修改功能包文件
需要安装 vim
比如:rosed turtlesim Color.msg
5.执行 ??5.1 roscore roscore 是 ROS 的系统先决条件节点和程序的集合, 必须运行 roscore 才能使 ROS 节点进行通信。
roscore 将启动:
-
ros master -
ros 参数服务器 -
rosout 日志节点
用法:
roscore
或(指定端口号)
roscore -p xxxx
🏀5.2 rosrun rosrun 包名 可执行文件名 === 运行指定的ROS节点
比如:rosrun turtlesim turtlesim_node
🏓5.3 roslaunch roslaunch 包名 launch文件名 === 执行某个包下的 launch 文件
5.3 ROS计算图
1.计算图简介 前面介绍的是ROS文件结构,是磁盘上 ROS 程序的存储结构,是静态的,而 ros 程序运行之后,不同的节点之间是错综复杂的,ROS 中提供了一个实用的工具:rqt_graph。
rqt_graph能够创建一个显示当前系统运行情况的动态图形。ROS 分布式系统中不同进程需要进行数据交互,计算图可以以点对点的网络形式表现数据交互过程。rqt_graph是rqt程序包中的一部分。 2.计算图安装 如果前期把所有的功能包(package)都已经安装完成,则直接在终端窗口中输入
rosrun rqt_graph rqt_graph
如果未安装则在终端(terminal)中输入
$ sudo apt install ros-<distro>-rqt
$ sudo apt install ros-<distro>-rqt-common-plugins
请使用你的ROS版本名称(比如:kinetic、melodic、Noetic等)来替换掉。
例如当前版本是 melodic,就在终端窗口中输入
$ sudo apt install ros-melodic-rqt
$ sudo apt install ros-melodic-rqt-common-plugins
3.计算图演示
接下来以 ROS 内置的小乌龟案例来演示计算图
首先,按照前面所示,运行案例
然后,启动新终端,键入: rqt_graph 或 rosrun rqt_graph rqt_graph,可以看到类似下图的网络拓扑图,该图可以显示不同节点之间的关系。
6 本章小结
本章内容主要介绍了ROS的相关概念、设计目标、发展历程等理论知识,安装了 ROS 并搭建了 ROS 的集成开发环境,编写了第一个 ROS小程序,对ROS实现架构也有了宏观的认识。ROS的大门已经敞开,接下来就要步入新的征程了。
学习是一个循序渐进的过程,具体到计算机领域的软件开发层面,每当接触一个新的知识模块时,按照一般的步骤,我们会先去了解该模块的相关概念,然后再安装官方软件包,接下来再搭建其集成的开发环境…这些准备工作完毕之后,才算是叩开了新领域的大门。
|