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.sourceforge.net/
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 bool
178 MSPerson::MSPersonStage_Walking::checkNoDuration(MSNet* /* net */, MSPerson* /* person */, SUMOTime duration, SUMOTime /* now */) {
179  if (duration == 0) {
180 
181  return true;
182  }
183  return false;
184 }
185 
186 
187 void
189  MSEdge* previousEdge, const SUMOReal at) {
190  previousEdge->removePerson(person);
191  myRouteStep = myRoute.begin();
192  myLastEntryTime = now;
193  if (myWalkingTime == 0) {
194  if (!person->proceed(net, now)) {
196  };
197  return;
198  }
200  if (at >= 0) {
201  myDepartPos = at;
202  }
203  ((MSEdge*) *myRouteStep)->addPerson(person);
204  myRoute.size() == 1
205  ? computeWalkingTime(*myRouteStep, myDepartPos, myArrivalPos, myDestinationBusStop)
206  : computeWalkingTime(*myRouteStep, myDepartPos, -1, 0);
207  net->getBeginOfTimestepEvents().addEvent(new MoveToNextEdge(person, *this), now + TIME2STEPS(myCurrentDuration), MSEventControl::ADAPT_AFTER_EXECUTION);
208 }
209 
210 
211 void
213  if (bs != 0) {
214  toPos = bs->getEndLanePosition();
215  } else if (toPos < 0) {
216  toPos = e->getLanes()[0]->getLength();
217  }
218  if (fromPos < 0) {
219  fromPos = 0;
220  }
221  myCurrentBeginPos = fromPos;
222  myCurrentLength = toPos - fromPos;
223  assert(myCurrentLength >= 0);
224  myCurrentDuration = MAX2(myCurrentLength, (SUMOReal)1.0) / mySpeed;
225 }
226 
227 
228 void
230  (os.openTag("walk") <<
231  " arrival=\"" << time2string(myArrived) <<
232  "\"").closeTag();
233 }
234 
235 
236 void
238  (os.openTag("event") <<
239  " time=\"" << time2string(t) <<
240  "\" type=\"departure" <<
241  "\" agent=\"" << p.getID() <<
242  "\" link=\"" << myRoute.front()->getID() <<
243  "\"").closeTag();
244 }
245 
246 
247 void
249  (os.openTag("event") <<
250  " time=\"" << time2string(t) <<
251  "\" type=\"arrival" <<
252  "\" agent=\"" << p.getID() <<
253  "\" link=\"" << myRoute.back()->getID() <<
254  "\"").closeTag();
255 }
256 
257 
258 SUMOTime
260  ((MSEdge*) *myRouteStep)->removePerson(person);
261  if (myRouteStep == myRoute.end() - 1) {
263  if (myDestinationBusStop != 0) {
264  myDestinationBusStop->addPerson(person);
265  }
266  if (!person->proceed(MSNet::getInstance(), currentTime)) {
268  }
269  return 0;
270  } else {
271  ++myRouteStep;
272  myRouteStep == myRoute.end() - 1
273  ? computeWalkingTime(*myRouteStep, 0, myArrivalPos, myDestinationBusStop)
274  : computeWalkingTime(*myRouteStep, 0, -1, 0);
275  ((MSEdge*) *myRouteStep)->addPerson(person);
276  myLastEntryTime = currentTime;
277  return TIME2STEPS(myCurrentDuration);
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(now)->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, 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  myVehicle = net->getVehicleControl().getWaitingVehicle(previousEdge, myLines);
351  if (myVehicle != 0 && myVehicle->getParameter().departProcedure == DEPART_TRIGGERED) {
352  previousEdge->removePerson(person);
353  myVehicle->addPerson(person);
354  net->getInsertionControl().add(myVehicle);
355  net->getVehicleControl().removeWaiting(previousEdge, myVehicle);
357  } else {
358  net->getPersonControl().addWaiting(previousEdge, person);
359  previousEdge->addPerson(person);
360  }
361 }
362 
363 
364 bool
365 MSPerson::MSPersonStage_Driving::isWaitingFor(const std::string& line) const {
366  return myLines.count(line) > 0;
367 }
368 
369 
370 bool
372  return myVehicle == 0;
373 }
374 
375 
376 std::string
378  return isWaiting4Vehicle() ? "waiting for " + joinToString(myLines, ",") : "driving";
379 }
380 
381 
382 void
384  (os.openTag("ride") <<
385  " depart=\"" << time2string(myDeparted) <<
386  "\" arrival=\"" << time2string(myArrived) <<
387  "\"").closeTag();
388 }
389 
390 
391 void
393  (os.openTag("event") <<
394  " time=\"" << time2string(t) <<
395  "\" type=\"arrival" <<
396  "\" agent=\"" << p.getID() <<
397  "\" link=\"" << getEdge(t)->getID() <<
398  "\"").closeTag();
399 }
400 
401 
402 void
404  (os.openTag("event") <<
405  " time=\"" << time2string(t) <<
406  "\" type=\"arrival" <<
407  "\" agent=\"" << p.getID() <<
408  "\" link=\"" << getEdge(t)->getID() <<
409  "\"").closeTag();
410 }
411 
412 
413 /* -------------------------------------------------------------------------
414  * MSPerson::MSPersonStage_Waiting - methods
415  * ----------------------------------------------------------------------- */
417  SUMOTime duration, SUMOTime until, SUMOReal pos, const std::string& actType) :
418  MSPersonStage(destination, WAITING),
419  myWaitingDuration(duration),
420  myWaitingUntil(until),
421  myActType(actType),
422  myStartPos(pos) {
425 }
426 
427 
429 
430 
431 const MSEdge*
433  return &myDestination;
434 }
435 
436 
437 const MSEdge*
439  return &myDestination;
440 }
441 
442 
443 SUMOReal
445  return myStartPos;
446 }
447 
448 Position
450  return getEdgePosition(&myDestination, myStartPos, SIDEWALK_OFFSET);
451 }
452 
453 
454 SUMOReal
456  return getEdgeAngle(&myDestination, myStartPos) + 45;
457 }
458 
459 
460 void
462  MSEdge* previousEdge, const SUMOReal /* at */) {
463  previousEdge->addPerson(person);
464  const SUMOTime until = MAX3(now, now + myWaitingDuration, myWaitingUntil);
465  net->getPersonControl().setWaitEnd(until, person);
466 }
467 
468 
469 void
471  (os.openTag("stop") <<
472  " arrival=\"" << time2string(myArrived) <<
473  "\"").closeTag();
474 }
475 
476 
477 void
479  (os.openTag("event") <<
480  " time=\"" << time2string(t) <<
481  "\" type=\"actstart " << myActType <<
482  "\" agent=\"" << p.getID() <<
483  "\" link=\"" << getEdge(t)->getID() <<
484  "\"").closeTag();
485 }
486 
487 
488 void
490  (os.openTag("event") <<
491  " time=\"" << time2string(t) <<
492  "\" type=\"actend " << myActType <<
493  "\" agent=\"" << p.getID() <<
494  "\" link=\"" << getEdge(t)->getID() <<
495  "\"").closeTag();
496 }
497 
498 /* -------------------------------------------------------------------------
499  * MSPerson - methods
500  * ----------------------------------------------------------------------- */
502  : myParameter(pars), myVType(vtype), myPlan(plan) {
503  myStep = myPlan->begin();
504 }
505 
506 
508  for (MSPersonPlan::const_iterator i = myPlan->begin(); i != myPlan->end(); ++i) {
509  delete *i;
510  }
511  delete myPlan;
512  delete myParameter;
513 }
514 
515 
516 const std::string&
518  return myParameter->id;
519 }
520 
521 
522 bool
524  MSEdge* arrivedAt = (MSEdge*)(*myStep)->getEdge(time);
525  SUMOReal atPos = (*myStep)->getEdgePos(time);
526  //MSPersonPlan::iterator prior = myStep;
527  (*myStep)->setArrived(time);
528  /*
529  if(myWriteEvents) {
530  (*myStep)->endEventOutput(*this, time, OutputDevice::getDeviceByOption("person-event-output"));
531  }
532  */
533  Position pos = (*myStep)->getPosition(time);
534  myStep++;
535  if (myStep != myPlan->end()) {
536  (*myStep)->proceed(net, this, time, arrivedAt, atPos);
537  /*
538  if(myWriteEvents) {
539  (*myStep)->beginEventOutput(*this, time, OutputDevice::getDeviceByOption("person-event-output"));
540  }
541  */
542  return true;
543  } else {
544  arrivedAt->removePerson(this);
545  return false;
546  }
547 }
548 
549 
550 SUMOTime
552  return myParameter->depart;
553 }
554 
555 
556 void
558  (*myStep)->setDeparted(now);
559 }
560 
561 
562 void
564  for (MSPersonPlan::const_iterator i = myPlan->begin(); i != myPlan->end(); ++i) {
565  (*i)->tripInfoOutput(os);
566  }
567 }
568 
569 
570 /****************************************************************************/
571