Commit d30fc202 authored by jimonreal's avatar jimonreal
Browse files

Adding support for Person

parent 29be77b1
......@@ -100,7 +100,7 @@
<!-- jgrapht can be found there -->
<repository>
<id>conjars.org</id>
<url>http://conjars.org/repo</url>
<url>https://conjars.wensel.net/repo</url>
</repository>
<!-- uk maven central, since the local central server is slow as hell -->
......
/*
* 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 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.vehicular.DefaultPersonInformationComponent;
import de.tudarmstadt.maki.simonstrator.api.*;
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.PedestrianInformationComponent;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.api.PersonController;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.api.SimulationSetupExtractor;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetwork;
import de.tudarmstadt.maki.simonstrator.api.util.XMLConfigurableConstructor;
import java.util.*;
public class PersonMovementModel 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 PersonMovementModel 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 sumoTripOutputFile;
private final String sumoTrace;
private String sumoIntersections;
private final long timestepConversion = Time.SECOND;
private boolean initialized = false;
private PersonController _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", "sumoTripOutputFile", "offsetX", "offsetY", "width", "height" })
public PersonMovementModel(long timeBetweenMoveOperations, String sumoExe, String sumoConfigFile, String sumoTripOutputFile, 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.sumoTripOutputFile = sumoTripOutputFile;
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 PersonMovementModel(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.sumoTripOutputFile = 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, sumoTripOutputFile);
_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 person 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> allPersons = _controller.getAllPersons();
for (int i = 0; i < allPersons.size(); i++) {
String person = allPersons.get(i);
Location position = _controller.getPersonPosition(person);
if (position == null) {
allPersons.remove(i--);
continue;
}
SimLocationActuator component = requestSimActuator(person);
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.getPersonSpeed(person));
}
if (allPersons.size() != idComponentMatcher.size()) {
ArrayList<String> registeredPersons = new ArrayList<>(idComponentMatcher.keySet());
for (int i = 0; i < registeredPersons.size(); i++) {
String person = registeredPersons.get(i);
if (!allPersons.contains(person)) {
addFreeHost(person);
}
}
}
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 person from the set of moved components as the person has stopped moving/walking
* @param pPersonID The stopped person
*/
private void addFreeHost(String pPersonID) {
if (idComponentMatcher.containsKey(pPersonID)) {
SimLocationActuator simLocationActuator = idComponentMatcher.remove(pPersonID);
if (simLocationActuator != null) {
try {
PedestrianInformationComponent personHostComponent = simLocationActuator.getHost().getComponent(PedestrianInformationComponent.class);
personHostComponent.resetPersonID();
} 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 person. If no component has been assigned to the person yet, a new component is assigned.
* @param pPersonID The person for which a component is requested.
* @throws RuntimeException If no component can be assigned.
* @return The component for the person.
*/
private SimLocationActuator requestSimActuator(String pPersonID) {
if (!idComponentMatcher.containsKey(pPersonID)) {
SimLocationActuator simLocationActuator = freeComponents.poll();
if (simLocationActuator != null) {
PedestrianInformationComponent pedestrianHostComponent;
try {
pedestrianHostComponent = simLocationActuator.getHost().getComponent(PedestrianInformationComponent.class);
} catch (ComponentNotAvailableException e) {
Host host = simLocationActuator.getHost();
boolean routeKnown;
if (_knownRoutesRandom.nextDouble() < _percentageOfKnownRoutes) {
routeKnown = true;
} else {
routeKnown = false;
}
pedestrianHostComponent = new DefaultPersonInformationComponent(host, _controller, _extractor, routeKnown);
host.registerComponent(pedestrianHostComponent);
}
pedestrianHostComponent.setPedestrianID(pPersonID);
idComponentMatcher.put(pPersonID, simLocationActuator);
hostVehicleIDMatching.put(simLocationActuator.getHost().getId(), pPersonID);
} else {
throw new RuntimeException("Unable to assign new components. Please increase node amount" + (_reuseComponents?".":" or enable the reuse of components."));
}
}
return idComponentMatcher.get(pPersonID);
}
public static RoadNetwork getRoadNetwork() {
return MOVEMENT._extractor.getRoadNetwork();
}
public static String getPedestrianType(String pPersonID) {
return MOVEMENT._controller.getPersonType(pPersonID);
}
}
......@@ -6,10 +6,7 @@ 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.TrafficLightController;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.api.VehicleController;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.api.*;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.api.information.LocationUtils;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.*;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.exception.NoAdditionalRouteAvailableException;
......@@ -35,7 +32,7 @@ import java.util.*;
* @version 1.0 at 06.11.2017
*
*/
public class TraciSimulationController implements VehicleController, SimulationSetupExtractor, EdgeController, SimulatorObserver, TrafficLightController {
public class TraciSimulationController implements VehicleController, SimulationSetupExtractor, EdgeController, SimulatorObserver, TrafficLightController, PersonController {
private static final File TEMP_FILE = new File(new File(System.getProperty("java.io.tmpdir")), "road_network.tmp");
private Random _random = Randoms.getRandom(getClass());
......@@ -159,6 +156,41 @@ public class TraciSimulationController implements VehicleController, SimulationS
}
}
@Override
public double getPersonSpeed(String pPersonID) {
return 0;
}
@Override
public void stopPerson(String pPerson) {
}
@Override
public String getPersonType(String pPersonID) {
return null;
}
@Override
public void setPersonSpeed(String pPersonID, double pPersonSpeed) {
}
@Override
public void setPersonMaxSpeed(String pPersonID, double pPersonSpeed) {
}
@Override
public void setPersonGap(String pPersonID, double gap) {
}
@Override
public String getPersonRoadId(String pPersonID) {
return null;
}
private String getSummaryFilename(String tripOutputFile) {
Path path = Paths.get(_configFile);
return path.getParent().toString() + "/summary/" + tripOutputFile;
......@@ -511,6 +543,16 @@ public class TraciSimulationController implements VehicleController, SimulationS
return false;
}
@Override
public List<String> getAllPersons() {
return null;
}
@Override
public List<String> getAllPersons(double pStep) {
return null;
}
public String getVehicleType(String pVehicleID) {
String vehicleType = "default";
SumoCommand typeCommand = Vehicle.getTypeID(pVehicleID);
......@@ -565,6 +607,11 @@ public class TraciSimulationController implements VehicleController, SimulationS
return nextTLSList;
}
@Override
public double getPersonWaitingTime(String pPersonID) {
return 0;
}
/*
@Override
public long getWaitingTime(String vehicleID) {
......@@ -730,6 +777,11 @@ public class TraciSimulationController implements VehicleController, SimulationS
return edge;
}
@Override
public void reroutePerson(String pPersonID) {
}
@Override
public double getFuelConsumption(String vehicleID) {
SumoCommand fuelCmd = Vehicle.getFuelConsumption(vehicleID);
......@@ -822,6 +874,11 @@ public class TraciSimulationController implements VehicleController, SimulationS
return getStep();
}
@Override
public void reroutePerson(String pPersonID, RoadNetworkRoute pRoute) {
}
@Override
public void rerouteVehicle(String pVehicle, RoadNetworkRoute pRoute) {
SumoStringList routeEdges = new SumoStringList();
......@@ -842,6 +899,16 @@ public class TraciSimulationController implements VehicleController, SimulationS
_observedAreaSet = true;
}
@Override
public Location getPersonPosition(String pPersonID) {
return null;
}
@Override
public Location getPersonPosition(double pStep, String pPersonID) {
return null;
}
@Override
public double getScenarioWidth() {
SumoCommand netBoundaryCommand = Simulation.getNetBoundary();
......
/*
* 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.vehicular;
import de.tudarmstadt.maki.simonstrator.api.Host;
import de.tudarmstadt.maki.simonstrator.api.common.graph.INodeID;
import de.tudarmstadt.maki.simonstrator.api.component.ComponentNotAvailableException;
import de.tudarmstadt.maki.simonstrator.api.component.sis.SiSComponent;
import de.tudarmstadt.maki.simonstrator.api.component.sis.SiSDataCallback;
import de.tudarmstadt.maki.simonstrator.api.component.sis.SiSInfoProperties;
import de.tudarmstadt.maki.simonstrator.api.component.sis.SiSInformationProvider.SiSProviderHandle;
import de.tudarmstadt.maki.simonstrator.api.component.sis.exception.InformationNotAvailableException;
import de.tudarmstadt.maki.simonstrator.api.component.sis.type.SiSTypes;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.PedestrianInformationComponent;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.api.PersonController;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.api.SimulationSetupExtractor;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkEdge;
import de.tudarmstadt.maki.simonstrator.api.component.vehicular.roadnetwork.RoadNetworkRoute;
import java.util.List;
import java.util.Set;
public class DefaultPersonInformationComponent implements PedestrianInformationComponent {
private Host host;
private PersonController controller;
private SimulationSetupExtractor extractor;
private String personID;
public DefaultPersonInformationComponent(Host host, PersonController controller, SimulationSetupExtractor extractor, boolean pRouteKnown) {
this.host = host;
this.controller = controller;
this.extractor = extractor;
try {
SiSComponent siSComponent = getHost().getComponent(SiSComponent.class);
siSComponent.provide().nodeState(SiSTypes.ROAD_EDGE, new SiSDataCallback<RoadNetworkEdge>() {
@Override
public RoadNetworkEdge getValue(INodeID pNodeID,
SiSProviderHandle pProviderHandle)
throws InformationNotAvailableException {
if (pNodeID == getHost().getId()) {
if (isValid()) {
RoadNetworkRoute route = getCurrentRoute();
if (route != null) {
return route.getStart();
}
}
}
return null;
}
@Override
public Set<INodeID> getObservedNodes() {
return INodeID.getSingleIDSet(getHost().getId());
}
@Override
public SiSInfoProperties getInfoProperties() {
return new SiSInfoProperties();
}
});
/*
siSComponent.provide().nodeState(SiSTypes.HEADING, new SiSDataCallback<Double>() {
@Override
public Double getValue(INodeID pNodeID,
SiSProviderHandle pProviderHandle)
throws InformationNotAvailableException {
if (pNodeID == getHost().getId()) {
if (isValid()) {
return controller.getVehicleHeading(personID);
}
}
return null;
}
@Override
public Set<INodeID> getObservedNodes() {
return INodeID.getSingleIDSet(getHost().getId());
}
@Override
public SiSInfoProperties getInfoProperties() {
return new SiSInfoProperties();
}
});
*/
if (pRouteKnown) {
siSComponent.provide().nodeState(SiSTypes.ROUTE, new SiSDataCallback<RoadNetworkRoute>() {
@Override
public RoadNetworkRoute getValue(INodeID pNodeID,
SiSProviderHandle pProviderHandle)
throws InformationNotAvailableException {
if (pNodeID == getHost().getId()) {
if (isValid()) {
return getCurrentRoute();
}
}
return null;
}
@Override
public Set<INodeID> getObservedNodes() {
return INodeID.getSingleIDSet(getHost().getId());
}
@Override
public SiSInfoProperties getInfoProperties() {
return new SiSInfoProperties();
}
});
}
} catch (ComponentNotAvailableException e) {
// Nothing to do!
}
}
public PersonController getController() {
return controller;
}
@Override
public void setPedestrianID(String pPersonID) {
personID = pPersonID;
}
@Override
public String getPedestrianID() {
return personID;
}
@Override
public String getPedestrianType() {
return controller.getPersonType(personID);
}
@Override
public void setPedestrianSpeed(double pPedestrianSpeed) {
controller.setPersonSpeed(personID, pPedestrianSpeed);
}
@Override
public void setPedestrianGap(double pedestrianGap) {
controller.setPersonGap(personID, pedestrianGap);
}
@Override
public List<String> getNextTLS(String vehicleId) {
return controller.getNextTLS(vehicleId);
}
@Override
public double getPedestrianWaitingTime() {
return controller.getPersonWaitingTime(personID);
}
/*
@Override
public RoadNetwork getRoadNetwork() {
return controller.getRoadNetwork();
}
*/
@Override
public RoadNetworkEdge getCurrentRoad() {
return controller.getCurrentEdge(personID);
}
@Override
public double getStep() {
return controller.getStep();
}
@Override
public void resetPersonID() {
personID = null;
}
@Override
public void initialize() {
// TODO Auto-generated method stub
}
@Override
public void shutdown() {
// TODO Auto-generated method stub
}
@Override
public Host getHost() {
return host;
}
@Override
public boolean isValid() {
return personID != null;
}
@Override
public double getPedestrianCurrentSpeed() {
return controller.getPersonSpeed(personID);
}
@Override
public RoadNetworkRoute getCurrentRoute() {
return controller.getCurrentRoute(personID);
}
}
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