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-2014 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 #include "MSPModel.h"
47 
48 #ifdef CHECK_MEMORY_LEAKS
49 #include <foreign/nvwa/debug_new.h>
50 #endif // CHECK_MEMORY_LEAKS
51 
52 /* -------------------------------------------------------------------------
53  * static member definitions
54  * ----------------------------------------------------------------------- */
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  return getLanePosition(e->getLanes()[0], at, offset);
98 }
99 
100 
101 Position
103  return lane->getShape().positionAtOffset(lane->interpolateLanePosToGeometryPos(at), offset);
104 }
105 
106 
107 SUMOReal
109  // @todo: well, definitely not the nicest way... Should be precomputed
110  PositionVector shp = e->getLanes()[0]->getShape();
111  return shp.rotationDegreeAtOffset(at);
112 }
113 
114 
115 
116 /* -------------------------------------------------------------------------
117  * MSPerson::MSPersonStage_Walking - methods
118  * ----------------------------------------------------------------------- */
119 MSPerson::MSPersonStage_Walking::MSPersonStage_Walking(const std::vector<const MSEdge*>& route,
120  MSBusStop* toBS,
121  SUMOTime walkingTime, SUMOReal speed,
122  SUMOReal departPos, SUMOReal arrivalPos) :
123  MSPersonStage(*route.back(), WALKING), myWalkingTime(walkingTime), myRoute(route),
124  myCurrentInternalEdge(0),
125  myDepartPos(departPos), myArrivalPos(arrivalPos), myDestinationBusStop(toBS),
126  mySpeed(speed),
127  myPedestrianState(0) {
129  myDepartPos, myRoute.front()->getLength(), SUMO_ATTR_DEPARTPOS, "person walking from " + myRoute.front()->getID());
131  myArrivalPos, myRoute.back()->getLength(), SUMO_ATTR_ARRIVALPOS, "person walking to " + myRoute.back()->getID());
132  if (walkingTime > 0) {
134  }
135 }
136 
137 
139 }
140 
141 
142 const MSEdge*
144  if (myCurrentInternalEdge != 0) {
145  return myCurrentInternalEdge;
146  } else {
147  return *myRouteStep;
148  }
149 }
150 
151 
152 const MSEdge*
154  return myRoute.front();
155 }
156 
157 
158 SUMOReal
160  return myPedestrianState->getEdgePos(*this, now);
161 }
162 
163 
164 Position
166  return myPedestrianState->getPosition(*this, now);
167 }
168 
169 
170 SUMOReal
172  return myPedestrianState->getAngle(*this, now);
173 }
174 
175 
176 SUMOTime
178  return myPedestrianState->getWaitingTime(*this, now);
179 }
180 
181 
182 SUMOReal
184  return myPedestrianState->getSpeed(*this);
185 }
186 
187 
188 void
190  MSEdge* previousEdge, const SUMOReal at) {
191  previousEdge->removePerson(person);
192  myRouteStep = myRoute.begin();
193  if (myWalkingTime == 0) {
194  if (!person->proceed(net, now)) {
196  };
197  return;
198  }
200  if (at >= 0) {
201  myDepartPos = at;
202  if (myWalkingTime > 0) {
203  mySpeed = computeAverageSpeed();
204  }
205  }
206  myPedestrianState = MSPModel::getModel()->add(person, this, now);
207  ((MSEdge*) *myRouteStep)->addPerson(person);
208 }
209 
210 
211 SUMOReal
213  SUMOReal length = 0;
214  for (std::vector<const MSEdge*>::const_iterator i = myRoute.begin(); i != myRoute.end(); ++i) {
215  length += (*i)->getLength();
216  }
217  length -= myDepartPos;
218  length -= myRoute.back()->getLength() - myArrivalPos;
219  return length / STEPS2TIME(myWalkingTime + 1); // avoid systematic rounding errors
220 }
221 
222 
223 void
225  os.openTag("walk").writeAttr("arrival", time2string(myArrived)).closeTag();
226 }
227 
228 
229 void
231  os.openTag("walk").writeAttr(SUMO_ATTR_EDGES, myRoute);
232  if (myWalkingTime > 0) {
233  os.writeAttr(SUMO_ATTR_DURATION, time2string(myWalkingTime));
234  } else if (mySpeed > 0) {
235  os.writeAttr(SUMO_ATTR_SPEED, mySpeed);
236  }
237  os.closeTag();
238 }
239 
240 
241 void
243  os.openTag("event").writeAttr("time", time2string(t)).writeAttr("type", "departure")
244  .writeAttr("agent", p.getID()).writeAttr("link", myRoute.front()->getID()).closeTag();
245 }
246 
247 
248 void
250  os.openTag("event").writeAttr("time", time2string(t)).writeAttr("type", "arrival")
251  .writeAttr("agent", p.getID()).writeAttr("link", myRoute.back()->getID()).closeTag();
252 }
253 
254 
255 bool
257  ((MSEdge*)getEdge())->removePerson(person);
258  //std::cout << SIMTIME << " moveToNextEdge person=" << person->getID() << "\n";
259  if (myRouteStep == myRoute.end() - 1) {
261  if (myDestinationBusStop != 0) {
262  myDestinationBusStop->addPerson(person);
263  }
264  if (!person->proceed(MSNet::getInstance(), currentTime)) {
266  }
267  //std::cout << " end walk. myRouteStep=" << (*myRouteStep)->getID() << "\n";
268  return true;
269  } else {
270  if (nextInternal == 0) {
271  ++myRouteStep;
272  myCurrentInternalEdge = 0;
273  } else {
274  myCurrentInternalEdge = nextInternal;
275  }
276  ((MSEdge*) getEdge())->addPerson(person);
277  return false;
278  }
279 }
280 
281 
282 
283 /* -------------------------------------------------------------------------
284  * MSPerson::MSPersonStage_Driving - methods
285  * ----------------------------------------------------------------------- */
287  MSBusStop* toBS, const std::vector<std::string>& lines)
288  : MSPersonStage(destination, DRIVING), myLines(lines.begin(), lines.end()),
289  myVehicle(0), myDestinationBusStop(toBS) {}
290 
291 
293 
294 
295 const MSEdge*
297  if (myVehicle != 0) {
298  return myVehicle->getEdge();
299  }
300  return myWaitingEdge;
301 }
302 
303 
304 const MSEdge*
306  return myWaitingEdge;
307 }
308 
309 
310 SUMOReal
312  if (myVehicle != 0) {
313  // vehicle may already have passed the lane (check whether this is correct)
314  return MIN2(myVehicle->getPositionOnLane(), getEdge()->getLength());
315  }
316  return myWaitingPos;
317 }
318 
319 
320 Position
322  if (myVehicle != 0) {
324  return myVehicle->getEdge()->getLanes()[0]->getShape().positionAtOffset(myVehicle->getPositionOnLane());
325  }
326  return getEdgePosition(myWaitingEdge, myWaitingPos, MSPModel::SIDEWALK_OFFSET);
327 }
328 
329 
330 SUMOReal
332  if (myVehicle != 0) {
333  MSVehicle* veh = dynamic_cast<MSVehicle*>(myVehicle);
334  if (veh != 0) {
335  return veh->getAngle() + 90;
336  } else {
337  return 0;
338  }
339  }
340  return getEdgeAngle(myWaitingEdge, myWaitingPos);
341 }
342 
343 
344 
345 void
347  MSEdge* previousEdge, const SUMOReal at) {
348  myWaitingEdge = previousEdge;
349  myWaitingPos = at;
350  myWaitingSince = now;
351  myVehicle = net->getVehicleControl().getWaitingVehicle(previousEdge, myLines);
352  if (myVehicle != 0 && myVehicle->getParameter().departProcedure == DEPART_TRIGGERED) {
353  previousEdge->removePerson(person);
354  myVehicle->addPerson(person);
355  net->getInsertionControl().add(myVehicle);
356  net->getVehicleControl().removeWaiting(previousEdge, myVehicle);
358  } else {
359  net->getPersonControl().addWaiting(previousEdge, person);
360  previousEdge->addPerson(person);
361  }
362 }
363 
364 
365 bool
366 MSPerson::MSPersonStage_Driving::isWaitingFor(const std::string& line) const {
367  return myLines.count(line) > 0;
368 }
369 
370 
371 bool
373  return myVehicle == 0;
374 }
375 
376 
377 SUMOTime
379  return isWaiting4Vehicle() ? now - myWaitingSince : 0;
380 }
381 
382 
383 SUMOReal
385  return myVehicle == 0 ? 0 : myVehicle->getSpeed();
386 }
387 
388 
389 std::string
391  return isWaiting4Vehicle() ? "waiting for " + joinToString(myLines, ",") : "driving";
392 }
393 
394 
395 void
397  os.openTag("ride").writeAttr("depart", time2string(myDeparted)).writeAttr("arrival", time2string(myArrived)).closeTag();
398 }
399 
400 
401 void
404  os.writeAttr(SUMO_ATTR_LINES, myLines).closeTag();
405 }
406 
407 
408 void
410  os.openTag("event").writeAttr("time", time2string(t)).writeAttr("type", "arrival").writeAttr("agent", p.getID()).writeAttr("link", getEdge()->getID()).closeTag();
411 }
412 
413 
414 void
416  os.openTag("event").writeAttr("time", time2string(t)).writeAttr("type", "arrival").writeAttr("agent", p.getID()).writeAttr("link", getEdge()->getID()).closeTag();
417 }
418 
419 
420 
421 /* -------------------------------------------------------------------------
422  * MSPerson::MSPersonStage_Waiting - methods
423  * ----------------------------------------------------------------------- */
425  SUMOTime duration, SUMOTime until, SUMOReal pos, const std::string& actType) :
426  MSPersonStage(destination, WAITING),
427  myWaitingDuration(duration),
428  myWaitingUntil(until),
429  myActType(actType),
430  myStartPos(pos) {
433 }
434 
435 
437 
438 
439 const MSEdge*
441  return &myDestination;
442 }
443 
444 
445 const MSEdge*
447  return &myDestination;
448 }
449 
450 
451 SUMOReal
453  return myStartPos;
454 }
455 
456 
457 SUMOTime
459  return myWaitingUntil;
460 }
461 
462 
463 Position
465  return getEdgePosition(&myDestination, myStartPos, MSPModel::SIDEWALK_OFFSET);
466 }
467 
468 
469 SUMOReal
471  return getEdgeAngle(&myDestination, myStartPos) + 45;
472 }
473 
474 
475 void
477  MSEdge* previousEdge, const SUMOReal /* at */) {
478  previousEdge->addPerson(person);
479  myWaitingStart = now;
480  const SUMOTime until = MAX3(now, now + myWaitingDuration, myWaitingUntil);
481  net->getPersonControl().setWaitEnd(until, person);
482 }
483 
484 
485 void
487  os.openTag("stop").writeAttr("arrival", time2string(myArrived)).closeTag();
488 }
489 
490 
491 void
494  if (myWaitingDuration >= 0) {
495  os.writeAttr(SUMO_ATTR_DURATION, time2string(myWaitingDuration));
496  }
497  if (myWaitingUntil >= 0) {
498  os.writeAttr(SUMO_ATTR_UNTIL, time2string(myWaitingUntil));
499  }
500  os.closeTag();
501 }
502 
503 
504 void
506  os.openTag("event").writeAttr("time", time2string(t)).writeAttr("type", "actstart " + myActType)
507  .writeAttr("agent", p.getID()).writeAttr("link", getEdge()->getID()).closeTag();
508 }
509 
510 
511 void
513  os.openTag("event").writeAttr("time", time2string(t)).writeAttr("type", "actend " + myActType).writeAttr("agent", p.getID())
514  .writeAttr("link", getEdge()->getID()).closeTag();
515 }
516 
517 
518 SUMOTime
520  return now - myWaitingStart;
521 }
522 
523 
524 SUMOReal
526  return 0;
527 }
528 
529 
530 
531 
532 /* -------------------------------------------------------------------------
533  * MSPerson - methods
534  * ----------------------------------------------------------------------- */
536  : myParameter(pars), myVType(vtype), myPlan(plan) {
537  myStep = myPlan->begin();
538 }
539 
540 
542  for (MSPersonPlan::const_iterator i = myPlan->begin(); i != myPlan->end(); ++i) {
543  delete *i;
544  }
545  delete myPlan;
546  delete myParameter;
547 }
548 
549 
550 const std::string&
552  return myParameter->id;
553 }
554 
555 
556 bool
558  MSEdge* arrivedAt = (MSEdge*)(*myStep)->getEdge();
559  SUMOReal atPos = (*myStep)->getEdgePos(time);
560  //MSPersonPlan::iterator prior = myStep;
561  (*myStep)->setArrived(time);
562  /*
563  if(myWriteEvents) {
564  (*myStep)->endEventOutput(*this, time, OutputDevice::getDeviceByOption("person-event-output"));
565  }
566  */
567  myStep++;
568  if (myStep != myPlan->end()) {
569  (*myStep)->proceed(net, this, time, arrivedAt, atPos);
570  /*
571  if(myWriteEvents) {
572  (*myStep)->beginEventOutput(*this, time, OutputDevice::getDeviceByOption("person-event-output"));
573  }
574  */
575  return true;
576  } else {
577  arrivedAt->removePerson(this);
578  return false;
579  }
580 }
581 
582 
583 SUMOTime
585  return myParameter->depart;
586 }
587 
588 
589 void
591  (*myStep)->setDeparted(now);
592 }
593 
594 
595 void
597  for (MSPersonPlan::const_iterator i = myPlan->begin(); i != myPlan->end(); ++i) {
598  (*i)->tripInfoOutput(os);
599  }
600 }
601 
602 
603 void
605  MSPersonPlan::const_iterator i = myPlan->begin();
606  if ((*i)->getStageType() == WAITING && getDesiredDepart() == static_cast<MSPersonStage_Waiting*>(*i)->getUntil()) {
607  ++i;
608  }
609  for (; i != myPlan->end(); ++i) {
610  (*i)->routeOutput(os);
611  }
612 }
613 
614 SUMOReal
616  return (*myStep)->getEdgePos(MSNet::getInstance()->getCurrentTimeStep());
617 }
618 
619 Position
621  return (*myStep)->getPosition(MSNet::getInstance()->getCurrentTimeStep());
622 }
623 
624 
625 SUMOReal
627  return (*myStep)->getAngle(MSNet::getInstance()->getCurrentTimeStep());
628 }
629 
630 SUMOReal
632  return STEPS2TIME((*myStep)->getWaitingTime(MSNet::getInstance()->getCurrentTimeStep()));
633 }
634 
635 SUMOReal
637  return (*myStep)->getSpeed();
638 }
639 
640 /****************************************************************************/
641