> For the complete documentation index, see [llms.txt](https://docs.hello-robot.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hello-robot.com/stretch4_docs/working-with-stretch/nav_u/local-planning-dwb.md).

# Local Planning with DWB

In this tutorial, we will be learning how to configure the local planner. The local planner is the algorithm that takes the global plan and decides which velocities to send to the Stretch base to efficiently drive along the path and get to the goal.

## Velocity Commands

In configuring the local planner, the first thing you need to specify are what velocity commands are valid. We’ll be publishing Twist messages just like we were in the [Moving the Robot](https://github.com/hello-robot/stretch4_docs/blob/main/wiki/moving-the-robot/README.md) tutorial. Stretch 4 is omnidirectional, we’ll need to configure the two linear components (x and y) and the rotational component (depending on the context, either theta, yaw or z). (If you are configuring an earlier Stretch, you would need to ensure that the y component is zero.)

A sensible maximum linear speed (in any direction) of Stretch 4 is 0.3 meters per second. A sensible maximum angular speed is 2.0 radians per second.

In addition to specifying the maximum velocities, we also need to specify the maximum accelerations. There is a physical limit to how quickly we can change speeds. While you could just start sending a maximum velocity command when the robot is not moving, and it will eventually reach that velocity, modeling the acceleration limits gives the planner a more accurate model of the movement. We also may need to model the deceleration limits for how quickly the robot can slow down. Often, these are set symmetrically to the acceleration limits (i.e. negative the acceleration limit) unless there are specific kinematic constraints to deal with.

Linear acceleration for Stretch 4 can be 0.25 meters per second squared, and angular acceleration can be 2.0 radians per second squared.

## DWB Controller Kinemetic Parameters

We’re going to start by configuring the DWB controller, since it is conceptually relatively simple. Let’s start by looking at the existing parameters, located at \[stretch\_nav2/config/dwb\_params.yaml]. The velocity and acceleration parameters are specified in the following parameters.

The following parameters should be relatively straight-forward.

* `min_vel_x`
* `max_vel_x`
* `min_vel_y`
* `max_vel_y`
* `max_vel_theta`
* `acc_lim_x`
* `decel_lim_x`
* `acc_lim_y`
* `decel_lim_y`
* `acc_lim_theta`
* `decel_lim_theta`

> **Advanced note:** If you consider all of the components indepndently, this means that the Stretch could theoretically move at the maximum speed in both the X and Y directions at the same time. i.e. If both x and y velocities were 0.3 m/s, then the resulting velocity vector would have a magnitude of 0.4243 m/s, which is too fast. To avoid this scenario, there is also the `max_speed_xy` parameter, which should also be set to 0.3 m/s.

> **TODO:** Insert info about min\_speed\_theta and min\_speed\_xy

One other key parameter is the `sim_time` parameter, which is how far into the future (in seconds) to consider for each round of planning.

The DWB algorithm uses the robot’s current velocity (which it obtains from the `/odom` topic) as input, and uses these kinematic parameters to figure out a range of velocity parameters to consider.

For each component (x, y and theta), we determine the minimum and maximum velocity obtainable with the `sim_time` window. If we consider just the x velocities, let’s say we have the following variables:

* `min_vel_x`
* `max_vel_x`
* `acc_lim_x`
* `decel_lim_x`
* `cur_vel_x` (the current x velocity)
* `sim_time`

We calculate the maximum obtainable x velocity as

```
min(max_vel_x, cur_vel_x + acc_lim_x * sim_time)
```

and the minimum obtainable x velocity as

```
max(min_vel_x, cur_vel_x + decel_lim_x * sim_time)
```

This gives us a range of velocities to consider. The DWB planner does a uniform sampling of this velocity space. This is dictated by the three parameters `vx_samples, vy_samples, vtheta_samples`. So if `vx_samples` is set to 10, it will consider 10 different x velocities ranging from the minimum to maximum obtainable velocities (equally spaced).

The more velocities are sampled, the more potentially efficient the planning will be, but with an obvious computation time downside. The total number of velocities considered is the product of the three sampling parameters. So with `vx_samples=10, vy_samples=5, vtheta_samples=10`, that’s 500 total velocities considered each iteration. The number of samples should be increased with caution: adding a single y sample will result in an additional 100 velocities to the optimization.

Now that we know which velocities are available to us, the question then becomes, which one is best? For that, we must explore the trajectory scoring critics.

## Critics

DWB generates a trajectory (series of poses through time) for each of the velocities. Then it uses a series of “critics” to assign scores to each one, and the trajectory with the **lowest** score is then selected as the best, and is used to steer the robot. The scoring often uses other key pieces of information, such as the local costmap, global plan and goal location.

Here is a quick overview of some of the critics provided by default:

* `BaseObstacle` - determines if any of the poses on the trajectory collides with an obstacle (in which case the trajectory is rejected outright), and also provides higher scores for trajectories that go close to obstacles.
* `PathDist` - assigns higher scores to trajectories that are further from the global plan.
* `GoalDist` - assigns lower scores to trajectories that move toward the goal.
* `GoalAlign` - ensures the “front” of the robot is pointed toward the goal.
* `PathAlign` - ensures the “front” of the robot is pointed along the global plan.
* `RotateToGoal` - ensures the robot turns to the goal orientation at the end of the path.
* `Oscillation` - assigns high scores to trajectories that oscillate (based on previously selected velocities).
* `PreferForward` - gives preference to positive x velocities and low theta velocities.

Since Stretch 4 is an omni-directional platform, the `GoalAlign`, `PathAlign` and `PreferForward` are actually not needed to effectively reach goals.

## Different Behaviors

If you wanted to get movement that resembled a diff-drive robot (i.e. without motion in the Y direction), all you need to change is several of the Y component parameters, namely setting `min_vel_y` and `max_vel_y` to `0.0`.

Stretch 4 has sensor coverage in all directions, enabling it to move backwards (i.e. motion in the negative X direction). If you only wanted it to move “forward”, then you would simply need to set `min_vel_x` to `0.0` instead of `-0.26`.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hello-robot.com/stretch4_docs/working-with-stretch/nav_u/local-planning-dwb.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
