In this section we describe a kinematic model and optimization problem that assume that there is no latency when applying activators. In the next section we describe an extension of the model and optimization problem that takes into account the latency.
We used a global kinematic model with 6-dimensional state vector
st = [xt, yt, ψt, vt, ctet, eψt]where
- xt and yt are car coordinates at time t
- ψt is a direction of velocity at time t
- vt is a velocity at time t
- ctet is a cross-track error at time t, defined as the distance between the desired position (x, f(x)) and the actual position (xt, yt) of the car. In our code we approximated ctet by f(xt) - yt. The value of f(x) is obtained by fitting a polynomial to the input waypoints, as described here.
- eψt is an error of the velocity direction at time t, defined as ψt - arctan(f'(xt)).
The state vector st+1 at time t+1 is predicted from the state vector at time t using the following equations:
xt+1 = xt + vt cos(ψt) dt
yt+1 = yt + vt sin(ψt) dt
ψt+1 = ψt - vt δt dt / Lf
vt+1 = vt + at dt
ctet+1 = ctet + vt sin(eψt) dt = f(xt) - yt + vt sin(eψt) dt
eψt+1 = eψt - vt δt dt / Lf = ψt - arctan(f'(xt)) - vt δt dt / Lf
where
- δt and at are change of direction and acceleration applied at time t
- dt is the difference between time t+1 and t
- Lf is the distance between the center of mass of the vehicle and it's front axle. We used Lf=2.67 .
The values of δt and at are found by solving an optimization problem. The objective function of this optimization problem has 4 components:
-
error component, ∑t=0,1,...,N-2 ( Ccte•(ctet)2 + Ceψ•(eψt)2 + Cv•(vt - vtarget)2), that ensures that the car has low cross-track and direction errors and also drives with the velocity that is as close to the desired velocity vtarget as possible. The value of vtarget is a constant positive parameter.
-
actuators component, ∑t=0,1,...,N-2 (Cδ•(δt)2+Ca•(at)2), that ensures that the driving is not wobbly and the velocity is as close to constant as possible.
-
smoothness component, ∑t=0,1,...,N-3 (Cdelta_diff•(δt+1-δt)2+Ca_diff•(at+1-at)2), that ensures that the car drives smoothly and doesn't have abrupt changes of speed and direction.
-
slowdown component, ∑t=0,1,...,N-2 Cslowdown•((ctet•at)2+(eψt•at)2), that reduces acceleration when the car is in dangerous zone and has a large cross-track error and/or large error in the direction of velocity.
In all these components the parameters Ccte, Ceψ, Cv, Cδ, Ca, Cdelta_diff, Ca_diff, Cslowdown have non-negative values. The parameter N is the number of look-ahead steps and is described in detail in the last section.
The final optimization problem is
min δ0,...,δN-2,a0,...,aN-2 ∑t=0,1,...,N-2 ( Ccte•(ctet)2 + Ceψ•(eψt)2 + Cv•(vt - vtarget)2) + ∑t=0,1,...,N-2 (Cδ•(δt)2+Ca•(at)2) +
∑t=0,1,...,N-3 (Cdelta_diff•(δt+1-δt)2+Ca_diff•(at+1-at)2) + ∑t=0,1,...,N-2 Cslowdown•((ctet•at)2+(eψt•at)2)
such that
∀ t=0,...,N-2, -1 ≤ at ≤ 1
∀ t=0,...,N-2, -0.436332 ≤ δt ≤ 0.436332
∀ t=0,...,N-2, xt+1 = xt + vt cos(ψt) dt
∀ t=0,...,N-2, yt+1 = yt + vt sin(ψt) dt
∀ t=0,...,N-2, ψt+1 = ψt - vt δt dt / Lf
∀ t=0,...,N-2, vt+1 = vt + at dt
∀ t=0,...,N-2, ctet+1 = f(xt) - yt + vt sin(eψt) dt
∀ t=0,...,N-2, eψt+1 = ψt - arctan(f'(xt)) - vt δt dt / Lf
Notice that the last six constraints are the global kinematic model described above. These constraints describe a trajectory of the car, from the known state s0 = [x0, y0, ψ0, v0, cte0, eψ0] of the car immediately before solving optimization problem, to the future states s1,...,sN-1.
We use the values of δ0 and a0, found by solving the above optimization problem, to accelerate the car and change its current direction.
In our car there is a latency of 100 milliseconds when we decide to apply the actuators δ0 and a0 to accelerate the car and change its current direction. In this section we describe an extension of the optimization problem to deal with this latency.
To accomodate the latency, we decompose the time interval [t,t+1] into two parts, [t,t'] and [t',t+1]. The time between t and t' is the latency interval. The time between t' and t+1 is the new value of dt. When applying the new actuators δ0 and a0 at time t, the car continues to drive at time [t,t'] with the old values of actuators. The new actuators are only applied at time t'.
Since each time iterval [t,t+1] is split into two parts, we replace N with 2N-1 lookahead steps. The time between each even step and its successive odd step is the latency interval. The new actuators are found at even steps, but applied at the odd steps and last for two time steps. Hence we define dti to be dt when i is odd and latency interval when i is even. The modified optimization problem is
min δ0,...,δN-2,a0,...,aN-2 ∑t=0,1,...,2N-1 ( Ccte•(ctet)2 + Ceψ•(eψt)2 + Cv•(vt - vtarget)2) + ∑t=0,1,...,N-2 (Cδ•(δt)2+Ca•(at)2) +
∑t=0,1,...,N-3 (Cdelta_diff•(δt+1-δt)2+Ca_diff•(at+1-at)2) + ∑t=0,1,...,N-2 Cslowdown•((ctet•at)2+(eψt•at)2)
such that
∀ t=0,...,N-2, -1 ≤ at ≤ 1
∀ t=0,...,N-2, -0.436332 ≤ δt ≤ 0.436332
∀ t=0,...,2N-1, xt+1 = xt + vt cos(ψt) dti
∀ t=0,...,2N-1, yt+1 = yt + vt sin(ψt) dti
∀ t=1,...,2N-1, ψt+1 = ψt - vt δ⌊t/2⌋-1 dti / Lf
∀ t=1,...,2N-1, vt+1 = vt + a⌊t/2⌋-1 dti
∀ t=0,...,2N-1, ctet+1 = f(xt) - yt + vt sin(eψt) dti
∀ t=1,...,2N-1, eψt+1 = ψt - arctan(f'(xt)) - vt δ⌊t/2⌋-1 dti / Lf
Notice that the fifth, sixth and eighth constraints now start from t=1 instead of t=0. That's because, due to the latency, at time t=0 these constraints use the current δcurr and acurr direction and acceleration of the car, that are found when solving optimization problem at previous iteration. Hence the optimization problem has three additional constraints:
ψ1 = ψ0 - v0 δcurr dt / Lf
v1 = v0 + acurr dt
eψ1 = ψ0 - arctan(f'(x0)) - v0 δcurr dt / Lf
Similarly to the optimization problem in the previous section, the state of the car s0 = [x0, y0, ψ0, v0, cte0, eψ0] immediately before solving the optimization problem is known.
After tuning parameters, we set N = 5, dt = 0.11, Ccte = 200, Ceψ = 200, Cv = 5, Cdelta = 100, Ca = 100, Cdelta_diff = 200, Ca_diff = 10, Cslowdown = 500 and vtarget=100. In the last section we discuss further the influence of N and dt on car's driving.
At each iteration we receive from the simulator the car's current state [xcar, ycar, ψcar, vcar] in a global coordinate system. We performed a number of preprocessing steps before solving optimization problem:
-
Coordinate transformation. Since the visualization of waypoints and predicted trajectory is done in car coordinate system, we decided to use this coordinate system in our optimization process. The origin of car coordinate system is at car location, x axis is aligned with the direction of velocity and y axis points to the left. Since simulator sends us waypoints in a global coordinate system, we transformed waypoints to car coordinate system. Let (x,y) be waypoint global coordinates. We denote by (x',y') the same waypoint with coordinates in car's coordinate system. We used the following equations to transform waypoints to car coordinate system:
x' = (x-xcar)•cos(-ψ) - (y-ycar)•sin(-ψ)
y' = (x-xcar)•sin(-ψ) + (y-ycar)•cos(-ψ) -
Polynomial fitting. We fitted a second degree polynomial to waypoints in car's coordinate system. By decreasing polynomial degree from 3 to 2 we reduced processing time at each iteration, while still obtaining a smooth curve that goes through waypoints. We discuss a connection between processing time and the accuracy of car driving in the next section.
-
Initialization of state vector. After fitting polynomial, we initialize car's state vector [x0, y0, ψ0, v0, cte0, eψ0] in its own coordinate system. By the definition of car coordinate system, x0=y0=ψ0=0. The value of v0=vcar remains the same in global and car coordinate systems.
Let f(x) be a polynomial fitted at the previous step. The value of cte0 should be the distance from (0,0) to the closest point of the polynomial. The computation of this distance is not straightforward, will increase the processing time, which in turn will affect car's driving. Instead of computing cross-track error exactly, we approximated cte0 by f(0).
The desired direction at point x=0 is arctan(f'(0)). Since the direction of the car in car coordinate system is 0, eψ0 = 0 - arctan(f'(0)) = -arctan(f'(0)).
In this section we describe our reasoning for choosing the values of N and dt.
The parameter N defines the number of predictions when building car's trajectory and solving optimization problem. The optimization time is proportional to N. A small value of N (e.g. 3,4) would reduce processing time, but will make projected trajectory noisy and less reliable. A large value of N (e.g. 10) will result in an accurate prediction of car trajectory, but will also increase the processing time. We observed emprically that the large processing time causes car to react slowly to sharp turns, which in turn might put the car on ledges or off-track.
The parameter dt defines the length of prediction interval. When dt is small (e.g. less than 0.1) the car drives wobbly. Also when dt is large (e.g. 0.2) the car reacts slowly to sharp turns, which in turn might put the car on ledges or off-track.
Based on these considerations, after several trials we choose N=5 and dt=0.11.