Chapter 3: The Vehicle Model
The kinematic bicycle model explained, with its equations, derivation, discretization and Python code. To simulate a vehicle, we need equations that say how its position and heading change when it accelerates and steers. This chapter derives the kinematic bicycle model, the motion model that every later chapter uses: the path tracking controllers as geometry, the localization filters with noise, the planners as a constraint, and the optimal controllers in a linearized form. It then turns the model into the discrete-time update that the simulator runs, and shows where the model stops being valid.

3.1 The kinematic bicycle model
Assumptions. The model describes a car with front-wheel steering under four assumptions:
The vehicle moves on a plane, as a rigid body.
The two wheels of each axle are merged into one wheel at the center of the axle, which gives a “bicycle” with a rear and a front wheel.
The wheels don’t slip sideways: each wheel moves in the direction it points.
The speed is controlled directly through the acceleration, without modeling the engine or the brakes.
Geometry. Let the wheelbase \(L\) be the distance between the axles, \(\delta\) the steering angle of the front wheel, and \((x, y, \theta)\) the position of the rear axle center and the yaw angle (Chapter 2). Because neither wheel slips, the rear wheel moves along the body and the front wheel along its own direction, rotated by \(\delta\). The lines perpendicular to the two wheels meet at one point, the instantaneous center of rotation, and the whole vehicle turns around it.
The kinematic bicycle model. The lines perpendicular to the wheels meet at the center of rotation, and the rear axle moves on a circle of radius \(R = L / \tan\delta\).
The rear axle, the front axle and the center of rotation form a right triangle with the right angle at the rear axle, so the turning radius of the rear axle is
The rear axle moves with speed \(v\) along this circle, so the yaw angle changes at the rate \(\dot\theta = v / R\). With the speed changed by the acceleration \(a\), the model is
The position moves along the heading, the heading turns faster when the vehicle is faster or the steering angle larger, and a straight wheel (\(\delta = 0\)) gives \(R = \infty\): the vehicle goes straight.
The model is written for the rear axle on purpose: the rear wheel doesn’t steer, so its velocity is always along the body, and the equations stay this simple. The front axle, used by the Stanley controller, is \(L\) ahead along the heading.
3.2 Steering angle or yaw rate
The simulator of this project doesn’t take the steering angle as its input. It takes the yaw rate \(\omega = \dot\theta\) directly, with the input vector \(\mathbf{u} = [a, \omega]^\top\). The two are related by (2):
so the model the simulator runs is (2) with \(\dot\theta = \omega\). Controllers compute a steering angle, because that is what a driver or an actuator sets, and convert it with (3) before giving it to the vehicle (see equation (4) of the Stanley section).
Both forms describe the same motion while the vehicle moves. They differ at \(v = 0\): a stopped vehicle can’t turn whatever the steering angle, which (3) gives as \(\omega = 0\). The input of the simulator will be unified with the code roadmap (#108).
3.3 From continuous to discrete time
The equations (2) are in continuous time, but the simulator moves in steps of \(\Delta t\) (Chapter 2). The simplest way to turn them into a step is the Euler method: assume that the right-hand side stays constant during the step, \(\mathbf{x}_{t+1} = \mathbf{x}_t + f(\mathbf{x}_t, \mathbf{u}_t)\,\Delta t\).
The simulator uses a slightly better version: during one step it keeps the heading \(\theta_t\) and the acceleration \(a_t\) constant, and integrates the speed exactly, so the distance traveled is \(v_t \Delta t + \frac{1}{2} a_t \Delta t^2\):
Written with the state \(\mathbf{x}_t = [x_t, y_t, \theta_t, v_t]^\top\), this is \(\mathbf{x}_{t+1} = A(\theta_t)\,\mathbf{x}_t + B(\theta_t)\,\mathbf{u}_t\) with
This is the form the code uses (State.motion_model() in src/components/state/state.py). The matrices depend on \(\theta_t\), so the model is still nonlinear; the localization filters of Chapter 6 linearize it.
The time step matters. Within a step, the vehicle moves on a straight segment along \(\theta_t\), while in reality it turns during the whole step. The error is small when the heading changes little in one step, that is when \(\omega\,\Delta t\) is small:
One full turn at \(v = 5\) m/s and \(\omega = 0.5\) rad/s (\(R = 10\) m), computed with (4). With \(\Delta t = 0.1\) s (\(\omega\Delta t = 0.05\) rad) the vehicle ends 0.17 m from where it started; with \(\Delta t = 1.0\) s (\(\omega\Delta t = 0.5\) rad) it ends 2.2 m away.
The default \(\Delta t = 0.1\) s keeps \(\omega\,\Delta t\) small for the speeds and curves of the simulations in this book.
3.4 Where the model holds
No slip means moderate speeds. In a real car the tires slip sideways, more as the lateral acceleration \(v^2 / R\) grows. The kinematic model is good at low speeds and gentle curves, and gets worse in fast, tight turns. Chapter 14 adds the tire slip with a dynamic model and compares the two.
No limits in the model. The equations allow any steering angle and any acceleration. A real vehicle has a maximum steering angle (so a minimum turning radius) and limited acceleration. The simulator clamps the speed between \(-10\) km/h and \(60\) km/h, and stops the vehicle below \(0.5\) km/h; the steering limit is left to the controllers.
Reverse driving. The equations also hold for \(v < 0\), driving backward. The simulator allows speeds down to \(-10\) km/h.
How later chapters use this model
Chapter |
How the model is used |
|---|---|
As geometry: (1) and (3) relate the curve to drive to the steering angle |
|
As the prediction step, (4) with noise on the input, and its Jacobians |
|
As a constraint: Hybrid A* only expands motions the vehicle can drive |
|
Linearized around the course, and as the constraint of MPC |
|
Replaced by a dynamic model with tire slip |
The vehicle’s code (its state, the drawing of its body and tires, and the specification of its size) will change with the code roadmap (#108, #121). Its walkthrough is added to this chapter after those changes. Until then, the examples visualize_vehicle.py and visualize_vehicle_zoom.py in this folder show how a vehicle is put in the world.
References
R. Rajamani, “Vehicle Dynamics and Control”, 2nd ed., Springer, 2012. Chapter 2, kinematic model of lateral vehicle motion.
J. M. Snider, “Automatic Steering Methods for Autonomous Automobile Path Tracking”, Technical Report CMU-RI-TR-09-08, Carnegie Mellon University, 2009. PDF