0% found this document useful (0 votes)
2K views

Traffic Simulator Unreal Engine 4/unity Project Description

This document discusses the scope and challenges of a project to build a traffic simulator in Unreal Engine 4 or Unity. It outlines several key questions around the scope such as the size of the road network, number of vehicle types, and level of realism. It also identifies potential problems like the author's lack of experience with Unreal Engine. The document then reviews existing traffic simulation programs and academic papers on traffic modeling and simulation to inform the project design.

Uploaded by

api-340783236
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2K views

Traffic Simulator Unreal Engine 4/unity Project Description

This document discusses the scope and challenges of a project to build a traffic simulator in Unreal Engine 4 or Unity. It outlines several key questions around the scope such as the size of the road network, number of vehicle types, and level of realism. It also identifies potential problems like the author's lack of experience with Unreal Engine. The document then reviews existing traffic simulation programs and academic papers on traffic modeling and simulation to inform the project design.

Uploaded by

api-340783236
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 23

Wouter Mertens 3DAE1, Graduation Work, Milestone 1

Traffic Simulator Unreal Engine 4/Unity

Project description

Build a traffic system in unreal/unity so it is an own ecosystem.

Questions and Problems

The scope of the project is one of the first questions that comes to mind; How large is the
road network we work with? How customizable does it have to be? How many different vehicles and
vehicle types will be created? Do the AI have to be hyperrealistic with personal drivingstyles and
reactiontimes? Will collisionphysics need to be implemented? What about different roadsystems like
highways and traffic lights? How detailed should the endresult be? What about public transport?
When does the pathfinding happen? How do you implement limited access roads? Should
emergency vehicles be added? Should a client-proof GUI/tool be available.

As for the foreseeable problems, a first that comes to mind is that I’ve never coded in Unreal Engine
before. I’m sure the documentation is plentiful, but this could become a problem for the scheduling.

The capabilities of my laptop are lacking to say the least, however a sturdier system is available for
me on weekends, this should speed up the process a little.

Findings and Research

Existing Simulation Programs

Even though the use of computers to simulate traffic for testing purposes goes back almost 60 years,
the market is still quite limited, resulting in about 4 major international companies that sell a
simulator. Most with very limited access to the backend (or sometimes even the program due to
cost). Aimsun is one of the few that has a free trial and provides several papers on their website, they
could be used later for comparison purposes. At the development stage however the existing
programs are of limited value other than as general examples or sources for features.

The programs seem, in general, to only focus on motorized vehicles with at least 4 wheels, while also
leaving out roadworks and public transport. I have found systems that tackle events like large
influxes of traffic, caused by for example concerts or rushhour.

Academic Papers and Theses

-Hierarchical Modeling and Simulation Environment for Intelligent Transportation Systems


by Jong-Keun Lee, Ye-Hwan Lim and Sung-Do Chi

Most simulators work with 4 different levels for their calculations, as proposed in the paper;
these are the system entity structure/model base, the model abstraction, traffic modeling and ITS
simulation systems layer.

System entity structure consists of two components: a system entity structure (SES) and a model base
(MB). The SES represents knowledge of decomposition (breaking down problems into easily
understood and achievable parts), component taxonomies (classifications), coupling specification,
and constraints. Although I personally find the representation in the following image far easier to
understand.
System entity structure (SES) representation of the transportation system

The model base contains models that are procedural in character, they are expressed in discrete
event system specification (DEVS) formalism and are a theoretically well-grounded means of
expressing modular discrete event simulation models.

A nice overview of this level is provided in the following graphic

Model abstraction is a key to model construction for simulation, as a process it refers to a method or
algorithm applied to a model to simplify its complexity while preserving its validity. This process is
especially important for flexible traffic analysis since it reduces the complexity of a model while
retaining its validity relation to the modeling objectives and experimental frame.
Traffic modeling is probably the more visually interesting layer as it actually handles the realtime
calculations of the traffic modeling while not being as theoretical or in depth (hardware wise) as the
previous two levels. It’s also subdivided in 4 levels; the Vehicle-Level, Cell-Level (a group of nearby
vehicles is seen as a cell), Road-Level and Street-Level as developed by the DEVS (Discrete EVent
system Specification) formalism.

