Python 在星型算法中,我们是如何给出八个方向的值的?

Python 在星型算法中,我们是如何给出八个方向的值的?,python,a-star,motion-planning,Python,A Star,Motion Planning,我正在尝试基于此代码实现我自己的代码。当我阅读这段代码时,我对这部分感到困惑。以下功能的一部分: def get_motion_model(): # dx, dy, cost motion = [[1, 0, 1], [0, 1, 1], [-1, 0, 1], [0, -1, 1], [-1, -1, math.sqrt(2)], [-1,

我正在尝试基于此代码实现我自己的代码。当我阅读这段代码时,我对这部分感到困惑。以下功能的一部分:

def get_motion_model():
    # dx, dy, cost
    motion = [[1, 0, 1],
              [0, 1, 1],
              [-1, 0, 1],
              [0, -1, 1],
              [-1, -1, math.sqrt(2)],
              [-1, 1, math.sqrt(2)],
              [1, -1, math.sqrt(2)],
              [1, 1, math.sqrt(2)]]

    return motion
作者是如何给出这些值的?。我知道我们什么时候开始检查8个邻居,但这些数字是多少?。我指的是这些[1,0,1]等等。如果我想为3D生成什么呢

下面是一个星形算法Python代码:

"""
A* grid based planning
See Wikipedia article (https://en.wikipedia.org/wiki/A*_search_algorithm)
"""

import matplotlib.pyplot as plt
import math

show_animation = True


class Node:

    def __init__(self, x, y, cost, pind):
        self.x = x
        self.y = y
        self.cost = cost
        self.pind = pind

    def __str__(self):
        return str(self.x) + "," + str(self.y) + "," + str(self.cost) + "," + str(self.pind)


def calc_final_path(ngoal, closedset, reso):
    # generate final course
    rx, ry = [ngoal.x * reso], [ngoal.y * reso]
    pind = ngoal.pind
    while pind != -1:
        n = closedset[pind]
        rx.append(n.x * reso)
        ry.append(n.y * reso)
        pind = n.pind

    return rx, ry


def a_star_planning(sx, sy, gx, gy, ox, oy, reso, rr):
    """
    gx: goal x position [m]
    gx: goal x position [m]
    ox: x position list of Obstacles [m]
    oy: y position list of Obstacles [m]
    reso: grid resolution [m]
    rr: robot radius[m]
    """

    nstart = Node(round(sx / reso), round(sy / reso), 0.0, -1)
    ngoal = Node(round(gx / reso), round(gy / reso), 0.0, -1)
    ox = [iox / reso for iox in ox]
    oy = [ioy / reso for ioy in oy]

    obmap, minx, miny, maxx, maxy, xw, yw = calc_obstacle_map(ox, oy, reso, rr)

    motion = get_motion_model()

    openset, closedset = dict(), dict()
    openset[calc_index(nstart, xw, minx, miny)] = nstart

    while 1:
        c_id = min(
            openset, key=lambda o: openset[o].cost + calc_heuristic(ngoal, openset[o]))
        current = openset[c_id]

        # show graph
        if show_animation:  # pragma: no cover
            plt.plot(current.x * reso, current.y * reso, "xc")
            if len(closedset.keys()) % 10 == 0:
                plt.pause(0.001)

        if current.x == ngoal.x and current.y == ngoal.y:
            print("Find goal")
            ngoal.pind = current.pind
            ngoal.cost = current.cost
            break

        # Remove the item from the open set
        del openset[c_id]
        # Add it to the closed set
        closedset[c_id] = current

        # expand search grid based on motion model
        for i, _ in enumerate(motion):
            node = Node(current.x + motion[i][0],
                        current.y + motion[i][1],
                        current.cost + motion[i][2], c_id)
            n_id = calc_index(node, xw, minx, miny)

            if n_id in closedset:
                continue

            if not verify_node(node, obmap, minx, miny, maxx, maxy):
                continue

            if n_id not in openset:
                openset[n_id] = node  # Discover a new node
            else:
                if openset[n_id].cost >= node.cost:
                    # This path is the best until now. record it!
                    openset[n_id] = node

    rx, ry = calc_final_path(ngoal, closedset, reso)

    return rx, ry


def calc_heuristic(n1, n2):
    w = 1.0  # weight of heuristic
    d = w * math.sqrt((n1.x - n2.x)**2 + (n1.y - n2.y)**2)
    return d


