机器人路径规划:基于双向A*算法(bidirectional a star)的机器人路径规划(提供Python代码)

一、双向A*算法简介

传统A*算法是一种静态路网中求解最短路径最有效的方法, 它结合了BFS 算法和迪杰斯特拉算法(Dijkstra)的优点。 和迪杰斯特拉算法(Dijkstra)一样, A*算法能够用于 搜索最短路径; 和BFS 算法一样, A*算法可以用 启发式函数引导给出当下的最佳解。 传统A*算法的重点在于扩展下一个节点时引入了启发式函数 h(n), 对当前节点到目标节点的距离代价进行了评 估。 通过计算函数的相对最优解来筛选当前节点周 围的扩展节点, 能适用于各种场景, 相当灵活。

双向A*算法具体操作步骤如下:

1) 建立两个open列表和两个close列表, open 列表用来存放正反方向上已经生成但还没有被遍历 即等待检查的节点数据, close列表用来记录正反方 向上已访问过的即不需要再检查的节点数据。

2) 将开始结点和目标节点分别放在两个open 列表中作为当前节点, 对它所有的可达到且没有标 记过的子节点进行扩展, 由于此时待搜索的节点只 有一个, 即开始结点和目标节点的评估值肯定为最 优值, 则将这两个节点分别加入到两个close列 表中。

3) 对open 列表中的子节点计算评估值, 按照 评估值的大小进行排列, 找出评估值最小的节点, 并给它作标记加入到对应的close列表中。

4) 如果满足搜索条件, 表示找到路径, 停止搜 索; 否则将该节点继续进行扩展, 重复执行第三步; 或者open列表空了, 表示没有路径。

5) 从两个close列表的相遇节点开始进行父亲 节点遍历, 规划出最终的路径。

参考文献:

[1]刘梦杰,朱希安,王占刚,等.基于双向A*算法的矿井水灾逃生路径应用研究[J].煤炭工程, 2019(9):6.DOI:CNKI:SUN:MKSJ.0.2019-09-011.

二、部分代码

import math

import matplotlib.pyplot as plt

show_animation = False


class BidirectionalAStarPlanner:

    def __init__(self, ox, oy, resolution, rr):
        """
        Initialize grid map for a star planning

        ox: x position list of Obstacles [m]
        oy: y position list of Obstacles [m]
        resolution: grid resolution [m]
        rr: robot radius[m]
        """

        self.min_x, self.min_y = None, None
        self.max_x, self.max_y = None, None
        self.x_width, self.y_width, self.obstacle_map = None, None, None
        self.resolution = resolution
        self.rr = rr
        self.calc_obstacle_map(ox, oy)
        self.motion = self.get_motion_model()

    class Node:
        def __init__(self, x, y, cost, parent_index):
            self.x = x  # index of grid
            self.y = y  # index of grid
            self.cost = cost
            self.parent_index = parent_index

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

三、部分结果

四、完整Python代码

