您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center   Code  
会员   
   
 
     
   
 
 订阅
如何学习ROS?
 
作者:系统组
   次浏览      
2022-1-21
 
编辑推荐:
本文从学习ROS的角度,掌握下面基础知识,提升对ROS的理解和认知。这里将会在Ubuntu系统上介绍下面的各个部分,希望对您的学习有所帮助。
本文来自于知乎,由火龙果软件Alice编辑、推荐。

1. 前言

ROS(Robot Operating System)是应用在机器人领域里的一套开源软件框架和工具,旨在帮助研究、开发人员能够聚焦在具体的算法研究和应用开发中,而无需过多关注和算法应用不太相关的系统层次,帮助研究人员快速实现具体功能。ROS是一套开源的构建在操作系统之上的中间件系统,提供完整的系统功能库、调试工具。

2. 待学习的模块

2.1 操作系统

ROS默认建议使用Ubuntu和Centos操作系统,当然也支持Mac OS、OpenEmbedded、Arch Linux等。在学习ROS之前,需要选择一个可用的操作系统并熟悉掌握它。建议使用Ubuntu操作系统,这是ROS大部分使用者选择的,对于后期遇到的问题和一些公用库能够更好地支持。

对于操作系统,需要做到下面几个掌握程度:

1.掌握安装过程:

这是基本能力,在开发和研究过程中,很大程度会出现将电脑弄崩溃的情况,这时候掌握安装知识就显得很必要了;

2.掌握基本操作指令:

不管使用哪个操作系统,基本的操作指令都必须掌握。以Ubuntu为例,需要掌握基本的命令行操作(包括文件目录操作、软件库管理、文件编辑、配置管理等),建议参 Ubuntu桌面操作指南

3.掌握基本的编程工具使用:

掌握基本的编程工具使用,强制要求掌握python和C/C++这两类语言的编程工具,包括gcc、cmake等;

4.掌握依赖库管理:

掌握对应操作系统依赖库的管理,包括安装、升级、卸载等,掌握从源码安装依赖库的方法,掌握编程需要的环境变量配置方式。

对于操作系统,了解掌握得越深,对于后面的学习越有帮助,建议详细并深入地学习操作系统方面的知识,当然简单掌握上面的知识点也可以进行下面的学习。

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/wi ki

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从模块上拆分,可以分为下面几个部分:

  • 1.核心模块,包含各类语言的功能实现,通信上的处理;
  • 2.编译系统,提供完整的编译功能,包含各类语言的处理;
  • 3.工具系统,提供各类工具,如rostopic、rviz、rqt等;
  • 4.应用功能包,为其他第三方提供的优质功能应用,一般都是开源可用的。
  • 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 创建工作空间

    通过下面的命令来完成工作空间的创建:

    2.4.7.2 创建ROS软件包

    #!/bin/bash source /opt/ros/kinetic/setup.bash ​
    # 创建一个自己的目录 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/
    # 编译空工作空间以启用 catkin_make
    # 这样一个工作空间 catkin_ws 就创建完成,可以看到目录下有src(源码目录)、
    devel(开发编译目录)、build(编译中间目录)和install(目标程序生成目录)

    通过下面的命令来完成一个独立的软件包的创建:

    #!/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/Tut orials/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 python import 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, 确保它包含一下两条语句:
    <build_depend>message_generation</build_depend>
    <run_depend>message_runtime</run_depend> # 如果没有,添加进去。
    注意,在构建的时候,我们只需要"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<beginner_tutorials::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是一套软件框架,从传感器数据处理、定位、规划和控制,完整地提供了一整套的机器人开发软件框架,对于研究者和初学者是一个不错的练手工具。具体的介绍和使用可以参考下面的几个链接:

  • 官网介绍: http:// wiki.ros.org/navigation
  • github链接: https://github.com/ros-planning/navigation.git
  • 3. 总结

    ROS本身作为一套学习框架,对于软件开发人员来说并不是很难理解,掌握了原理后,上手是很快的。从我的角度来看,学习ROS本身就是一次不断练习的过程,只有在实践中才能更深层次地理解它。

       
    次浏览       
    相关文章

    基于图卷积网络的图深度学习
    自动驾驶中的3D目标检测
    工业机器人控制系统架构介绍
    项目实战:如何构建知识图谱
     
    相关文档

    5G人工智能物联网的典型应用
    深度学习在自动驾驶中的应用
    图神经网络在交叉学科领域的应用研究
    无人机系统原理
    相关课程

    人工智能、机器学习&TensorFlow
    机器人软件开发技术
    人工智能,机器学习和深度学习
    图像处理算法方法与实践

    最新活动计划
    C++高级编程 12-25 [线上]
    白盒测试技术与工具实践 12-24[线上]
    LLM大模型应用与项目构建 12-26[特惠]
    需求分析最佳实践与沙盘演练 1-6[线上]
    SysML建模专家 1-16[北京]
    UAF架构体系与实践 1-22[北京]
     
     
    最新文章
    AIGC技术与应用全解析
    详解知识图谱的构建全流程
    大模型升级与设计之道
    自动驾驶和辅助驾驶系统
    ROS机器人操作系统底层原理
    最新课程
    人工智能,机器学习和深度学习
    人工智能与机器学习应用实战
    人工智能-图像处理和识别
    人工智能、机器学习& TensorFlow+Keras框架实践
    人工智能+Python+大数据
    成功案例
    某综合性科研机构 人工智能与机器学习应用
    某银行 人工智能+Python+大数据
    北京 人工智能、机器学习& TensorFlow框架实践
    某领先数字地图提供商 Python数据分析与机器学习
    中国移动 人工智能、机器学习和深度学习