An exercise of modeling and testing the traffic lights at an intersection
Please find in this repo:
- the code of a crude traffic lights controller
- the corresponding unit tests
- a simulator
Code is written in TypeScript 2 / ES7 since it's what I'm using the most right now.
NOTE: Since it changes in every country, let's assume the traffic lights are going in cycles of:
RED -> GREEN -> YELLOW -> ...
Here we want to simulate an intersection of 2 roads, North <-> South and East <-> West. Without further instructions, we'll assume that the lights alternance is this trivial one:
- N&S proceeding, E&W stopped
- E&W proceeding, N&S stopped
It's obvious that we don't want to model the lights separately, because:
- the N/S lights are paired to the same state, same for E/W
- the state of N/S and E/W are also linked, when one is green or yellow, the other MUST be red, and so on.
So we'd rather model the intersection itself as having 2 traffic flows:
- N <-> S
- E <-> W
proceeding and stopping alternatively.
Code is written in TypeScript 2 / ES7 and exposed as JavaScript ES7 / CommonJS
npm i -S Offirmo/traffic-lights-simulator << XXX I didn't publish it to npm to not waste their resourcesimport * as TrafficLightsController from 'traffic-lights-simulator'
const controller = TrafficLightsController.factory({
onStateChange: console.log
})The controller immediately starts running indefinitely on invocation, starting with N<->S green.
It can be stopped with controller.stop()
To retrieve how the lights should be displayed for a flow according to a state:
TrafficLightsController.getTrafficLightStateForFlow(controller.getState(), 'NS') // -> red, yellow, green
TrafficLightsController.getTrafficLightStateForFlow(controller.getState(), 'EW') // -> red, yellow, green
// or use this shortcut
controller.getTrafficLightStateForFlow('NS') // -> red, yellow, green
controller.getTrafficLightStateForFlow('EW') // -> red, yellow, greenBut this is more convenient to do it on transitions, hence the onStateChange callback:
import * as TrafficLightsController from 'traffic-lights-simulator'
const controller = TrafficLightsController.factory({
onStateChange: (state) => {
changeNSLightTo(TrafficLightsController.getTrafficLightStateForFlow(controller.getState(), 'NS'))
...
}
})The factory takes a bunch of options:
const controller = TrafficLightsController.factory({
// here are the default values
SWITCH_PERIOD_S: 5 * 60, // lights alternance period, in s
SWITCH_NOTIFICATION_DURATION_S: 30, // how much time before a change do we switch to yellow
debug: false, // prints traces on state change
onStateChange: (state) => {} // called on state change
})From the cloned repository, using node 7:
npm install
npm run simulate // defaulting to simulating 1800s = 30min
npm run simulate 500Should give something like that:
From the cloned repository, using node 7:
npm install (do NOT use yarn, sorry)
npm run dev
npm testShould give something like that:
Extension of the model:
- for safety reasons we should have an initial state and an error state
- How about having different timings for each "flows" ? For example, N/S could be a bigger road than E/W, thus being allowed more time in "pass" state
- how about more flows than just 2, maybe flows than can be allowed in parallel
- How about linking to the state the pedestrian lights also ?
- this is trivial with our model