见下方联系方式

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是基于栅格地图的BiLSTM改进的A*算法路径规划Python代码: ```python import numpy as np import torch import torch.nn as nn import torch.optim as optim import torch.nn.functional as F # 定义BiLSTM模型 class BiLSTM(nn.Module): def __init__(self, input_size, hidden_size, num_layers, num_classes): super(BiLSTM, self).__init__() self.hidden_size = hidden_size self.num_layers = num_layers self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True, bidirectional=True) self.fc = nn.Linear(hidden_size*2, num_classes) def forward(self, x): h0 = torch.zeros(self.num_layers*2, x.size(0), self.hidden_size).to(device) c0 = torch.zeros(self.num_layers*2, x.size(0), self.hidden_size).to(device) out, _ = self.lstm(x, (h0, c0)) out = self.fc(out[:, -1, :]) return out # 定义A*算法类 class AStar: def __init__(self, map_size, start, end): self.map_size = map_size self.start = start self.end = end self.open_list = [] self.close_list = [] self.father = {} self.g_score = {} self.h_score = {} self.f_score = {} self.bi_lstm = None # 定义启发函数 def heuristic(self, a, b): return np.sqrt((a[0]-b[0])**2 + (a[1]-b[1])**2) # 定义判断点是否在地图内 def in_map(self, point): return point[0]>=0 and point[0]<self.map_size[0] and point[1]>=0 and point[1]<self.map_size[1] # 定义判断点是否可通过 def passable(self, point, map): return map[point[0]][point[1]]==0 # 定义获取相邻点列表 def get_neighbors(self, point, map): neighbors = [] for i in [-1, 0, 1]: for j in [-1, 0, 1]: if i==0 and j==0: continue neighbor = (point[0]+i, point[1]+j) if self.in_map(neighbor) and self.passable(neighbor, map): neighbors.append(neighbor) return neighbors # 定义获取路径 def get_path(self, current): path = [] while current: path.append(current) current = self.father.get(current) path.reverse() return path # 定义A*算法函数 def astar(self, map): self.open_list.append(self.start) self.g_score[self.start] = 0 self.h_score[self.start] = self.heuristic(self.start, self.end) self.f_score[self.start] = self.h_score[self.start] while self.open_list: current = min(self.open_list, key=lambda x:self.f_score[x]) if current == self.end: return self.get_path(current) self.open_list.remove(current) self.close_list.append(current) for neighbor in self.get_neighbors(current, map): if neighbor in self.close_list: continue g = self.g_score[current] + self.heuristic(current, neighbor) if neighbor not in self.open_list: self.open_list.append(neighbor) self.h_score[neighbor] = self.heuristic(neighbor, self.end) self.g_score[neighbor] = g self.f_score[neighbor] = self.g_score[neighbor] + self.h_score[neighbor] self.father[neighbor] = current elif g < self.g_score[neighbor]: self.g_score[neighbor] = g self.f_score[neighbor] = self.g_score[neighbor] + self.h_score[neighbor] self.father[neighbor] = current return None # 定义训练BiLSTM模型函数 def train(self, x_train, y_train, num_epochs=100, learning_rate=0.001): self.bi_lstm = BiLSTM(2, 128, 2, 2).to(device) criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(self.bi_lstm.parameters(), lr=learning_rate) for epoch in range(num_epochs): inputs = torch.Tensor(x_train).to(device) targets = torch.Tensor(y_train).long().to(device) optimizer.zero_grad() outputs = self.bi_lstm(inputs) loss = criterion(outputs, targets) loss.backward() optimizer.step() if (epoch+1) % 10 == 0: print('Epoch [{}/{}], Loss: {:.4f}'.format(epoch+1, num_epochs, loss.item())) # 定义预测函数 def predict(self, x): inputs = torch.Tensor(x).to(device) outputs = self.bi_lstm(inputs) _, predicted = torch.max(outputs.data, 1) return predicted.cpu().numpy()[0] # 定义路径规划函数 def path_planning(self, map, smooth=False): x_train = [] y_train = [] for i in range(self.map_size[0]): for j in range(self.map_size[1]): if (i,j) == self.start or (i,j) == self.end: continue x_train.append([i,j]) y_train.append(int(map[i][j])) self.train(x_train, y_train) current = self.start path = [current] while current != self.end: neighbors = self.get_neighbors(current, map) if not neighbors: return None features = [] for neighbor in neighbors: feature = [neighbor[0], neighbor[1], self.heuristic(neighbor, self.end)] feature.append(self.predict([feature])) features.append(feature) features = np.array(features) index = np.argmin(features[:,2] + features[:,3]*0.5) next = tuple(features[index][:2].astype(int)) path.append(next) current = next if smooth: return self.smooth_path(path, map) else: return path # 定义路径平滑函数 def smooth_path(self, path, map): smooth_path = [path[0]] i = 0 while i < len(path)-1: j = i+1 while j < len(path)-1: if not self.passable(path[i], path[j], map): break j += 1 smooth_path.append(path[j-1]) i = j-1 smooth_path.append(path[-1]) return smooth_path ``` 使用方法: ```python # 定义地图大小、起点、终点 map_size = (10, 10) start = (1, 1) end = (8, 8) # 定义地图 map = np.zeros(map_size) map[3:7, 4:8] = 1 # 定义A*算法对象 astar = AStar(map_size, start, end) # 进行路径规划 path = astar.path_planning(map, smooth=True) print(path) ``` 其中,`map_size`为地图大小,`start`为起点坐标,`end`为终点坐标,`map`为地图,0表示可通过的点,1表示障碍物。`path_planning`函数的第二个参数`smooth`表示是否对路径进行平滑处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值