智(能)(避)障小车项目研究 基本思路

从一开始,我的 TDPS 项目的源代码就全部上传到了 GitHub,方便修改和查阅,说到抄袭,我觉得其他组用一用我的代码也应该没啥问题,前提是能看懂我的逻辑。

这里给出全部的 TDPS 项目代码的 Repo地址

是什么?

TDPS (Team Design Project and Skills) 是我院一个特色课程,目标是让大三学生(也就是我),与一个 10 人左右的团队做一个智(能)(避)障小车,并在无人干预的情况下完成以下内容:

(PS:整个过程中可以使用两个信标辅助定位)

Patio 1:

Patio 1全图

  • 跟随一条由两种不同材质形成的、有细微色差但难以分辨的地面寻线前进。

第一部分的图片

  • 前进到某一个位置后,右转上和下一个接近30度的桥。
  • 过桥之后定位并通过宽度为50厘米的拱门。

第三部分的图片

Patio 2:

  • 从起点前进找到识别区,识别区域内放置的色块。
  • 根据识别到的颜色,寻找相应的色块的位置,并前往对应色块放置的位置。
  • 自主通过一条路径(包含几个转弯和卵石路面)将放置在车上的某一物体放置到目标点。
  • 放置完成后,回退并沿另一路线,前往指定区域,利用指定模块与电脑通信。

怎么做?

在经过了长期的摸索之后(指花了不少钱买了些没用的模块),拟采用带编码器履带式小车,树莓派 3B + Arduino + OpenMV + Razor IMU。

  • 树莓派 3B 运行 Ubuntu Mate + ROS,处理大部分任务。
  • Arduino 运行 ros_arduino_bridge ,执行树莓派发来的控制指令,控制底盘 + 舵机,并返回编码器数据。
  • OpenMV 执行轻量化的颜色识别任务,并直接返回探测到的值和坐标。
  • Razor IMU 运行 AHRS,将数据传回树莓派作辅助方向纠正。

为什么?

为什么用履带式?

诚然,轮式小车在控制上有更大的优势,能使用编码器获得更精准的数据,而履带式小车由于履带打滑和车身重量不平衡等原因,误差会大一些。但是这里要考虑的是路面的状况。

任务中提到的路面会有大量的鹅卵石区域,这将会引入巨大的误差,这是无论哪一种底盘都无法避免的,而履带式小车的底盘减震系统将会大大削弱误差中致命的部分,并且履带式小车可以通过差速实现原地打转的功能。

为什么用编码器?

显然,由于先前说到的各种原因导致电机转速不匹配,会引入致命的误差,在仅仅知道通电时间和电压的程度上,无法精准的计算出小车的行驶距离,也没有调整速度所需要的参照,而编码器则可以通过反映转速完美的解决这一点,这也是PID算法的前置条件。

为什么用ROS?

其实这是最重要的疑问。为什么需要花费时间去配置一个庞大的元操作系统呢?

这里其实是与任务的复杂性相适应的考虑。如果使用简单的C语言程序,甚至简单的 Python 脚本,完全无法实现多种程序同时对底盘控制权的调度、冲突的处理和交互,小组中每个人的程序都需要考虑与他人程序之间的复杂的交互,这非常的麻烦。同时,为了实现某些算法,也需要单独运行各种代码,它们之间的交互、调度,会更加复杂,这使得项目不可能在短时间内完成。

而 ROS 则完全不同!资瓷 ROS Kinetic 版本的 Ubuntu Mate 的树莓派,可以直接运行大部分 ROS 中的导航、控制、分析代码,需要额外做的,仅仅是根据现场,修改一下参数罢了。同时,分布式的设计使得笔记本甚至不需要 ssh 连接过去,就能图形化地、实时地查看各种参数,进行调试。

ROS 的设计理念,包含了节点(Node),话题(Topic),消息(Message),服务(Service)等内容,能将 TDPS 这类大任务拆分成多个子任务,并将各自负责的部分拆分成不同的节点,独立运行,完美地解决了复杂性的问题。因此,使用 ROS 可以说是本项目的一个重大决定。

为什么使用Razor IMU?

首先,Razor IMU 在 ROS 上有相应的包,可以做到开箱即用。其次,在实地测量中可以发现,由于打滑的原因,利用编码器进行姿态、里程估计,在角度上会有极大的偏差,尤其是在转向的时候。

Razor IMU M0 是一个 9 轴的惯性测量单元,内置了 MPU-9250 传感器,可以使用 Arduino IDE 进行编程。

在 ROS 中,可以利用 ekf(Extended Kalman Filter),即扩展卡尔曼滤波器,对里程计和加速度值进行数据的融合,进而提升姿态估计的精确性,最后实现利用预先构建的地图进行导航的目标。虽然在某些需要更精准的定位的地点需要摄像头的帮助,但是该方法可以在大部分路线上有效,毕竟树莓派处理图像的延迟和性能占用是很高的,能不用就尽量不用。

为什么使用OpenMV?

OpenMV 是一个可编程的摄像头,内置了一些图像处理的算法,可以使用 MicroPython 写一些性能占用不太高的脚本(虽然本人觉得这玩意儿性能太弱了)(甚至组内一度决定不使用这个模块)。

这个模块相当于一个独立的摄像头 + 图像处理器 + 输出,可以直接返回图像处理的结果,可以在某种程度上降低树莓派的计算量。当然,它的性能很弱,并不能替代接在树莓派上的摄像头。(因此本组的小车是双摄)

为什么使用Arduino?

如果直接使用树莓派,将会有两个大问题:

  • Linux 不是一个实时的操作系统,运行高负荷程序时,控制部分,尤其是舵机的 PWM,将会出现不可避的、致命的抖动,编码器数据读取的准确性也很大程度上依赖于实时性(码盘每秒旋转上百圈呢)。
  • 本小车的外设过多,包含了两个摄像头、1 个 IMU、两个舵机、两个编码器、1 个电机控制板、1 个通信模块,这些模块的电流输出,可能会超过树莓派的承载能力,从而引发系统崩溃等场景。

为什么不使用激光雷达?

其实本项目一开始决定使用的是激光雷达,因为它可以完美实现无需摄像头的精准导航。但是后来发现有如下问题:

  • 真实比赛的时候场地可能构造发生变化,并且围观的人太多,不可能腾出空间。
  • 场地的各个位置相似性太高,定位算法反而容易发生偏移。

因此就抛弃了这个方案(以及好几百买的激光雷达)

为什么不…?

提出的还有一种仿造 VOR (甚高频全向信标)的导航原理,设计两个能够进行两点定位的信标。但是由于本组人都没有这方面的经验,就没有考虑使用了。