正确实施围墙跟随转向行为 简介代码关闭

问题描述

简介

一段时间以来,我一直在尝试按照Craig Reynold的here描述的转向行为来实施隔离墙。行为本质上可以归结为网站上的以下描述:

要实施跟踪墙,我们首先要预测车辆的 根据其当前速度在未来短时间内定位 (黑点)。这个未来的位置预计到最近的点 “墙”(红点)。沿着墙从此墙点移出 法线(红线)所需的偏移距离产生目标 点(红色圆圈)。

链接页面上有一个Java小程序,上面展示了上述内容,但是对于那些(大多数人)无法查看的Java小程序,请参见下面的.gif。

Wall following


我已经很接近了,但是由于某种原因,我的版本仍然略有下降。我的投标人似乎在选择下一个最近的墙像素时遇到麻烦,这导致投影的目标点出现抖动。这个问题非常极端,以至于有时没有一个新的计划就可以将目标赶到目标点。请参阅下面的.gif进行比较。

Wall following 2

简要介绍一下boid在我的实现中的运作方式:

  1. 在每个帧中,boid都会调用followWall()
  2. followWall()内,如果boid的成员变量hasHitWall为False,它将检查boid前面的点是否已降落在墙像素上(boid在其中移动的环境是黑白像素网格,其中黑色=墙)。
  3. 如果检测到墙像素,它将hasHitWall设置为True,并收集墙的所有连接的“边缘像素”,并将它们存储在名为currentEdgePixels的对象列表中。
  4. li>
  5. 下一帧,如果hasHitWall为True,则该Boid将通过迭代currentEdgePixels并找到与其position的距离最短的像素来找到最近的边缘像素。然后,它将拉动该墙像素的法线,并沿着法线向量将点投影一个设定距离。这成为“指导点”。
  6. 然后,Boid将使用其seek()行为来引导转向点(在Craig Reynold的描述中称为目标点)。
  7. 只要hasHitWall保持为True,Boid就会继续在currentEdgePixels内找到最接近的边缘像素并向其寻找。

简要说明:我完全理解,将壁的所有边缘像素存储在boid对象中并每帧检查每个像素都不理想且效率低下。这是一个临时设计,可以简化调试,一旦一切正常,我可能会重新设计。

代码


我上述行为的代码可以在下面找到。首先,对一些常见元素进行一些简要说明:

pixelGrid:此参数是代表图像行的列表的列表。表示行的列表中的每个元素都包含1或0,具体取决于该行/列位置的像素颜色是白色还是黑色。

getnormalizedVectorFromOrigin():此函数返回一个表示在[-1,1]范围内的单位圆上的矢量的元组。如果将一个向量(或点)传递到其未归一化向量在[-1,1]范围之外的函数中,则在返回之前,将减小所得向量以使其适合于适当范围。 Ex .:(1.7675,-1.7675)的向量将变为(0.707,-0.707)


followWall()

def followWall(self,pixelGrid,screenSize): 
        if (not self.hasHitWall):
            wallCollisionPixel = self.detectWall(pixelGrid,screenSize)
            if (wallCollisionPixel):
                self.hasHitWall = True
                self.currentEdgePixels = utils.findAllEdgePixels(wallCollisionPixel,screenSize)
                
        elif (self.hasHitWall):
            wallPixel = self.findClosestEdgePixel(pixelGrid,screenSize)       
            wallPixelnormal = utils.getEdgePixelnormal(wallPixel,screenSize)
            steeringPointdistance = 30
            steeringPoint = (int(round(wallPixel[0] + (wallPixelnormal[0] * steeringPointdistance),0)),int(round(wallPixel[1] + (wallPixelnormal[1] * steeringPointdistance),0)))
            self.seekPoint = steeringPoint
            self.seek(steeringPoint,1)

findClosestEdgePixel()

    def findClosestEdgePixel(self,screenSize):
        futuredistance = 20
        normalizedVeLocity = utils.getnormalizedVectorFromOrigin(self.veLocity.get())
        futurePosition = (int(round(self.position.x + (normalizedVeLocity[0] * futuredistance),int(round(self.position.y + (normalizedVeLocity[1] * futuredistance),0)))
        
        closestEdgePixel = self.currentEdgePixels[0]
        for edgePixel in self.currentEdgePixels:
            if (utils.getdistance(futurePosition,edgePixel) < utils.getdistance(futurePosition,closestEdgePixel)):
                closestEdgePixel = edgePixel
        return closestEdgePixel

getdistance()

def getdistance(point1,point2):
    return math.sqrt(((point2[0] - point1[0]) ** 2) + ((point2[1] - point1[1]) ** 2))

关闭

如果任何人可能对如何使我的实现工作得更好的想法,或者指出我的代码中可能导致此问题的缺陷,我将不胜感激。如果您认为可能有更好的方法来实现这种特殊的转向行为,我也很乐意听到建议。

请告诉我是否可以提供更多信息或部分代码。预先非常感谢。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)