DWA (Dynamic Window Approach)#

DWA is a famous local planning method developed since the 90s.[1] DWA is a sampling-method consists of sampling a set of constant velocity trajectories within a window of admissible reachable velocities. This window of reachable velocities will change based on the current velocity and the acceleration limits, i.e. a Dynamic Window.

Implementation Requirements:

  • Define the acceleration limits and the motion model of the robot

  • Define a sampling step (or max number of samples) for the velocity commands

  • Define an admissible trajectory criteria

  • Simulate the robot movement based on the motion model for each velocity sample in the dynamic window and generate a set of admissible trajectories

  • Define a cost or optimization criteria to select the best trajectory (minimal cost) among the admissible trajectories

Supported Motion Models#

  • ACKERMANN

  • DIFFERENTIAL_DRIVE

  • OMNI

Supported Sensory Inputs#

  • LaserScan

  • PointCloud

  • OccupancyGrid (comping soon)

Trajectory Samples Generator:#

Admissible trajectory criteria:#

A collision-free admissibility criteria in implemented within the trajectory samples generator using FCL to check the collision between the simulated robot state and the reference sensor input.

Trajectory Samples for ACKERMANN Robot

Generated Trajectory Samples for an Ackermann Robot#

Note

To maintain a natural movement For both Differential drive and Omni robots; rotation in place and linear movement at the same time are not supported. The trajectory sampler implements rotate-then-move policy.

Trajectory Samples for Differential Drive Robot

Generated Trajectory Samples for a Differential Drive Robot#

Trajectory Samples for OMNI Robot

Generated Trajectory Samples for an Omni motion Robot#

Trajectory Selection#

The cost of each admissible sample is computed using Cost Evaluator and the sample with the lowest cost is selected for navigation.

usage Example#

from kompass_core.control import DWAConfig, DWA
from kompass_core.models import (
    AngularCtrlLimits,
    LinearCtrlLimits,
    Robot,
    RobotCtrlLimits,
    RobotGeometry,
    RobotType,
)

# Configure the robot
my_robot = Robot(
        robot_type=RobotType.ACKERMANN,
        geometry_type=RobotGeometry.Type.CYLINDER,
        geometry_params=np.array([0.1, 0.4]),
    )

# Configure the control limits (used to compute the dynamic window)
robot_ctr_limits = RobotCtrlLimits(
    vx_limits=LinearCtrlLimits(max_vel=1.0, max_acc=5.0, max_decel=10.0),
    omega_limits=AngularCtrlLimits(
        max_vel=2.0, max_acc=3.0, max_decel=3.0, max_steer=np.pi
    ),
)

# Configure the controller
config = DWAConfig(
        max_linear_samples=20,
        max_angular_samples=20,
        octree_resolution=0.1,
        prediction_horizon=1.0,
        control_horizon=0.2,
        control_time_step=0.1,
    )

controller = DWA(robot=my_robot, ctrl_limits=robot_ctr_limits, config=config)