Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
We have upgraded GitLab to 15.1. Due to major code changes GitLab was down for some time.
Open sidebar
vadere
vadere
Commits
6c2cad9b
Commit
6c2cad9b
authored
Oct 31, 2016
by
Felix Dietrich
Browse files
Add model ovm/OptimalVelocityModel.java
parent
de9267c2
Changes
5
Hide whitespace changes
Inline
Side-by-side
VadereGui/src/org/vadere/gui/topographycreator/model/TopographyBuilder.java
View file @
6c2cad9b
...
...
@@ -6,8 +6,16 @@ import java.util.Iterator;
import
java.util.LinkedList
;
import
org.vadere.state.attributes.scenario.AttributesAgent
;
import
org.vadere.state.attributes.scenario.AttributesCar
;
import
org.vadere.state.attributes.scenario.AttributesTopography
;
import
org.vadere.state.scenario.*
;
import
org.vadere.state.scenario.Obstacle
;
import
org.vadere.state.scenario.Pedestrian
;
import
org.vadere.state.scenario.ScenarioElement
;
import
org.vadere.state.scenario.Source
;
import
org.vadere.state.scenario.Stairs
;
import
org.vadere.state.scenario.Target
;
import
org.vadere.state.scenario.Teleporter
;
import
org.vadere.state.scenario.Topography
;
import
org.vadere.util.geometry.shapes.VPoint
;
/**
...
...
@@ -33,6 +41,7 @@ public class TopographyBuilder implements Iterable<ScenarioElement> {
private
LinkedList
<
ScenarioElement
>
topographyElements
;
private
AttributesTopography
attributes
;
private
AttributesAgent
attributesPedestrian
;
private
AttributesCar
attributesCar
;
/**
* Default-Constructor that initialize an empty TopographyBuilder.
...
...
@@ -69,6 +78,7 @@ public class TopographyBuilder implements Iterable<ScenarioElement> {
}
attributes
=
topography
.
getAttributes
();
attributesPedestrian
=
topography
.
getAttributesPedestrian
();
attributesCar
=
topography
.
getAttributesCar
();
topographyElements
=
new
LinkedList
<>();
topographyElements
.
addAll
(
obstacles
);
topographyElements
.
addAll
(
stairs
);
...
...
@@ -104,7 +114,7 @@ public class TopographyBuilder implements Iterable<ScenarioElement> {
}
public
Topography
build
()
{
Topography
topography
=
new
Topography
(
attributes
,
attributesPedestrian
);
Topography
topography
=
new
Topography
(
attributes
,
attributesPedestrian
,
attributesCar
);
for
(
Obstacle
obstacle
:
obstacles
)
topography
.
addObstacle
(
obstacle
);
...
...
VadereSimulator/src/org/vadere/simulator/models/ovm/OVMEquations.java
0 → 100644
View file @
6c2cad9b
/**
* This class manages the Equations of the Optimal Velocity Model and computes the
* derivative-equations
*
*/
package
org.vadere.simulator.models.ovm
;
import
java.text.DecimalFormat
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.List
;
import
java.util.Random
;
import
java.util.concurrent.ExecutionException
;
import
org.vadere.simulator.models.ode.AbstractModelEquations
;
import
org.vadere.simulator.models.ode.ODEModel
;
import
org.vadere.state.attributes.models.AttributesODEIntegrator
;
import
org.vadere.state.attributes.models.AttributesOVM
;
import
org.vadere.state.scenario.Car
;
import
org.vadere.state.scenario.Pedestrian
;
import
org.vadere.state.scenario.Target
;
import
org.vadere.util.geometry.Vector2D
;
import
org.vadere.util.geometry.shapes.VPoint
;
import
org.vadere.util.parallel.AParallelWorker
;
import
org.vadere.util.parallel.CountableParallelWorker
;
import
org.vadere.util.parallel.IAsyncComputable
;
import
org.vadere.util.parallel.AParallelWorker.Work
;
public
class
OVMEquations
extends
AbstractModelEquations
<
Car
>
implements
IAsyncComputable
{
private
AttributesOVM
attributesOVM
;
private
double
sensitivity
;
private
double
sightDistance
;
private
double
sightDistanceFactor
;
private
boolean
pedestrianInteraction
;
private
final
Random
rand
=
new
Random
(
1
);
// needed to create ghost cars for a time instant.
/**
* Optimal Velocity Function in the form of the original paper
*
* @param x_n Xn
* @param x_n_1 Xn-1
* @return
*/
public
double
ovFunction
(
double
x_n
,
double
x_n_1
,
double
speed
)
{
double
dX
=
Math
.
max
(
0
,
x_n_1
-
x_n
);
return
speed
/
2
*
(
Math
.
tanh
((
8
*
dX
)
/
(
3.6
*
speed
)
-
2
)
+
Math
.
tanh
(
2
));
}
@Override
public
void
computeDerivatives
(
double
t
,
double
[]
x
,
double
[]
xdot
)
{
// fetch attributes of the model
sensitivity
=
attributesOVM
.
getSensitivity
();
sightDistance
=
attributesOVM
.
getSightDistance
();
sightDistanceFactor
=
attributesOVM
.
getSightDistanceFactor
();
// update position of all dynamic elements
ODEModel
.
updateElementPositions
(
Car
.
class
,
t
,
topography
,
this
,
x
);
// create workers for each pedestrian
List
<
AParallelWorker
<
Double
[]>>
workers
=
new
ArrayList
<
AParallelWorker
<
Double
[]>>();
// loop over all persons and compute the next step
int
personCounter
=
0
;
// used for arrays, not identical to personID!
for
(
final
Car
car
:
elements
)
{
AParallelWorker
<
Double
[]>
w
=
new
CountableParallelWorker
<
Double
[]>(
personCounter
,
new
Work
<
Double
[]>()
{
private
int
ID
;
@Override
public
Double
[]
call
()
throws
Exception
{
computeSingleCarParallel
(
car
,
getWorkerID
(),
t
,
x
,
xdot
);
return
null
;
}
@Override
public
void
setID
(
int
ID
)
{
this
.
ID
=
ID
;
}
@Override
public
int
getWorkerID
()
{
return
this
.
ID
;
}
});
personCounter
++;
workers
.
add
(
w
);
w
.
start
();
}
// finish the work
for
(
AParallelWorker
<
Double
[]>
worker
:
workers
)
{
try
{
worker
.
finish
();
}
catch
(
ExecutionException
e
)
{
e
.
printStackTrace
();
}
catch
(
InterruptedException
e
)
{
// Necessary in order to tell Simulation the thread has been
// interrupted.
// TODO [priority=medium] [task=refactoring] Hack, other solution?
Thread
.
currentThread
().
interrupt
();
break
;
}
}
}
private
void
computeSingleCarParallel
(
Car
currentCar
,
int
carIdInArray
,
double
t
,
double
[]
x
,
double
[]
xdot
)
{
int
fCI
=
-
1
;
Car
nearestCar
=
null
;
List
<
Car
>
neighbors
=
topography
.
getSpatialMap
(
Car
.
class
).
getObjects
(
currentCar
.
getPosition
(),
sightDistance
);
if
(
topography
.
hasTeleporter
())
{
Vector2D
tpoint
=
topography
.
getTeleporter
().
getTeleporterShift
();
List
<
Car
>
ghostCars
=
topography
.
getSpatialMap
(
Car
.
class
).
getObjects
(
currentCar
.
getPosition
().
add
(
tpoint
),
sightDistance
);
for
(
Car
ghost
:
ghostCars
)
{
Car
repositionedGhost
=
new
Car
(
ghost
.
getAttributes
(),
rand
);
repositionedGhost
.
setPosition
(
ghost
.
getPosition
().
add
(
topography
.
getTeleporter
().
getTeleporterShift
().
multiply
(-
1
)));
neighbors
.
add
(
repositionedGhost
);
}
}
for
(
int
j
=
0
;
j
<
neighbors
.
size
();
j
++)
{
Car
car
=
neighbors
.
get
(
j
);
if
(
nearestCar
==
null
)
{
if
(
car
!=
currentCar
&&
isInFront
(
car
,
currentCar
))
{
nearestCar
=
car
;
fCI
=
j
;
}
}
else
{
if
(
car
!=
currentCar
&&
isInFront
(
car
,
currentCar
)
&&
isInFront
(
nearestCar
,
car
))
{
nearestCar
=
car
;
fCI
=
j
;
}
}
}
// Check Pedestrians if pedestrianIteraction is turned on
if
(
pedestrianInteraction
)
{
// TODO [priority=medium] [task=bugfix] [Error?]
}
// evaluate the front car with respect to a limited sight distance
/*
* List<Car> neighbors =
* topography.getSpatialMap(Car.class).getObjects(actualCar.getPosition(), sightDistance);
* for(Car car:neighbors){
* if (nearestCar == null){
* nearestCar=car;
* } else {
* if (car.getPosition().getX() > actualCar.getPosition().getX()
* && car.getPosition().getX() < nearestCar.getPosition().getX()){
* nearestCar=car;
* }
* }
* }
*/
computeSingleCar
(
currentCar
,
nearestCar
,
t
,
x
,
xdot
,
carIdInArray
,
fCI
);
}
private
boolean
isInFront
(
Car
car
,
Car
currentCar
)
{
if
(
this
.
attributesOVM
.
isIgnoreOtherCars
())
return
false
;
if
(
currentCar
.
hasNextTarget
()
&&
car
.
hasNextTarget
())
{
// TODO [priority=low] [task=feature] check that the cars actually stop when another
// car is in front
if
(
currentCar
.
getNextTargetId
()
!=
car
.
getNextTargetId
())
{
return
false
;
}
Target
target
=
topography
.
getTarget
(
currentCar
.
getNextTargetId
());
if
(
target
==
null
)
{
System
.
out
.
println
(
currentCar
.
getNextTargetId
());
}
double
distanceToThis
=
target
.
getShape
().
distance
(
currentCar
.
getPosition
());
double
distanceToOther
=
target
.
getShape
().
distance
(
car
.
getPosition
());
return
distanceToOther
<
distanceToThis
;
}
else
{
return
car
.
getPosition
().
getX
()
>=
currentCar
.
getPosition
().
getX
();
}
}
/**
* Computation of speed and position of a single car for one time step
*
* @param currentCar
* @param frontCar
* @param t
* @param x
* @param xdot
* @param index
*/
private
void
computeSingleCar
(
Car
currentCar
,
Car
frontCar
,
double
t
,
double
[]
x
,
double
[]
xdot
,
int
index
,
int
fCI
)
{
double
[]
position
=
new
double
[
2
];
double
[]
speed
=
new
double
[
2
];
double
[]
position2
=
new
double
[
2
];
getPosition
(
index
,
x
,
position2
);
getVelocity
(
index
,
x
,
speed
);
VPoint
myPos
=
new
VPoint
(
position2
[
0
],
position2
[
1
]);
Vector2D
myVelocity
=
new
Vector2D
(
speed
[
0
],
speed
[
1
]);
double
mySpeed
=
myVelocity
.
x
;
// only the x coordinate is set. Do NOT use "length" here, otherwise negative speeds occur.
// velocity is just passed through, but rotated so that the vector points in target
// direction
if
(
currentCar
.
hasNextTarget
())
{
position
[
0
]
=
myVelocity
.
x
;
position
[
1
]
=
myVelocity
.
y
;
}
// also change the direction of the acceleration so that the velocity for each car is
// correctly set.
if
(
currentCar
.
hasNextTarget
())
{
Target
target
=
topography
.
getTarget
(
currentCar
.
getNextTargetId
());
VPoint
closest
=
new
Vector2D
(
target
.
getShape
().
getBounds2D
().
getCenterX
(),
target
.
getShape
().
getBounds2D
().
getCenterY
());
double
localspeed
=
mySpeed
;
Vector2D
direction
=
new
Vector2D
(
closest
.
add
(
myPos
.
scalarMultiply
(-
1
))).
normalize
(
localspeed
);
position
[
0
]
=
direction
.
x
;
position
[
1
]
=
direction
.
y
;
}
if
(
frontCar
==
null
)
{
double
newTargetX
=
sightDistance
*
sightDistanceFactor
;
if
(
currentCar
.
hasNextTarget
())
// only one target left (?)
{
Target
target
=
topography
.
getTarget
(
currentCar
.
getNextTargetId
());
if
(
target
==
null
)
{
System
.
out
.
println
(
currentCar
.
getNextTargetId
());
}
if
(
target
.
getShape
().
distance
(
myPos
)
<
sightDistance
)
{
newTargetX
=
myPos
.
distance
(
new
VPoint
(
target
.
getShape
().
getBounds2D
().
getCenterX
(),
target
.
getShape
().
getBounds2D
().
getCenterY
()));
}
}
speed
[
0
]
=
sensitivity
*
ovFunction
(
0.0
,
newTargetX
,
currentCar
.
getFreeFlowSpeed
())
-
sensitivity
*
mySpeed
;
}
else
{
speed
[
0
]
=
sensitivity
*
ovFunction
(
0.0
,
myPos
.
distance
(
frontCar
.
getPosition
())
-
currentCar
.
getAttributes
().
getLength
()
*
2
,
currentCar
.
getFreeFlowSpeed
())
-
sensitivity
*
myVelocity
.
getLength
();
}
speed
[
1
]
=
0
;
setPosition
(
index
,
xdot
,
position
);
setVelocity
(
index
,
xdot
,
speed
);
}
@Override
/**
* Dimension per Car
* 4 parameters: position (x,y), velocity (x,y)
*/
protected
int
dimensionPerPerson
()
{
return
4
;
}
public
void
setVelocity
(
int
personID
,
double
[]
solution
,
double
[]
velocity
)
{
solution
[
personID
*
dimensionPerPerson
()
+
2
]
=
velocity
[
0
];
solution
[
personID
*
dimensionPerPerson
()
+
3
]
=
velocity
[
1
];
}
@Override
public
void
getVelocity
(
int
personID
,
double
[]
solution
,
double
[]
velocity
)
{
velocity
[
0
]
=
solution
[
personID
*
dimensionPerPerson
()
+
2
];
velocity
[
1
]
=
solution
[
personID
*
dimensionPerPerson
()
+
3
];
}
public
void
setModelAttributes
(
AttributesOVM
attributes
)
{
this
.
attributesOVM
=
attributes
;
}
public
void
setPedestrianInteraction
(
boolean
pedestrianInteraction
)
{
this
.
pedestrianInteraction
=
pedestrianInteraction
;
}
}
VadereSimulator/src/org/vadere/simulator/models/ovm/OptimalVelocityModel.java
0 → 100644
View file @
6c2cad9b
/**
* This class implements the optimal velocity model for car traffic
*
*/
package
org.vadere.simulator.models.ovm
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Random
;
import
org.vadere.simulator.control.ActiveCallback
;
import
org.vadere.simulator.models.Model
;
import
org.vadere.simulator.models.ode.IntegratorFactory
;
import
org.vadere.simulator.models.ode.ODEModel
;
import
org.vadere.state.attributes.Attributes
;
import
org.vadere.state.attributes.models.AttributesOVM
;
import
org.vadere.state.attributes.scenario.AttributesAgent
;
import
org.vadere.state.attributes.scenario.AttributesCar
;
import
org.vadere.state.scenario.Agent
;
import
org.vadere.state.scenario.Car
;
import
org.vadere.state.scenario.DynamicElement
;
import
org.vadere.state.scenario.Pedestrian
;
import
org.vadere.state.scenario.Topography
;
import
org.vadere.util.data.Table
;
import
org.vadere.util.geometry.shapes.VPoint
;
import
org.vadere.util.parallel.ParallelWorkerUtil
;
public
class
OptimalVelocityModel
extends
ODEModel
<
Car
,
AttributesCar
>
{
private
int
carIdCounter
=
10000000
;
// TODO [priority=low] [task=refactoring] hack, think about another way of separating car IDs and pedestrian IDs.
private
AttributesOVM
attributesOVM
;
private
OVMEquations
ovmEquations
;
private
List
<
ActiveCallback
>
activeCallbacks
;
/**
* Constructor for OptimalVelocityModel used in the ModelCreator
*
* @param scenario
* @param ovmEquations
* @param attributesOVM
* @param elementAttributes
* @param random
*/
@Deprecated
public
OptimalVelocityModel
(
Topography
scenario
,
OVMEquations
ovmEquations
,
AttributesOVM
attributesOVM
,
AttributesCar
elementAttributes
,
boolean
pedestrianInteraction
,
Random
random
)
{
super
(
Car
.
class
,
scenario
,
IntegratorFactory
.
createFirstOrderIntegrator
(
attributesOVM
.
getAttributesODEIntegrator
()),
ovmEquations
,
elementAttributes
,
random
);
this
.
attributesOVM
=
attributesOVM
;
this
.
ovmEquations
=
ovmEquations
;
ovmEquations
.
setPedestrianInteraction
(
pedestrianInteraction
);
ovmEquations
.
setModelAttributes
(
attributesOVM
);
ovmEquations
.
setGradients
(
null
,
null
,
null
,
scenario
);
}
public
OptimalVelocityModel
()
{
}
@Override
public
void
initialize
(
List
<
Attributes
>
modelAttributesList
,
Topography
topography
,
AttributesAgent
attributesPedestrian
,
Random
random
)
{
this
.
attributesOVM
=
Model
.
findAttributes
(
modelAttributesList
,
AttributesOVM
.
class
);
AttributesCar
elementAttributes
=
topography
.
getAttributesCar
();
// Model.findAttributes(modelAttributesList, AttributesCar.class);
this
.
ovmEquations
=
new
OVMEquations
();
super
.
initializeODEModel
(
Car
.
class
,
IntegratorFactory
.
createFirstOrderIntegrator
(
attributesOVM
.
getAttributesODEIntegrator
()),
ovmEquations
,
elementAttributes
,
topography
,
random
);
ovmEquations
.
setPedestrianInteraction
(
false
);
ovmEquations
.
setModelAttributes
(
attributesOVM
);
ovmEquations
.
setGradients
(
null
,
null
,
null
,
topography
);
activeCallbacks
=
Collections
.
singletonList
(
this
);
}
@Override
/**
* Creates a single car with given attributes
*
* @param store
* @return single Car-Object
*/
public
<
T
extends
DynamicElement
>
Agent
createElement
(
VPoint
position
,
int
id
,
Class
<
T
>
type
)
{
if
(!
Car
.
class
.
isAssignableFrom
(
type
))
throw
new
IllegalArgumentException
(
"OVM cannot initialize "
+
type
.
getCanonicalName
());
carIdCounter
++;
AttributesCar
carAttributes
=
new
AttributesCar
(
elementAttributes
,
id
>
0
?
id
:
carIdCounter
);
Car
result
=
new
Car
(
carAttributes
,
random
);
result
.
setPosition
(
position
);
// result.setVelocity(result.getCarAttrributes().getDirection());
return
result
;
}
@Override
public
void
preLoop
(
final
double
simTimeInSec
)
{
super
.
preLoop
(
simTimeInSec
);
// setup thread pool if it is not setup already
int
WORKERS_COUNT
=
16
;
// pedestrians.keySet().size();
ParallelWorkerUtil
.
setup
(
WORKERS_COUNT
);
}
@Override
public
void
postLoop
(
final
double
simTimeInSec
)
{
super
.
postLoop
(
simTimeInSec
);
}
@Override
public
void
update
(
final
double
simTimeInSec
)
{
// Get all cars in the topography
Collection
<
Car
>
cars
=
topography
.
getElements
(
Car
.
class
);
// Give cars to the OVMEquations-Object
ovmEquations
.
setElements
(
cars
);
super
.
update
(
simTimeInSec
);
}
/**
* @return the attributesOVM
*/
public
AttributesOVM
getAttributesOVM
()
{
return
attributesOVM
;
}
@Override
public
List
<
ActiveCallback
>
getActiveCallbacks
()
{
return
activeCallbacks
;
}
}
VadereSimulator/src/org/vadere/simulator/projects/io/JsonConverter.java
View file @
6c2cad9b
...
...
@@ -191,7 +191,7 @@ public abstract class JsonConverter {
private
static
class
TopographyStore
{
AttributesTopography
attributes
=
new
AttributesTopography
();
AttributesAgent
attributesPedestrian
=
new
AttributesAgent
();
AttributesCar
attributesCar
;
AttributesCar
attributesCar
=
new
AttributesCar
()
;
Collection
<
AttributesObstacle
>
obstacles
=
new
LinkedList
<>();
Collection
<
AttributesStairs
>
stairs
=
new
LinkedList
<>();
Collection
<
AttributesTarget
>
targets
=
new
LinkedList
<>();
...
...
VadereState/src/org/vadere/state/scenario/Topography.java
View file @
6c2cad9b
...
...
@@ -58,13 +58,9 @@ public class Topography {
public
Topography
(
AttributesTopography
attributes
,
AttributesAgent
attributesPedestrian
,
AttributesCar
attributesCar
)
{
this
(
attributes
,
attributesPedestrian
);
this
.
attributesCar
=
attributesCar
;
}
public
Topography
(
AttributesTopography
attributes
,
AttributesAgent
attributesPedestrian
)
{
this
.
attributes
=
attributes
;
this
.
attributesPedestrian
=
attributesPedestrian
;
this
.
attributesCar
=
attributesCar
;
this
.
obstacles
=
new
LinkedList
<>();
this
.
stairs
=
new
LinkedList
<>();
this
.
sources
=
new
LinkedList
<>();
...
...
@@ -81,7 +77,7 @@ public class Topography {
* Creates an empty scenario where bounds and finishTime are empty / zero.
*/
public
Topography
()
{
this
(
new
AttributesTopography
(),
new
AttributesAgent
());
this
(
new
AttributesTopography
(),
new
AttributesAgent
()
,
new
AttributesCar
()
);
}
public
Rectangle2D
.
Double
getBounds
()
{
...
...
@@ -303,8 +299,7 @@ public class Topography {
*/
@Override
public
Topography
clone
()
{
Topography
s
=
new
Topography
(
this
.
attributes
,
this
.
attributesPedestrian
);
s
.
attributesCar
=
this
.
attributesCar
;
Topography
s
=
new
Topography
(
this
.
attributes
,
this
.
attributesPedestrian
,
this
.
attributesCar
);
for
(
Obstacle
obstacle
:
this
.
getObstacles
())
{
if
(
this
.
boundaryObstacles
.
contains
(
obstacle
))
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment