先学python还是ros_如何学习Ros?
不邀自来~~
题主从未有过机器人方面的学习,因此,我邀请了从其他部门转岗过来的RD小哥过来回答这个问题,小哥在来无人配送之前是美团基础研发的同学,以前没有学过ROS,也没有做过机器人,应该和题主的情况比较相似,以下为RD小哥写的学习教程,希望对题主有所帮助。
万字长文警告!本文包含了详细的学习模块、资料和介绍,先收藏食用更佳
目录
1. 前言
2. 待学习的模块
2.1 操作系统
2.2 编程语言
2.3 ROS概述
2.4 ROS模块
3. 总结
以下为正文:
1. 前言
ROS(Robot Operating System)是应用在机器人领域里的一套开源软件框架和工具,旨在帮助研究、开发人员能够聚焦在具体的算法研究和应用开发中,而无需过多关注和算法应用不太相关的系统层次,帮助研究人员快速实现具体功能。ROS是一套开源的构建在操作系统之上的中间件系统,提供完整的系统功能库、调试工具。
2. 待学习的模块
2.1 操作系统
ROS默认建议使用Ubuntu和Centos操作系统,当然也支持Mac OS、OpenEmbedded、Arch Linux等。在学习ROS之前,需要选择一个可用的操作系统并熟悉掌握它。建议使用Ubuntu操作系统,这是ROS大部分使用者选择的,对于后期遇到的问题和一些公用库能够更好地支持。
对于操作系统,需要做到下面几个掌握程度:掌握安装过程:
这是基本能力,在开发和研究过程中,很大程度会出现将电脑弄崩溃的情况,这时候掌握安装知识就显得很必要了;
掌握基本操作指令:
不管使用哪个操作系统,基本的操作指令都必须掌握。以Ubuntu为例,需要掌握基本的命令行操作(包括文件目录操作、软件库管理、文件编辑、配置管理等),建议参Ubuntu桌面操作指南;
掌握基本的编程工具使用:
掌握基本的编程工具使用,强制要求掌握python和C/C++这两类语言的编程工具,包括gcc、cmake等;
掌握依赖库管理:
掌握对应操作系统依赖库的管理,包括安装、升级、卸载等,掌握从源码安装依赖库的方法,掌握编程需要的环境变量配置方式。
对于操作系统,了解掌握得越深,对于后面的学习越有帮助,建议详细并深入地学习操作系统方面的知识,当然简单掌握上面的知识点也可以进行下面的学习。
2.2 编程语言
ROS框架的主要编程语言为C/C++和python,可能在应用开发中需要用到类似shell等语言知识,但是主要的开发语言是C/C++和python,所以C/C++和python语言的掌握程度决定了ROS的掌握程度。
C++的学习和掌握建议看《C++ Primer》,python的学习建议直接通W3C来学习。
2.3 ROS概述
▍2.3.1 起源
ROS的产生验证了一句话:需求推动进度。在10年前,要想开发机器人类的应用,基本上研发人员需要将前人的工作全部做一遍:驱动、通信、交互、算法和应用。2007年,Morgan Quigley在自己的STAIR项目中发现对于机器人应用,各个模块其实很大程度并不相关,可以同步进行,如机械臂操作、激光处理等,于是他在这个项目中采用这种分布式处理的方法,并在项目结束后发表了这一理念:《STAIR: Hardware and Software Architecture》,这一理念的名称是Switchyard,也就是我们ROS的前身。后来在2009年,在Switchyard基础上开发完善了ROS系统,并正式对外发布,这就是ROS的起源。
ROS的产生极大的减少了重复工作量,也让研发人员更多地关注在自身的应用上。
▍2.3.2 特点
ROS的设计目标就是分布式系统,它的特点包含了下面几种:
1. 支持多计算节点部署
由于ROS通过TCP/UDP来实现数据之间的交互,所以可以将整个系统切分到多个计算节点上,不同计算节点负责不同的应用功能模块。
2. 丰富的工具
ROS官方提供了丰富的开发、编译、调试工具,极大地方便了开发和调试过程。如统一编译工具catkin、算法综合调试工具rviz、rqt等。
3. 丰富的开源库
提供了开源的软件库管理,全世界的开发者都可以共享各类驱动、算法、应用上的成果。
4. 多语言支持
当前ROS应用开发可以使用C/C++、Python、Lisp等。
▍2.3.3 现状
由于ROS是在2007年确定技术框架,当时选择了主流的框架、通信机制等,但是在技术演进快速的年代,新技术、新需求、新场景会很快让原先的框架实现陷入瓶颈或遇到技术障碍。鉴于机器人实时性、安全性、交互性、高数据量传输要求,ROS自身已经很难满足一些场景的要求,尽管有很多大厂和开源贡献者做了相应的改造,但是针对ROS自身改造的呼声也愈来愈高,最终ROS官方在2017年12月8号发布了ROS 2.0的第一个正式版本。在这个新版本中,众多的新技术和新概念被应用进来,可以说是完全颠覆了原先的框架设计,带来了更高更强的处理性能。
ROS2.0作为一个全新的框架,和原先的ROS基本完全不一样,可以作为一个新的事物对待,当前ROS2.0还在开发过程中,当然已有稳定版本可用,具体想了解可以参考https://github.com/ros2/ros2/wiki
2.4 ROS模块
ROS模块的学习可以参考官方教程,教程中基本上涵盖了安装、基本功能应用、原理、工具使用等各个方面的知识,官方教程链接见:http://wiki.ros.org/cn,大部分都有中文版,不影响学习。
从学习ROS的角度,掌握下面基础知识,提升对ROS的理解和认知。这里将会在Ubuntu系统上介绍下面的各个部分。
▍2.4.1 安装管理
ROS当前很有多版本,官方会对Ubuntu系统提供默认的长期支持版本,这些版本更稳定,当然也可以安装最新的版本,最新的版本会快速推出新的功能,可能存在一些问题和未解决的Bug。
ROS是一个开源软件,所有的软件源码在github上维护,可以通过https://github.com/ros来查找所有模块的源码。整个ROS从模块上拆分,可以分为下面几个部分:核心模块,包含各类语言的功能实现,通信上的处理;
编译系统,提供完整的编译功能,包含各类语言的处理;
工具系统,提供各类工具,如rostopic、rviz、rqt等;
应用功能包,为其他第三方提供的优质功能应用,一般都是开源可用的。
ROS官方只提供前三者的源码管理和更新,不提供任何应用功能,应用功能一般都是由第三方开发者提供和维护,例如各类传感器厂商、研究所、高校、企业等,会针对自身的一些实现做相关的开源。在学习过程中,对于这些模块可以拿来直接使用,我们只需要掌握如何去安装他们就行。
以Ubuntu为例,一个完整的安装过程如下:
#!/bin/bash
配置ubuntu的安装源
sudo sh -c 'echo "deb http://mirrors.ustc.edu.cn/ros/ubuntu/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116
sudo apt-get update
安装ROS功能模块,这里有多种选择,如果自身的电脑支持显卡,可以安装完整桌面版本;如果只是一个服务器,那么建议安装基础版本
sudo apt-get install ros-kinetic-desktop-full # 桌面完整版
sudo apt-get install ros-kinetic-desktop # 桌面版
sudo apt-get install ros-kinetic-ros-base # 基础版
在开始使用ROS之前你还需要初始化rosdep。rosdep可以方便在你需要编译某些源码的时候为其安装一些系统依赖,同时也是某些ROS核心功能组件所必需用到的工具。
sudo rosdep init
rosdep update
完成上面的步骤,基本上ROS已经成功安装在你的电脑中,接下来就是使用它
在使用之前,我们需要配置系统环境,默认ROS已经给我们准备好了配置脚本,一般位于 /opt/ros/${ROS_DISTRO}/setup.bash,将其加入到 .bashrc 启动配置脚本中即可
执行 echo "source /opt/ros/{ROS_DISTRO}/setup.bash" >> ~/.bashrc,需要注意 {ROS_DISTRO} 是安装的ROS版本名称。
▍2.4.2 经典ros应用 -- 小乌龟
开始ROS学习的第一个应用可以是ROS吉祥物移动应用。每个版本的ROS都是以不同种类的乌龟作为logo,同时也提供了一个应用软件包,通过下面来安装启动小乌龟吧。
#!/bin/bash 
安装ros turtlesim sudo apt-get install ros-$(rosversion -d)-turtlesim 
安装完成后,即可以通过下面的命令来启动小乌龟 rosrun turtlesim turtlesim_node
如下图所示
接下来可以通过 rosrun turtlesim turtle_teleop_key 来启动指令控制器,控制小乌龟上下左右运动。
▍2.4.3 ROS环境变量配置及说明
ROS是依赖于某种组合空间的概念,而这种概念就是通过配置环境变量来实现的,这一机制可以让针对不同版本或者不同软件包集的开发更加容易。不管你要运行的应用来自哪里:从网上下载安装的第三方开发应用,或者是ROS自身提供,或者是自己编码实现的,必然有其自身的环境变量配置脚本(类似setup.*sh的文件),一般都是在安装目录下,如/opt/ros/${ROS_DISTRO}/setup.*sh。所有的环境变量配置都可以通过这些脚本来完成,无需自己额外配置。
通过source命令启动了配置脚本,可以通过命令 export | grep ROS 来查看配置的环境变量。
▍2.4.4 ROS文件系统
学习ROS需要了解ROS的文件系统,也就是ROS代码工作空间。整个ROS可以理解为下面的一个概念图:
整个ROS通过组合空间的概念将应用分布在不同的地方,通过环境变量和文件系统工具完成定位和管理。每一个工作空间就是我们常见的代码编辑、编译、链接的地方,每一个软件包就是我们想要实现功能的地方。
在ROS软件包中,有两个概念:Packages: 软件包,是ROS应用程序代码的组织单元,每个软件包都可以包含程序库、可执行文件、脚本或者其它手动创建的东西。
Manifest (package.xml): 清单,是对于'软件包'相关信息的描述,用于定义软件包相关元信息之间的依赖关系,这些信息包括版本、维护者和许可协议等。
在整个ROS文件系统中,主要通过软件包的Manifest来完成程序的定位和运行,所以软件包在整个文件系统中是命名唯一的。
ROS提供了多个文件系统工具集,如rospack、roscd和rosls。具体的功能建议直接在文件系统中使用,大致的功能:rospack:允许你获取软件包的有关信息,如rospack find roscpp
roscd:是rosbash命令集中的一部分,它允许你直接切换工作目录到某个软件包或者软件包集当中。如roscd roscpp
rosls:是rosbash命令集中的一部分,它允许你直接按软件包的名称而不是绝对路径执行ls命令(罗列目录)。
▍2.4.5 ROS topic/message机制
topic/message是ROS中一种主要的通信和数据交互机制,主要用于不同的进程之间。ROS在自身系统中会维护一个topic列表,对于新注册的节点,它会主动去查询该节点是否有自身的topic list,如果有会统一加入到维护的topic列表中。可以将topic理解为一种通信管道,管道两侧有数据的发布者和数据的接收者。如图:
Topic必然是单向的,一方创造数据,一方消费数据,而在其中流动的就是ROS message。ROS提供了自身的数据类型定义(可以参考官网),提供了基础类型(int、double、string等)和组合类型,需要开发者在应用开发中根据需要配置和使用。
▍2.4.6 ROS request/response机制
request/response机制有点类似网络开发过程中的网络请求机制,两者在原理上基本一致,如果你理解网络开发中request/response,那么ROS中提供了同样的逻辑。
▍2.4.7 ROS标准软件包开发示例
一个完整的ROS软件包开发需要完成下面的步骤:创建工作空间
创建ROS软件包
创建并实现ROS功能节点
声明并定义topic/message对,实现具体的数据生产和解析功能
声明并定义request/response对,实现数据解析功能
编写并实现功能
配置启动项,编写启动脚本等
下面以一个基本的实例来分步骤说明。
┃2.4.7.1 创建工作空间
通过下面的命令来完成工作空间的创建:
#!/bin/bash
source /opt/ros/kinetic/setup.bash
创建一个自己的目录
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/
编译空工作空间以启用
catkin_make
这样一个工作空间 catkin_ws 就创建完成,可以看到目录下有src(源码目录)、devel(开发编译目录)、build(编译中间目录)和install(目标程序生成目录)
┃2.4.7.2 创建ROS软件包
通过下面的命令来完成一个独立的软件包的创建:
#!/bin/bash
source /opt/ros/kinetic/setup.bash
cd ~/catkin_ws/src
通过catkin_create_pkg工具来完成软件的创建,使用这样的工具来创建的好处在于:
1. 可以帮你自动生成和功能实现无关的内容,如package.xml文件等
2. 可以自动生成编译模板,同时通过参数来指定本软件包的依赖项
catkin_create_pkg beginner_tutorials std_msgs rospy roscpp
当前软件包名称为beginner_tutorials,其中创建命令中的 std_msgs rospy roscpp 为当前包依赖项,分别是标准message包 std_msgs,python语言包 rospy,c++语言包 roscpp
这样一个名为beginner_tutorials的软件包就被我们创建成功。
当然,你也可以不通过catkin_create_pkg工具来创建软件包,也可以通过手动为编译需要的文件,具体可以参考http://wiki.ros.org/cn/ROS/Tutorials/CreatingPackage。
┃2.4.7.3 创建并实现ROS功能节点
首先我们需要理解什么是ROS功能节点,在解释这个之前,我们需要了解C++程序开发流程,一个完整的C++程序开发包含了:代码编辑、代码编译、库链接、生成可执行程序。ROS的功能节点从逻辑上就是一个C++的可执行程序,这样说来ROS功能节点也会经历C++可执行程序的所有步骤。
ROS所有的功能都是必然在ROS功能节点中完成:创建消息、发布消息、发送请求等。
ROS节点可以使用ROS通信库与其他节点通信,节点可以发布或接收一个topic,节点也可以提供或使用某种服务。
那么如何来创建一个ROS节点呢?这视使用的开发语言来定,这里分别以python和C++来创建一个功能节点:
#include "ros/ros.h"
int main(int argc, char **argv)
{
// 初始化一个节点,通过ros::init来完成,当前节点名称为talker ros::init(argc, argv, "talker");
ros::NodeHandle n;
ros::Rate loop_rate(10);
while (ros::ok())
{
ROS_INFO("This is in one ros node.");
ros::spinOnce();
loop_rate.sleep();
}
return 0;
}
#!/usr/bin/env pythonimport rospy
def talker():
rate = rospy.Rate(10) # 10hz
while not rospy.is_shutdown():
rospy.loginfo("this is in ros node.")
rate.sleep()
def main():
rospy.init_node('talker', anonymous=True)
talker()
if name == 'main':
try:
main()
except rospy.ROSInterruptException:
pass
║2.4.7.4 功能实现
ROS软件包的功能实现一方面是算法上的实现,另一方面就是包与包之间的数据交互。算法上的实现属于开发者需要关注的,对于数据交互来说,ROS提供了多种机制,包括:topic/message、request/response和共享内存nodelets。大部分的应用使用更多的是topic/message机制和request/response机制,这里以这一机制来具体讲解下使用方法。 如果想在ROS应用中进行数据交互,第一步需要定义ROS消息和服务消息(msg): msg文件就是一个描述ROS中所使用消息类型的简单文本,它们会被用来生成不同语言的源代码。
服务(srv): 一个srv文件描述一项服务。它包含两个部分:请求和响应。
msg文件存放在package的msg目录下,srv文件则存放在srv目录下,编译系统会自动查找这两个目录下的定义和声明。
下面,我们将在之前创建的软件包里定义新的消息。
#!/bin/bash
cd~/catkin_ws/src/beginner_tutorials
mkdir msg
echo"int64 num" > msg/Num.msg
上面是最简单的例子:在.msg文件中只有一行数据。接下来,还有关键的一步:我们要确保msg文件被转换成为C++,Python和其他语言的源代码:
查看package.xml, 确保它包含一下两条语句:
message_generation
message_runtime
如果没有,添加进去。 注意,在构建的时候,我们只需要"message_generation"。然而,在运行的时候,我们只需要"message_runtime"。
编辑CMakeLists.txt文件
在 CMakeLists.txt文件中,利用find_packag函数,增加对message_generation的依赖,这样就可以生成消息了。
你可以直接在COMPONENTS的列表里增加message_generation,就像这样:
find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation)
同样,你需要确保你设置了运行依赖:
catkin_package( ... CATKIN_DEPENDS message_runtime ... ...)
找到如下代码块:
add_message_files( # FILES # Message1.msg # Message2.msg # )
去掉注释符号#,用你的.msg文件替代Message*.msg,就像下边这样:
add_message_files( FILES Num.msg )
手动添加.msg文件后,我们要确保CMake知道在什么时候重新配置我们的project。 确保添加了如下代码:
generate_messages()
现在,你可以生成自己的消息源代码了
这样通过catkin_make就能编译生成可用的依赖库。同样的思路可以创建srv,建议详细参考其官方文档。
当完成msg和srv创建后,我们即可在编程中使用到对应的msg和srv。以上面定义的Num.msg为例,下面给出发布者和订阅者的C++和python实现:
// 发布者代码#include "ros/ros.h"#include "beginner_tutorials/Num.h"
int main(int argc, char **argv)
{
ros::init(argc, argv, "talker");
ros::NodeHandle n;
ros::Publisher chatter_pub = n.advertise<:num>("chatter", 1000);
ros::Rate loop_rate(10);
int number = 0;
while (ros::ok())
{
beginner_tutorials::Num msg;
msg.num = number;
ROS_INFO("talk data is %d", msg.num);
chatter_pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();
++number;
}
return 0;
}
// 订阅者#include "ros/ros.h"#include "beginner_tutorials/Num.h"
void chatterCallback(const beginner_tutorials::Num::ConstPtr& msg)
{
ROS_INFO("I heard: [%d]", msg->num);
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "listener");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
ros::spin();
return 0;
}
发布者代码
#!/usr/bin/env python
import rospy
from beginner_tutorials.msg import Num
def talker():
pub = rospy.Publisher('chatter', Num, queue_size=10)
rate = rospy.Rate(10) # 10hz
number = 0
while not rospy.is_shutdown():
msg = Num()
msg.num = number
pub.publish(msg)
rospy.loginfo("talk data%d", msg.num)
rate.sleep()
number += 1
def main():
rospy.init_node('talker', anonymous=True)
talker()
if name == 'main':
try:
main()
except rospy.ROSInterruptException:
pass
订阅者
import rospy
from beginner_tutorials.msg import Num
def callback(data):
rospy.loginfo(rospy.get_caller_id() + "I heard%s", data.num)
def listener():
rospy.init_node('listener', anonymous=True)
rospy.Subscriber("chatter", Num, callback)
rospy.spin()
if name == 'main':
listener()
一般来说,针对不同进程间的通信,使用topic/messge或者request/response更简便,如果对于延时要求更高的,建议使用nodelets机制,具体的使用说明参考其官方说明。
▍2.4.8 机器人开发通用库 -- navigation
navigation是一套软件框架,从传感器数据处理、定位、规划和控制,完整地提供了一整套的机器人开发软件框架,对于研究者和初学者是一个不错的练手工具。具体的介绍和使用可以参考下面的几个链接:
3. 总结
ROS本身作为一套学习框架,对于软件开发人员来说并不是很难理解,掌握了原理后,上手是很快的。从我的角度来看,学习ROS本身就是一次不断练习的过程,只有在实践中才能更深层次地理解它。
作者:系统组
出处:美团无人配送
你这么好看,一定会点赞~~
