Python探索Raspberry Pi机器人平台

随机轨迹

第一代机器人吸尘器在一个无限循环中使用了一种非常简单的算法:

  • 直行直到撞到障碍物
  • 转一个随机角度

如果您担心这种行为的清洁质量,那可能是对的。 但是从数学角度来看,如果给定无限的时间,只要机器人可以物理上到达,该算法将覆盖整个清洁区域。

随机驱动程序(下面Python程序)基本上由一个while循环组成,该循环一直运行到按下END键(KEY4)为止。

from eye import *
 from random import *

 safe=300
 LCDMenu("","","","END")

 while(KEYRead() != KEY4):
    OSWait(100)
    if(PSDGet(PSD_FRONT)>safe and PSDGet(PSD_LEFT)>safe and PSDGet(PSD_RIGHT)r>safe):
       VWStraight(100,200)
    else:
       VWStraight(-25,50)
       VWWait()
       dir=int(180*(random()-0.5))
       VWTurn(dir,45)
       VWWait()

我们在每次循环迭代中等待100毫秒(0.1秒)以减少计算开销。一条if选择,则在继续前进之前检查所有三个侧面是否有足够的空间(300毫米)。 如果不是,则机器人后退一小段距离(25毫米),然后旋转随机角度。 函数random()产生一个介于0和1之间的数字,因此项180 *(random()-0.5)产生一个介于–90和+90之间的值,该值定义了我们随机回合的可能范围。 在下一个循环迭代中,如果机器人沿新方向有足够的空间,它将再次直行。

下面Python程序使用相同算法的扩展版本。 它将PSD传感器的数值打印到显示器上,这要求将它们存储在变量f,l和r中。 每当旋转时,它还会打印一条有关机器人动作的消息,并不断读取并显示摄像机图像。

from eye import *
from random import *

safe=300
LCDMenu("","","","END")
CAMInit(QVGA)

while(KEYRead() != KEY4):
 OSWait(100)
 img = CAMGet()
 LCDImage(img)
 f=PSDGet(PSD_FRONT)
 l=PSDGet(PSD_LEFT)
 r=PSDGet(PSD_RIGHT)
 LCDSetPrintf(18,0,"PSD L%3d",l,f,r)
 
 if(l>safe and f>safe and r>safe):
  VWStraight(100,200)
 else:
  VWStraight(-25,50)
  VWWait()
  dir = int(180*(random()-0.5))
  LCDSetPrintf(19,0,"Turn %d",dir)
  VWTurn(dir,45)
  VWWait()
  LCDSetPrintf(19,0," ")

下图中的屏幕截图显示了机器人经过几条直腿后的驾驶。 我们将机器人足球运动场用作此任务的背景。

该程序的C版本与Python实现非常相似。 它只是使用不同的语法。 驱动结果完全相同–参见下面C程序。 相机被初始化为QVGA,并且其图像与PSD读数一起显示在前,左和右。 需要按KEY4(“ END”软键)以终止程序。

#include "eyebot.h"

#define SAFE 300

int main() {
  BYTE img[QVGA_SIZE];
  int dir, l, f, r;

  LCDMenu("", "", "", "END");
  CAMInit(QVGA);

  while (KEYRead() != KEY4) {
    CAMGet(img); // demo
    LCDImage(img); // only
    l = PSDGet(PSD_LEFT);
    f = PSDGet(PSD_FRONT);
    r = PSDGet(PSD_RIGHT);
    LCDSetPrintf(18, 0, "PSD L%3d F%3d R%3d", l, f, r);
    if (l > SAFE && f > SAFE && r > SAFE)
      VWStraight(100, 200); // start driving 100mm dist.
    else {
      VWStraight(-25, 50);
      VWWait(); // back up
      dir = 180 * ((float) rand() / RAND_MAX - 0.5);
      LCDSetPrintf(19, 0, "Turn %d", dir);
      VWTurn(dir, 45);
      VWWait(); // turn [-90, +90]
      LCDSetPrintf(19, 0, " ");
    }
    OSWait(100);
  } // while
  return 0;
}

由于机器人会因各种障碍而停下来,因此遇到另一个机器人时也会停下来。 因此,我们现在可以安全地让多个机器人在同一编程环境中运行。 为此,我们只需要为每个机械手添加一条额外的行到SIM脚本中即可。 在下面程序的脚本中,我们将启动三个不同的机器人-两个LabBots和一个SoccerBot S4。 此示例中的所有机械手都具有相同的可执行程序,但是您可以通过更改可执行文件名来轻松指定不同的程序。

# Environment
 world $HOME/worlds/small/Soccer1998.wld

 settings VIS TRACE

 # robotname x y phi
 LabBot 400 400 0 randomdrive.py
 S4 700 700 45 randomdrive.py
 LabBot 1000 1000 90 randomdrive.py

每个机器人增加一条额外的轨迹线很容易,但是如果您想为一个群体应用程序拥有100个机器人,即使这样也会很乏味。 对于这些应用程序,有一些适用于SIM脚本的通用方法。 下图3.4中显示了三个随机驱动机器人在其行动的各个阶段。

目标轨迹

随机驱动的相反方向是朝目标或目标行驶。 现在,假设这些点之间没有障碍,我们介绍许多让我们从A转向B的方法

下图显示了许多如何从A点(左上角的机器人位置)到B点(右下角的红色点)的方法。

我们可以

  • 转弯直至到达正确的方向,然后直接驶向目标(深绿线)
  • 沿着将A链接到B的圆弧(蓝线)行驶
  • 不断地将机器人的前进方向更改为回到目标位置(“狗形曲线”,浅绿色线)
  • 沿着计算出的三次样条曲线进行驱动,这也使我们可以在到达目标时指定所需的机器人方向(红线)

转向和直驱

在现场旋转然后直线驱动可能是从A到B的最简单方法。尽管机器人驱动的距离最短,但它可能无法在最短的时间内完成任务,因为它执行两个单独的动作 在转弯后必须完全停止才能开始直线行驶。

下面C程序显示了该算法。

圆形

除了旋转然后直线行驶外,我们还可以根据点A和B之间的距离以及线AB与机器人的初始航向之间的角差来计算所需的角速度。 然后,我们可以发出恒定曲率的单个驱动命令,形成一个圆弧。

和以前一样,我们使用函数atan2来计算目标方向和直接目标距离d的勾股公式。 总旋转角度由目标方向减去机器人的初始航向phi得出。 如图所示,

狗曲线

如果机器人保持恒定的速度并最初从其起始方向开始直线行驶,但随后在每一步中都将其角度校正至目标,则我们将以连续运动结束,在此运动中曲率在每个单个迭代步骤中都会发生变化。 产生的路径通常称为狗曲线,这表明狗追逐目标时遵循此原理。 该算法仍然非常简单,如下面C程序所示。

样条曲线

三次样条曲线是从A到B的更复杂的驱动方法,但是它们提供了以前的方法无法实现的功能。 样条曲线允许我们指定目标点B的方向,因此机器人将以指定的方向到达指定的点。 这对于许多应用程序来说非常重要。 例如,在机器人足球比赛中,我们希望机器人将球驱动到球上,但是它应该以可以将球踢向对手目标的角度接近球。

机器人嵌入式控制平台细节

机器人嵌入式控制平台仿真细节

机器人嵌入式控制平台功能

软件

算法

激光雷达

机器人群

行走

迷宫

视觉

转向

自主

详情参阅 - 亚图跨际

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值