def verify_node(node, obmap, minx, miny, maxx, maxy):

    if node.x < minx:
        return False
    elif node.y < miny:
        return False
    elif node.x >= maxx:
        return False
    elif node.y >= maxy:
        return False

    if obmap[node.x][node.y]:
        return False

    return True


def calc_obstacle_map(ox, oy, reso, vr):

    minx = round(min(ox))
    miny = round(min(oy))
    maxx = round(max(ox))
    maxy = round(max(oy))
    #  print("minx:", minx)
    #  print("miny:", miny)
    #  print("maxx:", maxx)
    #  print("maxy:", maxy)

    xwidth = round(maxx - minx)
    ywidth = round(maxy - miny)
    #  print("xwidth:", xwidth)
    #  print("ywidth:", ywidth)

    # obstacle map generation
    obmap = [[False for i in range(ywidth)] for i in range(xwidth)]
    for ix in range(xwidth):
        x = ix + minx
        for iy in range(ywidth):
            y = iy + miny
            #  print(x, y)
            for iox, ioy in zip(ox, oy):
                d = math.sqrt((iox - x)**2 + (ioy - y)**2)
                if d <= vr / reso:
                    obmap[ix][iy] = True
                    break

    return obmap, minx, miny, maxx, maxy, xwidth, ywidth


def calc_index(node, xwidth, xmin, ymin):
    return (node.y - ymin) * xwidth + (node.x - xmin)


def get_motion_model():
    # dx, dy, cost
    motion = [[1, 0, 1],
              [0, 1, 1],
              [-1, 0, 1],
              [0, -1, 1],
              [-1, -1, math.sqrt(2)],
              [-1, 1, math.sqrt(2)],
              [1, -1, math.sqrt(2)],
              [1, 1, math.sqrt(2)]]

    return motion


def main():
    print(__file__ + " start!!")

    # start and goal position
    sx = 10.0  # [m]
    sy = 10.0  # [m]
    gx = 50.0  # [m]
    gy = 50.0  # [m]
    grid_size = 1.0  # [m]
    robot_size = 1.0  # [m]

    ox, oy = [], []

    for i in range(60):
        ox.append(i)
        oy.append(0.0)
    for i in range(60):
        ox.append(60.0)
        oy.append(i)
    for i in range(61):
        ox.append(i)
        oy.append(60.0)
    for i in range(61):
        ox.append(0.0)
        oy.append(i)
    for i in range(40):
        ox.append(20.0)
        oy.append(i)
    for i in range(40):
        ox.append(40.0)
        oy.append(60.0 - i)

    if show_animation:  # pragma: no cover
        plt.plot(ox, oy, ".k")
        plt.plot(sx, sy, "xr")
        plt.plot(gx, gy, "xb")
        plt.grid(True)
        plt.axis("equal")

    rx, ry = a_star_planning(sx, sy, gx, gy, ox, oy, grid_size, robot_size)

    if show_animation:  # pragma: no cover
        plt.plot(rx, ry, "-r")
        plt.show()


if __name__ == '__main__':
    main()
