Skip to content

winkula/jts

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Java Traffic Simulator (jts)

Java Traffic Simulator (jts) is an agent based micro simulation on real transport networks. Designt for easy use. The project is relaized as part of the module: Project 1 at Bern University of Applied Sciences.

This project is currently under heavy developement.

Features

  • Easy but highly configurable with java properties
  • Simulation of elements:
    • Agents; moving parts of the simulation
    • Lanes; where agents are moving on
    • Edge; bundling lanes together.
    • Junctions; connecting edges
    • Networks; holding elements
  • Import of open street map data
  • Layered/parallelized simulation
  • Independent simulation and drawing
  • Simulation interpolation for smooth drawing
  • GPS implementation with dijekstra

Table of contents

Table of Contents generated with DocToc

System context

system context

Code highlights

  • Simulatable.java: Simulation engine which is easily extensible with new elements.
  • Command.java: Integrated console engine with commands that are easy extensible.
    • Command autodiscovery with reflection
  • Thinkable.java: Easy interface for smart new agents.
  • Importer.java: Import road map data from OpenStreetMap.
  • Window.java: Graphical user interface with 2D output.
    • Allows scrolling and zooming
    • Allows console input & selection of elements by clicking

Ideas & Thoughts

Main Application logic

  • main()
  • Loads configuration
  • Simulates with thinking
  • Keeps map of saved simulation states
// load configuration
initialization();
// load net from xml files
loadNet();
// load agent routes & traffic flows
loadRoutes();
// app run
showWindow();
loop {
    // remove agents which reached their target
    checkRemoveAgents();
    // spawn new agents according to routs & flows
    spawnAgents();
    // simulate all the layers
    foreach( layer : layers ){
        foreach in parallel( simulatable : layer ){
            simulatable.simulate()
        }
    }
    // give the thinkables some time to make decisions
    foreach( thinkable : elements) {
        thinkable.think();
    }
    // add simulation state to the list of saved states
    addSimulationState( deepCopy( this ) );
}
end();

Data model

Maybe the biggest decision in the beginning of our project was how to model the road network. The first input cam from our supervisor and was the approach of using a skip list to model a lane. The index should represent the position in meters on the lane.

We decided to model not only straight roads with multiple lanes but also junctions to realize more complex road networks. We oriented us on the road network data format of the SUMO simulator. Therefore our basic domain objects were net, edge, junction, lane and agent.

Parallelization

Jts is structured in layers. The class which keeps track of them is Layers.java. Its usage is shown below.

layers class

  • Net stores two different layering objects
    • renderables : used for rendering
    • simulatables : used for simulation
  • Net adds elements based on their implementing interfaces (Renderable, Simulatable) to the layers.
  • RenderPanel gets the layering object from Net (instance: wall clock) by calling getRenderables().
  • Simulation gets the layering object from Net (instance: simulation time) by calling getSimulatables().
  • RenderPanel and Simulation delegate execution to all the elements in layering order. See code taken from Simulation.simulate() as example below.
    • SortedSet in Layers ensures total order according to natural order (for Integer '<') of layerKeys.
    • .parallel().foreach() runs lambda-function in parallel, see Multithreading.
    // delegate simulation to @{link Simulatable}s
    final Layers<Simulatable> simulatables = simulateNet.getSimulatable();
    for (final int layer : simulatables.getLayersIterator()) {
        simulatables.getLayerStream(layer).parallel().forEach(e -> {
            e.simulate(duration);
        });
    }

The parallelization paradigm is: Every simulatabe (s) with layer (l) is only allowed to change element states of simulatables (s2) if s2.l < s.l or s2 == s. This allows parallel simulation of all the simulatables in one layer. Due to the simple fact that there is no way java to enforce the paradigm we had to be very careful when writing new code.

Simulatables

All known simulation layers and residing classes.

layer 0
  • Agent
    1. apply agent decision
    2. update agent pysics
layer 1
  • Lane
    1. update position of agents in lane datastructure
    2. do collisions of agent on lane
layer 2
  • Edge
    1. switch agents between lanes on this edge
layer 3
  • Junction
    1. select agent for despawning
    2. reroute agents between edges
layer 4
  • Net
    1. agent spawning
    2. agent despawning

Renderables

All knownt rendering layers and residig classes.

layer 0
layer 1
layer 2

Multithreading

In jts we heavily use the with java 8 newly introduces streams. The parallel() method in conjunction with lambda function are particularly useful for multithreading. The jre regulates instantiation of worker threads automagically and does quite a good job in scheduling work for all the workers as they are all more or less under the same load.

load distribugion

  • green: running
  • orange: park

Dijekstra for path finding

GPS implements a working dijekstra algorithm for Net. The interfaces DirectedGraphVertex and DirectedGraphEdge make the dijekstra impelemntation independent from the data classes.

dijekstra

Wall clock & simulation time

The actual simulation of the Net advances in discrete quantities of time. Meanwhile the Window advances according to the time the user experiences in real life. Those two components are decoupled with the getWallClockSimulationState() method in Simulation

times

Agent intelligence

We tried to implement an artificial intelligence that could master to drive on a arbitrary road network without causing a lot of collisions.

The agent has to make three kinds of decisions:

  1. How much to accelerate/deccelerate?
  2. Switch lane? When yes: left or right?
  3. Which turning to take on a junction?

For the acceleration we calculated a security distance, so that no collision would happen, if the agent ahead would fully break. This would work perfectly, if there are no lane changes and no junctions. But this two circumstances made things complicated. We didn't solve this problem through the lack of time.

The idea behind the lane switching decision was the following: An agent tries to drive on the rightest lane of a track whenever this is possible. If he has to slow down, because the agent ahead is too slow, his impatience increases. If the impatience reaches a specified threshold, the agent tries to switch lane to the left to overtake the slow agent ahead. One consequence of this behavior was, that the agents switched to the motorway access road in the ramp scenario. This problem could be solved if we would type the lanes (default, fast lane, motorway access road and so on).

For the turning decision we decided to provide the agent a "GPS" function. The route was then given by the spawning point and the destination. Both informations were given by the routes file. The GPS function was realized with an implementation of the Dijkstra algorithm.

Journal

Calendar week 39

Enteee, winki

  • Write requirements doc

Calendar week 40

Enteee

  • Basic simulator setup

winki

  • Projekt setup
  • Basic data structure
  • Implement xml importer

Calendar week 41

Enteee

  • Simulation (Decision objects, think, simulate)
    • call every think method of all Intelligents (parallel)
    • fill a collection
    • loop through decisions -> simulate every decision (serial), without lane switching

winki

  • Spawn agents
  • Dummy AI
  • Move agents

Calendar week 42

Enteee

  • Zooming
  • Collisions
  • Lane switching

winki

  • Render agents on polygons
  • Orientation of agents visible

Calendar week 43

Enteee

  • GPS-helper

winki

  • Import of route-files
  • Spawning of agents based on activities

Calendar week 44

Enteee

  • Commands to element redirection

winki

  • Embedded console, thread-safe
  • Spawn and time commands for console

Calendar week 45

Enteee

  • GPS unit tests
  • Smarter agent, empty

winki

Calendar week 46

Enteee

  • Draw simulation decoupling
  • Bugfix lane set agent override

winki

  • Simple map for developing agent
  • Fix index out of bounds bug in polyshape class
  • Realistic agent

Calendar week 47

Enteee

  • Draw fake laneswitch
  • Extended render interface with simulationStates

winki

  • Improvement of realistic agent

Calendar week 48

Enteee

  • Fixed interval simulation
  • Dynamic app sleeping

winki

  • Bugfix in lane
  • Lane switching logic of realisitc agent
  • Implementation of traffic flows
  • Agent type can be configured in the routes xml file
  • Despawning of agents when spawn info of type "Flow"
  • Added restart command to console

Calendar week 49

Enteee

  • Bugfix time conversion 10E-9 -> 1E-9 for nano
  • Wall clock time in Window introduced
  • Wall clock / simulation time decoupling -> issue lag
  • Restart command fixing
  • singleton app / window
  • reflection for command finding
  • toggleInterpolate command added

winki

  • Added "ramp" net -> error at junctions
  • Console can receive parameters from clickable GUI

Calendar week 50

Enteee

winki

  • Every element has a position and can be located
  • RealisitcAgent uses GPS

Calendar week 51

Enteee

  • Simulation lag -> fixed with average velocity

winki

  • Spawning and despawning only at junctions. Edges will be mapped to begin junction or end junction at importing time of the routes file
  • Bugfix in RealisticAgent

Calendar week 52

Enteee

winki

  • Bugfix (invalid relative positions)
  • Agents can set turning (short-term decision) or destination (long-term decision)
  • Console bugfix (command argument variables must not be final!)
  • Help text for commands
  • Added remove command

Calendar week 1

Enteee

winki

Calendar week 2

Enteee

  • Advanced langechange
  • Config stuff review
  • Fixing collisions

winki

  • Record statistics data (space mean speed, time mean speed, density)
  • Comments, refactoring
  • Configuration file
  • Lane statistic values

Calendar week 3

Enteee

  • Readme goes documentation
  • Refactoring clicking
  • Jcommander bug workaround
  • Info command
  • Agent despawning on no junction cross
  • Refactor element removal -> Advanced removal (elements)

winki

Open issues

  • Bugfixes
    • Transcendent agents when collision happend
  • Agent handling on junctions
  • RealsticAgents not looking beyond edge boundaries
  • Area restricted tick method
  • Weather / daylight
  • Console command to import OpenStreetMap data

Resources

Licence

This software and the underlying source code is licensed under the MIT license.