采样规划系列讲完了,从今天开始进入局部规划系列。第一个要讲的就是DWA——动态窗口法(Dynamic Window Approach)。这是移动机器人局部规划中最经典、用得最多的算法。讲真,做导航的面试不问DWA几乎不可能。

DWA是Fox等人在1997年提出的。核心思想很直白:机器人在每个控制周期,根据当前速度和一个时间窗口,算出一组可行的速度命令,然后从中选一组"最好"的。"最好"由三个评价函数决定——朝目标走、走得快、远离障碍物。

一、DWA的核心流程

DWA在每个控制周期做以下事情:

  1. 计算动态窗口:根据当前速度和加速度限制,算出下一个时间步内能达到的速度范围。这个范围就是"动态窗口"。
  2. 采样速度:在动态窗口内均匀采样若干组(v, omega)——线速度和角速度。
  3. 前向仿真:对每组速度,模拟机器人在未来一小段时间内的运动轨迹。
  4. 评价轨迹:用三个评价函数给每条轨迹打分。
  5. 选最优速度:得分最高的那组速度就是输出。
def dwa(current_vel, goal, obstacles, dt=0.1):
    # 1. 动态窗口:当前速度 +/- 加速度*dt
    v_range = (current_vel.v - a_max*dt, current_vel.v + a_max*dt)
    w_range = (current_vel.w - alpha_max*dt, current_vel.w + alpha_max*dt)
    # 2. 采样速度
    best_score, best_cmd = -inf, None
    for v, w in sample_velocities(v_range, w_range):
        # 3. 前向仿真
        traj = simulate(v, w, dt, steps=10)
        # 4. 评价
        score = heading(traj, goal) + velocity(v) + clearance(traj, obstacles)
        if score > best_score:
            best_score, best_cmd = score, (v, w)
    return best_cmd

动态窗口的"动态"二字很关键——窗口大小取决于当前速度。速度高时窗口大(能选择的速度范围宽),速度低时窗口小。这保证了速度的连续性——机器人不会突然从高速变成低速。

二、三个评价函数

DWA的核心在于三个评价函数的设计和权重调参。

heading(朝向目标):轨迹终点到目标的方向角。角度越小(越朝目标方向),得分越高。这个函数让机器人趋向目标。

velocity(速度):线速度的大小。速度越快,得分越高。这个函数让机器人尽量走快。

clearance(离障碍物距离):轨迹上最近点到障碍物的距离。距离越大,得分越高。这个函数让机器人远离障碍物。

最终得分是三个函数的加权和:score = alpha * heading + beta * velocity + gamma * clearance。权重alpha、beta、gamma需要根据场景调参。一般heading权重最大(朝目标最重要),clearance次之,velocity最小。

# 评价函数的典型权重
alpha = 0.75  # heading
beta = 0.05   # velocity
gamma = 0.2   # clearance

调参是个技术活。heading权重太高,机器人会直冲目标不管障碍物。clearance权重太高,机器人会过度保守,贴着墙根走。velocity权重太高,机器人会冒不必要的风险去走快。

三、DWA的工程细节

工程上实现DWA有几个容易忽略的点。

速度采样分辨率:v和omega的采样步长直接影响计算量和路径质量。步长太粗,可能漏掉好的速度组合;步长太细,计算量大。工程上一般v采样10-20个值,omega采样20-40个值,总共200-800条轨迹。在ROS的nav2中,DWA的默认配置是v采样20个、omega采样20个,总共400条轨迹。

仿真时间:前向仿真多长时间?太短了看不到远处障碍物,太长了计算量大且预测不准。一般取1-3秒。如果机器人速度快(比如2m/s),仿真时间短一些(1秒)就够了。仿真时间和控制频率也有关系——频率高(比如20Hz),仿真时间可以短一些,因为很快会重新规划。

机器人模型:仿真时要考虑机器人的实际形状,不能只用一个点。工程上通常把机器人简化为圆形(用最大半径),这样碰撞检测只需要算轨迹点到障碍物的距离减去机器人半径。如果是矩形机器人,需要更精确的碰撞检测(比如分离轴定理),计算量会大一些。

局部最小值:DWA可能陷入局部最小值——比如U型障碍物中,机器人可能在U口来回摆动。工程上的解决办法:如果DWA连续几个周期输出速度接近零,切换到全局重规划或者退回到安全位置。ROS2的nav2中有一个recovery behavior机制——检测到DWA卡住时触发旋转或者后退。

不同机器人类型的适配:DWA最初是为差速驱动机器人设计的(两个独立驱动的轮子)。对于全向轮机器人(比如Mecanum轮),速度空间从(v, omega)扩展到(vx, vy, omega)——多了一个横向速度维度。对于Ackermann转向的机器人(比如汽车),速度空间要受最小转弯半径约束——omega不能任意大,它和v/r_min有关。

# 不同机器人类型的速度空间
# 差速驱动: (v, omega), v∈[-v_max, v_max], omega∈[-w_max, w_max]
# 全向轮: (vx, vy, omega), 三个维度独立
# Ackermann: (v, omega), omega∈[-v/r_min, v/r_min]

四、面试实战

Q:DWA和势场法有什么区别? A:势场法在每个点算一个合力方向,然后沿合力方向走。DWA是采样一组速度,前向仿真后选最优。势场法计算简单但容易振荡,DWA计算量大一些但路径更平滑。DWA考虑了机器人的运动学约束(速度、加速度限制),势场法没有。

Q:DWA为什么叫"动态"窗口? A:因为速度窗口的大小取决于当前速度。当前速度高,窗口大(能加减速的范围宽);当前速度低,窗口小。窗口随当前状态动态变化,所以叫"动态窗口"。

Q:DWA在实际项目中用过吗? A:用过。做仓储AGV导航时,全局用A*规划路径,局部用DWA避障。控制频率10Hz,每次DWA计算约5ms(采样400条轨迹)。效果不错,但在狭窄通道中偶尔会振荡——后来加了全局路径引导(让heading函数参考全局路径而不是直接指向目标),问题解决了。

Q:DWA的缺点是什么? A:三个主要缺点。一是局部最小值问题——U型障碍物中容易卡住。二是只看一步——前向仿真时间有限,看不到远处的路。三是调参麻烦——三个权重需要根据场景反复调。

Q:DWA和TEB有什么区别? A:DWA采样速度后选最优,TEB直接优化轨迹。DWA更简单、计算更快,但路径质量不如TEB。TEB能处理更复杂的约束(比如差速驱动的运动学模型、时间最优),但计算量大。工程上DWA用于简单场景(仓储AGV、服务机器人),TEB用于复杂场景(自动驾驶、高精度导航)。

小结

DWA的核心:根据当前速度计算动态窗口,在窗口内采样速度,前向仿真后选评价最高的速度命令。

优势:实现简单,计算快,考虑了运动学约束,路径平滑。 劣势:局部最小值问题,只看一步,调参有门槛。

DWA是移动机器人局部规划的入门算法,也是工业界用得最多的局部规划器之一。ROS1的dwa_local_planner和ROS2的nav2_dwb_controller都是基于DWA的思想。理解DWA之后,下一篇讲TEB局部规划器——用图优化来生成更高质量的局部轨迹,能处理更复杂的运动学约束。


如果这篇文章对你有帮助,欢迎点赞、在看、转发三连。 你的支持是我持续更新的最大动力。

「机器人软件开发面试·从入门到精通」连载系列 

上一篇:第218篇 BIT*——当采样规划遇上图搜索

下一篇预告:第220篇 TEB局部规划器——用图优化生成局部轨迹

有任何问题欢迎评论区留言,我会尽量回复。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