机器人路径规划中基于栅格地图的A星搜索算法

在机器人路径规划中,基于栅格地图的A*搜索算法是一种非常流行且高效的方法。它结合了启发式搜索和图搜索的优点,能够在复杂的环境中快速找到从起点到终点的最优路径。以下是对该算法的详细说明,包括其原理、实现步骤以及一个简单的MATLAB实现示例。

1. A*搜索算法原理

A算法是一种启发式搜索算法,它通过评估每个节点的代价来选择最优路径。A 算法的核心思想是利用启发式函数 h(n)h(n)h(n) 来估计从当前节点 n 到目标节点的代价,同时结合实际代价 g(n)g(n)g(n) 来评估每个节点的总代价 f(n)f(n)f(n) :
f(n)=g(n)+h(n)f(n) = g(n) + h(n)f(n)=g(n)+h(n)

  • g(n)g(n)g(n) :从起点到当前节点 n 的实际代价。
  • h(n)h(n)h(n) :启发式函数,估计从当前节点 n 到目标节点的代价。
  • f(n)f(n)f(n) :总代价,用于选择最优路径。

2. 基于栅格地图的路径规划

在栅格地图中,环境被划分为一个个离散的单元格,每个单元格可以是可通行的(自由空间)或不可通行的(障碍物)。机器人只能在可通行的单元格之间移动。

2.1 算法步骤
  1. 初始化

    • 将起点加入开放列表(Open List),并设置其 g 、 h 和 f 值。
    • 初始化关闭列表(Closed List)为空。
  2. 主循环

    • 从开放列表中选择 f 值最小的节点作为当前节点。
    • 如果当前节点是目标节点,则路径搜索成功,通过回溯父节点构建路径。
    • 否则,将当前节点从开放列表中移除,并加入关闭列表。
    • 对当前节点的每个邻居节点进行处理:
      • 如果邻居节点是障碍物或已在关闭列表中,则跳过。
      • 如果邻居节点不在开放列表中,则将其加入开放列表,并设置其g 、 h 和 f 值。
      • 如果邻居节点已在开放列表中,但通过当前节点到达该邻居节点的代价更低,则更新其 g 和 f 值,并设置其父节点为当前节点。
  3. 终止条件

    • 如果开放列表为空且未找到目标节点,则路径搜索失败。
    • 如果找到目标节点,则路径搜索成功。

3. MATLAB实现

matlab 复制代码
function [path, openList, closedList] = AStarSearch(gridMap, start, goal)
    % 输入参数:
    % gridMap - 栅格地图,0表示可通行,1表示障碍物
    % start - 起点坐标 [x, y]
    % goal - 目标点坐标 [x, y]

    % 初始化
    [rows, cols] = size(gridMap);
    openList = [];
    closedList = false(rows, cols);
    g = inf(rows, cols);
    h = manhattanDistance(gridMap, goal);
    f = g + h;
    parent = zeros(rows, cols, 2);

    % 起点
    startNode = struct('position', start, 'g', 0, 'h', h(start(2), start(1)), 'f', 0 + h(start(2), start(1)));
    openList = [openList; startNode];
    g(start(2), start(1)) = 0;
    f(start(2), start(1)) = 0 + h(start(2), start(1));

    % 主循环
    while ~isempty(openList)
        % 选择f值最小的节点
        [~, idx] = min([openList.f]);
        currentNode = openList(idx);
        openList(idx) = [];
        currentPos = currentNode.position;

        % 检查是否到达目标
        if isequal(currentPos, goal)
            disp('路径搜索成功!');
            path = reconstructPath(parent, start, goal);
            return;
        end

        % 将当前节点加入关闭列表
        closedList(currentPos(2), currentPos(1)) = true;

        % 遍历邻居节点
        neighbors = getNeighbors(currentPos, rows, cols);
        for i = 1:size(neighbors, 1)
            neighborPos = neighbors(i, :);
            if gridMap(neighborPos(2), neighborPos(1)) == 1 || closedList(neighborPos(2), neighborPos(1))
                continue; % 跳过障碍物或已关闭的节点
            end

            % 计算移动代价
            tentative_g = currentNode.g + 1; % 假设每次移动代价为1

            % 如果邻居节点不在开放列表中,或新的g值更小
            if tentative_g < g(neighborPos(2), neighborPos(1))
                parent(neighborPos(2), neighborPos(1), :) = currentPos;
                g(neighborPos(2), neighborPos(1)) = tentative_g;
                f(neighborPos(2), neighborPos(1)) = tentative_g + h(neighborPos(2), neighborPos(1));

                % 如果邻居节点不在开放列表中,加入开放列表
                if ~ismember(neighborPos, [openList.position], 'rows')
                    neighborNode = struct('position', neighborPos, 'g', tentative_g, ...
                        'h', h(neighborPos(2), neighborPos(1)), 'f', tentative_g + h(neighborPos(2), neighborPos(1)));
                    openList = [openList; neighborNode];
                end
            end
        end
    end

    % 如果未找到路径
    disp('未找到路径');
    path = [];
