资讯动态

动态窗口法DWA:无人机避障原理与MATLAB实现

发布时间:2026/10/24 4:38:35 来源:尧图企业网站定制
先说结论DWADynamic Window Approach动态窗口法是目前做无人机、移动机器人、无人车局部路径规划时非常经典的算法尤其在“动态环境下自主避障并优化路径”这个场景它既不需要预先建出高精地图也不需要对障碍物做复杂的概率预测而是直接在速度空间里搜索可行轨迹再用评价函数挑一条最“合适”的。这篇文章我结合自己做的一个基于DWA的无人机避障仿真项目把原理、MATLAB实现、路径优化和调参经验一次讲清楚代码思路可以直接复用到ROS、Python或其他语言里。先说一下适合谁看如果你是刚接触路径规划的学生或者手头有个无人机自主飞行项目需要做避障模块再或者只想快速读懂DWA源码然后改造成自己的算法这篇文章都适用。核心内容包含完整的速度采样流程、轨迹推算、碰撞检测、评价函数设计以及动态障碍物模拟、全局路径衔接和多目标权重调节这些“只靠看论文学不到”的细节。1. DWA为什么适合动态环境下的无人机避障1.1 动态环境避障真正难在哪里无人机在动态环境里飞行难的不是“看到障碍物躲开”而是要在每一帧感知信息到来时快速算出“当前这一小段时间内到底该飞多快、往哪个方向转”。静态规划可以慢慢算几毫秒甚至几十毫秒延迟问题不大但动态环境里的行人、其他飞行器、移动车辆都是连续运动的等你算出一条完整路径障碍物可能已经不在原位置了。所以动态避障的核心约束是实时性规划必须在几十毫秒内完成而且要能随时打断、重新规划。DWA天然适合这个场景因为它不是规划一条从起点到终点的长路径而是只规划当前时刻到未来一小段时间内的运动轨迹周期循环、滚动执行。这种“短视”反而是优点配合全局路径方向做引导既能避开动态障碍又能保持整体方向不偏。这里要说明一点动态环境对算法的鲁棒性要求也很高。真实的传感器数据不可能像仿真里那样干净激光雷达会有噪声视觉里程计会漂移障碍物检测偶尔会漏检。DWA的滚动规划和频繁重决策机制天然能容忍一定程度的感知噪声——因为每一帧都在重新判断即使某一帧检测出问题下一帧也有机会纠正。这一点我在后面实机验证部分还会展开讲。1.2 DWA核心思想一句话描述DWA的核心可以用一句话概括在当前速度线速度和角速度附近开一个“动态窗口”窗口内采样多组候选速度每一组速度都模拟出一段圆弧轨迹然后检查轨迹是否碰撞并用评价函数对无碰撞轨迹打分得分最高的那组速度就是本周期要执行的速度。下一周期重新采样、重新打分形成持续避障。这里要注意关键词“动态窗口”。窗口不是固定的全速度空间而是受当前速度、最大加速度、减速距离约束的一个局部窗口。这样做有物理意义无人机或机器人的速度不能突变上一时刻还在慢速巡航这一时刻不可能立刻达到最大速度如果直接在全局速度空间采样会出现大量实际无法执行的速度组合算出来也白算。窗口越贴近真实运动能力规划结果越可靠。还有一个容易忽略的点DWA其实隐含了一个“假设”即在极短的控制周期内无人机近似做匀速圆周运动。这个假设在低速室内场景下非常合理但在高速大机动飞行时会偏差较大。如果你要做得更精细可以引入加加速度约束或者把轨迹模型从圆弧升级为多项式曲线但这会显著增加计算量。从工程角度说绝大多数项目先用圆弧模型就够用。1.3 和全局规划、采样规划、人工势场等方法对比算法核心思路动态避障能力主要弱点全局规划如图搜索类算法先建图再搜路径弱动态障碍需要频繁重规划计算开销大、地图更新慢人工势场障碍物斥力目标引力中容易局部极小、抖动目标与障碍距离接近时易震荡采样规划方法随机采样碰撞检测中概率完备但实时性一般高维或动态环境需大量采样DWA速度空间采样动态窗口强周期滚动执行需要合理设计评价函数全局最优性弱我自己的体会是DWA不是万能的它解决的是“局部避障”和“实时响应”这两件事。要想飞行整体路径仍然合理前面通常还要叠加一个全局规划器DWA只负责跟踪全局路径并避开局部动态障碍。这也是后面第4节要重点讲的问题。对比表里那几类方法人工势场实现简单但抖动问题实在太明显采样规划方法在高维空间实时性又跟不上DWA在性能和实现成本之间是一个很均衡的选择。2. DWA算法原理与关键参数2.1 速度采样空间一个窗口算给你看DWA第一步是确定本周期能接受多少组速度。以无人机二维平面避障为例假设当前线速度为v_c角速度为w_c最大线加速度为a_v_max最大角加速度为a_w_max控制周期为dt比如0.1秒那么下一个周期的线速度必须满足物理极限v 属于 [0, v_max]或 [-v_max, v_max] 如果允许后退加速度极限v 属于 [v_c - a_v_max * dt, v_c a_v_max * dt]安全制动约束v 不超过 sqrt(2 * dist_obstacle * a_brake)也就是保证在当前探测距离内能刹停这三个约束的交集就是动态窗口。很多人只做了前两个约束忽略了第三个结果仿真里看起来没问题实机上直接撞上去——特别是在高速飞行时探测距离不够的话很容易来不及刹车。安全制动距离是我调试时踩过的第一个坑。具体算一个例子假设当前前方2米处有障碍物最大减速度为0.8 m/s²那么安全制动约束下的最大线速度约为 sqrt(2 * 2 * 0.8) ≈ 1.79 m/s。如果你的v_max设成了2.5 m/s在接近障碍物时就应当被窗口限制到1.79 m/s以内而不是继续全速冲过去。采样分辨率也直接影响效果。线速度采样步长取0.01~0.1 m/s角速度采样步长取0.05~0.2 rad/s是比较常见的。步长太小采样组合数量暴涨计算时间拉长步长太大轨迹粗糙容易出现“看似避开了实际擦边”的情况。实际项目中可以先粗采样确定趋势再细采样精调方向。比如先在角速度上以0.2 rad/s步长找大致方向再在候选方向附近用0.05 rad/s步长细扫。2.2 轨迹预测每组速度对应一条圆弧DWA的轨迹预测采用“圆弧模型”。在很短的控制周期内假设无人机线速度和角速度保持不变那么位置变化可以近似为x_next x v * dt * cos(theta); y_next y v * dt * sin(theta); theta_next theta w * dt;对于多步预测比如前看时间horizon2秒预测20步就把这组方程循环执行20次得到一条圆弧轨迹。如果无人机还有垂直速度再加一个z方向递推即可但二维平面模型仍然是理解DWA的最佳起点。实际项目中三维DWA通常是在高度方向上做PID保持或独立的高度规划水平面避障用二维DWA这样实现起来更简单而且调试时更容易定位问题。轨迹预测里有一个重要细节轨迹点的密度如何设置。假设horizon2秒dt0.1秒那么一条轨迹上有21个点。如果你把dt设成0.05秒轨迹点增加到41个碰撞检测更精细但计算量也翻倍。我在仿真里发现20~30个轨迹点通常就足够再多对最终评分影响很小反而拖慢速度。真正需要增加轨迹点的情况是障碍物很薄、无人机飞行速度很快时这时点太少可能会“跳过”一个薄障碍。2.3 评价函数三条指标怎么权衡DWA经典的评价函数由三项组成方位角评价angle评价轨迹终点方向与目标点方向的夹角。夹角越小说明这条轨迹越“指向目标”分越高。障碍物距离评价dist评价轨迹与最近障碍物的距离。距离越大越安全分越高。速度评价velocity评价当前速度大小。速度越大越高效分越高。总评分为三项的加权和通常还要做归一化处理。权重recommend比例不同项目差异很大我自己常用的是 方位角0.2、障碍物距离0.5、速度0.3 这一组优先保证安全然后再兼顾效率和指向性。如果你做的是服务机器人可能希望更加平滑那可以降低速度权重增加方位角权重如果做的是巡检无人机需要更快到达目标那速度权重可以调高。真正调试时要注意三项指标量纲不同不能直接加权。方位角是弧度距离是米速度是米每秒。归一化不是可选项是必要步骤。但归一化也要小心如果某条轨迹障碍物距离为0已经碰撞应该直接排除而不是让它参与归一化后把障碍距离项变成0分这样会把危险轨迹强行拉高到和其他轨迹一起比较容易产生误判。实际代码里我会先把所有碰撞轨迹的评分设为一个极小的负数然后再对无碰撞轨迹做归一化这样能保证碰撞轨迹永远排不到前面。3. MATLAB实现从零写一个DWA避障仿真3.1 程序整体架构和数据结构我先说一下整体架构。我做这个项目的时候没有用复杂的类封装而是按照“初始化-主循环-结果可视化”三段式来写。这样做主是因为无人机避障的核心逻辑在循环里过早抽象反而增加阅读门槛。建议思路如下%% 初始化参数 dt 0.1; % 控制周期 v_max 2.0; % 最大线速度 m/s w_max pi/2; % 最大角速度 rad/s a_v_max 1.0; % 最大线加速度 m/s^2 a_w_max pi/3; % 最大角加速度 rad/s^2 v_res 0.05; % 速度采样分辨率 w_res 0.1; % 角速度采样分辨率 horizon 2.0; % 轨迹预测前向时长 goal [8, 6]; % 目标点 obs_static [2,2; 4,3; 3,6]; % 静态障碍物位置 % 动态障碍物可以定义为一个结构体数组记录位置、速度、半径 dyn_obs.pos [5,2]; dyn_obs.vel [0.5, 0.2]; dyn_obs.r 0.4;这里把静态障碍物坐标写死主要便于复现和理解。如果你有栅格地图或激光雷达数据可以用障碍物列表甚至距离场替代。注意事项如果你希望代码更通用建议把障碍物统一整理为一个N行3列的矩阵[N, x, y]并额外一个列存半径。这样做碰撞检测时可以用矩阵运算一次算完避免写一堆for循环。3.2 主循环滚动执行采样与评价整个避障过程是一个固定频率的滚动规划循环。每0.1秒重新计算一次速度指令然后发给飞行控制层。主循环结构如下state [0, 0, pi/3]; % x, y, thetatheta是航向角 v 0; w 0; for t 0:dt:30 % 1. 计算动态窗口范围 [v_min_win, v_max_win, w_min_win, w_max_win] computeWindow(v, w, params); % 2. 在窗口内采样候选速度 [v_samples, w_samples] sampleVelocity(v_min_win, v_max_win, w_min_win, w_max_win, v_res, w_res); % 3. 对每组速度生成预测轨迹并做碰撞检测 [traj_set, feasible_idx] generateTrajectory(state, v_samples, w_samples, horizon, dt); % 4. 计算评价函数选出当前最优速度 [best_v, best_w] evaluateTrajectory(traj_set, feasible_idx, v_samples, w_samples, goal, obstacles); % 5. 更新状态移动障碍物 state updateState(state, best_v, best_w, dt); v best_v; w best_w; moveDynamicObstacles(dyn_obs, dt); % 6. 可视化 plotResult(state, traj_set, goal, obstacles); end几个要注意的地方每周期都要把动态障碍物移动一步不然“动态”就只是个摆设轨迹生成和碰撞检测要用向量化写法避免用纯for循环叠加否则采样组数一多比如几千组仿真会变得很慢。MATLAB里用矩阵运算一次算完所有轨迹位置能快一个数量级。循环里我用了动态障碍物结构体如果你有多个动态障碍物最好把它们做成数组并在moveDynamicObstacles函数里统一更新。更新状态时注意航向角theta需要做角度归一化否则长时间仿真后角度值越积越大cos/sin计算虽然没问题但显示轨迹和比较方位角时会很麻烦。我习惯把theta归一到[-pi, pi]范围。3.3 动态窗口计算与速度采样函数具体的动态窗口计算函数我按前文所述三个约束实现。这是DWA的“门禁”速度越界直接pass实际写出如下function [v_min_win, v_max_win, w_min_win, w_max_win] computeWindow(v, w, params) % 物理极限 v_min -params.v_max; v_max params.v_max; w_min -params.w_max; w_max params.w_max; % 加速度约束 v_min_acc v - params.a_v_max * params.dt; v_max_acc v params.a_v_max * params.dt; w_min_acc w - params.a_w_max * params.dt; w_max_acc w params.a_w_max * params.dt; % 取交集 v_min_win max([v_min, v_min_acc]); v_max_win min([v_max, v_max_acc]); w_min_win max([w_min, w_min_acc]); w_max_win min([w_max, w_max_acc]); end注意我在这里没加入安全制动约束是因为这个约束依赖障碍物距离需要在碰撞检测模块里逐条轨迹判断。如果你希望窗口级过滤可以把当前前方障碍距离作为输入修改v_max_win min(v_max_win, sqrt(2 * min_dist * a_brake))。算制动距离时我通常把加速度取为最大减速度的0.8倍留出安全余量。为什么取0.8而不是1.0因为真实减速度受电机响应、电池电压、风阻等因素影响不一定能达到标定值留20%余量是工程上的常见做法。速度采样就是生成网格组合。比如v取0到2.0 m/s、步长0.05得到41个点w取-1.57到1.57 rad/s、步长0.1得到32个点组合后就是1312组候选速度。这个数量在MATLAB里进行向量化轨迹预测是没问题的如果你用Python可以借助NumPy效果一样。采样时要注意边界条件MATLAB的linspace和meshgrid组合起来很方便但记得把w0也就是直线飞行的情况保留下来否则无人机只能在转弯中选一个会导致直线段缺失。3.4 轨迹预测和碰撞检测的MATLAB实现轨迹预测模块我来展示最核心的向量化写法。这里把候选速度组合转换成矩阵然后用状态递推公式一次性算出所有轨迹。直到horizon时刻结束记录每条轨迹的终点位置、最小障碍物距离、终点航向角。function traj predictTrajectory(state, v_samples, w_samples, horizon, dt) n length(v_samples); steps horizon / dt; x0 state(1); y0 state(2); theta0 state(3); traj_x zeros(n, steps1); traj_y zeros(n, steps1); traj_theta zeros(n, steps1); traj_x(:,1) x0; traj_y(:,1) y0; traj_theta(:,1) theta0; for k 1:steps traj_x(:, k1) traj_x(:, k) v_samples .* cos(traj_theta(:, k)) * dt; traj_y(:, k1) traj_y(:, k) v_samples .* sin(traj_theta(:, k)) * dt; traj_theta(:, k1) traj_theta(:, k) w_samples * dt; end % 保存每条轨迹终点和最小障碍距离等信息 traj.x traj_x; traj.y traj_y; traj.theta traj_theta; end注意这里的v_samples和w_samples必须是相同长度的列向量组合采样时一一对应。如果你想对“前向速度”和“角速度”做独立组合那就需要生成网格然后拉平对应关系也要同步处理。这个函数每执行一次就生成一整批轨迹比在循环里逐个调函数要快很多。碰撞检测我用的是最近距离判断计算轨迹上所有点到每个障碍物中心的欧氏距离如果小于无人机安全半径与障碍物半径之和就判定碰撞。为了效率可以只检查预测轨迹末端的几个关键点——因为轨迹中点比端点更接近当前状态但实际调试发现这样并不可靠最好全程检测。function [collision, min_dist] checkCollision(traj, obstacles, drone_radius) collision false; min_dist inf; for i 1:size(obstacles, 1) dx traj.x - obstacles(i,1); dy traj.y - obstacles(i,2); dist sqrt(dx.^2 dy.^2); min_current min(dist(:)); if min_current (drone_radius obstacles(i,3)) collision true; end if min_current min_dist min_dist min_current; end end end如果你有多个动态障碍物可以把moving obstacle也合并在obstacles矩阵中每一帧更新位置后再检测。实际项目里注意轨迹点密度太高会让碰撞检测耗时长但太小则会漏检“掠边”情况。建议把steps控制在20~50个既能覆盖预测时长又不会造成运算瓶颈。一个小技巧当你发现仿真中偶尔出现“穿模”式碰撞未检出的情况先把steps加倍看看是否消失如果能消失说明是轨迹采样点太稀而不是算法逻辑问题。3.5 动态障碍物建模与运动更新动态环境的模拟我采用“匀速直线运动随机噪声”的模型简单好用。每个动态障碍物有位置、速度、半径三个字段每控制周期更新function moveDynamicObstacles(dyn_obs, dt) for i 1:length(dyn_obs) dyn_obs(i).pos dyn_obs(i).pos dyn_obs(i).vel * dt; % 可添加小幅随机扰动模拟不可预测运动 dyn_obs(i).vel dyn_obs(i).vel 0.02 * randn(1,2); end end加随机噪声的目的是模拟真实世界的不确定性避免算法“背答案”。如果你只做匀速障碍物DWA当然容易避开一旦障碍物随机改变方向才是真正考验局部规划实时性的时候。我实际调试中发现障碍物速度不要超过无人机最大速度的0.6倍否则单纯靠局部规划很难保证安全需要更高层的速度约束介入。这里的0.6倍没有严格理论依据只是经验值超过这个比例无人机即使全速避开也很难在预测窗口内拉开足够距离。在动态障碍物的更新里还有一个细节如果随机噪声加得太大障碍物会在原地抖动既不真实也增加避障难度。建议噪声方差不要太大能体现“运动不确定性”即可比如0.02~0.05的std。你还可以让障碍物在到达地图边界时反弹避免它飞出视野范围。4. 路径优化从局部避障到全局路径的衔接4.1 为什么只有DWA不够DWA是“近视眼”它只看未来2秒内的轨迹。如果目标点很远而且中间有曲折障碍区纯DWA可能会陷入局部振荡甚至卡在U形障碍区域。我做个仿真对比在没有全局路径引导时无人机遇到一个凹形障碍物会反复左右尝试轨迹来回摆动最后虽然没撞上但飞行距离明显增加。因此实际系统普遍用全局规划器先生成一条参考路径DWA的方位角评价不再是直接指向目标点而是指向参考路径上的前瞻点。全局路径可以用经典的A*、RRT或者更轻量的路线点数组来生成。关键是把全局路径转成“航向引导”选择距离无人机当前位置一定前瞻距离比如1.5米的路径点作为中间目标替代最终目标参与评价函数。这样做DWA既能跟随全局趋势又能局部避障。如果你用的全局路径点很密可以每隔几个点取一个做采样避免频繁切换中间目标导致航向抖动。衔接代码的伪代码大概是这样lookahead_idx findNextLookaheadIndex(global_path, state, lookahead_dist); local_goal global_path(lookahead_idx, :); score evaluateTrajectory(traj_set, feasible_idx, v_samples, w_samples, local_goal, obstacles);这里的lookahead_dist和时间常数类似太近了会导致无人机频繁转弯太远了又忽略了局部的障碍信息。一般设为1~2倍的安全距离或者0.5~1秒航程。4.2 路径平滑与轨迹执行优化DWA输出的速度指令是分段恒定的直接给飞行控制器会造成速度突变。所以我在仿真和实际项目中都会加一个低通滤波器或速度斜坡限制目标速度经过一阶惯性环节后再发给执行层。简单写法v_cmd_filtered v_cmd_filtered (v_new - v_cmd_filtered) * 0.5; w_cmd_filtered w_cmd_filtered (w_new - w_cmd_filtered) * 0.5;这里的系数0.5相当于时间常数约为0.1秒具体情况看你飞控的响应速度。响应过慢会导致轨迹滞后过快的又起不到平滑作用。调平滑系数的时候你可以先观察角度指令曲线是否毛刺很多再把系数降到0.3~0.5之间。实际测试中如果系数小于0.2飞机会变得“肉”很多转弯明显迟缓大于0.8则基本没有平滑效果。另外一个常被忽略的优化点是“动态窗口里的轨迹终点方向”。如果只用轨迹终点到目标点的夹角做评价转弯时容易大角度偏转。改进办法是把目标点方向改成“前瞻点方向”或者用路径切向量做参考这样转弯更顺。举例来说无人机在直线路径上飞行时轨迹终点方向与路径切向几乎一致评分自然高遇到动态障碍需要绕行时朝向参考点偏移也不会偏太多。4.3 仿真场景设计和参数调优边界仿真场景的好坏直接决定你能否发现算法的问题。我的做法是设计三个难度梯度第一场景只有静态障碍物验证基本导航能力第二场景加入一个匀速横穿障碍物验证动态避障第三场景加入两个方向交叉的随机运动障碍物验证多障碍物下的实时性与稳定性。每个场景跑够100次记录成功率无碰撞到达目标、平均飞行时间、最小障碍距离。不要只看某一次成功就说算法OK因为动态环境的随机扰动会导致不同结果。我做过一次参数调整把速度权重从0.3提到0.5单次仿真看起来更快了跑了50次之后发现碰撞率从2%升到了11%明显不可接受。所以一定要做统计测试不要拿单次轨迹说事。我的仿真场景参数大致如下地图范围20m x 20m起点(0,0)目标(15,15)静态障碍物数量8~12个动态障碍物数量1~3个速度方向每次随机。成功率低于90%就要回头调参。如果你发现某个场景几乎100%成功但某个随机种子下偶尔失败不要忽略它那很可能暴露了算法在边界条件下的缺陷。我会单独保存这些失败案例的轨迹和参数用来反向定位问题。为了可视化方便我还会在图上画出当前周期的所有候选轨迹用透明度区分分数高低这样能看到DWA每个时刻在想什么。这个可视化对调试特别有帮助否则只看最终路径根本不知道某个转向是“有意为之”还是“被迫选择”。5. 常见问题与调试经验5.1 无人机轨迹振荡的四个原因振荡是DWA调试里出现最多的现象表现是航向角频繁正负切换轨迹呈锯齿状。我排查时按四个步骤来第一看评价函数三项的权重是否失衡。如果方位角权重太高会把无人机拉向目标但避障产生的方向变化又让它立刻回拉来回拉扯。这时先降低方位角权重或加大障碍物距离权重。第二看采样分辨率是否太粗。w_res设为0.2 rad/s时角速度只有正负7个可选档位导致转向前后只有两种大变化轨迹自然不连贯。改成分辨率0.05 rad/s锯齿明显减少。第三看预测前向时间horizon是否过短。horizon小于1秒时轨迹看得太短算法发现前方有障碍时几乎马上要打方向没有提前量。调到2秒以上后避障路径变得更平滑。第四看安全制动约束是否生效。如果窗口没限制最大速度无人机在靠近障碍物时还是全速碰撞检测就会要求它急转引发剧烈摆动。加入制动约束后速度提前降下来摆动问题缓解很大。振荡问题的一个快速判断技巧把轨迹图画出来如果候选轨迹像扇子一样发散说明采样空间太大或分辨率太粗如果候选轨迹都挤在一起说明窗口太窄或加速度约束太强。通过观察扇面形状基本能定位是哪一类参数出了问题。5.2 陷入局部最优绕过U形障碍的经验U形障碍凹形障碍区是所有局部规划算法的噩梦。DWA在U形口附近会错误地认为“往目标方向走最安全”于是向里探索最后发现三面被围。要解决这个问题我给出三个方向一是在全局层面增加“逃逸”逻辑比如允许无人机临时偏离全局路径反向寻找“开路点”。这通常需要更高层的状态机判断当连续多个周期位移变化很小且前方障碍距离持续小于阈值时进入“撤退模式”。二是在评价函数层面降低DWA对局部目标的精确追求把方位角评价换得更“柔和”减少向障碍内部前进的倾向。同时增大障碍物距离评价对附近障碍物的“惩罚范围”而不是只在很近时才触发。三是配置全局路径点提供“穿越引导”让DWA沿着一条预先穿过U形障碍外沿的路径走而不是直接穿向目标。从工程上来讲DWA不擅长设计全局绕行策略这一块让给全局规划器更合理。我在仿真里测试过一种简单有效的办法当检测到前方障碍密度较大且路径偏移持续增大时把局部目标点人为标到障碍物边缘外迫使DWA先远离U形口。这个“骚扰式”的临时目标切换虽然土但很好用而且代码改动量很小。5.3 参数调优参考表我把一组合适的初始参数列成表供你起步用。这里以室内小型无人机为例参数需要根据你的物理平台调整参数推荐初始值调整方向dt控制周期0.1 s越小越平滑但计算量增大v_max最大线速度2.0 m/s按无人机性能上限设w_max最大角速度1.57 rad/s机动性弱可减小a_v_max1.0 m/s^2越大越灵活但冲击大a_w_max1.05 rad/s^2越大越灵活horizon预测时长2.0 s环境动态快则减小方位角权重0.2路径跟随需求高可加大障碍距离权重0.5安全优先就加大速度权重0.3效率优先可加大这组参数在我做的某模拟项目X中表现稳定但换一个传感器噪声特性不同的平台可能就要调整。比如激光雷达测距误差大的话障碍物距离权重不能设太高否则会让无人机离障碍物过远路径绕到离谱。另一个经验是如果你发现DWA在某些情况下变得过于保守总是远离障碍物到夸张程度可以适当调低障碍距离权重或缩小安全半径。安全性并不是唯一指标飞行任务能不能完成同样重要。调参时我还有个习惯每次只调整一个参数别同时动两三个。这说起来简单但实际操作时特别容易犯。如果同时调了权重和horizon出了问题你很难知道是哪一步造成的。保持一个参数变化记录前后仿真统计结果比对效果会清晰很多。5.4 从MATLAB仿真到实机验证的注意事项仿真和真机的差距主要在三方面时间延迟、感知噪声、执行误差。MATLAB仿真里你用完美状态做规划但实机上状态估计有延迟和漂移所以DWA的输入状态必须做滤波常见做法是对位置、速度、航向分别使用低通滤波或卡尔曼滤波。第二个是时间同步。实机控制频率可能不是稳定的10Hz而DWA代码默认dt固定如果实际周期忽长忽短轨迹预测会产生误差。建议在代码里加一个实际dt的计算用时戳相减替代固定值。第三个是执行误差。飞控给出的速度指令与实际速度有差异DWA的输出只是一个参考速度。安全起见把障碍物安全半径扩大20%~30%我实测下来防碰撞效果明显提升。另外切记在实机测试前先在仿真里把所有障碍物速度、噪声扰动都加上多跑随机场景不要拿真实无人机冒险。实机验证还有一个容易被忽视的点传感器视场角有限。仿真里障碍物是全向可见的但真实无人机上的雷达或视觉传感器通常只有前方一定角度范围。DWA假设无人机能看到周围所有障碍物如果你的传感器没有全向覆盖就需要把检测范围限制在传感器FOV内否则算法会以为侧面没障碍物而做出危险动作。我遇到过几次这种问题后来干脆在DWA的碰撞检测模块里加入“只在距离小于感知范围时不检测”的逻辑实机表现才稳定。结尾最后再分享一个小技巧调试DWA时不要一上来就盯权重先固定一个默认权重把采样分辨率、预测时长、加速度约束这组物理参数调到行为稳定再去调权重。我见过很多新人卡在权重组合上其实大部分抖动问题都出在前三类参数上。先把“运动学可行”做到位评价函数只是帮你选“更优”而不是替你弥补运动模型错误。你把这个思路理顺再回头去看DWA的MATLAB代码会感觉每一步都很顺。希望这篇基于我实际项目经验的拆解能帮你把DWA真正用起来。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