Open-source project
movsim/traffic-simulation-de avatar
movsim/traffic-simulation-de

traffic-simulation.de: a traffic microsimulation in a browser tab

Source code for javascript simulation of website

1,057 stars156 forksJavaScriptGPL-3.0

At a glance

What is it?
This repository is the source of the interactive JavaScript simulation behind traffic-simulation.de, a road traffic microsimulation that runs on an HTML5 canvas with the IDM and ACC car following models and the MOBIL lane changing model. What makes it interesting to read is the structure: pseudo objects in plainly named files, a set of documented conventions for coordinates and vehicle identifiers, and a written recipe for adding a new behavioural model.
Who is it for?
Adopt this repository if you teach traffic flow, if you want a simulation you can send to a student as a downloaded folder, or if you want vehicle trajectory and virtual detector data generated by a model you can read and change. Do not adopt it as the basis for a large scale traffic assignment, because the whole thing runs in a browser tab on one machine, and do not treat the exported files as a calibrated dataset without checking the model parameters.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 32 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A road network that runs in a browser tab

The repository is described in one line as the source code for the interactive Javascript simulation at traffic-simulation.de, and the licence is GPL-3.0.

The design intent is in the README's first paragraph. The simulations should be self-explaining, and each scenario also has instruction boxes. That is a teaching constraint as much as a usability one, because a simulation that has to be explained in prose is a simulation that a student will not engage with on their own.

The scenarios are the familiar ones. The repository root holds onramp.html, offramp.html, onrampBare.html, intersection.html, coffeemeterGame.html and index.html, and the README files named after the features give the list: a gridlock scenario, a routing game, a magic roundabout, traffic light control, a 3D transform, intersections with variable networks, the coffee meter game, and separate treatments of opposite traffic and of speed limits.

There is a second capability that is easy to miss in the README. Besides simulating online, you can use the simulator to generate vehicle trajectory files and virtual detector data files, using the blue download button. So the tool is two things: a teaching toy and a data generator for microscopic traffic analysis.

That second role is what makes a repository like this interesting to a traffic engineer, because a trajectory file is the input format that a range of offline analysis tools consume, and the README documents it in files named README_trajData4ExternalUse and README_exportDataFromJs.

The project is not archived, the last push was on 2026-09-21, and there are no GitHub releases, so the deployed site is the artefact of record.

The canvas, init() and a setInterval at 1000/fps

The implementation detail in the README is short and complete, and it explains why the project is approachable for someone who has written browser code but not simulation code.

This simulation uses JavaScript together with html5. The master html file, for example onramp.html, starts the actual simulation by the canvas tag:

html
<canvas id="canvas_onramp" ... >some text for old browsers </canvas>

What to do with that canvas is specified in the init() procedure of onramp.js, which starts the simulation and is associated with the canvas by the first command of the init procedure:

javascript
canvas = document.getElementById("canvas_onramp");

And at the end of the initialization, init() starts the actual simulation thread by the command:

javascript
return setInterval(main_loop, 1000/fps);

So the loop is a plain setInterval at the frame rate, the drawing is a canvas, and there is no framework, no bundler and no build step in the story. The canvas dimensions are set and reset depending on the actual browser's viewport size by additional controls in canvasresize.js, which implements the responsive design, so the same file works on a phone and on a large screen.

Two practical notes come with that design. The first is a caching warning: if the simulation does not run, sometimes the cause is old code in cached javascript or css files, so the first thing to do is empty the cache. The second is the offline path, which the README describes in detail. You download the whole project with the Download ZIP option from the green Code button, unpack it, and load, for example, index.html as a local file in your browser. No server, no dependencies, no build.

That last point is the most underrated feature in the repository. A simulation that runs from a file:// URL can be emailed, put on a USB stick, or opened in a lecture room with no network, and that is worth more to a teacher than any feature in the feature list.

Pseudo objects in plainly named files

