模拟退火-粒子群全局路径规划+DWA局部路径规划

这篇具有很好参考价值的文章主要介绍了模拟退火-粒子群全局路径规划+DWA局部路径规划。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

整理了一个路径规划demo,当然图是改进的效果 demo分别有对应的开源 可以在网上搜到,我觉得已经介绍的很详细了,所以不做过多的解释,传送门在下面

写的不好 轻喷

粒子群算法

粒子群本质是参数寻优问题,也就是说在运用到路径规划这块需要对规划的路径进行模型建立,这块的demo当时是从一个b站up那块了解的,我记得好像有个up做了这个的讲解 但是我没找到QAQ

模拟退火粒子群,路径规划,动态规划

传送门

b站up的链接:

粒子群算法,路径规划,星际穿越_哔哩哔哩_bilibili

开源的粒子群路径规划demo链接(要感谢上面up的分享):

Optimal Robot Path Planning using PSO in MATLAB - Yarpiz

(多说一嘴:咱就是说要有点学术态度吧,别直接照搬照抄一点改进都没有,直接拿来用就发论文,看到了真感觉很恶心 说的是这篇论文:Verification and Analysis of Two-dimensional Path Planning Objective Function Optimization Based on Classical Particle Swarm Optimization Algorithm)

话说回来,对路径建立数学模型(适应度函数),那么首要的任务是确定要量化哪些信息,demo写在了MyCost.m里面 包含两部分:1.路径长度 2.碰撞惩罚 

模拟退火粒子群,路径规划,动态规划

在确定了适应度函数之后,就可以用粒子群算法进行寻优了,寻优过程在pso.m中进行。

在初始化时需要确定粒子群的维度n,这个维度可以理解为路径中间节点的个数,节点越多需要迭代的次数也就越多,生成最优路径的可能性也就越大。

%% Problem Definition

model=CreateModel(); %环境初始化 
%@(x) 变量名 = @(输入参数列表)运算表达式 既是一种可用于传参和赋值的变量,又可以作为函数名使用。
%这个x是  第x个粒子群
CostFunction=@(x) MyCost(x,model);  % CostFunction 适应度函数 做了一个声明
nVar=model.n;       % Number of Decision Variables  决策变量数量 10个位置点
VarSize=[1 nVar];   %[1 10] % Size of Decision Variables Matrix  决策变量矩阵的大小

%设置边界
VarMin.x=model.xmin;          
VarMax.x=model.xmax;           
VarMin.y=model.ymin;           
VarMax.y=model.ymax;          

%% PSO Parameters

%迭代次数
MaxIt=500;          % Maximum Number of Iterations  500
%种群规模
nPop=150;           % Population Size (Swarm Size)

%粒子群的三个系数 w为惯性权重系数 c1、c2分别为向个体和群体最优飞行速度
%wdamp的设置是为了降低惯性,提升后期局部搜索能力
w=1;                % Inertia Weight
wdamp=0.98;         % Inertia Weight Damping Ratio
c1=1.5;             % Personal Learning Coefficient
c2=1.5;             % Global Learning Coefficient

%定义速度可行域
alpha=0.1;
VelMax.x=alpha*(VarMax.x-VarMin.x);    % Maximum Velocity
VelMin.x=-VelMax.x;                    % Minimum Velocity
VelMax.y=alpha*(VarMax.y-VarMin.y);    % Maximum Velocity
VelMin.y=-VelMax.y;                    % Minimum Velocity

%% Initialization 种群初始化

% Create Empty Particle Structure
empty_particle.Position=[];
empty_particle.Velocity=[];
empty_particle.Cost=[];
empty_particle.Sol=[];
%结构体里的结构体
empty_particle.Best.Position=[];
empty_particle.Best.Cost=[];
empty_particle.Best.Sol=[];

% Initialize Global Best 因为是找最优(短)距离,所以在一开始置为无穷大
GlobalBest.Cost=inf;
% Create Particles Matrix  创建粒子矩阵 维度(nPop,1)
particle=repmat(empty_particle,nPop,1);

