# 6.5. Planning for Autonomous Driving.#

Motion primitives provide a computationally efficient tool for fast, local motion planning.

In previous chapters, we have mainly considered two kinds of planning problems. For the trash sorting robot, vacuum cleaning robot, and warehouse robot, we focused on the problem of making the best decisions in the presence of uncertainty. In these problems, we used probability theory to quantify uncertainty, and developed policies to maximize the expected benefit (or to minimize the expected cost) of executing actions in a given state. In contrast, for the differential drive robot (DDR), we considered the purely geometric problem of planning collision-free paths.

A common characteristic of these is that each addresses a global problem. For MDPs, we used value or policy iteration to establish a policy over the entire state space. For DDRs, we searched the entire configuration space for a collision-free path. Furthermore, the methods we developed for both problems were completely general. Our probabilistic approaches work for arbitrary probability distributions, reward functions, and system dynamics. Our geometric approaches to path planning work for arbitrary environments, and can easily be extended to robots with complex dynamics (e.g., we will extend RRTs to the case of drones in the next chapter).

Methods that address global problems in broad generality often require significant computational resources and significant computation time. This can render such methods ineffective for situations in which real-time adaptivity is required over short time horizons, or in local regions of the state space. These conditions are exactly those confronted by self-driving cars, and for this reason, in this chapter we introduce a new approach, one that exploits precomputed motion primitives, for motion planning.

## 6.5.1. Motion Primitives#

To this point, we have considered two approaches for quantifying motions. For all of our probabilistic methods, we used a discrete time formulation and considered the effects of executing an action (e.g., move forward, move left) for a small duration of time, \(\Delta t\). To plan collision-free paths, we considered artificial potential fields and RRTs, both of which use short straight-line paths in the configuration space to connect configurations (small gradient descent steps for potential fields, and steering toward \(q_\mathrm{rand}\) for RRTs). In each case, the language of path segments is very simple, and in each case, a full plan will consist of many sequential steps.

This approach can be very inefficient for planning long trajectories that have well-defined
properties.
For example, consider a car traveling in reverse that wishes to suddenly change it’s orientation
by completing a rapid 180-degree turn (a favorite maneuver for drivers like James Bond and Steve McQueen).
This maneuver can be achieved by a predefined
sequence of steps: after achieving a reasonable speed, remove your foot from the gas pedal;
turn left sharply and hit the breaks; at the perfect moment, release the breaks
and straighten the wheel.
When stunt drivers execute this maneuver, they do not plan step-by-step what to do.
Rather, they have pre-compiled this sequence of steps into a basic action that can be executed
with little reasoning.
This is the basic idea of **motion primitives**.

Motion primitives can be defined in numerous ways. We could specify a geometric curve without consideration of time or dynamics (e.g., for a parallel parking robot, we might define an initial curve to move the car from the street into an empty parking spot). In cases where dynamics are significant (e.g., in drone flight), we might specify a feedback control law to be executed from an initial state until some final state is achieved. We might parameterize these primitives by duration, by geometric properties (e.g., angle, distance), or by state feedback conditions. This idea is illustrated in the figure below, which shows four motion primitives for a car. The primitive \(P_1\) corresponds to driving forward, while motion primitives \(P_2\), \(P_3\), and \(P_4\) correspond to veering to the left at increasingly sharp angles.

## 6.5.2. Planning using Motion Primitives#

The use of motion primitives can greatly reduce the cost of planning, since the set of actions available at any moment in time is small and easily computed. For the car example above, if we assume a symmetric set of motion primitives for veering to the right, motion planning can be reduced to choosing from this set of seven possible actions at each moment in time. If, for example, there is a slow moving car just ahead, it might be advantageous to change lanes using one of \(P_2\), \(P_3\), or \(P_4\). If there is a rapidly approaching oncoming car, it might be best to use \(P_2\), to delay changing lanes until that car has passed by.

More generally, a motion primitive typically includes a set of conditions that define when the primitive is applicable, and a set of possible transitions to other motion primitives. For example, it would be reasonable to veer left slightly and then drive straight, but it would not be reasonable to transition from forward motion to reverse motion without some intermediate maneuvering.

Under these conditions, planning can be effected by a generate-and-test approach. At each moment in time, the planner considers the current situation, enumerates the valid motion primitives (using preconditions for execution and set of valid transitions), and evaluates the benefit of each admissible candidate motion primitive. This approach can be effective for problems such as highway driving, where local context is all that is necessary for making decisions. For example, the traffic outside the Atlanta perimeter is irrelevant when leaving the downtown on a trip to Chicago. In this case, immediate driving decisions depend on the car just ahead, and the nearby cars in adjacent lanes.