自动驾驶GAZ66怪物卡车1/16

哈伯,你好!

我想告诉你我是如何做的以及如何制作一台自我管理的机器的。:)

我可以立即通过干连接电路和bash命令来告诉我如何做,但是那样会很无聊。我为您提供了一个有趣的故事(我希望如此),它讲述了我个人的经历以及到达的地方。

在那些可以拍照的地方。关于软件的地方-最有可能没有照片。

正如我要通过一杯咖啡告诉您的那样,这确实是一个叙事形式的故事。这与bash命令,python脚本无关,仅此而已。

让我们从发生的事情的照片和视频开始,然后是完整的故事。




历史将遵循这种情况。


  • 为什么我想要
  • 自动驾驶机器的工作原理(顶视图)
  • 年龄1-儿童世界的Gelendwagen + Raspberry Pi Zero W +相机
  • 年龄2-GAZ66 + NVIDIA Jetson Nano + RaspberryPi相机
  • 3岁-Remo Hobby SMAX
  • 年龄4-连接SMAX和GAZ66
  • 年龄5-在巨型卡车上安装组件
  • 年龄6-安装驴车和周围环境
  • 7岁-履带组装,旅行
  • 年龄8-操纵杆旅行
  • 9岁-神经元训练
  • 10岁-一切正常,最后!
  • 下一步是什么?
  • 战斗挑战
  • 社区
  • 我的打字机SD卡的图像

倒咖啡,我们要走了!

为什么我想要


这一切始于我对俄罗斯的一家大型IT公司制造非常酷的无人机感到非常沮丧

,这真是太酷了,但是我却没有工作:) 不,这真的太酷了-自动驾驶汽车)一种出色的合金力学和算法:)

挫败感一直持续到我将关于自己的不同事实结合在一起时,即:

  • 我可以用python编写
  • 我(大约)了解机器学习的工作原理
  • 我知道如何在控制台上使用Linux
  • 我的童年是用烙铁度过的
  • 我有一个装有diy组件(覆盆子pi,arduino,传感器等)的盒子。

当一切都浮现在脑海中时,我决定-自驾车(sdc)成为!

首先,我认为值得弄清楚sdc的工作方式,这将是下一节。

自动驾驶机器的工作原理(顶视图)


为了使汽车自行行驶,它需要四个组件-推车,传感器,计算机和算法。

让我们弄清楚


台车

实际上会推动什么。车轮,电动机,为这一切供电的电池。

我为自己命名的有条件的汽车有两个:儿童世界的汽车和业余爱好的汽车。

我试过了,甚至都没有尝试过来自儿童世界的汽车,这是失败的。他们的缺点是他们的电动机很弱,没有反馈。这意味着您很可能可以停下任何家用地毯,并且不能以给定的精度转动。

您需要的是来自爱好世界的汽车。它们具有强大的发动机,优质的电池和前轮转向助力器。将此视为进入阈值。我能找到的最便宜,最普通的东西是Remo Hobby SMAX。



感测器

它收集有关周围世界的一些信息,并将其传输到计算机进行决策。

基本上,为SDC设置的绅士风格是:

  • 相机。SDC基础知识的基础。他看着自己面前的一块空间,将图像传输到计算机上,该计算机可以识别正在发生的事情,并确定要做什么。似乎没有摄像头我就看不到SDC实现。
  • IMU传感器。显示沿轴的加速度和倾斜角度的图形。它有助于了解我们的实际去向,以及相对于起点我们的位置发生了怎样的变化。用于几乎所有直升机。
  • . , , , . , SDC, , . , 75$, SDC Velodyne 4K$. , 3D , 2D.
  • GPS. , , , SDC .
  • . — , . 3D .





从传感器接收值的计算机分析情况,我们将控制命令传输到购物车。

在用于嵌入式电子设备的计算机世界中,高能效的ARM处理器(如手机中的处理器)以及基于它们的单板计算机占据了主导地位。

如今,有两种最受欢迎​​的单板选项-RaspberryPi和NVIDIA Jetson。
RaspberryPi具有较低的价格,种类繁多的项目和庞大的社区。

