⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rectwave.m

📁 矩形波路径规划算法
💻 M
字号:
function path = RectWave(map, startPos, endPos)
%map——二维数组图 0: passable 1: obstacle
% startPos: Original Position
% endPos:   Target Postion
% Search the shortest path by rect wave propagation algorithm
% Rectwave should search the path from the DTM begin with principal
% neibourgh grids, else it will make zigzag path


%路径规划
    
    %s->Start, G->Goal
    S.x = startPos(1);
    S.y = startPos(2);

    G.x = endPos(1);
    G.y = endPos(2);
    
    DTM = GetDistanceTransform(map, S, G);
    path = FindPathFromDTM(DTM, S, G);
    return;
    
%%%%%%%%%%%%%
%make DistanceTransformMatrix
%+++++++++++++++++++++++++++++++++++++++++++++++++
function  DTM = GetDistanceTransform(map, S, G)

    DTM = Inf * ones(size(map));
    DTM(G.y, G.x) = 0;
    G.cost = 0;
   
    WFT = [];
    WFT = INSERT_NODE(WFT, G);
    cur = G;
 
    while ~(cur.x==S.x & cur.y==S.y) & length(WFT)~=0
        [cur WFT] = GetTail(WFT);
%         plot(cur.x, cur.y, 'k+'); drawnow;
        [WFT DTM] = PropagateWave(map, DTM, WFT, cur);
    end
    return;
%=================================================


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Find path from Distance Transform Matrix
%+++++++++++++++++++++++++++++++++++++++++++++++
function path = FindPathFromDTM(DTM, S, G)

    if DTM(S.y, S.x) == Inf%寻路失败
        path = [];
        return;
    end
    
    [Ymax Xmax] = size(DTM);
    p = S;
    path = S;

    j = 0; % 0 : start with N4(p) or principal grids;  4: start with ND(p) or diagonal grids
    
    while DTM(p.y, p.x)~=0
        for k = j : j+7
            x = p.x; y = p.y;
            switch(mod(k,8))
                case 0
                    x = x + 1;
                case 1
                    x = x - 1;
                case 2
                    y = y - 1;
                case 3
                    y = y + 1;
                case 4
                    x = x + 1;
                    y = y + 1;
                case 5
                    x = x - 1;
                    y = y - 1;
                case 6
                    x = x + 1;
                    y = y - 1;
                case 7
                    x = x - 1;
                    y = y + 1;
            end
            if x<1 | y<1 | x>Xmax | y>Ymax
                continue;
            end
            if DTM(y,x) == DTM(p.y, p.x)-1
                p.x = x; p.y = y;
%                 j = k;
                break;
            end
        end
        path = [path, p];
    end
%=================================================
    

 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%name: insert_node(): 将节点插入列表并排序

%%%%%%%%%%=======begining of insert_node=========%%%%%%%%%%%%%%%%%%%%  
function NewWFT = INSERT_NODE(WFT, p)
% p可能在WFT里有重复,卍代码是删除WFT重复p,但实验表明删除重复点反而增加耗时
%     global tag;
%     if tag(p.y, p.x) > 0
%         WFT = Delete(p, WFT);
%     else
%         tag(p.y, p.x) = tag(p.y, p.x)+1;
%     end

%以下代码是对WFT进行排序,但实验表明排序也使算法耗时增加
%     if isempty(WFT)    %a new or null list
%         NewWFT = p;
%     else
%         num = length(WFT);
%         while num~=0 & WFT(num).cost<p.cost
%             num = num-1;
%         end
%         NewWFT = [WFT(1:num), p, WFT(num+1:end)];
%     end

%以下代码是将p直接插入WFT前面,既不排序也不删除重复点,但实验表明耗时反而最少
    NewWFT = [p WFT];
    

%%%%%%%%%%=======end of insert_node=========%%%%%%%%%%%%%%%%%%%%%%


function NewList = Delete(X, List)
    num = length(List);
    while num~=0 & ~(List(num).x==X.x & List(num).y==X.y)
        num = num - 1;
    end
    % 不考虑状态增大或者减小吗?
    NewList = [List(1:num-1), List(num+1:end)];

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%function: GetTail(): 从List中取出末尾节点并修改List
%%%%%%%%%%======= begining =========%%%%%%%%%%%%%%%%%%%%
function [y, newlist] = GetTail(list)
    if isempty(list)
        y = [];
        newlist = [];
    else
        y = list(end);
        newlist = list(1 : end-1);
    end

 %%%%%%%%%%=======end of get_node()=========%%%%%%%%%%%%%%%%%%%%%%     
    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%function: Ex_nods(): 扩展节点
%%%%%%%%%%======= begining =========%%%%%%%%%%%%%%%%%%%%
function [newlist newVmap] = PropagateWave(map, Vmap, openlist, p)
    global tag;
    [Ymax Xmax] = size(map);
    for k = 1 : 8
        x = p.x; y = p.y; d=1;
        switch(k)
            case 1
                x = x - 1;
            case 2
                x = x + 1;
            case 3
                y = y - 1;
            case 4
                y = y + 1;
            case 5
                x = x - 1;
                y = y - 1;
            case 6
                x = x + 1;
                y = y + 1;
            case 7
                x = x - 1;
                y = y + 1;
            case 8
                x = x + 1;
                y = y - 1;
        end
        
        if x<1 | y<1 | x>Xmax | y>Ymax | map(y, x)==1 | Vmap(y, x)<=Vmap(p.y, p.x)+d
            continue;
        else
            Vmap(y, x) = Vmap(p.y, p.x)+d;
            temp.x = x; temp.y = y;
            temp.cost = Vmap(y,x);
            openlist = INSERT_NODE(openlist, temp); 
        end
    end
     newlist = openlist;
     newVmap = Vmap;
    return;
%%%%%%%%%%=======   end  =========%%%%%%%%%%%%%%%%%%%%%%    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -