Eclipse SUMO - Simulation of Urban MObility
MSBaseVehicle.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-2020 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
20 // A base class for vehicle implementations
21 /****************************************************************************/
22 #include <config.h>
23 
24 #include <iostream>
25 #include <cassert>
26 #include <utils/common/StdDefs.h>
33 #include "MSGlobals.h"
34 #include "MSVehicleControl.h"
35 #include "MSVehicleType.h"
36 #include "MSEdge.h"
37 #include "MSLane.h"
38 #include "MSMoveReminder.h"
39 #include "MSEdgeWeightsStorage.h"
40 #include "MSBaseVehicle.h"
41 #include "MSNet.h"
42 #include "MSStop.h"
43 #include "MSParkingArea.h"
44 #include "devices/MSDevice.h"
53 #include "MSInsertionControl.h"
54 #include <mesosim/MELoop.h>
55 
56 //#define DEBUG_REROUTE
57 //#define DEBUG_COND (getID() == "follower")
58 //#define DEBUG_COND (true)
59 #define DEBUG_COND (isSelected())
60 
61 // ===========================================================================
62 // static members
63 // ===========================================================================
65 std::vector<MSTransportable*> MSBaseVehicle::myEmptyTransportableVector;
66 #ifdef _DEBUG
67 std::set<std::string> MSBaseVehicle::myShallTraceMoveReminders;
68 #endif
70 
71 // ===========================================================================
72 // Influencer method definitions
73 // ===========================================================================
74 
76  myRoutingMode(0)
77 {}
78 
81  if (myRoutingMode == 1) {
82  return MSRoutingEngine::getRouterTT(rngIndex, svc);
83  } else {
84  return MSNet::getInstance()->getRouterTT(rngIndex);
85  }
86 }
87 
88 
89 
90 // ===========================================================================
91 // method definitions
92 // ===========================================================================
93 
94 double
96  throw ProcessError("getPreviousSpeed() is not available for non-MSVehicles.");
97 }
98 
99 
101  MSVehicleType* type, const double speedFactor) :
102  SUMOVehicle(pars->id),
103  myParameter(pars),
104  myRoute(route),
105  myType(type),
106  myCurrEdge(route->begin()),
107  myChosenSpeedFactor(pars->speedFactor < 0 ? speedFactor : pars->speedFactor),
108  myMoveReminders(0),
109  myPersonDevice(nullptr),
110  myContainerDevice(nullptr),
112  myDepartPos(-1),
113  myArrivalPos(-1),
114  myArrivalLane(-1),
115  myNumberReroutes(0),
117  myOdometer(0.),
120  myEdgeWeights(nullptr)
121 #ifdef _DEBUG
122  , myTraceMoveReminders(myShallTraceMoveReminders.count(pars->id) > 0)
123 #endif
124 {
125  if ((*myRoute->begin())->isTazConnector() || myRoute->getLastEdge()->isTazConnector()) {
127  }
128  if (!pars->wasSet(VEHPARS_FORCE_REROUTE)) {
130  }
133  const int routeEdges = (int)myRoute->getEdges().size();
135  // write specific edge in vehroute output for reproducibility
136  pars->departEdge = RandHelper::rand(0, routeEdges);
138  }
139  assert(pars->departEdge >= 0);
140  assert(pars->departEdge < routeEdges);
141  myCurrEdge += pars->departEdge;
142  }
143 }
144 
145 
147  delete myEdgeWeights;
148  myRoute->release();
149  if (myParameter->repetitionNumber == 0) {
151  }
152  for (MSVehicleDevice* dev : myDevices) {
153  delete dev;
154  }
155  delete myParameter;
156 }
157 
158 
159 void
162  for (MSVehicleDevice* dev : myDevices) {
163  myMoveReminders.push_back(std::make_pair(dev, 0.));
164  }
165 }
166 
167 
168 void
169 MSBaseVehicle::setID(const std::string& /*newID*/) {
170  throw ProcessError("Changing a vehicle ID is not permitted");
171 }
172 
175  return *myParameter;
176 }
177 
178 const std::map<int, double>*
180  MSDevice_Battery* batteryDevice = static_cast<MSDevice_Battery*>(getDevice(typeid(MSDevice_Battery)));
181  if (batteryDevice != nullptr) {
182  return &batteryDevice->getEnergyParams();
183  } else {
184  return nullptr;
185  }
186 }
187 
188 void
190  delete myParameter;
191  myParameter = newParameter;
192 }
193 
194 double
196  return myType->getMaxSpeed();
197 }
198 
199 
200 const MSEdge*
201 MSBaseVehicle::succEdge(int nSuccs) const {
202  if (myCurrEdge + nSuccs < myRoute->end() && std::distance(myCurrEdge, myRoute->begin()) <= nSuccs) {
203  return *(myCurrEdge + nSuccs);
204  } else {
205  return nullptr;
206  }
207 }
208 
209 
210 const MSEdge*
212  return *myCurrEdge;
213 }
214 
215 
216 void
217 MSBaseVehicle::reroute(SUMOTime t, const std::string& info, SUMOAbstractRouter<MSEdge, SUMOVehicle>& router, const bool onInit, const bool withTaz, const bool silent) {
218  // check whether to reroute
219  const MSEdge* source = withTaz && onInit ? MSEdge::dictionary(myParameter->fromTaz + "-source") : getRerouteOrigin();
220  if (source == nullptr) {
221  source = getRerouteOrigin();
222  }
223  const MSEdge* sink = withTaz ? MSEdge::dictionary(myParameter->toTaz + "-sink") : myRoute->getLastEdge();
224  if (sink == nullptr) {
225  sink = myRoute->getLastEdge();
226  }
227  ConstMSEdgeVector oldEdgesRemaining(source == *myCurrEdge ? myCurrEdge : myCurrEdge + 1, myRoute->end());
228  ConstMSEdgeVector edges;
229  ConstMSEdgeVector stops;
230  if (myParameter->via.size() == 0) {
231  double firstPos = -1;
232  double lastPos = -1;
233  stops = getStopEdges(firstPos, lastPos);
234  if (stops.size() > 0) {
235  const double sourcePos = onInit ? 0 : getPositionOnLane();
236  // avoid superfluous waypoints for first and last edge
237  const bool skipFirst = stops.front() == source && sourcePos <= firstPos;
238  const bool skipLast = stops.back() == sink && myArrivalPos >= lastPos;
239 #ifdef DEBUG_REROUTE
240  if (DEBUG_COND) {
241  std::cout << SIMTIME << " reroute " << info << " veh=" << getID() << " lane=" << Named::getIDSecure(getLane())
242  << " source=" << source->getID() << " sourcePos=" << sourcePos << " firstPos=" << firstPos << " arrivalPos=" << myArrivalPos << " lastPos=" << lastPos
243  << " route=" << toString(myRoute->getEdges()) << " stopEdges=" << toString(stops) << " skipFirst=" << skipFirst << " skipLast=" << skipLast << "\n";
244  }
245 #endif
246  if (stops.size() == 1 && (skipFirst || skipLast)) {
247  stops.clear();
248  } else {
249  if (skipFirst) {
250  stops.erase(stops.begin());
251  }
252  if (skipLast) {
253  stops.erase(stops.end() - 1);
254  }
255  }
256  }
257  } else {
258  // via takes precedence over stop edges
259  // XXX check for inconsistencies #2275
260  for (std::vector<std::string>::const_iterator it = myParameter->via.begin(); it != myParameter->via.end(); ++it) {
261  MSEdge* viaEdge = MSEdge::dictionary(*it);
262  if (viaEdge == source || viaEdge == sink) {
263  continue;
264  }
265  assert(viaEdge != 0);
266  if (!viaEdge->isTazConnector() && viaEdge->allowedLanes(getVClass()) == nullptr) {
267  throw ProcessError("Vehicle '" + getID() + "' is not allowed on any lane of via edge '" + viaEdge->getID() + "'.");
268  }
269  stops.push_back(viaEdge);
270  }
271  }
272 
273  for (MSRouteIterator s = stops.begin(); s != stops.end(); ++s) {
274  // !!! need to adapt t here
275  ConstMSEdgeVector into;
276  router.computeLooped(source, *s, this, t, into, silent);
277  if (into.size() > 0) {
278  into.pop_back();
279  edges.insert(edges.end(), into.begin(), into.end());
280  if ((*s)->isTazConnector()) {
281  source = into.back();
282  edges.pop_back();
283  } else {
284  source = *s;
285  }
286  } else {
287  std::string error = "Vehicle '" + getID() + "' has no valid route from edge '" + source->getID() + "' to stop edge '" + (*s)->getID() + "'.";
288  if (MSGlobals::gCheckRoutes || silent) {
289  throw ProcessError(error);
290  } else {
291  WRITE_WARNING(error);
292  edges.push_back(source);
293  }
294  source = *s;
295  }
296  }
297  router.compute(source, sink, this, t, edges, silent);
298  if (edges.empty() && silent) {
299  return;
300  }
301  if (!edges.empty() && edges.front()->isTazConnector()) {
302  edges.erase(edges.begin());
303  }
304  if (!edges.empty() && edges.back()->isTazConnector()) {
305  edges.pop_back();
306  }
307  const double routeCost = router.recomputeCosts(edges, this, t);
308  const double previousCost = onInit ? routeCost : router.recomputeCosts(oldEdgesRemaining, this, t);
309  const double savings = previousCost - routeCost;
310  //if (getID() == "43") std::cout << SIMTIME << " pCost=" << previousCost << " cost=" << routeCost
311  // << " onInit=" << onInit
312  // << " prevEdges=" << toString(oldEdgesRemaining)
313  // << " newEdges=" << toString(edges)
314  // << "\n";
315  replaceRouteEdges(edges, routeCost, savings, info, onInit);
316  // this must be called even if the route could not be replaced
317  if (onInit) {
318  if (edges.empty()) {
320  throw ProcessError("Vehicle '" + getID() + "' has no valid route.");
321  } else if (source->isTazConnector()) {
322  WRITE_WARNING("Removing vehicle '" + getID() + "' which has no valid route.");
324  return;
325  }
326  }
328  }
329 }
330 
331 
332 bool
333 MSBaseVehicle::replaceRouteEdges(ConstMSEdgeVector& edges, double cost, double savings, const std::string& info, bool onInit, bool check, bool removeStops) {
334  if (edges.empty()) {
335  WRITE_WARNING("No route for vehicle '" + getID() + "' found.");
336  return false;
337  }
338  // build a new id, first
339  std::string id = getID();
340  if (id[0] != '!') {
341  id = "!" + id;
342  }
343  const std::string idSuffix = id + "!var#";
344  int varIndex = 1;
345  id = idSuffix + toString(varIndex);
346  while (MSRoute::hasRoute(id)) {
347  id = idSuffix + toString(++varIndex);
348  }
349  int oldSize = (int)edges.size();
350  if (!onInit) {
351  const MSEdge* const origin = getRerouteOrigin();
352  if (origin != *myCurrEdge && edges.front() == origin) {
353  edges.insert(edges.begin(), *myCurrEdge);
354  oldSize = (int)edges.size();
355  }
356  edges.insert(edges.begin(), myRoute->begin(), myCurrEdge);
357  }
359  // re-assign stop iterators when rerouting to a new parkingArea
360  return true;
361  }
362  const RGBColor& c = myRoute->getColor();
363  MSRoute* newRoute = new MSRoute(id, edges, false, &c == &RGBColor::DEFAULT_COLOR ? nullptr : new RGBColor(c), std::vector<SUMOVehicleParameter::Stop>());
364  newRoute->setCosts(cost);
365  newRoute->setSavings(savings);
366  if (!MSRoute::dictionary(id, newRoute)) {
367  delete newRoute;
368  return false;
369  }
370 
371  std::string msg;
372  if (check && !hasValidRoute(msg, newRoute)) {
373  WRITE_WARNING("Invalid route replacement for vehicle '" + getID() + "'. " + msg);
375  newRoute->addReference();
376  newRoute->release();
377  return false;
378  }
379  }
380  if (!replaceRoute(newRoute, info, onInit, (int)edges.size() - oldSize, false, removeStops)) {
381  newRoute->addReference();
382  newRoute->release();
383  return false;
384  }
385  return true;
386 }
387 
388 
389 bool
390 MSBaseVehicle::replaceRoute(const MSRoute* newRoute, const std::string& info, bool onInit, int offset, bool addRouteStops, bool removeStops) {
391  const ConstMSEdgeVector& edges = newRoute->getEdges();
392  // rebuild in-vehicle route information
393  if (onInit) {
394  myCurrEdge = newRoute->begin();
395  } else {
396  MSRouteIterator newCurrEdge = std::find(edges.begin() + offset, edges.end(), *myCurrEdge);
397  if (newCurrEdge == edges.end()) {
398  return false;
399  }
400  if (getLane() != nullptr && getLane()->getEdge().isInternal() && (
401  (newCurrEdge + 1) == edges.end() || (*(newCurrEdge + 1)) != &(getLane()->getOutgoingViaLanes().front().first->getEdge()))) {
402  return false;
403  }
404  myCurrEdge = newCurrEdge;
405  }
406  const bool stopsFromScratch = onInit && myRoute->getStops().empty();
407  // check whether the old route may be deleted (is not used by anyone else)
408  newRoute->addReference();
409  myRoute->release();
410  // assign new route
411  myRoute = newRoute;
412  // update arrival definition
414  // save information that the vehicle was rerouted
418  // if we did not drive yet it may be best to simply reassign the stops from scratch
419  if (stopsFromScratch) {
420  myStops.clear();
422  } else {
423  // recheck old stops
424  MSRouteIterator searchStart = myCurrEdge;
425  double lastPos = getPositionOnLane();
426  if (getLane() != nullptr && getLane()->isInternal()
427  && myStops.size() > 0 && !myStops.front().lane->isInternal()) {
428  // searchStart is still incoming to the intersection so lastPos
429  // relative to that edge must be adapted
430  lastPos += (*myCurrEdge)->getLength();
431  }
432 #ifdef DEBUG_REPLACE_ROUTE
433  if (DEBUG_COND) {
434  std::cout << " replaceRoute on " << (*myCurrEdge)->getID() << " lane=" << myLane->getID() << " stopsFromScratch=" << stopsFromScratch << "\n";
435  }
436 #endif
437  for (std::list<MSStop>::iterator iter = myStops.begin(); iter != myStops.end();) {
438  double endPos = iter->getEndPos(*this);
439 #ifdef DEBUG_REPLACE_ROUTE
440  if (DEBUG_COND) {
441  std::cout << " stopEdge=" << iter->lane->getEdge().getID() << " start=" << (searchStart - myCurrEdge) << " endPos=" << endPos << " lastPos=" << lastPos << "\n";
442  }
443 #endif
444  if (*searchStart != &iter->lane->getEdge()
445  || endPos < lastPos) {
446  if (searchStart != edges.end() && !iter->reached) {
447  searchStart++;
448  }
449  }
450  lastPos = endPos;
451 
452  iter->edge = std::find(searchStart, edges.end(), &iter->lane->getEdge());
453 #ifdef DEBUG_REPLACE_ROUTE
454  if (DEBUG_COND) {
455  std::cout << " foundIndex=" << (iter->edge - myCurrEdge) << " end=" << (edges.end() - myCurrEdge) << "\n";
456  }
457 #endif
458  if (iter->edge == edges.end()) {
459  if (removeStops) {
460  iter = myStops.erase(iter);
461  continue;
462  } else {
463  assert(false);
464  }
465  } else {
466  searchStart = iter->edge;
467  }
468  ++iter;
469  }
470  // add new stops
471  if (addRouteStops) {
472  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator i = newRoute->getStops().begin(); i != newRoute->getStops().end(); ++i) {
473  std::string error;
475  if (error != "") {
476  WRITE_WARNING(error);
477  }
478  }
479  }
480  }
481  return true;
482 }
483 
484 
485 double
487  return 0;
488 }
489 
490 
491 void
496 }
497 
498 
499 bool
501  return myDeparture != NOT_YET_DEPARTED;
502 }
503 
504 
505 bool
507  return succEdge(1) == nullptr;
508 }
509 
510 
511 int
513  return (int) std::distance(myRoute->begin(), myCurrEdge);
514 }
515 
516 
517 void
519  myCurrEdge = myRoute->begin() + index;
520  const_cast<SUMOVehicleParameter*>(myParameter)->departLaneProcedure = departLaneProcedure;
521  // !!! hack
522  myArrivalPos = (*(myRoute->end() - 1))->getLanes()[0]->getLength();
523 }
524 
525 double
528 }
529 
530 bool
532  if (getPersonNumber() >= getVehicleType().getPersonCapacity()) {
533  return false;
534  }
535  MSDevice_Taxi* taxiDevice = static_cast<MSDevice_Taxi*>(getDevice(typeid(MSDevice_Taxi)));
536  if (taxiDevice != nullptr) {
537  return taxiDevice->allowsBoarding(t);
538  }
539  return true;
540 }
541 
542 
543 void
545  if (transportable->isPerson()) {
546  if (myPersonDevice == nullptr) {
548  myMoveReminders.push_back(std::make_pair(myPersonDevice, 0.));
551  }
552  }
553  myPersonDevice->addTransportable(transportable);
554  } else {
555  if (myContainerDevice == nullptr) {
557  myMoveReminders.push_back(std::make_pair(myContainerDevice, 0.));
560  }
561  }
562  myContainerDevice->addTransportable(transportable);
563  }
564 }
565 
566 
567 bool
568 MSBaseVehicle::hasValidRoute(std::string& msg, const MSRoute* route) const {
569  MSRouteIterator start = myCurrEdge;
570  if (route == nullptr) {
571  route = myRoute;
572  } else {
573  start = route->begin();
574  }
575  MSRouteIterator last = route->end() - 1;
576  // check connectivity, first
577  for (MSRouteIterator e = start; e != last; ++e) {
578  if ((*e)->allowedLanes(**(e + 1), myType->getVehicleClass()) == nullptr) {
579  msg = "No connection between edge '" + (*e)->getID() + "' and edge '" + (*(e + 1))->getID() + "'.";
580  return false;
581  }
582  }
583  last = route->end();
584  // check usable lanes, then
585  for (MSRouteIterator e = start; e != last; ++e) {
586  if ((*e)->prohibits(this)) {
587  msg = "Edge '" + (*e)->getID() + "' prohibits.";
588  return false;
589  }
590  }
591  return true;
592 }
593 
594 
595 bool
597  if (myRoute->getEdges().size() > 0 && !(*myCurrEdge)->prohibits(this)) {
599  return true;
600  } else {
601  msg = "Vehicle '" + getID() + "' is not allowed to depart on its first edge.";
603  return false;
604  }
605 }
606 
607 
608 int
610  if (!update) {
611  return myRouteValidity;
612  }
613  // insertion check must be done in any case
614  std::string msg;
615  if (!hasValidRouteStart(msg)) {
617  throw ProcessError(msg);
618  } else if (!silent) {
619  // vehicle will be discarded
620  WRITE_WARNING(msg);
621  }
622  }
624  && (myRouteValidity & ROUTE_UNCHECKED) != 0
625  // we could check after the first rerouting
627  if (!hasValidRoute(msg, myRoute)) {
629  throw ProcessError("Vehicle '" + getID() + "' has no valid route. " + msg);
630  }
631  }
633  return myRouteValidity;
634 }
635 
636 void
638 #ifdef _DEBUG
639  if (myTraceMoveReminders) {
640  traceMoveReminder("add", rem, 0, true);
641  }
642 #endif
643  myMoveReminders.push_back(std::make_pair(rem, 0.));
644 }
645 
646 
647 void
649  for (MoveReminderCont::iterator r = myMoveReminders.begin(); r != myMoveReminders.end(); ++r) {
650  if (r->first == rem) {
651 #ifdef _DEBUG
652  if (myTraceMoveReminders) {
653  traceMoveReminder("remove", rem, 0, false);
654  }
655 #endif
656  myMoveReminders.erase(r);
657  return;
658  }
659  }
660 }
661 
662 
663 void
665  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
666  if (rem->first->notifyEnter(*this, reason, enteredLane)) {
667 #ifdef _DEBUG
668  if (myTraceMoveReminders) {
669  traceMoveReminder("notifyEnter", rem->first, rem->second, true);
670  }
671 #endif
672  ++rem;
673  } else {
674 #ifdef _DEBUG
675  if (myTraceMoveReminders) {
676  traceMoveReminder("notifyEnter", rem->first, rem->second, false);
677  }
678 #endif
679  rem = myMoveReminders.erase(rem);
680  }
681  }
682 }
683 
684 
685 void
687  if (myRoute->getLastEdge()->isTazConnector()) {
688  return;
689  }
690  const std::vector<MSLane*>& lanes = myRoute->getLastEdge()->getLanes();
691  const double lastLaneLength = lanes[0]->getLength();
692  switch (myParameter->arrivalPosProcedure) {
694  if (fabs(myParameter->arrivalPos) > lastLaneLength) {
695  WRITE_WARNING("Vehicle '" + getID() + "' will not be able to arrive at the given position!");
696  }
697  // Maybe we should warn the user about invalid inputs!
698  myArrivalPos = MIN2(myParameter->arrivalPos, lastLaneLength);
699  if (myArrivalPos < 0) {
700  myArrivalPos = MAX2(myArrivalPos + lastLaneLength, 0.);
701  }
702  break;
704  myArrivalPos = RandHelper::rand(lastLaneLength);
705  break;
707  myArrivalPos = lastLaneLength / 2.;
708  break;
709  default:
710  myArrivalPos = lastLaneLength;
711  break;
712  }
714  if (myParameter->arrivalLane >= (int)lanes.size() || !lanes[myParameter->arrivalLane]->allowsVehicleClass(myType->getVehicleClass())) {
715  WRITE_WARNING("Vehicle '" + getID() + "' will not be able to arrive at the given lane '" + myRoute->getLastEdge()->getID() + "_" + toString(myParameter->arrivalLane) + "'!");
716  }
717  myArrivalLane = MIN2(myParameter->arrivalLane, (int)(lanes.size() - 1));
718  }
720  for (std::vector<MSLane*>::const_iterator l = lanes.begin(); l != lanes.end(); ++l) {
721  if (myParameter->arrivalSpeed <= (*l)->getVehicleMaxSpeed(this)) {
722  return;
723  }
724  }
725  WRITE_WARNING("Vehicle '" + getID() + "' will not be able to arrive with the given speed!");
726  }
727 }
728 
729 
730 double
732  return MAX2(0., MIN2(1., getVehicleType().getImpatience() +
734 }
735 
736 
738 MSBaseVehicle::getDevice(const std::type_info& type) const {
739  for (MSVehicleDevice* const dev : myDevices) {
740  if (typeid(*dev) == type) {
741  return dev;
742  }
743  }
744  return nullptr;
745 }
746 
747 
748 void
750  // this saves lots of departParameters which are only needed for vehicles that did not yet depart
751  // the parameters may hold the name of a vTypeDistribution but we are interested in the actual type
753  // params and stops must be written in child classes since they may wish to add additional attributes first
755  std::ostringstream os;
756  os << myOdometer << " " << myNumberReroutes;
757  out.writeAttr(SUMO_ATTR_DISTANCE, os.str());
760  }
762  out.writeAttr(SUMO_ATTR_REROUTE, true);
763  }
765  // could be set from stop
767  }
768  // here starts the vehicle internal part (see loading)
769  // @note: remember to close the vehicle tag when calling this in a subclass!
770 }
771 
772 
773 bool
774 MSBaseVehicle::handleCollisionStop(MSStop& stop, const bool collision, const double distToStop, const std::string& errorMsgStart, std::string& errorMsg) {
775  UNUSED_PARAMETER(stop);
776  UNUSED_PARAMETER(collision);
777  UNUSED_PARAMETER(distToStop);
778  UNUSED_PARAMETER(errorMsgStart);
779  UNUSED_PARAMETER(errorMsg);
780  return true;
781 }
782 
783 
784 bool
786  return !myStops.empty() && myStops.begin()->reached /*&& myState.mySpeed < SUMO_const_haltingSpeed @todo #1864#*/;
787 }
788 
789 
790 bool
792  return isStopped() && myStops.begin()->pars.parking && (
793  myStops.begin()->parkingarea == nullptr || !myStops.begin()->parkingarea->parkOnRoad());
794 }
795 
796 
797 bool
799  return isStopped() && (myStops.begin()->triggered || myStops.begin()->containerTriggered || myStops.begin()->joinTriggered);
800 }
801 
802 
803 bool
804 MSBaseVehicle::isStoppedInRange(const double pos, const double tolerance) const {
805  if (isStopped()) {
806  const MSStop& stop = myStops.front();
807  return stop.pars.startPos - tolerance <= pos && stop.pars.endPos + tolerance >= pos;
808  }
809  return false;
810 }
811 
812 
813 double
814 MSBaseVehicle::basePos(const MSEdge* edge) const {
815  double result = MIN2(getVehicleType().getLength() + POSITION_EPS, edge->getLength());
816  if (hasStops()
817  && myStops.front().edge == myRoute->begin()
818  && (&myStops.front().lane->getEdge()) == *myStops.front().edge) {
819  result = MIN2(result, MAX2(0.0, myStops.front().getEndPos(*this)));
820  }
821  return result;
822 }
823 
824 
825 bool
826 MSBaseVehicle::addStop(const SUMOVehicleParameter::Stop& stopPar, std::string& errorMsg, SUMOTime untilOffset, bool collision,
827  MSRouteIterator* searchStart) {
828  MSStop stop(stopPar);
829  if (stopPar.lane == "") {
830  // use rightmost allowed lane
831  MSEdge* e = MSEdge::dictionary(stopPar.edge);
832  for (MSLane* cand : e->getLanes()) {
833  if (cand->allowsVehicleClass(getVClass())) {
834  stop.lane = cand;
835  break;
836  }
837  }
838  if (stop.lane == nullptr) {
839  errorMsg = "Vehicle '" + myParameter->id + "' is not allowed to stop on any lane of edge '" + stopPar.edge + "'.";
840  return false;
841  }
842  } else {
843  stop.lane = MSLane::dictionary(stopPar.lane);
845  errorMsg = "Vehicle '" + myParameter->id + "' is not allowed to stop on lane '" + stopPar.lane + "'.";
846  return false;
847  }
848  }
850  stop.segment = MSGlobals::gMesoNet->getSegmentForEdge(stop.lane->getEdge(), stop.getEndPos(*this));
851  if (stop.lane->isInternal()) {
852  errorMsg = "Mesoscopic simulation does not allow stopping on internal edge '" + stopPar.edge + "' for vehicle '" + myParameter->id + "'.";
853  return false;
854  }
855  }
856  stop.initPars(stopPar);
857  if (stopPar.until != -1) {
858  // !!! it would be much cleaner to invent a constructor for stops which takes "until" as an argument
859  const_cast<SUMOVehicleParameter::Stop&>(stop.pars).until += untilOffset;
860  }
861  if (stopPar.arrival != -1) {
862  const_cast<SUMOVehicleParameter::Stop&>(stop.pars).arrival += untilOffset;
863  }
864  stop.collision = collision;
865  std::string stopType = "stop";
866  std::string stopID = "";
867  if (stop.busstop != nullptr) {
868  stopType = "busStop";
869  stopID = stop.busstop->getID();
870  } else if (stop.containerstop != nullptr) {
871  stopType = "containerStop";
872  stopID = stop.containerstop->getID();
873  } else if (stop.chargingStation != nullptr) {
874  stopType = "chargingStation";
875  stopID = stop.chargingStation->getID();
876  } else if (stop.overheadWireSegment != nullptr) {
877  stopType = "overheadWireSegment";
878  stopID = stop.overheadWireSegment->getID();
879  } else if (stop.parkingarea != nullptr) {
880  stopType = "parkingArea";
881  stopID = stop.parkingarea->getID();
882  }
883  const std::string errorMsgStart = stopID == "" ? stopType : stopType + " '" + stopID + "'";
884 
885  if (stop.pars.startPos < 0 || stop.pars.endPos > stop.lane->getLength()) {
886  errorMsg = errorMsgStart + " for vehicle '" + myParameter->id + "' on lane '" + stop.lane->getID() + "' has an invalid position.";
887  return false;
888  }
889  if (stopType != "stop" && stopType != "parkingArea" && myType->getLength() / 2. > stop.pars.endPos - stop.pars.startPos
890  && MSNet::getInstance()->warnOnce(stopType + ":" + stopID)) {
891  errorMsg = errorMsgStart + " on lane '" + stop.lane->getID() + "' is too short for vehicle '" + myParameter->id + "'.";
892  }
893  // if stop is on an internal edge the normal edge before the intersection is used
894  const MSEdge* stopEdge = stop.lane->getEdge().getNormalBefore();
895  if (searchStart == nullptr) {
896  searchStart = &myCurrEdge;
897  }
898  stop.edge = std::find(*searchStart, myRoute->end(), stopEdge);
899  MSRouteIterator prevStopEdge = myCurrEdge;
900  const MSEdge* prevEdge = (getLane() == nullptr ? getEdge() : &getLane()->getEdge());
901  double prevStopPos = getPositionOnLane();
902  // where to insert the stop
903  std::list<MSStop>::iterator iter = myStops.begin();
904  if (stopPar.index == STOP_INDEX_END || stopPar.index >= static_cast<int>(myStops.size())) {
905  iter = myStops.end();
906  if (myStops.size() > 0 && myStops.back().edge >= *searchStart) {
907  prevStopEdge = myStops.back().edge;
908  prevEdge = &myStops.back().lane->getEdge();
909  prevStopPos = myStops.back().pars.endPos;
910  stop.edge = std::find(prevStopEdge, myRoute->end(), stopEdge);
911  if (prevStopEdge == stop.edge // laneEdge check is insufficient for looped routes
912  && prevEdge == &stop.lane->getEdge() // route iterator check insufficient for internal lane stops
913  && prevStopPos > stop.pars.endPos) {
914  stop.edge = std::find(prevStopEdge + 1, myRoute->end(), stopEdge);
915  }
916  }
917  } else {
918  if (stopPar.index == STOP_INDEX_FIT) {
919  while (iter != myStops.end() && (iter->edge < stop.edge ||
920  (iter->pars.endPos < stop.pars.endPos && iter->edge == stop.edge))) {
921  prevStopEdge = iter->edge;
922  prevStopPos = iter->pars.endPos;
923  ++iter;
924  }
925  } else {
926  int index = stopPar.index;
927  while (index > 0) {
928  prevStopEdge = iter->edge;
929  prevStopPos = iter->pars.endPos;
930  ++iter;
931  --index;
932  }
933  stop.edge = std::find(prevStopEdge, myRoute->end(), stopEdge);
934  }
935  }
936  const bool sameEdgeAsLastStop = prevStopEdge == stop.edge && prevEdge == &stop.lane->getEdge();
937  if (stop.edge == myRoute->end() || prevStopEdge > stop.edge ||
938  (sameEdgeAsLastStop && prevStopPos > stop.pars.endPos && !collision)
939  || (stop.lane->getEdge().isInternal() && stop.lane->getNextNormal() != *(stop.edge + 1))) {
940  if (stop.edge != myRoute->end()) {
941  // check if the edge occurs again later in the route
942  MSRouteIterator next = stop.edge + 1;
943  return addStop(stopPar, errorMsg, untilOffset, collision, &next);
944  }
945  errorMsg = errorMsgStart + " for vehicle '" + myParameter->id + "' on lane '" + stop.lane->getID() + "' is not downstream the current route.";
946  //std::cout << " could not add stop " << errorMsgStart << " prevStops=" << myStops.size() << " searchStart=" << (*searchStart - myRoute->begin()) << " route=" << toString(myRoute->getEdges()) << "\n";
947  return false;
948  }
949  // David.C:
950  //if (!stop.parking && (myCurrEdge == stop.edge && myState.myPos > stop.endPos - getCarFollowModel().brakeGap(myState.mySpeed))) {
951  const double endPosOffset = stop.lane->getEdge().isInternal() ? (*stop.edge)->getLength() : 0;
952  const double distToStop = stop.pars.endPos + endPosOffset - getPositionOnLane();
953  if (!handleCollisionStop(stop, collision, distToStop, errorMsgStart, errorMsg)) {
954  return false;
955  }
956  if (!hasDeparted() && myCurrEdge == stop.edge) {
957  double pos = -1;
959  pos = myParameter->departPos;
960  if (pos < 0.) {
961  pos += (*myCurrEdge)->getLength();
962  }
963  }
965  pos = MIN2(stop.pars.endPos + endPosOffset, basePos(*myCurrEdge));
966  }
967  if (pos > stop.pars.endPos + endPosOffset) {
968  if (stop.edge != myRoute->end()) {
969  // check if the edge occurs again later in the route
970  MSRouteIterator next = stop.edge + 1;
971  return addStop(stopPar, errorMsg, untilOffset, collision, &next);
972  }
973  errorMsg = errorMsgStart + " for vehicle '" + myParameter->id + "' on lane '" + stop.lane->getID() + "' is before departPos.";
974  return false;
975  }
976  }
977  if (iter != myStops.begin()) {
978  std::list<MSStop>::iterator iter2 = iter;
979  iter2--;
980  if (stop.pars.until >= 0 && iter2->pars.until > stop.pars.until) {
981  errorMsg = errorMsgStart + " for vehicle '" + myParameter->id + "' on lane '" + stop.lane->getID() + "' ends earlier than previous stop.";
982  }
983  }
984  myStops.insert(iter, stop);
985  //std::cout << " added stop " << errorMsgStart << " totalStops=" << myStops.size() << " searchStart=" << (*searchStart - myRoute->begin())
986  // << " routeIndex=" << (stop.edge - myRoute->begin())
987  // << " stopIndex=" << std::distance(myStops.begin(), iter)
988  // << " route=" << toString(myRoute->getEdges()) << "\n";
989  return true;
990 }
991 
992 
993 void
994 MSBaseVehicle::addStops(const bool ignoreStopErrors, MSRouteIterator* searchStart) {
995  for (const SUMOVehicleParameter::Stop& stop : myRoute->getStops()) {
996  std::string errorMsg;
997  if (!addStop(stop, errorMsg, myParameter->depart, stop.startPos == stop.endPos, searchStart) && !ignoreStopErrors) {
998  throw ProcessError(errorMsg);
999  }
1000  if (errorMsg != "") {
1001  WRITE_WARNING(errorMsg);
1002  }
1003  }
1005  for (const SUMOVehicleParameter::Stop& stop : myParameter->stops) {
1006  std::string errorMsg;
1007  if (!addStop(stop, errorMsg, untilOffset, stop.startPos == stop.endPos, searchStart) && !ignoreStopErrors) {
1008  throw ProcessError(errorMsg);
1009  }
1010  if (errorMsg != "") {
1011  WRITE_WARNING(errorMsg);
1012  }
1013  }
1014 }
1015 
1016 
1017 bool
1019  MSRouteIterator start = myCurrEdge;
1020  const std::string err = "for vehicle '" + getID() + "' at time " + time2string(MSNet::getInstance()->getCurrentTimeStep());
1021  int i = 0;
1022  bool ok = true;
1023  double lastPos = getPositionOnLane();
1024  if (getLane() != nullptr && getLane()->isInternal()
1025  && myStops.size() > 0 && !myStops.front().lane->isInternal()) {
1026  // start edge is still incoming to the intersection so lastPos
1027  // relative to that edge must be adapted
1028  lastPos += (*myCurrEdge)->getLength();
1029  }
1030  for (const MSStop& stop : myStops) {
1031  const double endPos = stop.getEndPos(*this);
1032  MSRouteIterator it;
1033  const std::string prefix = "Stop " + toString(i) + " on edge '" + stop.lane->getEdge().getID() + "' ";
1034  if (stop.lane->isInternal()) {
1035  // find the normal predecessor and ensure that the next route edge
1036  // matches the successor of the internal edge successor
1037  it = std::find(start, myRoute->end(), stop.lane->getEdge().getNormalBefore());
1038  if (it != myRoute->end() && (
1039  it + 1 == myRoute->end() || *(it + 1) != stop.lane->getEdge().getNormalSuccessor())) {
1040  it = myRoute->end(); // signal failure
1041  }
1042  } else {
1043  const MSEdge* const stopEdge = &stop.lane->getEdge();
1044  it = std::find(start, myRoute->end(), stopEdge);
1045  }
1046  if (it == myRoute->end()) {
1047  WRITE_ERROR(prefix + "is not found after edge '" + (*start)->getID() + "' (" + toString(start - myCurrEdge) + " after current " + err);
1048  ok = false;
1049  } else {
1050  MSRouteIterator it2;
1051  for (it2 = myRoute->begin(); it2 != myRoute->end(); it2++) {
1052  if (it2 == stop.edge) {
1053  break;
1054  }
1055  }
1056  if (it2 == myRoute->end()) {
1057  WRITE_ERROR(prefix + "used invalid route index " + err);
1058  ok = false;
1059  } else if (it2 < start) {
1060  WRITE_ERROR(prefix + "used invalid (relative) route index " + toString(it2 - myCurrEdge) + " expected after " + toString(start - myCurrEdge) + " " + err);
1061  ok = false;
1062  } else {
1063  if (it != stop.edge && endPos >= lastPos) {
1064  WRITE_WARNING(prefix + "is used in " + toString(stop.edge - myCurrEdge) + " edges but first encounter is in "
1065  + toString(it - myCurrEdge) + " edges " + err);
1066  }
1067  start = stop.edge;
1068  }
1069  }
1070  lastPos = endPos;
1071  i++;
1072  }
1073  return ok;
1074 }
1075 
1076 
1077 const ConstMSEdgeVector
1078 MSBaseVehicle::getStopEdges(double& firstPos, double& lastPos) const {
1079  assert(haveValidStopEdges());
1080  ConstMSEdgeVector result;
1081  const MSStop* prev = nullptr;
1082  const MSEdge* internalSuccessor = nullptr;
1083  for (const MSStop& stop : myStops) {
1084  if (stop.reached) {
1085  continue;
1086  }
1087  const double stopPos = stop.getEndPos(*this);
1088  if ((prev == nullptr
1089  || prev->edge != stop.edge
1090  || (prev->lane == stop.lane && prev->getEndPos(*this) > stopPos))
1091  && *stop.edge != internalSuccessor) {
1092  result.push_back(*stop.edge);
1093  if (stop.lane->isInternal()) {
1094  internalSuccessor = stop.lane->getNextNormal();
1095  result.push_back(internalSuccessor);
1096  } else {
1097  internalSuccessor = nullptr;
1098  }
1099  }
1100  prev = &stop;
1101  if (firstPos < 0) {
1102  firstPos = stopPos;
1103  }
1104  lastPos = stopPos;
1105  }
1106  //std::cout << "getStopEdges veh=" << getID() << " result=" << toString(result) << "\n";
1107  return result;
1108 }
1109 
1110 
1111 std::vector<std::pair<int, double> >
1113  std::vector<std::pair<int, double> > result;
1114  for (std::list<MSStop>::const_iterator iter = myStops.begin(); iter != myStops.end(); ++iter) {
1115  result.push_back(std::make_pair(
1116  (int)(iter->edge - myRoute->begin()),
1117  iter->getEndPos(*this)));
1118  }
1119  return result;
1120 }
1121 
1122 
1123 bool
1124 MSBaseVehicle::abortNextStop(int nextStopIndex) {
1125  if (hasStops() && nextStopIndex < (int)myStops.size()) {
1126  if (nextStopIndex == 0 && isStopped()) {
1128  } else {
1129  auto stopIt = myStops.begin();
1130  std::advance(stopIt, nextStopIndex);
1131  myStops.erase(stopIt);
1132  }
1133  return true;
1134  } else {
1135  return false;
1136  }
1137 }
1138 
1139 
1140 double
1142  if (isOnRoad() || isIdling()) {
1144  } else {
1145  return 0.;
1146  }
1147 }
1148 
1149 
1150 double
1152  if (isOnRoad() || isIdling()) {
1154  } else {
1155  return 0.;
1156  }
1157 }
1158 
1159 
1160 double
1162  if (isOnRoad() || isIdling()) {
1164  } else {
1165  return 0.;
1166  }
1167 }
1168 
1169 
1170 double
1172  if (isOnRoad() || isIdling()) {
1174  } else {
1175  return 0.;
1176  }
1177 }
1178 
1179 
1180 double
1182  if (isOnRoad() || isIdling()) {
1184  } else {
1185  return 0.;
1186  }
1187 }
1188 
1189 
1190 double
1192  if (isOnRoad() || isIdling()) {
1194  } else {
1195  return 0.;
1196  }
1197 }
1198 
1199 
1200 double
1202  if (isOnRoad() || isIdling()) {
1204  } else {
1205  return 0.;
1206  }
1207 }
1208 
1209 double
1211  if (static_cast<MSDevice_Battery*>(getDevice(typeid(MSDevice_Battery))) != 0) {
1212  MSDevice_Battery* batteryOfVehicle = dynamic_cast<MSDevice_Battery*>(getDevice(typeid(MSDevice_Battery)));
1213  return batteryOfVehicle->getActualBatteryCapacity();
1214  } else {
1215  if (static_cast<MSDevice_ElecHybrid*>(getDevice(typeid(MSDevice_ElecHybrid))) != 0) {
1216  MSDevice_ElecHybrid* batteryOfVehicle = dynamic_cast<MSDevice_ElecHybrid*>(getDevice(typeid(MSDevice_ElecHybrid)));
1217  return batteryOfVehicle->getActualBatteryCapacity();
1218  }
1219  }
1220 
1221  return -1;
1222 }
1223 
1224 double
1226  if (static_cast<MSDevice_ElecHybrid*>(getDevice(typeid(MSDevice_ElecHybrid))) != 0) {
1227  MSDevice_ElecHybrid* batteryOfVehicle = dynamic_cast<MSDevice_ElecHybrid*>(getDevice(typeid(MSDevice_ElecHybrid)));
1228  return batteryOfVehicle->getCurrentFromOverheadWire();
1229  }
1230 
1231  return NAN;
1232 }
1233 
1234 double
1236  if (isOnRoad() || isIdling()) {
1238  } else {
1239  return 0.;
1240  }
1241 }
1242 
1243 
1244 const MSEdgeWeightsStorage&
1246  return _getWeightsStorage();
1247 }
1248 
1249 
1252  return _getWeightsStorage();
1253 }
1254 
1255 
1258  if (myEdgeWeights == nullptr) {
1260  }
1261  return *myEdgeWeights;
1262 }
1263 
1264 
1265 
1266 
1267 int
1269  int boarded = myPersonDevice == nullptr ? 0 : myPersonDevice->size();
1270  return boarded + myParameter->personNumber;
1271 }
1272 
1273 std::vector<std::string>
1275  std::vector<std::string> ret;
1276  const std::vector<MSTransportable*>& persons = getPersons();
1277  for (std::vector<MSTransportable*>::const_iterator it_p = persons.begin(); it_p != persons.end(); ++it_p) {
1278  ret.push_back((*it_p)->getID());
1279  }
1280  return ret;
1281 }
1282 
1283 int
1285  int loaded = myContainerDevice == nullptr ? 0 : myContainerDevice->size();
1286  return loaded + myParameter->containerNumber;
1287 }
1288 
1289 
1290 void
1292  // this might be called from the MSTransportable destructor so we cannot do a dynamic cast to determine the type
1293  if (myPersonDevice != nullptr) {
1295  }
1296  if (myContainerDevice != nullptr) {
1298  }
1299 }
1300 
1301 
1302 const std::vector<MSTransportable*>&
1304  if (myPersonDevice == nullptr) {
1306  } else {
1308  }
1309 }
1310 
1311 
1312 const std::vector<MSTransportable*>&
1314  if (myContainerDevice == nullptr) {
1316  } else {
1318  }
1319 }
1320 
1321 
1322 bool
1323 MSBaseVehicle::isLineStop(double position) const {
1324  if (myParameter->line == "") {
1325  // not a public transport line
1326  return false;
1327  }
1328  for (const SUMOVehicleParameter::Stop& stop : myParameter->stops) {
1329  if (stop.startPos <= position && position <= stop.endPos) {
1330  return true;
1331  }
1332  }
1333  for (const SUMOVehicleParameter::Stop& stop : myRoute->getStops()) {
1334  if (stop.startPos <= position && position <= stop.endPos) {
1335  return true;
1336  }
1337  }
1338  return false;
1339 }
1340 
1341 
1342 bool
1343 MSBaseVehicle::hasDevice(const std::string& deviceName) const {
1344  for (MSDevice* const dev : myDevices) {
1345  if (dev->deviceName() == deviceName) {
1346  return true;
1347  }
1348  }
1349  return false;
1350 }
1351 
1352 
1353 void
1354 MSBaseVehicle::createDevice(const std::string& deviceName) {
1355  if (!hasDevice(deviceName)) {
1356  if (deviceName == "rerouting") {
1357  ((SUMOVehicleParameter*)myParameter)->setParameter("has." + deviceName + ".device", "true");
1359  if (hasDeparted()) {
1360  // vehicle already departed: disable pre-insertion rerouting and enable regular routing behavior
1361  MSDevice_Routing* routingDevice = static_cast<MSDevice_Routing*>(getDevice(typeid(MSDevice_Routing)));
1362  assert(routingDevice != 0);
1363  routingDevice->notifyEnter(*this, MSMoveReminder::NOTIFICATION_DEPARTED);
1364  }
1365  } else {
1366  throw InvalidArgument("Creating device of type '" + deviceName + "' is not supported");
1367  }
1368  }
1369 }
1370 
1371 
1372 std::string
1373 MSBaseVehicle::getDeviceParameter(const std::string& deviceName, const std::string& key) const {
1374  for (MSVehicleDevice* const dev : myDevices) {
1375  if (dev->deviceName() == deviceName) {
1376  return dev->getParameter(key);
1377  }
1378  }
1379  throw InvalidArgument("No device of type '" + deviceName + "' exists");
1380 }
1381 
1382 
1383 void
1384 MSBaseVehicle::setDeviceParameter(const std::string& deviceName, const std::string& key, const std::string& value) {
1385  for (MSVehicleDevice* const dev : myDevices) {
1386  if (dev->deviceName() == deviceName) {
1387  dev->setParameter(key, value);
1388  return;
1389  }
1390  }
1391  throw InvalidArgument("No device of type '" + deviceName + "' exists");
1392 }
1393 
1394 
1395 void
1397  assert(type != nullptr);
1398  if (myType->isVehicleSpecific() && type != myType) {
1400  }
1401  myType = type;
1402 }
1403 
1404 
1407  if (myType->isVehicleSpecific()) {
1408  return *myType;
1409  }
1410  MSVehicleType* type = myType->buildSingularType(myType->getID() + "@" + getID());
1411  replaceVehicleType(type);
1412  return *type;
1413 }
1414 
1415 
1416 int
1418  const MSLane* const lane = getLane();
1419  if (lane == nullptr) {
1420  return getEdge()->getLanes()[0]->getRNGIndex();
1421  } else {
1422  return lane->getRNGIndex();
1423  }
1424 }
1425 
1426 
1427 std::mt19937*
1429  const MSLane* lane = getLane();
1430  if (lane == nullptr) {
1431  return getEdge()->getLanes()[0]->getRNG();
1432  } else {
1433  return lane->getRNG();
1434  }
1435 }
1436 
1437 std::string
1438 MSBaseVehicle::getPrefixedParameter(const std::string& key, std::string& error) const {
1439  const MSVehicle* microVeh = dynamic_cast<const MSVehicle*>(this);
1440  if (StringUtils::startsWith(key, "device.")) {
1441  StringTokenizer tok(key, ".");
1442  if (tok.size() < 3) {
1443  error = "Invalid device parameter '" + key + "' for vehicle '" + getID() + "'.";
1444  return "";
1445  }
1446  try {
1447  return getDeviceParameter(tok.get(1), key.substr(tok.get(0).size() + tok.get(1).size() + 2));
1448  } catch (InvalidArgument& e) {
1449  error = "Vehicle '" + getID() + "' does not support device parameter '" + key + "' (" + e.what() + ").";
1450  return "";
1451  }
1452  } else if (StringUtils::startsWith(key, "laneChangeModel.")) {
1453  if (microVeh == nullptr) {
1454  error = "Meso Vehicle '" + getID() + "' does not support laneChangeModel parameters.";
1455  return "";
1456  }
1457  const std::string attrName = key.substr(16);
1458  try {
1459  return microVeh->getLaneChangeModel().getParameter(attrName);
1460  } catch (InvalidArgument& e) {
1461  error = "Vehicle '" + getID() + "' does not support laneChangeModel parameter '" + key + "' (" + e.what() + ").";
1462  return "";
1463  }
1464  } else if (StringUtils::startsWith(key, "carFollowModel.")) {
1465  if (microVeh == nullptr) {
1466  error = "Meso Vehicle '" + getID() + "' does not support carFollowModel parameters.";
1467  return "";
1468  }
1469  const std::string attrName = key.substr(15);
1470  try {
1471  return microVeh->getCarFollowModel().getParameter(microVeh, attrName);
1472  } catch (InvalidArgument& e) {
1473  error = "Vehicle '" + getID() + "' does not support carFollowModel parameter '" + key + "' (" + e.what() + ").";
1474  return "";
1475  }
1476  } else if (StringUtils::startsWith(key, "has.") && StringUtils::endsWith(key, ".device")) {
1477  StringTokenizer tok(key, ".");
1478  if (tok.size() != 3) {
1479  error = "Invalid check for device. Expected format is 'has.DEVICENAME.device'.";
1480  return "";
1481  }
1482  return hasDevice(tok.get(1)) ? "true" : "false";
1483  } else {
1484  return getParameter().getParameter(key, "");
1485  }
1486 }
1487 
1488 #ifdef _DEBUG
1489 void
1490 MSBaseVehicle::initMoveReminderOutput(const OptionsCont& oc) {
1491  if (oc.isSet("movereminder-output.vehicles")) {
1492  const std::vector<std::string> vehicles = oc.getStringVector("movereminder-output.vehicles");
1493  myShallTraceMoveReminders.insert(vehicles.begin(), vehicles.end());
1494  }
1495 }
1496 
1497 
1498 void
1499 MSBaseVehicle::traceMoveReminder(const std::string& type, MSMoveReminder* rem, double pos, bool keep) const {
1500  OutputDevice& od = OutputDevice::getDeviceByOption("movereminder-output");
1501  od.openTag("movereminder");
1502  od.writeAttr(SUMO_ATTR_TIME, STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()));
1503  od.writeAttr("veh", getID());
1505  od.writeAttr("type", type);
1506  od.writeAttr("pos", toString(pos));
1507  od.writeAttr("keep", toString(keep));
1508  od.closeTag();
1509 }
1510 #endif
1511 
1512 
1513 /****************************************************************************/
#define DEBUG_COND
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:74
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:54
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:284
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:276
std::string time2string(SUMOTime t)
convert SUMOTime to string
Definition: SUMOTime.cpp:68
#define STEPS2TIME(x)
Definition: SUMOTime.h:53
#define SUMOTime_MAX
Definition: SUMOTime.h:32
#define SIMTIME
Definition: SUMOTime.h:60
long long int SUMOTime
Definition: SUMOTime.h:31
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
const int STOP_INDEX_END
DepartLaneDefinition
Possible ways to choose a lane on depart.
@ GIVEN
The speed is given.
@ GIVEN
The position is given.
@ DEFAULT
No information given; use default.
@ BASE
Back-at-zero position.
const int VEHPARS_SPEEDFACTOR_SET
@ GIVEN
The arrival lane is given.
@ RANDOM
The edge is chosen randomly.
@ GIVEN
The edge index is given.
@ DEFAULT
No information given; use default.
const int VEHPARS_FORCE_REROUTE
const int STOP_INDEX_FIT
@ RANDOM
The arrival position is chosen randomly.
@ GIVEN
The arrival position is given.
@ CENTER
Half the road length.
const int VEHPARS_LINE_SET
@ DEPART_CONTAINER_TRIGGERED
The departure is container triggered.
@ DEPART_TRIGGERED
The departure is person triggered.
@ SUMO_TAG_VEHICLE
description of a vehicle
@ SUMO_TAG_PARKING_ZONE_REROUTE
entry for an alternative parking zone
@ SUMO_ATTR_LINE
@ SUMO_ATTR_REROUTE
@ SUMO_ATTR_DISTANCE
@ SUMO_ATTR_SPEEDFACTOR
@ SUMO_ATTR_ROUTE
@ SUMO_ATTR_ID
@ SUMO_ATTR_TIME
trigger: the time of the step
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:29
T MIN2(T a, T b)
Definition: StdDefs.h:73
T MAX2(T a, T b)
Definition: StdDefs.h:79
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:44
static double computeNoise(SUMOEmissionClass c, double v, double a)
Returns the noise produced by the a vehicle of the given type at the given speed.
MESegment * getSegmentForEdge(const MSEdge &e, double pos=0)
Get the segment for a given edge at a given position.
Definition: MELoop.cpp:302
virtual std::string getParameter(const std::string &key) const
try to retrieve the given parameter from this laneChangeModel. Throw exception for unsupported key
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const int rngIndex, SUMOVehicleClass svc) const
double getMaxSpeed() const
Returns the maximum speed.
MSVehicleDevice * getDevice(const std::type_info &type) const
Returns a device of the given type if it exists or 0.
void addStops(const bool ignoreStopErrors, MSRouteIterator *searchStart=nullptr)
Adds stops to the built vehicle.
std::list< MSStop > myStops
The vehicle's list of stops.
double getImpatience() const
Returns this vehicles impatience.
const std::vector< MSTransportable * > & getPersons() const
retrieve riding persons
virtual void initDevices()
const MSEdge * succEdge(int nSuccs) const
Returns the nSuccs'th successor of edge the vehicle is currently at.
void resetRoutePosition(int index, DepartLaneDefinition departLaneProcedure)
reset index of edge within route
std::string getDeviceParameter(const std::string &deviceName, const std::string &key) const
try to retrieve the given parameter from any of the vehicles devices, raise InvalidArgument if no dev...
MSVehicleType * myType
This vehicle's type.
MoveReminderCont myMoveReminders
Currently relevant move reminders.
bool allowsBoarding(MSTransportable *t) const
whether the given transportable is allowed to board this vehicle
double myDepartPos
The real depart position.
const SUMOVehicleParameter & getParameter() const
Returns the vehicle's parameter (including departure definition)
void addReminder(MSMoveReminder *rem)
Adds a MoveReminder dynamically.
bool replaceRouteEdges(ConstMSEdgeVector &edges, double cost, double savings, const std::string &info, bool onInit=false, bool check=false, bool removeStops=true)
Replaces the current route by the given edges.
double getFuelConsumption() const
Returns fuel consumption of the current state.
void replaceParameter(const SUMOVehicleParameter *newParameter)
replace the vehicle parameter (deleting the old one)
double getCO2Emissions() const
Returns CO2 emission of the current state.
std::vector< MSVehicleDevice * > myDevices
The devices this vehicle has.
virtual bool replaceRoute(const MSRoute *route, const std::string &info, bool onInit=false, int offset=0, bool addStops=true, bool removeStops=true)
Replaces the current route by the given one.
double getPreviousSpeed() const
Returns the vehicle's previous speed.
virtual void addTransportable(MSTransportable *transportable)
Adds a person or container to this vehicle.
double getElectricityConsumption() const
Returns electricity consumption of the current state.
int getRouteValidity(bool update=true, bool silent=false)
check for route validity at first insertion attempt
double getOdometer() const
Returns the distance that was already driven by this vehicle.
virtual bool hasArrived() const
Returns whether this vehicle has already arived (by default this is true if the vehicle has reached i...
const NumericalID myNumericalID
static NumericalID myCurrentNumericalIndex
MSVehicleType & getSingularType()
Replaces the current vehicle type with a new one used by this vehicle only.
void replaceVehicleType(MSVehicleType *type)
Replaces the current vehicle type by the one given.
double getLength() const
Returns the vehicle's length.
bool isParking() const
Returns whether the vehicle is parking.
const MSEdge * getEdge() const
Returns the edge the vehicle is currently at.
double getHarmonoise_NoiseEmissions() const
Returns noise emissions of the current state.
const std::map< int, double > * getEmissionParameters() const
Returns the vehicle's emission model parameter.
bool hasValidRoute(std::string &msg, const MSRoute *route=0) const
Validates the current or given route.
bool isStoppedInRange(const double pos, const double tolerance) const
return whether the given position is within range of the current stop
int getPersonNumber() const
Returns the number of persons.
double getNOxEmissions() const
Returns NOx emission of the current state.
void setID(const std::string &newID)
set the id (inherited from Named but forbidden for vehicles)
std::mt19937 * getRNG() const
double getPMxEmissions() const
Returns PMx emission of the current state.
MSRouteIterator myCurrEdge
Iterator to current route-edge.
static std::vector< MSTransportable * > myEmptyTransportableVector
bool hasDeparted() const
Returns whether this vehicle has already departed.
double getCOEmissions() const
Returns CO emission of the current state.
MSDevice_Transportable * myContainerDevice
The containers this vehicle may have.
MSBaseVehicle(SUMOVehicleParameter *pars, const MSRoute *route, MSVehicleType *type, const double speedFactor)
Constructor.
double getStateOfCharge() const
Returns actual state of charge of battery (Wh) RICE_CHECK: This may be a misnomer,...
MSEdgeWeightsStorage & _getWeightsStorage() const
bool hasDevice(const std::string &deviceName) const
check whether the vehicle is equiped with a device of the given type
virtual const MSEdge * getRerouteOrigin() const
Returns the starting point for reroutes (usually the current edge)
void calculateArrivalParams()
(Re-)Calculates the arrival position and lane from the vehicle parameters
double basePos(const MSEdge *edge) const
departure position where the vehicle fits fully onto the edge (if possible)
void setDeviceParameter(const std::string &deviceName, const std::string &key, const std::string &value)
try to set the given parameter from any of the vehicles devices, raise InvalidArgument if no device p...
MSDevice_Transportable * myPersonDevice
The passengers this vehicle may have.
const MSRoute * myRoute
This vehicle's route.
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
bool hasStops() const
Returns whether the vehicle has to stop somewhere.
virtual void activateReminders(const MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
"Activates" all current move reminder
bool isLineStop(double position) const
returns whether the vehicle serves a public transport line that serves the given stop
double myChosenSpeedFactor
A precomputed factor by which the driver wants to be faster than the speed limit.
@ ROUTE_INVALID
route was checked and is valid
Definition: MSBaseVehicle.h:70
@ ROUTE_START_INVALID_PERMISSIONS
Definition: MSBaseVehicle.h:72
std::string getPrefixedParameter(const std::string &key, std::string &error) const
retrieve parameters of devices, models and the vehicle itself
void removeTransportable(MSTransportable *t)
removes a person or container
SUMOVehicleClass getVClass() const
Returns the vehicle's access class.
int myArrivalLane
The destination lane where the vehicle stops.
virtual ~MSBaseVehicle()
Destructor.
SUMOTime myDeparture
The real departure time.
std::vector< std::string > getPersonIDList() const
Returns the list of persons.
const MSEdgeWeightsStorage & getWeightsStorage() const
Returns the vehicle's internal edge travel times/efforts container.
bool isStoppedTriggered() const
Returns whether the vehicle is on a triggered stop.
bool addStop(const SUMOVehicleParameter::Stop &stopPar, std::string &errorMsg, SUMOTime untilOffset=0, bool collision=false, MSRouteIterator *searchStart=nullptr)
Adds a stop.
double getHCEmissions() const
Returns HC emission of the current state.
virtual bool resumeFromStopping()
void onDepart()
Called when the vehicle is inserted into the network.
void removeReminder(MSMoveReminder *rem)
Removes a MoveReminder dynamically.
bool haveValidStopEdges() const
check whether all stop.edge MSRouteIterators are valid and in order
virtual double getAcceleration() const
Returns the vehicle's acceleration.
virtual bool handleCollisionStop(MSStop &stop, const bool collision, const double distToStop, const std::string &errorMsgStart, std::string &errorMsg)
int getRoutePosition() const
return index of edge within route
static const SUMOTime NOT_YET_DEPARTED
double getElecHybridCurrent() const
Returns actual current (A) of ElecHybrid device RICE_CHECK: Is this the current consumed from the ove...
const SUMOVehicleParameter * myParameter
This vehicle's parameter.
virtual bool hasValidRouteStart(std::string &msg)
checks wether the vehicle can depart on the first edge
int myRouteValidity
status of the current vehicle route
std::vector< std::pair< int, double > > getStopIndices() const
return list of route indices for the remaining stops
const ConstMSEdgeVector getStopEdges(double &firstPos, double &lastPos) const
Returns the list of still pending stop edges also returns the first and last stop position.
SUMOTime myStopUntilOffset
The offset when adding route stops with 'until' on route replacement.
virtual bool isOnRoad() const
Returns the information whether the vehicle is on a road (is simulated)
void reroute(SUMOTime t, const std::string &info, SUMOAbstractRouter< MSEdge, SUMOVehicle > &router, const bool onInit=false, const bool withTaz=false, const bool silent=false)
Performs a rerouting using the given router.
const std::vector< MSTransportable * > & getContainers() const
retrieve riding containers
int getRNGIndex() const
MSEdgeWeightsStorage * myEdgeWeights
void createDevice(const std::string &deviceName)
create device of the given type
bool isStopped() const
Returns whether the vehicle is at a stop.
bool abortNextStop(int nextStopIndex=0)
deletes the next stop at the given index if it exists
int myNumberReroutes
The number of reroutings.
double myArrivalPos
The position on the destination lane where the vehicle stops.
virtual void saveState(OutputDevice &out)
Saves the (common) state of a vehicle.
double myOdometer
A simple odometer to keep track of the length of the route already driven.
int getContainerNumber() const
Returns the number of containers.
virtual std::string getParameter(const MSVehicle *veh, const std::string &key) const
try to get the given parameter for this carFollowingModel
Definition: MSCFModel.h:572
Battery device for electric vehicles.
double getActualBatteryCapacity() const
Get the actual vehicle's Battery Capacity in kWh.
const std::map< int, double > & getEnergyParams() const
retrieve parameters for the energy consumption model
A device which collects info on the vehicle trip (mainly on departure and arrival)
double getCurrentFromOverheadWire() const
Get actual current in the overhead wire segment.
double getActualBatteryCapacity() const
Get the actual vehicle's Battery Capacity in kWh.
A device that performs vehicle rerouting based on current edge speeds.
bool notifyEnter(SUMOTrafficObject &veh, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Computes a new route on vehicle insertion.
static void buildVehicleDevices(SUMOVehicle &v, std::vector< MSVehicleDevice * > &into)
Build devices for the given vehicle, if needed.
A device which collects info on the vehicle trip (mainly on departure and arrival)
Definition: MSDevice_Taxi.h:48
bool allowsBoarding(MSTransportable *t) const
whether the given person is allowed to board this taxi
const std::vector< MSTransportable * > & getTransportables() const
Returns the list of transportables using this vehicle.
static MSDevice_Transportable * buildVehicleDevices(SUMOVehicle &v, std::vector< MSVehicleDevice * > &into, const bool isContainer)
Build devices for the given vehicle, if needed.
int size() const
Return the number of passengers / containers.
void addTransportable(MSTransportable *transportable)
Add a passenger.
void removeTransportable(MSTransportable *transportable)
Remove a passenger (TraCI)
Abstract in-vehicle / in-person device.
Definition: MSDevice.h:61
static void buildVehicleDevices(SUMOVehicle &v, std::vector< MSVehicleDevice * > &into)
Build devices for the given vehicle, if needed.
Definition: MSDevice.cpp:99
A road/street connecting two junctions.
Definition: MSEdge.h:77
const std::vector< MSLane * > * allowedLanes(const MSEdge &destination, SUMOVehicleClass vclass=SVC_IGNORING) const
Get the allowed lanes to reach the destination-edge.
Definition: MSEdge.cpp:366
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:166
double getLength() const
return the length of the edge
Definition: MSEdge.h:630
bool isTazConnector() const
Definition: MSEdge.h:279
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:256
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn't already in the dictionary....
Definition: MSEdge.cpp:814
const MSEdge * getNormalBefore() const
if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself
Definition: MSEdge.cpp:723
A storage for edge travel times and efforts.
static bool gUseMesoSim
Definition: MSGlobals.h:88
static bool gCheckRoutes
Definition: MSGlobals.h:76
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition: MSGlobals.h:94
static SUMOTime gTimeToImpatience
Definition: MSGlobals.h:63
void descheduleDeparture(const SUMOVehicle *veh)
stops trying to emit the given vehicle (and delete it)
Representation of a lane in the micro simulation.
Definition: MSLane.h:82
int getRNGIndex() const
returns the associated RNG index
Definition: MSLane.h:210
const MSEdge * getNextNormal() const
Returns the lane's follower if it is an internal lane, the edge of the lane otherwise.
Definition: MSLane.cpp:1884
double getLength() const
Returns the lane's length.
Definition: MSLane.h:539
bool allowsVehicleClass(SUMOVehicleClass vclass) const
Definition: MSLane.h:812
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:1908
bool isInternal() const
Definition: MSLane.cpp:2036
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:673
std::mt19937 * getRNG() const
return the associated RNG
Definition: MSLane.h:215
Something on a lane to be noticed about vehicle movement.
Notification
Definition of a vehicle state.
@ NOTIFICATION_DEPARTED
The vehicle has departed (was inserted into the network)
const std::string & getDescription() const
bool warnOnce(const std::string &typeAndID)
return whether a warning regarding the given object shall be issued
Definition: MSNet.cpp:1355
@ VEHICLE_STATE_NEWROUTE
The vehicle got a new route.
Definition: MSNet.h:599
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:171
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const int rngIndex, const MSEdgeVector &prohibited=MSEdgeVector()) const
Definition: MSNet.cpp:1199
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:371
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:313
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:424
void informVehicleStateListener(const SUMOVehicle *const vehicle, VehicleState to, const std::string &info="")
Informs all added listeners about a vehicle's state change.
Definition: MSNet.cpp:1071
void addReference() const
increments the reference counter for the route
Definition: MSRoute.cpp:94
int size() const
Returns the number of edges to pass.
Definition: MSRoute.cpp:81
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the stops.
Definition: MSRoute.cpp:397
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:75
static bool dictionary(const std::string &id, const MSRoute *route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:113
void setCosts(double costs)
Sets the costs of the route.
Definition: MSRoute.h:185
static bool hasRoute(const std::string &id)
returns whether a route with the given id exists
Definition: MSRoute.cpp:156
void release() const
deletes the route if there are no further references to it
Definition: MSRoute.cpp:100
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:87
const RGBColor & getColor() const
Returns the color.
Definition: MSRoute.cpp:388
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:69
static void checkDist(const std::string &id)
Checks the distribution whether it is permanent and deletes it if not.
Definition: MSRoute.cpp:194
const ConstMSEdgeVector & getEdges() const
Definition: MSRoute.h:120
SUMOTime getPeriod() const
returns the period
Definition: MSRoute.h:156
void setSavings(double savings)
Sets the savings of the route.
Definition: MSRoute.h:192
static SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const int rngIndex, SUMOVehicleClass svc, const MSEdgeVector &prohibited=MSEdgeVector())
return the router instance
Definition: MSStop.h:44
const MSLane * lane
The lane to stop at (microsim only)
Definition: MSStop.h:50
MSStoppingPlace * containerstop
(Optional) container stop if one is assigned to the stop
Definition: MSStop.h:56
bool collision
Whether this stop was triggered by a collision.
Definition: MSStop.h:85
void initPars(const SUMOVehicleParameter::Stop &stopPar)
initialize attributes from the given stop parameters
Definition: MSStop.cpp:85
const MESegment * segment
The segment to stop at (mesosim only)
Definition: MSStop.h:52
MSRouteIterator edge
The edge in the route to stop at.
Definition: MSStop.h:48
double getEndPos(const SUMOVehicle &veh) const
return halting position for upcoming stop;
Definition: MSStop.cpp:33
MSParkingArea * parkingarea
(Optional) parkingArea if one is assigned to the stop
Definition: MSStop.h:58
MSStoppingPlace * chargingStation
(Optional) charging station if one is assigned to the stop
Definition: MSStop.h:60
const SUMOVehicleParameter::Stop pars
The stop parameter.
Definition: MSStop.h:65
MSStoppingPlace * busstop
(Optional) bus stop if one is assigned to the stop
Definition: MSStop.h:54
MSStoppingPlace * overheadWireSegment
(Optional) overhead wire segment if one is assigned to the stop
Definition: MSStop.h:63
bool isPerson() const
Whether it is a person.
void vehicleDeparted(const SUMOVehicle &v)
Informs this control about a vehicle's departure.
void removeVType(const MSVehicleType *vehType)
Abstract in-vehicle device.
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:77
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:4699
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
Definition: MSVehicle.h:930
The car-following model and parameter.
Definition: MSVehicleType.h:62
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
double getMaxSpeed() const
Get vehicle's maximum speed [m/s].
bool isVehicleSpecific() const
Returns whether this type belongs to a single vehicle only (was modified)
SUMOEmissionClass getEmissionClass() const
Get this vehicle type's emission class.
const std::string & getID() const
Returns the name of the vehicle type.
Definition: MSVehicleType.h:90
double getLength() const
Get vehicle's length [m].
MSVehicleType * buildSingularType(const std::string &id) const
Duplicates the microsim vehicle type giving the newly created type the given id, marking it as vehicl...
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
Definition: Named.h:66
const std::string & getID() const
Returns the id.
Definition: Named.h:73
A storage for options typed value containers)
Definition: OptionsCont.h:89
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
const StringVector & getStringVector(const std::string &name) const
Returns the list of string-value of the named option (only for Option_StringVector)
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:60
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:239
static OutputDevice & getDeviceByOption(const std::string &name)
Returns the device described by the option.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
static double compute(const SUMOEmissionClass c, const EmissionType e, const double v, const double a, const double slope, const std::map< int, double > *param=0)
Returns the amount of the emitted pollutant given the vehicle type and state (in mg/s or ml/s for fue...
static const RGBColor DEFAULT_COLOR
The default color (for vehicle types and vehicles)
Definition: RGBColor.h:194
static double rand(std::mt19937 *rng=nullptr)
Returns a random real number in [0, 1)
Definition: RandHelper.h:51
bool computeLooped(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into, bool silent=false)
Builds the route between the given edges using the minimum effort at the given time if from == to,...
double recomputeCosts(const std::vector< const E * > &edges, const V *const v, SUMOTime msTime, double *lengthp=nullptr) const
virtual bool compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into, bool silent=false)=0
Builds the route between the given edges using the minimum effort at the given time The definition of...
virtual SUMOTime getWaitingTime() const =0
virtual double getSlope() const =0
Returns the slope of the road at object's position in degrees.
virtual double getSpeed() const =0
Returns the object's current speed.
virtual const MSLane * getLane() const =0
Returns the lane the object is currently at.
virtual double getPositionOnLane() const =0
Get the object's position along the lane.
Representation of a vehicle.
Definition: SUMOVehicle.h:58
long long int NumericalID
Definition: SUMOVehicle.h:60
virtual bool isIdling() const =0
Returns whether the vehicle is idling (waiting to re-enter the net.
Definition of vehicle stop (position and duration)
std::string edge
The edge to stop at (used only in NETEDIT)
std::string lane
The lane to stop at.
double startPos
The stopping position start.
int index
at which position in the stops list
SUMOTime until
The time at which the vehicle may continue its journey.
double endPos
The stopping position end.
SUMOTime arrival
The (expected) time at which the vehicle reaches the stop.
Structure representing possible vehicle parameter.
int parametersSet
Information for the router which parameter were set, TraCI may modify this (when changing color)
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle's end speed shall be chosen.
SUMOTime repetitionOffset
The time offset between vehicle reinsertions.
std::vector< std::string > via
List of the via-edges the vehicle must visit.
int repetitionsDone
The number of times the vehicle was already inserted.
ArrivalLaneDefinition arrivalLaneProcedure
Information how the vehicle shall choose the lane to arrive on.
void write(OutputDevice &dev, const OptionsCont &oc, const SumoXMLTag tag=SUMO_TAG_VEHICLE, const std::string &typeID="") const
Writes the parameters as a beginning element.
int personNumber
The static number of persons in the vehicle when it departs (not including boarding persons)
double departPos
(optional) The position the vehicle shall depart from
double arrivalPos
(optional) The position the vehicle shall arrive on
std::string routeid
The vehicle's route id.
std::string id
The vehicle's id.
std::vector< Stop > stops
List of the stops the vehicle will make, TraCI may add entries here.
int departEdge
(optional) The initial edge within the route of the vehicle
bool wasSet(int what) const
Returns whether the given parameter was set.
ArrivalPosDefinition arrivalPosProcedure
Information how the vehicle shall choose the arrival position.
DepartEdgeDefinition departEdgeProcedure
Information how the vehicle's initial edge shall be chosen.
std::string toTaz
The vehicle's destination zone (district)
double arrivalSpeed
(optional) The final speed of the vehicle (not used yet)
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
std::string fromTaz
The vehicle's origin zone (district)
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
std::string line
The vehicle's line (mainly for public transport)
int containerNumber
The static number of containers in the vehicle when it departs.
int size() const
returns the number of existing substrings
std::string get(int pos) const
returns the item at the given position
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.
static bool endsWith(const std::string &str, const std::string suffix)
Checks whether a given string ends with the suffix.