SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSPerson.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // The class for modelling person-movements
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
13 // Copyright (C) 2001-2013 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 
34 #include <string>
35 #include <vector>
38 #include <utils/common/ToString.h>
39 #include "MSNet.h"
40 #include "MSEdge.h"
41 #include "MSLane.h"
42 #include "MSPerson.h"
43 #include "MSPersonControl.h"
44 #include "MSInsertionControl.h"
45 #include "MSVehicle.h"
46 
47 #ifdef CHECK_MEMORY_LEAKS
48 #include <foreign/nvwa/debug_new.h>
49 #endif // CHECK_MEMORY_LEAKS
50 
51 /* -------------------------------------------------------------------------
52  * static member definitions
53  * ----------------------------------------------------------------------- */
55 
56 // ===========================================================================
57 // method definitions
58 // ===========================================================================
59 /* -------------------------------------------------------------------------
60  * MSPerson::MSPersonStage - methods
61  * ----------------------------------------------------------------------- */
63  : myDestination(destination), myDeparted(-1), myArrived(-1), myType(type) {}
64 
65 
67 
68 
69 const MSEdge&
71  return myDestination;
72 }
73 
74 
75 void
77  if (myDeparted < 0) {
78  myDeparted = now;
79  }
80 }
81 
82 
83 void
85  myArrived = now;
86 }
87 
88 
89 bool
90 MSPerson::MSPersonStage::isWaitingFor(const std::string& /*line*/) const {
91  return false;
92 }
93 
94 
97  // @todo: well, definitely not the nicest way... Should be precomputed
98  const MSLane* lane = e->getLanes()[0];
99  PositionVector shp = lane->getShape();
100  shp.move2side(offset);
102 }
103 
104 
105 SUMOReal
107  // @todo: well, definitely not the nicest way... Should be precomputed
108  PositionVector shp = e->getLanes()[0]->getShape();
109  return shp.rotationDegreeAtOffset(at);
110 }
111 
112 
113 
114 /* -------------------------------------------------------------------------
115  * MSPerson::MSPersonStage_Walking - methods
116  * ----------------------------------------------------------------------- */
117 MSPerson::MSPersonStage_Walking::MSPersonStage_Walking(const std::vector<const MSEdge*>& route,
118  MSBusStop* toBS,
119  SUMOTime walkingTime, SUMOReal speed,
120  SUMOReal departPos, SUMOReal arrivalPos) :
121  MSPersonStage(*route.back(), WALKING), myWalkingTime(walkingTime), myRoute(route),
122  myDepartPos(departPos), myArrivalPos(arrivalPos), myDestinationBusStop(toBS),
123  mySpeed(speed) {
125  myDepartPos, myRoute.front()->getLength(), SUMO_ATTR_DEPARTPOS, "person walking from " + myRoute.front()->getID());
127  myArrivalPos, myRoute.back()->getLength(), SUMO_ATTR_ARRIVALPOS, "person walking to " + myRoute.back()->getID());
128  if (walkingTime > 0) {
129  SUMOReal length = 0;
130  for (std::vector<const MSEdge*>::const_iterator i = route.begin(); i != route.end(); ++i) {
131  length += (*i)->getLength();
132  }
133  length -= myDepartPos;
134  length -= route.back()->getLength() - myArrivalPos;
135  mySpeed = length / STEPS2TIME(walkingTime);
136  }
137 }
138 
139 
141 
142 
143 const MSEdge*
145  return *myRouteStep;
146 }
147 
148 
149 const MSEdge*
151  return myRoute.front();
152 }
153 
154 
155 SUMOReal
157  SUMOReal off = STEPS2TIME(now - myLastEntryTime);
158  return myCurrentBeginPos + myCurrentLength / myCurrentDuration * off;
159 }
160 
161 
162 Position
164  const MSEdge* e = getEdge(now);
165  SUMOReal off = STEPS2TIME(now - myLastEntryTime);
166  return getEdgePosition(e, myCurrentBeginPos + myCurrentLength / myCurrentDuration * off, SIDEWALK_OFFSET);
167 }
168 
169 
170 SUMOReal
172  const MSEdge* e = getEdge(now);
173  SUMOReal off = STEPS2TIME(now - myLastEntryTime);
174  return getEdgeAngle(e, myCurrentBeginPos + myCurrentLength / myCurrentDuration * off) + 90;
175 }
176 
177 
178 void
180  MSEdge* previousEdge, const SUMOReal at) {
181  previousEdge->removePerson(person);
182  myRouteStep = myRoute.begin();
183  myLastEntryTime = now;
184  if (myWalkingTime == 0) {
185  if (!person->proceed(net, now)) {
187  };
188  return;
189  }
191  if (at >= 0) {
192  myDepartPos = at;
193  }
194  ((MSEdge*) *myRouteStep)->addPerson(person);
195  myRoute.size() == 1
196  ? computeWalkingTime(*myRouteStep, myDepartPos, myArrivalPos, myDestinationBusStop)
197  : computeWalkingTime(*myRouteStep, myDepartPos, -1, 0);
198  net->getBeginOfTimestepEvents().addEvent(new MoveToNextEdge(person, *this), now + TIME2STEPS(myCurrentDuration), MSEventControl::ADAPT_AFTER_EXECUTION);
199 }
200 
201 
202 void
204  if (bs != 0) {
205  toPos = bs->getEndLanePosition();
206  } else if (toPos < 0) {
207  toPos = e->getLanes()[0]->getLength();
208  }
209  if (fromPos < 0) {
210  fromPos = 0;
211  }
212  myCurrentBeginPos = fromPos;
213  myCurrentLength = toPos - fromPos;
214  assert(myCurrentLength >= 0);
215  myCurrentDuration = MAX2(myCurrentLength, (SUMOReal)1.0) / mySpeed;
216 }
217 
218 
219 void
221  os.openTag("walk").writeAttr("arrival", time2string(myArrived)).closeTag();
222 }
223 
224 
225 void
227  os.openTag("walk").writeAttr(SUMO_ATTR_EDGES, myRoute);
228  if (myWalkingTime > 0) {
229  os.writeAttr(SUMO_ATTR_DURATION, time2string(myWalkingTime));
230  } else if (mySpeed > 0) {
231  os.writeAttr(SUMO_ATTR_SPEED, mySpeed);
232  }
233  os.closeTag();
234 }
235 
236 
237 void
239  os.openTag("event").writeAttr("time", time2string(t)).writeAttr("type", "departure")
240  .writeAttr("agent", p.getID()).writeAttr("link", myRoute.front()->getID()).closeTag();
241 }
242 
243 
244 void
246  os.openTag("event").writeAttr("time", time2string(t)).writeAttr("type", "arrival")
247  .writeAttr("agent", p.getID()).writeAttr("link", myRoute.back()->getID()).closeTag();
248 }
249 
250 
251 SUMOTime
253  ((MSEdge*) *myRouteStep)->removePerson(person);
254  if (myRouteStep == myRoute.end() - 1) {
256  if (myDestinationBusStop != 0) {
257  myDestinationBusStop->addPerson(person);
258  }
259  if (!person->proceed(MSNet::getInstance(), currentTime)) {
261  }
262  return 0;
263  } else {
264  ++myRouteStep;
265  myRouteStep == myRoute.end() - 1
266  ? computeWalkingTime(*myRouteStep, 0, myArrivalPos, myDestinationBusStop)
267  : computeWalkingTime(*myRouteStep, 0, -1, 0);
268  ((MSEdge*) *myRouteStep)->addPerson(person);
269  myLastEntryTime = currentTime;
270  return TIME2STEPS(myCurrentDuration);
271  }
272 }
273 
274 
275 
276 /* -------------------------------------------------------------------------
277  * MSPerson::MSPersonStage_Driving - methods
278  * ----------------------------------------------------------------------- */
280  MSBusStop* toBS, const std::vector<std::string>& lines)
281  : MSPersonStage(destination, DRIVING), myLines(lines.begin(), lines.end()),
282  myVehicle(0), myDestinationBusStop(toBS) {}
283 
284 
286 
287 
288 const MSEdge*
290  if (myVehicle != 0) {
291  return myVehicle->getEdge();
292  }
293  return myWaitingEdge;
294 }
295 
296 
297 const MSEdge*
299  return myWaitingEdge;
300 }
301 
302 
303 SUMOReal
305  if (myVehicle != 0) {
306  // vehicle may already have passed the lane (check whether this is correct)
307  return MIN2(myVehicle->getPositionOnLane(), getEdge(now)->getLength());
308  }
309  return myWaitingPos;
310 }
311 
312 
313 Position
315  if (myVehicle != 0) {
317  return myVehicle->getEdge()->getLanes()[0]->getShape().positionAtOffset(myVehicle->getPositionOnLane());
318  }
319  return getEdgePosition(myWaitingEdge, myWaitingPos, SIDEWALK_OFFSET);
320 }
321 
322 
323 SUMOReal
325  if (myVehicle != 0) {
326  MSVehicle* veh = dynamic_cast<MSVehicle*>(myVehicle);
327  if (veh != 0) {
328  return veh->getAngle() + 90;
329  } else {
330  return 0;
331  }
332  }
333  return getEdgeAngle(myWaitingEdge, myWaitingPos);
334 }
335 
336 
337 
338 void
340  MSEdge* previousEdge, const SUMOReal at) {
341  myWaitingEdge = previousEdge;
342  myWaitingPos = at;
343  myWaitingSince = now;
344  myVehicle = net->getVehicleControl().getWaitingVehicle(previousEdge, myLines);
345  if (myVehicle != 0 && myVehicle->getParameter().departProcedure == DEPART_TRIGGERED) {
346  previousEdge->removePerson(person);
347  myVehicle->addPerson(person);
348  net->getInsertionControl().add(myVehicle);
349  net->getVehicleControl().removeWaiting(previousEdge, myVehicle);
351  } else {
352  net->getPersonControl().addWaiting(previousEdge, person);
353  previousEdge->addPerson(person);
354  }
355 }
356 
357 
358 bool
359 MSPerson::MSPersonStage_Driving::isWaitingFor(const std::string& line) const {
360  return myLines.count(line) > 0;
361 }
362 
363 
364 bool
366  return myVehicle == 0;
367 }
368 
369 
370 SUMOTime
372  return isWaiting4Vehicle() ? now - myWaitingSince : 0;
373 }
374 
375 
376 std::string
378  return isWaiting4Vehicle() ? "waiting for " + joinToString(myLines, ",") : "driving";
379 }
380 
381 
382 void
384  os.openTag("ride").writeAttr("depart", time2string(myDeparted)).writeAttr("arrival", time2string(myArrived)).closeTag();
385 }
386 
387 
388 void
391  os.writeAttr(SUMO_ATTR_LINES, myLines).closeTag();
392 }
393 
394 
395 void
397  os.openTag("event").writeAttr("time", time2string(t)).writeAttr("type", "arrival").writeAttr("agent", p.getID()).writeAttr("link", getEdge(t)->getID()).closeTag();
398 }
399 
400 
401 void
403  os.openTag("event").writeAttr("time", time2string(t)).writeAttr("type", "arrival").writeAttr("agent", p.getID()).writeAttr("link", getEdge(t)->getID()).closeTag();
404 }
405 
406 
407 
408 /* -------------------------------------------------------------------------
409  * MSPerson::MSPersonStage_Waiting - methods
410  * ----------------------------------------------------------------------- */
412  SUMOTime duration, SUMOTime until, SUMOReal pos, const std::string& actType) :
413  MSPersonStage(destination, WAITING),
414  myWaitingDuration(duration),
415  myWaitingUntil(until),
416  myActType(actType),
417  myStartPos(pos) {
420 }
421 
422 
424 
425 
426 const MSEdge*
428  return &myDestination;
429 }
430 
431 
432 const MSEdge*
434  return &myDestination;
435 }
436 
437 
438 SUMOReal
440  return myStartPos;
441 }
442 
443 
444 SUMOTime
446  return myWaitingUntil;
447 }
448 
449 
450 Position
452  return getEdgePosition(&myDestination, myStartPos, SIDEWALK_OFFSET);
453 }
454 
455 
456 SUMOReal
458  return getEdgeAngle(&myDestination, myStartPos) + 45;
459 }
460 
461 
462 void
464  MSEdge* previousEdge, const SUMOReal /* at */) {
465  previousEdge->addPerson(person);
466  const SUMOTime until = MAX3(now, now + myWaitingDuration, myWaitingUntil);
467  net->getPersonControl().setWaitEnd(until, person);
468 }
469 
470 
471 void
473  os.openTag("stop").writeAttr("arrival", time2string(myArrived)).closeTag();
474 }
475 
476 
477 void
480  if (myWaitingDuration >= 0) {
481  os.writeAttr(SUMO_ATTR_DURATION, time2string(myWaitingDuration));
482  }
483  if (myWaitingUntil >= 0) {
484  os.writeAttr(SUMO_ATTR_UNTIL, time2string(myWaitingUntil));
485  }
486  os.closeTag();
487 }
488 
489 
490 void
492  os.openTag("event").writeAttr("time", time2string(t)).writeAttr("type", "actstart " + myActType)
493  .writeAttr("agent", p.getID()).writeAttr("link", getEdge(t)->getID()).closeTag();
494 }
495 
496 
497 void
499  os.openTag("event").writeAttr("time", time2string(t)).writeAttr("type", "actend " + myActType).writeAttr("agent", p.getID())
500  .writeAttr("link", getEdge(t)->getID()).closeTag();
501 }
502 
503 
504 
505 /* -------------------------------------------------------------------------
506  * MSPerson - methods
507  * ----------------------------------------------------------------------- */
509  : myParameter(pars), myVType(vtype), myPlan(plan) {
510  myStep = myPlan->begin();
511 }
512 
513 
515  for (MSPersonPlan::const_iterator i = myPlan->begin(); i != myPlan->end(); ++i) {
516  delete *i;
517  }
518  delete myPlan;
519  delete myParameter;
520 }
521 
522 
523 const std::string&
525  return myParameter->id;
526 }
527 
528 
529 bool
531  MSEdge* arrivedAt = (MSEdge*)(*myStep)->getEdge(time);
532  SUMOReal atPos = (*myStep)->getEdgePos(time);
533  //MSPersonPlan::iterator prior = myStep;
534  (*myStep)->setArrived(time);
535  /*
536  if(myWriteEvents) {
537  (*myStep)->endEventOutput(*this, time, OutputDevice::getDeviceByOption("person-event-output"));
538  }
539  */
540  Position pos = (*myStep)->getPosition(time);
541  myStep++;
542  if (myStep != myPlan->end()) {
543  (*myStep)->proceed(net, this, time, arrivedAt, atPos);
544  /*
545  if(myWriteEvents) {
546  (*myStep)->beginEventOutput(*this, time, OutputDevice::getDeviceByOption("person-event-output"));
547  }
548  */
549  return true;
550  } else {
551  arrivedAt->removePerson(this);
552  return false;
553  }
554 }
555 
556 
557 SUMOTime
559  return myParameter->depart;
560 }
561 
562 
563 void
565  (*myStep)->setDeparted(now);
566 }
567 
568 
569 void
571  for (MSPersonPlan::const_iterator i = myPlan->begin(); i != myPlan->end(); ++i) {
572  (*i)->tripInfoOutput(os);
573  }
574 }
575 
576 
577 void
579  MSPersonPlan::const_iterator i = myPlan->begin();
580  if ((*i)->getStageType() == WAITING && getDesiredDepart() == static_cast<MSPersonStage_Waiting*>(*i)->getUntil()) {
581  ++i;
582  }
583  for (; i != myPlan->end(); ++i) {
584  (*i)->routeOutput(os);
585  }
586 }
587 
588 
589 /****************************************************************************/
590