ITS simulation systems can be accomplished through the abstraction method and traffic modeling
based on the hierarchical modular modeling and simulation environment proposed earlier. Basically
this is the process of planning, creating databases (temporal and traffic information) and
structural/dynamic models, the creation of a simulation model structure using the previously
gathered info and making various analyses and expressions about simulation results. In other words,
this is the pipeline a researcher should follow if he wants to use the simulator for scientific research.

-Simulation of Traffic Systems – An Overview


by Matti Pursula

This paper gives a neat overview of the main traffic simulation systems over the 40 year
leading up to 1999, as told by the title. The basic application areas over this period remained the
same, but the applications have grown in size and complexity, like any software application since the
1960s. The trends popping up within the time constraints of the overview are also given a paragraph,
although overall this is not very applicable to the project.
-Modeling and Simulation of Urban Traffic Signals
by Khodakaram Salimifard and Mehdi Ansari

A deeper look into optimizing traffic lights on urban intersections by testing them in
simulations, in this case using data of an Iranian intersection near Bushehr in order to create a better
traffic flow by adapting the light timings.

A discrete event simulation model concentrates on the event times that can happen as these are the
only times when the system is going to alter its mood. Examining the system in between the
sequential event times is not for the simulator.

Most traffic lights operate on two strategies; fixed time strategies and vehicle motivated strategies.
Fixed time strategies are implemented offline using maximum efficiency codes based on important
and historical traffic data. These strategies don’t use information of real time traffic conditions.
Vehicle motivated strategies, which carry out an online synchronization and optimization of the
signal scheduling programs. These strategies are a traffic reactive signal control policy utilizing a
signal timing scheme that automatically answers to traffic requirements.

-Masterproef Traffic Simulator


by Frédérique Vanneste

The process of developing a tunnel simulation module for Traficon is described in this thesis
by this ex-Howest student Industrial sciences and technology. Building on an older thesis it adds a
scene generating module, a traffic generating module and a module to gather the user’s input. The
output file of the simulator is a video and a reference file, the reference contains a description of
what happens in the video (as an OVF text file).
He goes in depth into every step however; the modeling software selection, material creation, Bezier
curves, … They also looked into the possibility of game engines being used for the simulation and
thus the rendering process, as their rendertimes were higher than preferred.

Looking at the masterproef thesis of his fellow student and colleague for his project, Karel Hennebel,
who was responsible for the traffic simulation and general vehicle behavior, we can see that they
used a simple method where the car would follow the middle of the road (a spline) with an offset.
This would probably cut down on the cost of my original idea of simply have the cars actually drive
but would require some different calculations when it comes to changing lanes and and collision
detection.

In their simulation however no active speedchanges are possible, they need to be calculated
beforehand. A special stopevent has to be created to achieve changes in speed and as Traficon did
not require changing lanes, this is the default reaction upon disturbances on the road. The lack of
lanechanges also allows the offset to be hardcoded, although this is only useful when working with
uninterrupted roads.

-Autonomous traffic simulations


by Dan A. Alcantara

Finding bottlenecks can often be difficult if the traffic is dense enough. This is often the case
for urban environments, where simulations are mainly used for. The traffic then clogs up so fast the
source is harder to locate.

Civil engineering aims to produce more accurate models of behavior, while the video game industry
has focused on producing efficient simulations. A mix of both is also possible, in an attempt to
produce an interesting, but not quite accurate, model of ambient traffic.

The cars are treated as autonomous entities, each with its own set of preferences and randomized
path. They behave selfishly, and alter their behavior in an attempt to prevent themselves from
getting into a collision in while achieving their goals as quickly as possible. Doing so introduces some
realistic behaviors, such as repeated lane switching, forcing slower cars out of faster lanes, and
sending waves of decelerations down the road.
In older games cars often can’t change lanes, instead they stop before the blockage and wait until
the blockage disappears (in most they just vanish after a while). This causes long traffic lines and is to
be avoided.

Here the lanes are represented by a Bézier curve and they manage the updating of all vehicles that
are traveling over them, moving the vehicles along the lanes path and transitioning vehicles to
connected lanes. Connected either means that a vehicle transitions to the lane after this lane ends,
or a vehicle may merge into an adjacent lane. Lanes are used as the building blocks for roads.