The README says the JavaScript code uses pseudo objects in appropriately named files, and the file names are the documentation.

The scenario file, <scenario>.js, of which ring.js and onramp.js are examples, holds the top-level simulation code for the corresponding scenario. It initializes the road network elements needed for that scenario, for example mainroad and onramp for the onramp scenario, starts and stops the simulation, controls the simulation updates in each time step depending on the scenario, draws everything, and implements the user controls defined in ring_gui.js, onramp_gui.js and the equivalents.

The gui file, <scenario_gui>.js, defines the user controls. Each scenario such as ring, onramp or roadworks has both a top-level simulation file and an associated gui file, and of course an html file.

road.js represents a directional logical road link as an array element of the network variable defined in the top-level scenario files, and organizes the vehicles on it. It contains an array of vehicles and methods to get the neighboring vehicles for a given vehicle, to update all vehicles for one time step, and to interact with and get information from neighboring road network elements. It also has a unique roadID, and provides methods to draw this network element and the vehicles on it.

vehicle.js holds each vehicle, which represents a vehicle-driver unit. It has properties such as length, width and type, dynamic variables such as position and speed, and a deep copied instance of the acceleration and lane changing methods from models.js. Optionally a vehicle has a route as a sequence of roadIDs to be traversed, which is only needed in scenarios with off-ramps or intersections.

models.js is the collection of pseudo-classes for the longitudinal models, presently the IDM and an extension from it, the ACC model, and the lane-changing decision models, presently MOBIL.

The deep copy in vehicle.js is worth a second look, because it is the mechanism that lets one model serve many vehicles with different parameters: each vehicle carries its own copy of the model methods, and a driverfactor set at construction time scales that vehicle's behaviour relative to the others.

u along the road, v across it

The coordinate convention is stated in the README and it is the kind of detail that makes a simulation code base readable or unreadable.

The longitudinal, or arclength, coordinate u runs from u=0 to u=roadLen. The lateral coordinate v increases to the right with v=0 at the road axis, and the lane numbering also starts from the left.

The important part is what that buys. The drawing methods of a road depend on the road geometry functions traj_x and traj_y, which give the geo-located positions, that is the x and y coordinates, as a function of the arclength u. Those functions are provided by the calling pseudoclasses in the scenario file at construction time.

So the simulation works in a road coordinate system, where a position is a distance along the road and an offset from the axis, and the mapping to screen or map coordinates is supplied by the scenario. A straight road is a line, a curved ramp is an arc, and the vehicle code never has to know which it is on.

That is the right way to build a road network simulation, because the same vehicle model has to work on a ring road, on a merge and on a junction, and because the alternative, doing the geometry in the vehicle code, would put road shape knowledge in the model of a driver.

The README also points to the sections of the simulator page for information on the models and the numerical integration schemes, and says that information can be found in the links on that page. That is the one part of the model documentation that lives outside the repository, so it is worth reading before drawing conclusions from the code.

Vehicle identifiers as a control channel

vehicle.js does something that is unusual and very useful for an interactive simulation: it reserves a range of identifiers for special roles, so that the user interface and the model code can address individual vehicles by their id.

The identifiers are laid out in bands. veh.id = 1 is the ego vehicle, described as being for future ego-game versions. veh.id = 10 to 49 are vehicles that are clicked, and disturbed. veh.id = 50 to 99 are user-moveable obstacles with desired speed zero and no stochasticity, so they behave deterministically when a user drags them into the way. veh.id = 100 to 149 are obstacles representing red traffic lights. And veh.id of 200 and above are normal vehicles and fixed obstacles.

Read as a design, this is a clean separation of concerns achieved with an integer. The bands mean that a scenario does not need a separate concept of an obstacle or a traffic light, it needs to know the id range, and the model code can implement behaviour for the ranges rather than for object types. A red light is an obstacle with a desired speed of zero that happens to sit at an intersection.

