MATSIM
TransitQSimEngine.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  *
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2010 by the members listed in the COPYING, *
8  * LICENSE and WARRANTY file. *
9  * email : info at matsim dot org *
10  * *
11  * *********************************************************************** *
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * See also COPYING, LICENSE and WARRANTY file *
18  * *
19  * *********************************************************************** */
20 
21 package org.matsim.core.mobsim.qsim.pt;
22 
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.List;
27 import java.util.Map.Entry;
28 
29 import org.apache.logging.log4j.LogManager;
30 import org.apache.logging.log4j.Logger;
31 import org.matsim.api.core.v01.Id;
32 import org.matsim.api.core.v01.Scenario;
40 import org.matsim.core.mobsim.qsim.QSim;
44 import org.matsim.pt.Umlauf;
45 import org.matsim.pt.UmlaufBuilder;
48 import org.matsim.vehicles.Vehicle;
50 
51 import jakarta.inject.Inject;
52 
58 
59 
60  private Collection<MobsimAgent> ptDrivers;
62 
64 
65  public TransitAgentTriesToTeleportException(String message) {
66  super(message);
67  }
68 
69  private static final long serialVersionUID = 1L;
70 
71  }
72 
73  private static final Logger log = LogManager.getLogger(TransitQSimEngine.class);
74 
75  private final QSim qSim;
76 
77  private TransitSchedule schedule = null;
78 
80 
82 
84 
86 
87  @Override
88  public void setInternalInterface( InternalInterface internalInterface ) {
89  this.internalInterface = internalInterface ;
90  }
91 
92  TransitQSimEngine(QSim queueSimulation) {
93  this(queueSimulation, new SimpleTransitStopHandlerFactory(),
94  new ReconstructingUmlaufBuilder(queueSimulation.getScenario()),
95  new TransitStopAgentTracker(queueSimulation.getEventsManager()),
97  }
98 
99  @Inject
100  public TransitQSimEngine(QSim queueSimulation, TransitStopHandlerFactory stopHandlerFactory,
101  UmlaufBuilder umlaufBuilder, TransitStopAgentTracker tracker,
102  TransitDriverAgentFactory transitDriverFactory) {
103  // This should be package-private. See https://github.com/google/guice/wiki/KeepConstructorsHidden .
104 
105  this.qSim = queueSimulation;
106  this.schedule = queueSimulation.getScenario().getTransitSchedule();
107  this.umlaufBuilder = umlaufBuilder;
108  this.agentTracker = tracker;
109  this.stopHandlerFactory = stopHandlerFactory;
110  this.transitDriverFactory = transitDriverFactory;
111  }
112 
113  // For tests (which create an Engine, and externally create Agents as well).
115  // yyyy exposing this in this way defeats its purpose (which was to restrict who can add or remove agents into or from the mobsim). --> move
116  // test into same package so we can remove the public. kai, feb'25
117  return this.internalInterface;
118  }
119 
120  @Override
121  public void onPrepareSim() {
122  //nothing to do here
123  }
124 
125 
126  @Override
127  public void afterSim() {
128  double now = this.qSim.getSimTimer().getTimeOfDay();
129  for (Entry<Id<TransitStopFacility>, List<PTPassengerAgent>> agentsAtStop : this.agentTracker.getAgentsAtStop().entrySet()) {
130  TransitStopFacility stop = this.schedule.getFacilities().get(agentsAtStop.getKey());
131  for (PTPassengerAgent agent : agentsAtStop.getValue()) {
132  this.qSim.getEventsManager().processEvent(new PersonStuckEvent( now, agent.getId(), stop.getLinkId(), ((MobsimAgent)agent).getMode()));
133  this.qSim.getAgentCounter().decLiving();
134  this.qSim.getAgentCounter().incLost();
135  }
136  }
137  }
138 
139  private Collection<MobsimAgent> createVehiclesAndDriversWithUmlaeufe() {
140  Scenario scenario = this.qSim.getScenario();
141  Vehicles vehicles = scenario.getTransitVehicles();
142  Collection<MobsimAgent> drivers = new ArrayList<>();
143  UmlaufCache umlaufCache = getOrCreateUmlaufCache( scenario );
144 
145  for (Umlauf umlauf : umlaufCache.getUmlaeufe()) {
146  Vehicle basicVehicle = vehicles.getVehicles().get(umlauf.getVehicleId());
147  if (!umlauf.getUmlaufStuecke().isEmpty()) {
148  MobsimAgent driver = createAndScheduleVehicleAndDriver(umlauf, basicVehicle);
149  drivers.add(driver);
150  }
151  }
152  return drivers;
153  }
154 
155  private UmlaufCache getOrCreateUmlaufCache(final Scenario scenario) {
156  UmlaufCache umlaufCache;
157 
158  Collection<Umlauf> umlaeufe = umlaufBuilder.build();
159  umlaufCache = new UmlaufCache(scenario.getTransitSchedule(), umlaeufe);
160 
161  return umlaufCache;
162  }
163 
165  TransitQVehicle veh = new TransitQVehicle(vehicle);
166  AbstractTransitDriverAgent driver = this.transitDriverFactory.createTransitDriver(umlauf, internalInterface, agentTracker);
167  veh.setDriver(driver);
168  veh.setStopHandler(this.stopHandlerFactory.createTransitStopHandler(veh.getVehicle()));
169  driver.setVehicle(veh);
170  Leg firstLeg = (Leg) driver.getNextPlanElement();
171  Id<Link> startLinkId = firstLeg.getRoute().getStartLinkId();
172  this.qSim.addParkedVehicle(veh, startLinkId);
173  this.qSim.insertAgentIntoMobsim(driver);
174  return driver;
175  }
176 
177  private void handleAgentPTDeparture(final MobsimAgent planAgent, Id<Link> linkId) {
178  // this puts the agent into the transit stop.
179  Id<TransitStopFacility> accessStopId = ((PTPassengerAgent) planAgent).getDesiredAccessStopId();
180  if (accessStopId == null) {
181  // looks like this agent has a bad transit route, likely no
182  // route could be calculated for it
183  log.error("pt-agent doesn't know to what transit stop to go. Removing agent from simulation. Agent " + planAgent.getId().toString());
184  this.qSim.getAgentCounter().decLiving();
185  this.qSim.getAgentCounter().incLost();
186  return;
187  }
188  TransitStopFacility stop = this.schedule.getFacilities().get(accessStopId);
189  if (stop.getLinkId() == null || stop.getLinkId().equals(linkId)) {
190  double now = this.qSim.getSimTimer().getTimeOfDay();
191  this.agentTracker.addAgentToStop(now, (PTPassengerAgent) planAgent, stop.getId());
192  this.internalInterface.registerAdditionalAgentOnLink(planAgent) ;
193  } else {
194  throw new TransitAgentTriesToTeleportException("Agent "+planAgent.getId() + " tries to enter a transit stop at link "+stop.getLinkId()+" but really is at "+linkId+"!");
195  }
196  }
197 
198  @Override
199  public boolean handleDeparture(double now, MobsimAgent agent, Id<Link> linkId) {
200  String requestedMode = agent.getMode();
201  if (qSim.getScenario().getConfig().transit().getTransitModes().contains(requestedMode)) {
202  handleAgentPTDeparture(agent, linkId);
203  return true ;
204  }
205  return false ;
206  }
207 
208  @Override
210  return agentTracker;
211  }
212 
213  @Override
214  public void doSimStep(double time) {
215  // Nothing to do here.
216  }
217 
218  @Override
219  public void insertAgentsIntoMobsim() {
221  }
222 
223  public Collection<MobsimAgent> getPtDrivers() {
224  return Collections.unmodifiableCollection(ptDrivers);
225  }
226 
227 
228 }
AbstractTransitDriverAgent createTransitDriver(Umlauf umlauf, InternalInterface internalInterface, TransitStopAgentTracker transitStopAgentTracker)
void handleAgentPTDeparture(final MobsimAgent planAgent, Id< Link > linkId)
TransitQSimEngine(QSim queueSimulation, TransitStopHandlerFactory stopHandlerFactory, UmlaufBuilder umlaufBuilder, TransitStopAgentTracker tracker, TransitDriverAgentFactory transitDriverFactory)
Map< Id< TransitStopFacility >, TransitStopFacility > getFacilities()
void addAgentToStop(final double now, final PTPassengerAgent agent, final Id< TransitStopFacility > stopId)
Collection< MobsimAgent > createVehiclesAndDriversWithUmlaeufe()
void setInternalInterface(InternalInterface internalInterface)
abstract Collection< Umlauf > build()
AbstractTransitDriverAgent createAndScheduleVehicleAndDriver(Umlauf umlauf, Vehicle vehicle)
void insertAgentIntoMobsim(final MobsimAgent agent)
Definition: QSim.java:430
void registerAdditionalAgentOnLink(MobsimAgent agent)
UmlaufCache getOrCreateUmlaufCache(final Scenario scenario)
TransitStopHandler createTransitStopHandler(Vehicle vehicle)
TransitConfigGroup transit()
Definition: Config.java:451
EventsManager getEventsManager()
Definition: QSim.java:565
boolean handleDeparture(double now, MobsimAgent agent, Id< Link > linkId)
AgentCounter getAgentCounter()
Definition: QSim.java:629
Map< Id< Vehicle >, Vehicle > getVehicles()
TransitSchedule getTransitSchedule()
Map< Id< TransitStopFacility >, List< PTPassengerAgent > > getAgentsAtStop()
void setStopHandler(TransitStopHandler stopHandler)
void addParkedVehicle(MobsimVehicle veh, Id< Link > startLinkId)
Definition: QSim.java:305
final TransitDriverAgentFactory transitDriverFactory