paint-brush
构建 Raspberry Pi + ESP32 无人机:我进入机器人技术的第一步经过@tohntobshi
10,379 讀數
10,379 讀數

构建 Raspberry Pi + ESP32 无人机:我进入机器人技术的第一步

经过 Anton D2022/04/26
Read on Terminal Reader
Read this story w/o Javascript

太長; 讀書

Anton 写了他进入机器人技术的第一步,尤其是他的 Raspberry Pi + ESP32 无人机。 Anton 在 Blender 中设计零件,然后在廉价的 3D 打印机上以 3D 打印它们。无人机由一个应用程序控制,用户可以使用类似模拟的应用程序监控和监控无人机。安东还为此制作了一段视频,并附在文章末尾。

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - 构建 Raspberry Pi + ESP32 无人机:我进入机器人技术的第一步
Anton D HackerNoon profile picture

大家好!我叫安东。我想分享我迈向机器人技术的第一步的故事,尤其是关于我的 Raspberry Pi + ESP32 无人机的故事。 (我也做了一个视频,附在文末)

前言

在故事开始时,我是一名网络开发人员(React、Typescript 等),有一些 C++ 知识,至于电子技能——我可以焊接撕裂的耳机线。问题是,作为一名 Web 开发人员,我开始感到不满意,因为我所做的事情并没有以任何有意义的方式影响物理世界。当然,有很多纯软件项目会影响现实世界,但我决定采用最直接的方法并深入研究机器人技术。


所以我读了一些关于这个主题的书,在 youtube 上看了一些视频,阅读了一些文章,并购买了焊接设备和 3D 打印机,因为 3D 打印机现在很便宜,而且可以让我免于用食品容器制作零件的头痛和类似的垃圾。

第一个机器人

我的第一个机器人是这个 Caterpillar 平台:


我的第一个机器人


我在 Blender 中设计零件,然后打印出来。我使用 Raspberry Pi 作为它的大脑和一个移动电源作为电源。我用继电器和晶体管焊接了电机控制器。在制作这个东西的过程中,我遇到了一个问题,当我组装好所有东西时,电机几乎没有动。结果我把晶体管的集电极和发射极混在一起了,重新焊接后一切都开始工作了。很难把这个东西称为机器人,因为它自己不做任何事情,只是被远程控制。无论如何,我对制作它感觉很好,相信自己,并决定制作同样的东西,但要飞行。

第二个机器人

经过一番研究,我决定使用一些传统的四轴飞行器部件,例如无刷电机、电子速度控制器和能够为电机提供大电流的锂电池。作为大脑,我仍然使用相同的 Raspberry Pi。在我了解了如何将 Raspberry Pi 与 ESC 连接后,我开始设计一个框架来容纳所有部件。我这样做只是依靠直觉,希望对框架的要求不是很严格,因为我看到了这种形状怪异的无人机仍然可以飞行。


我还在 i2c 总线上购买了一块集成了陀螺仪、加速度计、气压计和磁力计的电路板。在我了解 PID 控制器是什么之前,我的第一个直观方法类似于其 P 组件的工作方式——只是根据无人机与水平面的偏离角度成比例地增加或减少电机速度。


一开始,我认为这不会是一项非常困难的任务,但在所有失败的尝试之后,我不知道如何以正确的方式做到这一点,因为有很多事情可能无法正常工作。与只制作软件相反,每次运行都可能导致物理损坏,并且只有在更换损坏的部件后才能进行下一次尝试。而且,在出租的小公寓里测试这个东西也不是那么容易。如果我有一个大车库、棚子或类似的东西,我可以建造限制无人机运动的结构。


垂直运动受鞋带限制


相反,我不得不即兴创作并使用鞋带和自己的双手,这有时会导致轻微但不愉快的伤害。


在某个时候,我觉得用鼠标和键盘控制无人机不方便,于是决定制作一个控制器应用程序,我可以在其中更改参数,监控传感器读数,并逐渐用类似模拟的 UI 控制无人机。


移动应用截图

另一个截图


最初,出于某种原因,我专注于水平调平控制,只是意识到我无法安全地对其进行测试,而我更需要的是自动高度控制。我的第一个想法是使用气压计读数,但它们不够精确,无法控制室内高度(或者我可能只是以错误的方式使用它们)所以我在当地的电子元件店买了一个超声波传感器。实际上,它有一个奇怪的接口,在测量过程中会将其中一个引脚变为高电平,您必须计算时间来推断距离。当 Raspberry Pi 相对空闲时,它工作得很好,但在计算负载下,它只是错过了计时,读数是垃圾。因此,我不得不在项目中添加一个额外的 AVR 控制器,仅用于测量这些时序并在 SPI 接口上以方便的数字形式输出结果。


我还为无人机购买了两条自行车刹车线和印刷指南,以限制其上下运动,这样我就可以专注于高度控制,而无需考虑控制其他自由度。

水平运动受制动电缆限制


除了螺旋桨工作的情况外,它有点工作,会产生湍流,干扰 40 厘米以上高度的超声波传感器读数。当我终于发现它时,我不得不用激光传感器替换超声波传感器。


那时,我已经有了高度控制,但仍然无法实现稳定的水平调平,即使我已经对其进行了 PID 控制。我猜到了几个原因,但我不确定其中哪一个对问题的影响最大。但他们在这里:


  • 对于第一个并且可能是最重要的,我使用了廉价的螺旋桨(甚至尝试打印它们)并且忽略了平衡它们的必要性,这反过来又使 IMU 传感器过载并降低了它们的精度。当我最终决定解决这个问题时,我在我的应用程序中添加了一项功能,以获取最后 100 个陀螺仪读数和最大和最小值之间的输出范围。螺旋桨工作时的范围越大,它就越不平衡。我随机将管道胶带粘在螺旋桨的叶片上,然后运行它们检查值,如果它增加了 - 可能是一个不好的地方粘在那里,如果噪音减少 - 我在正确的道路上,然后我试图坚持它进一步或靠近中心并再次检查,这样我就减少了每个螺旋桨的噪音。
  • 第二个可能的问题是树莓派只有两个 PWM 通道,但它控制了四个 ESC,软件 PWM 可能不够精确,还浪费 CPU 周期。所以我决定使用 ESP32 来完成这项任务,因为它们便宜、容易获得,并且有很多 Raspberry Pi 缺乏的接口。我开始通过 ESP32 通过 SPI 与 Raspberry Pi 连接来控制 ESC,最后将所有飞行控制器逻辑移至 ESP32。
  • 第三个问题可能是框架不够坚固,我重新设计并打印了几次。
  • 另一个问题是我用于估计倾斜角的互补滤波器的次优系数。对于集成陀螺仪读数估计的角度,最佳值为 0.999,加速度计测量的角度为 0.001。
  • 如果倾斜的无人机围绕其局部 z 轴旋转,我不认为俯仰变成滚动,反之亦然。
  • 倾斜角的非常缓慢的振荡可以通过多次增加 P 系数来解决,而不是像某些消息来源所建议的那样减少它。



在开发过程中的某个地方,我对模块之间的电线数量和它们的放置方式感到沮丧。所以我决定花一些时间在制作定制 PCB 的技能上。我考虑了很长时间,但因必须购买昂贵的工具和处理化学品而感到沮丧。


实际上,结果比我想象的要容易,我看了一些关于 KiCAD 的教程来创建我的 PCB 设计。我花了 40 美元买了一台二手激光打印机,还花 5 美元买了一个普通的无孔熨斗,最贵的工具是 75 美元的钻孔机。事实证明,这些化学物质并没有那么危险,如果你触摸它们,它们不会溶解你的皮肤。


KiCAD 中的设计

蚀刻和应用阻焊层后


所以我在第四次尝试时制作了这个PCB。最难的部分实际上是应用阻焊层。该 PCB 的作用是将传感器、ESP32 和 Raspberry Pi 互连,并为不同的部件提供适当的电压。


显示应用程序中当前传感器读数的精美图表在试图防止无人机坠毁时难以分析。所以我添加了记录传感器数据的能力,并编写了一个 python 脚本,用飞行的视频记录逐帧分析它。

飞行分析器脚本


如果我早点这样做,我将花费更少的时间来调查由我之前提到的有故障的超声波传感器引起的问题。


在某些时候,我实现了相对稳定的高度、方向和水平调平控制,但仍然无法避免水平漂移。如果有人知道仅使用 IMU 传感器是否可以消除水平漂移,请在评论中告诉我。


我做了一些研究,发现一些无人机使用 GPS 进行定位,我尝试实施相同的技术。但问题是它只能在外面工作,但即使在外面我也无法取得任何令人满意的结果。那个季节的天气很糟糕,有风、有雨和有雪,所以我没有做太多尝试,用 GPS 保释,并尝试了计算机视觉方法。


跟踪蓝色标记的脚本草图


我在无人机底部放置了一个摄像头,并尝试使用 OpenCV 库将这个蓝色标记保持在地板上。经过几次尝试和调整,结果如下:


https://www.youtube.com/watch?v=poqQmvoBlP8

现在它可以在没有手动控制和任何字符串的情况下悬停在某一点。这是我最终实现的中间目标,所以我决定记录并分享我的进步。



我还添加了从无人机到应用程序的视频流传输,所以现在我可以尝试使用计算机视觉来尝试不同的方法来保持一般位置,而不在地板上进行特殊标记,并制作其他功能。




在目前的配置下,无人机是这样制作的:ESP32负责高度、方向和水平控制。它从 IMU 传感器和底部的激光距离传感器获取数据。它向电机控制器发出命令,还接受来自树莓派的命令,树莓派本身负责与应用程序通信并使用来自相机的数据进行位置控制。


如果有人有兴趣查看代码

ESP32 部分

树莓派部分

客户端安卓应用


代码不是很干净,因为我经常更改实现以使其正常工作。也许我将来会清理它:)


另外,我制作了一个关于它的视频:

https://www.youtube.com/watch?v=3mAFEW0YOJ0


感谢您的关注!干杯!