迷雾知道像你工作一样努力打球的重要性。这就是为什么她愿意冒险在她的跟随球技能一些草污渍。

在这项技能中,Misty 使用 Pixy2 视觉传感器的物体识别功能,在足球在房间里移动时追逐它。以下是其工作原理的高级概述:

  • Pixy2 – “经过训练”以识别和检测足球 – 将图像数据发送到连接到 Misty 的微控制器。
  • 微控制器计算距离,并从 Misty 到球的方向,然后通过内置于 Misty 背面的 UART 串行端口将这些值发送到在 Misty 上运行的代码。
  • 当 Misty 收到这些数据时,她将其转换为线性和角速度值,用于驱动命令,并朝球或远离球移动。
  • Pixy2 向微控制器发送更新的信息,该过程会随着新的图像数据而重复。

这篇文章分解每个点在一点点的细节,所以你可以建立自己的跟随球技能的迷雾。我们先看看Pixy2。

刺激皮西2

Pixy2是一种用于机器人的闪电式快速视觉传感器。训练 Pixy2 识别物体非常简单,只需将物体放在传感器前面并按下按钮即可。它专为轻松连接微控制器(如 Arduino 或树莓派)而构建,Pixy 提供库以简化代码中的图像数据使用。

在”跟随球”技能中,我们使用微控制器上的 ISCP 连接器将 Pixy 连接到雾(与 Arduino 兼容)背包。我们使用3D 打印附件将传感器正面和中心位置放在 Misty 的底座上。完成此设置后,我们”教”传感器识别足球,将其指向正确的方向并按住 Pixy2 上的按钮。

是的。这就是它的所有。

现在,Pixy2 知道该对象,我们准备为微控制器编写代码。

准备微控制器

为了这一技能,Misty在她自己与Arduino兼容的背包中使用微控制器。此微控制器是Arduino Uno的克隆,在一些重要方面进行了更改。其中一个变化是增加了磁铁,将电路板连接到 Misty 的背面,以便直接连接到她的 UART 串行端口。

与编程阿杜诺乌诺相同的工具写素描。为了处理来自视觉传感器的数据,我们在草图中包括Pixy2 Arduino 库。

#include <Pixy2.h>

// This is the main Pixy object 
Pixy2 pixy;

我们在草图的函数中初始化了 pixy setup() 对象。Serial.begin()串行库中的函数打开串行端口,并将数据传输速率设置为 9600 波特(这是与 Misty 的 UART 串行端口通信的速率)。我们还设置了用于计算球运动的几个变量的值。

void setup()
{

  //Serial.print("Starting...\n");
  pixy.init();
  OLD = 0;
  towards = 0;
  Serial.begin(9600);
}

在她执行她的驱动命令之前,Misty需要知道她相对于球的位置。具体来说,她需要知道她的方向或她面对的方向和球的位置之间的角度。她还需要知道球离她的距离和它目前的运动方向。

loop()此草图中的函数每 200 毫秒将所有此信息传输到 Misty 一次。在 loop() 函数中,我们调用 pixy.ccc.getBlocks() 返回有关视觉传感器检测到的对象的数据。此数据包括帧中对象的宽度和高度(以像素为单位),这让我们大致了解球与 Misty 的接近程度。尺寸越大越近,越小越远。


通过计算图像中心与框架中球中心的 X 坐标之间的差异,我们得到 Misty 的标题。要确定球移动的方向,我们将此值与最后一个循环的风向角度进行比较。

然后,我们将所有这些数据打包 size pan direction 到字符串化的 JSON 对象中,并使用 将其发送到 Serial.println() Misty。请查看 GitHub 上的草图,或查看 loop() 下面的函数。

void loop()
{ 
  pixy.ccc.getBlocks();
  if (pixy.ccc.numBlocks) {

       // ~Max size of the ball in pixels
       sizeMin = min(pixy.ccc.blocks[0].m_width, pixy.ccc.blocks[0].m_height);
       sizeMax = max(pixy.ccc.blocks[0].m_width, pixy.ccc.blocks[0].m_height);

       if (sizeMin >10) {

          // Heading to ball
          panOffset = (int32_t)pixy.frameWidth/2 - (int32_t)pixy.ccc.blocks[0].m_x;

          // Calculate direction of motion
          NEW = panOffset;
          if (abs(NEW-OLD) > 20) {
            //towards = sign(NEW-OLD,DEC)*1;
            if (NEW-OLD <0) { towards = -1;}
            else { towards = 1;}
            OLD = NEW;
            count = 0;
          } 

          if (abs(NEW-OLD) < 10){
            count++;
            if (count>30){
              towards = 0;
            }
          }
          // This data is sent to misty
          Serial

编码迷雾

在 Misty 上运行的代码处理微控制器发送的每条消息。它将这些数据转换为参数,当传递给 Misty 的驱动命令时,将她移近(或远离)球。

为了在技能中管理此项,我们使用 misty.RegisterEvent() 注册 SerialMessage 事件。每次微控制器通过 Misty 的 UART 串行端口上的接收器 (RX) 引脚发送消息时,都会发生这些事件。

function sub_arduino(){
    misty.AddReturnProperty("SerialMessage", "SerialMessage");
    misty.RegisterEvent("SerialMessage", "SerialMessage", 0, true);
}

默认情况下, SerialMessage 当事件发生时,技能会查找 _SerialMessage() 用于传递事件数据的回调函数。此数据包括微控制器发送到 Misty 的任何消息。在回调的函数定义中定义如何处理此 _SerialMessage() 数据。

function _SerialMessage(data) { 
// Process incoming message from Misty's UART serial
}

在”跟随球”技能中, _SerialMessage() 回调从微控制器中解析数据并将其转换为 linearVelocity 该方法 angularVelocity misty.Drive() 的值。每个值都是 -100 和 100 之间的整数。对于 linearVelocity ,值 -100 转换为”以最大速度向后驱动”,而 100 表示”以最大速度向前驱动”。对于 angularVelocity ,-100 表示”以最大速度顺时针旋转”,100 表示”以最大速度逆时针旋转”。

我们使用 Pixy2 图像中的球的大小来计算 linearVelocity 参数的适当值。如果球看起来比它应该小,Misty会朝它开去,如果球看起来更大,她就退后。的值与 angularVelocity Misty 的标题相关联 – 我们计算一个值,该值使 Misty 在曲线中旋转或驱动,向球方向移动。请参阅第 35 – 72 followBall.js 行,了解这些计算在代码中的进行方式。

每次微控制器发送新图像数据时,Misty 都会重新计算这些值,因此她不断调整相对于球的速度和位置。所有这些都构成了一个动态有趣的机器人,优化了可爱。

可扩展性意味着无限潜力

你很难找到一个机器人,他的硬件使每一个你梦想的工作。这就是可扩展平台如此引人注目的原因。具有强大的原生功能的机器人,您可以使用第三方硬件进行增强,有很多就业机会,更不用说创造性的娱乐了。请查看以下视频,了解更多:

不要错过GitHub 上的”关注球”技能的完整存储库,如果您对更多有关机器人的讨论感兴趣,请务必加入本文(和其他文章)。

Comments are closed.