“”“
A*基于网格的规划
参见维基百科文章(https://en.wikipedia.org/wiki/A*_搜索(U算法)
"""
将matplotlib.pyplot作为plt导入
输入数学
显示动画=真
类节点:
定义初始值(self、x、y、cost、pind):
self.x=x
self.y=y
自我成本=成本
self.pind=pind
定义(自我):
返回str(self.x)+“,”+str(self.y)+“,”+str(self.cost)+“,”+str(self.pind)
def计算最终路径(ngoal、closedset、reso):
#生成最终课程
rx,ry=[ngoal.x*reso],[ngoal.y*reso]
pind=ngoal.pind
而品脱!=-1:
n=关闭设置[pind]
接收附加(n.x*reso)
y.append(纽约*决议)
品脱
返回rx,ry
定义星级规划(sx、sy、gx、gy、ox、oy、reso、rr):
"""
gx:目标x位置[m]
gx:目标x位置[m]
ox:x障碍物位置列表[m]
oy:y位置障碍物列表[m]
分辨率:网格分辨率[m]
rr:机器人半径[m]
"""
nstart=节点(圆形(sx/reso),圆形(sy/reso),0.0,-1)
ngoal=节点(圆形(gx/reso),圆形(gy/reso),0.0,-1)
ox=[iox/reso表示iox在ox中]
oy=[ioy/reso代表oy中的ioy]
obmap,minx,miny,maxx,maxy,xw,yw=计算障碍物地图(ox,oy,reso,rr)
运动=获取运动模型()
openset,closedset=dict(),dict()
openset[calc_索引(nstart,xw,minx,miny)]=nstart
而1:
c_id=min(
openset,key=lambda o:openset[o]。成本+计算启发式(ngoal,openset[o]))
当前=开放集[c_id]
#显示图形
如果显示动画:#杂注:无封面
plt.绘图(当前x*分辨率,当前y*分辨率,“xc”)
如果len(closedset.keys())%10==0:
plt.暂停(0.001)
如果当前.x==ngoal.x且当前.y==ngoal.y:
打印(“查找目标”)
ngoal.pind=当前的.pind
ngoal.cost=当前成本
打破
#从打开的集合中删除该项
del openset[c_id]
#将其添加到闭合集
闭合集[c_id]=当前
#基于运动模型扩展搜索网格
就我而言,在列举(动议)中:
节点=节点(当前.x+运动[i][0],
当前.y+动议[i][1],
当前成本+动议[i][2],c_id)
n_id=计算索引(节点,xw,minx,miny)
如果n_id位于闭合集中:
持续
如果未验证_节点(节点、对象映射、最小值、最小值、最大值、最大值):
持续
如果n_id不在openset中:
openset[n_id]=节点#发现新节点
其他:
如果openset[n_id].cost>=node.cost:
#这条路是迄今为止最好的。录下来!
openset[n_id]=节点
rx,ry=计算最终路径(ngoal,closedset,reso)
返回rx,ry
def calc_启发式(n1,n2):
w=1.0#启发式权重
d=w*数学sqrt((n1.x-n2.x)**2+(n1.y-n2.y)**2)
返回d
def verify_节点(节点、对象映射、最小值、最小值、最大值、最大值):
如果node.x=maxx:
返回错误
elif node.y>=最大值:
返回错误
如果对象映射[node.x][node.y]:
返回错误
返回真值
def计算障碍物地图(ox、oy、reso、vr):
最小值=圆形(最小值(牛))
最小值=圆形(最小值(oy))
maxx=圆形(最大(牛))
最大值=圆形(最大值(oy))
#打印(“minx:,minx”)
#打印(“miny:,miny)
#打印(“maxx:,maxx”)
#打印(“maxy:,maxy”)
xwidth=圆形(最大-最小)
Y宽度=圆形(最大-最小)
#打印(“X宽度:”,X宽度)
#打印(“ywidth:,ywidth)
#障碍地图生成
obmap=[[范围内i为假(ywidth)]范围内i为假(xwidth)]
对于范围内的ix(X宽度):
x=ix+minx
对于范围内的iy(Y宽度):
y=iy+miny
#打印(x,y)
对于iox,拉链中的ioy(ox,oy):
d=数学sqrt((iox-x)**2+(ioy-y)**2)

如果d这些行上方的注释给出了线索:

# dx, dy, cost
这里的成本显然对应于欧几里德距离,即dx²+dy²的平方根

每个三元组代表一个方向:

  • x坐标的变化:可以是-1(向左),0(不沿x轴移动),(向右)
  • y坐标上的同时更改:可以是-1(向上)、0(不沿y轴移动)、1(向下)
  • 此移动表示的距离:如果上述两个数字中的一个为0,则方向为上、下、左、右,距离正好为1。然而,如果两个数字都不是零,那么我们有对角线移动(左上、右上、左下、右下),在这种情况下,距离是2的平方根
运动
也可以定义为:

motion = [[
    [dx, dy, math.sqrt(dx*dx+dy*dy)] 
        for dx in ([-1,0,1] if dy else [-1, 1])
] for dy in [-1,0,1]]
请注意,此欧几里德距离公式在代码后面也会出现,例如,用于计算路径剩余部分的启发式成本,作为当前单元格和目标单元格之间的距离

如果你想使用3D,那么每个方向有4个值:dx,dy,dz,距离是dx²+dy²+dz²的平方根:

  • 如果这三者中只有一个是1
  • 如果三者中的两个为1,则为2的平方根
  • 如果三个都不为零,则为3的平方根

非常感谢您的澄清,先生。动议