MATSIM
TransitDriverAgentImpl.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.pt;
21 
22 import java.util.Iterator;
23 import java.util.ListIterator;
24 
25 import org.matsim.api.core.v01.Id;
26 import org.matsim.api.core.v01.Scenario;
36 import org.matsim.core.gbl.Gbl;
44 import org.matsim.pt.PtConstants;
45 import org.matsim.pt.Umlauf;
46 import org.matsim.pt.UmlaufStueckI;
50 import org.matsim.vehicles.Vehicle;
51 
56 
58 
59  private static class PlanBuilder {
60 
61  final Plan plan = PopulationUtils.createPlan();
62 
63  static final String activityType = PtConstants.TRANSIT_ACTIVITY_TYPE;
64 
65  public void addTrip(NetworkRoute networkRoute, String transportMode) {
66  Activity lastActivity;
67  if (!plan.getPlanElements().isEmpty()) {
68  lastActivity = (Activity) plan.getPlanElements().get(plan.getPlanElements().size()-1);
69  assert lastActivity.getLinkId().equals(networkRoute.getStartLinkId());
70  } else {
71  lastActivity = PopulationUtils.createActivityFromLinkId(activityType, networkRoute.getStartLinkId());
72  plan.addActivity(lastActivity);
73  }
74  Leg leg = PopulationUtils.createLeg(transportMode);
75  leg.setRoute(networkRoute);
76  plan.addLeg(leg);
77  Activity activity = PopulationUtils.createActivityFromLinkId(activityType, networkRoute.getEndLinkId());
78  plan.addActivity(activity);
79  }
80 
81  public Plan build() {
82  return plan;
83  }
84 
85  }
86 
87  private final Umlauf umlauf;
88  private final Iterator<UmlaufStueckI> iUmlaufStueck;
89  private final ListIterator<PlanElement> iPlanElement;
91  private double departureTime;
96  private Scenario scenario;
97 
99  String transportMode,
101  super(internalInterface, thisAgentTracker);
102  this.umlauf = umlauf;
103  this.eventsManager = internalInterface.getMobsim().getEventsManager();
104  this.scenario = internalInterface.getMobsim().getScenario() ;
105  // (yy AbstractTransitDriverAgent already keeps both of them. kai, dec'15)
106  this.iUmlaufStueck = this.umlauf.getUmlaufStuecke().iterator();
107  Person driverPerson = PopulationUtils.getFactory().createPerson(Id.create("pt_" + umlauf.getId(), Person.class)); // we use the non-wrapped route for efficiency, but the leg has to return the wrapped one.
108  PlanBuilder planBuilder = new PlanBuilder();
109  for (UmlaufStueckI umlaufStueck : umlauf.getUmlaufStuecke()) {
110  NetworkRoute carRoute2 = umlaufStueck.getCarRoute();
111  Gbl.assertNotNull(carRoute2);
112  planBuilder.addTrip(getWrappedCarRoute(carRoute2), transportMode);
113  }
114  Plan plan = planBuilder.build();
115  driverPerson.addPlan(plan);
116  driverPerson.setSelectedPlan(plan);
117  setDriver(driverPerson);
118  iPlanElement = plan.getPlanElements().listIterator();
119  this.currentPlanElement = iPlanElement.next();
120  setNextLeg();
121  }
122 
123  @Override
124  public void endActivityAndComputeNextState(final double now) {
125  this.currentPlanElement = iPlanElement.next();
126  sendTransitDriverStartsEvent(now);
127 
128 // this.sim.arrangeAgentDeparture(this);
129  this.state = MobsimAgent.State.LEG ;
130 // this.sim.reInsertAgentIntoMobsim(this) ;
131 
132  }
133 
134  @Override
135  public void endLegAndComputeNextState(final double now) {
136  eventsManager.processEvent(
137  new PersonArrivalEvent(now, this.getId(), this.getDestinationLinkId(), this.getCurrentLeg().getMode()));
138  this.currentPlanElement = iPlanElement.next();
139  if (this.iUmlaufStueck.hasNext()) {
140  setNextLeg();
141  if (this.departureTime < now) {
142  this.departureTime = now;
143  }
144 
145 // this.sim.arrangeActivityStart(this);
146  this.state = MobsimAgent.State.ACTIVITY ;
147 // this.sim.reInsertAgentIntoMobsim(this) ;
148 
149 
150  } else {
151  // inserting an activity with end time infinity. one can debate if this is a hack:
152  // * in general, a MobsimAgent can construct its path through the day on the fly
153  // * in this particular instance, the agent pretends to have a plan
154  // kai, mar'12
155 
156  this.state = MobsimAgent.State.ACTIVITY ;
157  this.departureTime = Double.POSITIVE_INFINITY ;
158 
159  }
160  }
161 
162  private void setNextLeg() {
163  UmlaufStueckI umlaufStueck = this.iUmlaufStueck.next();
164  if (umlaufStueck.isFahrt()) {
165  setLeg(umlaufStueck.getLine(), umlaufStueck.getRoute(), umlaufStueck.getDeparture());
166  } else {
167  setWenden(umlaufStueck.getCarRoute());
168  }
169  init();
170  }
171 
172  private void setWenden(NetworkRoute carRoute) {
173  this.transitLine = null;
174  this.transitRoute = null;
175  this.departure = null;
176  this.carRoute = carRoute;
177  }
178 
179  private void setLeg(final TransitLine line, final TransitRoute route, final Departure departure) {
180  this.transitLine = line;
181  this.transitRoute = route;
182  this.departure = departure;
183  this.departureTime = departure.getDepartureTime();
184  this.carRoute = route.getRoute();
185  }
186 
187  @Override
188  Leg getCurrentLeg() {
189  return (Leg) this.currentPlanElement;
190  }
191 
192  @Override
194  return ((Leg) this.currentPlanElement).getTravelTime();
195  }
196 
197  @Override
198  public Double getExpectedTravelDistance() {
199  return ((Leg) this.currentPlanElement).getRoute().getDistance();
200  }
201 
202  @Override
203  public String getMode() {
204  return ((Leg)this.currentPlanElement).getMode();
205  }
206 
207  @Override
209  Route route = ((Leg)this.currentPlanElement).getRoute() ;
210  return ((NetworkRoute)route).getVehicleId() ;
211  }
212 
213 // @Override
214 // public Activity getCurrentActivity() {
215 // return (Activity) this.currentPlanElement;
216 // }
217 
218  @Override
220  return this.currentPlanElement;
221  }
222 
223  @Override
225  if (iPlanElement.hasNext()) {
226  PlanElement next = iPlanElement.next(); // peek at the next element, but...
227  iPlanElement.previous(); // ...rewind iterator by one step
228  return next;
229  } else {
230  return null ;
231  }
232  }
233  @Override
235  if (iPlanElement.hasPrevious()) {
236  PlanElement prev = iPlanElement.previous(); // peek at the element, but...
237  iPlanElement.next(); // ...rewind iterator by one step
238  return prev;
239  } else {
240  return null ;
241  }
242  }
243 
244  @Override
246  return getCurrentLeg().getRoute().getEndLinkId();
247  }
248 
249  @Override
251  return this.carRoute;
252  }
253 
254  @Override
256  return this.transitLine;
257  }
258 
259  @Override
261  return this.transitRoute;
262  }
263 
264  @Override
266  return this.departure;
267  }
268 
269  @Override
270  public double getActivityEndTime() {
271  return this.departureTime;
272  }
273 
274  @Override
275  public Plan getCurrentPlan() {
276  return PopulationUtils.unmodifiablePlan(this.getPerson().getSelectedPlan());
277  }
278 
279  @Override
281  // The following is the old condition: Being at the end of the plan means you arrive anyways, no matter if you are on the right or wrong link.
282  // kai, nov'14
283  if ( this.chooseNextLinkId()==null ) {
284  return true ;
285  } else {
286  return false ;
287  }
288  }
289 
290  @Override
292  PlanElement pe = this.getCurrentPlanElement() ;
293  Activity activity ;
294  if ( pe instanceof Activity ) {
295  activity = (Activity) pe;
296  } else if ( pe instanceof Leg ) {
297  activity = (Activity) this.getPreviousPlanElement() ;
298  } else {
299  throw new RuntimeException("unexpected type of PlanElement") ;
300  }
301  return FacilitiesUtils.toFacility( activity, this.scenario.getActivityFacilities() );
302 
303  // the above assumes alternating acts/legs. I start having the suspicion that we should revoke our decision to give that up.
304  // If not, one will have to use TripUtils to find the preceeding activity ... but things get more difficult. Preferably, the
305  // facility should then sit in the leg (since there it is used for routing). kai, dec'15
306  }
307 
308  @Override
310  PlanElement pe = this.getCurrentPlanElement() ;
311  if ( pe instanceof Leg ) {
312  Activity activity = (Activity)this.getNextPlanElement() ;
313  return FacilitiesUtils.toFacility( activity, this.scenario.getActivityFacilities() );
314  } else if ( pe instanceof Activity ) {
315  return null ;
316  }
317  throw new RuntimeException("unexpected type of PlanElement") ;
318  }
319 
320 
321 
322 
323 }
TransitDriverAgentImpl(Umlauf umlauf, String transportMode, TransitStopAgentTracker thisAgentTracker, InternalInterface internalInterface)
static Activity createActivityFromLinkId(String type, Id< Link > linkId)
static final String TRANSIT_ACTIVITY_TYPE
static< T > Id< T > create(final long key, final Class< T > type)
Definition: Id.java:68
void addTrip(NetworkRoute networkRoute, String transportMode)
void addActivity(final Activity act)
static Leg createLeg(String transportMode)
List< PlanElement > getPlanElements()
static void assertNotNull(Object obj)
Definition: Gbl.java:212
EventsManager getEventsManager()
Definition: QSim.java:565
NetworkRoute getCarRoute()
ActivityFacilities getActivityFacilities()
abstract void setSelectedPlan(T selectedPlan)
List< UmlaufStueckI > getUmlaufStuecke()
void setLeg(final TransitLine line, final TransitRoute route, final Departure departure)
static Facility toFacility(final Activity toWrap, ActivityFacilities activityFacilities)