% Initialization Loop
for i=1:nPop
    
    %i = 1的时候 等距离生成10个点 后面的就随机生成
    
    % Initialize Position
    if i > 1  %安排后面那些位置信息
        particle(i).Position=CreateRandomSolution(model);
    else 
        % Straight line from source to destination  从源到目标的直线
        %linspace ==> 在初始点目标点之间等距离生成 n+2(12个点包括初始点和目标点)
        xx = linspace(model.xs, model.xt, model.n+2);  
        yy = linspace(model.ys, model.yt, model.n+2);
        
        %把10个点的信息传给particle
        particle(i).Position.x = xx(2:end-1);
        particle(i).Position.y = yy(2:end-1);
    end
    
    % Initialize Velocity 速度赋0 VarSize=[1,10] zeros(VarSize) ==> zeros(1,10)
    % 相当于返回一个1X10的全零矩阵
    particle(i).Velocity.x=zeros(VarSize);
    particle(i).Velocity.y=zeros(VarSize);
    
    %Evaluation返回路径长度 Cost 和 Sol(拟合点 距离 容忍度 可靠性)
    [particle(i).Cost, particle(i).Sol]=CostFunction(particle(i).Position);
    
    % Update Personal Best  更新个体数据
    particle(i).Best.Position=particle(i).Position;
    particle(i).Best.Cost=particle(i).Cost;
    particle(i).Best.Sol=particle(i).Sol;
    
    % Update Global Best  更新全局数据(选择cost小的值)
    if particle(i).Best.Cost<GlobalBest.Cost
        GlobalBest=particle(i).Best;
    end 
end

% Array to Hold Best Cost Values at Each Iteration  在每次迭代中保持最优值的阵列
BestCost=zeros(MaxIt,1);  %迭代矩阵初始化 每一次的最优值

%% PSO Main Loop 主函数
for it=1:MaxIt(迭代次数)

    for i=1:nPop(粒子个数)

        %x方向
        % 更新速度(粒子群的基本公式)
        particle(i).Velocity.x = w*particle(i).Velocity.x ...
            + c1*rand(VarSize).*(particle(i).Best.Position.x-particle(i).Position.x) ...
            + c2*rand(VarSize).*(GlobalBest.Position.x-particle(i).Position.x);
        
        % Update Velocity Bounds  速度边界约束(如果超过边界 那么等于边界)
        particle(i).Velocity.x = max(particle(i).Velocity.x,VelMin.x);
        particle(i).Velocity.x = min(particle(i).Velocity.x,VelMax.x);
        
        % Update Position 更新位置(上一时刻位置+这这一时刻速度)
        particle(i).Position.x = particle(i).Position.x + particle(i).Velocity.x;
        
        % Velocity Mirroring  速度镜像(我感觉不到这块有啥用)
        OutOfTheRange=(particle(i).Position.x<VarMin.x | particle(i).Position.x>VarMax.x);
        particle(i).Velocity.x(OutOfTheRange)=-particle(i).Velocity.x(OutOfTheRange);
        
        % Update Position Bounds  位置边界约束
        particle(i).Position.x = max(particle(i).Position.x,VarMin.x);
        particle(i).Position.x = min(particle(i).Position.x,VarMax.x);
        
        %y方向(与x方向原理一致)
        % Update Velocity
        particle(i).Velocity.y = w*particle(i).Velocity.y ...
            + c1*rand(VarSize).*(particle(i).Best.Position.y-particle(i).Position.y) ...
            + c2*rand(VarSize).*(GlobalBest.Position.y-particle(i).Position.y);
        
        % Update Velocity Bounds
        particle(i).Velocity.y = max(particle(i).Velocity.y,VelMin.y);
        particle(i).Velocity.y = min(particle(i).Velocity.y,VelMax.y);
        
        % Update Position
        particle(i).Position.y = particle(i).Position.y + particle(i).Velocity.y;
        
        % Velocity Mirroring
        OutOfTheRange=(particle(i).Position.y<VarMin.y | particle(i).Position.y>VarMax.y);
        particle(i).Velocity.y(OutOfTheRange)=-particle(i).Velocity.y(OutOfTheRange);
        
        % Update Position Bounds
        particle(i).Position.y = max(particle(i).Position.y,VarMin.y);
        particle(i).Position.y = min(particle(i).Position.y,VarMax.y);
        

        % Evaluation 评价 循环 返回路径长度Cost和 Sol(拟合点 距离 容忍度 可靠性)
        [particle(i).Cost, particle(i).Sol]=CostFunction(particle(i).Position);
        
        % Update Personal Best  更新个体最优(如果本次迭代cost小,那么记录该粒子的位置、cost、和sol信息)
        if particle(i).Cost<particle(i).Best.Cost
            
            particle(i).Best.Position=particle(i).Position;
            particle(i).Best.Cost=particle(i).Cost;
            particle(i).Best.Sol=particle(i).Sol;
            
            % Update Global Best 更新全局最优(如果本次迭代cost比全局cost要小,那么保留本次cost为全局cost)
            if particle(i).Best.Cost<GlobalBest.Cost
                GlobalBest=particle(i).Best;
            end
        end
    end
    
    % Update Best Cost Ever Found
    BestCost(it)=GlobalBest.Cost; %每次迭代都把种群最优路径加到BestCost中 以便生成适应度曲线
    
    % Inertia Weight Damping
    w=w*wdamp;  %降低惯性 wdamp = 0.98
 
    % Show Iteration Information 显示迭代信息
    if GlobalBest.Sol.IsFeasible
        Flag=' *';
    else
        Flag=[', Violation = ' num2str(GlobalBest.Sol.Violation)];
    end
    disp(['Iteration ' num2str(it) ': Best Cost = ' num2str(BestCost(it)) Flag]);
    
    % Plot Solution
    figure(1);
    PlotSolution(GlobalBest.Sol,model);
    pause(0.01);
    
