Commit a9baf33b authored by Björn Richerzhagen's avatar Björn Richerzhagen
Browse files

Merge remote-tracking branch 'simonstrator/tm/vehicular-services'

parents 705984e5 f476dae3
......@@ -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
......
......@@ -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;
......
......@@ -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 = "Aqtbe";
name = "Aqtbe";
break;
case 5:
name = "Astana";
......@@ -7071,7 +7071,7 @@ public class regionName {
name = "Bauskas";
break;
case 5:
name = "Csu";
name = "Csu";
break;
case 6:
name = "Daugavpils";
......@@ -7086,7 +7086,7 @@ public class regionName {
name = "Gulbenes";
break;
case 10:
name = "Jkabpils";
name = "Jkabpils";
break;
case 11:
name = "Jelgava";
......@@ -7098,16 +7098,16 @@ public class regionName {
name = "Jurmala";
break;
case 14:
name = "Krslavas";
name = "Krslavas";
break;
case 15:
name = "Kuldigas";
break;
case 16:
name = "Liepja";
name = "Liepja";
break;
case 17:
name = "Liepjas";
name = "Liepjas";
break;
case 18:
name = "Limbazu";
......@@ -7125,10 +7125,10 @@ public class regionName {
name = "Preilu";
break;
case 23:
name = "Rzekne";
name = "Rzekne";
break;
case 24:
name = "Rzeknes";
name = "Rzeknes";
break;
case 25:
name = "Riga";
......
......@@ -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);
......
......@@ -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.
......
......@@ -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);
......
/*
* 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
/*
* 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
/*
* 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();
}
}
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();
}
}
}
/*
* 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
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;
}
}
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;
}
}
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;
}
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;
}
}
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;
}
}
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();
}
}
/*
* 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);
}
}
}
......@@ -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 ConcurrentHashMap<INodeID, VisNodeInformation> nodeInformation = new ConcurrentHashMap<INodeID, VisNodeInformation>();
protected final static int PADDING = 16;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment