Eclipse SUMO - Simulation of Urban MObility
MSTransportable.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
17 // The common superclass for modelling transportable objects like persons and containers
18 /****************************************************************************/
19 
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25 
27 #include <utils/geom/GeomHelper.h>
31 #include "MSEdge.h"
32 #include "MSLane.h"
33 #include "MSNet.h"
36 #include "MSVehicleControl.h"
37 #include "MSTransportableControl.h"
38 #include "MSTransportable.h"
39 
40 /* -------------------------------------------------------------------------
41 * static member definitions
42 * ----------------------------------------------------------------------- */
43 const double MSTransportable::ROADSIDE_OFFSET(3);
44 
45 
46 // ===========================================================================
47 // method definitions
48 // ===========================================================================
49 /* -------------------------------------------------------------------------
50  * MSTransportable::Stage - methods
51  * ----------------------------------------------------------------------- */
52 MSTransportable::Stage::Stage(const MSEdge* destination, MSStoppingPlace* toStop, const double arrivalPos, StageType type)
53  : myDestination(destination), myDestinationStop(toStop), myArrivalPos(arrivalPos), myDeparted(-1), myArrived(-1), myType(type) {}
54 
56 
57 const MSEdge*
59  return myDestination;
60 }
61 
62 
63 const MSEdge*
65  return myDestination;
66 }
67 
68 
69 const MSEdge*
71  return myDestination;
72 }
73 
74 
75 double
77  return myArrivalPos;
78 }
79 
80 
83  return 0;
84 }
85 
86 
87 double
89  return 0.;
90 }
91 
92 
95  ConstMSEdgeVector result;
96  result.push_back(getDestination());
97  return result;
98 }
99 
100 
101 void
103  if (myDeparted < 0) {
104  myDeparted = now;
105  }
106 }
107 
108 SUMOTime
110  return myDeparted;
111 }
112 
113 void
114 MSTransportable::Stage::setArrived(MSNet* /* net */, MSTransportable* /* transportable */, SUMOTime now) {
115  myArrived = now;
116 }
117 
118 bool
120  return false;
121 }
122 
123 Position
124 MSTransportable::Stage::getEdgePosition(const MSEdge* e, double at, double offset) const {
125  return getLanePosition(e->getLanes()[0], at, offset);
126 }
127 
128 Position
129 MSTransportable::Stage::getLanePosition(const MSLane* lane, double at, double offset) const {
130  return lane->getShape().positionAtOffset(lane->interpolateLanePosToGeometryPos(at), offset);
131 }
132 
133 double
134 MSTransportable::Stage::getEdgeAngle(const MSEdge* e, double at) const {
135  return e->getLanes()[0]->getShape().rotationAtOffset(at);
136 }
137 
138 
139 void
140 MSTransportable::Stage::setDestination(const MSEdge* newDestination, MSStoppingPlace* newDestStop) {
141  myDestination = newDestination;
142  myDestinationStop = newDestStop;
143  if (newDestStop != nullptr) {
144  myArrivalPos = (newDestStop->getBeginLanePosition() + newDestStop->getEndLanePosition()) / 2;
145  }
146 }
147 
148 
149 
150 /* -------------------------------------------------------------------------
151 * MSTransportable::Stage_Trip - methods
152 * ----------------------------------------------------------------------- */
154  const MSEdge* destination, MSStoppingPlace* toStop,
155  const SUMOTime duration, const SVCPermissions modeSet,
156  const std::string& vTypes, const double speed, const double walkFactor,
157  const double departPosLat, const bool hasArrivalPos, const double arrivalPos):
158  MSTransportable::Stage(destination, toStop, arrivalPos, TRIP),
159  myOrigin(origin),
160  myOriginStop(fromStop),
161  myDuration(duration),
162  myModeSet(modeSet),
163  myVTypes(vTypes),
164  mySpeed(speed),
165  myWalkFactor(walkFactor),
166  myDepartPosLat(departPosLat),
167  myHaveArrivalPos(hasArrivalPos) {
168 }
169 
170 
172 
175  return new Stage_Trip(myOrigin, const_cast<MSStoppingPlace*>(myOriginStop),
178 }
179 
180 
181 Position
183  // may be called concurrently while the trip is still being routed
184  return getEdgePosition(myOrigin, myDepartPos, ROADSIDE_OFFSET * (MSNet::getInstance()->lefthand() ? -1 : 1));
185 }
186 
187 
188 double
190  // may be called concurrently while the trip is still being routed
191  return getEdgeAngle(myOrigin, myDepartPos) + M_PI / 2 * (MSNet::getInstance()->lefthand() ? -1 : 1);
192 }
193 
194 
195 const MSEdge*
197  return myOrigin;
198 }
199 
200 
201 double
203  return myDepartPos;
204 }
205 
206 
207 void
209  MSTransportable::Stage::setArrived(net, transportable, now);
210  MSVehicleControl& vehControl = net->getVehicleControl();
211  std::vector<SUMOVehicleParameter*> pars;
212  for (StringTokenizer st(myVTypes); st.hasNext();) {
213  pars.push_back(new SUMOVehicleParameter());
214  pars.back()->vtypeid = st.next();
215  pars.back()->parametersSet |= VEHPARS_VTYPE_SET;
216  pars.back()->departProcedure = DEPART_TRIGGERED;
217  pars.back()->id = transportable->getID() + "_" + toString(pars.size() - 1);
218  }
219  if (pars.empty()) {
220  if ((myModeSet & SVC_PASSENGER) != 0) {
221  pars.push_back(new SUMOVehicleParameter());
222  pars.back()->id = transportable->getID() + "_0";
223  pars.back()->departProcedure = DEPART_TRIGGERED;
224  } else if ((myModeSet & SVC_BICYCLE) != 0) {
225  pars.push_back(new SUMOVehicleParameter());
226  pars.back()->vtypeid = DEFAULT_BIKETYPE_ID;
227  pars.back()->id = transportable->getID() + "_b0";
228  pars.back()->departProcedure = DEPART_TRIGGERED;
229  } else {
230  // allow shortcut via busStop even when not intending to ride
231  pars.push_back(nullptr);
232  }
233  }
234  MSTransportable::Stage* previous;
236  if (transportable->getNumStages() == transportable->getNumRemainingStages()) { // this is a difficult way to check that we are the first stage
237  myDepartPos = transportable->getParameter().departPos;
238  if (transportable->getParameter().departPosProcedure == DEPART_POS_RANDOM) {
240  }
241  previous = new MSTransportable::Stage_Waiting(myOrigin, nullptr, -1, transportable->getParameter().depart, myDepartPos, "start", true);
242  time = transportable->getParameter().depart;
243  } else {
244  previous = transportable->getNextStage(-1);
245  myDepartPos = previous->getArrivalPos();
246  }
247  // TODO This works currently only for a single vehicle type
248  for (SUMOVehicleParameter* vehPar : pars) {
249  SUMOVehicle* vehicle = nullptr;
250  if (vehPar != nullptr) {
251  if (myDepartPos != 0) {
252  vehPar->departPosProcedure = DEPART_POS_GIVEN;
253  vehPar->departPos = myDepartPos;
254  vehPar->parametersSet |= VEHPARS_DEPARTPOS_SET;
255  }
256  MSVehicleType* type = vehControl.getVType(vehPar->vtypeid);
257  if (type->getVehicleClass() != SVC_IGNORING && (myOrigin->getPermissions() & type->getVehicleClass()) == 0) {
258  WRITE_WARNING("Ignoring vehicle type '" + type->getID() + "' when routing person '" + transportable->getID() + "' because it is not allowed on the start edge.");
259  } else {
260  const MSRoute* const routeDummy = new MSRoute(vehPar->id, ConstMSEdgeVector({ myOrigin }), false, nullptr, std::vector<SUMOVehicleParameter::Stop>());
261  vehicle = vehControl.buildVehicle(vehPar, routeDummy, type, !MSGlobals::gCheckRoutes);
262  }
263  }
264  bool carUsed = false;
265  std::vector<MSNet::MSIntermodalRouter::TripItem> result;
266  int stageIndex = 1;
267  if (net->getIntermodalRouter().compute(myOrigin, myDestination, previous->getArrivalPos(), myArrivalPos, myDestinationStop == nullptr ? "" : myDestinationStop->getID(),
268  transportable->getMaxSpeed() * myWalkFactor, vehicle, myModeSet, time, result)) {
269  for (std::vector<MSNet::MSIntermodalRouter::TripItem>::iterator it = result.begin(); it != result.end(); ++it) {
270  if (!it->edges.empty()) {
272  double localArrivalPos = bs != nullptr ? bs->getAccessPos(it->edges.back()) : it->edges.back()->getLength() / 2.;
273  if (it + 1 == result.end() && myHaveArrivalPos) {
274  localArrivalPos = myArrivalPos;
275  }
276  if (it->line == "") {
277  double depPos = previous->getArrivalPos();
278  if (previous->getDestinationStop() != nullptr) {
279  depPos = previous->getDestinationStop()->getAccessPos(it->edges.front());
280  } else if (previous->getEdge() != it->edges.front()) {
281 // if (previous->getEdge()->getToJunction() == it->edges.front()->getToJunction()) {
282 // depPos = it->edges.front()->getLength();
283 // } else {
284  depPos = 0.;
285 // }
286  }
287  previous = new MSPerson::MSPersonStage_Walking(transportable->getID(), it->edges, bs, myDuration, mySpeed, depPos, localArrivalPos, myDepartPosLat);
288  transportable->appendStage(previous, stageIndex++);
289  } else if (vehicle != nullptr && it->line == vehicle->getID()) {
290  if (bs == nullptr && it + 1 != result.end()) {
291  // we have no defined endpoint and are in the middle of the trip, drive as far as possible
292  localArrivalPos = it->edges.back()->getLength();
293  }
294  previous = new MSPerson::MSPersonStage_Driving(it->edges.back(), bs, localArrivalPos, std::vector<std::string>({ it->line }));
295  transportable->appendStage(previous, stageIndex++);
296  vehicle->replaceRouteEdges(it->edges, -1, 0, "person:" + transportable->getID(), true);
297  vehicle->setArrivalPos(localArrivalPos);
298  vehControl.addVehicle(vehPar->id, vehicle);
299  carUsed = true;
300  } else {
301  previous = new MSPerson::MSPersonStage_Driving(it->edges.back(), bs, localArrivalPos, std::vector<std::string>({ it->line }), it->intended, TIME2STEPS(it->depart));
302  transportable->appendStage(previous, stageIndex++);
303  }
304  }
305  }
306  } else {
307  // append stage so the GUI won't crash due to inconsistent state
308  transportable->appendStage(new MSPerson::MSPersonStage_Walking(transportable->getID(), ConstMSEdgeVector({ myOrigin, myDestination }), myDestinationStop, myDuration, mySpeed, previous->getArrivalPos(), myArrivalPos, myDepartPosLat), stageIndex++);
310  const std::string error = "No connection found between edge '" + myOrigin->getID() + "' and edge '" + (myDestinationStop != nullptr ? myDestinationStop->getID() : myDestination->getID()) + "' for person '" + transportable->getID() + "'.";
311  transportable->myStep++;
312  throw ProcessError(error);
313  } else {
314  // pedestrian will teleport
315  }
316  }
317  if (vehicle != nullptr && !carUsed) {
318  vehControl.deleteVehicle(vehicle, true);
319  }
320  }
321 }
322 
323 
324 void
325 MSTransportable::Stage_Trip::proceed(MSNet* net, MSTransportable* transportable, SUMOTime now, Stage* /* previous */) {
326  // just skip the stage, every interesting happens in setArrived
327  transportable->proceed(net, now);
328 }
329 
330 
331 void
333 }
334 
335 
336 void
337 MSTransportable::Stage_Trip::routeOutput(OutputDevice&, const bool /* withRouteLength */) const {
338 }
339 
340 
341 void
343 }
344 
345 
346 void
348 }
349 
350 
351 std::string
353  return "trip from '" + myOrigin->getID() + "' to '" + getDestination()->getID() + "'";
354 }
355 
356 
357 
358 /* -------------------------------------------------------------------------
359 * MSTransportable::Stage_Waiting - methods
360 * ----------------------------------------------------------------------- */
362  SUMOTime duration, SUMOTime until, double pos, const std::string& actType,
363  const bool initial) :
364  MSTransportable::Stage(destination, toStop, SUMOVehicleParameter::interpretEdgePos(
365  pos, destination->getLength(), SUMO_ATTR_DEPARTPOS, "stopping at " + destination->getID()),
366  initial ? WAITING_FOR_DEPART : WAITING),
367  myWaitingDuration(duration),
368  myWaitingUntil(until),
369  myActType(actType) {
370 }
371 
372 
374 
378 }
379 
380 SUMOTime
382  return myWaitingUntil;
383 }
384 
385 
386 Position
389  ROADSIDE_OFFSET * (MSNet::getInstance()->lefthand() ? -1 : 1));
390 }
391 
392 
393 double
395  return getEdgeAngle(myDestination, myArrivalPos) + M_PI / 2 * (MSNet::getInstance()->lefthand() ? -1 : 1);
396 }
397 
398 
399 void
401  myDeparted = now;
402  const SUMOTime until = MAX3(now, now + myWaitingDuration, myWaitingUntil);
403  if (myDestinationStop != nullptr) {
404  myDestinationStop->addTransportable(transportable);
405  }
406  if (dynamic_cast<MSPerson*>(transportable) != nullptr) {
407  previous->getEdge()->addPerson(transportable);
408  net->getPersonControl().setWaitEnd(until, transportable);
409  } else {
410  previous->getEdge()->addContainer(transportable);
411  net->getContainerControl().setWaitEnd(until, transportable);
412  }
413 }
414 
415 
416 void
418  if (myType != WAITING_FOR_DEPART) {
419  os.openTag("stop");
420  os.writeAttr("duration", time2string(myArrived - myDeparted));
421  os.writeAttr("arrival", time2string(myArrived));
422  os.writeAttr("arrivalPos", toString(myArrivalPos));
423  os.writeAttr("actType", toString(myActType));
424  os.closeTag();
425  }
426 }
427 
428 
429 void
430 MSTransportable::Stage_Waiting::routeOutput(OutputDevice& os, const bool /* withRouteLength */) const {
431  if (myType != WAITING_FOR_DEPART) {
432  // lane index is arbitrary
433  os.openTag("stop").writeAttr(SUMO_ATTR_LANE, getDestination()->getID() + "_0");
434  if (myWaitingDuration >= 0) {
436  }
437  if (myWaitingUntil >= 0) {
439  }
440  os.closeTag();
441  }
442 }
443 
444 
445 void
447  os.openTag("event").writeAttr("time", time2string(t)).writeAttr("type", "actstart " + myActType)
448  .writeAttr("agent", p.getID()).writeAttr("link", getEdge()->getID()).closeTag();
449 }
450 
451 
452 void
454  os.openTag("event").writeAttr("time", time2string(t)).writeAttr("type", "actend " + myActType).writeAttr("agent", p.getID())
455  .writeAttr("link", getEdge()->getID()).closeTag();
456 }
457 
458 
459 SUMOTime
461  return now - myDeparted;
462 }
463 
464 
465 void
467  MSTransportableControl& tc = (dynamic_cast<MSPerson*>(t) != nullptr ?
470  tc.abortWaiting(t);
471 }
472 
473 
474 std::string
476  std::string timeInfo;
477  if (myWaitingUntil >= 0) {
478  timeInfo += " until " + time2string(myWaitingUntil);
479  }
480  if (myWaitingDuration >= 0) {
481  timeInfo += " duration " + time2string(myWaitingDuration);
482  }
483  return "stopping at edge '" + getDestination()->getID() + "' " + timeInfo + " (" + myActType + ")";
484 }
485 
486 
487 /* -------------------------------------------------------------------------
488 * MSTransportable::Stage_Driving - methods
489 * ----------------------------------------------------------------------- */
491  MSStoppingPlace* toStop, const double arrivalPos, const std::vector<std::string>& lines,
492  const std::string& intendedVeh, SUMOTime intendedDepart) :
493  MSTransportable::Stage(destination, toStop, arrivalPos, DRIVING),
494  myLines(lines.begin(), lines.end()),
495  myVehicle(nullptr),
496  myVehicleID("NULL"),
497  myVehicleVClass(SVC_IGNORING),
498  myVehicleDistance(-1.),
499  myWaitingSince(-1),
500  myWaitingEdge(nullptr),
501  myStopWaitPos(Position::INVALID),
502  myIntendedVehicleID(intendedVeh),
503  myIntendedDepart(intendedDepart) {
504 }
505 
506 
508 
509 const MSEdge*
511  if (myVehicle != nullptr) {
512  if (myVehicle->getLane() != nullptr) {
513  return &myVehicle->getLane()->getEdge();
514  }
515  return myVehicle->getEdge();
516  }
517  return myWaitingEdge;
518 }
519 
520 
521 const MSEdge*
523  return myWaitingEdge;
524 }
525 
526 
527 double
529  if (isWaiting4Vehicle()) {
530  return myWaitingPos;
531  }
532  // vehicle may already have passed the lane (check whether this is correct)
534 }
535 
536 
537 Position
539  if (isWaiting4Vehicle()) {
541  return myStopWaitPos;
542  }
544  ROADSIDE_OFFSET * (MSNet::getInstance()->lefthand() ? -1 : 1));
545  }
546  return myVehicle->getPosition();
547 }
548 
549 
550 double
552  if (!isWaiting4Vehicle()) {
553  MSVehicle* veh = dynamic_cast<MSVehicle*>(myVehicle);
554  if (veh != nullptr) {
555  return veh->getAngle();
556  } else {
557  return 0;
558  }
559  }
560  return getEdgeAngle(myWaitingEdge, myWaitingPos) + M_PI / 2. * (MSNet::getInstance()->lefthand() ? -1 : 1);
561 }
562 
563 
564 bool
566  return (myLines.count(vehicle->getID()) > 0
567  || myLines.count(vehicle->getParameter().line) > 0
568  || (myLines.count("ANY") > 0 && vehicle->stopsAt(myDestinationStop)));
569 }
570 
571 
572 bool
574  return myVehicle == nullptr;
575 }
576 
577 
578 SUMOTime
580  return isWaiting4Vehicle() ? now - myWaitingSince : 0;
581 }
582 
583 
584 double
586  return isWaiting4Vehicle() ? 0 : myVehicle->getSpeed();
587 }
588 
589 
592  ConstMSEdgeVector result;
593  result.push_back(getFromEdge());
594  result.push_back(getDestination());
595  return result;
596 }
597 
598 void
600  MSTransportable::Stage::setArrived(net, transportable, now);
601  if (myVehicle != nullptr) {
602  // distance was previously set to driven distance upon embarking
606  if (myVehicle->isStopped()) {
608  }
609  } else {
610  myVehicleDistance = -1.;
611  }
612 }
613 
614 void
616  myVehicle = v;
617  myVehicleID = v->getID();
619  myVehicleVClass = v->getVClass();
623 }
624 
625 void
627  if (myVehicle != nullptr) {
628  // jumping out of a moving vehicle!
629  dynamic_cast<MSVehicle*>(myVehicle)->removeTransportable(t);
630  } else {
631  MSTransportableControl& tc = (dynamic_cast<MSPerson*>(t) != nullptr ?
635  }
636 }
637 
638 
639 std::string
641  return isWaiting4Vehicle() ? ("waiting for " + joinToString(myLines, ",")
642  + " at " + (myDestinationStop == nullptr
643  ? ("edge '" + myWaitingEdge->getID() + "'")
644  : ("busStop '" + myDestinationStop->getID() + "'"))
645  ) : "";
646 }
647 
648 
649 void
651  os.openTag("event").writeAttr("time", time2string(t)).writeAttr("type", "arrival").writeAttr("agent", p.getID()).writeAttr("link", getEdge()->getID()).closeTag();
652 }
653 
654 
655 void
657  os.openTag("event").writeAttr("time", time2string(t)).writeAttr("type", "arrival").writeAttr("agent", p.getID()).writeAttr("link", getEdge()->getID()).closeTag();
658 }
659 
660 
661 
662 /* -------------------------------------------------------------------------
663  * MSTransportable - methods
664  * ----------------------------------------------------------------------- */
666  : myParameter(pars), myVType(vtype), myPlan(plan) {
667  myStep = myPlan->begin();
668  // init devices
670 }
671 
672 
674  if (myStep != myPlan->end() && getCurrentStageType() == DRIVING) {
675  Stage_Driving* const stage = dynamic_cast<Stage_Driving*>(*myStep);
676  if (stage->getVehicle() != nullptr) {
677  stage->getVehicle()->removeTransportable(this);
678  }
679  }
680  if (myPlan != nullptr) {
681  for (MSTransportablePlan::const_iterator i = myPlan->begin(); i != myPlan->end(); ++i) {
682  delete *i;
683  }
684  delete myPlan;
685  myPlan = nullptr;
686  }
687  delete myParameter;
688  if (myVType->isVehicleSpecific()) {
690  }
691 }
692 
693 const std::string&
695  return myParameter->id;
696 }
697 
698 SUMOTime
700  return myParameter->depart;
701 }
702 
703 void
705  (*myStep)->setDeparted(now);
706 }
707 
708 double
710  return (*myStep)->getEdgePos(MSNet::getInstance()->getCurrentTimeStep());
711 }
712 
713 Position
715  return (*myStep)->getPosition(MSNet::getInstance()->getCurrentTimeStep());
716 }
717 
718 double
720  return (*myStep)->getAngle(MSNet::getInstance()->getCurrentTimeStep());
721 }
722 
723 double
725  return STEPS2TIME((*myStep)->getWaitingTime(MSNet::getInstance()->getCurrentTimeStep()));
726 }
727 
728 double
730  return (*myStep)->getSpeed();
731 }
732 
733 
734 int
736  return (int)(myPlan->end() - myStep);
737 }
738 
739 int
741  return (int)myPlan->size();
742 }
743 
744 void
746  // myStep is invalidated upon modifying myPlan
747  const int stepIndex = (int)(myStep - myPlan->begin());
748  if (next < 0) {
749  myPlan->push_back(stage);
750  } else {
751  if (stepIndex + next > (int)myPlan->size()) {
752  throw ProcessError("invalid index '" + toString(next) + "' for inserting new stage into plan of '" + getID() + "'");
753  }
754  myPlan->insert(myPlan->begin() + stepIndex + next, stage);
755  }
756  myStep = myPlan->begin() + stepIndex;
757 }
758 
759 
760 void
762  assert(myStep + next < myPlan->end());
763  assert(next >= 0);
764  if (next > 0) {
765  // myStep is invalidated upon modifying myPlan
766  int stepIndex = (int)(myStep - myPlan->begin());
767  delete *(myStep + next);
768  myPlan->erase(myStep + next);
769  myStep = myPlan->begin() + stepIndex;
770  } else {
771  if (myStep + 1 == myPlan->end()) {
772  // stay in the simulation until the start of simStep to allow appending new stages (at the correct position)
773  appendStage(new Stage_Waiting(getEdge(), nullptr, 0, 0, getEdgePos(), "last stage removed", false));
774  }
775  (*myStep)->abort(this);
776  proceed(MSNet::getInstance(), MSNet::getInstance()->getCurrentTimeStep());
777  }
778 }
779 
780 
781 void
783  for (MSTransportablePlan::const_iterator i = myPlan->begin(); i != myPlan->end(); ++i) {
784  (*i)->setSpeed(speed);
785  }
786 }
787 
788 
789 void
791  if (myVType->isVehicleSpecific()) {
793  }
794  myVType = type;
795 }
796 
797 
800  if (myVType->isVehicleSpecific()) {
801  return *myVType;
802  }
803  MSVehicleType* type = myVType->buildSingularType(myVType->getID() + "@" + getID());
804  replaceVehicleType(type);
805  return *type;
806 }
807 
808 
811  PositionVector centerLine;
812  const Position p = getPosition();
813  const double angle = getAngle();
814  const double length = getVehicleType().getLength();
815  const Position back = p + Position(-cos(angle) * length, -sin(angle) * length);
816  centerLine.push_back(p);
817  centerLine.push_back(back);
818  centerLine.move2side(0.5 * getVehicleType().getWidth());
819  PositionVector result = centerLine;
820  centerLine.move2side(-getVehicleType().getWidth());
821  result.append(centerLine.reverse(), POSITION_EPS);
822  //std::cout << " transp=" << getID() << " p=" << p << " angle=" << GeomHelper::naviDegree(angle) << " back=" << back << " result=" << result << "\n";
823  return result;
824 }
825 
826 
827 std::string
828 MSTransportable::getStageSummary(int stageIndex) const {
829  assert(stageIndex < (int)myPlan->size());
830  assert(stageIndex >= 0);
831  return (*myPlan)[stageIndex]->getStageSummary();
832 }
833 
834 
835 bool
837  return myStep == myPlan->end();
838 }
839 
840 bool
842  return myPlan->size() > 0 && myPlan->front()->getDeparted() >= 0;
843 }
844 
845 
846 void
848  // check whether the transportable was riding to the orignal stop
849  // @note: parkingArea can currently not be set as myDestinationStop so we
850  // check for stops on the edge instead
851  assert(getCurrentStageType() == DRIVING);
852  if (dynamic_cast<MSPerson*>(this) == nullptr) {
853  WRITE_WARNING("parkingAreaReroute not support for containers");
854  return;
855  }
856  if (getDestination() == &orig->getLane().getEdge()) {
857  Stage_Driving* const stage = dynamic_cast<Stage_Driving*>(*myStep);
858  assert(stage != 0);
859  assert(stage->getVehicle() != 0);
860  // adapt plan
861  stage->setDestination(&replacement->getLane().getEdge(), replacement);
862  if (myStep + 1 == myPlan->end()) {
863  return;
864  }
865  // if the next step is a walk, adapt the route
866  Stage* nextStage = *(myStep + 1);
867  if (nextStage->getStageType() == TRIP) {
868  dynamic_cast<MSTransportable::Stage_Trip*>(nextStage)->setOrigin(stage->getDestination());
869  } else if (nextStage->getStageType() == MOVING_WITHOUT_VEHICLE) {
870  Stage_Trip* newStage = new Stage_Trip(stage->getDestination(), nullptr, nextStage->getDestination(),
871  nextStage->getDestinationStop(), -1, 0, "", -1, 1, 0, true, nextStage->getArrivalPos());
872  removeStage(1);
873  appendStage(newStage, 1);
874  }
875  // if the plan contains another ride with the same vehicle from the same
876  // parking area, adapt the preceeding walk to end at the replacement
877  // (ride origin is set implicitly from the walk destination)
878  for (auto it = myStep + 2; it != myPlan->end(); it++) {
879  const Stage* const futureStage = *it;
880  Stage* const prevStage = *(it - 1);
881  if (futureStage->getStageType() == DRIVING) {
882  const MSPerson::MSPersonStage_Driving* const ds = dynamic_cast<const MSPerson::MSPersonStage_Driving* const>(futureStage);
883  if (ds->getLines() == stage->getLines()
884  && prevStage->getDestination() == &orig->getLane().getEdge()) {
885  if (prevStage->getStageType() == TRIP) {
886  dynamic_cast<MSTransportable::Stage_Trip*>(prevStage)->setDestination(stage->getDestination(), replacement);
887  } else if (prevStage->getStageType() == MOVING_WITHOUT_VEHICLE) {
888  Stage_Trip* newStage = new Stage_Trip(prevStage->getFromEdge(), nullptr, stage->getDestination(),
889  replacement, -1, 0, "", -1, 1, 0, true, stage->getArrivalPos());
890  int prevStageRelIndex = (int)(it - 1 - myStep);
891  removeStage(prevStageRelIndex);
892  appendStage(newStage, prevStageRelIndex);
893  }
894  break;
895  }
896  }
897  }
898  }
899 }
900 
902 MSTransportable::getDevice(const std::type_info& type) const {
903  for (MSTransportableDevice* const dev : myDevices) {
904  if (typeid(*dev) == type) {
905  return dev;
906  }
907  }
908  return nullptr;
909 }
910 
911 double
913  const MSEdge* edge = getEdge();
914  const double ep = getEdgePos();
915  const double gp = edge->getLanes()[0]->interpolateLanePosToGeometryPos(ep);
916  return edge->getLanes()[0]->getShape().slopeDegreeAtOffset(gp);
917 }
918 
919 SUMOTime
921  return (*myStep)->getWaitingTime(MSNet::getInstance()->getCurrentTimeStep());
922 }
923 
924 double
927 }
928 
931  return getVehicleType().getVehicleClass();
932 }
933 
934 /****************************************************************************/
virtual void beginEventOutput(const MSTransportable &p, SUMOTime t, OutputDevice &os) const
Called for writing the events output.
The departure is person triggered.
void abortWaiting(MSTransportable *t)
aborts waiting stage of transportable
bool compute(const E *from, const E *to, const double departPos, const double arrivalPos, const std::string stopID, const double speed, const V *const vehicle, const SVCPermissions modeSet, const SUMOTime msTime, std::vector< TripItem > &into, const double externalFactor=0.)
Builds the route between the given edges using the minimum effort at the given time The definition of...
virtual void proceed(MSNet *net, MSTransportable *transportable, SUMOTime now, Stage *previous)
proceeds to the next step
double getAccessPos(const MSEdge *edge) const
the position on the given edge which is connected to this stop, -1 on failure
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:256
void abort(MSTransportable *)
abort this stage (TraCI)
virtual void proceed(MSNet *net, MSTransportable *transportable, SUMOTime now, Stage *previous)
proceeds to the next step
Stage(const MSEdge *destination, MSStoppingPlace *toStop, const double arrivalPos, StageType type)
constructor
std::string getStageSummary() const
return string summary of the current stage
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:670
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:80
virtual void deleteVehicle(SUMOVehicle *v, bool discard=false)
Deletes the vehicle.
long long int SUMOTime
Definition: SUMOTime.h:35
double getBeginLanePosition() const
Returns the begin position of this stop.
std::string getWaitingDescription() const
Return where the person waits and for what.
std::string myActType
The type of activity.
double getAngle(SUMOTime now) const
returns the angle of the transportable
double getAngle() const
Returns the vehicle&#39;s direction in radians.
Definition: MSVehicle.h:681
virtual const MSEdge * getFromEdge() const
void append(const PositionVector &v, double sameThreshold=2.0)
virtual void setArrived(MSNet *net, MSTransportable *transportable, SUMOTime now)
logs end of the step
double getMaxSpeed() const
Returns the vehicle&#39;s maximum speed.
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types...
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
const MSEdge * getEdge() const
Returns the current edge.
const SVCPermissions myModeSet
The allowed modes of transportation.
MSStoppingPlace * getStoppingPlace(const std::string &id, const SumoXMLTag category) const
Returns the named stopping place of the given category.
Definition: MSNet.cpp:899
virtual const MSRoute & getRoute() const =0
Returns the current route.
A lane area vehicles can halt at.
static void buildTransportableDevices(MSTransportable &p, std::vector< MSTransportableDevice *> &into)
Build devices for the given person, if needed.
Definition: MSDevice.cpp:112
void setSpeed(double speed)
sets the walking speed (ignored in other stages)
virtual double getEdgePos() const
Return the position on the edge.
double getAngle(SUMOTime now) const
returns the angle of the transportable
bool hasArrived() const
return whether the person has reached the end of its plan
PositionVector getBoundingBox() const
return the bounding box of the person
const MSEdge * getDestination() const
returns the destination edge
Stage_Waiting(const MSEdge *destination, MSStoppingPlace *toStop, SUMOTime duration, SUMOTime until, double pos, const std::string &actType, const bool initial)
constructor
vehicle is a bicycle
void abort(MSTransportable *)
abort this stage (TraCI)
const std::set< std::string > & getLines() const
virtual const MSEdge * getEdge() const
Returns the current edge.
The position is given.
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
MSVehicleType * getVType(const std::string &id=DEFAULT_VTYPE_ID, std::mt19937 *rng=nullptr)
Returns the named vehicle type or a sample from the named distribution.
const MSEdge * getEdge() const
Returns the current edge.
virtual double getEdgePos(SUMOTime now) const
static double rand(std::mt19937 *rng=0)
Returns a random real number in [0, 1)
Definition: RandHelper.h:60
double getSlope() const
Returns the slope of the road at vehicle&#39;s position.
virtual const MSEdge * getEdge() const =0
Returns the edge the vehicle is currently at.
#define INVALID
virtual void beginEventOutput(const MSTransportable &p, SUMOTime t, OutputDevice &os) const
Called for writing the events output.
MSIntermodalRouter & getIntermodalRouter(const int routingMode=0, const MSEdgeVector &prohibited=MSEdgeVector()) const
Definition: MSNet.cpp:995
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:65
void setWaitEnd(SUMOTime time, MSTransportable *transportable)
sets the arrival time for a waiting transportable
ConstMSEdgeVector getEdges() const
the edges of the current stage
virtual void removeTransportable(MSTransportable *t)=0
removes a person or container
virtual MSLane * getLane() const =0
Returns the lane the vehicle is on.
Position getPosition(SUMOTime now) const
returns the position of the transportable
double getEdgePos(SUMOTime now) const
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:165
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:168
Stage_Trip(const MSEdge *origin, MSStoppingPlace *fromStop, const MSEdge *destination, MSStoppingPlace *toStop, const SUMOTime duration, const SVCPermissions modeSet, const std::string &vTypes, const double speed, const double walkFactor, const double departPosLat, const bool hasArrivalPos, const double arrivalPos)
constructor
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:478
const std::set< std::string > myLines
the lines to choose from
double getSpeed() const
the speed of the transportable
PositionVector reverse() const
reverse position vector
const std::string DEFAULT_BIKETYPE_ID
virtual bool addVehicle(const std::string &id, SUMOVehicle *v)
Tries to insert the vehicle into the internal vehicle container.
virtual SUMOVehicleClass getVClass() const =0
Returns the vehicle&#39;s access class.
virtual void beginEventOutput(const MSTransportable &p, SUMOTime t, OutputDevice &os) const
Called for writing the events output.
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:73
virtual bool proceed(MSNet *net, SUMOTime time)=0
SUMOTime myDuration
the time the trip should take (applies to only walking)
const std::string & getID() const
Returns the id.
Definition: Named.h:77
#define TIME2STEPS(x)
Definition: SUMOTime.h:59
Position getLanePosition(const MSLane *lane, double at, double offset) const
get position on lane at length at with orthogonal offset
virtual double getSpeed() const
the current speed of the transportable
const MSEdge * myDestination
the next edge to reach by getting transported
bool hasNext()
returns the information whether further substrings exist
MSStoppingPlace * myDestinationStop
the stop to reach by getting transported (if any)
const SUMOVehicleParameter & getParameter() const
MSTransportablePlan::iterator myStep
the iterator over the route
double getEdgePos(SUMOTime now) const
double getLength() const
return the length of the edge
Definition: MSEdge.h:582
SUMOVehicleClass getVClass() const
Returns the vehicle&#39;s access class.
The position is chosen randomly.
const MSEdge * getFromEdge() const
int getNumRemainingStages() const
Return the number of remaining stages (including the current)
T MAX3(T a, T b, T c)
Definition: StdDefs.h:94
SUMOTime getWaitingTime() const
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:239
The simulated network and simulation perfomer.
Definition: MSNet.h:92
The car-following model and parameter.
Definition: MSVehicleType.h:66
bool isVehicleSpecific() const
Returns whether this type belongs to a single vehicle only (was modified)
void setArrived(MSNet *net, MSTransportable *transportable, SUMOTime now)
marks arrival time and records driven distance
virtual MSTransportableControl & getContainerControl()
Returns the container control.
Definition: MSNet.cpp:806
const SUMOVehicleParameter * myParameter
the plan of the transportable
void removeStage(int next)
removes the nth next stage
std::string getStageSummary() const
return string summary of the current stage
bool isWaiting4Vehicle() const
Whether the person waits for a vehicle.
SUMOTime myWaitingSince
The time since which this person is waiting for a ride.
MSVehicleType & getSingularType()
Replaces the current vehicle type with a new one used by this vehicle only.
A road/street connecting two junctions.
Definition: MSEdge.h:76
double myDepartPos
The depart position.
const double myWalkFactor
The factor to apply to walking durations.
std::vector< MSTransportable::Stage * > MSTransportablePlan
the structure holding the plan of a transportable
double getEndLanePosition() const
Returns the end position of this stop.
virtual ConstMSEdgeVector getEdges() const
the edges of the current stage
std::vector< MSTransportableDevice * > myDevices
The devices this transportable has.
MSTransportable::Stage * getNextStage(int next) const
Return the current stage.
virtual SUMOTime getWaitingTime(SUMOTime now) const
the time this transportable spent waiting
MSVehicleType * myVType
This transportable&#39;s type. (mainly used for drawing related information Note sure if it is really nec...
SUMOTime myArrived
the time at which this stage ended
virtual void setArrived(MSNet *net, MSTransportable *transportable, SUMOTime now)
logs end of the step
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:48
SUMOTime myDeparted
the time at which this stage started
void setDeparted(SUMOTime now)
logs depart time of the current stage
Representation of a vehicle.
Definition: SUMOVehicle.h:61
static bool gCheckRoutes
Definition: MSGlobals.h:79
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
MSVehicleType * buildSingularType(const std::string &id) const
Duplicates the microsim vehicle type giving the newly created type the given id, marking it as vehicl...
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:798
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
SUMOTime getDesiredDepart() const
Returns the desired departure time.
A list of positions.
Position getPosition(SUMOTime now) const
returns the position of the transportable
virtual double getAngle() const
return the current angle of the transportable
virtual void addPerson(MSTransportable *p) const
Definition: MSEdge.h:609
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:337
bool hasDeparted() const
return whether the transportable has started it&#39;s plan
virtual ~Stage_Trip()
destructor
void move2side(double amount, double maxExtension=100)
move position vector to side using certain ammount
SUMOTime getDeparted() const
get departure time of stage
void removeVType(const MSVehicleType *vehType)
virtual ~MSTransportable()
destructor
SUMOTime getWaitingTime(SUMOTime now) const
time spent waiting for a ride
#define STEPS2TIME(x)
Definition: SUMOTime.h:57
Abstract in-person device.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:284
double getArrivalPos() const
double getMaxSpeed() const
Get vehicle&#39;s maximum speed [m/s].
T MIN2(T a, T b)
Definition: StdDefs.h:74
std::string myVehicleID
cached vehicle data for output after the vehicle has been removed
#define POSITION_EPS
Definition: config.h:169
const std::string & getID() const
returns the id of the transportable
const double mySpeed
The walking speed.
virtual ~Stage_Driving()
destructor
SUMOTime myWaitingUntil
the time until the person is waiting
SUMOVehicle * myVehicle
The taken vehicle.
Position getPosition(SUMOTime now) const
returns the position of the transportable
std::string getStageSummary(int stageIndex) const
return textual summary for the given stage
virtual void endEventOutput(const MSTransportable &p, SUMOTime t, OutputDevice &os) const
Called for writing the events output (end of an action)
bool lefthand() const
return whether the network was built for lefthand traffic
Definition: MSNet.h:662
vehicle is a passenger car (a "normal" car)
bool addTransportable(MSTransportable *p)
adds a transportable to this stop
std::string line
The vehicle&#39;s line (mainly for public transport)
Position getEdgePosition(const MSEdge *e, double at, double offset) const
get position on edge e at length at with orthogonal offset
virtual void endEventOutput(const MSTransportable &p, SUMOTime t, OutputDevice &os) const
Called for writing the events output (end of an action)
virtual double getSpeed() const
the speed of the transportable
MSStoppingPlace * getDestinationStop() const
returns the destination stop (if any)
virtual double getSpeedFactor() const
the current speed factor of the transportable (where applicable)
void appendStage(Stage *stage, int next=-1)
Appends the given stage to the current plan.
virtual double getDepartPos() const =0
Returns this vehicle&#39;s real departure position.
double getAngle(SUMOTime now) const
returns the angle of the transportable
void rerouteParkingArea(MSStoppingPlace *orig, MSStoppingPlace *replacement)
adapt plan when the vehicle reroutes and now stops at replacement instead of orig ...
double departPos
(optional) The position the vehicle shall depart from
StageType myType
The type of this stage.
virtual void tripInfoOutput(OutputDevice &os, const MSTransportable *const transportable) const
Called on writing tripinfo output.
Structure representing possible vehicle parameter.
MSTransportable(const SUMOVehicleParameter *pars, MSVehicleType *vtype, MSTransportablePlan *plan)
constructor
virtual void addContainer(MSTransportable *container) const
Add a container to myContainers.
Definition: MSEdge.h:621
void abortWaitingForVehicle(MSTransportable *t)
let the given transportable abort waiting for a vehicle (when removing stage via TraCI) ...
#define M_PI
Definition: odrSpiral.cpp:40
virtual Position getPosition() const
Return the Network coordinate of the transportable.
Stage_Driving(const MSEdge *destination, MSStoppingPlace *toStop, const double arrivalPos, const std::vector< std::string > &lines, const std::string &intendedVeh="", SUMOTime intendedDepart=-1)
constructor
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle&#39;s parameter (including departure definition)
virtual void endEventOutput(const MSTransportable &p, SUMOTime t, OutputDevice &os) const
Called for writing the events output (end of an action)
MSTransportableDevice * getDevice(const std::type_info &type) const
Returns a device of the given type if it exists or 0.
SUMOVehicle * getVehicle() const
Whether the transportable waits for a vehicle.
StageType getStageType() const
double interpolateLanePosToGeometryPos(double lanePos) const
Definition: MSLane.h:499
const std::string & getID() const
Returns the name of the vehicle type.
Definition: MSVehicleType.h:94
virtual void tripInfoOutput(OutputDevice &os, const MSTransportable *const transportable) const
Called on writing tripinfo output.
virtual void routeOutput(OutputDevice &os, const bool withRouteLength) const
Called on writing vehroute output.
static const double ROADSIDE_OFFSET
the offset for computing positions when standing at an edge
const MSEdge * myOrigin
the origin edge
void replaceVehicleType(MSVehicleType *type)
Replaces the current vehicle type by the one given.
double getLength() const
Get vehicle&#39;s length [m].
SUMOTime getWaitingTime(SUMOTime now) const
the time this transportable spent waiting
const std::string myVTypes
The possible vehicles to use.
const int VEHPARS_VTYPE_SET
double getEdgeAngle(const MSEdge *e, double at) const
get angle of the edge at a certain position
virtual bool isWaitingFor(const SUMOVehicle *vehicle) const
Whether the transportable waits for the given vehicle.
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type.
virtual double getWaitingSeconds() const
the time this transportable spent waiting in seconds
virtual double getPositionOnLane() const =0
Get the vehicle&#39;s position along the lane.
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:64
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
void setDeparted(SUMOTime now)
logs end of the step
const double myDepartPosLat
The lateral depart position.
const MSEdge * getDestination() const
Returns the current destination.
MSTransportablePlan * myPlan
the plan of the transportable
virtual ~Stage_Waiting()
destructor
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:70
The class responsible for building and deletion of vehicles.
const int VEHPARS_DEPARTPOS_SET
SVCPermissions getPermissions() const
Definition: MSEdge.h:546
virtual ~Stage()
destructor
virtual SUMOVehicle * buildVehicle(SUMOVehicleParameter *defs, const MSRoute *route, MSVehicleType *type, const bool ignoreStopErrors, const bool fromRouteFile=true)
Builds a vehicle, increases the number of built vehicles.
const bool myHaveArrivalPos
whether an arrivalPos was in the input
const MSLane & getLane() const
Returns the lane this stop is located at.
const MSStoppingPlace * myOriginStop
the origin edge
virtual const ConstMSEdgeVector::const_iterator & getCurrentRouteEdge() const =0
Returns an iterator pointing to the current edge in this vehicles route.
const MSEdge * getEdge() const
Returns the current edge.
virtual void routeOutput(OutputDevice &os, const bool withRouteLength) const
Called on writing vehroute output.
virtual double getSpeed() const =0
Returns the vehicle&#39;s current speed.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
Representation of a lane in the micro simulation.
Definition: MSLane.h:83
virtual bool isStopped() const =0
Returns whether the vehicle is at a stop.
bool isWaitingFor(const SUMOVehicle *vehicle) const
Whether the person waits for the given vehicle.
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
Definition: ToString.h:247
vehicles ignoring classes
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
SUMOVehicleClass getVehicleClass() const
Get this vehicle type&#39;s vehicle class.
SUMOTime myWaitingDuration
the time the person is waiting
int getNumStages() const
Return the total number stages in this persons plan.
std::string id
The vehicle&#39;s id.
static const Position INVALID
used to indicate that a position is valid
Definition: Position.h:285
virtual bool stopsAt(MSStoppingPlace *stop) const =0
Returns whether the vehicle stops at the given stopping place.
virtual Position getPosition(const double offset=0) const =0
Return current position (x/y, cartesian)
double myArrivalPos
the position at which we want to arrive
StageType getCurrentStageType() const
the current stage type of the transportable
void setDestination(const MSEdge *newDestination, MSStoppingPlace *newDestStop)
double getDistanceBetween(double fromPos, double toPos, const MSEdge *fromEdge, const MSEdge *toEdge, bool includeInternal=true, int routePosition=0) const
Compute the distance between 2 given edges on this route, including the length of internal lanes...
Definition: MSRoute.cpp:277