end

CreateModel.m

function model=CreateModel()

    % Source  初始点
    xs=-50;
    ys=-50;
    
    % Target  目标点
    xt=45;
    yt=36;
    
    %三个障碍物
%     xobs=[1.5 4.0 1.2 40];
%     yobs=[4.5 3.0 1.5 32];
%     robs=[1.5 1.0 0.8 1.2];

    %随机生成100个障碍物
     xobs=(rand(100,1)*2-1)*50; %障碍物x坐标
     yobs=(rand(100,1)*2-1)*50; %障碍物y坐标
     robs=rand(100,1)*3;        %障碍物半径
     for i=1:size(robs)         %约束一下半径都大于1
     if robs(i) < 2
         robs(i) =robs(i)+ 1;     
     end
      
    %10个中间节点
    n=10;   
    
    %位置的可行域范围
    xmin=-50;
    xmax= 50;
    ymin=-50;
    ymax= 50;
    
    %赋值给model结构体
    model.xs=xs;
    model.ys=ys;
    model.xt=xt;
    model.yt=yt;
    model.xobs=xobs;
    model.yobs=yobs;
    model.robs=robs;
    model.n=n;
    model.xmin=xmin;
    model.xmax=xmax;
    model.ymin=ymin;
    model.ymax=ymax;
    
end

 ParseSolution.m

function sol2=ParseSolution(sol1,model)

    %把生成的10个点的位置信息传进去
    x=sol1.x;
    y=sol1.y;
    %初始点目标点
    xs=model.xs;
    ys=model.ys;
    xt=model.xt;
    yt=model.yt;
    %障碍物
    xobs=model.xobs;
    yobs=model.yobs;
    robs=model.robs;
    
    XS=[xs x xt];
    YS=[ys y yt];
    k=numel(XS);  %numel 返回 数组元素个数
    TS=linspace(0,1,k); %在 0 - 1 之间等距离生成k个点(包括0 1)
    
    tt=linspace(0,1,100);  %(0,1,5000)的意思是通过样条曲线将tt(5个点)转换成5000个点
    xx=spline(TS,XS,tt);  %spline 三次样条插值 就是说每两个节点之间进行一次三次样条插值,插入的个数是tt(tt越大,生成的轨迹越慢,但也越详细)
    yy=spline(TS,YS,tt);
    
    %前后相邻元素之差 维度降1 用于计算距离
    dx=diff(xx);  
    dy=diff(yy);
    
    L=sum(sqrt(dx.^2+dy.^2)); %计算每一小段距离再求和
    
    nobs = numel(xobs); % Number of Obstacles  numel返回数组元素个数 (几个障碍物)
    Violation = 0;
    for k=1:nobs
        d=sqrt((xx-xobs(k)).^2+(yy-yobs(k)).^2); %计算三次样条插值的 每一个点到第k个障碍物的距离之和
        v=max(1-d/robs(k),0);   %从 1-d/robs(k)或0 中返回最大值 返回0说明d>robs(k) 路径可行  
        Violation=Violation+mean(v); %mean 计算每列的平均值 大于0说明路径与障碍物相遇
    end
    %sol的一些数据
    sol2.TS=TS;
    sol2.XS=XS;
    sol2.YS=YS;
    sol2.tt=tt;
    sol2.xx=xx;
    sol2.yy=yy;
    sol2.dx=dx;
    sol2.dy=dy;
    sol2.L=L;
    sol2.Violation=Violation;
    sol2.IsFeasible=(Violation==0);   %Violation==0 返回 1 sol2.IsFeasible=1 证明可靠
    
    
end

也没啥了吧 还有就是障碍物绘制填充什么的,在此基础上在pso中加入模拟退火算法,就形成了模拟退火粒子群算法

模拟退火-粒子群算法:

自适应模拟退火粒子群算法BSAPSO(学习笔记_03)_自适应模拟退火算法_Cloud-Lii的博客-CSDN博客自适应模拟退火粒子群算法BSAPSO(学习笔记_3)https://blog.csdn.net/weixin_49647278/article/details/122549504?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-1-122549504-blog-127769197.pc_relevant_aa&spm=1001.2101.3001.4242.2&utm_relevant_index=4

模拟退火粒子群,路径规划,动态规划
标题全局路径规划

DWA算法

DWA算法就是把动态因素考虑进去的,最简单的方法就是在上面的基础上,设置一些动态障碍物,在全局路径规划完成后,进行DWA避障。DWAdemo好像挺久了,这个人写的比较全面,用的也是这个代码,只不过是加到了上面里,所以直接参考他这个自己写一份也是可以的。

DWA算法:

DWA动态窗口法的原理及应用_动态窗口法原理_gophae的博客-CSDN博客看了CSDN博客上面的各种介绍DWA的博客,就这辣鸡点击都能过万?完全是对学术的不尊重吧,还是我来写一下吧。DWA算法的核心:DWA的核心在于所谓的动态窗口,这个东西在sampling based method 中就是sampling. 对于sampling可以是去sample state,也可以sample action. 百度的lattice planner其实就是在sample sta...https://blog.csdn.net/gophae/article/details/105299926

 在完成pso后,进行循环迭代DWA算法

模拟退火粒子群,路径规划,动态规划
全局+局部路径规划(包含移动障碍物)
%% 机器人的初期状态
x = [-50 -50 pi/4 0 0]'; 
% x下标宏定义 状态[x(m),y(m),yaw(Rad),v(m/s),w(rad/s)]
POSE_X      = 1;  %坐标 X
POSE_Y      = 2;  %坐标 Y
YAW_ANGLE   = 3;  %机器人航向角
V_SPD       = 4;  %机器人速度
W_ANGLE_SPD = 5;  %机器人角速度 
 
goal=[45 36];  %设置目标位置

global dt; 
dt = 0.1;% 时间[s]

%最高速度m/s],最高旋转速度[rad/s],加速度[m/ss],旋转加速度[rad/ss],速度分辨率[m/s],转速分辨率[rad/s]]
Kinematic = [1.5,toRadian(20.0),0.2,toRadian(50.0),0.01,toRadian(1)];

%定义Kinematic的下标含义
MD_MAX_V    = 1;%   最高速度m/s]
MD_MAX_W    = 2;%   最高角速度[rad/s]
MD_ACC      = 3;%   加速度[m/ss]
MD_VW       = 4;%   旋转加速度[rad/ss]
MD_V_RESOLUTION  = 5;%  速度分辨率[m/s]
MD_W_RESOLUTION  = 6;%  转速分辨率[rad/s]]

% 评价函数参数 航向得分的比重、距离得分的比重、速度得分的比重、向前模拟轨迹的时间
evalParam = [0.045, 0.1 ,0.1, 3.0];

% 模拟实验的结果
result_x=[];   %累积存储走过的轨迹点的状态值
tic; % 估算程序运行时间开始
abc = 0;  %循环第abc次

%% 设置纵向移动障碍物
%初始化障碍物的速度参数 在(-1,1)之间
flag_obstacle = [1-2*rand(1) 1-2*rand(1) 1-2*rand(1) 1-2*rand(1) 1-2*rand(1) 1-2*rand(1) 1-2*rand(1) 1-2*rand(1) 1-2*rand(1)];   
vel_obstacle = 0.1;  %障碍物速度参数权值

%设置纵向障碍物的具体目标(9个)
obstacle=[model.xobs(8) model.yobs(8); 
    model.xobs(65) model.yobs(65);
    model.xobs(63) model.yobs(63);
    model.xobs(42) model.yobs(42);
    model.xobs(30) model.yobs(30);
    model.xobs(45) model.yobs(45);
    model.xobs(37) model.yobs(37);
    model.xobs(46) model.yobs(46);
    model.xobs(10) model.yobs(10);];

%% 设置横向移动障碍物
%% 初始化横向移动障碍物速度参数 在(-1,1)之间
flag_obstacle_1 = [1-2*rand(1) 1-2*rand(1) 1-2*rand(1) 1-2*rand(1) 1-2*rand(1) 1-2*rand(1)];   

%设置横向障碍物具体目标(6个)
obstacle_1=[model.xobs(52) model.yobs(52);   
    model.xobs(29) model.yobs(29);
    model.xobs(3) model.yobs(3);
    model.xobs(2) model.yobs(2);
    model.xobs(18) model.yobs(18);
    model.xobs(61) model.yobs(61);];

psi_obs=ones(numel(flag_obstacle),1);
psi_obs_1=ones(numel(flag_obstacle_1),1);