end

function h = manhattanDistance(gridMap, goal)
    % 曼哈顿距离启发式函数
    [rows, cols] = size(gridMap);
    h = zeros(rows, cols);
    for i = 1:rows
        for j = 1:cols
            h(i, j) = abs(j - goal(1)) + abs(i - goal(2));
        end
    end
end

function neighbors = getNeighbors(pos, rows, cols)
    % 获取当前节点的邻居节点
    directions = [0 1; 1 0; 0 -1; -1 0]; % 上、右、下、左
    neighbors = [];
    for i = 1:size(directions, 1)
        neighborPos = pos + directions(i, :);
        if neighborPos(1) >= 1 && neighborPos(1) <= cols && neighborPos(2) >= 1 && neighborPos(2) <= rows
            neighbors = [neighbors; neighborPos];
        end
    end
end

function path = reconstructPath(parent, start, goal)
    % 从父节点信息中重建路径
    path = [];
    currentPos = goal;
    while ~isequal(currentPos, start)
        path = [currentPos; path];
        currentPos = parent(currentPos(2), currentPos(1), :);
    end
    path = [start; path];
end

4. 使用示例

matlab 复制代码
% 定义栅格地图
gridMap = [0 0 0 0 0;
           0 1 1 0 0;
           0 1 0 0 0;
           0 0 0 1 0;
           0 0 0 0 0];

% 定义起点和目标点
start = [1, 1];
goal = [5, 5];

% 调用A*搜索算法
[path, openList, closedList] = AStarSearch(gridMap, start, goal);

% 可视化路径
figure;
imagesc(gridMap);
hold on;
plot(start(1), start(2), 'go', 'MarkerSize', 10, 'LineWidth', 2);
plot(goal(1), goal(2), 'ro', 'MarkerSize', 10, 'LineWidth', 2);
if ~isempty(path)
    plot(path(:, 1), path(:, 2), 'b', 'LineWidth', 2);
end
axis equal;

参考代码 机器人路径规划中基于栅格地图的A*搜索算法] www.youwenfan.com/contentcsm/53191.html

5. 输出结果

运行上述代码后,MATLAB将输出路径搜索结果,并在栅格地图上可视化路径。如果找到路径,path变量将包含从起点到目标点的路径坐标;否则,path为空。

6. 总结

基于栅格地图的A*搜索算法是一种高效且实用的路径规划方法,特别适用于机器人导航和自动驾驶等领域。通过合理设计启发式函数和优化搜索过程,可以进一步提高算法的性能和效率。

相关推荐
点云SLAM2 小时前
点云配准算法之-Voxelized GICP(VGICP)算法
算法·机器人·gpu·slam·点云配准·vgicp算法·gicp算法
m0_689618286 小时前
会“变形”的软3D电磁结构,让4D电子、柔性机器人迎来新可能
笔记·学习·机器人
FateRing9 小时前
使用SLAM Toolbox 定位模式进行nav导航
机器人
King's King9 小时前
码垛机器人编程及解析
机器人
DAdaguai212 小时前
2026-2032年机器学习操作 (MLOps)行业增长37.4%趋势分析报告
机器学习·机器人
科普瑞传感仪器14 小时前
从“盲操作”到“智能感知”:六维力传感器解决装配卡死的创新方案
人工智能·科技·物联网·机器人·无人机·1024程序员节
PNP Robotics14 小时前
[PNP具身风向]ABB出售机器人业务的深层逻辑:历史积淀与面向未来具身工业智能时代转型的必然抉择
人工智能·机器人
GAOJ_K14 小时前
滚柱导轨中如何判断润滑状态?
科技·机器人·自动化·制造
中國龍在廣州16 小时前
李飞飞最新思考:语言模型救不了机器人
人工智能·深度学习·算法·语言模型·自然语言处理·chatgpt·机器人