MATSIM
NetworkModeDepartureHandlerDefaultImpl.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * *
4  * *********************************************************************** *
5  * *
6  * copyright : (C) 2010 by the members listed in the COPYING, *
7  * LICENSE and WARRANTY file. *
8  * email : info at matsim dot org *
9  * *
10  * *********************************************************************** *
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * See also COPYING, LICENSE and WARRANTY file *
17  * *
18  * *********************************************************************** */
19 
20 package org.matsim.core.mobsim.qsim.qnetsimengine;
21 
22 import java.util.Collection;
23 
24 import com.google.inject.Inject;
25 import org.apache.logging.log4j.LogManager;
26 import org.apache.logging.log4j.Logger;
27 import org.matsim.api.core.v01.Id;
33 import org.matsim.vehicles.Vehicle;
34 
36  // needs to be public so it can be used as a delegate. Constructor is package-private (and should remain so). kai, jan'25
37 
38  private static final Logger log = LogManager.getLogger( NetworkModeDepartureHandlerDefaultImpl.class );
39 
40  private static int cntTeleportVehicle = 0;
41 
43 
45 
46  private final Collection<String> networkModes;
47 
48  @Inject /* deliberately package-private */ NetworkModeDepartureHandlerDefaultImpl( QNetsimEngineI qNetsimEngine, QSimConfigGroup qsimConfig ) {
49  this.qNetsimEngine = qNetsimEngine;
50  this.vehicleBehavior = qsimConfig.getVehicleBehavior();
51  this.networkModes =qsimConfig.getMainModes();
52  }
53 
54  @Override public boolean handleDeparture( double now, MobsimAgent agent, Id<Link> linkId ) {
55  if (this.networkModes.contains(agent.getMode() )) {
56  if ( agent instanceof MobsimDriverAgent ) {
57  handleNetworkModeDeparture(now, (MobsimDriverAgent)agent, linkId );
58  return true;
59  } else {
60  throw new UnsupportedOperationException("wrong agent type to depart on a network mode");
61  }
62  }
63  return false;
64  }
65 
66  private void handleNetworkModeDeparture( double now, MobsimDriverAgent agent, Id<Link> linkId ) {
67  // The situation where a leg starts and ends at the same link used to be handled specially, for all agents except
68  // AbstractTransitDriverAgents. This however caused some problems in some cases, as apparently for taxicabs. Thus, such trips are now
69  // simulated normally. See MATSIM-233 for details. td apr'14
70  Id<Vehicle> vehicleId = agent.getPlannedVehicleId() ;
71  QLinkI qlink = (QLinkI) qNetsimEngine.getNetsimNetwork().getNetsimLink(linkId);
72  QVehicle vehicle = qlink.removeParkedVehicle(vehicleId);
73  if (vehicle == null) {
74  if (vehicleBehavior == VehicleBehavior.teleport) {
75  vehicle = qNetsimEngine.getVehicles().get(vehicleId);
76  if ( vehicle==null ) {
77  // log a maximum of information, to help the user identifying the cause of the problem
78  final String msg = "could not find requested vehicle "+vehicleId+" in simulation for agent "+agent+" with id "+agent.getId()+" on link "+agent.getCurrentLinkId()+" at time "+now+".";
79  log.error( msg );
80  log.error( "Note that, with AgentSource and if the agent starts on a leg, the vehicle needs to be inserted BEFORE the agent!") ;
81  throw new RuntimeException( msg+" aborting ...") ;
82  }
83  teleportVehicleTo(vehicle, linkId, qNetsimEngine);
84 
85  vehicle.setDriver(agent);
86  agent.setVehicle(vehicle) ;
87 
88  qlink.letVehicleDepart(vehicle);
89  // (since the "teleportVehicle" does not physically move the vehicle, this is finally achieved in the departure
90  // logic. kai, nov'11)
91  } else if (vehicleBehavior == VehicleBehavior.wait ) {
92  // While we are waiting for our car
94  } else {
95  throw new RuntimeException("vehicle " + vehicleId + " not available for agent " + agent.getId() + " on link " + linkId + " at time "+ now);
96  }
97  } else {
98  vehicle.setDriver(agent);
99  agent.setVehicle(vehicle) ;
100  qlink.letVehicleDepart(vehicle);
101  }
102  }
103 
104  public static void teleportVehicleTo(QVehicle vehicle, Id<Link> linkId, QNetsimEngineI qNetsimEngine ) {
105  if (vehicle.getCurrentLink() != null) {
106 
107  if (cntTeleportVehicle < 9) {
108  cntTeleportVehicle++;
109  log.info("teleport vehicle " + vehicle.getId() + " from link " + vehicle.getCurrentLink().getId() + " to link " + linkId);
110  if (cntTeleportVehicle == 9) {
111  log.info("No more occurrences of teleported vehicles will be reported.");
112  }
113  }
114  QLinkI qlinkOld = (QLinkI) qNetsimEngine.getNetsimNetwork().getNetsimLink(vehicle.getCurrentLink().getId());
115  QVehicle result = qlinkOld.removeParkedVehicle(vehicle.getId());
116  if ( result==null ) {
117  throw new RuntimeException( "Could not remove parked vehicle with id " + vehicle.getId() +" on the link id "
118  + vehicle.getCurrentLink().getId()
119  + ". Maybe it is currently used by someone else?"
120  + " (In which case ignoring this exception would lead to duplication of this vehicle.) "
121  + "Maybe was never placed onto a link?" );
122  }
123  }
124  }
125 
126 }
NetsimLink getNetsimLink(final Id< Link > id)
static void teleportVehicleTo(QVehicle vehicle, Id< Link > linkId, QNetsimEngineI qNetsimEngine)