The position and orientation of the vehicles are calculated by seeing how far along the lane they have
traveled, then getting the correct point and tangent along the curve. Calculating the correct
transition points for merging onto an adjacent lane A is done by discretizing A’s curve and finding the
closest point from the transition point in this lane.

Each lane can have its own speed limit, and this is reduced on curvy pathways to simulate the danger
in turning at high speeds.

Roads come in three categories; generators, which destroy cars leaving the map and create cars at
preset intervals; streets, which act as connections between the other types of roads; and
intersections, which allow switching between different roads.

Intersections come in 3-way and 4-way varieties and operate in a number of phases, where each
phase allows non-colliding traffic to flow. These phases are automatically generated, dependent on
the number of lanes in the streets that are connected to the intersection. The default is 4 phases, if a
set of input lanes doesn’t exist, as in the 3-way case, the simulation attempts to find further non-
colliding pathways to add to the current phase. When switching phases a small moment is left open
so cars that couldn’t stop in time for the block can cross safely.

When a car is initially generated, it is given a random set of properties. These include physical
properties, such as the car’s mass, its maximum acceleration/deceleration, and its length. Starting at
a set length, vehicles are categorized as trucks, mass is logically also connected to the length, so
larger vehicles tend to be slower than the smaller cars. Behavioral properties are also generated;
distances they prefer to keep between themselves and its neighboring cars, the speed it is
comfortable driving, and the amount of time they’ve spent traveling around the map. A personal,
randomized driving plan is also generated at creation, although not implemented, the plan was to
start and end the routes with a generator.

The interaction with neighboring cars is limited to 6 possibilities: the cars in front and behind it in the
same lane, and the cars that would be ahead or behind it if it were to switch lanes. This brought up
the problem that “collision-free” equations that exist are often not collision-free as the variables in
the tracked neighboring cars aren’t constant. A set of forces is a better idea in this case, as it is more
flexible and modular. The speed of the vehicle is there for calculated by 4 forces, truncated to fit
within the minimum and maximum speeds of the vehicle:

F = min(max(Fdesired speed, Ftailgating),Fcollision,Fblocks)

A car can have only 4 reasons to switch a lane; “I’m about to crash”, “I’m being pushed into a slow
lane…”, “I can’t move fast enough in this lane!”, and “This lane is going to end soon”. Upon switching
the cars in this model force their way into the desired lane, only stopped if they would hit the car in
front or get hit by the car behind them in that lane. This is detected by a kind of “Shadow car”,
essentially a hitbox the size of the switching car plus a buffer zone in front and behind it. A last check
is added where the new lane is checked on its desirability; Is it faster? Is it the slow lane while being
tailgated? Is the current lane ending soon? If any of these checks return true, the car will try to
switch.

My first thought of this system is that it might be quite heavy given larger numbers of vehicles and
the number of calculations per vehicle, especially with the seemingly constant checks for the lane
changing, which was apparently a simplified model, and the addition of “shadow cars”. Although
apparently it runs fine on a 6x6 grid randomly generated map, not quite sure on the number of cars
added to it at any given time.

Articles
-Game Design Deep Dive: Traffic systems in Cities: Skylines
Gamasutra.com

In Cities: Skylines traffic management is obviously a very important gameplay mechanic, each
player at some point in the game will be faced with a problematic part in their road network.

Two nodes create a segment and a road is made out of one or more segments, who also have a
maximum size, a long road will therefor consist of several segments. Smaller segments are better
optimized for collision detection, rendering and whatnots. Nodes (known as control points) hold the
start and end position of a segment while a segment holds a start and an end direction. This
structure is then “converted” into a Bézier curve for the vehicles to follow.

A vertex shader is then, in combination with a static mesh with a set tessellation, used to visualize
the road, the shader will transform the mesh according to the spline data.

Intersections are created using a similar approach and segments store their connections to
neighbouring segments as well as their road type. Each segment can then know about their available
lanes using their road type, which define the amount of lanes and their offset on the mesh.

Each segment/lane has a score considering the congestion level, speed limit and direction that
supplies the pathfinding with the necessary data to find the optimal route for every vehicle.