NVIDIA具有更高的价格,更少的项目,但在机器学习任务中却具有更高的生产率。它具有板载128个CUDA内核(就像您的大型NVIDIA图形卡一样),用于加速机器学习算法。

我的收藏集中有三块Raspberry Pi(ZeroW,3、4)和NVIDIA Jetson Nano。我决定当然要在Jetson上组装机器。



可以

根据传感器读数确定动作的算法。通常,为此使用计算机视觉和神经网络的组合。在最基本的版本中,您可以在打字机上沿着一些标记驾驶自己,通过加油/刹车/转弯追踪来记录此类行程的视频,然后在此神经网络上进行训练,以便发现引擎信号对摄像机图像的依赖性。很简单,这是识别标记并尝试保留标记的任务。

如果您想刷新神经网络的工作原理,那么我建议您观看以下视频:


在这里,我描述了最简单的选择,即只有一个摄像头和一个打标机。但是,还有更多的传感器选项和不同的工作逻辑-这里将有单独的帖子。

如果水平很高,就是这样。

它仅保留:

  • 组装手推车
  • 悬挂传感器
  • 连接电脑
  • 绘制标记
  • 骑上它
  • 训练神经网络

现在我们已经弄清楚了无人驾驶汽车的全部意义,让我们继续我具体实现的时代。

年龄1-儿童世界的Gelendwagen + Raspberry Pi Zero W +相机


是的,我的第一个方法就是这样。发生这种情况的原因是,在我家附近有一个儿童乐园,我喜欢Gelik,然后我买了它。

好吧,我以为有一个螺旋线,现在我需要一台计算机和一个传感器。思想-完成。为她订购了RPi Zero W和一台相机。当我等待计算机和照相机时,我进去并购买了用于此业务的移动电源。
因此,一切就绪,是时候收集了。我找到了一个这样的项目,所以我决定跟随它。
Gelik拆卸了一下,拔出了他的本机脑,将它们转移到引擎控制器,然后,他又将它们转移到了RPi,连接了一个摄像头,并用移动电源为整个设备供电,并感到满意。

在进行自治之前,我决定在控制台上玩耍,追逐一只猫,将图像从相机传播到笔记本电脑。

那时,有几次失败等待着我。

首先,Raspberry Pi Zero W在性能方面非常弱。

第二-来自儿童世界的Gelik几乎不存在可传递性,几乎没有任何最小障碍阻止了它的通过。

已经很清楚该项目已经死了,但是出于兴趣的考虑,我试图在其上直接为Raspberry Pi Zero组装计算机视觉(OpenCV)。花了一天多的时间,没有开玩笑,这是该SDC实现方案棺材盖上的最后一钉钉子。
很明显,您需要同时更换计算机以提高性能,并同时更换购物车以提高越野能力。

原来很有趣:



2 — 66 + NVIDIA Jetson Nano + RaspberryPi


因此,在这一点上很明显,您需要一些更通行的汽车,最好是卡车,才能将所有组件放入体内。在研究了一项用于商品选择的服务之后,我们很清楚我们的本地GAZ66型号适合我,它也是人们中的志贺加。好吧,我订购了它,等等,是时候考虑一​​下计算机了。到这个时候,NVIDIA才刚刚准备开始其Jetson Nano的销售,而我在销售的第一天就下了订单。

一辆卡车赶到了,我继续等待杰特森,不耐烦地骑着shishiga绕着房子,推着上面提到的猫生了的小猫。并不是说小猫喜欢它-必须停下来。

同时,Jetson仍在驾驶,我从中国订购了一个真空激光雷达仪-我不知道如何具体使用它,但我知道我想这样做。

有一天,公司的快递员出现在办公室门口,递给我一大盒NVIDIA单付款人,我在发票上签名,觉得自己像是开发者。

现在该收集了!但是首先,您需要弄清楚,大声笑。拆除石狮区,扔掉她的本机大脑,润滑机械装置,开始在计算机的基础上进行组装。

我连接了摄像头,引擎控制器,旋转引擎,汽油/制动引擎,并启动了Python脚本进行测试-真是太可惜了!

这次的故事是这样的:shishigi使用常规的电动机来转动,而不是使用伺服驱动器。因此,他没有反馈。因此,我无法确定是否控制它们,这意味着它不适用于SDC。

好的,再次,您需要以某种方式解决此问题,做一些事情。我们进入下一个时代。





3岁-Remo Hobby SMAX


由于此时很明显该机器不仅需要合格的机器,而且还需要极少的零件,因此对于那些拥有RC的人来说,选择落在了商店上,这是一种爱好。
事不宜迟,我来到了一家这样的商店,没有躲藏就告诉我我在做什么,我需要哪种机器。卖方很友好,告诉我哪台机器符合我的最低要求,那是一台Remo Hobby SMAX。我买了它。

我回到家,得到了一个shishigu,从中取出了所有东西,坐下来连接到SMAX。你觉得怎么样?是的-再次失败!

基本上,RC车的设计方式是,引擎连接到引擎控制器,然后依次连接到与遥控器通信的无线电模块。正是SMAX的设计使发动机控制器和无线电模块结合在一起-我实际上没有机会连接到发动机控制器而不是无线电模块。

好的,您必须再次做些事情。我回到RC汽车的现场,爬到零部件上。我在那儿摸索,欢呼,发现一个马达控制器与无线电模块有一条独立的电线。

我重新订购,带来,收集所有东西-它可以工作,但只能转弯。但是没有气和逆!为什么,该死,我想,但是我一直在选择它。

这次,为了唤醒SMAX引擎,控制台必须通过无线电模块向它发送某个值(360),这是行不通的。但我对此一无所知,直接输入了刹车油的数值。引擎没有做出反应,从没有人要求他醒来的逻辑出发。

在某个时候,我坐下来逐字逐句地整理了所有内容,期望它至少会对某些内容做出反应。

一开始我走了100多岁。然后50乘。当我搜索10时,我听到了360的欢迎声-欢呼!作品!

我从控制台测试了gas / reverse / left / right,一切正常。这是火,我是程序员=)

看起来是时候组装了,但是有一个问题-绝对没有地方可以放这些零件。RC汽车的设计使其最高端是有条件的。首先,顶部由非常薄的塑料组成,其次,它是一辆吉普车,而且无处可放。
此时此刻,我决定进行搜索,以及实际上其他人是如何进行搜索的。

我找到了驴车项目,该项目具有交钥匙的一切功能,可以组装您的SDC-包括硬件示例和软件框架。看起来很酷,可以使用并使用它,但是有一些细微差别:

  • 他们在3D打印机上打印汽车的顶部,然后很远地提醒汽车。丑陋的,简而言之,不美观
  • 他们的3D模型与我们不出售的机器兼容。

好的,请记住Donkey Car,然后我们采用他们的软件框架,但是现在我们需要考虑硬件。

有一天,我在公寓里转过头,看着没有顶的SMAX拆开的shishigu,心想-嗯,它们似乎是相同的比例(1/16)。他驾驶了shishiga,驾驶了SMAX,一个接一个地放-确实如此!而且看起来很酷!好,我必须做!我们进入下一个时代。







年龄4-连接SMAX和GAZ66


因此,在这个时代开始之初,我有一个内部目标-将一台机器的顶部连接到另一台机器的底部。由于我和我的同事在一台3D打印机中使用了芯片,并且我是该芯片的共同拥有者(一位认真的投资者),因此决定在CAD程序中绘制连接,进行打印,然后将它们连接起来。

有了这个主意,我走了大约2个月,以为我只是想坐下来了解CAD系统。哈哈,不。在承认自己不想理解CAD系统之后,我开始思考还有其他选择。

我回到了儿童世界,决定去看设计师,突然他们以某种方式帮助了我。我买了一个经典的金属构造器,那是我在学校的时候(灰老学校汇聚在一起)。

他将他拖到家里,将机器的两个部分并排放置,并开始将各种设计元素应用于它们。某种程度的理解开始出现多长时间,至少在理论上,该如何完成。

开始做。花了一天多的时间用婴儿扳手,螺母和空间思维工具。

连接时,我学会了用螺丝刀钻孔塑料,小心地撕掉多余的零件,以免损坏外壳,将螺母与其他螺母锁定(但不要垫圈)。总的来说,我的Trudovik将为我感到骄傲。

经过大约三天的修改和三天的时间,我看到了这辆巨型卡车在我面前-Beslan的GAZ66 SMAX Edition。

因此,看来硬件基础已经准备就绪,可以进入下一个时代。





年龄5-在巨型卡车上安装组件


最后:

  • 我的手推车配件好
  • 我的鞋面美观大方
  • 汽油/刹车/转弯在此手推车上正常工作
  • 顶部和底部甚至连接在一起=)

现在是时候在此外观上安装组件了。

我用螺丝刀武装着塑料钻,并用双面胶带把所有东西都通用了,我开始做生意了。

我在驾驶室上为摄像机安装了一个支架,可让您调整摄像机的角度。将一长列火车从相机扔到Jetson,然后又将其固定在后面。

除Jetson外,以下人员定居在后面:

  • 用于为计算机供电的移动电源(捐赠了他的主要产品(很酷),并带有USB供电,因此杰森不会断电)
  • PCA9685(PWM控制器)用于电机控制
  • 电池为机器的引擎供电

由于当时该项目已被认为是长期的,所以我决定不打扰激光雷达,至少在Donkey Car的摄像头和软件上做MVP。

为了娱乐,我连接了GAZ66的原生大灯,以使其在黑暗中更加美观和自信。

好的,我的机器打开了,引擎响应了来自python的命令,相机给出了图片,灯亮了,一切都很好,是时候安装软件了。





年龄6-安装驴车和周围环境


幸运的是,在最后阶段,我找到了“驴车”项目,这使我的生活变得更加轻松,使我不必自己编写任何东西。简而言之,DonkeyCar是一个已经具有SDC所需功能的框架。他们甚至还提供有关如何安装软件的指南。但是,与OpenSource的通常情况一样,这些指南已经过时并且彼此之间相互矛盾。

好的,必须弄清楚。为了使框架正常运行,需要以下库:

  • Opencv的
  • tensorflow-gpu(gpu用于jetson,因为有cuda内核。对于rpi有tensorflow-lite)
  • tensorrt(用于加速神经元推理的库)
  • 以及根据环境列表自动设置的所有内容

让我们从OpenCV开始。

DonkeyCar指南说,您需要从源代码本身构建它,因为对于ARM,pip中没有OpenCV。我什至做到了,编译了OpenCV,但是在安装它之前,我决定检查一下,系统突然有一个旧版本的OpenCV,因此需要将其拆除。我调用了一个python,导入了cv2,要求提供一个版本,但它是bam且相关。快速搜索并发现,在最新版本的linux4tegra(位于jetson中)中,来自NVIDIA的家伙开始安装OpenCV。太酷了,我没事做。做得好,我可以编译自己:)

接下来,tensorflow-gpu。

DonkeyCar指南首先指出了一个过时的版本分支(1.xx),其次甚至没有指出过时的分支的最新版本。我决定不听他们的话,而是放最新的当前版本(2.0)。

下一步是张量。

在jetson上安装tensrort的指南是在单独的Wiki页面中编写的,从中可以清楚地看出,作者没有阅读主要指南=)因为在tensorrt指南中,环境变量被重新分配,并且OpenCV停止工作。我以这种方式扭曲了它,将所有内容回滚,并决定对环境和环境变量进行锤击-将其直接滚动到主要环境中。

对自己很满意的是,他打开了python,依次称为cv2,tensorflow,tensorrt,然后要求python提供其版本-它们都已导入,都显示了最新版本。凉!

驴车本身的安装过程非常简单,我将不对其进行描述,建议阅读其指南。我现在唯一要注意的是,在驴车配置中,您可以将图像的分辨率从RPi的86x86提高到Jetson的224x224(因为这样会提高性能,并且准确性会更高)。

因此,一切就绪,可以运行和测试了!

我的机器真的打开了,它在该IP上启动了Web服务器,路由器向该IP发送了该机器。您可以真正去那里,并从浏览器驱动操纵杆,查看摄像机中的图像。

我还必须校准PWM(PCA9685)提供的值,以找到侧面的完整正向,完整向后,最大转弯。

顺便说一句,在这里,我发现我的引擎连接不正确-机器回退的动力比向前回回的动力大-我实验地发现了电线,然后将电线反过来扔了。如此安排,以至于引擎的所有电线都是相同的颜色,您不记得它是怎么回事。但是我正确地连接了它,并在每根电线上放了一个热缩管,以便以后可以区分它们。

太酷了,是时候继续进行赛道准备了!

7岁-履带组装,旅行


驴车算法的设计如此,以至于有一个由老师训练的神经元。这意味着来自摄像机的图片正在跟踪,并且每张图片旁边都会出现一个json文件,其中写入了图片的名称,加速,旋转,时间戳。为了训练神经元,此类图片+ json对至少需要5K。

他们决定在家里组装轨道,他们说公寓很大,有可以转弯的地方。但是开始收集后,很明显公寓周围没有人骑车了-地板的颜色不同,对比度也不同,模型无法取出。

好吧,我决定将它放在一个房间里。我买了4卷胶带,然后将它们粘在地板的轨道上。

我把汽车放进去,发动了汽车,开了车,然后又失败了-事实证明一个房间太小了,我的汽车简直就是老土。更精确地说,它是包含在内的,但是以这样的速度以至于会令人感到羞耻=)

好吧,我们需要进行第二次迭代,并且需要一个很大的空间。选择权落在办公室上-有很多地方,地板都是单音的,开放式24X7。唯一的问题是清洁工在夜间工作,因此需要将其拆除。也就是说,您需要一口气做所有事情-双手骑手成为一名老师,训练模型,将其扔回到打字机中,并且已经可以不用手动控制了。

好的,第十天,在进行了A / B实验之后,决定留在办公室里进行跟踪。
选择位置,准备好磁带,在游戏中创建轨道团队。仅仅一个小时,办公室走廊里就走得很好。

我把汽车放进去,打开它,尝试开车-欢呼,它转弯了,我不得不将速度限制在80%。



年龄8-操纵杆旅行


因此,我有一条轨道,我有一辆汽车,并且我需要5K对图片+ json。

根据经验,我发现轨迹的一圈是250对photo + json,这意味着我至少需要离开20圈。

最好连续。您当然可以间歇性地进行,但是随后模型会散发出乱七八糟的气体,并且气体可以开始变慢,但是我不希望这样。

我开始尝试不间断地骑20圈,我必须说,这不是一件容易的事。

出现第一个困难是因为路线中心有一根沉重的立柱,当机器在其后面行驶时,与控制它的笔记本电脑的连接变得滞后,而这一小滞后使我无法进入路线范围。

好的,所以您需要确保连接是从我自己开车时与打字机相连的设备进行的。这意味着您需要从手机的浏览器中进行驱动。

但是仍然有操纵杆,我用双手握住它,还能从哪里获得电话?不能使用打字机,它会减慢速度,然后,如果没有电话,它将运行得更快,并且可能由于过度加速而在角落里感到困惑。

嗯,那么您需要以某种方式将手机和操纵杆组合在一起。好的,我有一个阅读器,它足够大,可以同时适合电话和游戏杆-可以。他拿起磁带,用胶带将电话贴到阅读器上,就在操纵杆的下面。我看着这个奇迹,心想-您总体上是什么? :-)

但是,它起作用了:)通过这件事,我设法离开了20圈。但是实际上,即使是25岁,因为我在15圈左右有品味。

腊肠犬,准备好了,我有一个训练神经元的数据集,是时候训练了!

9岁-神经元训练


现在,我有一辆汽车,一条轨道,一个数据集-是的,我离结果只有一步之遥!
在家里,我打算学习的NVIDIA RTX 2070使PC处于闲置状态。幸运的是,对于智能家居,我拥有一个外部IP,并且只需要将22端口从Internet接入PC。很好,当我在办公室时,有助手为我完成了这项工作。

因此,我使用ubuntu将ssh转到计算机,监视sshfs的主文件夹,上传文件。看起来只有40兆字节,但是持续了大约30分钟。据我了解,它发生了,因为其中有很多。

在您的计算机上安装文件,安装tensorflow-gpu,安装DonkeyCar软件之后,就该进行培训了。
我正在从DonkeyCar调用一个用于训练神经元的脚本,我将其指向带有数据集的文件夹-它已运行。
在神经元运行时,nvtop(视频卡负载监视器)显示出1406%的利用率,常规htop显示所有16个内核的cpu负载为100%(正在运行)。

大约20分钟后,我有一个训练有素的驾驶汽车模型。看起来,接受它,使用它。但是没有:)

还记得吗,我在上面写过关于tensorrt的文章,它可以优化神经元的推理并在cuda内核上运行它们?当然,我想经历一下。

这就是我需要的:

  • 冻结模型(您需要将模型的所有内容打包到一个文件中)
  • 将fr带结果转换为张量格式

我试图冻结模型,但我从DonkeyCar调用了脚本,失败了。同时,这是深夜,清洁工很快要拆除我的车道,我需要尽快。

假设诞生是因为我采用了DonkeyCar的错误张量流。好的,我正在拉张量流2.0,设置为1.15,然后重试-成功,干杯!

现在进行转换,再进行细分-找不到团队。好的,我要查找问题所在。事实证明,NVIDIA将该功能标记为过时,并且取消了对该功能的支持。他们说,现在,您需要手动进行转换。幸运的是,我找到了一个git repo,那里有一个类似的请求,用户找到了python脚本实际所在的地方,该地方可以转换模型。

我从那个地方叫剧本,事实真相大白。但是,他说,没有适合您的第三条蟒蛇,排在第二位。

好吧,我在叫第二条蟒蛇。他告诉我-我没有张量流。好吧,我请他将tensorflow-gpu设置为1.15,他告诉我没有这样的版本,只有1.14。好的,我同意,让我们抓住一个机会,将不同的版本放在不同的python环境中。将tensorflow放在第二个python中,要求进行转换-干杯,它起作用了!

好的,我有用于tensorrt和普通tensorflow-gpu的模型,我将其放入机器中。

我用tensorrt模型,巨大的错误跟踪,按时间启动模型-好的,我将尝试通常的模型。

我再次开始执行通常的错误,但这一次很清楚-您的图片大小为224X224,而预期为86X86。还记得我在更高的地方写过配置规则,改变了摄像机的图像分辨率吗?

因此,我在打字机上更正了,但在主机上却没有。

我回到主机,在那里更正配置,重新训练,重新做带状装饰,重新转换,扔回去。



我用张量模型启动机器,然后...

10岁-一切正常,最后!


万岁!我的车去了!本身,没有我。很酷。我非常高兴)


我做了将近一年的时间,现在)

下一步是什么?


有许多进一步发展的计划;我将从简单到复杂。

  • 在模型中添加IMU传感器可能会提高准确性。例如,在上坡行驶时,发动机需要付出更多努力。
  • 将逻辑转化为旅途,而不是在高速公路上,而只是绕过障碍物
  • 添加激光雷达并从中获取读数

战斗挑战


如果您自己或与朋友一起感觉要参加比赛,请写信给我,让我们安排比赛=)

社区


我还建立了一个兴趣聊天室,并正在准备一个频道。我不确定根据哈伯(Habr)的规则是否有可能,因此我会应要求发送给PM。

我的打字机SD卡的图像


同样,如果您要在类似的基础上进行,并且不希望使用此设置,我也会应要求向您发送我的汽车的img图像。

All Articles