GalecinoCar:一个基于 Java 的自动驾驶车辆

爱好者们使用 Java、Raspberry Pi、机器学习、微服务等技术创建了一个自动驾驶的机器人汽车。
283 位读者喜欢此文。
How Linux got to be Linux: Test driving 1993-2003 distros

互联网档案馆图书图片。 由 Opensource.com 修改。 CC BY-SA 4.0

我们是典型的极客……总是寻找新的业余项目来保持我们的技能敏锐,消磨时间,并希望有一天能创建一个让我们致富的项目。 好的,最后一部分还没有发生,但总有一天……其余的时间一直都在一起做一些有趣的项目。 通常在晚上我们的孩子们都睡觉后,我们在我们的一个车库里见面并编写代码。

前段时间,我们听说了Donkey Car,一辆自动驾驶的机器人汽车,心想,“哇。 那太酷了。 想知道我们是否能做到?” 当我们发现 Donkey Car 项目是基于 Python 的,而我们则在 Java 阵营时,我们更加激动了。 所以,GalecinoCar 诞生了,它是我们基于 Java 和 Groovy 移植的基于 Python 的 Donkey Car 项目。(向 Donkey Car 社区致敬!)

设置硬件

该项目构建在 Exceed Magnet 卡车底盘之上。 Raspberry Pi 提供计算能力,连接的 Raspberry Pi 摄像头实现光学输入。 一个 PCA 9685 是底盘和 Pi 之间的中间人,提供脉冲宽度调制。 汽车的另一个主要部件是 3D 打印的防滚架,它连接到汽车并能够安装 Pi 和摄像头。 我们必须承认,我们太懒了,无法为底盘设计自己的安装架,所以我们直接使用了 Donkey Car 的防滚架设计。

硬件很容易组合在一起,只有一个小例外:汽车底盘很难找到。 Exceed Magnet 卡车已经有好几年历史了,而且 Donkey Car 的流行使得它很难找到。 我们花了大约两个月的时间才找到这两辆车。

训练自动驾驶仪

在制造汽车并处理好软件之后,训练自动驾驶仪完全是一次冒险。 我们尝试了好几次才创建训练数据,然后训练汽车的自动驾驶仪。 有时,感觉就像第一次教青少年开车一样。

不,别走那边!

踩油门!

别撞到那只猫!

我们第一次让汽车实现自动驾驶的时候,真是太棒了。 我们在另一个房间里,通过墙上的投影仪观看来自车载摄像头的画面。 紧张地,我们倒计时,直到汽车被放开。 接下来的是 30 秒的强烈兴奋、恐惧和混乱。 当自动驾驶仪启动时,汽车全速启动,撞了三面墙后才翻倒并保持静止。 我们第一次观察汽车时,发现它撞坏了一个传动系统,并且在汽车撞到的石膏板上留下了一些小痕迹。 通过车载摄像头观看整个过程真是太疯狂了!

我们发现训练汽车的最佳方法是使用旧的 PS3 控制器,它可以通过蓝牙轻松与汽车配对。

你可以使用 Pi 上软件提供的其他几个选项来控制汽车;但是,我们发现用户输入命令(例如,右转)之间存在延迟,并产生了一些非常糟糕的自动驾驶仪模型。 PS3 控制器选项具有低延迟,并让我们更好地控制汽车,从而为我们提供了更好的自动驾驶仪模型。

编写软件

我们使用 Micronaut 软件来为远程控制用户界面 (UI) 提供 REST 端点,并能够控制汽车的油门和转向。 用户可以使用 Tensorflow/Keras Donkeycar 选择手动控制或自动驾驶。

Micronaut 是一个现代的、基于 Java 虚拟机 (JVM) 的全栈框架,用于构建模块化、易于测试的微服务应用程序。 它具有内置的依赖注入、自动配置、配置共享、HTTP 路由、快速配置和负载平衡。 它具有快速的启动时间(在配备精良的开发机器上大约一秒),并支持 Java、Groovy 和 Kotlin。 它支持使用 Zipkin 等第三方工具进行分布式跟踪,包括一个用于生成代码的不错的命令行界面 (CLI),并提供一个用于为创建各种类型的项目提供配置文件支持的控制台。

