我最近在做一个项目,这是第一个涉及到足以使传感器网络复杂化的项目。最后,我认为沟通是整体性能的瓶颈,我想知道更有经验的人会如何解决这个问题。这是一个很长的阅读,但我认为它很有趣,所以请坚持下去。问题是设计一种能够在障碍物路线上航行并将乒乓球投向棕色盒子目标的自主飞艇。开始:
传感器
- 4D Systems uCAM-TTL 相机模块 - UART 接口
- HMC6352 数字罗盘 - I2C 接口
- Maxbotix Sonar ez4 - 1 针模拟接口
执行器
- 2 个 L293D 电机驱动器(连接到简单的爱好电机) - 这些用于双向驱动 6 个电机。他们需要 PWM 输入来改变速度。现在我们的 3 个电机总是在做同样的事情(控制向上/向下运动的那些),所以它们只需要来自我们的控制器的 2 个 PWM 输出来控制所有 3 个电机。控制横向运动的其他 3 个电机都需要单独控制(用于全方位运动),因此我们的控制器需要另外 6 个 PWM 输出。
- 伺服电机 - PWM接口
控制器
出于稍后会清楚的原因,我们最终使用了 2x ATmega328P。我们使用 Arduino Uno 对它们进行编程(我们无法访问 ISP)但我们制造了一个定制的 PCB,因此我们不必使用 arduino 板,因为这只会给我们的飞艇增加不必要的重量。至于我们为什么选择 ATmega328P,我对 arduino 环境非常熟悉,我认为这让代码开发变得更快更容易。
通讯与处理
- 2x Xbee 基础版
- 2x ATmega328P
- 使用 openCV 运行 C++ 的台式计算机
从相机模块可以看出,我们的大部分项目都依赖于计算机视觉。飞艇只能承载这么大的重量,我们对在微控制器上实现计算机视觉感到不舒服。所以我们最终做的是使用 XBee 将图像数据传递回台式计算机。所以在服务器端,我们接收图像数据并使用 openCV 处理图像并从中找出一些东西。现在服务器端还需要知道高度信息(来自声纳)和指南针信息。
第一个问题是我们无法让相机由微控制器控制,原因有几个。主要问题是 uP 的内部存储器无法处理存储整个帧。通过巧妙的编码可能有解决这个问题的方法,但出于这个问题的目的,让我们假设这是不可能的。所以为了解决这个问题,我们让服务器端通过 XBee 收发器发送相机命令,并且 XBee 接收器(在飞艇上)的输出连接到相机的输入。
下一个问题是单个 ATmega328P 上没有足够的 PWM 来控制所有电机,因为 I2C 接口使用了一个 PWM 引脚(该死的……)。这就是为什么我们决定使用第二个。无论如何,该代码实际上非常适合并行处理,因为高度控制完全独立于横向移动控制(因此 2 微可能比连接到 PWM 控制器的更好)。因此,U1 负责 2 个 PWM 输出(向上/向下)并读取声纳。U2 负责读取罗盘、控制 6 个 PWM 输出(横向电机)以及读取声纳。U2 还负责通过 XBee 接收来自服务器的命令。
这导致了我们的第一个沟通问题。XBee DOUT 线连接到微控制器和相机。当然,现在我们设计了一个协议,以便我们的微命令将忽略相机命令,而相机命令将忽略微命令,这很好。然而,当忽略我们的微指令时,相机会在其输出线上发回 NAK 数据。由于该命令是针对 micro 的,我们需要以某种方式关闭到 XBee 的相机输出。为了解决这个问题,我们制作了微控制器 2 个 FET,它们位于相机和 XBee(这是第一个 FET)之间以及 U2 和 XBee(这是第二个 FET)之间。因此,当摄像机试图将信息发送回服务器时,第一个 FET 处于“开启”状态,而第二个 FET 处于“关闭”状态。
因此,为了让您了解它是如何工作的,这里有几个例子:
- 服务器请求一张图片 - PIC_REQUEST 通过 XBee 并到达 U2 和相机。U2 忽略它,相机发回图像数据。
- 服务器刚刚处理完一张图片并正在发送电机数据以告诉飞艇右转 - MOTOR_ANGLE(70) 通过 XBee 到达 U2 和摄像头。U2 识别为微命令,因此关闭了相机的 FET(但也许相机已经用 NAK 响应了?谁知道……)。U2 然后通过改变电机 PWM 输出来响应命令。然后它会重新打开相机的 FET(这是默认设置,因为图像数据是最重要的)。
- 服务器意识到我们已经到了障碍路线中的一个点,我们的默认悬停高度现在需要为 90 英寸而不是 50 英寸。SET_HEIGHT 通过 XBee,发生与示例 2 相同的事情。U2 识别 SET_HEIGHT 命令并在 U1 上触发中断。U1 现在从它的高度控制回路中出来并等待从 U2 接收串行数据。没错,更多的串行数据。此时 U2 的 FET 开启(相机的 FET 关闭),因此服务器接收到 U2 也发送给 U1 的高度。那是出于验证目的。现在 U1 为 height2HoverAt 重置其内部变量。U2 现在关闭它的 FET 并重新打开相机 FET。
我肯定遗漏了大量信息,但我认为这足以理解一些复杂性。最后,我们的问题只是同步一切。有时缓冲区中会留下数据,但只有 3 个字节(我们所有的命令都是 6 个字节序列)。有时我们会失去与相机的连接,不得不重新同步它。
所以我的问题是:你们建议哪些技术可以使所有这些组件之间的通信更可靠/健壮/更简单/更好?
例如,我知道有人会在板载 XBee 输出和摄像头之间添加一个延迟电路,以便微型在响应带有 NAK 的微型命令之前有机会关闭摄像头的通话线路。还有其他类似的想法吗?
谢谢,我相信这将需要很多编辑,所以请继续关注。
编辑1:对我们来说,通过其中一个微控制器拼接相机的 UART 数据似乎是不可能的。相机数据有两个选项,原始位图或 JPEG。对于原始位图,相机会尽可能快地向您发送数据。ATmega328P 只有 128 字节的串行缓冲区(技术上这是可配置的,但我不确定如何配置),我们认为我们无法足够快地将其从缓冲区中取出并通过 XBee。这留下了 JPEG 方法,它发送每个包并等待控制器确认它(小握手协议)。这可以达到的最快速度是 115200 波特。现在由于某种原因,我们可以通过 XBee 可靠地传输大量数据的最快速度是 57600 波特(即使在我们进行了节点/网络配对以允许自动重新发送功能之后)。在我们的网络中添加额外的停止(相机到微型到 XBee,而不仅仅是相机到 XBee)只是简单地减慢了传输图像所需的时间。我们需要一定的图像刷新率才能使我们的电机控制算法正常工作。