Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Simonstrator
PeerfactSim.KOM
Commits
a9baf33b
Commit
a9baf33b
authored
May 07, 2018
by
Björn Richerzhagen
Browse files
Merge remote-tracking branch 'simonstrator/tm/vehicular-services'
parents
705984e5
f476dae3
Changes
62
Show whitespace changes
Inline
Side-by-side
src/de/tud/kom/p2psim/impl/network/gnp/BitmapHeader.java
View file @
a9baf33b
...
...
@@ -27,7 +27,7 @@ import java.io.IOException;
/**
* Represents the header of a bitmap.
*
* @author Andr
�
Mink, Sebastian Kaune
* @author Andr
–
Mink, Sebastian Kaune
*/
public
class
BitmapHeader
{
public
int
nsize
;
// Size of file
...
...
src/de/tud/kom/p2psim/impl/network/gnp/BitmapLoader.java
View file @
a9baf33b
...
...
@@ -32,7 +32,7 @@ import java.util.ArrayList;
* colorTable of the bitmap. Currently, there are only 8bit bitmaps (256 colors)
* supported.
*
* @author Andr
�
Mink, Sebastian Kaune
* @author Andr
–
Mink, Sebastian Kaune
*/
public
class
BitmapLoader
{
public
int
[][]
cartesianSpace
;
...
...
src/de/tud/kom/p2psim/impl/network/gnp/geoip/regionName.java
View file @
a9baf33b
...
...
@@ -3584,7 +3584,7 @@ public class regionName {
if
(
country_code
.
equals
(
"FI"
)
==
true
)
{
switch
(
region_code2
)
{
case
1
:
name
=
"
�
land"
;
name
=
"
–
land"
;
break
;
case
6
:
name
=
"Lapland"
;
...
...
@@ -6683,7 +6683,7 @@ public class regionName {
name
=
"Aqmola"
;
break
;
case
4
:
name
=
"Aqt
�
be"
;
name
=
"Aqt
–
be"
;
break
;
case
5
:
name
=
"Astana"
;
...
...
@@ -7071,7 +7071,7 @@ public class regionName {
name
=
"Bauskas"
;
break
;
case
5
:
name
=
"C
�
su"
;
name
=
"C
–
su"
;
break
;
case
6
:
name
=
"Daugavpils"
;
...
...
@@ -7086,7 +7086,7 @@ public class regionName {
name
=
"Gulbenes"
;
break
;
case
10
:
name
=
"J
�
kabpils"
;
name
=
"J
–
kabpils"
;
break
;
case
11
:
name
=
"Jelgava"
;
...
...
@@ -7098,16 +7098,16 @@ public class regionName {
name
=
"Jurmala"
;
break
;
case
14
:
name
=
"Kr
�
slavas"
;
name
=
"Kr
–
slavas"
;
break
;
case
15
:
name
=
"Kuldigas"
;
break
;
case
16
:
name
=
"Liep
�
ja"
;
name
=
"Liep
–
ja"
;
break
;
case
17
:
name
=
"Liep
�
jas"
;
name
=
"Liep
–
jas"
;
break
;
case
18
:
name
=
"Limbazu"
;
...
...
@@ -7125,10 +7125,10 @@ public class regionName {
name
=
"Preilu"
;
break
;
case
23
:
name
=
"R
�
zekne"
;
name
=
"R
–
zekne"
;
break
;
case
24
:
name
=
"R
�
zeknes"
;
name
=
"R
–
zeknes"
;
break
;
case
25
:
name
=
"Riga"
;
...
...
src/de/tud/kom/p2psim/impl/scenario/DefaultConfigurator.java
View file @
a9baf33b
...
...
@@ -662,7 +662,7 @@ public class DefaultConfigurator implements Configurator {
}
public
String
parseValue
(
String
value
)
{
if
(
value
.
trim
().
startsWith
(
CONFIG_VARIABLE_PREFIX_TAG
))
{
if
(
value
.
trim
().
startsWith
(
CONFIG_VARIABLE_PREFIX_TAG
)
&&
!
value
.
trim
().
startsWith
(
CONFIG_VARIABLE_PREFIX_TAG
+
"{"
)
)
{
int
posDollar
=
value
.
indexOf
(
CONFIG_VARIABLE_PREFIX_TAG
);
String
varName
=
value
.
substring
(
posDollar
+
1
,
value
.
length
());
value
=
variables
.
get
(
varName
);
...
...
src/de/tud/kom/p2psim/impl/simengine/Scheduler.java
View file @
a9baf33b
...
...
@@ -44,7 +44,7 @@ import de.tudarmstadt.maki.simonstrator.api.component.core.TimeComponent;
* @author Sebastian Kaune
*/
public
class
Scheduler
implements
EventHandler
,
SchedulerComponent
,
TimeComponent
{
SchedulerComponent
,
TimeComponent
{
// Flag to allow the compiler to remove the unneeded debug code
private
static
final
boolean
DEBUG_CODE
=
false
;
...
...
@@ -449,6 +449,7 @@ public class Scheduler implements EventHandler,
*
* @return current scheduler time
*/
@Override
public
long
getCurrentTime
()
{
return
currentTime
;
}
...
...
@@ -518,6 +519,7 @@ public class Scheduler implements EventHandler,
return
simTime
;
}
@Override
public
int
compareTo
(
SchedulerEvent
o
)
{
int
comp
=
Double
.
compare
(
this
.
simTime
,
o
.
simTime
);
return
comp
==
0
?
Double
.
compare
(
this
.
globalOrderIdx
,
o
.
globalOrderIdx
)
:
comp
;
...
...
@@ -567,6 +569,10 @@ public class Scheduler implements EventHandler,
}
}
public
double
getTimeSkew
()
{
return
timeSkew
;
}
/**
* Sets the simulation speed lock, changes in setRealTime or setTimeSkew
* will not apply while the lock is set.
...
...
src/de/tud/kom/p2psim/impl/simengine/Simulator.java
View file @
a9baf33b
src/de/tud/kom/p2psim/impl/topology/DefaultTopologyComponent.java
View file @
a9baf33b
...
...
@@ -165,13 +165,42 @@ public class DefaultTopologyComponent implements TopologyComponent {
}
});
sis
.
provide
().
nodeState
(
SiSTypes
.
SPEED
,
new
SiSDataCallback
<
Double
>()
{
Set
<
INodeID
>
localID
=
INodeID
.
getSingleIDSet
(
getHost
().
getId
());
@Override
public
Double
getValue
(
INodeID
nodeID
,
SiSProviderHandle
providerHandle
)
throws
InformationNotAvailableException
{
if
(
nodeID
.
equals
(
getHost
().
getId
()))
{
return
getMovementSpeed
();
}
else
{
throw
new
InformationNotAvailableException
();
}
}
@Override
public
Set
<
INodeID
>
getObservedNodes
()
{
return
localID
;
}
@Override
public
SiSInfoProperties
getInfoProperties
()
{
return
new
SiSInfoProperties
();
}
});
// Provide Underlay topology
Event
.
scheduleImmediately
(
new
EventHandler
()
{
@Override
public
void
eventOccurred
(
Object
content
,
int
type
)
{
if
(
getHost
().
getLinkLayer
().
hasPhy
(
PhyType
.
WIFI
))
{
new
SiSTopologyProvider
(
sis
,
SiSTypes
.
NEIGHBORS_WIFI
,
new
SiSTopologyProvider
(
sis
,
SiSTypes
.
NEIGHBORS_WIFI
,
DefaultTopologyComponent
.
this
,
getTopologyID
(
NetInterfaceName
.
WIFI
,
true
),
DefaultTopologyComponent
.
class
);
...
...
src/de/tud/kom/p2psim/impl/topology/movement/RSUMovementModel.java
0 → 100755
View file @
a9baf33b
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package
de.tud.kom.p2psim.impl.topology.movement
;
import
java.util.HashMap
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Map
;
import
de.tud.kom.p2psim.api.network.SimNetInterface
;
import
de.tud.kom.p2psim.api.topology.movement.MovementModel
;
import
de.tud.kom.p2psim.api.topology.movement.SimLocationActuator
;
import
de.tud.kom.p2psim.impl.network.routed.RoutedNetLayer
;
import
de.tud.kom.p2psim.impl.topology.PositionVector
;
import
de.tud.kom.p2psim.impl.topology.movement.vehicular.sumo.simulation.controller.traci.TraciSimulationController
;
import
de.tud.kom.p2psim.impl.topology.movement.vehicular.sumo.simulation.controller.xml.XMLSimulationController
;
import
de.tudarmstadt.maki.simonstrator.api.Time
;
import
de.tudarmstadt.maki.simonstrator.api.common.graph.INodeID
;
import
de.tudarmstadt.maki.simonstrator.api.component.ComponentNotAvailableException
;
import
de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.api.SimulationSetupExtractor
;
import
de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor
;
public
class
RSUMovementModel
implements
MovementModel
{
private
final
List
<
SimLocationActuator
>
components
;
private
final
String
sumoExe
;
private
final
String
sumoConfigFile
;
private
final
String
sumoIntersections
;
private
final
int
offsetX
;
private
final
int
offsetY
;
private
final
int
width
;
private
final
int
height
;
private
final
long
timestepConversion
=
Time
.
SECOND
;
private
boolean
initialized
=
false
;
private
SimulationSetupExtractor
_controller
;
private
List
<
Location
>
_intersections
;
private
int
_currentIndex
=
0
;
private
final
Map
<
INodeID
,
Integer
>
hostIntersectionMatching
=
new
HashMap
<>();
@XMLConfigurableConstructor
({
"sumoExe"
,
"sumoConfigFile"
,
"offsetX"
,
"offsetY"
,
"width"
,
"height"
})
public
RSUMovementModel
(
String
sumoExe
,
String
sumoConfigFile
,
String
offsetX
,
String
offsetY
,
String
width
,
String
height
)
{
this
.
components
=
new
LinkedList
<>();
this
.
sumoExe
=
sumoExe
;
this
.
sumoConfigFile
=
sumoConfigFile
;
this
.
sumoIntersections
=
null
;
this
.
offsetX
=
Integer
.
parseInt
(
offsetX
);
this
.
offsetY
=
Integer
.
parseInt
(
offsetY
);
this
.
width
=
Integer
.
parseInt
(
width
);
this
.
height
=
Integer
.
parseInt
(
height
);
}
@XMLConfigurableConstructor
({
"sumoIntersections"
,
"offsetX"
,
"offsetY"
,
"width"
,
"height"
})
public
RSUMovementModel
(
String
sumoIntersections
,
String
offsetX
,
String
offsetY
,
String
width
,
String
height
)
{
this
.
components
=
new
LinkedList
<>();
this
.
sumoIntersections
=
sumoIntersections
;
this
.
sumoExe
=
null
;
this
.
sumoConfigFile
=
null
;
this
.
offsetX
=
Integer
.
parseInt
(
offsetX
);
this
.
offsetY
=
Integer
.
parseInt
(
offsetY
);
this
.
width
=
Integer
.
parseInt
(
width
);
this
.
height
=
Integer
.
parseInt
(
height
);
}
@Override
public
final
void
addComponent
(
SimLocationActuator
comp
)
{
components
.
add
(
comp
);
}
@Override
public
void
setTimeBetweenMoveOperations
(
long
time
)
{
//Do nothing, only used for placement of RSU
}
@Override
public
synchronized
void
placeComponent
(
SimLocationActuator
actuator
)
{
if
(!
initialized
)
{
initializeModel
();
initialized
=
true
;
}
if
(
_currentIndex
<
_intersections
.
size
())
{
// Initial placement
Location
intersection
=
_intersections
.
get
(
_currentIndex
);
actuator
.
updateCurrentLocation
(
new
PositionVector
(
intersection
.
getLongitude
(),
intersection
.
getLatitude
()));
hostIntersectionMatching
.
put
(
actuator
.
getHost
().
getId
(),
_currentIndex
);
_currentIndex
++;
//Put interfaces online
try
{
RoutedNetLayer
routedNetLayer
=
actuator
.
getHost
().
getComponent
(
RoutedNetLayer
.
class
);
for
(
SimNetInterface
netInterface
:
routedNetLayer
.
getSimNetworkInterfaces
())
{
if
(
netInterface
.
isOffline
())
{
netInterface
.
goOnline
();
}
}
}
catch
(
ComponentNotAvailableException
e
)
{
e
.
printStackTrace
();
}
}
else
{
actuator
.
updateCurrentLocation
(
new
PositionVector
(
Double
.
NaN
,
Double
.
NaN
));
}
}
/**
* Initializes the movement model by executing BonnMotion and parsing the
* resulting movement trace.
*/
protected
void
initializeModel
()
{
if
(
this
.
sumoExe
!=
null
)
{
_controller
=
TraciSimulationController
.
createSimulationController
(
sumoExe
,
sumoConfigFile
);
_controller
.
init
();
_controller
.
setObservedArea
(
offsetX
,
offsetY
,
offsetX
+
width
,
offsetY
+
height
);
_intersections
=
_controller
.
getAllIntersections
(
true
);
}
else
{
_controller
=
new
XMLSimulationController
(
null
,
sumoIntersections
);
_controller
.
init
();
_controller
.
setObservedArea
(
offsetX
,
offsetY
,
offsetX
+
width
,
offsetY
+
height
);
_intersections
=
_controller
.
getAllIntersections
(
true
);
}
// System.out.println("Require " + _intersections.size() + " RSUs");
}
}
\ No newline at end of file
src/de/tud/kom/p2psim/impl/topology/movement/SumoTraceMovementModel.java
0 → 100644
View file @
a9baf33b
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package
de.tud.kom.p2psim.impl.topology.movement
;
import
java.io.IOException
;
import
java.nio.charset.Charset
;
import
java.nio.file.Files
;
import
java.nio.file.Paths
;
import
java.util.LinkedHashMap
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Queue
;
import
java.util.stream.Stream
;
import
de.tud.kom.p2psim.api.topology.movement.MovementModel
;
import
de.tud.kom.p2psim.api.topology.movement.SimLocationActuator
;
import
de.tud.kom.p2psim.impl.topology.PositionVector
;
import
de.tudarmstadt.maki.simonstrator.api.Event
;
import
de.tudarmstadt.maki.simonstrator.api.EventHandler
;
import
de.tudarmstadt.maki.simonstrator.api.Time
;
import
de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor
;
public
class
SumoTraceMovementModel
implements
MovementModel
,
EventHandler
{
private
long
timeBetweenMoveOperations
;
private
final
List
<
SimLocationActuator
>
components
;
private
final
Map
<
SimLocationActuator
,
Queue
<
Step
>>
movements
;
private
final
String
tracefile
;
private
final
long
timestepConversion
=
Time
.
SECOND
;
private
boolean
initialized
=
false
;
@XMLConfigurableConstructor
({
"timeBetweenMoveOperations"
,
"tracefile"
})
public
SumoTraceMovementModel
(
long
timeBetweenMoveOperations
,
String
tracefile
)
{
this
.
timeBetweenMoveOperations
=
timeBetweenMoveOperations
;
this
.
components
=
new
LinkedList
<>();
this
.
movements
=
new
LinkedHashMap
<>();
this
.
tracefile
=
tracefile
;
}
@Override
public
final
void
addComponent
(
SimLocationActuator
comp
)
{
components
.
add
(
comp
);
}
public
long
getTimeBetweenMoveOperations
()
{
return
timeBetweenMoveOperations
;
}
@Override
public
void
setTimeBetweenMoveOperations
(
long
time
)
{
this
.
timeBetweenMoveOperations
=
time
;
}
@Override
public
void
placeComponent
(
SimLocationActuator
actuator
)
{
if
(!
initialized
)
{
initializeModel
();
initialized
=
true
;
}
// Initial placement
actuator
.
updateCurrentLocation
(
new
PositionVector
(
5
,
5
));
}
/**
* Initializes the movement model by executing BonnMotion and parsing the
* resulting movement trace.
*/
protected
void
initializeModel
()
{
// Schedule first step
Event
.
scheduleWithDelay
(
timeBetweenMoveOperations
,
this
,
null
,
0
);
// Read the if-file (.if)
try
(
Stream
<
String
>
lines
=
Files
.
lines
(
Paths
.
get
(
tracefile
),
Charset
.
defaultCharset
()))
{
lines
.
forEachOrdered
(
line
->
process
(
line
));
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
System
.
out
.
println
(
"Initialization: done."
);
}
/**
* Invoked for each line within the input file. A line consists of the
* following data, separated by a space:
*
* Node-ID Timestamp X-Coordinate Y-Coordinate
*
* @param line
*/
protected
void
process
(
String
line
)
{
String
[]
step
=
line
.
split
(
" "
);
int
nodeId
=
Integer
.
valueOf
(
step
[
0
]);
//assert nodeId < components.size();
long
time
=
Long
.
valueOf
(
step
[
1
]);
double
x
=
Double
.
valueOf
(
step
[
2
]);
double
y
=
Double
.
valueOf
(
step
[
3
]);
if
(
nodeId
>=
components
.
size
())
{
return
;
}
// TODO make SUMO trace offsets configurable.
time
-=
21600
;
x
-=
10000
;
y
-=
10000
;
x
/=
10
;
y
/=
10
;
SimLocationActuator
comp
=
components
.
get
(
nodeId
);
Queue
<
Step
>
steps
=
movements
.
get
(
comp
);
if
(
steps
==
null
)
{
steps
=
new
LinkedList
<>();
movements
.
put
(
comp
,
steps
);
}
steps
.
add
(
new
Step
(
time
,
x
,
y
));
}
@Override
public
void
eventOccurred
(
Object
content
,
int
type
)
{
/*
* One event for all nodes (synchronized movement), as this boosts
* simulation performance due to less recalculations in the network
* models.
*/
long
currentTime
=
Time
.
getCurrentTime
()
/
timestepConversion
;
movements
.
forEach
((
component
,
steps
)
->
{
Step
step
=
null
;
Step
nextStep
=
null
;
do
{
step
=
steps
.
peek
();
nextStep
=
null
;
// Valid step
if
(
step
!=
null
&&
step
.
timestamp
<=
currentTime
)
{
step
=
steps
.
poll
();
// Look ahead, maybe we need to skip?
nextStep
=
steps
.
peek
();
}
}
while
(
step
!=
null
&&
nextStep
!=
null
&&
nextStep
.
timestamp
<
currentTime
);
if
(
step
!=
null
)
{
component
.
updateCurrentLocation
(
new
PositionVector
(
step
.
x
,
step
.
y
));
// System.out.println("Set component "+component.getHost().getId()+" location to "+step.x+","+step.y);
}
});
// Reschedule next step
Event
.
scheduleWithDelay
(
timeBetweenMoveOperations
,
this
,
null
,
0
);
}
/**
* A Step.
*
* @author Bjoern Richerzhagen
*
*/
private
class
Step
{
public
final
double
x
;
public
final
double
y
;
public
final
long
timestamp
;
public
Step
(
long
timestamp
,
double
x
,
double
y
)
{
this
.
x
=
x
;
this
.
y
=
y
;
this
.
timestamp
=
timestamp
;
}
}
}
\ No newline at end of file
src/de/tud/kom/p2psim/impl/topology/movement/VehicleMovementModel.java
0 → 100644
View file @
a9baf33b
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package
de.tud.kom.p2psim.impl.topology.movement
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Queue
;
import
java.util.Random
;
import
de.tud.kom.p2psim.api.network.SimNetInterface
;
import
de.tud.kom.p2psim.api.topology.movement.MovementModel
;
import
de.tud.kom.p2psim.api.topology.movement.SimLocationActuator
;
import
de.tud.kom.p2psim.impl.network.routed.RoutedNetLayer
;
import
de.tud.kom.p2psim.impl.topology.PositionVector
;
import
de.tud.kom.p2psim.impl.topology.movement.vehicular.sumo.simulation.controller.traci.TraciSimulationController
;
import
de.tud.kom.p2psim.impl.topology.movement.vehicular.sumo.simulation.controller.xml.XMLSimulationController
;
import
de.tud.kom.p2psim.impl.vehicular.DefaultVehicleInformationComponent
;
import
de.tudarmstadt.maki.simonstrator.api.Event
;
import
de.tudarmstadt.maki.simonstrator.api.EventHandler
;
import
de.tudarmstadt.maki.simonstrator.api.Host
;
import
de.tudarmstadt.maki.simonstrator.api.Randoms
;
import
de.tudarmstadt.maki.simonstrator.api.Time
;
import
de.tudarmstadt.maki.simonstrator.api.common.graph.INodeID
;
import
de.tudarmstadt.maki.simonstrator.api.component.ComponentNotAvailableException
;
import
de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.VehicleInformationComponent
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.api.SimulationSetupExtractor
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.api.VehicleController
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetwork
;
import
de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor
;
public
class
VehicleMovementModel
implements
MovementModel
,
EventHandler
{
private
Random
_knownRoutesRandom
=
Randoms
.
getRandom
(
getClass
());
private
static
final
Location
DEFAULT_LOCATION
=
new
PositionVector
(
Double
.
NaN
,
Double
.
NaN
);
private
boolean
_reuseComponents
=
false
;
private
static
VehicleMovementModel
MOVEMENT
;
private
long
timeBetweenMoveOperations
;
private
final
List
<
SimLocationActuator
>
components
;
private
final
Queue
<
SimLocationActuator
>
freeComponents
;
private
final
Map
<
String
,
SimLocationActuator
>
idComponentMatcher
;
private
final
Map
<
INodeID
,
String
>
hostVehicleIDMatching
=
new
HashMap
<>();
private
final
int
offsetX
;
private
final
int
offsetY
;
private
final
int
width
;
private
final
int
height
;
private
double
scenarioWidth
=
0
;
private
double
scenarioHeight
=
0
;
private
final
String
sumoExe
;
private
final
String
sumoConfigFile
;
private
final
String
sumoTrace
;
private
String
sumoIntersections
;
private
final
long
timestepConversion
=
Time
.
SECOND
;
private
boolean
initialized
=
false
;
private
VehicleController
_controller
;
private
SimulationSetupExtractor
_extractor
;
private
double
_percentageOfKnownRoutes
=
1
;
/**
* Constructor for the movement model using the sumo TraCI API
* @param timeBetweenMoveOperations The time between two movement operations.
* @param sumoExe The path to the executable of sumo
* @param sumoConfigFile The path to the configuration file of the scenario
* @param offsetX The offset that should be used. If no offset is required, offset 0 shall be used.
* @param offsetY The offset that should be used. If no offset is required, offset 0 shall be used.
* @param width The width of the scenario.
* @param height The height of the scenario.
*/
@XMLConfigurableConstructor
({
"timeBetweenMoveOperations"
,
"sumoExe"
,
"sumoConfigFile"
,
"offsetX"
,
"offsetY"
,
"width"
,
"height"
})
public
VehicleMovementModel
(
long
timeBetweenMoveOperations
,
String
sumoExe
,
String
sumoConfigFile
,
String
offsetX
,
String
offsetY
,
String
width
,
String
height
)
{
MOVEMENT
=
this
;
this
.
timeBetweenMoveOperations
=
timeBetweenMoveOperations
;
this
.
components
=
new
LinkedList
<>();
this
.
freeComponents
=
new
LinkedList
<>();
this
.
idComponentMatcher
=
new
HashMap
<>();
this
.
sumoExe
=
sumoExe
;
this
.
sumoConfigFile
=
sumoConfigFile
;
this
.
sumoTrace
=
null
;
this
.
offsetX
=
Integer
.
parseInt
(
offsetX
);
this
.
offsetY
=
Integer
.
parseInt
(
offsetY
);
this
.
width
=
Integer
.
parseInt
(
width
);
this
.
height
=
Integer
.
parseInt
(
height
);
}
/**
* Constructor for the movement model using the a generated sumo trace file
* @param timeBetweenMoveOperations The time between two movement operations.
* @param sumoTrace The path to the vehicle movement file (*.xml)
* @param sumoIntersections The path to the intersections file (*.csv)
* @param offsetX The offset that should be used. If no offset is required, offset 0 shall be used.
* @param offsetY The offset that should be used. If no offset is required, offset 0 shall be used.
* @param width The width of the scenario.
* @param height The height of the scenario.
*/
@XMLConfigurableConstructor
({
"timeBetweenMoveOperations"
,
"sumoTrace"
,
"sumoIntersections"
,
"offsetX"
,
"offsetY"
,
"width"
,
"height"
})
public
VehicleMovementModel
(
long
timeBetweenMoveOperations
,
String
sumoTrace
,
String
sumoIntersections
,
int
offsetX
,
int
offsetY
,
int
width
,
int
height
)
{
MOVEMENT
=
this
;
this
.
timeBetweenMoveOperations
=
timeBetweenMoveOperations
;
this
.
components
=
new
LinkedList
<>();
this
.
freeComponents
=
new
LinkedList
<>();
this
.
idComponentMatcher
=
new
HashMap
<>();
this
.
sumoExe
=
null
;
this
.
sumoConfigFile
=
null
;
this
.
sumoTrace
=
sumoTrace
;
this
.
sumoIntersections
=
sumoIntersections
;
this
.
offsetX
=
offsetX
;
this
.
offsetY
=
offsetY
;
this
.
width
=
width
;
this
.
height
=
height
;
}
/**
* @param pPercentageOfKnownRoutes the percentageOfKnownRoutes to set
*/
public
void
setPercentageOfKnownRoutes
(
double
pPercentageOfKnownRoutes
)
{
_percentageOfKnownRoutes
=
pPercentageOfKnownRoutes
;
}
public
void
setReuseComponents
(
boolean
pReuseComponents
)
{
_reuseComponents
=
pReuseComponents
;
if
(
_reuseComponents
)
{
System
.
err
.
println
(
"WARNING: Enabling the reuse of components might cause strange behaviors of your simulation!"
);
}
}
/**
* Adding an additional component to be moved by this movement model
* @param comp The component to be added.
*/
@Override
public
final
void
addComponent
(
SimLocationActuator
comp
)
{
components
.
add
(
comp
);
freeComponents
.
add
(
comp
);
comp
.
updateCurrentLocation
(
DEFAULT_LOCATION
);
}
/**
* Returns the time between movement operations
* @return time between movement operations
*/
public
long
getTimeBetweenMoveOperations
()
{
return
timeBetweenMoveOperations
;
}
/**
* Set the time between movement operations
* @param time the time between movement operations
*/
@Override
public
void
setTimeBetweenMoveOperations
(
long
time
)
{
this
.
timeBetweenMoveOperations
=
time
;
}
/**
* Place a component at the correct location
* @param actuator The component to be placed.
*/
@Override
public
void
placeComponent
(
SimLocationActuator
actuator
)
{
if
(!
initialized
)
{
initializeModel
();
VehicleMovementModel
.
getRoadNetwork
();
initialized
=
true
;
}
// Initial placement
actuator
.
updateCurrentLocation
(
DEFAULT_LOCATION
);
}
/**
* Initializes the movement model by executing BonnMotion and parsing the
* resulting movement trace.
*/
protected
void
initializeModel
()
{
// Schedule first step
if
(!
initialized
)
{
Event
.
scheduleWithDelay
(
timeBetweenMoveOperations
,
this
,
null
,
0
);
if
(
sumoExe
!=
null
)
{
TraciSimulationController
simulationController
=
TraciSimulationController
.
createSimulationController
(
sumoExe
,
sumoConfigFile
);
_controller
=
simulationController
;
_controller
.
setObservedArea
(
offsetX
,
offsetY
,
offsetX
+
width
,
offsetY
+
height
);
_controller
.
init
();
_controller
.
nextStep
();
_extractor
=
simulationController
;
}
else
{
XMLSimulationController
simulationController
;
if
(
sumoIntersections
==
null
||
sumoIntersections
.
equals
(
""
))
{
simulationController
=
new
XMLSimulationController
(
sumoTrace
);
}
else
{
simulationController
=
new
XMLSimulationController
(
sumoTrace
,
sumoIntersections
);
}
_controller
=
simulationController
;
_controller
.
setObservedArea
(
offsetX
,
offsetY
,
offsetX
+
width
,
offsetY
+
height
);
_controller
.
init
();
_controller
.
nextStep
();
_extractor
=
simulationController
;
}
scenarioWidth
=
_extractor
.
getScenarioWidth
();
scenarioHeight
=
_extractor
.
getScenarioHeight
();
System
.
out
.
println
(
"Initialization: done."
);
}
}
/**
* Used for the periodical updates of the vehicle positions
* @param content not used in this case, should be null
* @param type not used in this case, should be 0
*/
@Override
public
void
eventOccurred
(
Object
content
,
int
type
)
{
/*
* One event for all nodes (synchronized movement), as this boosts
* simulation performance due to less recalculations in the network
* models.
*/
long
currentTime
=
Time
.
getCurrentTime
()
/
timestepConversion
;
while
(
_controller
.
getStep
()
-
_controller
.
getStart
()
<
currentTime
)
{
if
(!
_controller
.
nextStep
())
{
return
;
}
}
List
<
String
>
allVehicles
=
_controller
.
getAllVehicles
();
for
(
int
i
=
0
;
i
<
allVehicles
.
size
();
i
++)
{
String
vehicle
=
allVehicles
.
get
(
i
);
Location
position
=
_controller
.
getVehiclePosition
(
vehicle
);
if
(
position
==
null
)
{
allVehicles
.
remove
(
i
--);
continue
;
}
SimLocationActuator
component
=
requestSimActuator
(
vehicle
);
try
{
RoutedNetLayer
routedNetLayer
=
component
.
getHost
().
getComponent
(
RoutedNetLayer
.
class
);
for
(
SimNetInterface
netInterface
:
routedNetLayer
.
getSimNetworkInterfaces
())
{
if
(
netInterface
.
isOffline
())
{
netInterface
.
goOnline
();
}
}
}
catch
(
ComponentNotAvailableException
e
)
{
e
.
printStackTrace
();
}
component
.
updateCurrentLocation
(
new
PositionVector
(
position
.
getLongitude
(),
position
.
getLatitude
()));
component
.
setMovementSpeed
(
_controller
.
getVehicleSpeed
(
vehicle
));
}
if
(
allVehicles
.
size
()
!=
idComponentMatcher
.
size
())
{
ArrayList
<
String
>
registeredVehicles
=
new
ArrayList
<>(
idComponentMatcher
.
keySet
());
for
(
int
i
=
0
;
i
<
registeredVehicles
.
size
();
i
++)
{
String
vehicle
=
registeredVehicles
.
get
(
i
);
if
(!
allVehicles
.
contains
(
vehicle
))
{
addFreeHost
(
vehicle
);
}
}
}
if
(
Time
.
getCurrentTime
()
<
5
*
Time
.
SECOND
)
{
for
(
SimLocationActuator
simLocationActuator
:
freeComponents
)
{
simLocationActuator
.
updateCurrentLocation
(
DEFAULT_LOCATION
);
}
}
// Reschedule next step
Event
.
scheduleWithDelay
(
timeBetweenMoveOperations
,
this
,
null
,
0
);
}
/**
* Remove a vehicle from the set of moved components as the vehicle has stopped driving
* @param vehicleID The stopped vehicle
*/
private
void
addFreeHost
(
String
vehicleID
)
{
if
(
idComponentMatcher
.
containsKey
(
vehicleID
))
{
SimLocationActuator
simLocationActuator
=
idComponentMatcher
.
remove
(
vehicleID
);
if
(
simLocationActuator
!=
null
)
{
try
{
VehicleInformationComponent
vehicularHostComponent
=
simLocationActuator
.
getHost
().
getComponent
(
VehicleInformationComponent
.
class
);
vehicularHostComponent
.
resetVehicleID
();
}
catch
(
ComponentNotAvailableException
e
)
{
// Nothing to do here
}
hostVehicleIDMatching
.
remove
(
simLocationActuator
.
getHost
().
getId
());
try
{
RoutedNetLayer
routedNetLayer
=
simLocationActuator
.
getHost
().
getComponent
(
RoutedNetLayer
.
class
);
for
(
SimNetInterface
netInterface
:
routedNetLayer
.
getSimNetworkInterfaces
())
{
if
(
netInterface
.
isOnline
())
{
netInterface
.
goOffline
();
}
}
}
catch
(
ComponentNotAvailableException
e
)
{
e
.
printStackTrace
();
}
simLocationActuator
.
updateCurrentLocation
(
DEFAULT_LOCATION
);
if
(
_reuseComponents
)
{
freeComponents
.
add
(
simLocationActuator
);
}
}
}
}
/**
* Request a component for a vehicle. If no component has been assigned to the vehicle yet, a new component is assigned.
* @param vehicle The vehicle for which a component is requested.
* @throws RuntimeException If no component can be assigned.
* @return The component for the vehicle.
*/
private
SimLocationActuator
requestSimActuator
(
String
vehicle
)
{
if
(!
idComponentMatcher
.
containsKey
(
vehicle
))
{
SimLocationActuator
simLocationActuator
=
freeComponents
.
poll
();
if
(
simLocationActuator
!=
null
)
{
VehicleInformationComponent
vehicularHostComponent
;
try
{
vehicularHostComponent
=
simLocationActuator
.
getHost
().
getComponent
(
VehicleInformationComponent
.
class
);
}
catch
(
ComponentNotAvailableException
e
)
{
Host
host
=
simLocationActuator
.
getHost
();
boolean
routeKnown
;
if
(
_knownRoutesRandom
.
nextDouble
()
<
_percentageOfKnownRoutes
)
{
routeKnown
=
true
;
}
else
{
routeKnown
=
false
;
}
vehicularHostComponent
=
new
DefaultVehicleInformationComponent
(
host
,
_controller
,
_extractor
,
routeKnown
);
host
.
registerComponent
(
vehicularHostComponent
);
}
vehicularHostComponent
.
setVehicleID
(
vehicle
);
idComponentMatcher
.
put
(
vehicle
,
simLocationActuator
);
hostVehicleIDMatching
.
put
(
simLocationActuator
.
getHost
().
getId
(),
vehicle
);
}
else
{
throw
new
RuntimeException
(
"Unable to assign new components. Please increase node amount"
+
(
_reuseComponents
?
"."
:
" or enable the reuse of components."
));
}
}
return
idComponentMatcher
.
get
(
vehicle
);
}
public
static
RoadNetwork
getRoadNetwork
()
{
return
MOVEMENT
.
_extractor
.
getRoadNetwork
();
}
}
src/de/tud/kom/p2psim/impl/topology/movement/vehicular/sumo/simulation/controller/SimulationSetupInformationProvider.java
0 → 100755
View file @
a9baf33b
package
de.tud.kom.p2psim.impl.topology.movement.vehicular.sumo.simulation.controller
;
import
java.io.FileInputStream
;
import
java.io.IOException
;
import
javax.xml.parsers.ParserConfigurationException
;
import
javax.xml.parsers.SAXParser
;
import
javax.xml.parsers.SAXParserFactory
;
import
org.xml.sax.SAXException
;
import
de.tud.kom.p2psim.impl.topology.movement.vehicular.sumo.simulation.controller.xml.CancelParsingSAXException
;
import
de.tud.kom.p2psim.impl.topology.movement.vehicular.sumo.simulation.controller.xml.SimulationSetupInformationHandler
;
import
de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location
;
public
class
SimulationSetupInformationProvider
{
private
static
final
SimulationSetupInformationProvider
ONLY_INSTANCE
=
new
SimulationSetupInformationProvider
();
private
SimulationSetupInformationHandler
_handler
=
new
SimulationSetupInformationHandler
();
private
SimulationSetupInformationProvider
()
{
}
public
static
SimulationSetupInformationProvider
getOnlyInstance
()
{
return
ONLY_INSTANCE
;
}
public
Location
getUpperLeft
()
{
return
_handler
.
getUpperLeft
();
}
public
Location
getLowerRight
()
{
return
_handler
.
getLowerRight
();
}
public
static
void
init
(
String
pNetFileLocation
)
{
try
{
SAXParser
parser
=
SAXParserFactory
.
newInstance
().
newSAXParser
();
parser
.
parse
(
new
FileInputStream
(
pNetFileLocation
),
ONLY_INSTANCE
.
_handler
);
}
catch
(
CancelParsingSAXException
e
)
{
return
;
}
catch
(
ParserConfigurationException
|
SAXException
|
IOException
e
)
{
e
.
printStackTrace
();
}
}
}
src/de/tud/kom/p2psim/impl/topology/movement/vehicular/sumo/simulation/controller/VehicleInformationContainer.java
0 → 100755
View file @
a9baf33b
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package
de.tud.kom.p2psim.impl.topology.movement.vehicular.sumo.simulation.controller
;
import
de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkRoute
;
public
class
VehicleInformationContainer
{
private
Location
_position
;
private
double
_heading
;
private
double
_speed
;
private
RoadNetworkRoute
_route
;
public
VehicleInformationContainer
(
Location
pPosition
,
double
pHeading
,
double
pSpeed
,
RoadNetworkRoute
pRoute
)
{
_position
=
pPosition
;
_heading
=
pHeading
;
_speed
=
pSpeed
;
_route
=
pRoute
;
}
public
Location
getPosition
()
{
return
_position
;
}
public
double
getHeading
()
{
return
_heading
;
}
public
double
getSpeed
()
{
return
_speed
;
}
public
RoadNetworkRoute
getRoute
()
{
return
_route
;
}
}
\ No newline at end of file
src/de/tud/kom/p2psim/impl/topology/movement/vehicular/sumo/simulation/controller/csv/RoadSideUnitInformationHandler.java
0 → 100755
View file @
a9baf33b
package
de.tud.kom.p2psim.impl.topology.movement.vehicular.sumo.simulation.controller.csv
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileNotFoundException
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Scanner
;
import
de.tud.kom.p2psim.impl.topology.PositionVector
;
import
de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location
;
public
class
RoadSideUnitInformationHandler
{
private
List
<
Location
>
_positions
=
new
ArrayList
<>();
private
boolean
_observedAreaSet
=
false
;
private
double
_startX
=
-
1
;
private
double
_startY
=
-
1
;
private
double
_endX
=
-
1
;
private
double
_endY
=
-
1
;
public
List
<
Location
>
getIntersections
()
{
if
(!
_observedAreaSet
)
{
return
_positions
;
}
else
{
List
<
Location
>
result
=
new
ArrayList
<>();
for
(
Location
position
:
_positions
)
{
if
(
_startX
<=
position
.
getLongitude
()
&&
position
.
getLongitude
()
<=
_endX
&&
_startY
<=
position
.
getLatitude
()
&&
position
.
getLatitude
()
<=
_endY
)
{
result
.
add
(
new
PositionVector
(
position
.
getLongitude
()
-
_startX
,
position
.
getLatitude
()
-
_startY
,
0
));
}
}
return
result
;
}
}
public
void
parseIntersectionsFile
(
String
pRoadSideUnitDataPath
)
{
File
file
=
new
File
(
pRoadSideUnitDataPath
);
try
{
FileInputStream
inputStream
=
new
FileInputStream
(
file
);
Scanner
scanner
=
new
Scanner
(
inputStream
);
while
(
scanner
.
hasNextLine
())
{
String
line
=
scanner
.
nextLine
();
if
(
line
.
contains
(
";"
))
{
String
[]
split
=
line
.
split
(
";"
);
if
(
split
.
length
==
2
)
{
double
x
=
Double
.
parseDouble
(
split
[
0
]);
double
y
=
Double
.
parseDouble
(
split
[
1
]);
_positions
.
add
(
new
PositionVector
(
x
,
y
,
0
));
}
}
}
scanner
.
close
();
}
catch
(
FileNotFoundException
e
)
{
System
.
err
.
println
(
"Unable to read file "
+
e
.
getMessage
());
}
}
public
void
setObservedArea
(
double
pStartX
,
double
pStartY
,
double
pEndX
,
double
pEndY
)
{
_startX
=
pStartX
;
_startY
=
pStartY
;
_endX
=
pEndX
;
_endY
=
pEndY
;
_observedAreaSet
=
true
;
}
}
src/de/tud/kom/p2psim/impl/topology/movement/vehicular/sumo/simulation/controller/traci/TraciSimulationController.java
0 → 100755
View file @
a9baf33b
package
de.tud.kom.p2psim.impl.topology.movement.vehicular.sumo.simulation.controller.traci
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileOutputStream
;
import
java.io.IOException
;
import
java.io.ObjectInputStream
;
import
java.io.ObjectOutputStream
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Random
;
import
de.tud.kom.p2psim.api.simengine.SimulatorObserver
;
import
de.tud.kom.p2psim.impl.simengine.Simulator
;
import
de.tud.kom.p2psim.impl.topology.PositionVector
;
import
de.tud.kom.p2psim.impl.topology.movement.vehicular.sumo.simulation.controller.VehicleInformationContainer
;
import
de.tudarmstadt.maki.simonstrator.api.Randoms
;
import
de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.api.EdgeController
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.api.SimulationSetupExtractor
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.api.VehicleController
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.api.information.LocationUtils
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetwork
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkEdge
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkLane
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkRoute
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.SerializableRoadNetwork
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.exception.NoAdditionalRouteAvailableException
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.exception.NoExitAvailableException
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.routing.DijkstraAlgorithm
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.routing.RoutingAlgorithm
;
import
de.tudresden.sumo.cmd.Edge
;
import
de.tudresden.sumo.cmd.Junction
;
import
de.tudresden.sumo.cmd.Lane
;
import
de.tudresden.sumo.cmd.Simulation
;
import
de.tudresden.sumo.cmd.Vehicle
;
import
de.tudresden.sumo.util.SumoCommand
;
import
de.tudresden.ws.container.SumoBoundingBox
;
import
de.tudresden.ws.container.SumoGeometry
;
import
de.tudresden.ws.container.SumoLink
;
import
de.tudresden.ws.container.SumoLinkList
;
import
de.tudresden.ws.container.SumoPosition2D
;
import
de.tudresden.ws.container.SumoStringList
;
import
edu.emory.mathcs.backport.java.util.Collections
;
import
it.polito.appeal.traci.SumoTraciConnection
;
/**
*
* @author Tobias Meuser (tobias.meuser@kom.tu-darmstadt.de)
* @version 1.0 at 06.11.2017
*
*/
public
class
TraciSimulationController
implements
VehicleController
,
SimulationSetupExtractor
,
EdgeController
,
SimulatorObserver
{
private
static
final
File
TEMP_FILE
=
new
File
(
new
File
(
System
.
getProperty
(
"java.io.tmpdir"
)),
"road_network.tmp"
);
private
Random
_random
=
Randoms
.
getRandom
(
getClass
());
private
static
final
Map
<
String
,
TraciSimulationController
>
CONTROLLER
=
new
HashMap
<>();
private
static
final
double
CLUSTERING_DISTANCE
=
50
;
private
String
_sumoExe
;
private
String
_configFile
;
private
SumoTraciConnection
_connection
;
private
double
_start
=
-
1
;
private
double
_step
=
-
1
;
private
double
_startX
;
private
double
_startY
;
private
double
_endX
;
private
double
_endY
;
private
Map
<
String
,
VehicleInformationContainer
>
_positons
=
new
HashMap
<>();
private
boolean
_initalized
=
false
;
private
boolean
_observedAreaSet
;
private
Map
<
String
,
Double
>
_vehiclesOutOfRange
=
new
HashMap
<>();
private
RoadNetwork
_roadNetwork
;
private
RoutingAlgorithm
_algorithm
=
new
DijkstraAlgorithm
();
public
static
synchronized
TraciSimulationController
createSimulationController
(
String
pSumoExe
,
String
pConfigFile
)
{
if
(!
CONTROLLER
.
containsKey
(
pConfigFile
))
{
CONTROLLER
.
put
(
pConfigFile
,
new
TraciSimulationController
(
pSumoExe
,
pConfigFile
));
}
return
CONTROLLER
.
get
(
pConfigFile
);
}
private
TraciSimulationController
(
String
pSumoExe
,
String
pConfigFile
)
{
_sumoExe
=
pSumoExe
;
_configFile
=
pConfigFile
;
}
public
static
VehicleController
getSimulationController
()
{
return
CONTROLLER
.
values
().
iterator
().
next
();
}
@Override
public
synchronized
void
init
()
{
if
(!
_initalized
)
{
Random
random
=
Randoms
.
getRandom
(
"SUMO"
);
// This will only work with the updated version of the TraaS API for sumo
// It is available for download at https://dev.kom.e-technik.tu-darmstadt.de/gitlab/tobiasm/TraaS.git
_connection
=
new
SumoTraciConnection
(
_sumoExe
,
_configFile
,
random
.
nextInt
());
/*
* prevent vehicles form teleporting (http://sumo.dlr.de/wiki/Simulation/Why_Vehicles_are_teleporting)
*/
_connection
.
addOption
(
"time-to-teleport"
,
Integer
.
toString
(-
1
));
try
{
_connection
.
runServer
();
}
catch
(
RuntimeException
e
)
{
throw
e
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
Simulator
.
getInstance
().
addObserver
(
this
);
_initalized
=
true
;
}
}
@Override
public
void
simulationFinished
()
{
/*
* This is called by the simulation scheduler once the simulation is
* finished - it should be used to terminate the connection to SUMO.
*/
if
(
_connection
!=
null
&&
!
_connection
.
isClosed
())
{
_connection
.
close
();
}
}
@Override
public
Location
getVehiclePosition
(
String
pVehicleID
)
{
return
_positons
.
get
(
pVehicleID
).
getPosition
();
}
@Override
public
double
getVehicleHeading
(
String
pVehicleID
)
{
return
_positons
.
get
(
pVehicleID
).
getHeading
();
}
@Override
public
Location
getVehiclePosition
(
double
pStep
,
String
pVehicleID
)
{
if
(
pStep
==
_step
)
{
return
getVehiclePosition
(
pVehicleID
);
}
throw
new
UnsupportedOperationException
(
"Future locations is not supported anymore!"
);
}
@Override
public
List
<
Location
>
getAllIntersections
(
boolean
pCluster
)
{
List
<
Location
>
result
=
new
ArrayList
<>();
SumoCommand
intersectionCommand
=
Junction
.
getIDList
();
Object
intersectionObject
=
requestObject
(
intersectionCommand
);
SumoStringList
intersections
=
(
SumoStringList
)
intersectionObject
;
for
(
String
intersection
:
intersections
)
{
SumoCommand
positionCommand
=
Junction
.
getPosition
(
intersection
);
Object
positionObject
=
requestObject
(
positionCommand
);
SumoPosition2D
sumoPosition
=
(
SumoPosition2D
)
positionObject
;
if
(
_observedAreaSet
)
{
if
(
_startX
<=
sumoPosition
.
x
&&
sumoPosition
.
x
<=
_endX
&&
_startY
<=
sumoPosition
.
y
&&
sumoPosition
.
y
<=
_endY
)
{
result
.
add
(
new
PositionVector
(
sumoPosition
.
x
-
_startX
,
sumoPosition
.
y
-
_startY
,
0
));
}
}
else
{
result
.
add
(
new
PositionVector
(
sumoPosition
.
x
,
sumoPosition
.
y
,
0
));
}
}
if
(
pCluster
)
{
List
<
Location
>
tempResult
=
new
ArrayList
<>();
outer:
for
(
int
i
=
0
;
i
<
result
.
size
();
i
++)
{
Location
position
=
result
.
get
(
i
);
for
(
int
j
=
0
;
j
<
tempResult
.
size
();
j
++)
{
Location
addedPosition
=
tempResult
.
get
(
j
);
if
(
position
!=
addedPosition
&&
LocationUtils
.
calculateDistance
(
position
,
addedPosition
)
<
CLUSTERING_DISTANCE
/
1000.0
)
{
continue
outer
;
}
}
tempResult
.
add
(
position
);
}
result
=
tempResult
;
}
return
result
;
}
@Override
public
boolean
nextStep
()
{
if
(
Simulator
.
getEndTime
()
==
Simulator
.
getCurrentTime
())
{
return
false
;
}
try
{
_connection
.
do_timestep
();
try
{
synchronized
(
_positons
)
{
_positons
.
clear
();
int
temp
=
(
Integer
)
_connection
.
do_job_get
(
Simulation
.
getCurrentTime
());
_step
=
temp
/
1000.0
;
if
(
_start
==
-
1
)
{
_start
=
_step
;
}
Map
<
String
,
VehicleInformationContainer
>
vehiclePositions
=
new
HashMap
<>();
List
<
String
>
allVehicles
=
requestAllVehicles
();
for
(
String
vehicle
:
allVehicles
)
{
Location
position
=
requestVehiclePosition
(
vehicle
);
if
(
position
!=
null
)
{
double
heading
=
requestVehicleHeading
(
vehicle
);
double
speed
=
requestVehicleSpeed
(
vehicle
);
RoadNetworkRoute
route
=
requestVehicleRoute
(
vehicle
);
VehicleInformationContainer
informationContainer
=
new
VehicleInformationContainer
(
position
,
heading
,
speed
,
route
);
vehiclePositions
.
put
(
vehicle
,
informationContainer
);
}
}
_positons
=
vehiclePositions
;
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
true
;
}
catch
(
RuntimeException
e
)
{
throw
e
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
false
;
}
private
Location
requestVehiclePosition
(
String
pVehicleID
)
{
if
(
_vehiclesOutOfRange
.
containsKey
(
pVehicleID
))
{
if
(
_vehiclesOutOfRange
.
get
(
pVehicleID
)
<
_step
)
{
return
null
;
}
else
{
_vehiclesOutOfRange
.
remove
(
pVehicleID
);
}
}
SumoCommand
positionCommand
=
Vehicle
.
getPosition
(
pVehicleID
);
Object
positionObject
=
requestObject
(
positionCommand
);
SumoPosition2D
sumoPosition
=
(
SumoPosition2D
)
positionObject
;
if
(
_observedAreaSet
)
{
if
(
_startX
<=
sumoPosition
.
x
&&
sumoPosition
.
x
<=
_endX
&&
_startY
<=
sumoPosition
.
y
&&
sumoPosition
.
y
<=
_endY
)
{
return
new
PositionVector
(
sumoPosition
.
x
-
_startX
,
sumoPosition
.
y
-
_startY
,
0
);
}
else
{
double
diffX
=
_startX
-
sumoPosition
.
x
;
if
(
diffX
<
0
||
sumoPosition
.
x
-
_endX
<
diffX
)
{
diffX
=
sumoPosition
.
x
-
_endX
;
}
if
(
diffX
<
0
)
{
diffX
=
0
;
}
double
diffY
=
_startY
-
sumoPosition
.
y
;
if
(
diffY
<
0
||
sumoPosition
.
y
-
_endY
<
diffY
)
{
diffY
=
sumoPosition
.
y
-
_endY
;
}
if
(
diffY
<
0
)
{
diffY
=
0
;
}
double
diff
=
Math
.
sqrt
(
Math
.
pow
(
diffX
,
2
)
+
Math
.
pow
(
diffY
,
2
));
double
timeTillNextJoin
=
diff
/
50
;
// _vehiclesOutOfRange.put(pVehicleID, _step + timeTillNextJoin);
return
null
;
}
}
else
{
return
new
PositionVector
(
sumoPosition
.
x
,
sumoPosition
.
y
,
0
);
}
}
private
double
requestVehicleHeading
(
String
pVehicleID
)
{
if
(
_vehiclesOutOfRange
.
containsKey
(
pVehicleID
))
{
if
(
_vehiclesOutOfRange
.
get
(
pVehicleID
)
<
_step
)
{
return
-
1
;
}
else
{
_vehiclesOutOfRange
.
remove
(
pVehicleID
);
}
}
SumoCommand
angleCommand
=
Vehicle
.
getAngle
(
pVehicleID
);
Object
angleObject
=
requestObject
(
angleCommand
);
if
(
angleObject
!=
null
)
{
return
(
Double
)
angleObject
;
}
return
-
1
;
}
private
double
requestVehicleSpeed
(
String
pVehicleID
)
{
if
(
_vehiclesOutOfRange
.
containsKey
(
pVehicleID
))
{
if
(
_vehiclesOutOfRange
.
get
(
pVehicleID
)
<
_step
)
{
return
-
1
;
}
else
{
_vehiclesOutOfRange
.
remove
(
pVehicleID
);
}
}
SumoCommand
speedCommand
=
Vehicle
.
getSpeed
(
pVehicleID
);
Object
speedObject
=
requestObject
(
speedCommand
);
if
(
speedObject
!=
null
)
{
return
(
Double
)
speedObject
;
}
return
-
1
;
}
private
List
<
String
>
requestAllVehicles
()
{
SumoCommand
idList
=
Vehicle
.
getIDList
();
Object
object
=
requestObject
(
idList
);
SumoStringList
list
=
(
SumoStringList
)
object
;
List
<
String
>
result
=
new
ArrayList
<>();
for
(
String
vehicle
:
list
)
{
result
.
add
(
vehicle
);
}
return
result
;
}
@Override
public
List
<
String
>
getAllVehicles
()
{
return
getAllVehicles
(
_step
);
}
@Override
public
List
<
String
>
getAllVehicles
(
double
pStep
)
{
if
(
pStep
==
_step
)
{
return
new
ArrayList
<>(
_positons
.
keySet
());
}
throw
new
UnsupportedOperationException
(
"Future locations is not supported anymore!"
);
}
public
RoadNetworkEdge
getCurrentEdge
(
String
pVehicleID
)
{
obtainRoadNetwork
();
SumoCommand
roadIDCommand
=
Vehicle
.
getRoadID
(
pVehicleID
);
String
currentRoadID
=
(
String
)
requestObject
(
roadIDCommand
);
RoadNetworkEdge
edge
=
_roadNetwork
.
getEdge
(
currentRoadID
);
while
(
edge
.
isInternal
())
{
if
(
edge
.
getAccessibleEdges
().
size
()
==
1
)
{
edge
=
edge
.
getAccessibleEdges
().
get
(
0
);
}
else
{
break
;
}
}
return
edge
;
}
public
RoadNetworkRoute
requestVehicleRoute
(
String
pVehicleID
)
{
obtainRoadNetwork
();
synchronized
(
_positons
)
{
List
<
RoadNetworkEdge
>
streets
=
new
ArrayList
<>();
SumoCommand
routeCommand
=
Vehicle
.
getRoute
(
pVehicleID
);
Object
object
=
requestObject
(
routeCommand
);
SumoStringList
streetList
=
(
SumoStringList
)
object
;
RoadNetworkEdge
currentEdge
=
getCurrentEdge
(
pVehicleID
);
if
(
currentEdge
==
null
)
{
return
null
;
}
boolean
add
=
false
;
for
(
String
street
:
streetList
)
{
if
(
street
.
equals
(
currentEdge
.
getEdgeID
()))
{
add
=
true
;
}
if
(
add
)
{
streets
.
add
(
_roadNetwork
.
getEdge
(
street
));
}
}
if
(
streets
.
size
()
==
0
)
{
return
new
RoadNetworkRoute
(
new
ArrayList
<>());
}
return
new
RoadNetworkRoute
(
streets
);
}
}
@Override
public
RoadNetworkRoute
getCurrentRoute
(
String
pVehicleID
)
{
if
(
_positons
.
containsKey
(
pVehicleID
))
{
VehicleInformationContainer
route
=
_positons
.
get
(
pVehicleID
);
if
(
route
!=
null
)
{
return
route
.
getRoute
();
}
}
return
null
;
}
public
Object
requestObject
(
SumoCommand
routeCommand
)
{
Object
object
=
null
;
try
{
object
=
_connection
.
do_job_get
(
routeCommand
);
}
catch
(
RuntimeException
e
)
{
throw
e
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
object
;
}
public
void
execute
(
SumoCommand
routeCommand
)
{
try
{
_connection
.
do_job_set
(
routeCommand
);
}
catch
(
RuntimeException
e
)
{
throw
e
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
@Override
public
double
getStep
()
{
return
_step
;
}
@Override
public
double
getStart
()
{
return
_start
;
}
@Override
public
double
getMaximumAvailablePrediction
()
{
return
getStep
();
}
@Override
public
void
setObservedArea
(
double
pStartX
,
double
pStartY
,
double
pEndX
,
double
pEndY
)
{
_startX
=
pStartX
;
_startY
=
pStartY
;
_endX
=
pEndX
;
_endY
=
pEndY
;
_observedAreaSet
=
true
;
}
@Override
public
double
getScenarioWidth
()
{
SumoCommand
netBoundaryCommand
=
Simulation
.
getNetBoundary
();
try
{
SumoBoundingBox
netBoundary
=
(
SumoBoundingBox
)
_connection
.
do_job_get
(
netBoundaryCommand
);
return
Math
.
max
(
netBoundary
.
x_max
-
netBoundary
.
x_min
,
10
);
}
catch
(
Exception
e
)
{
//Nothing to do
}
return
-
1
;
}
@Override
public
double
getScenarioHeight
()
{
SumoCommand
netBoundaryCommand
=
Simulation
.
getNetBoundary
();
try
{
SumoBoundingBox
netBoundary
=
(
SumoBoundingBox
)
_connection
.
do_job_get
(
netBoundaryCommand
);
return
Math
.
max
(
netBoundary
.
y_max
-
netBoundary
.
y_min
,
10
);
}
catch
(
Exception
e
)
{
//Nothing to do
}
return
-
1
;
}
public
boolean
providesRoadInformation
()
{
return
true
;
}
public
RoadNetworkEdge
getVehicleDestination
(
String
pVehicleID
)
{
RoadNetworkRoute
roadNetworkRoute
=
getCurrentRoute
(
pVehicleID
);
return
roadNetworkRoute
.
getDestination
();
}
@Override
public
RoadNetwork
getRoadNetwork
()
{
obtainRoadNetwork
();
return
_roadNetwork
;
}
@Override
public
RoadNetworkRoute
findNewRoute
(
String
pVehicle
)
throws
NoAdditionalRouteAvailableException
{
List
<
RoadNetworkRoute
>
routes
=
new
ArrayList
<>();
RoadNetworkRoute
route
=
getCurrentRoute
(
pVehicle
);
if
(
route
.
getRoute
().
isEmpty
())
{
return
null
;
}
routes
.
add
(
route
);
RoadNetworkRoute
findRoute
=
_algorithm
.
findRoute
(
_roadNetwork
,
route
.
getStart
(),
route
.
getDestination
(),
routes
);
if
(
findRoute
==
null
)
{
throw
new
NoAdditionalRouteAvailableException
(
route
.
getStart
(),
route
.
getDestination
(),
routes
);
}
return
findRoute
;
}
@Override
public
RoadNetworkRoute
findNewRoute
(
String
pVehicle
,
List
<
RoadNetworkEdge
>
pEdgesToAvoid
,
boolean
pKeepDestination
)
throws
NoAdditionalRouteAvailableException
,
NoExitAvailableException
{
if
(
pKeepDestination
)
{
List
<
RoadNetworkRoute
>
routes
=
new
ArrayList
<>();
RoadNetworkRoute
route
=
getCurrentRoute
(
pVehicle
);
if
(
route
.
getRoute
().
isEmpty
())
{
return
null
;
}
routes
.
add
(
route
);
RoadNetworkRoute
findRoute
=
_algorithm
.
findRoute
(
_roadNetwork
,
route
.
getStart
(),
route
.
getDestination
(),
routes
,
pEdgesToAvoid
);
if
(
findRoute
==
null
)
{
throw
new
NoAdditionalRouteAvailableException
(
route
.
getStart
(),
route
.
getDestination
(),
routes
);
}
return
findRoute
;
}
else
{
RoadNetworkRoute
route
=
getCurrentRoute
(
pVehicle
);
if
(
route
.
getRoute
().
isEmpty
())
{
return
null
;
}
List
<
RoadNetworkEdge
>
routeList
=
route
.
getRoute
();
RoadNetworkEdge
lastEdge
=
null
;
boolean
search
=
false
;
outer:
for
(
int
i
=
routeList
.
size
()
-
1
;
i
>=
0
;
i
--)
{
if
(
search
)
{
List
<
RoadNetworkEdge
>
accessibleEdges
=
routeList
.
get
(
i
).
getAccessibleEdges
();
if
(
accessibleEdges
.
size
()
>
1
)
{
for
(
int
j
=
0
;
j
<
accessibleEdges
.
size
();
j
++)
{
if
(!
accessibleEdges
.
get
(
j
).
equals
(
lastEdge
))
{
List
<
RoadNetworkEdge
>
edges
=
new
ArrayList
<>();
for
(
int
k
=
0
;
k
<=
i
;
k
++)
{
edges
.
add
(
routeList
.
get
(
k
));
}
edges
.
add
(
accessibleEdges
.
get
(
j
));
List
<
RoadNetworkEdge
>
newPaths
;
while
((
newPaths
=
edges
.
get
(
edges
.
size
()
-
1
).
getAccessibleEdges
()).
size
()
>
0
)
{
edges
.
add
(
newPaths
.
get
(
_random
.
nextInt
(
newPaths
.
size
())));
}
for
(
RoadNetworkEdge
roadNetworkEdge
:
edges
)
{
if
(
pEdgesToAvoid
.
contains
(
roadNetworkEdge
))
{
continue
outer
;
}
}
return
new
RoadNetworkRoute
(
edges
);
}
}
}
}
search
=
true
;
lastEdge
=
routeList
.
get
(
i
);
}
throw
new
NoExitAvailableException
(
route
.
getStart
(),
route
.
getDestination
());
}
}
@Override
public
void
rerouteVehicle
(
String
pVehicle
,
RoadNetworkRoute
pRoute
)
{
SumoStringList
routeEdges
=
new
SumoStringList
();
for
(
RoadNetworkEdge
edge
:
pRoute
.
getRoute
())
{
routeEdges
.
add
(
edge
.
getEdgeID
());
}
execute
(
Vehicle
.
setRoute
(
pVehicle
,
routeEdges
));
}
@Override
public
void
stopVehicle
(
String
pVehicle
)
{
SumoCommand
stopCommand
=
Vehicle
.
setSpeed
(
pVehicle
,
0
);
execute
(
stopCommand
);
}
public
void
obtainRoadNetwork
()
{
if
(
_roadNetwork
==
null
)
{
if
(
TEMP_FILE
.
exists
())
{
try
{
ObjectInputStream
inputStream
=
new
ObjectInputStream
(
new
FileInputStream
(
TEMP_FILE
));
Object
readObject
=
inputStream
.
readObject
();
if
(
readObject
instanceof
SerializableRoadNetwork
)
{
SerializableRoadNetwork
serializedRoadNetwork
=
(
SerializableRoadNetwork
)
readObject
;
_roadNetwork
=
new
RoadNetwork
(
serializedRoadNetwork
,
this
);
}
inputStream
.
close
();
}
catch
(
IOException
|
ClassNotFoundException
|
NullPointerException
e
)
{
//Nothing to do
}
}
if
(
_roadNetwork
!=
null
)
{
System
.
out
.
println
(
"Got network from cache"
);
SumoCommand
edgeIDCommand
=
Edge
.
getIDList
();
SumoStringList
edgeIDStringList
=
(
SumoStringList
)
requestObject
(
edgeIDCommand
);
if
(
_roadNetwork
.
getAvailableEdges
().
size
()
==
edgeIDStringList
.
size
())
{
boolean
matching
=
true
;
for
(
String
edgeID
:
edgeIDStringList
)
{
if
(
_roadNetwork
.
getEdge
(
edgeID
)
==
null
)
{
matching
=
false
;
}
}
if
(
matching
)
{
return
;
}
}
}
SumoCommand
laneIDCommand
=
Lane
.
getIDList
();
Map
<
String
,
RoadNetworkEdge
>
roadNetwork
=
new
HashMap
<>();
SumoStringList
laneIDStringList
=
(
SumoStringList
)
requestObject
(
laneIDCommand
);
//Requesting all lanes from sumo.
for
(
String
laneID
:
laneIDStringList
)
{
SumoCommand
edgeIDCommand
=
Lane
.
getEdgeID
(
laneID
);
SumoLinkList
linkStringList
=
(
SumoLinkList
)
requestObject
(
Lane
.
getLinks
(
laneID
));
double
angle
=
getLaneAngle
(
laneID
);
double
maxSpeed
=
getMaxSpeed
(
laneID
);
if
(
linkStringList
.
size
()
>
0
)
{
String
edgeID
=
(
String
)
requestObject
(
edgeIDCommand
);
if
(!
roadNetwork
.
containsKey
(
edgeID
))
{
roadNetwork
.
put
(
edgeID
,
new
RoadNetworkEdge
(
edgeID
,
angle
,
this
));
}
RoadNetworkEdge
edge
=
roadNetwork
.
get
(
edgeID
);
edge
.
setOriginalMaxSpeed
(
maxSpeed
);
edge
.
addLane
(
new
RoadNetworkLane
(
laneID
));
for
(
SumoLink
link
:
linkStringList
)
{
String
notInternalLane
=
link
.
notInternalLane
;
String
connectedEdge
=
(
String
)
requestObject
(
Lane
.
getEdgeID
(
notInternalLane
));
double
linkAngle
=
getLaneAngle
(
laneID
);
if
(!
roadNetwork
.
containsKey
(
connectedEdge
))
{
RoadNetworkEdge
roadNetworkEdge
=
new
RoadNetworkEdge
(
connectedEdge
,
linkAngle
,
this
);
roadNetwork
.
put
(
connectedEdge
,
roadNetworkEdge
);
}
edge
.
addConnectedEdge
(
roadNetwork
.
get
(
connectedEdge
));
}
}
}
_roadNetwork
=
new
RoadNetwork
(
roadNetwork
,
this
,
true
);
try
{
ObjectOutputStream
outputStream
=
new
ObjectOutputStream
(
new
FileOutputStream
(
TEMP_FILE
));
outputStream
.
writeObject
(
new
SerializableRoadNetwork
(
_roadNetwork
));
outputStream
.
flush
();
outputStream
.
close
();
}
catch
(
IOException
e
)
{
//Nothing to do
e
.
printStackTrace
();
}
}
RoadNetwork
.
CURRENT_ROAD_NETWORK
=
_roadNetwork
;
}
public
double
getMaxSpeed
(
String
laneID
)
{
SumoCommand
maxSpeedCommand
=
Lane
.
getMaxSpeed
(
laneID
);
double
maxSpeed
=
(
Double
)
requestObject
(
maxSpeedCommand
);
return
maxSpeed
;
}
public
double
getLaneAngle
(
String
laneID
)
{
SumoCommand
shapeCommand
=
Lane
.
getShape
(
laneID
);
SumoGeometry
geometry
=
(
SumoGeometry
)
requestObject
(
shapeCommand
);
LinkedList
<
SumoPosition2D
>
coords
=
geometry
.
coords
;
SumoPosition2D
start
=
coords
.
getFirst
();
SumoPosition2D
end
=
coords
.
getLast
();
double
sin
=
(
end
.
y
-
start
.
y
)
/
Math
.
sqrt
(
Math
.
pow
(
end
.
x
-
start
.
x
,
2
)
+
Math
.
pow
(
end
.
y
-
start
.
y
,
2
));
double
angle
=
Math
.
asin
(
sin
)
*
180
/
Math
.
PI
;
if
(
end
.
x
-
start
.
x
<
0
)
{
angle
+=
180
;
}
return
angle
;
}
@Override
public
List
<
Location
>
getLaneShape
(
String
pLaneID
)
{
List
<
Location
>
positions
=
new
ArrayList
<>();
boolean
set
=
true
;
SumoCommand
laneShapeCommand
=
Lane
.
getShape
(
pLaneID
);
SumoGeometry
geometry
=
(
SumoGeometry
)
requestObject
(
laneShapeCommand
);
for
(
SumoPosition2D
location
:
geometry
.
coords
)
{
if
(!
isObservedAreaSet
())
{
positions
.
add
(
new
PositionVector
(
location
.
x
,
location
.
y
));
}
else
{
if
(
_startX
<=
location
.
x
&&
location
.
x
<=
_endX
&&
_startY
<=
location
.
y
&&
location
.
y
<=
_endY
)
{
positions
.
add
(
new
PositionVector
(
location
.
x
-
_startX
,
location
.
y
-
_startY
));
}
else
{
set
=
true
;
}
}
}
if
(
set
)
{
return
positions
;
}
else
{
return
Collections
.
emptyList
();
}
}
@Override
public
Location
getEdgeMeanPosition
(
String
pEdgeID
)
{
List
<
Location
>
positions
=
new
ArrayList
<>();
for
(
RoadNetworkLane
lane
:
_roadNetwork
.
getEdge
(
pEdgeID
).
getLanes
())
{
String
laneID
=
lane
.
getLaneID
();
positions
.
addAll
(
getLaneShape
(
laneID
));
}
double
x
=
0
;
double
y
=
0
;
int
count
=
0
;
for
(
Location
position
:
positions
)
{
x
+=
position
.
getLongitude
();
y
+=
position
.
getLatitude
();
count
++;
}
return
new
PositionVector
(
x
/
(
count
),
y
/
(
count
));
}
@Override
public
double
getVehicleSpeed
(
String
pVehicleID
)
{
SumoCommand
speedCommand
=
Vehicle
.
getSpeed
(
pVehicleID
);
Object
object
=
requestObject
(
speedCommand
);
return
(
Double
)
object
;
}
@Override
public
double
getLastStepMeanSpeed
(
String
pEdgeID
)
{
SumoCommand
speedCommand
=
Edge
.
getLastStepMeanSpeed
(
pEdgeID
);
Object
object
=
requestObject
(
speedCommand
);
return
(
Double
)
object
;
}
@Override
public
void
setEdgeMaxSpeed
(
String
pEdgeID
,
double
pMaxSpeed
)
{
SumoCommand
setMaxSpeedCommand
=
Edge
.
setMaxSpeed
(
pEdgeID
,
pMaxSpeed
);
execute
(
setMaxSpeedCommand
);
RoadNetworkEdge
edge
=
getRoadNetwork
().
getEdge
(
pEdgeID
);
edge
.
setMaxSpeed
(
pMaxSpeed
);
}
@Override
public
double
getEdgeLength
(
String
pEdgeID
)
{
double
length
=
0
;
for
(
RoadNetworkLane
lane
:
_roadNetwork
.
getEdge
(
pEdgeID
).
getLanes
())
{
SumoCommand
speedCommand
=
Lane
.
getLength
(
lane
.
getLaneID
());
Object
object
=
requestObject
(
speedCommand
);
length
+=
(
double
)
object
;
}
return
length
/
(
_roadNetwork
.
getEdge
(
pEdgeID
).
getLaneAmount
());
}
@Override
public
boolean
isEdgeUsable
(
String
pEdgeID
)
{
if
(
_observedAreaSet
)
{
List
<
RoadNetworkLane
>
lanes
=
_roadNetwork
.
getEdge
(
pEdgeID
).
getLanes
();
if
(
lanes
.
size
()
>
0
)
{
List
<
Location
>
laneShape
=
getLaneShape
(
lanes
.
get
(
0
).
getLaneID
());
if
(
laneShape
.
size
()
>
1
)
{
return
true
;
}
}
return
false
;
}
return
true
;
}
/**
* @return the startX
*/
@Override
public
double
getStartX
()
{
return
_startX
;
}
/**
* @return the startY
*/
@Override
public
double
getStartY
()
{
return
_startY
;
}
/**
* @return the endX
*/
@Override
public
double
getEndX
()
{
return
_endX
;
}
/**
* @return the endY
*/
@Override
public
double
getEndY
()
{
return
_endY
;
}
/**
* @return the observedAreaSet
*/
@Override
public
boolean
isObservedAreaSet
()
{
return
_observedAreaSet
;
}
}
src/de/tud/kom/p2psim/impl/topology/movement/vehicular/sumo/simulation/controller/xml/CancelParsingSAXException.java
0 → 100755
View file @
a9baf33b
package
de.tud.kom.p2psim.impl.topology.movement.vehicular.sumo.simulation.controller.xml
;
import
org.xml.sax.SAXException
;
public
class
CancelParsingSAXException
extends
SAXException
{
/**
*
*/
private
static
final
long
serialVersionUID
=
1L
;
}
src/de/tud/kom/p2psim/impl/topology/movement/vehicular/sumo/simulation/controller/xml/SimulationSetupInformationHandler.java
0 → 100755
View file @
a9baf33b
package
de.tud.kom.p2psim.impl.topology.movement.vehicular.sumo.simulation.controller.xml
;
import
org.xml.sax.Attributes
;
import
org.xml.sax.SAXException
;
import
org.xml.sax.helpers.DefaultHandler
;
import
de.tud.kom.p2psim.impl.topology.PositionVector
;
import
de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location
;
public
class
SimulationSetupInformationHandler
extends
DefaultHandler
{
private
Location
_upperLeft
;
private
Location
_lowerRight
;
@Override
public
void
startElement
(
String
pUri
,
String
pLocalName
,
String
pQName
,
Attributes
pAttributes
)
throws
SAXException
{
if
(
pQName
.
equals
(
"location"
))
{
String
meterBoundary
=
pAttributes
.
getValue
(
"convBoundary"
);
if
(
meterBoundary
!=
null
)
{
String
[]
edges
=
meterBoundary
.
split
(
","
);
_upperLeft
=
new
PositionVector
(
Double
.
valueOf
(
edges
[
0
]),
Double
.
valueOf
(
edges
[
1
]),
0
);
_lowerRight
=
new
PositionVector
(
Double
.
valueOf
(
edges
[
2
]),
Double
.
valueOf
(
edges
[
3
]),
0
);
}
throw
new
CancelParsingSAXException
();
}
}
public
Location
getLowerRight
()
{
return
_lowerRight
;
}
public
Location
getUpperLeft
()
{
return
_upperLeft
;
}
}
src/de/tud/kom/p2psim/impl/topology/movement/vehicular/sumo/simulation/controller/xml/VehicleDataInformationHandler.java
0 → 100755
View file @
a9baf33b
package
de.tud.kom.p2psim.impl.topology.movement.vehicular.sumo.simulation.controller.xml
;
import
java.util.HashMap
;
import
org.xml.sax.Attributes
;
import
org.xml.sax.SAXException
;
import
org.xml.sax.helpers.DefaultHandler
;
import
de.tud.kom.p2psim.impl.topology.PositionVector
;
import
de.tud.kom.p2psim.impl.topology.movement.vehicular.sumo.simulation.controller.VehicleInformationContainer
;
public
class
VehicleDataInformationHandler
extends
DefaultHandler
{
private
boolean
_next
=
true
;
private
boolean
_run
=
true
;
private
HashMap
<
String
,
VehicleInformationContainer
>
_vehiclePositions
=
new
HashMap
<>();
private
double
_currentStep
=
-
1
;
private
boolean
_observedAreaSet
=
false
;
private
double
_startX
=
-
1
;
private
double
_startY
=
-
1
;
private
double
_endX
=
-
1
;
private
double
_endY
=
-
1
;
private
HashMap
<
String
,
VehicleInformationContainer
>
_nextVehiclePositions
=
new
HashMap
<>();
private
double
_nextStep
=
-
1
;
private
static
final
String
doublePattern
=
"-?[0-9]*\\.?[0-9]+"
;
private
boolean
_terminated
=
false
;
@Override
public
void
startElement
(
String
pUri
,
String
pLocalName
,
String
pQName
,
Attributes
pAttributes
)
throws
SAXException
{
if
(
pQName
.
equals
(
"timestep"
))
{
while
(!
_next
)
{
try
{
Thread
.
sleep
(
10
);
}
catch
(
InterruptedException
e
)
{
e
.
printStackTrace
();
}
}
_next
=
false
;
String
value
=
pAttributes
.
getValue
(
"time"
);
if
(
value
.
matches
(
doublePattern
))
{
_nextStep
=
Double
.
valueOf
(
value
);
}
}
else
if
(
pQName
.
equals
(
"vehicle"
))
{
String
id
=
pAttributes
.
getValue
(
"id"
);
String
lonString
=
pAttributes
.
getValue
(
"x"
);
String
latString
=
pAttributes
.
getValue
(
"y"
);
String
speedString
=
pAttributes
.
getValue
(
"speed"
);
String
headingString
=
pAttributes
.
getValue
(
"angle"
);
if
(
lonString
.
matches
(
doublePattern
)
&&
latString
.
matches
(
doublePattern
)
&&
headingString
.
matches
(
doublePattern
)
&&
speedString
.
matches
(
doublePattern
)
)
{
double
lon
=
Double
.
valueOf
(
lonString
);
double
lat
=
Double
.
valueOf
(
latString
);
double
heading
=
Double
.
valueOf
(
headingString
);
double
speed
=
Double
.
valueOf
(
speedString
);
if
(
_observedAreaSet
)
{
if
(
_startX
<=
lon
&&
lon
<=
_endX
&&
_startY
<=
lat
&&
lat
<=
_endY
)
{
_nextVehiclePositions
.
put
(
id
,
new
VehicleInformationContainer
(
new
PositionVector
(
lon
-
_startX
,
lat
-
_startY
,
0
),
heading
,
speed
,
null
));
}
}
else
{
_nextVehiclePositions
.
put
(
id
,
new
VehicleInformationContainer
(
new
PositionVector
(
lon
,
lat
,
0
),
heading
,
speed
,
null
));
}
}
}
}
@Override
public
void
endElement
(
String
pUri
,
String
pLocalName
,
String
pQName
)
throws
SAXException
{
if
(
pQName
.
equals
(
"timestep"
))
{
_run
=
false
;
}
else
if
(
pQName
.
equals
(
"fcd-export"
))
{
while
(!
_next
)
{
try
{
Thread
.
sleep
(
10
);
}
catch
(
InterruptedException
e
)
{
e
.
printStackTrace
();
}
}
_next
=
false
;
_run
=
false
;
_terminated
=
true
;
}
}
public
void
setObservedArea
(
double
pStartX
,
double
pStartY
,
double
pEndX
,
double
pEndY
)
{
_startX
=
pStartX
;
_startY
=
pStartY
;
_endX
=
pEndX
;
_endY
=
pEndY
;
_observedAreaSet
=
true
;
}
public
boolean
isTerminated
()
{
return
_terminated
;
}
public
HashMap
<
String
,
VehicleInformationContainer
>
getVehiclePositions
()
{
return
_vehiclePositions
;
}
public
void
readNext
()
{
while
(
_run
)
{
try
{
Thread
.
sleep
(
10
);
}
catch
(
InterruptedException
e
)
{
e
.
printStackTrace
();
}
}
_vehiclePositions
=
_nextVehiclePositions
;
_currentStep
=
_nextStep
;
_nextStep
=
-
1
;
_nextVehiclePositions
=
new
HashMap
<>();
_run
=
true
;
_next
=
true
;
}
public
boolean
isRunning
()
{
return
_run
;
}
public
double
getStep
()
{
return
_currentStep
;
}
}
src/de/tud/kom/p2psim/impl/topology/movement/vehicular/sumo/simulation/controller/xml/XMLSimulationController.java
0 → 100755
View file @
a9baf33b
package
de.tud.kom.p2psim.impl.topology.movement.vehicular.sumo.simulation.controller.xml
;
import
java.io.FileInputStream
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
javax.xml.parsers.SAXParser
;
import
javax.xml.parsers.SAXParserFactory
;
import
de.tud.kom.p2psim.impl.topology.movement.vehicular.sumo.simulation.controller.VehicleInformationContainer
;
import
de.tud.kom.p2psim.impl.topology.movement.vehicular.sumo.simulation.controller.csv.RoadSideUnitInformationHandler
;
import
de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.api.SimulationSetupExtractor
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.api.VehicleController
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetwork
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkEdge
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkRoute
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.exception.NoAdditionalRouteAvailableException
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.exception.NoExitAvailableException
;
public
class
XMLSimulationController
implements
VehicleController
,
SimulationSetupExtractor
,
Runnable
{
private
String
_vehicleDataPath
;
private
String
_roadSideUnitDataPath
;
private
List
<
String
>
_vehicles
;
private
Map
<
Double
,
Map
<
String
,
VehicleInformationContainer
>>
_positonsByTimestamp
=
new
HashMap
<>();
private
int
_futureInformation
=
0
;
private
boolean
_initalized
=
false
;
private
VehicleDataInformationHandler
_vehicleDataInformationHandler
=
new
VehicleDataInformationHandler
();
private
RoadSideUnitInformationHandler
_roadSideUnitInformationHandler
=
new
RoadSideUnitInformationHandler
();
private
double
_start
=
-
1
;
private
double
_step
;
public
XMLSimulationController
(
String
pVehicleDataPath
,
String
pRoadSideUnitDataPath
)
{
this
(
pVehicleDataPath
);
_roadSideUnitDataPath
=
pRoadSideUnitDataPath
;
}
public
XMLSimulationController
(
String
pVehicleDataPath
)
{
_vehicleDataPath
=
pVehicleDataPath
;
}
@Override
public
void
init
()
{
if
(!
_initalized
)
{
if
(
_vehicleDataPath
!=
null
)
{
Thread
thread
=
new
Thread
(
this
);
thread
.
start
();
for
(
int
i
=
0
;
i
<
_futureInformation
;
i
++)
{
nextStep
();
}
}
if
(
_roadSideUnitDataPath
!=
null
)
{
_roadSideUnitInformationHandler
.
parseIntersectionsFile
(
_roadSideUnitDataPath
);
}
_initalized
=
true
;
}
}
@Override
public
Location
getVehiclePosition
(
String
pVehicleID
)
{
return
getVehiclePosition
(
_step
,
pVehicleID
);
}
public
VehicleInformationContainer
requestVehicleInformation
(
String
pVehicleID
)
{
return
_vehicleDataInformationHandler
.
getVehiclePositions
().
get
(
pVehicleID
);
}
@Override
public
boolean
nextStep
()
{
_vehicleDataInformationHandler
.
readNext
();
_step
=
_vehicleDataInformationHandler
.
getStep
()
-
_futureInformation
;
if
(
_start
==
-
1
)
{
_start
=
_vehicleDataInformationHandler
.
getStep
();
}
double
newStep
=
_step
+
_futureInformation
;
if
(!
_positonsByTimestamp
.
containsKey
(
newStep
))
{
Map
<
String
,
VehicleInformationContainer
>
vehiclePositions
=
new
HashMap
<>();
_positonsByTimestamp
.
put
(
newStep
,
vehiclePositions
);
List
<
String
>
allVehicles
=
new
ArrayList
<>(
_vehicleDataInformationHandler
.
getVehiclePositions
().
keySet
());
for
(
String
vehicle
:
allVehicles
)
{
VehicleInformationContainer
vehiclePosition
=
requestVehicleInformation
(
vehicle
);
if
(
vehiclePosition
!=
null
)
{
vehiclePositions
.
put
(
vehicle
,
vehiclePosition
);
}
}
}
return
!
_vehicleDataInformationHandler
.
isTerminated
();
}
@Override
public
List
<
String
>
getAllVehicles
()
{
return
getAllVehicles
(
_step
);
}
@Override
public
double
getStep
()
{
return
_step
;
}
@Override
public
double
getStart
()
{
return
_start
;
}
@Override
public
void
run
()
{
try
{
SAXParser
parser
=
SAXParserFactory
.
newInstance
().
newSAXParser
();
parser
.
parse
(
new
FileInputStream
(
_vehicleDataPath
),
_vehicleDataInformationHandler
);
}
catch
(
RuntimeException
e
)
{
throw
e
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
@Override
public
void
setObservedArea
(
double
pStartX
,
double
pStartY
,
double
pEndX
,
double
pEndY
)
{
_vehicleDataInformationHandler
.
setObservedArea
(
pStartX
,
pStartY
,
pEndX
,
pEndY
);
_roadSideUnitInformationHandler
.
setObservedArea
(
pStartX
,
pStartY
,
pEndX
,
pEndY
);
}
@Override
public
Location
getVehiclePosition
(
double
pStep
,
String
pVehicleID
)
{
Map
<
String
,
VehicleInformationContainer
>
map
=
_positonsByTimestamp
.
get
(
pStep
);
return
map
.
get
(
pVehicleID
).
getPosition
();
}
@Override
public
List
<
String
>
getAllVehicles
(
double
pStep
)
{
Map
<
String
,
VehicleInformationContainer
>
map
=
_positonsByTimestamp
.
get
(
pStep
);
return
new
ArrayList
<>(
map
.
keySet
());
}
@Override
public
double
getMaximumAvailablePrediction
()
{
double
max
=
Collections
.
max
(
_positonsByTimestamp
.
keySet
());
return
max
;
}
@Override
public
List
<
Location
>
getAllIntersections
(
boolean
pCluster
)
{
return
_roadSideUnitInformationHandler
.
getIntersections
();
}
@Override
public
double
getScenarioWidth
()
{
return
-
1
;
}
@Override
public
double
getScenarioHeight
()
{
return
-
1
;
}
@Override
public
RoadNetworkRoute
getCurrentRoute
(
String
pVehicleID
)
{
throw
new
UnsupportedOperationException
(
"This method is not supported for "
+
getClass
().
getSimpleName
());
}
@Override
public
RoadNetwork
getRoadNetwork
()
{
return
null
;
}
@Override
public
void
rerouteVehicle
(
String
pVehicle
,
RoadNetworkRoute
pRoute
)
{
throw
new
UnsupportedOperationException
(
"This method is not supported for "
+
getClass
().
getSimpleName
());
}
@Override
public
RoadNetworkRoute
findNewRoute
(
String
pVehicle
)
throws
NoAdditionalRouteAvailableException
{
throw
new
UnsupportedOperationException
(
"This method is not supported for "
+
getClass
().
getSimpleName
());
}
@Override
public
RoadNetworkRoute
findNewRoute
(
String
pVehicle
,
List
<
RoadNetworkEdge
>
pEdgesToAvoid
,
boolean
pKeepDestination
)
throws
NoAdditionalRouteAvailableException
,
NoExitAvailableException
{
throw
new
UnsupportedOperationException
(
"This method is not supported for "
+
getClass
().
getSimpleName
());
}
@Override
public
void
stopVehicle
(
String
pVehicle
)
{
throw
new
UnsupportedOperationException
(
"This method is not supported for "
+
getClass
().
getSimpleName
());
}
@Override
public
double
getVehicleSpeed
(
String
pVehicleID
)
{
return
_vehicleDataInformationHandler
.
getVehiclePositions
().
get
(
pVehicleID
).
getSpeed
();
}
@Override
public
double
getVehicleHeading
(
String
pVehicleID
)
{
return
_vehicleDataInformationHandler
.
getVehiclePositions
().
get
(
pVehicleID
).
getHeading
();
}
}
src/de/tud/kom/p2psim/impl/topology/placement/RSUPlacement.java
0 → 100755
View file @
a9baf33b
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of PeerfactSim.KOM.
*
* PeerfactSim.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package
de.tud.kom.p2psim.impl.topology.placement
;
import
java.util.List
;
import
de.tud.kom.p2psim.api.topology.TopologyComponent
;
import
de.tud.kom.p2psim.api.topology.placement.PlacementModel
;
import
de.tud.kom.p2psim.impl.topology.PositionVector
;
import
de.tud.kom.p2psim.impl.topology.movement.vehicular.sumo.simulation.controller.traci.TraciSimulationController
;
import
de.tud.kom.p2psim.impl.topology.movement.vehicular.sumo.simulation.controller.xml.XMLSimulationController
;
import
de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location
;
import
de.tudarmstadt.maki.simonstrator.api.component.vehicular.api.SimulationSetupExtractor
;
import
de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor
;
/**
*/
public
class
RSUPlacement
implements
PlacementModel
{
private
final
String
sumoExe
;
private
final
String
sumoConfigFile
;
private
final
String
sumoIntersections
;
private
final
int
offsetX
;
private
final
int
offsetY
;
private
final
int
width
;
private
final
int
height
;
private
SimulationSetupExtractor
_controller
;
private
List
<
Location
>
_intersections
;
private
int
_currentIndex
=
0
;
@XMLConfigurableConstructor
({
"sumoExe"
,
"sumoConfigFile"
,
"offsetX"
,
"offsetY"
,
"width"
,
"height"
})
public
RSUPlacement
(
String
sumoExe
,
String
sumoConfigFile
,
String
offsetX
,
String
offsetY
,
String
width
,
String
height
)
{
this
.
sumoExe
=
sumoExe
;
this
.
sumoConfigFile
=
sumoConfigFile
;
this
.
sumoIntersections
=
null
;
this
.
offsetX
=
Integer
.
parseInt
(
offsetX
);
this
.
offsetY
=
Integer
.
parseInt
(
offsetY
);
this
.
width
=
Integer
.
parseInt
(
width
);
this
.
height
=
Integer
.
parseInt
(
height
);
initializeModel
();
}
@XMLConfigurableConstructor
({
"sumoIntersections"
,
"offsetX"
,
"offsetY"
,
"width"
,
"height"
})
public
RSUPlacement
(
String
sumoIntersections
,
String
offsetX
,
String
offsetY
,
String
width
,
String
height
)
{
this
.
sumoIntersections
=
sumoIntersections
;
this
.
sumoExe
=
null
;
this
.
sumoConfigFile
=
null
;
this
.
offsetX
=
Integer
.
parseInt
(
offsetX
);
this
.
offsetY
=
Integer
.
parseInt
(
offsetY
);
this
.
width
=
Integer
.
parseInt
(
width
);
this
.
height
=
Integer
.
parseInt
(
height
);
initializeModel
();
}
/**
* Initializes the movement model by executing BonnMotion and parsing the
* resulting movement trace.
*/
protected
void
initializeModel
()
{
if
(
this
.
sumoExe
!=
null
)
{
_controller
=
TraciSimulationController
.
createSimulationController
(
sumoExe
,
sumoConfigFile
);
_controller
.
init
();
_controller
.
setObservedArea
(
offsetX
,
offsetY
,
offsetX
+
width
,
offsetY
+
height
);
_intersections
=
_controller
.
getAllIntersections
(
true
);
}
else
{
_controller
=
new
XMLSimulationController
(
null
,
sumoIntersections
);
_controller
.
init
();
_controller
.
setObservedArea
(
offsetX
,
offsetY
,
offsetX
+
width
,
offsetY
+
height
);
_intersections
=
_controller
.
getAllIntersections
(
true
);
}
}
@Override
public
void
addComponent
(
TopologyComponent
comp
)
{
//
}
@Override
public
PositionVector
place
(
TopologyComponent
comp
)
{
if
(
_currentIndex
<
_intersections
.
size
())
{
Location
intersection
=
_intersections
.
get
(
_currentIndex
);
_currentIndex
++;
return
new
PositionVector
(
intersection
.
getLongitude
(),
intersection
.
getLatitude
());
}
else
{
return
new
PositionVector
(
Double
.
NaN
,
Double
.
NaN
);
}
}
}
src/de/tud/kom/p2psim/impl/topology/views/VisualizationTopologyView.java
View file @
a9baf33b
...
...
@@ -43,6 +43,7 @@ import java.util.Collection;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.ConcurrentLinkedQueue
;
import
java.util.concurrent.CopyOnWriteArrayList
;
...
...
@@ -387,7 +388,7 @@ public class VisualizationTopologyView extends JFrame
*/
protected
class
WorldPanel
extends
JLayeredPane
{
protected
HashMap
<
INodeID
,
VisNodeInformation
>
nodeInformation
=
new
HashMap
<
INodeID
,
VisNodeInformation
>();
protected
Concurrent
HashMap
<
INodeID
,
VisNodeInformation
>
nodeInformation
=
new
Concurrent
HashMap
<
INodeID
,
VisNodeInformation
>();
protected
final
static
int
PADDING
=
16
;
...
...
Prev
1
2
3
4
Next
Write
Preview
Markdown
is supported
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