MATSIM
DefaultTeleportationEngine.java
Go to the documentation of this file.
1 
2 /* *********************************************************************** *
3  * project: org.matsim.*
4  * DefaultTeleportationEngine.java
5  * *
6  * *********************************************************************** *
7  * *
8  * copyright : (C) 2019 by the members listed in the COPYING, *
9  * LICENSE and WARRANTY file. *
10  * email : info at matsim dot org *
11  * *
12  * *********************************************************************** *
13  * *
14  * This program is free software; you can redistribute it and/or modify *
15  * it under the terms of the GNU General Public License as published by *
16  * the Free Software Foundation; either version 2 of the License, or *
17  * (at your option) any later version. *
18  * See also COPYING, LICENSE and WARRANTY file *
19  * *
20  * *********************************************************************** */
21 
22  package org.matsim.core.mobsim.qsim;
23 
24 import java.util.Collection;
25 import java.util.Comparator;
26 import java.util.LinkedHashMap;
27 import java.util.PriorityQueue;
28 import java.util.Queue;
29 
30 import jakarta.inject.Inject;
31 
32 import org.apache.logging.log4j.LogManager;
33 import org.apache.logging.log4j.Logger;
34 import org.matsim.api.core.v01.Coord;
35 import org.matsim.api.core.v01.Id;
36 import org.matsim.api.core.v01.Scenario;
48 
53 public final class DefaultTeleportationEngine implements TeleportationEngine {
54  private static final Logger log = LogManager.getLogger( DefaultTeleportationEngine.class ) ;
55 
56  private final Queue<Tuple<Double, MobsimAgent>> teleportationList = new PriorityQueue<>(
57  30, new Comparator<Tuple<Double, MobsimAgent>>() {
58 
59  @Override
60  public int compare(Tuple<Double, MobsimAgent> o1, Tuple<Double, MobsimAgent> o2) {
61  int ret = o1.getFirst().compareTo(o2.getFirst()); // first compare time information
62  if (ret == 0) {
63  ret = o2.getSecond()
64  .getId()
65  .compareTo(o1.getSecond()
66  .getId()); // if they're equal, compare the Ids: the one with the larger Id should be first
67  }
68  return ret;
69  }
70  });
71  private final LinkedHashMap<Id<Person>, TeleportationVisData> teleportationData = new LinkedHashMap<>();
73  private Scenario scenario;
75 
76  private final boolean withTravelTimeCheck;
77 
78  @Inject
79  public DefaultTeleportationEngine(Scenario scenario, EventsManager eventsManager) {
81  }
82 
83  public DefaultTeleportationEngine(Scenario scenario, EventsManager eventsManager, boolean withTravelTimeCheck) {
84  this.scenario = scenario;
85  this.eventsManager = eventsManager;
86  this.withTravelTimeCheck = withTravelTimeCheck;
87  }
88 
89  @Override
90  public boolean handleDeparture(double now, MobsimAgent agent, Id<Link> linkId) {
91  if (agent.getExpectedTravelTime().isUndefined()) {
92  LogManager.getLogger(this.getClass()).info("mode: " + agent.getMode());
93  throw new RuntimeException("teleportation does not work when travel time is undefined. There is also really no magic fix for this,"
94  + " since we cannot guess travel times for arbitrary modes and arbitrary landscapes. kai/mz, apr'15 & feb'16") ;
95  }
96 
97  double travelTime = agent.getExpectedTravelTime().seconds() ;
98  if ( withTravelTimeCheck ) {
99  Double speed = scenario.getConfig().routing().getTeleportedModeSpeeds().get( agent.getMode() ) ;
100  Facility dpfac = agent.getCurrentFacility() ;
101  Facility arfac = agent.getDestinationFacility() ;
102  travelTime = DefaultTeleportationEngine.travelTimeCheck(travelTime, speed, dpfac, arfac);
103  }
104 
105  double arrivalTime = now + travelTime ;
106  this.teleportationList.add(new Tuple<>(arrivalTime, agent));
107 
108  // === below here is only visualization, no dynamics ===
109  Id<Person> agentId = agent.getId();
110  Link currLink = this.scenario .getNetwork().getLinks().get(linkId);
111  Link destLink = this.scenario .getNetwork().getLinks().get(agent.getDestinationLinkId());
112  Coord fromCoord = currLink.getToNode().getCoord();
113  Coord toCoord = destLink.getToNode().getCoord();
114  TeleportationVisData agentInfo = new TeleportationVisData(now, agentId, fromCoord, toCoord, travelTime);
115  this.teleportationData.put(agentId, agentInfo);
116 
117  return true;
118  }
119 
120  @Override
121  public Collection<AgentSnapshotInfo> addAgentSnapshotInfo(Collection<AgentSnapshotInfo> snapshotList) {
122  double time = internalInterface.getMobsim().getSimTimer().getTimeOfDay();
123  for (TeleportationVisData teleportationVisData : teleportationData.values()) {
124  teleportationVisData.updatePosition(time);
125  snapshotList.add(teleportationVisData);
126  }
127  return snapshotList;
128  }
129 
130  @Override
131  public void doSimStep(double time) {
133  }
134 
135  private void handleTeleportationArrivals(double now) {
136  while (!teleportationList.isEmpty()) {
137  Tuple<Double, MobsimAgent> entry = teleportationList.peek();
138  if (entry.getFirst() <= now) {
139  teleportationList.poll();
140  MobsimAgent personAgent = entry.getSecond();
142  double distance = personAgent.getExpectedTravelDistance();
143  this.eventsManager.processEvent(
144  new TeleportationArrivalEvent(now, personAgent.getId(), distance, personAgent.getMode()));
145  personAgent.endLegAndComputeNextState(now);
146  this.teleportationData.remove(personAgent.getId());
147  internalInterface.arrangeNextAgentState(personAgent);
148  } else {
149  break;
150  }
151  }
152  }
153 
154  @Override
155  public void onPrepareSim() {
156  }
157 
158  @Override
159  public void afterSim() {
160  double now = internalInterface.getMobsim().getSimTimer().getTimeOfDay();
161  for (Tuple<Double, MobsimAgent> entry : teleportationList) {
162  MobsimAgent agent = entry.getSecond();
163  eventsManager.processEvent(new PersonStuckEvent(now, agent.getId(), agent.getDestinationLinkId(), agent.getMode()));
164  }
165  teleportationList.clear();
166  }
167 
168  @Override
169  public void setInternalInterface(InternalInterface internalInterface) {
170  this.internalInterface = internalInterface;
171  }
172 
173  private static Double travelTimeCheck(Double travelTime, Double speed, Facility dpfac, Facility arfac) {
174  if ( speed==null ) {
175  // if we don't have a bushwhacking speed, the only thing we can do is trust the router
176  return travelTime ;
177  }
178 
179  if ( dpfac == null || arfac == null ) {
180  log.warn( "dpfac = " + dpfac ) ;
181  log.warn( "arfac = " + arfac ) ;
182  throw new RuntimeException("have bushwhacking mode but nothing that leads to coordinates; don't know what to do ...") ;
183  // (means that the agent is not correctly implemented)
184  }
185 
186  if ( dpfac.getCoord()==null || arfac.getCoord()==null ) {
187  // yy this is for example the case if activities are initialized at links, without coordinates. Could use the link coordinate
188  // instead, but somehow this does not feel any better. kai, feb'16
189 
190  return travelTime ;
191  }
192 
193  final Coord dpCoord = dpfac.getCoord();
194  final Coord arCoord = arfac.getCoord();
195 
196  double dist = NetworkUtils.getEuclideanDistance( dpCoord, arCoord ) ;
197  double travelTimeTmp = dist / speed ;
198 
199  if ( travelTimeTmp < travelTime ) {
200  return travelTime ;
201  }
202 
203  return travelTimeTmp ;
204  }
205 }
boolean handleDeparture(double now, MobsimAgent agent, Id< Link > linkId)
final LinkedHashMap< Id< Person >, TeleportationVisData > teleportationData
DefaultTeleportationEngine(Scenario scenario, EventsManager eventsManager)
void arrangeNextAgentState(MobsimAgent agent)
Collection< AgentSnapshotInfo > addAgentSnapshotInfo(Collection< AgentSnapshotInfo > snapshotList)
DefaultTeleportationEngine(Scenario scenario, EventsManager eventsManager, boolean withTravelTimeCheck)
final Queue< Tuple< Double, MobsimAgent > > teleportationList
void endLegAndComputeNextState(final double now)
static Double travelTimeCheck(Double travelTime, Double speed, Facility dpfac, Facility arfac)
QSimConfigGroup qsim()
Definition: Config.java:447
static double getEuclideanDistance(Coord origin, Coord destination)
RoutingConfigGroup routing()
Definition: Config.java:439
Map< Id< Link >, ? extends Link > getLinks()
void setInternalInterface(InternalInterface internalInterface)
void notifyArrivalOnLinkByNonNetworkMode(final Id< Link > linkId)