The ego vehicle band being reserved for future ego-game versions is a hint about where the project is heading, and it also explains the driverfactor mechanism, which models inter-driver variation. Each vehicle is given a driverfactor with a uniform distribution around 1, and both the desired speed and the desired acceleration are multiplied by it. There is a detail in the README that shows real care: because model parameters are often changed due to user interaction, speed limits and bottlenecks, the driverfactor is taken from the vehicle's driverfactor after each model change, so that a speed limit change does not reset the driver's personality.

The noise model is described with the same precision. White acceleration noise of intensity QnoiseAccel is uncorrelated between vehicles, which leads to a random walk in speed with an average speed difference of the square root of QnoiseAccel times dt. And because the longitudinal model is also used for lane changes and for decisions at intersections, a deterministic version of the acceleration is provided as well.

The four step recipe for a new behavioural model

The README includes a section on how to implement new models, and it is the part that tells you how serious the project is about extensibility.

The steps are: define the constructor and implement all the methods that are also present in the old models, for example ACC, in models.js. Set the model templates to the new model, and if needed also introduce new gui sliders in control_gui.js and the.html files. Then redefine the slider interactions and the model update in control_gui.js and road.js.

That is a complete and reasonably short procedure, and the reason it is short is that the architecture separates the model from everything else. The model is a pseudo-class in models.js with a known method set, the templates say which model a given vehicle type uses, the gui file exposes parameters, and road.js calls the model once per time step. Adding a car following rule touches the model file plus the template and gui hooks the README lists.

The README also documents the development aid that goes with this. The global flag testNewModel in control_gui.js, when set to true, uses a new skeleton CACC model which is essentially the IDM, and to check that this really works the desired speed for the truck template is set to 3 m/s, so you will see slow trucks if it works.

The speedlimit feature follows the same pattern. Speedlimits override all user-set desired speeds and also the driverfactor, but not the acceleration noise, which is a sensible split, since a speed limit is a constraint on intent and not on the random component of the behaviour.

Editorial conclusion

Adopt this repository if you teach traffic flow, if you want a simulation you can send to a student as a downloaded folder, or if you want vehicle trajectory and virtual detector data generated by a model you can read and change. Do not adopt it as the basis for a large scale traffic assignment, because the whole thing runs in a browser tab on one machine, and do not treat the exported files as a calibrated dataset without checking the model parameters. Verify first that the model you are studying is the one you think it is, since the README describes IDM, an ACC extension and MOBIL rather than a single model, and check the reference links on the simulator page for the numerical integration scheme used.

Frequently asked questions

How do I run the traffic-simulation.de scenarios locally?

Download the whole project with the Download ZIP option from the green Code button, unpack it, and load, for example, index.html as a local file in your browser. The simulation uses JavaScript with html5, so no server or build step is involved. If the simulation does not run, the README suggests emptying the cache first, since old cached javascript or css files are a common cause.

Which car following and lane changing models does the simulation implement?

models.js holds pseudo-classes for the longitudinal models, presently the IDM and an extension from it called ACC, and for the lane-changing decision models, presently MOBIL. It also adds white acceleration noise, inter-driver variation through a driverfactor, and speed limits that override desired speeds.

What can I export from the simulator?

Besides simulating online, the simulator can generate vehicle trajectory files and virtual detector data files, using the blue download button. The repository documents this in files named README_trajData4ExternalUse and README_exportDataFromJs.

How do I add a new behavioural model?

The README describes the steps: define the constructor and implement the same methods as the old models in models.js, set the model templates to the new model and add gui sliders in control_gui.js and the html files, then redefine the slider interactions and the model update in control_gui.js and road.js. A global flag testNewModel in control_gui.js exercises a skeleton model.

Official sources

  1. Issues
  2. License: GPL-3.0
  3. movsim/traffic-simulation-de on GitHub
  4. Project website
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/movsim-traffic-simulation-de.svg)](https://hysenlabs.com/projects/movsim-traffic-simulation-de)

Was this useful?