我是一家德国汽车公司的嵌入式软件工程师。我开始这个项目是作为嵌入式系统的学习平台。该项目被提前取消,但我非常喜欢它,所以我在空闲时间继续。这是结果...
我有以下要求:
除了学习之外,没有真正的目标。该平台可用于学习、监控、机器人竞赛、...
这不是初学者教程。你需要一些基本知识:
最后你可能会像我一样面临问题。带着一些好奇心和耐力,您将完成项目并解决挑战。我的代码尽可能简单,并且对关键代码行进行了注释以提供提示。
完整的源代码和文件可在此处获得:https ://github.com/makerobotics/RPIbot
力学
电子产品
我不是一个好的机械设计师。此外,该项目的目标是不要在底盘上花费太多时间。无论如何,我定义了以下要求:
可以用胶合板制成简单且便宜的底盘。使用电锯和手钻很容易加工。您可以粘合小木制零件来创建传感器和电机的支架。
考虑更换有缺陷的元件或电气调试。主要部件应采用可更换的螺钉固定。热胶枪可能很简单,但可能不是构建底盘的最佳方式......我需要很多时间来考虑一个简单的概念来轻松拆卸零件。3D 打印是一个不错的选择,但可能非常昂贵或耗时。
自由轮最终非常轻巧且易于安装。替代品都很重或充满摩擦(我在找到最后一个之前尝试了其中的几个)。安装主轮后,我只需要切割一个木制垫片来平整尾部自由轮。
车轮属性(用于软件计算)
周长:21.5 厘米
脉冲:20 脉冲/转。
分辨率:1075厘米(最后1个脉冲约为1厘米,便于软件计算)
如图所示,该项目正在使用不同的模块。
Raspberry Pi Zero是主控制器。它通过 PWM 信号读取传感器并控制电机。它通过wifi连接到远程PC。
DRV8833是一款双电机 H 桥。它为电机提供足够的电流(Raspberry Pi 无法做到这一点,因为输出只能提供一些 mA)。
每次光通过编码器轮时,光学编码器都会提供方形信号。每次信号切换时,我们将使用 Raspberry Pi 的硬件中断来获取信息。
pca9695是一个伺服控制板。它通过 I2C 串行总线进行通信。该板提供 PWM 信号和电源电压,用于控制凸轮的平移和倾斜伺服系统。
MPU9265是一款3轴加速度、3轴角转速、3轴磁通量传感器。我们将主要使用它来获取指南针航向。
不同的模块都通过跳线连接在一起。面包板充当调度程序并提供电源电压(5V 和 3.3V)和接地。连接都在连接表中描述(见附件)。将 5V 连接到 3.3V 输入可能会损坏您的芯片。在供应之前小心检查所有接线两次(这里特别要考虑编码器)。在连接所有板之前,您应该使用万用表测量调度板上的主电源电压。模块通过尼龙螺丝固定在底盘中。同样在这里,我很高兴将它们固定,但在发生故障时也可以拆卸。
最后唯一的焊接是电机、面包板和接头。老实说,我喜欢跳线,但它们会导致连接松动。在某些情况下,某些软件监控可能会支持您分析连接。
在实现机制之后,我们将建立一些软件基础设施,以拥有舒适的开发条件。
这是一个免费的开源版本控制系统。它用于像 Linux 一样管理大型项目,但也可以轻松地用于小型项目(参见 Github 和 Bitbucket)。
可以在本地跟踪项目更改,也可以将其推送到远程服务器以与社区共享软件。
主要使用的命令有:
git clone https://github.com/makerobotics/RPIbot.git 【获取源码和git配置】
git pull origin master [从远程仓库获取最新的]
git status [获取本地仓库的状态。是否有任何文件更改?] git log [获取提交列表] git add . [将所有更改的文件添加到下一次提交考虑的阶段] git commit -m "comment for commit" [将更改提交到本地存储库]git push origin master [将所有提交推送到远程存储库]
Python 提供了一些内置的日志功能。在开始进一步开发之前,软件结构应该已经定义了所有的日志框架。
记录器可以配置为在终端或日志文件中以定义的格式记录。在我们的示例中,记录器由 webserver 类配置,但我们也可以自己完成。这里我们只将日志级别设置为 DEBUG:
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
要随时间分析信号,最好将它们绘制在图表中。由于 Raspberry Pi 只有一个控制台终端,我们将在分号分隔的 csv 文件中跟踪数据并从远程 PC 绘制它。
分号分隔的跟踪文件是由我们的主要 python 代码生成的,并且必须具有如下标题:
timestamp;yawCorr;encoderR;I_L;odoDistance;ax;encoderL;I_R;yaw;eSpeedR;eSpeedL;pwmL;speedL;CycleTimeControl;wz;pwmR;speedR;Iyaw;hdg;m_y;m_x;eYaw;cycleTimeSense;
1603466959.65;0;0;25;0.0;-0.02685546875;0;25;0;25;25;52;0.0;23;0.221252441406;16;0.0;0;252.069366413;-5.19555664062;-16.0563964844;0;6;
1603466959.71;0;0;50;0.0;0.29150390625;0;50;0;25;25;55;0.0;57;-8.53729248047;53;0.0;0;253.562118111;-5.04602050781;-17.1031494141;0;6;
1603466959.76;0;-1;75;0.0;-0.188232421875;1;75;2;25;25;57;0;52;-24.1851806641;55;0;0;251.433794171;-5.64416503906;-16.8040771484;2;7;
第一列包含时间戳。以下列是免费的。使用要绘制的列列表调用绘图脚本:
remote@pc:~/python rpibot_plotter -f trace.csv -p speedL,speedR,pwmL,pwmR
绘图脚本位于工具文件夹中:https://github.com/makerobotics/RPIbot/tree/master/t...
绘图仪在 Python 中使用 mathplotlib。您必须将其复制到您的 PC 中。
为了更舒适,python 脚本由bash 脚本(plot.sh) 调用,该脚本用于将 Raspberry Pi 跟踪文件复制到远程 PC 并通过信号选择调用绘图仪。bash 脚本“plot.sh”询问如果必须复制文件。这对我来说更方便,而不是每次都手动复制。“sshpass”用于通过 scp 将文件从 Raspberry Pi 复制到远程 PC。它能够在不询问密码的情况下复制文件(它作为参数传递)。
最后打开一个窗口,如图所示。
Raspberry Pi 的开发接口是 SSH。文件可以直接在目标上编辑,也可以通过 scp 复制。
为了控制机器人,Pi 上运行了一个 Web 服务器,通过 Websocket 提供控制。该接口将在下一步中描述。
在源代码 (setup_rpi.txt) 的“doc”文件夹中有一个描述 Raspberry Pi 设置的文件。解释不多,但有很多有用的命令和链接。
我们使用轻量级 Tornado Web 服务器来托管用户界面。它是一个 Python 模块,我们在启动机器人控制软件时调用它。
用户界面由以下文件构建:gui.html [描述网页控件和布局] gui.js [包含处理控件并打开与我们机器人的 websocket 连接的 javascript 代码] gui.css [包含样式html 控件。控件的位置在这里定义]
用户界面不是最酷的,但它正在发挥作用。我在这里专注于对我来说是新的技术,比如 Websockets。
该网站正在通过 Websockets 与机器人 Web 服务器进行通信。这是一个双向通信通道,在连接启动时将保持打开状态。我们通过 Websocket 将机器人的命令发送到 Raspberry Pi 并获取信息(速度、位置、摄像头流)以供显示。
用户界面可以手动输入命令。这在开始时用于向机器人发送命令。复选框用于打开和关闭相机流。两个滑块控制摄像机平移和倾斜。用户界面的右上角部分控制机器人的运动。您可以控制速度和目标距离。基本遥测信息显示在机器人图纸中。
这部分是该项目的主要目标。在介绍带有直流电机的新机箱时,我重构了很多软件。出于不同的原因,我使用 Python 作为编程语言:
该软件是面向对象的,分为几个对象。我的想法是将代码分成 3 个功能块:
感知 --> 思考 --> 执行
感觉.py
主要传感器采集和处理。数据存储在字典中以供下一阶段使用。
控制.py
一个驱动子类在一些抽象之后控制电机和伺服系统。主要的控制对象处理高级命令以及电机的控制算法(PID)。
rpibot.py
这个主要对象是管理 Tornado Web 服务器并在单独的线程中实例化感知和控制类。
每个模块可以单独运行,也可以作为整个项目的一部分运行。您只能感测并打印出传感器信息,以检查传感器是否正确连接并提供正确的信息。
第一个任务是找出我们想要控制的东西。我一开始试图控制位置,这非常复杂并且没有多大帮助。
最后,我们要控制每个车轮的速度以及机器人的方向。为此,我们必须级联两个控制逻辑。
要逐步增加复杂性,应控制机器人:
开环(具有恒定功率)
pwm = K
然后添加闭环算法
pwm = Kp.speedError+Ki.Integration(speedError)
最后添加方向控制作为最后一步。
对于速度控制,我使用“PI”控制,而“P”仅用于偏航。我通过实验手动设置参数。可能在这里可以使用更好的参数。我的目标只是一条直线,我几乎得到了它。我在软件中创建了一个界面,通过用户界面编写一些变量。将参数 Kp 设置为 1.0 需要在用户界面中执行以下命令:
SET;Kp;1.0
我可以将 P 参数设置得足够低以避免任何超调。剩余误差由 I 参数校正(综合误差)
我很难找出如何级联两个控件。解决方法很简单,但我之前尝试了很多其他方法......所以最后,我将车轮的速度目标更改为向一个或另一个方向转动。直接更改速度控制输出是错误的,因为速度控制试图消除这种扰动。
附上使用的控制图。它仅显示机器人控制的左侧。
首先要考虑的是整个 IMU 必须正常工作。我订购了 3 个零件并将它们寄回,直到我有一个完整的工作传感器。以前的每个传感器都有传感器的某些部分无法正常工作或根本无法正常工作。在将其安装到机器人中之前,我使用了一些示例脚本来测试基础知识。
IMU传感器信号在使用前需要校准。一些传感器信号取决于安装角度和位置。
最简单的校准是纵向加速度 (A_x)。静止时应该有大约 0 m/s² 。如果您正确旋转传感器,您可以测量重力(大约 9.8 m/s²)。要校准 a_x,您只需正确安装它,然后定义偏移量以在静止时获得 0 m/s²。现在 A_x 已校准。您可以在静止时以类似的方式获得旋转速度的偏移量。
磁场传感器需要更复杂的校准。我们将使用 m_x 和 m_y 来获得水平方向的磁场。拥有 m_x 和 m_y 将使我们有机会计算罗盘航向。
为了我们的简单目的,我们将仅校准硬铁偏差。这必须在传感器处于最终位置时执行,因为它取决于磁场扰动。
我们在围绕 z 轴转动机器人时记录 m_x 和 m_y。我们在 XY 图表中绘制 m_x 与 m_y。如图所示,结果为省略号。省略号必须以原点为中心。这里我们考虑 m_x 和 m_y 的最大值和最小值来获得两个方向的偏移量。最后我们检查校准并看到省略号现在居中。
软铁校准意味着我们将图片从省略号更改为圆形。这可以通过在每个传感器值上添加一个因子来实现。
现在可以对测试例程进行编码以重新校准或至少检查传感器是否仍在校准。
现在将使用磁力计数据来计算罗盘航向。为此,我们必须将 m_x 和 m_y 信号转换为角度。Python 直接提供了具有此目标的 math.atan2 函数。完整的计算在 mpu9250_i2c.py 文件中定义(“calcHeading(mx, my, mz)”)。
由于设计完全开放,该项目花费了很多时间。对于每个组件,我都做了一些原型实现,并体验了系统的局限性。
最复杂的话题是车轮编码器。在找到当前使用的光学编码器之前,我测试了 3 种不同的选项。我认为在这样的项目中,中止的解决方案也很有趣。它涉及我学到最多的部分。
连接到 pca 9695 的连续旋转伺服
为了避免直流电机的额外 H 桥,我首先从连续旋转伺服系统开始。这些是由已经存在的 pca 9695 伺服驱动器驱动的。所有推进机制和相应的电子设备都简单得多。这种设计有两个缺点:
伺服系统以 50% 的 pwm 开始移动,全速约为 55%。这是一个非常差的控制范围。
如果没有编码器,很难找到准备就绪的编码器。我测试了安装在底盘上的 3 种不同的反射率编码器。我在轮子外侧用黑色和白色部分粘贴了一个自制的编码器轮。我使用了需要大量信号处理才能获得正确信号的 QTR-1RC 传感器。Raspberry Pi 无法执行这种实时处理。所以我决定为机器人添加一个 NodeMCU D1 mini 作为实时控制器。它通过串行 UART 连接到树莓派,以传递处理后的传感器数据。NodeMCU 也在管理 HC-SR04 传感器。机械结构很困难,而且不是很坚固,串行线路从 I2C 线路和电机中得到噪音,所以最后我用简单的齿轮直流电机驱动了底盘的第二个版本H桥。
为了改进自动驾驶,我们可以做一些图像处理。
opencv 库是一个参考。Python可以使用它来快速实现障碍物检测。
我们捕获图像并应用一些图像处理任务:
现在我们可以使用这些新信息来检测障碍物......
现在,我们有了一个带有传感器、执行器和摄像头的简单机器人平台。我的目标是在不增加任何传感器的情况下自主移动并返回车站。为此,我将需要以下步骤:
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
全部0条评论
快来发表一下你的评论吧 !