When a gridlock occurs, new cars get teleported away, that way the system doesn’t get overflowed
and the player can more easily locate the source of the problem to avoid a complete lockdown in
future. This also makes it easier to visualize congestions on a map, instead one big mess of red
coloured roads the problem area is easily identified.

Individual movement of every vehicle is calculated 4 times per second, this limits the framedrops and
makes a larger amount of vehicles possible. The renderer then smooths out the positions and
rotations between the calculated frames.

The vehicles have 2 modes; the creation and driving stage. During the creation the overall route is
calculated, while the driving stage is preserved for the calculations between the 2 current nodes.

Code Analyses

-Cities: Skylines Traffic Manager: Traffic President Edition by VictorPhillip

-Csl-traffic: csl-traffic: A WIP mod for Cities: Skylines to improve traffic by joaojfarias

-Original Traffic Manager with improved AI from Traffic++ by fadster

Three Cities: Skylines traffic mods with their source code on github. In case of any problems with my
own pathmanager, trafficlights or nodestructure these can be used as references. They also give a
detailed insight into the vanilla game as well, as they use the same variables and general class
structures. They can also be used to find inspiration for custom vehicles such as busses, emergency
vehicles, garbage trucks or even a hearse. Most of them focus on either improving the road
pathfinding or that of track based vehicles, like trams.

-SUMO – Simulation of Urban Mobility by the German Institute of Transportation Systems (DLR)

A free and open traffic simulation suite which is available since 2001. They have a free download link
available on the site, next to a manual, tutorial and examples. Even the source code is linked for all to
see. Online documentation is easily accessible and a bugtracker is provided in case you need it.

Personal Projects and Tests

-Pathfinding GPS code used for the Programming 4 exam in DAE of June 2015

An interesting method to find the shortest route when given a database consisting of a vector of
vectors of strings, where the inner vectors are the motorways and the strings are the cities they pass
through in order of passage. You would then set up an std::map for all the links of every city and use
a recursive search to find the best, in this case shortest, path to your destination, while logging every
city you passed. Exchange the cities with nodes and you have your basic GPS system.

GPS constructor sets up the std::map m_Links, built up of a string and an std::set of strings

-Unity spline drawing testscene

As a test to see how I could create the roaddrawing methods I created a scene where you left-click to
add a node to the current road, once you right-click the road is saved and you can start drawing the
next part of your network. Upon every click the linerenderer connects the last node with the newly
created one as a way of visualizing the current road. This was done in Unity while getting more
familiar with the Unreal Engine 4 ways of working.
Research Conclusion

The hyperrealistic engineering route would probably not be possible within the given timeframe,
therefor a more “game-y” approach seems more suited to both the reigns of possibility and my
personal interests for this project. As a personal addition to what is available on the market I would
like to add a few discrepancies of everyday traffic to the project, like road works or other
obstructions forcing a change in behaviour or route.

Pathfinding should take place upon creation of the vehicles, along with the initialization of several
behavioural variables such as minimum and maximum vehicle speed, acceleration, aggressiveness of
the driver, mass and length of the vehicle, … If possible, throwing in a few priority vehicles would be
interesting as well, or as mentor Brecht Kets suggested, bikes. The vehicles should be able to change
lanes and use crossroads efficiently.

The actual following of the path will be done by simple following the spline representing the road
with an offset. The difficulty here will lie in the collision detection and lanechanging mechanics.

The roads themselves are built up of spline data with Bézier curves, additionally the y-axis could also
be added to this equation; although this would also require an extra faction for the speed of the
vehicles traversing these roads. Several variables like speed limit, congestion and number of lanes
decide the score of each road, this is then used for the route calculations of the cars.

Editor-wise, several different editor modes would be desirable: a create mode, where you create the
actual layout of the roads as tested in the Unity project; an edit mode, where you can select different
modules of the roadnetwork and edit them, e.g.: changing the number of lanes on a road or the
timers on trafficlights.

Project Version 1:

Mechanics:

-MainManager

This class stores all the variables that need to be accessed across different scripts, making it
easier for all classes to send and receive this information. The manager also cleans out the roads
when needed and sends a spawnrequest to a random spawnernode when all conditions are met as
can be seen in the following pseudocode.

