![](./images/search.png)
![](./images/THUEE.png)
智能机器人精品公开课
目录
![](./images/catalogue (3).jpg)
课程概述
﹀课程概述
快速开始
1、请在在线机器人仿真系统中,点击终端
![](./images/catalogue (2).png)
2、输入指令
3、按下回车键,进入3D机器人仿真环境中
4、右键终端,开启一个新终端
5、输入指令
6、回车键,根据屏幕提示按下键盘任意键,3D仿真环境中的智能车引擎启动,智能车开始沿着跑道自动驾驶跑圈了!
这整个智能车自动驾驶的过程是如何完成的呢,这门课程将带你逐渐了解这个充满乐趣和知识领域。
第一章 机器人系统概述
﹀第一章 机器人系统概述
1.1 机器人系统运作方式
欢迎大家来到课程主线内容,相信现在你一定对机器人系统充满了好奇。
机器人是如何感知外界环境并且能够自主行动起来的呢?
这一小节,我们将带你走进机器人领域,对智能车这样简单的机器人系统运作方式产生初步的认知。
1.2 认识三个好朋友:Ubuntu、虚拟机、命令行
﹀1.2 认识三个好朋友:Ubuntu、虚拟机、命令行
1.2.1 Ubuntu
Ubuntu是一个以桌面应用为主的Linux操作系统,从前人们认为Linux难以安装、难以使用,在Ubuntu出现 后这些都成为了历史。Ubuntu也拥有庞大的社区力量,用户可以方便地从社区获得帮助。作为全球最流行且 最有影响力的Linux开源系统之一,Ubuntu自发布以来在应用体验方面:有较大幅度的提升,即使对比Windows、MacOS等操作系统,最新版本的Ubuntu也不逊色。
![](./images/1.2 (1).png)
1.2.2 虚拟机
虚拟机(Virtual Machine)指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整 计算机系统。在实体计算机中能够完成的工作在虚拟机中都能够实现。在计算机中创建虚拟机时,需要将实 体机的部分硬盘和内存容量作为虚拟机的硬盘和内存容量。
![](./images/1.2 (2).png)
1.2.3 命令
一般说的“命令行”是指linux命令,linux命令是对Linux系统进行管理的命令。对于Linux系统来说,无论是中 央处理器、内存、磁盘驱动器、键盘、鼠标,还是用户等都是文件,Linux系统管理的命令是它正常运行的核 心,与之前的DOS命令类似。
命令行是用户通过键盘输入字符指令、计算机输出字符结果的一种人机交互的方式。与图形界面(GUI)主 要使用鼠标、图像等直观视觉交互方式不同,命令行通常需要用户记忆操作的命令。在熟记命令的前提下, 使用命令行往往要较使用图形用户界面的操作速度要快,并且更容易执行批量操作。
1.2 实验:虚拟机和Ubuntu的安装
﹀1.2 实验:虚拟机和Ubuntu的安装
虚拟机和Ubuntu安装:(仅支持Windows系统!Mac OS系统不支持)
一、下载Ubuntu环境(下载虚拟机即可)
Ubuntu环境清华网盘下载链接:https://cloud.tsinghua.edu.cn/d/8ca80a18642d431cbf5b/
![](./images/1.3 (1).png)
下载后解压到当前文件夹(part1或part2选择解压其一即可)
![](./images/1.3 (2).png)
二、虚拟机VMware下载
打开虚拟机(vmware)下载链接:https://customerconnect.vmware.com/en/downloads/info/slug/desktop_end_user_computing/vmware_workstation_player/16_0 点击“DOWNLOAD NOW”
![](./images/1.3 (3).png)
安装虚拟机:
![](./images/1.3 (4).png)
![](./images/1.3 (5).png)
下一步
![](./images/1.3 (6).png)
![](./images/1.3 (7).png)
![](./images/1.3 (8).png)
![](./images/1.3 (9).png)
![](./images/1.3 (10).png)
![](./images/1.3 (11).png)
![](./images/1.3 (12).png)
![](./images/1.3 (13).png)
安装好之后,我们就能在桌面看到虚拟机的图标啦
双击图标
![](./images/1.3 (14).png)
我们选择打开虚拟机
![](./images/1.3 (15).png)
选择解压的环境(nicsrobot),点击"打开"
![](./images/1.3 (16).png)
点击播放虚拟机
![](./images/1.3 (17).png)
这里选择我已复制该虚拟机
![](./images/1.3 (18).png)
选择"是"
![](./images/1.3 (19).png)
密码为:nicsrobot
![](./images/1.3 (20).png)
输完密码之后,我们就能顺利的进入到Ubuntu界面啦!
三、实验:启动ROS!
打开终端有两种方法:
1、按快捷键"ctrl+alt+T"打开终端(terminal)
2、在桌面点击右键,点击terminal
按"ctrl+alt+T"打开终端(terminal),在当前路径下输入
![](./images/1.3 (21).png)
若您能看到下面这个界面,就成功启动ros啦。
![](./images/1.3 (22).png)
按"ctrl + c" 可以退出当前的ROS进程。
1.3 认识node和topics
﹀1.3 认识node和topics
1.3.1 Node简介
在ROS的世界里,最小的进程单元就是节点(node)。一个软件包里可以有多个可执行文件,可执行文件在 运行之后就成了一个进程(process),这个进程在ROS中就叫做节点。
从程序的角度来说,node就是一个可执行文件。从功能角度来说,通常一个node负责者机器人的某一个单 独的功能。由于机器人的功能模块非常复杂,我们往往不会把所有功能都集中到一个node上,而会采用分布 式的方式,把鸡蛋放到不同的篮子里。例如有一个node来控制底盘轮子的运动,有一个node驱动摄像头获 取图像,有一个node驱动激光雷达,有一个node根据传感器信息进行路径规划……这样做可以降低程序发 生崩溃的可能性,试想一下如果把所有功能都写到一个程序中,模块间的通信、异常处理将会很麻烦。
1.3.2 启动Node
当我们要启动ROS时,首先输入命令:
此时ROS master启动。
ROS中它被赋予了专用的名字——node。我们知道一个package中存放着可执行文件,可执行文件是静态的, 当系统执行这些可执行文件,将这些文件加载到内存中,它就成为了动态的node。具体启动node的语句是:
rosrun + 包名+节点名
翻译成代码就是
通常我们运行ROS,就是按照这样的顺序启动,有时候节点太多,我们会选择用launch文件来启动,下一小 节会有介绍。 Master、Node之间以及Node之间的关系如下图所示:
![](./images/1.4 (2).png)
1.3.3 ROS的四种通信方式
在我们上节课讲到,ROS为机器人系统提供了通信架构,所以通信方式是ROS最为核心的概念。
1、Topic话题
2、service服务
3、Parameter Service参数服务器
4、Actionlib动作服务器
1.3.4 Topic简介
我们这门课,只需要用到topic(话题)这种通信方式。
ROS中的通信方式中,topic是常用的一种。对于实时性、周期性的消息,使用topic来传输是最佳的选择。 topic是一种点对点的单向通信方式,这里的“点”指的是node,也就是说node之间可以通过topic方式来传递 信息。topic要经历下面几步的初始化过程:首先,publisher节点和subscriber节点都要到节点管理器进行注 册,然后publisher会发布topic,subscriber在master的指挥下会订阅该topic,从而建立起sub-pub之间的 通信。注意整个过程是单向的。其结构示意图如下
![](./images/1.4 (3).png)
我们以摄像头画面的发布、处理、显示为例讲讲topic通信的流程。在机器人上的摄像头拍摄程序是一个 node(圆圈表示,我们记作node1),当node1运行启动之后,它作为一个Publisher就开始发布topic。比如 它发布了一个topic(方框表示),叫做/camera_rgb,是rgb颜色信息,即采集到的彩色图像。
![](./images/1.4 (4).png)
同时,node2假如是图像处理程序,它订阅了/camera_rgb这个topic,经过节点管理器的介绍,它就能建立和 摄像头节点(node1)的连接。 是不是很简单~~!
这里我要给大家讲一个知识点,topic的通信方式是异步的!
那么怎么样来理解“异步”这个概念呢?
在node1每发布一次消息之后,就会继续执行下一个动作,至于消息是什么状态、被怎样处理,它不需要了 解;而对于node2图像处理程序,它只管接收和处理/camera_rgb上的消息,至于是谁发来的,它不会关心 。所以node1、node2两者都是各司其责,不存在协同工作,我们称这样的通信方式是异步的。
ROS是一种分布式的架构,一个topic可以被多个节点同时发布,也可以同时被多个节点接收。比如在这个场 景中用户可以再加入一个图像显示的节点node3,我们在想看看摄像头节点的画面,则可以用自己的笔记本 连接到机器人上的节点管理器,然后在自己的电脑上启动图像显示节点。
这就体现了分布式系统通信的好处:扩展性好、软件复用率高。
总结两点:
1. topic通信方式是异步的,发送时调用publish()方法,发送完成立即返回,不用等待反馈。
2. topic可以同时有多个subscribers,也可以同时有多个publishers。
1.3.5 操作命令
在实际应用中,我们应该熟悉topic的几种使用命令,下表详细的列出了各自的命令及其作用。
A | B | |
1 | 命令 | 作用 |
2 | rostopic list | 列出当前所有的topic |
3 | rostopic info topic_name | 显示某个topic的属性信息 |
4 | rostopic echo topic_name | 显示某个topic的内容 |
5 | rostopic pub topic_name ... | 向某个topic发布内容 |
6 | rostopic bw topic_name | 查看某个topic的带宽 |
7 | rostopic hz topic_name | 查看某个topic的频率 |
8 | rostopic find topic_type | 查找某个类型的topic |
9 | rostopic type topic_name | 查看某个topic的类型(msg) |
1.4 认识launch文件
﹀1.4 认识launch文件
1.4.1 简介
机器人是一个系统工程,通常一个机器人运行操作时要开启很多个node,对于一个复杂的机器人的启动操作 应该怎么做呢?当然,我们并不需要每个节点依次进行rosrun,ROS为我们提供了一个命令能一次性启动 master和多个node。该命令是:
$ roslaunch pkg_name file_name.launch
如果master没有启动,那么roslaunch就会首先启动master,然后再按照launch的规则执行。launch文件里 已经配置好了启动的规则。所以 roslaunch 就像是一个启动工具,能够一次性把多个节点按照我们预先的配 置启动起来,减少我们在终端中一条条输入指令的麻烦。
1.4.2 写法与格式
launch文件是一种标签文本,它的格式包括以下标签:
参考链接:http://wiki.ros.org/roslaunch/XML
1.4.3 示例
launch文件的写法和格式看起来内容比较复杂,我们先来介绍一个最简单的例子如下:
这是ros官网给出的一个最小的例子,文本中的信息是,它启动了一个单独的节点"talker",该节点是包" rospy_tutorials "软件包中的节点。
然而实际中的launch文件要复杂很多,同学们只需了解我们提供的launch文件即可
1.4.4 小结
对于初学者,我们不要求掌握每一个标签是什么作用,但至少应该有一个印象。如果我们要进行自己写 launch文件,可以先从改launch文件的模板入手,基本可以满足普通项目的要求。
1.4.5 小实验:搭建驾驶环境
PS:若想在终端里粘贴代码,需要"ctrl+shift +v"而不是"ctrl+v"
第一步:进入仿真环境
打开终端,输入
![](./images/1.4-02.png)
![](./images/1.4-03.png)
看到这个界面,我们就成功启动launch文件,进入到智能车仿真驾驶界面啦。
第二步:退出
在终端里按"ctrl+c"退出仿真界面
1.5 单元测试一
﹀1.5 单元测试一
1.机器人操作系统的全称是?
![](./images/success.png)
![](./images/error.png)
2.下列哪个不是ROS的特点?
![](./images/success.png)
![](./images/error.png)
3.ROS最早诞生于哪所学校的实验室?
![](./images/success.png)
![](./images/error.png)
4.(多选)下列哪几个命令可以启动ROS Master?
![](./images/success.png)
![](./images/error.png)
5.关于ROS Node的描述,哪一项是错误的?
![](./images/success.png)
![](./images/error.png)
6.关于.launch文件的描述,以下哪一项是错的?
![](./images/success.png)
![](./images/error.png)
7.想要查看`/odom`话题发布的内容,应该用哪个命令?
![](./images/success.png)
![](./images/error.png)
8.(多选)关于Topic通信的描述,正确的选项有:
![](./images/success.png)
![](./images/error.png)
第二章 让智能车跑起来
﹀第二章 让智能车跑起来
2.1 智能车数字仿真—Gazebo
2.1.1 简介
ROS中的工具就是帮助我们完成一系列的操作,使得我们的工作更加轻松高效。ROS工具的功能大概有以下 几个方向:仿真、调试、可视化。本节课我们要学习的Gazebo就是实现了仿真的功能,而调试与可视化由 Rviz、rqt来实现。
2.1.2 认识Gazebo
对于Gazebo,大家可能比较陌生,它是机器人仿真工具。在topic通信中,我们的demo都是在Gazebo中实现。 Gazebo是一个机器人仿真工具,模拟器,也是一个独立的开源机器人仿真平台。当今市面上还有其他的仿 真工具例如V—Rep、Webots等等。但是Gazebo不仅开源,也是是兼容ROS最好的仿真工具。
![](./images/2.1-01.png)
Gazebo的功能很强大,最大的优点是对ROS的支持很好,可以进行机器人的运动学、动力学仿真,能够模 拟机器人常用的传感器(如激光雷达、摄像头、IMU等),也可以加载自定义的环境和场景。
2.1.3 仿真的意义
仿真不仅仅只是做出一个很酷的3D场景,更重要的是给机器人一个逼近现实的虚拟物理环境,比如光照条 件、物理距离等等。设定好具体的参数,让机器人完成我们设定的目标任务。比如一些有危险因素的测试, 就可以让机器人在仿真的环境中去完成,例如无人车在交通环境复杂的交通要道的效果,我们就可以在仿真 的环境下测试各种情况无人车的反应与效果,如车辆的性能、驾驶的策略、车流人流的行为模式等,又或者 各种不可控因素如雨雪天气,突发事故,车辆故障等,从而收集结果参数指标信息等等,只有更大程度的逼 近现实,才能得出车辆的真实效果。直到无人车在仿真条件下做到万无一失,才能放心的投放到真实环境中 去使用,这即避免了危险因素对实验者的威胁,也节约了时间和资源,这就是仿真的意义。
通常一些不依赖于具体硬件的算法和场景都可以在Gazebo上仿真,例如图像识别、传感器数据融合处理、 路径规划、SLAM等任务完全可以在Gazebo上仿真实现,大大减轻了对硬件的依赖。
2.1 实验:在Gazebo中手动驾驶智能车
﹀2.1 实验:在Gazebo中手动驾驶智能车
2.1.1 gazebo操作说明
•平移:鼠标左键
•旋转:鼠标滚轮中键
•放缩:鼠标滚轮
•界面左侧是控制面板
•导入模型就在控制面板的insert,可以直接拖入模拟空间,也可以按需自制模型拖入。
2.1.2 实验:搭建驾驶环境——用键盘驾驶智能车
那么如何在Ubuntu系统中,打开驾驶仿真环境,并且用键盘驾驶智能车呢?
我们需要用到2个launch文件。
1、nics_gazebo_simple.launch,它是我们写好的的gezebo仿真器;
2、keyboard_teleop.launch ,它是用键盘控制智能车的launch文件。
接下来我们开始实验
PS:若想在终端里粘贴代码,需要"ctrl shift +v"而不是"ctrl+v"!!!
第一步 :打开仿真界面
和我们上一章节的实例测试一样,我们打开终端,输入
可以看到gezebo仿真界面
![](./images/2.1-02.png)
第二步 :启动键盘控制节点
按快捷键"ctrl+alt+T"另外打开一个新的终端,输入
启动键盘控制的launch文件
![](./images/2.1-03.png)
在终端里我们可以看到键盘控制的键位
i是前进 u是向左前进 o是向右前进 k是刹车 ,是倒车
![](./images/2.1-04.png)
现在我们就用键盘来控制小车前后左右行走吧!
注意!!!我们需要在键盘控制的终端界面,来按"i"、"u"、"o"等指令。在其他界面按前后左右的指令,小车动不了!
你会发现小车动得特别慢!
怎么让小车走的快一点呢?这个时候你可以看一眼下面的红框
按一次"q"可以让小车提速10%!
![](./images/2.1-05.png)
第三步 :在终端中查看车辆的线速度和角速度
再新打开一个终端,输入
我们可以看到返回的线速度和角速度
![](./images/2.1-06.png)
2.1.3 小结
虽然Gazebo目前的功能还称不上强大,同时还存在着一些BUG,但是对于我们的入门学习也已经是足够了, 随着版本的更新,Gazebo也在越来越强大。
2.2 实验:ROS的调试工具—RViz
﹀2.2 实验:ROS的调试工具—RViz
2.2.1 简介
本节课介绍的是我们在ROS开发中非常常用的一个工具,基本上调试和开发都离不开这个工具——RViz(the Robot Visualization tool)机器人可视化工具,可视化的作用是直观的,它极大的方便了监控和调试等操作。 例如能在窗口中看到机器人模型和轨迹、激光雷达、点云地图。
![](./images/2.2-01.png)
2.2.2 实验:在RViz中添加智能车的第一视角
第一步 :进入仿真环境
依然打开教材的模拟场景,输入
第二步 :打开RViz
之后打开新的终端,直接输入 " $ rviz "
打开rviz工具。
![](./images/2.2-02.png)
第三步 :添加智能车的第一视角
在这里我们想看智能车摄像头的第一视角,需要点击“Add”
![](./images/2.2-03.png)
在By topic里添加image,点"ok"
![](./images/2.2-04.png)
RViz的插件种类繁多功能强大,非常适合我们开发调试ROS程序。
2.2.3 差异
虽然从界面上来看,RViz和Gazebo非常相似,但实际上两者有着很大的不同,Gazebo实现的是仿真,提供一 个虚拟的世界,RViz实现的是可视化,呈现接收到的信息。左侧的插件相当于是一个个的subscriber,RViz接收 信息,并且显示。所以RViz和Gazebo有本质的差异。
2.2.4 小结
RViz和Gazebo是我们常用的ROS工具,更好的利用这些工具是我们ROS进阶的基础。具体的操作和使用可以 参考我们的官方演示视频,跟着视频去实战演练,熟悉这两个工具。
2.3 实验:ROS的调试工具—RViz
﹀2.3 实验:ROS的调试工具—Rqt
2.3.1 简介
rqt是一个基于qt开发的可视化工具,拥有扩展性好、灵活易用、跨平台等特点,主要作用和RViz一致都是可 视化,但是和RViz相比,rqt要高级一个层次。
2.3.2 命令
rqt_graph :显示通信架构
rqt_graph是来显示通信架构,也就是我们上一章所讲的内容节点、主题等等,当前有哪些Node和topic在运 行,消息的流向是怎样,都能通过这个语句显示出来。此命令由于能显示系统的全貌,所以非常的常用。
2.3.3 实验:查看智能车的通信架构
1. 首先打开我们教材的模拟场景,输入
2.输入命令语句" rqt_graph ",显示出了当前环境下运行的Node和topic,十分直观的看到通信结构以及消息流 向。注意在椭圆形的代表节点,矩形代表topic。(可以用鼠标滚轮放大缩小画面)
![](./images/2.3-01.png)
![](./images/2.3-02.png)
2.3.4 小结
rqt_graph这个功能是强大的,它使得我们初学者可以直观的看到ROS的通信架构和信息流,方便我们理解的同时,也使得我们能够最快的纠错等等。
2.4 单元测试二
﹀2.4 单元测试二
1.Gazebo是一款什么工具?
![](./images/success.png)
![](./images/error.png)
2.rqt_graph可以用来查看计算图,以下说法错误的是:
![](./images/success.png)
![](./images/error.png)
3.(多选)RViz可以图形化显示哪些类型的数据?
![](./images/success.png)
![](./images/error.png)
4.(多选)关于仿真环境的描述,以下说法正确的是:
![](./images/success.png)
![](./images/error.png)
第三章 python编程起步—用程序和智能车对话
﹀第三章 python编程起步—用程序和智能车对话
3.1 认识Python
3.2 实验:智能车喊话:Hello world !
﹀3.2 实验:智能车喊话:Hello world !
3.2.1 实验:智能车喊话:hello world !
print语句
如果要让Python打印出指定的文字,可以用print()函数,然后把希望打印的文字用单引号或者双引号括起来,但不能混用单引号和双引号:
实战开始:
1、首先我们打开桌面的Visual Studio Code,它是我们今后要用到的代码编辑器!
新建一个文件
![](./images/3.2-02.png)
输入 print("hello world")
保存到桌面
![](./images/3.2-04.png)
重命名为 test.py
![](./images/3.2-05.png)
接着打开终端,输入
进入到桌面路径(因为代码刚刚保存在桌面;按“tab”键可以补全Desktop的拼写哦)
输入
![](./images/3.2-07.png)
回车,我们可以看到“hello world”字符,在终端打印出来啦!
![](./images/3.2-08.png)
3.3 实验:如果红灯,请停车!
﹀3.3 实验:如果红灯,请停车!
每天的生活中,我们都在不断地做出一些判断。例如,每天有出门的时候,我们会决定今天穿什么衣服吃什 么样的早餐的。同时,每个判断背后都有一个理由,比如考虑到天气太冷了,就穿厚一点的衣服,所以理由 是用来做判断的条件。
如果要让小车能够在面对不同的路况时,做出一些优化的操作,就需要学习条件语句来做一些判断判断。判 断的条件来自小车对周围路况的“感知”。
3.3.1 if条件语句
当传感器获得的数据符合某种条件时,就会让小车执行相应策略的指令。这样的过程在计算机中可以理解为:
如果满足A条件:
那么执行a指令
如果满足B条件:
那么执行b指令
否则:
执行c指令
这就是一条简单的条件结构转化为计算机语句就是:
if 条件A:
指令a
elif 条件B:
指令b
else:
指令c
3.3.1 if条件语句
我们实现以下任务:
当小车检测到红灯时打印"stop",检测到绿灯打印"go",若既不是红灯也不是绿灯,则输出"no signal"
这样的要求可以通过下面的语句来实现:
在写代码之前,建议不要用“复制”-“粘贴”把代码从页面粘贴到你自己的电脑上。写程序也讲究一个感觉, 你需要一个字母一个字母地把代码自己敲进去,在敲代码的过程中,初学者经常会敲错代码:拼写不对,大 小写不对,混用中英文标点,混用空格和Tab键,所以,你需要仔细地检查、对照,才能以最快的速度掌握 如何写程序。
建议同学们亲自敲打一遍
我们在vscode里新建文件,输入上面那段代码
![](./images/3.3-01.png)
保存在桌面,命名为test2.py
和之前test1.py一样,在终端运行
![](./images/3.3-02.png)
输入red
会输出stop
输入green
会输出go
输入其他的字符串
则会输出no signal
![](./images/3.3-03.png)
3.4 单元测试三
﹀3.4 单元测试三
1.(多选)以下关于Python的说法正确的是?
![](./images/success.png)
![](./images/error.png)
第四章 初级视觉智能—完成基础寻迹关卡
﹀第四章 初级视觉智能—完成基础寻迹关卡
欢迎同学们来到赛道实践。
经过前面章节的铺垫学习,这一章节我们将带大家动手控制智能车完成寻迹任务。
我们首先来思考一下如何完成这样一个任务。
在这个任务中,任务的输入是环境信息,输出是智能车的ROS控制信号,我们需要做的就是处理环境信息,并决策,将ROS控制信号发送出去。
那么如何拿到完成任务需要参考的环境信息呢,采用视觉的方案是一种经典的方案。
欢迎同学们来到赛道实践。
4.1 计算机视觉
计算机视觉是研究如何使机器学会“看”的科学,也是人工智能和大量机器人系统的基础。这门科学体量庞 大、原理多样、应用领域很广泛。
![](./images/4.1-01.png)
但是请不要担心,这一章节我们会带你从零开始了解计算机视觉并动手操作计算机视觉的处理过程,经过这 一章节的学习,我们就能够让智能车自动完成跑圈任务。
本章共包含五个小节的内容,在第五小节我们会教大家手把手在Gazebo仿真器中调试车子。
![](./images/4.1-02.gif)
由摄像头拍摄的周围环境图像,经过ROS系统通信传输之后,到达智能无人车的大脑(计算机)进行处理, 这是智能车获取周围环境信息和自身相对位置的重要方式。下面的视频将为你简单介绍计算机中处理图像的 基本知识,帮助你基本了解计算机是如何从图像中提取、处理信息的。
对计算机视觉及进行图像处理技术感兴趣的同学,欢迎关注我们后续推出的视觉方面的课程。
4.2 学会提取图像颜色信息
﹀4.2 学会提取图像颜色信息
上一节中我们了解了计算机中对图像信息的存储,大多采用矩阵存储0~255这些数字的形式。那么如何利用 这些矩阵中数字呢?
我们通过完成一项简单的智能车任务——寻迹,即无人车自动检测位置,并围绕赛道行驶一圈的任务,理解 提取图像信息的过程。
![](./images/4.2-01.gif)
首先,来看一下咱们无人车跑圈的赛道场地。
![](./images/4.2-02.png)
第一步分析一下场地的特点:场地由绿色、黑色、白色、橘黄色组成,在这之中,我们希望无人车能够一直 沿着场地中橘黄色的线行驶。那么我们可以将任务可以分解为几个容易完成的任务链了:
1.找到图像中橘黄色的部分
2.确定橘黄色部分和目前无人车之间的相对位置
3.发送控制信号让无人车的中心靠近橘黄色区域并向前移动
视频中我们将教大家如何逐步完成这三个小任务链。
ok,我们已经完成了任务链的前两项任务了,距离完成智能车寻迹只剩下最后一个小任务了。
4.3 发出前进指令
﹀4.3 发出前进指令
上一小节中,我们将整体任务拆分成了小任务链,并完成了前两项小任务。
1.找到图像中橘黄色的部分
2.确定橘黄色部分和目前无人车之间的相对位置
3.发送控制信号让无人车的中心靠近橘黄色区域并向前移动
现在我们已经通过颜色信息提取出智能车偏离车道线的偏移量bias了,如何根据偏移量控制智能车运动呢?
![](./images/4.3-01.png)
在前面的课程中我们学到了控制智能车车前行:通过ROS topic发送线速度和角速度指令。因此,这里我们 要设计一个关于偏移量bias(y1-y2)和topic指令中线速度、角速度的函数。最后一步把topic发送出去即可 控制智能车按照我们的设计自动前进。
下面的视频将为你介绍如何设计关于偏移量bias和智能车线速度、角速度的函数。
三个小任务我们都完成了,距离动手实践只有一步之遥了。我们还需要设计一个应急预案,保证智能车在赛 道上的稳定性,应对丢失车道线等突发情况。
4.4 安全驾驶
﹀4.4 安全驾驶
经过前面三个小节的学习,相信同学们已经对完成任务胸有成竹,跃跃欲试想要操纵智能车开始竞速赛了。 别着急,还有最后一个问题需要注意,智能车驾驶的稳定性。
在自动驾驶的过程中,我们需要对可能遇到的异常驾驶情况做出提前的预案。这一小节内容非常简短,我们 将从实战的角度为大家讲解两个需要注意的事项。
4.5 开车调试——基础关卡
﹀4.5 开车调试——基础关卡
前面的四个小节中,我们已经掌握如何让智能车自动提取橙色的赛道线信息,并设计智能车前进的指令。 这一小节,我们将在实际场景的孪生仿真环境中调整和测试智能车,让它能够完成自动寻迹的基础任务。 需要提示大家非常重要的一点:
在调试的过程中,请注意做实验记录,记录不同参数带来的实验结果;同时,请将可以正常运行的程序文件 另存到另一个安全的目录下,制造一个可供恢复的原始time machine,以便在误操作时能够还原到之前正常 状态的代码。
ok,让我们开始吧!
视频版教程:
重要提示:如果代码报错,请同学们一定要仔细检查python语句中的缩进和逻辑关系。
文字版教程:
欢迎同学们来到赛道,在基础任务中我们将调用到两个launch文件。
第一个launch文件是打开仿真器环境的文件,请同学们打开一个终端,输入代码:
并回车,静待几秒之后,我们将进入仿真环境中。
![](./images/4.5 (1).jpg)
要让智能车动起来,我们还需要发出动作命令,首先是车道线检测节点,其次前进指令节点,这两个节点可 以通过另一个launch文件启动。
请再打开一个新的终端,右键点击终端,选择新终端,输入代码
![](./images/4.5 (2).jpg)
并回车,静待几秒后,命令行中将出现这样的提示
![](./images/4.5 (3).jpg)
按照命令行的提示,在键盘敲击任意键即可开始运行整个竞速跑圈程序。
我们按下回车键试一下,会发现命令行中出现了红字报错,这是因为目前的程序中缺少了几段代码。
![](./images/4.5 (4).jpg)
不过不要着急,经过这一小节的学习,你将能够完成这些代码,并让智能车动起来。
Start
首先,我们在刚才报错的终端中键入ctrl+c终止这段出错的文件运行并关闭它。打开这个launch文件查看一 下它所运行的节点文件。这个launch文件位于主目录下的catkin_ws/src/nics_gzb/nicsrobot_line_follower 下的launch文件夹中。打开launch文件可以看到,启动的节点分别是detection_node和motion_node,分别 对应上层目录中scripts文件夹下的.py文件。
那么让我们从起点开始,以寻迹的过程为线索,寻找节点文件中缺少了哪部分代码。
首先智能车调用摄像头的图像,
![](./images/4.5 (5).jpg)
接收到图像后,遍历图像找到图像中橙色像素点的坐标,并存入空间中。遍历图像后,计算空间中所有橙色像 素点坐标的均值。这部分操作可以在detection_node.py文件中查阅到(这里给一个打开文件的过程录屏)
(该文件位于Home/catkin_ws/src/nics_gzb/nicsrobot_line_follower/scripts/level_1).
这段操作中不需要更改代码的内容,但希望同学们可以学习代码内容尝试理解编写的逻辑和其中的函数操作。 我们可以直接利用求得的坐标均值center进行下一步操作.
![](./images/4.5 (6).jpg)
![](./images/4.5 (7).jpg)
接下来,橙色点坐标均值与智能车的位置横坐标相减,得到位置偏移量bias。请将这一操作的代码输入motion_node.py 第46行,motion_node.py文件位于
主目录下的catkin_ws/src/nics_gzb/nicsrobot_line_follower/scripts/level_1文件夹下
输入
注意保持输入的本行语句和上下文之间的缩进相同
![](./images/4.5 (8).jpg)
接下来,将bias与偏移量阈值进行比较,当bias大于阈值时,向智能车发出转向角速度指令同时让线速度减 小;当bias小于阈值时,智能车不发出转向角速度指令,只发出正常线速度指令。那么我们需要先设置一个 偏移阈值。
在motion_node.py文件的第24行输入self.center_band=50,这里我们将偏移阈值设置为50个单位的大小。
根据bias计算出无人车运动的线速度和角速度,向无人车发出指令。智能车线速度和角速度的计算,我们在第三节中为大家介绍了一种设计方案,你也可以发挥自己的智慧,改变函数的形式和参数大小。
在motion_node.py文件的第61 62行中,输入计算线速度和角速度的代码.
希望初学的同学们可以手动输入代码,加深理解。对编程熟练的同学也可以从教案中复制粘贴代码。
使用键盘Tab键和空格键调整缩进,注意保持本行语句和上下文间的缩进关系,保持这样的代码缩进。
![](./images/4.5 (9).jpg)
这个映射关系函数中包含了很多参数,我们来看下参数的意义。
- bias
是横坐标的差值
- velocity.linear.x
是智能车向前方x行驶的线速度
- velocity.angular.z
表示智能车转弯的角速度(逆时针为正)
- self.image_width
是摄像头采集图像的宽度
![](./images/4.5 (10).jpg)
接下来,将线速度和角速度指令topic发送出去,底盘接收到线速度角速度方向指令后,执行动作,这样我们 就完成了一个自动计算行驶的过程。
在motion_node.py文件的第71行中输入发送线速度和角速度的指令。
随后,智能车的程序中循环上述过程,就能够完成整个赛道的行驶,到达终点。
这样我们就完成了对代码的完善工作
键盘按下ctrl+s,或直接保存刚才我们改写的motion_node.py文件。
请再次打开一个终端,输入之前的roslaunch指令
并回车,静待几秒后,命令行中出现下面的提示,这时,在键盘输入任意键即可开始运行整个程序。
![](./images/4.5 (11).jpg)
成功了,智能车是不是动起来了!
恭喜!到此为止,你已经成功启动并完成了一次无人车寻迹行驶任务。
ok,现在你已经完成了基础寻迹关卡的任务了!
是不是很简单。不过,小e觉得还可以跑得更快。请尝试让小e更快地完成赛道任务。
回顾一下给小e发出线速度和角速度指令的设计过程
linear.x=0.1+0.28×( 1— |bias| ⁄ imagewidth/2)
angular.z=0.0023×bias
这里,线速度的计算中存在两个常量数值,尝试改变这两个常量,观察无人车的行为。我们可以先将常量改 变得尺寸略大一些,以方便观察智能车的行为变化,例如,我们将线速度改为
linear.x=0.1+0.2×( 1— |bias| ⁄ imagewidth/2)
如何在代码中调试呢?
接下来我们尝试调试代码的过程,如果智能车正在运行,请先在运行检测前进节点的nicsrobot_line_follower.launch文件的终端中键入ctrl+c,终止正在运行的launch文件,然后再调试。
首先,我们要让智能车回到起点,
在终端中输入
这个指令表示运行了一个设置智能车位置的节点
智能车就可以瞬间移动回起跑线啦。
我们打开motion_node.py文件,修改线速度的代码参数:
这样就将线速度的最小值限定为了1.0,保存motion_node.py文件,再在终端输入
再次启动launch文件,我们可以看到智能车前进的速度变快了。
同样的,每次调试程序前我们需要将智能车运行的launch文件程序中止,再发送指令让智能车回到起跑线。 然后修改角速度指令的权重参数,例如,我们将角速度代码参数改为:
angular.z=0.02×bias
需要注意的一点是,调整参数的过程中有可能会出现丢失车道线的情况。
请同学们打开rviz,调用智能车的摄像头image图像,查看以智能车第一视角观察到的图像。
![](./images/4.5 (12).jpg)
如果智能车的视野中丢失了车道线,可以采用第三节中我们提供的解决方案,这个方案的代码在motion_node.py文件第57-59行中已经为同学们提供了,通过代码让智能车以0.15的线速度和0.8的角速度转圈 直到视野中检测到橙色像素点。
如果你的智能车出现了丢失车道线的问题,也可以尝试改变这部分代码的参数值,观察智能车不同的行为。
同学们可以自行调整线速度和角速度的参数和常量,以及bias的偏移阈值,感受不同参数组合对智能车行为 的影响,调整参数到你认为最科学的组合,在最短时间内完成竞速赛吧!
帮助小工具:ubuntu目录以及文件操作方法
﹀帮助小工具:ubuntu目录以及文件操作方法
在使用ubuntu系统时,我们会需要对其中的文件进行操作。那如何找到在某个目录下的文件并进行操作呢? 这是ubuntu的桌面界面,我们有两种进入目录管理文件的方法。
![](./images/4.6-01.png)
第一种是通过命令行,可以查阅1.4小节中关于命令行的"cd"操作,在命令行中进入某个文件夹。
第二种是通过图形化界面,像我们平日在windows系统中进行文件操作一样,ubuntu中的文件可以通过
![](./images/4.6-02.png)
进入到文件管理界面,默认的路径是主目录文件夹下
![](./images/4.6-03.png)
然后按照目录的路径,逐级双击打开文件夹就可以操作啦,和windows的操作几乎相同。
第五章 高级视觉智能—障碍赛实战
﹀第五章 高级视觉智能—障碍赛实战
5.1 从检测障碍物开始
欢迎来到课程的高级关卡,恭喜你已经完成了本课程的基础任务,相信到目前为止的内容对你来说完全是游 刃有余。那么在这一章节,我们将挑战更高的课程难度和逻辑能力,不过不用担心,我们仍会手把手带你了 解和学习完成障碍赛任务所需的所有资料。准备好了就开始吧!
完成高级任务所需的避障环境如下:
![](./images/5 (6).png)
赛道还是原来的赛道,车子也是原来的车子,只不过,赛道上出现了一些红色的路障,路障的位置甚至挡到 了部分车道线,这种情况下,如何让车子既能完成车道线寻迹跑圈任务同时还能有效避开障碍物呢。解决这 个问题最重要的部分就是:检测障碍物,并规划避障路径。需要注意的是,为避免同学们冲出赛道,赛道两 侧的白色边线上设置有透明挡板。
5.2 避障路径规划
﹀5.2 避障路径规划
欢迎回到课程,这一小节我们开始一个简单的路径规划。
在前面基础关卡的寻迹任务中,我们给智能车发送的命令只是让其不要偏离车道线,一旦远离车道线超过阈 值,就发送指令让车子赶紧转向回来。在障碍赛阶段,这一策略在大部分时间内仍然是有效的,但是需要结 合实际的路况,做出更新的指令。
![](./images/5 (1).png)
例如,在雷达探测范围内出现了路障时,应该如何设计智能车前进的指令呢?
![](./images/5 (2).png)
5.3 接收雷达数据
﹀5.3 接收雷达数据
上一小节中我们为大家介绍了激光雷达,那么在程序中如何调用雷达的数据并处理呢?
这时,ROS系统的优势就体现出来了,我们不需要在硬件层面进行复杂的雷达驱动编写、程序烧录、调试等 工作,只需要在ROS系统中调用节点发送的雷达topic就可以了。而硬件层面的驱动等工程,在ROS系统中已 经预先封装过了。
这里,我们需要用到ROS系统的Subscriber函数,开启订阅雷达话题的功能。(英文subscribe意为订阅)
5.4 开车调试——高级关卡
﹀5.4 开车调试——高级关卡
恭喜同学们来到课程的最后一步了——挑战障碍赛关卡!
这一章节的内容稍微晦涩了一些,不过还好,我们已经完成了一大部分。
现在我们的手中,有车道线偏移信息以及雷达返回的全方位障碍物位置信息,让我们做出路径规划吧!
这一章最终的任务,需要同学们自行创造一些代码,我们会给大家代码的目的和逻辑,请同学们用python编 写出来。
首先,回顾一下在路径规划那一小节思考的路径方案,课程教案里给同学们提供了两个方案做参考,但相信 你一定想到了更好的方案,那么如何在程序里执行我们的方案呢,以示例方案为例,我们将教你如何编写代 码实现。
我们以第二种方案为例:
![](./images/5 (1).gif)
在小车行驶的过程中,持续关注前方障碍物信息,永远选择障碍物最远的角度作为避障方向。但同时应引入 对障碍物距离的阈值判定,如果障碍物已经非常接近了,要加大转弯角度,紧急避障。
在此基础上,关注车道线的偏移量,最终转向弧度的计算方法为
angularnew = angular + Kp*dir
这个公式我们也在5.2小节为大家解释了意义。
接下来,我们需要把这部分想法写到motion_node_2.py文件中。
(文件位于主目录/catkin_ws/src/nics_gzb/nicsrobot_line_follower/scripts/level_2)
motion_node_2.py文件中大部分的基础设置代码我们也为同学们完成了,希望同学们能根据代码和教案的提 示,自行完成89行的lidar_avoid函数内容的编写。
![](./images/5 (3).png)
我们为大家讲解一下代码编写的一种思路,希望同学们能理解后,自行创造代码。
lidar_avoid的功能为:接收了车道线偏移计算的angular弧度参数,操作雷达数据列表,进行判断和赋值计 算,计算出避障的弧度,最终根据权重公式,输出angular_new(智能车的转向弧度)。
首先,我们定义一些需要用到的参数包括:
K_p 为权重公式中障碍物转向值的权重
lidar_cut 为裁剪了雷达数据列表后得结果
裁剪雷达数据是为了删除小车身后的障碍物信息干扰,将表格索引和转向角度值相互对应。请同学们编写一 句代码,裁剪出self.lidar_data中前方障碍物的信息保存到lidar_cut中。这样,表格索引就和转向角度相互对 应起来了。
max_idx lidar_cut 列表中数值最大值的位置,也就是列表中的序号
max_idx参数找到列表中最大值的位置,也就是障碍物位置最远的角度信息,因为雷达列表中每0.5°为一个 单位,所以列表中的序号就表示方向。这里,请同学们编写代码,找出lidar_cut中,数据最大值所在的坐标 位置,并赋值给max_idx。
right_min_idx 从列表中起始位置到最大值位置间的索引中,找到最小值位置的索引序号
这句话比较绕口,让我们通过一张图来理解:
假设障碍物距离最远的方向为max_idx,由于车道线权重的存在,难以保证小车行驶中能完全躲开障碍物, 这时,我们设定一个检测,如果在水平方向上距离最近的障碍物索引right_min_idx的值小于一定阈值时,我 们就认为小车快要撞上了,必须转向。
这里,需要同学们编写一个判断语句。如果这个最近障碍物的距离小于阈值了,则需要额外加大转向角度;
如果最小障碍物的距离大于阈值,就保持最大障碍物方向的角度转向。
![](./images/5 (4).png)
dir_idx 转向角度
当距离障碍物过近时,转向角应尽量远离障碍物;当距离障碍物较远,转向角朝向障碍物最远的方向。
![](./images/5 (5).png)
dir 转向弧度(角度—弧度变换) 请将刚才计算出来的转向角度,转换为转向弧度
angular_new 最终的输出转向值
ok,我们已经将示例代码的逻辑呈现给同学们了,相信同学们一定有自己的想法并且跃跃欲试了。
请按照自己的逻辑和路径设计方案,任意修改并创造代码吧。完成编写后,需要保存代码才可以运行roslaunch,请注意python语言编写中的缩进关系。如果出现了报错提示,请尝试自己寻找解决方案。
你也可以定义自己需要的变量,请记得备份有效的代码文件,尝试更高效的避障跑圈方案吧。
比比看,谁可以在最短时间内完成避障寻迹任务!
结语
﹀课程结语
智能机器人实践的入门课程到此就结束啦,同学们可以在课程的“在线机器人仿真系统”中调试代码和智能车,每次调试完成后请将代码备份,避免云端服务器丢失数据。
对智能机器人系统感兴趣的同学,欢迎持续关注我们后续推出的课程和竞赛。
欢迎智能机器人相关的课程和赛事合作。
![](./images/THUEE.png)
出品:
清华大学电子工程系
制作:
清华大学电子工程系协同智能团队
指导老师:
汪玉沈渊
课程设计:
余金城夏妍杨天翔向云飞唐佳昊郭中贺
鸣谢:
颜钰陈加聪白鑫鑫
合作和联系:
Email:xiay15@tsinghua.org.cn
Tel:+86 15652764391
地址:清华大学电子工程系罗姆楼4F