This is the project for the fourth course in the Udacity C++ Nanodegree Program: Concurrency.
Throughout the Concurrency course, you have been developing a traffic simulation in which vehicles are moving along streets and are crossing intersections. However, with increasing traffic in the city, traffic lights are needed for road safety. Each intersection will therefore be equipped with a traffic light. In this project, you will build a suitable and thread-safe communication protocol between vehicles and intersections to complete the simulation. Use your knowledge of concurrent programming (such as mutexes, locks and message queues) to implement the traffic lights and integrate them properly in the code base.
- cmake >= 2.8
- All OSes: click here for installation instructions
- make >= 4.1 (Linux, Mac), 3.81 (Windows)
- Linux: make is installed by default on most Linux distros
- Mac: install Xcode command line tools to get make
- Windows: Click here for installation instructions
- OpenCV >= 4.1
- The OpenCV 4.1.0 source code can be found here
- gcc/g++ >= 5.4
- Linux: gcc / g++ is installed by default on most Linux distros
- Mac: same deal as make - install Xcode command line tools
- Windows: recommend using MinGW
- Clone this repo.
- Make a build directory in the top level directory:
mkdir build && cd build - Compile:
cmake .. && make - Run it:
./traffic_simulation.
When the project is built initially, all traffic lights will be green. When you are finished with the project, your traffic simulation should run with red lights controlling traffic, just as in the .gif file above. See the classroom instruction and code comments for more details on each of these parts.
- Task FP.1 : Define a class
TrafficLightwhich is a child class ofTrafficObject. The class shall have the public methodsvoid waitForGreen()andvoid simulate()as well asTrafficLightPhase getCurrentPhase(), whereTrafficLightPhaseis an enum that can be eitherredorgreen. Also, add the private methodvoid cycleThroughPhases(). Furthermore, there shall be the private member_currentPhasewhich can takeredorgreenas its value. - Task FP.2 : Implement the function with an infinite loop that measures the time between two loop cycles and toggles the current phase of the traffic light between red and green and sends an update method to the message queue using move semantics. The cycle duration should be a random value between 4 and 6 seconds. Also, the while-loop should use
std::this_thread::sleep_for to wait 1ms between two cycles. Finally, the private methodcycleThroughPhasesshould be started in a thread when the public methodsimulateis called. To do this, use the thread queue in the base class. - Task FP.3 : Define a class
MessageQueuewhich has the public methods send and receive. Send should take an rvalue reference of type TrafficLightPhase whereas receive should return this type. Also, the class should define anstd::dequeuecalled_queue, which stores objects of typeTrafficLightPhase. Finally, there should be anstd::condition_variableas well as anstd::mutexas private members. - Task FP.4 : Implement the method
Send, which should use the mechanismsstd::lock_guard<std::mutex>as well as_condition.notify_one()to add a new message to the queue and afterwards send a notification. Also, in classTrafficLight, create a private member of typeMessageQueuefor messages of typeTrafficLightPhaseand use it within the infinite loop to push each newTrafficLightPhaseinto it by calling send in conjunction with move semantics. - Task FP.5 : The method receive should use
std::unique_lock<std::mutex>and_condition.wait()to wait for and receive new messages and pull them from the queue using move semantics. The received object should then be returned by the receive function. Then, add the implementation of the methodwaitForGreen, in which an infinite while-loop runs and repeatedly calls thereceivefunction on the message queue. Once it receivesTrafficLightPhase::green, the method returns. - Task FP.6 : In class Intersection, add a private member
_trafficLightof typeTrafficLight. In methodIntersection::simulate(), start the simulation of_trafficLight. Then, in methodIntersection::addVehicleToQueue, use the methodsTrafficLight::getCurrentPhaseandTrafficLight::waitForGreento block the execution until the traffic light turns green.