Int nrRequestedVehicles = 0;
Int maxNrRequestedVehicles = MaxVehicles – AmountOfVehicles;
If(IsInSimMode && AtLeast2Spawners && deltaT < MaxDeltaT){
While(nrRequestedVehicles < maxNrRequestedVehicles){
Rand = RandomBetween0andAmountOfSpawners;
Send a spawnrequest to spawner[Rand];
Increase nrRequestedVehicles by 1;
}
}

-RoadNetwork
The whole system is divided in 2 categories; the Nodes and the Connections. This was done
for the Pathfinding as will be explained further down. All parts are put in separate lists according to
categorie in the MainManager for easy access to all the classes.

-Nodes

SpawnerNodes are essential one of the two in order to have a functioning simulation,
the minimum needed number is two as every vehicle needs a start and endspawner that is not the
same node.

Once a Spawnrequest is sent from the mainmanager a vehicletype is selected according to the
percentages set in the menus and added to a list. This list is gradually emptied out as new vehicles
are instantiated.

SpawnRequest overiew

IntersectionNode take in incoming vehicles and guard them until it’s their time to be
released, when entering they are stored in a dictionary according to the upcoming road of that
vehicle. Once it’s that roads turn, the respective list is emptied gradually and the vehicles continue
on their path. Within the intersection all collision detection and movement is halted up until the
vehicles are released.

Once released the automobiles are given a Lane and return to their normal behaviour continuing on
their journey. The releasetimer is reset and the releasedindex is increased.

-Connections
The roads aka connections, as they connect the different nodes, consist of a parent
element and childpoints (also called nodes). The children hold the positional information for the
vehicles to follow, while the parent has the variables like the speedlimit, number of lanes, lanewidth
and serialnumber. Important to the pathfinding is the two begin and endnode values, these link to
the spawner/intersection nodes on either side of the road.

-Vehicles

The vehicleselection extends to 4 choices, each with their own realization of the vehicle
variables:

float Speed;
float Width;
float Lenght;
float LaneChangeSpeed;
float BreakSpeed;
float AccelSpeed;
float BufferLength;
int Lane;

The vehicle consists of an invisible parent and a visible child, the parent follows the road while the
child just changes position upon lanechanges.

-AI

A behaviour tree was the obvious choice over finite-state machines, neural networks and so on as
the positives far outweigh the negatives, as well as the fact that we’ve seen this subject during
classes and have a limited amount of experience with it as a result.

•Cost: very lightweight •With bigger projects it can be easy to lose


•Scalability: can be decomposed into small sight of the structure
subtrees •Very reactively driven, not very "smart"
•Reusability: nodes are independent ->
subtrees are independent -> reuse possible
•Goal-oriented: independent, but because of
the structure the subtrees can still be
designed for a specific goal
•Parallelization: it is possible to run multiple
children at the same time
•Maintainability: defined by structure, not by
conditions -> nodes can be independent

-Behaviortree
The tree is built up as follows:

CheckStartEndNodes checks if theres a start and an end node


PathFinding creates a path of nodes and a list of connections from start to end
Intersection returns running if we’re on an intersection, else it’ll increase the node
and road indexes and return success
FollowRoad follows the current connection
Speedup checks if we’re going over the speedlimit, if not it’ll increase the speed
CheckHitDetection returns true if a neighbouring vehicle that is slower is in front of us
CheckLeftLane check if the left lane is open
ChangeLeftLane changes to the left lane
Slowdown decreases the speed if a neighbouring vehicle that is slower is in front of us
CheckRightLane checks if the right lane is open
ChangeRightLane changes to the right lane

-PathFinding

The pathfinding method is based upon A*, it searches for a path using the Spawner and
Intersection Nodes first by checking the connected Nodes and later adds the connections themselves
to a separate list.
Clear the pathlist.
Create two temporary LinkedLists (open and closed).
Add the startnode to the OpenList
While OpenList is not empty
Get the Nodes with the lowest FScore
Pop the current Node off the open list and push it to closed
Retrieve the chosen node’s adjacent nodes
Check if any of the neighbours is the goal
Else go over all the elements
If the node is in closed, ignore it
Else if the node is not in open list, compute score and add it
Reconstruct the path by going through the parents
Create the Connection path

