🥬Python探索Raspberry Pi机器人平台
Python | Raspberry Pi | 机器人 | C/C++
随机轨迹
第一代机器人吸尘器在一个无限循环中使用了一种非常简单的算法:
直行直到撞到障碍物
转一个随机角度
如果您担心这种行为的清洁质量,那可能是对的。 但是从数学角度来看,如果给定无限的时间,只要机器人可以物理上到达,该算法将覆盖整个清洁区域。
随机驱动程序(下面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的方向,因此机器人将以指定的方向到达指定的点。 这对于许多应用程序来说非常重要。 例如,在机器人足球比赛中,我们希望机器人将球驱动到球上,但是它应该以可以将球踢向对手目标的角度接近球。
机器人嵌入式控制平台细节
机器人嵌入式控制平台仿真细节
机器人嵌入式控制平台功能
软件
算法
激光雷达
机器人群
行走
迷宫
视觉
转向
自主
Last updated