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; ...@@ -27,7 +27,7 @@ import java.io.IOException;
/** /**
* Represents the header of a bitmap. * Represents the header of a bitmap.
* *
* @author Andr Mink, Sebastian Kaune * @author Andr Mink, Sebastian Kaune
*/ */
public class BitmapHeader { public class BitmapHeader {
public int nsize; // Size of file public int nsize; // Size of file
......
...@@ -32,7 +32,7 @@ import java.util.ArrayList; ...@@ -32,7 +32,7 @@ import java.util.ArrayList;
* colorTable of the bitmap. Currently, there are only 8bit bitmaps (256 colors) * colorTable of the bitmap. Currently, there are only 8bit bitmaps (256 colors)
* supported. * supported.
* *
* @author Andr Mink, Sebastian Kaune * @author Andr Mink, Sebastian Kaune
*/ */
public class BitmapLoader { public class BitmapLoader {
public int[][] cartesianSpace; public int[][] cartesianSpace;
......
...@@ -3584,7 +3584,7 @@ public class regionName { ...@@ -3584,7 +3584,7 @@ public class regionName {
if (country_code.equals("FI") == true) { if (country_code.equals("FI") == true) {
switch (region_code2) { switch (region_code2) {
case 1: case 1:
name = "land"; name = "land";
break; break;
case 6: case 6:
name = "Lapland"; name = "Lapland";
...@@ -6683,7 +6683,7 @@ public class regionName { ...@@ -6683,7 +6683,7 @@ public class regionName {
name = "Aqmola"; name = "Aqmola";
break; break;
case 4: case 4:
name = "Aqtbe"; name = "Aqtbe";
break; break;
case 5: case 5:
name = "Astana"; name = "Astana";
...@@ -7071,7 +7071,7 @@ public class regionName { ...@@ -7071,7 +7071,7 @@ public class regionName {
name = "Bauskas"; name = "Bauskas";
break; break;
case 5: case 5:
name = "Csu"; name = "Csu";
break; break;
case 6: case 6:
name = "Daugavpils"; name = "Daugavpils";
...@@ -7086,7 +7086,7 @@ public class regionName { ...@@ -7086,7 +7086,7 @@ public class regionName {
name = "Gulbenes"; name = "Gulbenes";
break; break;
case 10: case 10:
name = "Jkabpils"; name = "Jkabpils";
break; break;
case 11: case 11:
name = "Jelgava"; name = "Jelgava";
...@@ -7098,16 +7098,16 @@ public class regionName { ...@@ -7098,16 +7098,16 @@ public class regionName {
name = "Jurmala"; name = "Jurmala";
break; break;
case 14: case 14:
name = "Krslavas"; name = "Krslavas";
break; break;
case 15: case 15:
name = "Kuldigas"; name = "Kuldigas";
break; break;
case 16: case 16:
name = "Liepja"; name = "Liepja";
break; break;
case 17: case 17:
name = "Liepjas"; name = "Liepjas";
break; break;
case 18: case 18:
name = "Limbazu"; name = "Limbazu";
...@@ -7125,10 +7125,10 @@ public class regionName { ...@@ -7125,10 +7125,10 @@ public class regionName {
name = "Preilu"; name = "Preilu";
break; break;
case 23: case 23:
name = "Rzekne"; name = "Rzekne";
break; break;
case 24: case 24:
name = "Rzeknes"; name = "Rzeknes";
break; break;
case 25: case 25:
name = "Riga"; name = "Riga";
......
...@@ -662,7 +662,7 @@ public class DefaultConfigurator implements Configurator { ...@@ -662,7 +662,7 @@ public class DefaultConfigurator implements Configurator {
} }
public String parseValue(String value) { 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); int posDollar = value.indexOf(CONFIG_VARIABLE_PREFIX_TAG);
String varName = value.substring(posDollar + 1, value.length()); String varName = value.substring(posDollar + 1, value.length());
value = variables.get(varName); value = variables.get(varName);
......
...@@ -44,7 +44,7 @@ import de.tudarmstadt.maki.simonstrator.api.component.core.TimeComponent; ...@@ -44,7 +44,7 @@ import de.tudarmstadt.maki.simonstrator.api.component.core.TimeComponent;
* @author Sebastian Kaune * @author Sebastian Kaune
*/ */
public class Scheduler implements EventHandler, public class Scheduler implements EventHandler,
SchedulerComponent, TimeComponent { SchedulerComponent, TimeComponent {
// Flag to allow the compiler to remove the unneeded debug code // Flag to allow the compiler to remove the unneeded debug code
private static final boolean DEBUG_CODE = false; private static final boolean DEBUG_CODE = false;
...@@ -449,6 +449,7 @@ public class Scheduler implements EventHandler, ...@@ -449,6 +449,7 @@ public class Scheduler implements EventHandler,
* *
* @return current scheduler time * @return current scheduler time
*/ */
@Override
public long getCurrentTime() { public long getCurrentTime() {
return currentTime; return currentTime;
} }
...@@ -518,6 +519,7 @@ public class Scheduler implements EventHandler, ...@@ -518,6 +519,7 @@ public class Scheduler implements EventHandler,
return simTime; return simTime;
} }
@Override
public int compareTo(SchedulerEvent o) { public int compareTo(SchedulerEvent o) {
int comp = Double.compare(this.simTime, o.simTime); int comp = Double.compare(this.simTime, o.simTime);
return comp == 0 ? Double.compare(this.globalOrderIdx, o.globalOrderIdx) : comp; return comp == 0 ? Double.compare(this.globalOrderIdx, o.globalOrderIdx) : comp;
...@@ -567,6 +569,10 @@ public class Scheduler implements EventHandler, ...@@ -567,6 +569,10 @@ public class Scheduler implements EventHandler,
} }
} }
public double getTimeSkew() {
return timeSkew;
}
/** /**
* Sets the simulation speed lock, changes in setRealTime or setTimeSkew * Sets the simulation speed lock, changes in setRealTime or setTimeSkew
* will not apply while the lock is set. * will not apply while the lock is set.
......
...@@ -165,13 +165,42 @@ public class DefaultTopologyComponent implements TopologyComponent { ...@@ -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 // Provide Underlay topology
Event.scheduleImmediately(new EventHandler() { Event.scheduleImmediately(new EventHandler() {
@Override @Override
public void eventOccurred(Object content, int type) { public void eventOccurred(Object content, int type) {
if (getHost().getLinkLayer().hasPhy(PhyType.WIFI)) { if (getHost().getLinkLayer().hasPhy(PhyType.WIFI)) {
new SiSTopologyProvider(sis, SiSTypes.NEIGHBORS_WIFI, new SiSTopologyProvider(sis,
SiSTypes.NEIGHBORS_WIFI,
DefaultTopologyComponent.this, DefaultTopologyComponent.this,
getTopologyID(NetInterfaceName.WIFI, true), getTopologyID(NetInterfaceName.WIFI, true),
DefaultTopologyComponent.class); 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.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; ...@@ -43,6 +43,7 @@ import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
...@@ -387,7 +388,7 @@ public class VisualizationTopologyView extends JFrame ...@@ -387,7 +388,7 @@ public class VisualizationTopologyView extends JFrame
*/ */
protected class WorldPanel extends JLayeredPane { 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; 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