在 Micronaut 应用程序内部,Robo4J 库 在手动控制下控制油门和转向。 对于 Micronaut 与摄像头的接口,我们使用 jrpicam 库。 请参阅下图,了解所有部件如何组合在一起

GalecinoCar's software components

以下是一些代码如何将所有内容联系在一起

GalecinoCar code #1

在上面的代码中,Micronaut 创建了一个服务——在本例中,是一个 GORM 数据服务; 如果我们不需要数据库支持,我们可以使用 @Singleton 来获得一个更简单的服务。 这里发生了很多事情,从初始化例程开始。 (您可以将 @PostContruct 添加到将在创建类时运行的任何方法。如果将标签添加到多个方法,它们将按声明的顺序运行。) 因为服务器受到大量请求的轰炸,所以我们使用排队机制来丢弃所有但发送给汽车的最新命令。

GalecinoCar code #2

此代码显示了我们如何根据发送到电机的脉冲宽度调制 (PWM) 值来向前或向后移动汽车。

GalecinoCar code #3

此代码显示了 Robo4J 库如何控制转向。 Robo4J 是一个 Java 库,由 Marcus Hirt 和 Miro Wengner 编写,用于使用 Java 本机接口 (JNI) 支持来控制机器人,以帮助 Java 开发人员控制 Raspberry Pi 上的机器人。

同样在此代码中,Micronaut 控制器为 UI 提供端点以控制汽车。 你可以使用 @Get 标签控制方法和内容类型,并且用于方法的简单列表参数定义代码将使用的 GET 参数。 如果你想要返回 JSON,只需将 produces 参数更改为 text/json

GalecinoCar code #4

你可以在我们的 GitHub 存储库 中查看 GalecinoCar 项目的代码。

观看 GalecinoCar 的实际操作

GalecinoCar 的首次公开亮相是在 GR8Conf EU 2018 上,我们做了关于该项目的演示并展示了它的驾驶能力。

Image from GalecinoCar looking at the track

来自 GalecinoCar 的图片,显示了 GR8Conf EU 2018 的赛道。

这是来自 GR8Conf EU 2018 的一段视频,记录了汽车的运行情况

展望未来

我们对这个项目有很多很棒的想法。 最重要的是让 AI 部分更好地工作,并让 AI 开始像汽车方向盘后的一个人一样思考。 首先,我们希望汽车能够在驾驶时做出更好的决策,特别是在避障方面,因此我们计划使用机器学习、图像识别和 LIDAR 系统来添加识别物体的功能。

我们希望自动驾驶仪不仅能够识别物体有多远,还能确定物体是什么,以及是否有特殊的方式来应对它。 例如,汽车的转向避免反应应该大不相同,这取决于它试图避免的东西是人还是掉落的树枝。 不幸的是,我们受到 Pi 计算能力的限制,但也许有一天我们会得到一个 CUDA 核心装备。

车与车之间的通信是我们计划解决的另一个有趣的问题。 如果我们同时在赛道上放置两辆汽车,它们应该能够相互协商以进行超车。 也许我们甚至必须建立对交通协议和法律的学习。

我们无意将汽车扩大到全尺寸。 这排除了我们可以使用的几种技术。 例如,1/16 比例的汽车对 GPS 数据没有多大用处。

GalecinoCar 一直是一个非常有趣的项目,而且绝对是我们更具挑战性的业余项目之一。 然而,在奠定了坚实的基础之后,我们预计该项目将开始加速增长。 对于我们可以用这辆车做的事情以及我们可以训练人工智能使用自动驾驶汽车做的事情,都有很大的潜力,因此这个项目将持续一段时间。


Ryan Vanderwerf 和 Lee Fox 将在 7 月 16 日至 19 日在俄勒冈州波特兰举行的第 20 届年度 OSCON 活动上展示 GalecinoCar:一辆使用机器学习、微服务、Java 和 Groovy 的自动驾驶汽车

User profile image.
Ryan Vanderwerf 是 Object Computing, Inc. Grails/Micronaut 团队的开发人员。

评论已关闭。

Creative Commons License本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
© . All rights reserved.