%% 循环
for i = 1:5000
    
    %对obstcle的移动计算
    for j = 1:numel(flag_obstacle)    %移动障碍物设定
        if obstacle(j,2) > 36 && flag_obstacle(j) > 0 || obstacle(j,2) < -50 && flag_obstacle(j) < 0
            flag_obstacle(j) = -flag_obstacle(j);
        end
        obstacle(j,2)=obstacle(j,2)+flag_obstacle(j)*vel_obstacle;   %flag_obstacle(j)*vel_obstacle 变换速度
        %添加obstcle的航向信息
        if flag_obstacle(j)>0
            psi_obs(j,1)=pi/2;
        else
            psi_obs(j,1)=pi*3/2;
        end
    end
    
    model.yobs(8)=obstacle(1,2);
    model.yobs(65)=obstacle(2,2);
    model.yobs(63)=obstacle(3,2);
    model.yobs(42)=obstacle(4,2);
    model.yobs(30)=obstacle(5,2);
    model.yobs(45)=obstacle(6,2);
    model.yobs(37)=obstacle(7,2);
    model.yobs(46)=obstacle(8,2);
    model.yobs(10)=obstacle(9,2);
    
    %对obstcle_1的移动计算
    for j = 1:numel(flag_obstacle_1)    %移动障碍物设定
        if obstacle_1(j,1) > 45 && flag_obstacle_1(j) > 0 || obstacle_1(j,1) < -50 && flag_obstacle_1(j) < 0
            flag_obstacle_1(j) = -flag_obstacle_1(j);
        end
        obstacle_1(j,1)=obstacle_1(j,1)+flag_obstacle_1(j)*vel_obstacle;   %flag_obstacle(j)*vel_obstacle 变换速度
        %添加obstacle_1的航向信息
        if flag_obstacle_1(j)>0
            psi_obs_1(j,1)=0;
        else
            psi_obs_1(j,1)=pi;
        end
    end
    
    model.xobs(52)=obstacle_1(1,1);
    model.xobs(29)=obstacle_1(2,1);
    model.xobs(3)=obstacle_1(3,1);
    model.xobs(2)=obstacle_1(4,1);
    model.xobs(18)=obstacle_1(5,1);
    model.xobs(61)=obstacle_1(6,1);
    
    %撞上纵向移动障碍物
    for l = 1:numel(flag_obstacle)
        if norm(obstacle(l,:)-x(1:2)')-1 < 0
            disp('==========Hit an obstacle!!==========');  %撞上障碍物
            temp = 1;
            break;
        end
    end
    %撞上横向移动障碍物
    for l = 1:numel(flag_obstacle_1)
        if norm(obstacle_1(l,:)-x(1:2)')-1 < 0
            disp('==========Hit an obstacle!!!==========');  %撞上障碍物
            temp = 1;
            break;
        end
    end
    if temp == 1
        break;
    end
    
    % DWA参数输入 返回控制量 u = [v(m/s),w(rad/s)] 和 轨迹
    [u,traj] = DynamicWindowApproach(x,Kinematic,goal(k,:),evalParam,model,psi_obs,psi_obs_1,obstacle,obstacle_1);%算出下发速度u/当前速度u
    x = f(x,u);% 机器人移动到下一个时刻的状态量 根据当前速度和角速度推导 下一刻的位置和角度
    abc = abc+1;
    % 历史轨迹的保存
    result_x = [result_x; x'];  %最新结果 以行的形式 添加到result.x, 保存的是所有状态参数值,包括坐标xy、朝向、线速度、角速度,其实应该是只取坐标就OK
    
    % 是否到达目的地
    if norm(x(POSE_X:POSE_Y)-goal(k,:)')<2   % norm函数来求得坐标上的两个点之间的距离
        disp('==========Arrive Goal!!==========');break;
    end
    
    
    %导入PlotSolution_2绘制 动态障碍物  +  机器人模型
    ArrowLength = 0.5;      % 箭头长度
    PlotSolution_2(traj,result_x,x,ArrowLength,GlobalBest.Sol,model);
    
    disp(['time ' num2str(i)]); %打印
end
 
 
%% 航行时间   形式:时间已过 ** 秒。
toc;  

%% 计算航迹总长度
lx_c=[-50;result_x(:,1);45];
ly_c=[-50;result_x(:,2);36];

dlx=diff(lx_c);
dly=diff(ly_c);

L_c=sum(sqrt(dlx.^2+dly.^2));

disp(['DWA航迹长度为: ' num2str(L_c)]); %打印

DynamicWindowApproach.m

function [u,trajDB] = DynamicWindowApproach(x,model,goal,evalParam,model_1,psi_obs,psi_obs_1,obstacle,obstacle_1)
% Dynamic Window [vmin,vmax,wmin,wmax] 最小速度 最大速度 最小角速度 最大角速度速度
Vr = CalcDynamicWindow(x,model);  % 根据当前状态 和 运动模型 计算当前的参数允许范围(最小速度 最大速度 最小角速度 最大角速度速度)

% 评价函数的计算 evalDB N*5  每行一组可用参数 分别为 速度、角速度、航向得分、距离得分、速度得分
%               trajDB      每5行一条轨迹 每条轨迹都有状态x点串组成
[evalDB,trajDB]= Evaluation(x,Vr,goal,model_1,model,evalParam,psi_obs,psi_obs_1,obstacle,obstacle_1);  %evalParam 评价函数参数 [heading,dist,velocity,predictDT]

if isempty(evalDB)
    disp('no path to goal!!');
    u=[0;0];return;
end

% 各评价函数正则化
evalDB = NormalizeEval(evalDB);

% 最终评价函数的计算
feval=[];
for id=1:length(evalDB(:,1))
    feval = [feval;evalParam(1:3)*evalDB(id,3:5)']; %根据评价函数参数 前三个参数分配的权重 计算每一组可用的路径参数信息的得分  评价参数前三个指标 航向得分比重、距离得分比重、速度得分比重 X evalDB的 第三个到第五个指标 航向、距离、速度
end
evalDB = [evalDB feval]; % 最后一组;加最后一列,每一组速度的最终得分

[maxv,ind] = max(feval);% 选取评分最高的参数 对应分数返回给 maxv  对应下标返回给 ind
u = evalDB(ind,1:2)';% 返回最优参数的速度、角速度
end

Evaluation.m(这块把接口写上了以便后续为所欲为 包括障碍物角度以及障碍物位置)

function [evalDB,trajDB] = Evaluation(x,Vr,goal,model_1,model,evalParam,psi_obs,psi_obs_1,obstacle,obstacle_1)
evalDB = [];
trajDB = [];
for vt = Vr(1):model(5):Vr(2)       %根据速度分辨率遍历所有可用速度: 最小速度和最大速度 之间 速度分辨率 递增
    for ot=Vr(3):model(6):Vr(4)     %根据角度分辨率遍历所有可用角速度: 最小角速度和最大角速度 之间 角度分辨率 递增
        % 轨迹推测; 得到 xt: 机器人向前运动后的预测位姿; traj: 当前时刻 到 预测时刻之间的轨迹(由轨迹点组成)
        [xt,traj] = GenerateTrajectory(x,vt,ot,evalParam(4));  %evalParam(4),前向模拟时间;  得到运动后的位姿 + 这段路径
        % 各评价函数的计算
        heading = CalcHeadingEval(xt,goal); % 前项预测终点的航向得分  偏差越小分数越高
        [dist,Flag] = CalcDistEval(xt,model_1);    % 前项预测终点 距离最近障碍物的间隙得分 距离越远分数越高
        vel = abs(vt);                  % 速度得分 速度越快分越高
        stopDist = CalcBreakingDist(vel,model); % 制动距离的计算
         if dist > stopDist && Flag == 0 % 如果可能撞到最近的障碍物 则舍弃此路径 (到最近障碍物的距离 大于 刹车距离 才取用)
%         if Flag == 0 % 如果可能撞到最近的障碍物 则舍弃此路径 (到最近障碍物的距离 大于 刹车距离 才取用)
            evalDB = [evalDB;[vt ot heading dist vel]];
            trajDB = [trajDB;traj];   % 每5行 一条轨迹
        end
    end
end
end

其他内容基本就跟上面博主写的一样了,算法很简单,一看就懂

这块说一下障碍物移动,也是参考了DWA算法的demo

在PSO随机生成障碍物的基础上,将障碍物信息保存到Excel中,然后读取的Excel数据,以便更改具体障碍物,障碍物的迭代移动demo在PlotSolution_2.m中

function PlotSolution_2(traj,result_x,x,ArrowLength,sol,model)

    xs=model.xs;
    ys=model.ys;
    xt=model.xt;
    yt=model.yt;
    xobs=model.xobs;
    yobs=model.yobs;
    robs=model.robs;
    
    XS=sol.XS;
    YS=sol.YS;
    xx=sol.xx;
    yy=sol.yy;
    
    theta=linspace(0,2*pi,100);
    for k=1:numel(xobs)   %填充障碍物(应该是)
        fill(xobs(k)+robs(k)*cos(theta),yobs(k)+robs(k)*sin(theta),[0.5 0.7 0.8]);
        hold on;
    end
    
  
    fill(xobs(8)+robs(8)*cos(theta),yobs(8)+robs(8)*sin(theta),[0.9373 0.4353 0.4235]);
    hold on;
    fill(xobs(65)+robs(65)*cos(theta),yobs(65)+robs(65)*sin(theta),[0.9373 0.4353 0.4235]);
    hold on;
    fill(xobs(63)+robs(63)*cos(theta),yobs(63)+robs(63)*sin(theta),[0.9373 0.4353 0.4235]);
    hold on;
    fill(xobs(42)+robs(42)*cos(theta),yobs(42)+robs(42)*sin(theta),[0.9373 0.4353 0.4235]);
    hold on;
    fill(xobs(30)+robs(30)*cos(theta),yobs(30)+robs(30)*sin(theta),[0.9373 0.4353 0.4235]);
    hold on;
    fill(xobs(45)+robs(45)*cos(theta),yobs(45)+robs(45)*sin(theta),[0.9373 0.4353 0.4235]);
    hold on;
    fill(xobs(37)+robs(37)*cos(theta),yobs(37)+robs(37)*sin(theta),[0.9373 0.4353 0.4235]);
    hold on;
    fill(xobs(46)+robs(46)*cos(theta),yobs(46)+robs(46)*sin(theta),[0.9373 0.4353 0.4235]);
    hold on;
    fill(xobs(10)+robs(10)*cos(theta),yobs(10)+robs(10)*sin(theta),[0.9373 0.4353 0.4235]);
    hold on;

    
    fill(xobs(52)+robs(52)*cos(theta),yobs(52)+robs(52)*sin(theta),[0.9294, 0.6941, 0.5137]);
    hold on;
    fill(xobs(29)+robs(29)*cos(theta),yobs(29)+robs(29)*sin(theta),[0.9294, 0.6941, 0.5137]);
    hold on;
    fill(xobs(3)+robs(3)*cos(theta),yobs(3)+robs(3)*sin(theta),[0.9294, 0.6941, 0.5137]);
    hold on;
    fill(xobs(2)+robs(2)*cos(theta),yobs(2)+robs(2)*sin(theta),[0.9294, 0.6941, 0.5137]);
    hold on;
    fill(xobs(18)+robs(18)*cos(theta),yobs(18)+robs(18)*sin(theta),[0.9294, 0.6941, 0.5137]);
    hold on;
    fill(xobs(61)+robs(61)*cos(theta),yobs(61)+robs(61)*sin(theta),[0.9294, 0.6941, 0.5137]);
    hold on;
    
    
    POSE_X=x(1);
    POSE_Y=x(2);
    YAW_ANGLE=x(3);
    V_SPD=x(4);
    W_ANGLE_SPD=x(5);
    
    n=0.02;
    long = 150;  %船长
    width = 50;  %船宽
    l = n*long;  %n是比例
    w = n*width;
    % psi = psi*pi/180;
    YAW_ANGLE_1 = YAW_ANGLE ;

    y1 = POSE_X - (l/2)*cos(YAW_ANGLE_1);%1
    x1 = POSE_Y - (l/2)*sin(YAW_ANGLE_1);
    y2 = POSE_X + (l/6)*cos(YAW_ANGLE_1);%2
    x2 = POSE_Y + (l/6)*sin(YAW_ANGLE_1);
    y3 = POSE_X + (l/2)*cos(YAW_ANGLE_1);%3
    x3 = POSE_Y + (l/2)*sin(YAW_ANGLE_1);
    y5 = y1 - (w/2)*sin(YAW_ANGLE_1);%5
    x5 = x1 + (w/2)*cos(YAW_ANGLE_1);
    y6 = y1 + (w/2)*sin(YAW_ANGLE_1);%6
    x6 = x1 - (w/2)*cos(YAW_ANGLE_1);
    y4 = y2 - (w/2)*sin(YAW_ANGLE_1);%4
    x4 = x2 + (w/2)*cos(YAW_ANGLE_1);
    y7 = y2 + (w/2)*sin(YAW_ANGLE_1);%7
    x7 = x2 - (w/2)*cos(YAW_ANGLE_1);


    
    x = [x3 x4 x5 x6 x7 x3];
    y = [y3 y4 y5 y6 y7 y3];
    
    plot(y,x,'g','LineWidth',0.5);  %画船
    quiver(POSE_X, POSE_Y, ArrowLength*cos(YAW_ANGLE), ArrowLength*sin(YAW_ANGLE),'ok'); %画圆
    
    % 绘制走过的所有位置 所有历史数据的 X、Y坐标
    plot(result_x(:,1),result_x(:,2),'-b');
    
    % 探索轨迹 画出待评价的轨迹
    if ~isempty(traj) %轨迹非空
        for it=1:length(traj(:,1))/5    %计算所有轨迹数  traj 每5行数据 表示一条轨迹点
            ind = 1+(it-1)*5; %第 it 条轨迹对应在traj中的下标
            plot(traj(ind,:),traj(ind+1,:),'-g'); hold on;  %根据一条轨迹的点串画出轨迹   traj(ind,:) 表示第ind条轨迹的所有x坐标值  traj(ind+1,:)表示第ind条轨迹的所有y坐标值
        end
    end
    
    
    plot(xx,yy,'k','LineWidth',2);
    plot(XS,YS,'ro');
    plot(xt,yt,'kp','MarkerSize',16,'MarkerFaceColor','g');  %终点
    hold off;
    grid on;
    axis equal;
    drawnow limitrate;

end

整体demo打包到一起发吧,在此再次感谢前面几个博主的分享

代码传送门:

https://download.csdn.net/download/weixin_53293018/87679985?spm=1001.2014.3001.5503

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_53293018/article/details/129802545
 文章来源地址https://www.toymoban.com/news/detail-739616.html

到了这里,关于模拟退火-粒子群全局路径规划+DWA局部路径规划的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 机器人避障路径规划的MATLAB模拟退火算法

    机器人避障路径规划的MATLAB模拟退火算法 在机器人路径规划中,避免障碍物是一个重要的问题。模拟退火算法是一种启发式优化算法,可以用于解决路径规划问题。在本文中,我们将使用MATLAB实现一个基于模拟退火算法的机器人避障路径规划程序。 首先,我们需要定义问题

    2024年02月06日
    浏览(43)
  • ros中实现全局/局部避障算法的添加与rviz中规划路径的显示(上)

    目录 前言 一、命令行 二、所用到的launch文件、yaml文件等 1.map1_mrobot_laser_nav_gazebo.launch 2.gmapping_demo.launch 3.gmapping.launch 4.move_base.launch 5.nav03_map_server.launch 6.mrobot_teleop.launch 三、rviz中添加path插件 总结 最近在做ros相关的作业,故写下本文留做参考以便日后再次使用或理解,如有

    2024年02月01日
    浏览(39)
  • 湘潭大学 算法设计与分析实验 回溯 动态规划 贪心 模拟退火解决背包问题

    https://download.csdn.net/download/SQ_ZengYX/88620871 测试用例

    2024年02月02日
    浏览(61)
  • 基于粒子群算法的机器人动态路径规划

    基于粒子群算法的机器人动态路径规划 粒子群算法(Particle Swarm Optimization,PSO)是一种基于群体智能的优化算法,常用于解决优化问题。在机器人动态路径规划中,粒子群算法可以被应用于寻找最优路径,以使机器人在动态环境中能够高效地规划路径并避免障碍物。 本文将

    2024年02月07日
    浏览(52)
  • 【人工智能】—局部搜索算法、爬山法、模拟退火、局部剪枝、遗传算法

    在某些规模太大的问题状态空间内,A*往往不够用 问题空间太大了 无法访问 f 小于最优的所有状态 通常,甚至无法储存整个边缘队列 解决方案 设计选择更好的启发式函数 Greedy hill-climbing (fringe size = 1) Beam search (limited fringe size) 瓶颈:内存不足,无法存储整个边缘队列 爬山搜

    2023年04月22日
    浏览(52)
  • 智能算法系列之基于粒子群优化的模拟退火算法

      本篇是智能算法(Python复现)专栏的第四篇文章,主要介绍粒子群优化算法与模拟退火算法的结合,以弥补各自算法之间的不足。   在上篇博客【智能算法系列之粒子群优化算法】中有介绍到混合粒子群优化算法,比如将粒子更新后所获得的新的粒子,采用模拟退火的思

    2024年02月11日
    浏览(62)
  • 路径规划-DWA算法(C++实现)

    1、简单介绍 DWA算法(dynamic window approach),其原理主要是在速度空间(v,w)中采样多组速度,并模拟出这些速度在一定时间内的运动轨迹,并通过评价函数对这些轨迹进行评价(其中包括距离障碍物距离,距离目标点距离等等进行评价),选取最优轨迹对应的(v,w)驱动机器人

    2024年02月10日
    浏览(44)
  • 基于动态窗口法(DWA)的局部避障算法研究及MATALB的实现

    一、动态窗口法基本概念  1.1  速度采样空间 1.2  评价函数 二、基于Matlab的机器人局部避障仿真         动态窗口方法(DynamicWindowApproach) 是一种可以实现实时避障的局部规划算法,通过将轮式机器人的位置约束转化为 速度约束 ,根据约束进行 速度采样 ,并由一系列的

    2024年02月01日
    浏览(30)
  • 超详细 | 模拟退火-粒子群自适应优化算法及其实现(Matlab)

    作者在前面的文章中介绍了经典的优化算法——粒子群算法(PSO),各种智能优化算法解决问题的方式和角度各不相同,都有各自的适用域和局限性,对智能优化算法自身做的改进在算法性能方面得到了一定程度的提升,但算法缺点的解决并不彻底。 为了克服使用单一智能优化

    2024年02月05日
    浏览(73)
  • 【ROS-Navigation】—— DWA路径规划算法解析

        最近在学习ROS的navigation部分,写些东西作为笔记,方便理解与日后查看。本文从Astar算法入手,对navigation源码进行解析。 PS:ros navigation源码版本https://gitcode.net/mirrors/ros-planning/navigation/-/tree/noetic-devel DWA具体的算法原理在之前的博客(见自动驾驶路径规划——DWA(动态

    2023年04月16日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包