Self-Driving Car Engineer Nanodegree Program
You can download the Term3 Simulator which contains the Path Planning Project from the releases tab.
Please refer to the project.md for details.
-
The implementation is within the single file for the minimum change from project template and organization. I found it acceptable because the code is still relatively short.
-
The main components and their relations are implemented as the following several classes
SelfDrivingCar
: the state of SDC, including speed, position and etc.PeerCar
: the state of other cars on the same side of road (peer cars).Map
: it encapusulates the waypoint information into smooth trajectories, which are mappings from coordinates from car's view (a.k.a Frenet coordinates) to map view (x, y). The trajectory mapping is implemented by using the third-partyspline
library.Path
: an encapsulation of a set of steps in (x, y) map coordinates. This is the main protocol that the planner uses to communicate with the controller.PathPlanner
: the main class for path planning.
-
The main methods implemented in
PathPlanner
class are,plan()
: it is the main access point of the planner. It uses the self-driving-car and other cars information, combined with previous planned path (for smoothness), to plan for the next path. In general it estimates how the car should behave at the next step, by considering a strategy for different implemented behaviors. Currently the strategy is implemented as a set of rules. It might be implemented by other search algorithms e.g.a-star
for more complicated cases.keep_lane()
: it implements the car's staying in the current lane behaviorchange_lane()
: the other behavior of the car currently implemented.accelerate()
: it controls car's speed following the acceleration and jerk requirements.
The project compiles and builds as follows,
- Make a build directory:
mkdir build && cd build
- Compile:
cmake .. && make
- Run it:
./path_planning
.
This breaks down to the following items in details.
In the implementation, the car is setting its target speed dynamically according to its environment, e.g.,
- The maximum speed of the car is set as a parameter of
PathPlanner
, which is20 m/s
~44.7 MPH
. - The car dynamically adjusts its target speed based on the car ahead, e.g., when the car is keeping on its current lane, or changing to another lane.
This is implemented in the accelerate method of planner.
In general it considers the difference between current and target and calculates the acceleration by considering the constraints.
Collisions are avoided by,
- Being safe about the speed and distance estimates, e.g., assuming the car in front could brake suddenly.
- Giving enough time for lane changing, e.g., always checking if a lane-changing is safe before doing it.
This is done by building a smooth trajectory mapping using the waypoints. I am currently implementing this as a global trajectory for the whole map. But in practice it might make more sense to build local trajectory around the car for more complicated cases.
The lane-chaning is implememted in two parts,
- In the
plan()
method, a set of rules is implemented to decide whether a lane-changing is feasible when necessary. - The actual path generating is done in the
change_lane()
method, which is one of the car's preset behaviors.
- As discussed above, the actual path generating is delegated to the different "behavior" methods of the planner, including
keep_lane
andchange_lane
. - For
keep_lane
, two scenarios are considered,- when the lane is clear, the car will set its target speed as maximum and come up with a smooth trajectory both spatially and temporally.
- when there is a car ahead, the car will set its safe distance from the car ahead and set its target speed accordingly. If the speed on this lane is too slow, the car will try to plan to change to another lane by evaluating their feasibility and advantage over current lane.
- For
change_lane
,- the car will first evaluate whether it is safe to change to the target lane. If not, it wills stay on the same lane.
- otherwise, the car will plan a smooth local trajectory by combining half from the source lane and the other half from the target lane.
- at the meantime, since changing lane may take longer than one plan cycle to finish, the planner will monitor the lane changing state to avoid interruption.
- Since the car's Frenet coordinates will be reset at the end of loop, I had some difficulties with modelling the end part of the loop. I fixed it by looping the map again. This solves the issue for the current simulation, but a better solution might be just using a local trajectory model along with the travelling.
- The current lane_changing is implemented by planning a longer path (6 times longer in fact). And during the lane changing there won't be any further planning until it is finished. Safety is considered by employing strict rules on whether it is safe to change beforehand. However, this does make the lane-changing plan more conservative in my implementation. A better way might be continuing planning even during the lane-changing, e.g., possibility of going back to the previous lane in case of emergency.