动态窗口法(Dynamic Window Approach)概述

DWA是一种基于速度的局部规划器,可计算达到目标所需的机器人的最佳无碰撞速度。

DWA

程序实现

DWA算法主要分三步:

  • 计算动态窗口
  • 计算最优 [ v , ω ] [v,\omega] [v,ω]
  • 更新机器人状态

流程图如下:

流程图

以下代码参考:https://github.com/AtsushiSakai/PythonRobotics

初始化机器人状态、目标位置、障碍物位置
# 初始化机器人状态 [x(m), y(m), yaw(rad), v(m/s), omega(rad/s)]
x = np.array([0.0, 0.0, math.pi / 8.0, 0.0, 0.0])
# 目标位置 [x(m), y(m)]
goal = np.array([gx, gy])
# 障碍物位置 [x(m), y(m)]
ob = np.array([[-1, -1], ...... , [13.0, 13.0]])
获取动态窗口

这个动态窗口就是机器人在当前状态下能达到的速度 v v v和转速 ω \omega ω范围,受到自身机械特性以及当前状态的影响。

def calc_dynamic_window(x, config):
    """
    calculation dynamic window based on current state x
    """

    # Dynamic window from robot specification
    Vs = [config.min_speed, config.max_speed,
          -config.max_yawrate, config.max_yawrate]

    # Dynamic window from motion model
    Vd = [x[3] - config.max_accel * config.dt,
          x[3] + config.max_accel * config.dt,
          x[4] - config.max_dyawrate * config.dt,
          x[4] + config.max_dyawrate * config.dt]

    #  [vmin, vmax, yaw_rate min, yaw_rate max]
    dw = [max(Vs[0], Vd[0]), min(Vs[1], Vd[1]),
          max(Vs[2], Vd[2]), min(Vs[3], Vd[3])]

    return dw
计算最优 [ v , ω ] [v,\omega] [v,ω]

对动态窗口采样,得到 N × M N\times M N×M [ v i j , ω i j ] ∣ i < N , j < M [v_{ij},\omega_{ij}]|i<N,j<M [vij,ωij]i<N,j<M,并计算 v = v i j , ω = ω i j v=v_{ij},\omega=\omega_{ij} v=vij,ω=ωij时机器人的预测轨迹。接下来计算机器人 v = v i j , ω = ω i j v=v_{ij},\omega=\omega_{ij} v=vij,ω=ωij时的评价函数:
G ( v , ω ) = a 1 ⋅ h e a d i n g ( v , ω ) + a 2 ⋅ d i s t ( v , ω ) + a 3 ⋅ v e l o c i t y ( v , ω ) G(v,\omega)=a_1\cdot heading(v,\omega)+a_2\cdot dist(v,\omega)+a_3\cdot velocity(v,\omega) G(v,ω)=a1heading(v,ω)+a2dist(v,ω)+a3velocity(v,ω)

  • h e a d i n g ( v , ω ) heading(v,\omega) heading(v,ω)表示机器人运动方向与目标方向的偏差 θ \theta θ(如下图)。
target_heading
  • d i s t ( v , ω ) dist(v,\omega) dist(v,ω)表示与预测轨迹相交并且距离当前机器人位置最近的障碍物的距离,当没有障碍物处于预测轨迹上时,这个函数取一个很大的常数。
  • v e l o c i t y ( v , ω ) velocity(v,\omega) velocity(v,ω)表示机器人处于预测轨迹最后一点时的速度 v v v

计算机器人处于 v = v i j , ω = ω i j v=v_{ij},\omega=\omega_{ij} v=vij,ω=ωij时的评价函数,得到一系列的代价,代价最小时的 [ v i j , ω i j ] [v_{ij},\omega_{ij}] [vij,ωij]即为最优 [ v , ω ] [v,\omega] [v,ω]

def calc_control_and_trajectory(x, dw, config, goal, ob):
    """
    calculation final input with dynamic window
    """

    x_init = x[:]
    min_cost = float("inf")
    best_u = [0.0, 0.0]
    best_trajectory = np.array([x])

    # 计算动态窗口内所有的采样样本的代价函数
    for v in np.arange(dw[0], dw[1], config.v_reso):
        for y in np.arange(dw[2], dw[3], config.yawrate_reso):

            trajectory = predict_trajectory(x_init, v, y, config)

            # 计算代价函数
            to_goal_cost = config.to_goal_cost_gain * calc_to_goal_cost(trajectory, goal)
            speed_cost = config.speed_cost_gain * (config.max_speed - trajectory[-1, 3])
            ob_cost = config.obstacle_cost_gain * calc_obstacle_cost(trajectory, ob, config)

            final_cost = to_goal_cost + speed_cost + ob_cost

            # 寻找具有最小代价的样本以及它的轨迹
            if min_cost >= final_cost:
                min_cost = final_cost
                best_u = [v, y]
                best_trajectory = trajectory

    return best_u, best_trajectory
更新状态

根据最优 u = [ v , ω ] u=[v,\omega] u=[v,ω]更新机器人状态

x = motion(x, u, config.dt)  

完整代码参见这里

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