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
81462f76
Commit
81462f76
authored
May 23, 2017
by
Tobias Meuser
Committed by
Jose Ignacio Monreal Bailey
Aug 20, 2019
Browse files
Added comments
parent
7147a483
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/de/tud/kom/p2psim/impl/topology/movement/VehicleMovementModel.java
0 → 100644
View file @
81462f76
/*
* 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.Set
;
import
org.kom.probsense.information.Position
;
import
com.kom.probsense.sumo.simulation.controller.VehicleController
;
import
com.kom.probsense.sumo.simulation.controller.traci.TraciSimulationController
;
import
com.kom.probsense.sumo.simulation.controller.xml.XMLSimulationController
;
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.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.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.future_location.FutureLocationSensor
;
import
de.tudarmstadt.maki.simonstrator.api.component.sensor.location.Location
;
import
de.tudarmstadt.maki.simonstrator.api.component.sis.SiSComponent
;
import
de.tudarmstadt.maki.simonstrator.api.component.sis.SiSDataCallback
;
import
de.tudarmstadt.maki.simonstrator.api.component.sis.SiSInfoProperties
;
import
de.tudarmstadt.maki.simonstrator.api.component.sis.SiSInformationProvider.SiSProviderHandle
;
import
de.tudarmstadt.maki.simonstrator.api.component.sis.exception.InformationNotAvailableException
;
import
de.tudarmstadt.maki.simonstrator.api.component.sis.type.SiSTypes
;
import
de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor
;
public
class
VehicleMovementModel
implements
MovementModel
,
EventHandler
,
FutureLocationSensor
{
public
static
final
double
SCALING_FACTOR
=
1.0
;
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
final
String
sumoExe
;
private
final
String
sumoConfigFile
;
private
final
String
sumoTrace
;
private
final
long
timestepConversion
=
Time
.
SECOND
;
private
boolean
initialized
=
false
;
private
VehicleController
_controller
;
private
List
<
Position
>
intersections
;
private
String
sumoIntersections
;
/**
* 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
)
{
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
)
{
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
;
}
/**
* 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 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"
,
"offsetX"
,
"offsetY"
,
"width"
,
"height"
})
public
VehicleMovementModel
(
long
timeBetweenMoveOperations
,
String
sumoTrace
,
int
offsetX
,
int
offsetY
,
int
width
,
int
height
)
{
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
=
null
;
this
.
offsetX
=
offsetX
;
this
.
offsetY
=
offsetY
;
this
.
width
=
width
;
this
.
height
=
height
;
}
/**
* 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
*/
@XMLConfigurableConstructor
({
"timeBetweenMoveOperations"
,
"sumoExe"
,
"sumoConfigFile"
})
public
VehicleMovementModel
(
long
timeBetweenMoveOperations
,
String
sumoExe
,
String
sumoConfigFile
)
{
this
(
timeBetweenMoveOperations
,
sumoExe
,
sumoConfigFile
,
"10000"
,
"10000"
,
"15000"
,
"15000"
);
}
/**
* 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
);
}
/**
* 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
();
initialized
=
true
;
}
// Initial placement
actuator
.
updateCurrentLocation
(
new
PositionVector
(
Double
.
NaN
,
Double
.
NaN
));
try
{
final
SiSComponent
sis
=
actuator
.
getHost
().
getComponent
(
SiSComponent
.
class
);
sis
.
provide
().
nodeState
(
SiSTypes
.
FUTURE_PHY_LOCATION
,
new
SiSDataCallback
<
Location
>()
{
Set
<
INodeID
>
localID
=
INodeID
.
getSingleIDSet
(
actuator
.
getHost
().
getId
());
@Override
public
Location
getValue
(
INodeID
nodeID
,
SiSProviderHandle
providerHandle
)
throws
InformationNotAvailableException
{
if
(
nodeID
.
equals
(
actuator
.
getHost
().
getId
()))
{
return
getFutureLocation
(
actuator
.
getHost
());
}
else
{
throw
new
InformationNotAvailableException
();
}
}
@Override
public
Set
<
INodeID
>
getObservedNodes
()
{
return
localID
;
}
@Override
public
SiSInfoProperties
getInfoProperties
()
{
return
new
SiSInfoProperties
();
}
});
}
catch
(
ComponentNotAvailableException
e
)
{
// Nothing to do
}
}
/**
* 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
.
init
();
_controller
.
setObservedArea
(
offsetX
,
offsetY
,
offsetX
+
width
,
offsetY
+
height
);
_controller
.
nextStep
();
intersections
=
simulationController
.
getAllIntersections
(
true
);
}
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
();
intersections
=
simulationController
.
getAllIntersections
(
true
);
}
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
)
{
_controller
.
nextStep
();
}
List
<
String
>
allVehicles
=
_controller
.
getAllVehicles
();
for
(
int
i
=
0
;
i
<
allVehicles
.
size
();
i
++)
{
String
vehicle
=
allVehicles
.
get
(
i
);
Position
position
=
_controller
.
getVehiclePosition
(
vehicle
);
if
(
position
==
null
)
{
allVehicles
.
remove
(
i
--);
continue
;
}
SimLocationActuator
component
=
requestSimActuator
(
vehicle
);
component
.
updateCurrentLocation
(
new
PositionVector
(
position
.
getX
()
/
SCALING_FACTOR
,
position
.
getY
()
/
SCALING_FACTOR
));
component
.
setMovementSpeed
(
position
.
getSpeed
()
/
SCALING_FACTOR
);
try
{
RoutedNetLayer
routedNetLayer
=
component
.
getHost
().
getComponent
(
RoutedNetLayer
.
class
);
for
(
SimNetInterface
netInterface
:
routedNetLayer
.
getSimNetworkInterfaces
())
{
if
(
netInterface
.
isOffline
())
{
netInterface
.
goOnline
();
}
}
}
catch
(
ComponentNotAvailableException
e
)
{
e
.
printStackTrace
();
}
}
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
);
}
}
}
freeComponents
.
forEach
((
component
)
->
{
component
.
updateCurrentLocation
(
new
PositionVector
(
Double
.
NaN
,
Double
.
NaN
));
try
{
RoutedNetLayer
routedNetLayer
=
component
.
getHost
().
getComponent
(
RoutedNetLayer
.
class
);
for
(
SimNetInterface
netInterface
:
routedNetLayer
.
getSimNetworkInterfaces
())
{
if
(
netInterface
.
isOnline
())
{
netInterface
.
goOffline
();
}
}
}
catch
(
ComponentNotAvailableException
e
)
{
e
.
printStackTrace
();
}
});
// 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
)
{
freeComponents
.
add
(
simLocationActuator
);
hostVehicleIDMatching
.
remove
(
simLocationActuator
.
getHost
().
getId
());
}
}
}
/**
* 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
)
{
idComponentMatcher
.
put
(
vehicle
,
simLocationActuator
);
hostVehicleIDMatching
.
put
(
simLocationActuator
.
getHost
().
getId
(),
vehicle
);
}
else
{
throw
new
RuntimeException
(
"Unable to assign new components. Please increase node amount."
);
}
}
return
idComponentMatcher
.
get
(
vehicle
);
}
/**
* Returns the future location of a certain host.
* @param pHost The host for which the location is being requested.
* @return The future location of the host.
*/
@Override
public
Location
getFutureLocation
(
Host
pHost
)
{
if
(
hostVehicleIDMatching
.
containsKey
(
pHost
.
getId
()))
{
String
vehicleID
=
hostVehicleIDMatching
.
get
(
pHost
.
getId
());
Position
vehiclePosition
=
_controller
.
getVehiclePosition
(
_controller
.
getMaximumAvailablePrediction
(),
vehicleID
);
if
(
vehiclePosition
!=
null
)
{
return
new
PositionVector
(
vehiclePosition
.
getX
(),
vehiclePosition
.
getY
());
}
}
return
null
;
}
}
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