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  * MSPerson::MSPersonStage_Walking - methods
115  * ----------------------------------------------------------------------- */
116 MSPerson::MSPersonStage_Walking::MSPersonStage_Walking(const std::vector<const MSEdge*>& route,
117  MSBusStop* toBS,
118  SUMOTime walkingTime, SUMOReal speed,
119  SUMOReal departPos, SUMOReal arrivalPos) :
120  MSPersonStage(*route.back(), WALKING), myWalkingTime(walkingTime), myRoute(route),
121  myDepartPos(departPos), myArrivalPos(arrivalPos), myDestinationBusStop(toBS),
122  mySpeed(speed) {
124  myDepartPos, myRoute.front()->getLength(), SUMO_ATTR_DEPARTPOS, "person walking from " + myRoute.front()->getID());
126  myArrivalPos, myRoute.back()->getLength(), SUMO_ATTR_ARRIVALPOS, "person walking to " + myRoute.back()->getID());
127  if (walkingTime > 0) {
128  SUMOReal length = 0;
129  for (std::vector<const MSEdge*>::const_iterator i = route.begin(); i != route.end(); ++i) {
130  length += (*i)->getLength();
131  }
132  length -= myDepartPos;
133  length -= route.back()->getLength() - myArrivalPos;
134  mySpeed = length / STEPS2TIME(walkingTime);
135  }
136 }
137 
138 
140 
141 
142 const MSEdge*
144  return *myRouteStep;
145 }
146 
147 
148 const MSEdge*
150  return myRoute.front();
151 }
152 
153 
154 SUMOReal
156  SUMOReal off = STEPS2TIME(now - myLastEntryTime);
157  return myCurrentBeginPos + myCurrentLength / myCurrentDuration * off;
158 }
159 
160 
161 Position
163  const MSEdge* e = getEdge(now);
164  SUMOReal off = STEPS2TIME(now - myLastEntryTime);
165  return getEdgePosition(e, myCurrentBeginPos + myCurrentLength / myCurrentDuration * off, SIDEWALK_OFFSET);
166 }
167 
168 
169 SUMOReal
171  const MSEdge* e = getEdge(now);
172  SUMOReal off = STEPS2TIME(now - myLastEntryTime);
173  return getEdgeAngle(e, myCurrentBeginPos + myCurrentLength / myCurrentDuration * off) + 90;
174 }
175 
176 
177 void
179  MSEdge* previousEdge, const SUMOReal at) {
180  previousEdge->removePerson(person);
181  myRouteStep = myRoute.begin();
182  myLastEntryTime = now;
183  if (myWalkingTime == 0) {
184  if (!person->proceed(net, now)) {
186  };
187  return;
188  }
190  if (at >= 0) {
191  myDepartPos = at;
192  }
193  ((MSEdge*) *myRouteStep)->addPerson(person);
194  myRoute.size() == 1
195  ? computeWalkingTime(*myRouteStep, myDepartPos, myArrivalPos, myDestinationBusStop)
196  : computeWalkingTime(*myRouteStep, myDepartPos, -1, 0);
197  net->getBeginOfTimestepEvents().addEvent(new MoveToNextEdge(person, *this), now + TIME2STEPS(myCurrentDuration), MSEventControl::ADAPT_AFTER_EXECUTION);
198 }
199 
200 
201 void
203  if (bs != 0) {
204  toPos = bs->getEndLanePosition();
205  } else if (toPos < 0) {
206  toPos = e->getLanes()[0]->getLength();
207  }
208  if (fromPos < 0) {
209  fromPos = 0;
210  }
211  myCurrentBeginPos = fromPos;
212  myCurrentLength = toPos - fromPos;
213  assert(myCurrentLength >= 0);
214  myCurrentDuration = MAX2(myCurrentLength, (SUMOReal)1.0) / mySpeed;
215 }
216 
217 
218 void
220  (os.openTag("walk") <<
221  " arrival=\"" << time2string(myArrived) <<
222  "\"").closeTag();
223 }
224 
225 
226 void
228  os.openTag("walk").writeAttr(SUMO_ATTR_EDGES, myRoute);
229  if (myWalkingTime > 0) {
230  os.writeAttr(SUMO_ATTR_DURATION, time2string(myWalkingTime));
231  } else if (mySpeed > 0) {
232  os.writeAttr(SUMO_ATTR_SPEED, mySpeed);
233  }
234  os.closeTag();
235 }
236 
237 
238 void
240  (os.openTag("event") <<
241  " time=\"" << time2string(t) <<
242  "\" type=\"departure" <<
243  "\" agent=\"" << p.getID() <<
244  "\" link=\"" << myRoute.front()->getID() <<
245  "\"").closeTag();
246 }
247 
248 
249 void
251  (os.openTag("event") <<
252  " time=\"" << time2string(t) <<
253  "\" type=\"arrival" <<
254  "\" agent=\"" << p.getID() <<
255  "\" link=\"" << myRoute.back()->getID() <<
256  "\"").closeTag();
257 }
258 
259 
260 SUMOTime
262  ((MSEdge*) *myRouteStep)->removePerson(person);
263  if (myRouteStep == myRoute.end() - 1) {
265  if (myDestinationBusStop != 0) {
266  myDestinationBusStop->addPerson(person);
267  }
268  if (!person->proceed(MSNet::getInstance(), currentTime)) {
270  }
271  return 0;
272  } else {
273  ++myRouteStep;
274  myRouteStep == myRoute.end() - 1
275  ? computeWalkingTime(*myRouteStep, 0, myArrivalPos, myDestinationBusStop)
276  : computeWalkingTime(*myRouteStep, 0, -1, 0);
277  ((MSEdge*) *myRouteStep)->addPerson(person);
278  myLastEntryTime = currentTime;
279  return TIME2STEPS(myCurrentDuration);
280  }
281 }
282 
283 
284 
285 /* -------------------------------------------------------------------------
286  * MSPerson::MSPersonStage_Driving - methods
287  * ----------------------------------------------------------------------- */
289  MSBusStop* toBS, const std::vector<std::string>& lines)
290  : MSPersonStage(destination, DRIVING), myLines(lines.begin(), lines.end()),
291  myVehicle(0), myDestinationBusStop(toBS) {}
292 
293 
295 
296 
297 const MSEdge*
299  if (myVehicle != 0) {
300  return myVehicle->getEdge();
301  }
302  return myWaitingEdge;
303 }
304 
305 
306 const MSEdge*
308  return myWaitingEdge;
309 }
310 
311 
312 SUMOReal
314  if (myVehicle != 0) {
315  // vehicle may already have passed the lane (check whether this is correct)
316  return MIN2(myVehicle->getPositionOnLane(), getEdge(now)->getLength());
317  }
318  return myWaitingPos;
319 }
320 
321 
322 Position
324  if (myVehicle != 0) {
326  return myVehicle->getEdge()->getLanes()[0]->getShape().positionAtOffset(myVehicle->getPositionOnLane());
327  }
328  return getEdgePosition(myWaitingEdge, myWaitingPos, SIDEWALK_OFFSET);
329 }
330 
331 
332 SUMOReal
334  if (myVehicle != 0) {
335  MSVehicle* veh = dynamic_cast<MSVehicle*>(myVehicle);
336  if (veh != 0) {
337  return veh->getAngle() + 90;
338  } else {
339  return 0;
340  }
341  }
342  return getEdgeAngle(myWaitingEdge, myWaitingPos);
343 }
344 
345 
346 
347 void
349  MSEdge* previousEdge, const SUMOReal at) {
350  myWaitingEdge = previousEdge;
351  myWaitingPos = at;
352  myWaitingSince = now;
353  myVehicle = net->getVehicleControl().getWaitingVehicle(previousEdge, myLines);
354  if (myVehicle != 0 && myVehicle->getParameter().departProcedure == DEPART_TRIGGERED) {
355  previousEdge->removePerson(person);
356  myVehicle->addPerson(person);
357  net->getInsertionControl().add(myVehicle);
358  net->getVehicleControl().removeWaiting(previousEdge, myVehicle);
360  } else {
361  net->getPersonControl().addWaiting(previousEdge, person);
362  previousEdge->addPerson(person);
363  }
364 }
365 
366 
367 bool
368 MSPerson::MSPersonStage_Driving::isWaitingFor(const std::string& line) const {
369  return myLines.count(line) > 0;
370 }
371 
372 
373 bool
375  return myVehicle == 0;
376 }
377 
378 
379 SUMOTime
381  return isWaiting4Vehicle() ? now - myWaitingSince : 0;
382 }
383 
384 
385 std::string
387  return isWaiting4Vehicle() ? "waiting for " + joinToString(myLines, ",") : "driving";
388 }
389 
390 
391 void
393  (os.openTag("ride") <<
394  " depart=\"" << time2string(myDeparted) <<
395  "\" arrival=\"" << time2string(myArrived) <<
396  "\"").closeTag();
397 }
398 
399 
400 void
403  os.writeAttr(SUMO_ATTR_LINES, myLines).closeTag();
404 }
405 
406 
407 void
409  (os.openTag("event") <<
410  " time=\"" << time2string(t) <<
411  "\" type=\"arrival" <<
412  "\" agent=\"" << p.getID() <<
413  "\" link=\"" << getEdge(t)->getID() <<
414  "\"").closeTag();
415 }
416 
417 
418 void
420  (os.openTag("event") <<
421  " time=\"" << time2string(t) <<
422  "\" type=\"arrival" <<
423  "\" agent=\"" << p.getID() <<
424  "\" link=\"" << getEdge(t)->getID() <<
425  "\"").closeTag();
426 }
427 
428 
429 /* -------------------------------------------------------------------------
430  * MSPerson::MSPersonStage_Waiting - methods
431  * ----------------------------------------------------------------------- */
433  SUMOTime duration, SUMOTime until, SUMOReal pos, const std::string& actType) :
434  MSPersonStage(destination, WAITING),
435  myWaitingDuration(duration),
436  myWaitingUntil(until),
437  myActType(actType),
438  myStartPos(pos) {
441 }
442 
443 
445 
446 
447 const MSEdge*
449  return &myDestination;
450 }
451 
452 
453 const MSEdge*
455  return &myDestination;
456 }
457 
458 
459 SUMOReal
461  return myStartPos;
462 }
463 
464 
465 SUMOTime
467  return myWaitingUntil;
468 }
469 
470 
471 Position
473  return getEdgePosition(&myDestination, myStartPos, SIDEWALK_OFFSET);
474 }
475 
476 
477 SUMOReal
479  return getEdgeAngle(&myDestination, myStartPos) + 45;
480 }
481 
482 
483 void
485  MSEdge* previousEdge, const SUMOReal /* at */) {
486  previousEdge->addPerson(person);
487  const SUMOTime until = MAX3(now, now + myWaitingDuration, myWaitingUntil);
488  net->getPersonControl().setWaitEnd(until, person);
489 }
490 
491 
492 void
494  (os.openTag("stop") <<
495  " arrival=\"" << time2string(myArrived) <<
496  "\"").closeTag();
497 }
498 
499 
500 void
503  if (myWaitingDuration >= 0) {
504  os.writeAttr(SUMO_ATTR_DURATION, time2string(myWaitingDuration));
505  }
506  if (myWaitingUntil >= 0) {
507  os.writeAttr(SUMO_ATTR_UNTIL, time2string(myWaitingUntil));
508  }
509  os.closeTag();
510 }
511 
512 
513 void
515  (os.openTag("event") <<
516  " time=\"" << time2string(t) <<
517  "\" type=\"actstart " << myActType <<
518  "\" agent=\"" << p.getID() <<
519  "\" link=\"" << getEdge(t)->getID() <<
520  "\"").closeTag();
521 }
522 
523 
524 void
526  (os.openTag("event") <<
527  " time=\"" << time2string(t) <<
528  "\" type=\"actend " << myActType <<
529  "\" agent=\"" << p.getID() <<
530  "\" link=\"" << getEdge(t)->getID() <<
531  "\"").closeTag();
532 }
533 
534 /* -------------------------------------------------------------------------
535  * MSPerson - methods
536  * ----------------------------------------------------------------------- */
538  : myParameter(pars), myVType(vtype), myPlan(plan) {
539  myStep = myPlan->begin();
540 }
541 
542 
544  for (MSPersonPlan::const_iterator i = myPlan->begin(); i != myPlan->end(); ++i) {
545  delete *i;
546  }
547  delete myPlan;
548  delete myParameter;
549 }
550 
551 
552 const std::string&
554  return myParameter->id;
555 }
556 
557 
558 bool
560  MSEdge* arrivedAt = (MSEdge*)(*myStep)->getEdge(time);
561  SUMOReal atPos = (*myStep)->getEdgePos(time);
562  //MSPersonPlan::iterator prior = myStep;
563  (*myStep)->setArrived(time);
564  /*
565  if(myWriteEvents) {
566  (*myStep)->endEventOutput(*this, time, OutputDevice::getDeviceByOption("person-event-output"));
567  }
568  */
569  Position pos = (*myStep)->getPosition(time);
570  myStep++;
571  if (myStep != myPlan->end()) {
572  (*myStep)->proceed(net, this, time, arrivedAt, atPos);
573  /*
574  if(myWriteEvents) {
575  (*myStep)->beginEventOutput(*this, time, OutputDevice::getDeviceByOption("person-event-output"));
576  }
577  */
578  return true;
579  } else {
580  arrivedAt->removePerson(this);
581  return false;
582  }
583 }
584 
585 
586 SUMOTime
588  return myParameter->depart;
589 }
590 
591 
592 void
594  (*myStep)->setDeparted(now);
595 }
596 
597 
598 void
600  for (MSPersonPlan::const_iterator i = myPlan->begin(); i != myPlan->end(); ++i) {
601  (*i)->tripInfoOutput(os);
602  }
603 }
604 
605 
606 void
608  MSPersonPlan::const_iterator i = myPlan->begin();
609  if ((*i)->getStageType() == WAITING && getDesiredDepart() == static_cast<MSPersonStage_Waiting*>(*i)->getUntil()) {
610  ++i;
611  }
612  for (; i != myPlan->end(); ++i) {
613  (*i)->routeOutput(os);
614  }
615 }
616 
617 
618 /****************************************************************************/
619