/CppND-Program-a-Concurrent-Traffic-Simulation

The final project for the Udacity C++ Nanodegree Concurrency course

Primary LanguageC++OtherNOASSERTION

CPPND: Program a Concurrent Traffic Simulation

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.

Dependencies for Running Locally

Basic Build Instructions

  1. Clone this repo.
  2. Make a build directory in the top level directory: mkdir build && cd build
  3. Compile: cmake .. && make
  4. Run it: ./traffic_simulation.

Project Tasks

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 TrafficLight which is a child class of TrafficObject. The class shall have the public methods void waitForGreen() and void simulate() as well as TrafficLightPhase getCurrentPhase(), where TrafficLightPhase is an enum that can be either red or green. Also, add the private method void cycleThroughPhases(). Furthermore, there shall be the private member _currentPhase which can take red or green as 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 method cycleThroughPhases should be started in a thread when the public method simulate is called. To do this, use the thread queue in the base class.
  • Task FP.3 : Define a class MessageQueue which 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 an std::dequeue called _queue, which stores objects of type TrafficLightPhase. Finally, there should be an std::condition_variable as well as an std::mutex as private members.
  • Task FP.4 : Implement the method Send, which should use the mechanisms std::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 class TrafficLight, create a private member of type MessageQueue for messages of type TrafficLightPhase and use it within the infinite loop to push each new TrafficLightPhase into 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 method waitForGreen, in which an infinite while-loop runs and repeatedly calls the receive function on the message queue. Once it receives TrafficLightPhase::green, the method returns.
  • Task FP.6 : In class Intersection, add a private member _trafficLight of type TrafficLight. In method Intersection::simulate(), start the simulation of _trafficLight. Then, in method Intersection::addVehicleToQueue, use the methods TrafficLight::getCurrentPhase and TrafficLight::waitForGreen to block the execution until the traffic light turns green.