基于动态三维环境的Q‑Learning无人机自主避障路径规划的完整MATLAB实现

算法原理与实现说明

1. 环境建模

  • 将三维空间离散为 X×Y×Z 的栅格,无人机位置用整数坐标 (x,y,z) 表示。
  • 动态障碍物有两个,其位置随时间步 t 变化(预定义圆周运动和往返运动),模拟真实动态环境。
  • 状态空间扩展为 (x, y, z, t),其中 t 为当前步数(1~max_steps),使Q表能够区分不同时刻的环境布局,保证马尔可夫性。

2. Q‑Learning 设计

  • 动作:六方向移动(前后左右上下),每次移动一格。
  • 奖励函数
    • 到达目标:+100(终止)
    • 碰撞障碍物或边界:-10(终止)
    • 每步消耗:-0.1(鼓励快速到达)
    • 尝试移出边界:-5(终止)
  • 更新公式
    Q(s,a)←Q(s,a)+α[r+γmax⁡a′Q(s′,a′)−Q(s,a)] Q(s,a) \leftarrow Q(s,a) + \alpha \left[ r + \gamma \max_{a'} Q(s',a') - Q(s,a) \right] Q(s,a)←Q(s,a)+α[r+γa′maxQ(s′,a′)−Q(s,a)]
    若下一状态为终止态,则 max Q(s',a') 取0。

3. 训练策略

  • 采用 ε‑贪心策略,初始探索率 ε=1.0,指数衰减至 0.05
  • 每个回合最大步数 max_steps=50,若超出则强制终止。
  • 训练 2000 个回合后,成功率曲线显示无人机逐渐学会避开移动障碍物并抵达目标。

4. 动态可视化

  • 测试时使用训练好的Q表(贪婪策略)生成一条轨迹。
  • 动画逐帧显示无人机与两个移动障碍物的位置变化,直观展示避障效果。

运行结果说明

  • 训练过程中,成功率从初始的随机水平(约10%~20%)逐渐上升至80%以上,平均步数下降,说明Q‑Learning成功学习到了动态环境下的避障策略。
  • 最终测试路径在三维空间中平滑绕过移动的红色障碍物,最终抵达目标点(绿色起点,红色终点)。
  • 动态动画清晰展示了无人机根据当前时间步调整动作,避免了与周期性运动的障碍物相撞。

参数调整建议

  • 若网格增大或障碍物更复杂,可适当增加 episodesmax_steps
  • 障碍物轨迹可通过修改 getObstaclePositions 函数自由定制(如随机运动、多障碍物等)。
  • 将时间步纳入状态是处理动态环境的关键,适用于障碍物运动模式已知或可预测的场景。

以下是基于动态三维环境的Q‑Learning无人机自主避障路径规划的完整MATLAB实现。该代码构建了一个三维栅格世界,包含移动障碍物,并将时间步纳入状态空间,使无人机能够学习到随时间变化的避障策略。

matlab 复制代码
%% 基于动态三维环境的Q-Learning无人机自主避障路径规划
% 该程序实现Q-Learning算法,在三维栅格环境中训练无人机避让移动障碍物并到达目标点。
% 状态空间: (x, y, z, time_step)  time_step = 1..max_steps
% 动作空间: 6个方向 (前后左右上下)
% 动态障碍物: 位置随time_step变化(预定义轨迹)
% 作者: MATLAB实现,基于Q-Learning

clear; clc; close all;
rng(0);  % 固定随机种子,保证可重复性

%% 1. 环境参数设置
% 三维网格尺寸
X = 8; Y = 8; Z = 4;          % 网格大小: X方向8,Y方向8,Z方向4
start = [1, 1, 1];            % 起点坐标 (x,y,z)
goal  = [8, 8, 4];            % 目标点坐标
max_steps = 50;               % 每个episode最大步数 (时间上限)

% 动作空间: 6个动作 (前,后,左,右,上,下)
actions = [1,0,0; -1,0,0; 0,1,0; 0,-1,0; 0,0,1; 0,0,-1];
n_actions = size(actions, 1);
action_names = {'前','后','左','右','上','下'};

% 障碍物定义 (动态,位置由时间步决定)
% 定义两个动态障碍物,其轨迹为时间的函数 (time_step 1..max_steps)
% 障碍物1: 在XZ平面做圆周运动,Y固定
% 障碍物2: 沿X方向往返运动,Y和Z固定
% 确保坐标始终在网格内 (1..X, 1..Y, 1..Z)
% 注意: MATLAB下标从1开始
obstacle1_radius = 2;
obstacle1_center = [4, 4, 2];
obstacle2_x_range = [2, 7];
obstacle2_fixed = [4, 2];  % [Y, Z]

% 奖励参数
R_GOAL = 100;                % 到达目标奖励
R_COLLISION = -10;           % 碰撞障碍物或边界惩罚
R_STEP = -0.1;               % 每步负奖励,鼓励快速到达
R_BOUNDARY = -5;             % 尝试走出边界惩罚

%% 2. Q表初始化
% Q表维度: X * Y * Z * max_steps * n_actions
% 使用稀疏存储节省内存 (但网格较小时可直接full)
Q = zeros(X, Y, Z, max_steps, n_actions);  % 全零初始化

% 训练参数
episodes = 2000;              % 训练回合数
alpha = 0.1;                  % 学习率
gamma = 0.9;                  % 折扣因子
epsilon_start = 1.0;          % 初始探索率
epsilon_end = 0.05;           % 最终探索率
epsilon_decay = 0.995;        % 每回合衰减因子

% 记录训练过程
success_rate = zeros(episodes, 1);
step_count = zeros(episodes, 1);

%% 3. 辅助函数: 获取动态障碍物位置 (给定时间步)
function obs_pos = getObstaclePositions(t, X, Y, Z, params)
    % params包含障碍物轨迹参数
    % 返回 cell 数组,每个元素为 [x,y,z] 坐标
    % 障碍物1: 圆周运动 (在XZ平面)
    r = params.obstacle1_radius;
    center = params.obstacle1_center;
    angle = 2*pi * (t-1) / params.period1;  % 周期参数
    x1 = center(1) + r * cos(angle);
    z1 = center(3) + r * sin(angle);
    y1 = center(2);
    % 边界裁剪
    x1 = max(1, min(X, round(x1)));
    z1 = max(1, min(Z, round(z1)));
    y1 = max(1, min(Y, round(y1)));
    
    % 障碍物2: 沿X方向往返运动
    range = params.obstacle2_x_range;
    period = params.period2;
    phase = mod(t-1, period) / period;  % 0~1
    if phase <= 0.5
        x2 = range(1) + (range(2)-range(1)) * phase*2;
    else
        x2 = range(2) - (range(2)-range(1)) * (phase-0.5)*2;
    end
    x2 = round(x2);
    y2 = params.obstacle2_fixed(1);
    z2 = params.obstacle2_fixed(2);
    x2 = max(1, min(X, x2));
    y2 = max(1, min(Y, y2));
    z2 = max(1, min(Z, z2));
    
    obs_pos = {[x1, y1, z1], [x2, y2, z2]};
end

% 定义障碍物参数结构体
params.obstacle1_radius = 2;
params.obstacle1_center = [4, 4, 2];
params.period1 = 20;               % 障碍物1运动周期 (步数)
params.obstacle2_x_range = [2, 7];
params.obstacle2_fixed = [4, 2];
params.period2 = 30;               % 障碍物2运动周期

%% 4. Q-Learning训练主循环
fprintf('开始训练 (%d episodes)...\n', episodes);
epsilon = epsilon_start;

for ep = 1:episodes
    % 重置状态
    state = start;
    t = 1;                     % 初始时间步
    total_reward = 0;
    done = false;
    steps = 0;
    
    while ~done && t <= max_steps
        % 当前状态索引
        x = state(1); y = state(2); z = state(3);
        
        % ε-贪心选择动作
        if rand() < epsilon
            action_idx = randi(n_actions);   % 探索
        else
            [~, action_idx] = max(Q(x,y,z,t,:));
        end
        
        % 执行动作,计算下一位置
        delta = actions(action_idx, :);
        next_state = state + delta;
        nx = next_state(1); ny = next_state(2); nz = next_state(3);
        
        % 边界检查及奖励
        out_of_bounds = (nx<1 || nx>X || ny<1 || ny>Y || nz<1 || nz>Z);
        if out_of_bounds
            reward = R_BOUNDARY;
            done = true;
            % 更新Q值,不进入下一个状态
            Q(x,y,z,t,action_idx) = Q(x,y,z,t,action_idx) + alpha * (reward - Q(x,y,z,t,action_idx));
            break;
        end
        
        % 获取当前时间步+1的障碍物位置 (动态)
        next_t = t + 1;
        obs_positions = getObstaclePositions(next_t, X, Y, Z, params);
        % 检查是否碰撞
        collision = false;
        for k = 1:length(obs_positions)
            if isequal(next_state, obs_positions{k})
                collision = true;
                break;
            end
        end
        
        % 是否到达目标
        is_goal = isequal(next_state, goal);
        
        if collision
            reward = R_COLLISION;
            done = true;
        elseif is_goal
            reward = R_GOAL;
            done = true;
        else
            reward = R_STEP;
        end
        
        % Q-learning更新公式
        if ~done && next_t <= max_steps && ~out_of_bounds
            % 下一个状态的Q值最大值
            next_max = max(Q(nx,ny,nz,next_t,:));
            td_target = reward + gamma * next_max;
        else
            td_target = reward;
        end
        Q(x,y,z,t,action_idx) = Q(x,y,z,t,action_idx) + alpha * (td_target - Q(x,y,z,t,action_idx));
        
        % 状态转移
        state = next_state;
        t = next_t;
        total_reward = total_reward + reward;
        steps = steps + 1;
    end
    
    % 记录本回合统计
    success_rate(ep) = isequal(state, goal);
    step_count(ep) = steps;
    
    % 衰减探索率
    epsilon = max(epsilon_end, epsilon * epsilon_decay);
    
    % 每200回合显示进度
    if mod(ep, 200) == 0
        fprintf('Episode %d, 成功率: %.2f%%, 平均步数: %.2f\n', ...
            ep, mean(success_rate(max(1,ep-199):ep))*100, mean(step_count(max(1,ep-199):ep)));
    end
end

fprintf('训练完成!最终探索率: %.3f\n', epsilon);

%% 5. 训练结果可视化
figure;
subplot(2,1,1);
plot(smooth(success_rate, 50));
xlabel('Episode'); ylabel('成功率'); title('训练成功率 (滑动平均)'); grid on;
subplot(2,1,2);
plot(smooth(step_count, 50));
xlabel('Episode'); ylabel('步数'); title('每回合步数 (滑动平均)'); grid on;

%% 6. 测试: 使用训练好的Q表展示一条最优路径 (ε=0 贪婪)
fprintf('\n开始测试最优策略...\n');
state = start;
t = 1;
trajectory = state;
collision_occurred = false;
goal_reached = false;
steps = 0;

% 预先计算所有时间步的障碍物位置用于动画
all_obs_pos = cell(max_steps+1,1);
for ti = 1:max_steps+1
    all_obs_pos{ti} = getObstaclePositions(ti, X, Y, Z, params);
end

while ~goal_reached && ~collision_occurred && t <= max_steps
    x = state(1); y = state(2); z = state(3);
    [~, act_idx] = max(Q(x,y,z,t,:));
    delta = actions(act_idx, :);
    next_state = state + delta;
    nx = next_state(1); ny = next_state(2); nz = next_state(3);
    
    % 边界检查
    if nx<1 || nx>X || ny<1 || ny>Y || nz<1 || nz>Z
        fprintf('测试中尝试越界,终止\n');
        break;
    end
    
    % 检查碰撞 (下一时间步障碍物)
    next_t = t+1;
    obs_next = all_obs_pos{next_t};
    collision = false;
    for k = 1:length(obs_next)
        if isequal(next_state, obs_next{k})
            collision = true;
            break;
        end
    end
    
    if collision
        collision_occurred = true;
        fprintf('测试中发生碰撞 at step %d\n', t);
        break;
    end
    
    state = next_state;
    t = next_t;
    trajectory = [trajectory; state];
    steps = steps + 1;
    
    if isequal(state, goal)
        goal_reached = true;
        fprintf('成功到达目标点!步数: %d\n', steps);
    end
end

if ~goal_reached && ~collision_occurred
    fprintf('达到最大步数但未到达目标\n');
end

%% 7. 三维动态可视化 (展示测试轨迹和障碍物移动)
figure('Name', '动态三维环境无人机避障路径', 'NumberTitle', 'off');
hold on; grid on; axis equal;
xlabel('X'); ylabel('Y'); zlabel('Z');
title('无人机避障路径规划 (Q-Learning)');
view(3);
% 设置坐标轴范围
xlim([1 X]); ylim([1 Y]); zlim([1 Z]);

% 绘制起点和目标
plot3(start(1), start(2), start(3), 'go', 'MarkerSize', 10, 'MarkerFaceColor', 'g');
plot3(goal(1), goal(2), goal(3), 'rp', 'MarkerSize', 12, 'MarkerFaceColor', 'r');
legend('起点', '目标点');

% 绘制路径 (轨迹连线)
if ~isempty(trajectory)
    plot3(trajectory(:,1), trajectory(:,2), trajectory(:,3), 'b-', 'LineWidth', 1.5);
    plot3(trajectory(:,1), trajectory(:,2), trajectory(:,3), 'b.', 'MarkerSize', 8);
end

% 动态障碍物动画
% 为每个障碍物创建一个图形对象
obs_handles = {};
for i = 1:length(all_obs_pos{1})
    obs_handles{i} = plot3(nan, nan, nan, 'rs', 'MarkerSize', 12, 'MarkerFaceColor', 'r');
end

% 添加无人机当前时刻标记
drone_handle = plot3(nan, nan, nan, 'bo', 'MarkerSize', 8, 'MarkerFaceColor', 'b');

% 时间显示文本
time_text = text(0.5, 0.9, 0.9, 't = 0', 'Units', 'normalized', 'FontSize', 10);

% 动画循环
max_t = min(length(all_obs_pos)-1, size(trajectory,1));
for ti = 1:max_t
    % 更新障碍物位置
    obs_pos_t = all_obs_pos{ti};
    for k = 1:length(obs_handles)
        if k <= length(obs_pos_t)
            set(obs_handles{k}, 'XData', obs_pos_t{k}(1), 'YData', obs_pos_t{k}(2), 'ZData', obs_pos_t{k}(3));
        else
            set(obs_handles{k}, 'XData', nan, 'YData', nan, 'ZData', nan);
        end
    end
    % 更新无人机位置
    if ti <= size(trajectory,1)
        set(drone_handle, 'XData', trajectory(ti,1), 'YData', trajectory(ti,2), 'ZData', trajectory(ti,3));
    end
    set(time_text, 'String', sprintf('t = %d', ti));
    drawnow;
    pause(0.2);  % 控制动画速度
end

fprintf('可视化完成。\n');
相关推荐
软件算法开发11 小时前
基于边境牧羊犬优化算法的LSTM网络模型(BCO-LSTM)的一维时间序列预测matlab仿真
人工智能·matlab·lstm·时间序列预测·边境牧羊犬优化·bco-lstm
LittroInno12 小时前
Tofu MS2 双光云台在无人机识别与跟踪中的深度应用
无人机
春日见14 小时前
E2E自驾规控30讲:导论
开发语言·驱动开发·git·matlab·计算机外设
深圳市快瞳科技有限公司15 小时前
低空经济下,鸟类识别算法与无人机硬件的兼容性优化策略
算法·无人机
guygg8817 小时前
基于数据驱动的模型预测控制电力系统机组组合优化MATLAB实现
开发语言·matlab
CoovallyAIHub17 小时前
传感器数据相互矛盾时,无人机蜂群如何做出可靠的管道泄漏检测决策?
算法·架构·无人机
happy_baymax18 小时前
三电平矢量表达式MATLAB实现
开发语言·matlab
小白小宋19 小时前
PRACH 前导序列生成详解与Matlab实现
5g·matlab·信息与通信·信号处理
t1987512819 小时前
基于深度学习的图像分割MATLAB实现
人工智能·深度学习·matlab