-HitDetection

At first the hitdetection in CheckHitDetection() was done with a raycast with layercasting,
this however required every vehicle to have a boxcollider, performance wise this was the wrong
choice. The method has since been replaced with a method that checks if the neighbouring vehicles
are within a set distance in front of the current vehicle.

If(IsOnIntersection) return false;


Foreach(Vehicle neighbour in CurrentRoad.Vehicles){
If(neighbour == null || neighbour == this) continue;
If(absoluteValueDistanceToNeighbour < detectionLength *Speed && neighbour.Lane == Lane){
fwdPos = Vector3.forward*detectionLength*Speed in worldspace;
Return(distanceToNB < distFromfwdPosToNB
&& distFromfwdPosToNB < detectionLength*Speed
&& Speed > neighbour.Speed);
}
}
Return false;
-Changing speed

The two options here are obviously to speed up or slow down, speeding up occurs when
Speed is lower than the maximum speed allowed for the current lane (-5% when you move to the
right). Slowing down only happens when the vehicle in front of you is slower.
Version 1 results:

The creator is ok Slow


Vehicles are lightweight Bug in pathfinder
Limited amount of vehicles
Spawns multiple vehicles at
once
Looks
Not very userfriendly

In light of the feedback given I’ve decided to scrap most of this version and start anew, using
the first version as research and aiming to improve every aspect if needed.

Project Version 2:

Version 1 reflection:

Creator: Although functioning, a better option is likely to be out there. Search for a better
option to integrate or add visuals to the current creator. The user-friendliness also leaves to be
desired.

Pathfinder: Slows down the whole program as it needs to find a new path every time a new
vehicle is created, this ends up being very expensive. In addition to that the still existing bug where it
would go back to the start node ignoring all paths at the end of its route really questions the
functionality.

Vehicle setup: Lightweight and effective, but not very customizable.

Looks: Extremely basic, hard to know what is going on for someone new without an
explanation.

Planning:

The plan now is to research some improvements for all of these parts and see what can be
easily improved or just replaced. Then we’ll go start trying some of these ideas and possibly
implementing them into the final product.

The goal this time is to create a tool rather than a toy, what I mean by this is to have all the
heavy calculations done before we hit runtime, this could possibly limit those to the editor only. That
should keep the calculation costs at runtime low enough to expand the possible numbers on screen.

Research:
-TrafX by carx-tech (carx-tech.com/trafx-car-physics-engine-eng)

“A traffic simulation software unit that works best with their CarX engine and the unity3D
game engine”, as explained on their website. It seems very customizable and robust, supporting
multiple vehicle and road types. The setup is quite extensive however, as it requires you to draw
every single spline point and link them, which could take an enormous amount of time depending on
the map size. It also comes with a 3720$ (+ 3360$ with the source code) price tag.

-EasyRoads3D Free by AndaSoft (unityterraintools.com/tools.php)

A marker based road and river creation editor tool for Unity. It supports unlimited marker
points per road, vegetation, custom objects and changing terrain. It also has a neat test drive feature
to test your road objects quickly in the scene view. After trying to implement this plugin it became
apparent however that the free version is to limited, mostly because it has no automatic detection
on whether two roads intersect or not.

-RoadArchitect by MicroGSD (github.com/MicroGSD/RoadArchitect)

An open source road network creator featuring dynamic intersections, bridges and many
other road objects, with extensive documentation and tutorials. The creation is editor only but is
very customizable, with up to 3 lanes per side and multiple models to choose from.

-Easy Traffic by Gunabara Games (assetstore.unity3d.com/en/#!/content/4777)

A simple traffic A.I. including cars that avoid collision, stop at semaphores. The cars use rays
to detect collisions, this makes it easy to implement but also means the cars slow down in tight
corners and it is quite expensive in large numbers. The drawing of the nodes uses straight lines only,
requiring multiple nodes for curves, adding to the setup workload.

-Road Network Generation tool by PadMalCom

A plugin that creates both procedural road networks and can import OpenStreetMap exports
into unity. The generated levels include roads, intersections and buildings. The OpenStreetMap
support is quite interesting, however it is not released yet. After asking the creator, Jonas Freiknecht,
about the progress he responded he’s still working on it but didn’t want to release it yet as sidewalks
are not yet created at intersections and the editor gui is still a mess. It might be interesting to try and
use the OSM data to generate roads however.

Testing:

-OSM integration:

The exported .osm files can be read as .txt file, inside you can see readable text much alike to
json. It starts with a list of nodes with a unique id, a longitude and a latitude. Those nodes are linked
to past this list in the different roads, landscape lines and buildings. Looping through these objects
and connecting the nodes with lines redraws the map you’ve exported.

The red lines are the roads, the blue lines are the buildings and landscape lines, if these are enclosed
polygons are added. The area in the picture above is the area around campus theLevel.

-Road generation:

The researched options I’ve found that are usable are EasyRoads3D and RoadArchitect,
EasyRoads3D seems to be the more limited one of the two, lacking the automatic detection of
intersections. RoadArchitect is there for the choice I’ve gone with.

Dissecting the RoadBuilding:

We’ll search for how it works without multithreading to keep it simple. There’s two Unity
Profiler runs which we can use to see the order of the methods.
First run:

No MultiThreading:

50: Profiler sample: “RoadCon_RoadPrelim”


80: GSDRoadCreationT.RoadJob_Prelim()
Profiler sample: “RoadCon_Road1”
90: RoadCalcs1_static.RunMe()
Profiler sample: “MeshSetup1”
92: RCS.MeshSetup1()
Profiler sample: “RoadCon_Road2”
94: RoadCalcs2_static.RunMe()
Profiler sample “MeshSetup2”
96: RCS.MeshSetup()
Construction_Cleanup()
if TerrainCalcsJob != null -> ConstructRoad2()
if RoadCalcsJob1 != null -> ConstructRoad3()
if RoadCalcsJob2 != null -> ConstructRoad4()

Second run:

ConstructRoad2()
40: Make Spline fit terrain
60: Check TerrainCalcs, set to null, get road
72: Setup new RoadCalcsJob1.Start()
ConstructRoad3()
84: RCS.MeshSetup1()
96: Check RoadCalcsJob1, set to null
Setup new RoadCalcsJob2.Start()
98
ConstructRoad4()
RCS.MeshSetup2()
Construction_Cleanup()
The difference between RoadCalcsJob1 and RoadCalcsJob2 is that 1 creates a road and static runs
RoadJob1, 2 just static runs RoadJob2.

RoadJob1 handles the construction of most triangles and normals. In certain scenarios the UVs might
also be processed for efficiency reasons.

RoadJob2 handles the construction of most UVs and tangents. Some scenarios might involves
triangles and normal or lack UV construction for efficiency reasons.
Dissecting the code gives me the method it uses to create roads, combining that method with
the OSM data we initially get the following result:

Problem being it only draws the first sections of the roads, still not a bad start. Note that the
black roads are part of the OSM implementation, not RoadArchitect.
Fixing the initial problem gives the result above, as we can see the roads are complete but they seem
to connect to random nodes of the roads. The problem being the nodes in the OSM data aren’t
correctly ordered. I could fix this, but I’d honestly rather continue working on the base of the project,
setting this aside as an extra feature. We’ll keep the lines as a plan to help draw the roads for
whoever wants them, and keep the generating as a future possibility.

-Extracting the splines from the RoadArchitectNetwork to use as guides for the vehicles:

The GSDRoad component that every road has creates a GSDSplineC which has a collection of
GSDSplineN nodes which can be accessed with GSDSpline.mNodes[] and are visible in the editor
screen. The GSDSplineN objects hold a position, rotation, tangent, bIsIntersection and bIsEndPoint.
The GSDSplineC component has a function called GetSplineValue() which takes a float between 0 and
1 and returns a Vector3 position. We can use that function to move along the spline which saves us a
lot of work as no extra spline has to be generated.

-Building the network for pathfinding:

Go through every road in the network and go through all the nodes of those roads. If it’s an
intersection then save the connection between the previous node and this intersection and store the
spline and spline values of both start and end nodes of the connection in it.

To test the connections I’ve drawn debuglines along the splines, on the intersections I’ve also
added controlled curves for every turn possibility with the controlpoint being the position of the
intersection.
Mechanism:

-Vehicle

The vehicles consist of a parent object, a model child and a


lookAt target.

The parent object simply follows the road spline with the
GetSplineValue function. We input a value increased by
deltaTime and divided by the length of the road.

The LookAt target does the same but a small distance in front
of the parent, the parent rotation then does a simple LookAt
to this position.

The model simply follows the parent at a localposition x value


set to the variable CurrentLanePos, which increases or
decreases according to the lanechanging commands.

-RoadData

Public List<Vehicle> PosVehicles; //Vehicles traveling in the positive direction


Public List<Vehicle> NegVehicles; // Vehicles traveling in the negative direction
Public float MaxSpeed; //The speedlimit
Public int NrOfLanes; //The number of lanes
Public RoadData()
{
PosVehicles = new List<Vehicle>();
NegVehicles = new List<Vehicle>();
}

-PathData

Public Node StartNode; //The node we start at


Public float StartF; //The position along the spline startnode is at
Public Node EndNode;
Public float EndF;
Public GSDSplineC Spline;
Public RoadData RoadData; //RoadData of this part of the path
Public float Length; //The length of this part of the path
Public int Direction; //The direction the vehicle needs to travel (-1 or 1)
-PathFinding

The big problem with the last


version was the expensive
pathfinding, Dijkstra is often said
to be the fastest method. Also,
when generated, it leaves a table
with the cheapest routes to every
node that can be reached from the
current one. Therefor we will
generate a Dijkstratable for every
single vehicle-spawning node
when loading the runtime. When a
vehicle spawns all it needs to do is
copy over the route to its goal,
convert this into a list of PathData
and start driving.

-HitDetection

The hitdetection is one of the few things that has survived the versionchange, it works as
follows: You go through the list of vehicles in RoadData (PosVehicles or NegVehicles according to
your direction, exclude this vehicle) and if the other vehicles’ splineposition is within a set buffer we
tell this vehicle to slow down.

-LaneChanging

If the vehicle is traveling at a speed that is to slow or to fast for the current lane it is in, we
tell the vehicle to check if a more suitable lane is open, if it is we tell the model to increase or
decrease the CurrentLanePos, this will move the model towards that desired lane.

If this makes the model want to move outside of the bounds of the road the action is
negated.

-SpeedChanging

If the maximum speed of the vehicle or and road is not reached then the vehicles speed will
increase. If the hitdetection fires it will decrease.

-PathChanging

When the current section of the path is coming to an end we check if it’s the end of the
whole route or just the end of one part. If we have reached the final destination then the vehicle is
removed from all lists and deleted. If it’s just the end of a part, then the vehicle is removed from the
last parts vehicle list and added to the next parts list. The PathData is adapted, the current lane is
changed if needed, the path index is increased and the current spline position float is set to the start
of the next part.
-BehaviourTree

The functions above wouldn’t do much without a behaviour tree:


Result

I’m quite happy with the result of my project as it has reached the goal I wanted it to. It runs
smoothly with 500 vehicles without to many collisions, which you could probably fix by fiddling with
the vehicle settings. All problematic components of the first version are improved and functioning.

The pathfinding solution, which was suggested to me by a classmate, turned out to be a great fix, it
doesn’t get in the way of the framerate and the loading times seem to be constant whether the
network is big or small.

Other struggles, like finding a way to make the cars follow the splines of the RoadArchitect, just took
a bit of digging and time, in this case figuring out how the building process worked by dissecting the
source code. Therefor starting early is always a good idea, spreading the work instead of becoming a
zombie for a week with 48 hour days.

At the start I wasn’t very excited for this subject but as I researched more and more about it and,
especially for the second version, once I began to see results it became more and more interesting.
I’ve noticed in the process of making this that I need to ask around more and plan more before
rushing into a project with this one glorious idea I have that will totally work. More often than not
there’s a better solution available around you or stuck in the brain of someone around you.

Future additions could be completing the generating of the roads from the OSM data like I tested,
having traffic lights that stop the vehicles at the intersections and adding more types of vehicles.

You might also like