Eclipse SUMO - Simulation of Urban MObility
MSEdge.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 /****************************************************************************/
21 // A road/street connecting two junctions
22 /****************************************************************************/
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #include <config.h>
29 
30 #include <algorithm>
31 #include <iostream>
32 #include <cassert>
36 #include <mesosim/MELoop.h>
37 #include <mesosim/MESegment.h>
38 #include <mesosim/MEVehicle.h>
39 #include "MSInsertionControl.h"
40 #include "MSJunction.h"
41 #include "MSLane.h"
42 #include "MSLaneChanger.h"
43 #include "MSLaneChangerSublane.h"
44 #include "MSGlobals.h"
45 #include "MSNet.h"
46 #include "MSVehicle.h"
47 #include "MSLeaderInfo.h"
48 #include "MSContainer.h"
49 #include "MSEdgeWeightsStorage.h"
50 #include "MSEdge.h"
51 
52 #define BEST_LANE_LOOKAHEAD 3000.0
53 
54 // ===========================================================================
55 // static member definitions
56 // ===========================================================================
59 
60 
61 // ===========================================================================
62 // member method definitions
63 // ===========================================================================
64 MSEdge::MSEdge(const std::string& id, int numericalID,
65  const SumoXMLEdgeFunc function,
66  const std::string& streetName,
67  const std::string& edgeType,
68  int priority,
69  double distance) :
70  Named(id), myNumericalID(numericalID), myLanes(nullptr),
71  myLaneChanger(nullptr), myFunction(function), myVaporizationRequests(0),
72  myLastFailedInsertionTime(-1),
73  myFromJunction(nullptr), myToJunction(nullptr),
74  myStreetName(streetName),
75  myEdgeType(edgeType),
76  myPriority(priority),
77  myDistance(distance),
78  myWidth(0.),
79  myLength(0.),
80  myEmptyTraveltime(0.),
81  myTimePenalty(0.),
82  myAmDelayed(false),
83  myAmRoundabout(false),
84  myAmFringe(true),
85  myBidiEdge(nullptr)
86 { }
87 
88 
90  delete myLaneChanger;
91  for (auto i : myAllowed) {
92  if (i.second != myLanes) {
93  delete i.second;
94  }
95  }
96  for (auto i2 : myAllowedTargets) {
97  for (auto i1 : i2.second) {
98  if (i1.second != myLanes) {
99  delete i1.second;
100  }
101  }
102  }
103  delete myLanes;
104 }
105 
106 
107 void
108 MSEdge::initialize(const std::vector<MSLane*>* lanes) {
109  assert(lanes != 0);
110  myLanes = lanes;
113  }
114  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
115  myWidth += (*i)->getWidth();
116  }
117  double widthBefore = 0;
118  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
119  (*i)->setRightSideOnEdge(widthBefore, (int)mySublaneSides.size());
120  MSLeaderInfo ahead(*i);
121  for (int j = 0; j < ahead.numSublanes(); ++j) {
122  mySublaneSides.push_back(widthBefore + j * MSGlobals::gLateralResolution);
123  }
124  widthBefore += (*i)->getWidth();
125  }
126 }
127 
128 
130  if (myLanes->empty()) {
131  return;
132  }
133  myLength = myLanes->front()->getLength();
135 
137  // add tls penalties to the minimum travel time
138  SUMOTime minPenalty = -1;
139  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
140  MSLane* l = *i;
141  const MSLinkCont& lc = l->getLinkCont();
142  for (MSLinkCont::const_iterator j = lc.begin(); j != lc.end(); ++j) {
143  MSLink* link = *j;
144  SUMOTime linkPenalty = link->getMesoTLSPenalty() + (link->havePriority() ? 0 : MSGlobals::gMesoMinorPenalty);
145  if (minPenalty == -1) {
146  minPenalty = linkPenalty;
147  } else {
148  minPenalty = MIN2(minPenalty, linkPenalty);
149  }
150  }
151  }
152  if (minPenalty > 0) {
153  myEmptyTraveltime += STEPS2TIME(minPenalty);
154  }
155  } else if (isInternal()) {
156  const MSLink* link = myLanes->front()->getIncomingLanes()[0].viaLink;
157  if (!link->isTLSControlled() && !link->havePriority()) {
160  }
161  }
162 }
163 
164 
165 void
167  for (MSLane* const lane : *myLanes) {
168  for (MSLink* const link : lane->getLinkCont()) {
169  link->initParallelLinks();
170  MSLane* const toL = link->getLane();
171  MSLane* const viaL = link->getViaLane();
172  if (toL != nullptr) {
173  MSEdge& to = toL->getEdge();
174  if (std::find(mySuccessors.begin(), mySuccessors.end(), &to) == mySuccessors.end()) {
175  mySuccessors.push_back(&to);
176  myViaSuccessors.push_back(std::make_pair(&to, (viaL == nullptr ? nullptr : &viaL->getEdge())));
177  }
178  if (std::find(to.myPredecessors.begin(), to.myPredecessors.end(), this) == to.myPredecessors.end()) {
179  to.myPredecessors.push_back(this);
180  }
181  if (link->getDirection() != LINKDIR_TURN) {
182  myAmFringe = false;
183  }
184  }
185  if (viaL != nullptr) {
186  MSEdge& to = viaL->getEdge();
187  if (std::find(to.myPredecessors.begin(), to.myPredecessors.end(), this) == to.myPredecessors.end()) {
188  to.myPredecessors.push_back(this);
189  }
190  }
191  }
192  lane->checkBufferType();
193  }
194  std::sort(mySuccessors.begin(), mySuccessors.end(), by_id_sorter());
196  recalcCache();
197  // segment building depends on the finished list of successors (for multi-queue)
198  if (MSGlobals::gUseMesoSim && !myLanes->empty()) {
200  }
201 }
202 
203 
204 void
206  if (!myLanes->empty()) {
207  const bool allowChanging = allowsLaneChanging();
209  // may always initiate sublane-change
210  myLaneChanger = new MSLaneChangerSublane(myLanes, allowChanging);
211  } else {
213  myLaneChanger = new MSLaneChanger(myLanes, allowChanging);
214  } else if (myLanes->size() > 1 || canChangeToOpposite()) {
215  myLaneChanger = new MSLaneChanger(myLanes, allowChanging);
216  }
217  }
218  }
219 }
220 
221 
222 bool
224  if (isInternal()) {
225  // allow changing only if all links leading to this internal lane have priority
226  // or they are controlled by a traffic light
227  for (std::vector<MSLane*>::const_iterator it = myLanes->begin(); it != myLanes->end(); ++it) {
228  MSLane* pred = (*it)->getLogicalPredecessorLane();
229  MSLink* link = MSLinkContHelper::getConnectingLink(*pred, **it);
230  assert(link != 0);
231  LinkState state = link->getState();
232  if (state == LINKSTATE_MINOR
233  || state == LINKSTATE_EQUAL
234  || state == LINKSTATE_STOP
235  || state == LINKSTATE_ALLWAY_STOP
236  || state == LINKSTATE_DEADEND) {
237  return false;
238  }
239  }
240  }
241  return true;
242 }
243 
244 
245 void
246 MSEdge::addToAllowed(const SVCPermissions permissions, const std::vector<MSLane*>* allowedLanes, AllowedLanesCont& laneCont) const {
247  // recheck whether we had this list to save memory
248  if (allowedLanes->empty()) {
249  delete allowedLanes;
250  allowedLanes = nullptr;
251  } else {
252  for (auto& allowed : laneCont) {
253  if (*allowed.second == *allowedLanes) {
254  delete allowedLanes;
255  allowedLanes = nullptr;
256  allowed.first |= permissions;
257  break;
258  }
259  }
260  }
261  if (allowedLanes != nullptr) {
262  laneCont.push_back(std::make_pair(permissions, allowedLanes));
263  }
264 }
265 
266 
267 void
269  // rebuild myMinimumPermissions and myCombinedPermissions
272  for (MSLane* const lane : *myLanes) {
273  myMinimumPermissions &= lane->getPermissions();
274  myCombinedPermissions |= lane->getPermissions();
275  }
276  // rebuild myAllowed
277  for (const auto i : myAllowed) {
278  if (i.second != myLanes) {
279  delete i.second;
280  }
281  }
282  myAllowed.clear();
284  myAllowed.push_back(std::make_pair(SVC_IGNORING, myLanes));
285  for (SUMOVehicleClass vclass = SVC_PRIVATE; vclass <= SUMOVehicleClass_MAX; vclass = (SUMOVehicleClass)(2 * (int)vclass)) {
286  if ((myCombinedPermissions & vclass) == vclass) {
287  std::vector<MSLane*>* allowedLanes = new std::vector<MSLane*>();
288  for (MSLane* const lane : *myLanes) {
289  if (lane->allowsVehicleClass(vclass)) {
290  allowedLanes->push_back(lane);
291  }
292  }
293  addToAllowed(vclass, allowedLanes, myAllowed);
294  }
295  }
296  }
297  rebuildAllowedTargets(false);
298 }
299 
300 
301 void
302 MSEdge::rebuildAllowedTargets(const bool updateVehicles) {
303  for (const auto i2 : myAllowedTargets) {
304  for (const auto i1 : i2.second) {
305  if (i1.second != myLanes) {
306  delete i1.second;
307  }
308  }
309  }
310  myAllowedTargets.clear();
311 
312  for (const MSEdge* target : mySuccessors) {
313  bool universalMap = true; // whether the mapping for SVC_IGNORING is also valid for all vehicle classes
314  std::vector<MSLane*>* allLanes = new std::vector<MSLane*>();
315  // compute the mapping for SVC_IGNORING
316  for (MSLane* const lane : *myLanes) {
317  SVCPermissions combinedTargetPermissions = 0;
318  for (const MSLink* const link : lane->getLinkCont()) {
319  if (&link->getLane()->getEdge() == target) {
320  allLanes->push_back(lane);
321  combinedTargetPermissions |= link->getLane()->getPermissions();
322  }
323  }
324  if (combinedTargetPermissions == 0 || (lane->getPermissions() & combinedTargetPermissions) != lane->getPermissions()) {
325  universalMap = false;
326  }
327  }
328  if (universalMap) {
329  if (myAllowed.empty()) {
330  // we have no lane specific permissions
331  myAllowedTargets[target].push_back(std::make_pair(myMinimumPermissions, myLanes));
332  } else {
333  for (const auto i : myAllowed) {
334  // we cannot add the lane vectors directly because they are deleted separately (shared_ptr anyone?)
335  addToAllowed(i.first, new std::vector<MSLane*>(*i.second), myAllowedTargets[target]);
336  }
337  }
338  } else {
339  addToAllowed(SVC_IGNORING, allLanes, myAllowedTargets[target]);
340  // compute the vclass specific mapping
341  for (int vclass = SVC_PRIVATE; vclass <= SUMOVehicleClass_MAX; vclass *= 2) {
342  if ((myCombinedPermissions & vclass) == vclass) {
343  std::vector<MSLane*>* allowedLanes = new std::vector<MSLane*>();
344  for (MSLane* const lane : *myLanes) {
345  if (lane->allowsVehicleClass((SUMOVehicleClass)vclass)) {
346  for (const MSLink* const link : lane->getLinkCont()) {
347  if (link->getLane()->allowsVehicleClass((SUMOVehicleClass)vclass) && &link->getLane()->getEdge() == target) {
348  allowedLanes->push_back(lane);
349  }
350  }
351  }
352  }
353  addToAllowed(vclass, allowedLanes, myAllowedTargets[target]);
354  }
355  }
356  }
357  }
358  if (updateVehicles) {
359  for (const MSLane* const lane : *myLanes) {
360  const MSLane::VehCont& vehs = lane->getVehiclesSecure();
361  for (MSVehicle* veh : vehs) {
362  veh->updateBestLanes(true);
363  }
364  lane->releaseVehicles();
365  }
366  }
367  myClassesSuccessorMap.clear();
368 }
369 
370 
371 // ------------ Access to the edge's lanes
372 MSLane*
373 MSEdge::leftLane(const MSLane* const lane) const {
374  return parallelLane(lane, 1);
375 }
376 
377 
378 MSLane*
379 MSEdge::rightLane(const MSLane* const lane) const {
380  return parallelLane(lane, -1);
381 }
382 
383 
384 MSLane*
385 MSEdge::parallelLane(const MSLane* const lane, int offset, bool includeOpposite) const {
386  const int resultIndex = lane->getIndex() + offset;
387  if (resultIndex == (int)myLanes->size() && includeOpposite) {
388  return lane->getOpposite();
389  } else if (resultIndex >= (int)myLanes->size() || resultIndex < 0) {
390  return nullptr;
391  } else {
392  return (*myLanes)[resultIndex];
393  }
394 }
395 
396 
397 const std::vector<MSLane*>*
398 MSEdge::allowedLanes(const MSEdge& destination, SUMOVehicleClass vclass) const {
399  AllowedLanesByTarget::const_iterator i = myAllowedTargets.find(&destination);
400  if (i != myAllowedTargets.end()) {
401  for (const auto& allowed : i->second) {
402  if ((allowed.first & vclass) == vclass) {
403  return allowed.second;
404  }
405  }
406  }
407  return nullptr;
408 }
409 
410 
411 const std::vector<MSLane*>*
413  if ((myMinimumPermissions & vclass) == vclass) {
414  return myLanes;
415  } else {
416  if ((myCombinedPermissions & vclass) == vclass) {
417  for (const auto& allowed : myAllowed) {
418  if ((allowed.first & vclass) == vclass) {
419  return allowed.second;
420  }
421  }
422  }
423  return nullptr;
424  }
425 }
426 
427 
428 // ------------
429 SUMOTime
432  return 0;
433 }
434 
435 
436 SUMOTime
439  return 0;
440 }
441 
442 
443 MSLane*
444 MSEdge::getFreeLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass, double departPos) const {
445  if (allowed == nullptr) {
446  allowed = allowedLanes(vclass);
447  }
448  MSLane* res = nullptr;
449  if (allowed != nullptr) {
450  double largestGap = 0;
451  MSLane* resByGap = nullptr;
452  double leastOccupancy = std::numeric_limits<double>::max();;
453  for (std::vector<MSLane*>::const_iterator i = allowed->begin(); i != allowed->end(); ++i) {
454  const double occupancy = (*i)->getBruttoOccupancy();
455  if (occupancy < leastOccupancy) {
456  res = (*i);
457  leastOccupancy = occupancy;
458  }
459  const MSVehicle* last = (*i)->getLastFullVehicle();
460  const double lastGap = (last != nullptr ? last->getPositionOnLane() : myLength) - departPos;
461  if (lastGap > largestGap) {
462  largestGap = lastGap;
463  resByGap = (*i);
464  }
465  }
466  if (resByGap != nullptr) {
467  //if (res != resByGap) std::cout << SIMTIME << " edge=" << getID() << " departPos=" << departPos << " res=" << Named::getIDSecure(res) << " resByGap=" << Named::getIDSecure(resByGap) << " largestGap=" << largestGap << "\n";
468  res = resByGap;
469  }
470  }
471  return res;
472 }
473 
474 
475 double
476 MSEdge::getDepartPosBound(const MSVehicle& veh, bool upper) const {
477  const SUMOVehicleParameter& pars = veh.getParameter();
478  double pos = getLength();
479  // determine the position
480  switch (pars.departPosProcedure) {
481  case DEPART_POS_GIVEN:
482  pos = pars.departPos;
483  if (pos < 0.) {
484  pos += myLength;
485  }
486  break;
487  case DEPART_POS_RANDOM:
488  // could be any position on the edge
489  break;
491  // could be any position on the edge due to multiple random attempts
492  break;
493  case DEPART_POS_FREE:
494  // many candidate positions, upper bound could be computed exactly
495  // with much effort
496  break;
497  case DEPART_POS_LAST:
498  if (upper) {
499  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
500  MSVehicle* last = (*i)->getLastFullVehicle();
501  if (last != nullptr) {
502  pos = MIN2(pos, last->getPositionOnLane());
503  }
504  }
505  } else {
506  pos = 0;
507  }
508  case DEPART_POS_BASE:
509  case DEPART_POS_DEFAULT:
510  break;
511  default:
512  pos = MIN2(pos, veh.getVehicleType().getLength());
513  break;
514  }
515  return pos;
516 }
517 
518 
519 MSLane*
521  switch (veh.getParameter().departLaneProcedure) {
522  case DEPART_LANE_GIVEN:
523  if ((int) myLanes->size() <= veh.getParameter().departLane || !(*myLanes)[veh.getParameter().departLane]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
524  return nullptr;
525  }
526  return (*myLanes)[veh.getParameter().departLane];
527  case DEPART_LANE_RANDOM:
529  case DEPART_LANE_FREE:
530  return getFreeLane(nullptr, veh.getVehicleType().getVehicleClass(), getDepartPosBound(veh, false));
532  if (veh.getRoute().size() == 1) {
533  return getFreeLane(nullptr, veh.getVehicleType().getVehicleClass(), getDepartPosBound(veh, false));
534  } else {
536  }
537  case DEPART_LANE_BEST_FREE: {
538  veh.updateBestLanes(false, myLanes->front());
539  const std::vector<MSVehicle::LaneQ>& bl = veh.getBestLanes();
540  double bestLength = -1;
541  for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
542  if ((*i).length > bestLength) {
543  bestLength = (*i).length;
544  }
545  }
546  // beyond a certain length, all lanes are suitable
547  // however, we still need to check departPos to avoid unsuitable insertion
548  // (this is only possible in some cases)
549  double departPos = 0;
550  if (bestLength > BEST_LANE_LOOKAHEAD) {
551  departPos = getDepartPosBound(veh);
552  bestLength = MIN2(bestLength - departPos, BEST_LANE_LOOKAHEAD);
553  }
554  std::vector<MSLane*>* bestLanes = new std::vector<MSLane*>();
555  for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
556  if (((*i).length - departPos) >= bestLength) {
557  bestLanes->push_back((*i).lane);
558  }
559  }
560  MSLane* ret = getFreeLane(bestLanes, veh.getVehicleType().getVehicleClass(), getDepartPosBound(veh, false));
561  delete bestLanes;
562  return ret;
563  }
564  case DEPART_LANE_DEFAULT:
566  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
567  if ((*i)->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
568  return *i;
569  }
570  }
571  return nullptr;
572  default:
573  break;
574  }
575  if (!(*myLanes)[0]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
576  return nullptr;
577  }
578  return (*myLanes)[0];
579 }
580 
581 
582 bool
583 MSEdge::insertVehicle(SUMOVehicle& v, SUMOTime time, const bool checkOnly, const bool forceCheck) const {
584  // when vaporizing, no vehicles are inserted, but checking needs to be successful to trigger removal
585  if (isVaporizing() || isTazConnector()) {
586  return checkOnly;
587  }
588  const SUMOVehicleParameter& pars = v.getParameter();
589  const MSVehicleType& type = v.getVehicleType();
591  const std::vector<double>& speedFactorParams = type.getSpeedFactor().getParameter();
592  if (speedFactorParams[1] > 0.) {
594  if (v.getChosenSpeedFactor() > speedFactorParams[0] + 2 * speedFactorParams[1]) {
595  // only warn for significant deviation
596  WRITE_WARNING("Choosing new speed factor " + toString(v.getChosenSpeedFactor()) + " for vehicle '" + pars.id + "' to match departure speed.");
597  }
598  } else {
599  throw ProcessError("Departure speed for vehicle '" + pars.id +
600  "' is too high for the departure edge '" + getID() + "'.");
601  }
602  }
604  if (!forceCheck && myLastFailedInsertionTime == time) {
605  return false;
606  }
607  double pos = 0.0;
608  switch (pars.departPosProcedure) {
609  case DEPART_POS_GIVEN:
610  if (pars.departPos >= 0.) {
611  pos = pars.departPos;
612  } else {
613  pos = pars.departPos + getLength();
614  }
615  if (pos < 0 || pos > getLength()) {
616  WRITE_WARNING("Invalid departPos " + toString(pos) + " given for vehicle '" +
617  v.getID() + "'. Inserting at lane end instead.");
618  pos = getLength();
619  }
620  break;
621  case DEPART_POS_RANDOM:
623  pos = RandHelper::rand(getLength());
624  break;
625  default:
626  break;
627  }
628  bool result = false;
629  MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this, pos);
630  MEVehicle* veh = static_cast<MEVehicle*>(&v);
631  if (pars.departPosProcedure == DEPART_POS_FREE) {
632  while (segment != nullptr && !result) {
633  if (checkOnly) {
634  result = segment->hasSpaceFor(veh, time, true);
635  } else {
636  result = segment->initialise(veh, time);
637  }
638  segment = segment->getNextSegment();
639  }
640  } else {
641  if (checkOnly) {
642  result = segment->hasSpaceFor(veh, time, true);
643  } else {
644  result = segment->initialise(veh, time);
645  }
646  }
647  return result;
648  }
649  if (checkOnly) {
650  switch (v.getParameter().departLaneProcedure) {
651  case DEPART_LANE_GIVEN:
652  case DEPART_LANE_DEFAULT:
654  MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v));
655  if (insertionLane == nullptr) {
656  WRITE_WARNING("could not insert vehicle '" + v.getID() + "' on any lane of edge '" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()));
657  return false;
658  }
659  const double occupancy = insertionLane->getBruttoOccupancy();
660  return occupancy == 0 || occupancy * myLength + v.getVehicleType().getLengthWithGap() <= myLength;
661  }
662  default:
663  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
664  const double occupancy = (*i)->getBruttoOccupancy();
665  if (occupancy == 0 || occupancy * myLength + v.getVehicleType().getLengthWithGap() <= myLength) {
666  return true;
667  }
668  }
669  }
670  return false;
671  }
672  MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v));
673  if (insertionLane == nullptr) {
674  return false;
675  }
676 
677  if (!forceCheck) {
678  if (myLastFailedInsertionTime == time) {
679  if (myFailedInsertionMemory.count(insertionLane->getIndex())) {
680  // A vehicle was already rejected for the proposed insertionLane in this timestep
681  return false;
682  }
683  } else {
684  // last rejection occurred in a previous timestep, clear cache
685  myFailedInsertionMemory.clear();
686  }
687  }
688 
689  bool success = insertionLane->insertVehicle(static_cast<MSVehicle&>(v));
690 
691  if (!success) {
692  myFailedInsertionMemory.insert(insertionLane->getIndex());
693  }
694  return success;
695 }
696 
697 
698 void
700  if (myLaneChanger == nullptr) {
701  return;
702  }
704 }
705 
706 
707 
708 const MSEdge*
709 MSEdge::getInternalFollowingEdge(const MSEdge* followerAfterInternal) const {
710  //@todo to be optimized
711  for (const MSLane* const l : *myLanes) {
712  for (const MSLink* const link : l->getLinkCont()) {
713  if (&link->getLane()->getEdge() == followerAfterInternal) {
714  if (link->getViaLane() != nullptr) {
715  return &link->getViaLane()->getEdge();
716  } else {
717  return nullptr; // network without internal links
718  }
719  }
720  }
721  }
722  return nullptr;
723 }
724 
725 double
726 MSEdge::getInternalFollowingLengthTo(const MSEdge* followerAfterInternal) const {
727  assert(followerAfterInternal != 0);
728  assert(!followerAfterInternal->isInternal());
729  double dist = 0.;
730  const MSEdge* edge = getInternalFollowingEdge(followerAfterInternal);
731  // Take into account non-internal lengths until next non-internal edge
732  while (edge != nullptr && edge->isInternal()) {
733  dist += edge->getLength();
734  edge = edge->getInternalFollowingEdge(followerAfterInternal);
735  }
736  return dist;
737 }
738 
739 const MSEdge*
741  const MSEdge* result = this;
742  while (result->isInternal()) {
743  assert(result->getPredecessors().size() == 1);
744  result = result->getPredecessors().front();
745  }
746  return result;
747 }
748 
749 double
751  double v = 0;
752  double no = 0;
754  for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
755  const int vehNo = segment->getCarNumber();
756  if (vehNo > 0) {
757  v += vehNo * segment->getMeanSpeed();
758  no += vehNo;
759  }
760  }
761  if (no == 0) {
762  return getLength() / myEmptyTraveltime; // may include tls-penalty
763  }
764  } else {
765  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
766  const double vehNo = (double)(*i)->getVehicleNumber();
767  v += vehNo * (*i)->getMeanSpeed();
768  no += vehNo;
769  }
770  if (myBidiEdge != nullptr) {
771  for (const MSLane* lane : myBidiEdge->getLanes()) {
772  if (lane->getVehicleNumber() > 0) {
773  // do not route across edges which are already occupied in reverse direction
774  return 0;
775  }
776  }
777  }
778  if (no == 0) {
779  return getSpeedLimit();
780  }
781  }
782  return v / no;
783 }
784 
785 
786 double
787 MSEdge::getCurrentTravelTime(double minSpeed) const {
788  assert(minSpeed > 0);
789  if (!myAmDelayed) {
790  return myEmptyTraveltime;
791  }
792  return getLength() / MAX2(minSpeed, getMeanSpeed());
793 }
794 
795 
796 double
799 }
800 
801 
802 
803 bool
804 MSEdge::dictionary(const std::string& id, MSEdge* ptr) {
805  DictType::iterator it = myDict.find(id);
806  if (it == myDict.end()) {
807  // id not in myDict.
808  myDict[id] = ptr;
809  while ((int)myEdges.size() < ptr->getNumericalID() + 1) {
810  myEdges.push_back(0);
811  }
812  myEdges[ptr->getNumericalID()] = ptr;
813  return true;
814  }
815  return false;
816 }
817 
818 
819 MSEdge*
820 MSEdge::dictionary(const std::string& id) {
821  DictType::iterator it = myDict.find(id);
822  if (it == myDict.end()) {
823  // id not in myDict.
824  return nullptr;
825  }
826  return it->second;
827 }
828 
829 
830 int
832  return (int)myDict.size();
833 }
834 
835 
836 const MSEdgeVector&
838  return myEdges;
839 }
840 
841 
842 void
844  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
845  delete (*i).second;
846  }
847  myDict.clear();
848  myEdges.clear();
849 }
850 
851 
852 void
853 MSEdge::insertIDs(std::vector<std::string>& into) {
854  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
855  into.push_back((*i).first);
856  }
857 }
858 
859 
860 void
861 MSEdge::parseEdgesList(const std::string& desc, ConstMSEdgeVector& into,
862  const std::string& rid) {
863  if (desc[0] == BinaryFormatter::BF_ROUTE) {
864  std::istringstream in(desc, std::ios::binary);
865  char c;
866  in >> c;
867  FileHelpers::readEdgeVector(in, into, rid);
868  } else {
869  StringTokenizer st(desc);
870  parseEdgesList(st.getVector(), into, rid);
871  }
872 }
873 
874 
875 void
876 MSEdge::parseEdgesList(const std::vector<std::string>& desc, ConstMSEdgeVector& into,
877  const std::string& rid) {
878  for (std::vector<std::string>::const_iterator i = desc.begin(); i != desc.end(); ++i) {
879  const MSEdge* edge = MSEdge::dictionary(*i);
880  // check whether the edge exists
881  if (edge == nullptr) {
882  throw ProcessError("The edge '" + *i + "' within the route " + rid + " is not known."
883  + "\n The route can not be build.");
884  }
885  into.push_back(edge);
886  }
887 }
888 
889 
890 double
891 MSEdge::getDistanceTo(const MSEdge* other, const bool doBoundaryEstimate) const {
892  assert(this != other);
893  if (doBoundaryEstimate) {
894  return myBoundary.distanceTo2D(other->myBoundary);
895  }
896  if (isTazConnector()) {
897  if (other->isTazConnector()) {
898  return myBoundary.distanceTo2D(other->myBoundary);
899  }
900  return myBoundary.distanceTo2D(other->getLanes()[0]->getShape()[0]);
901  }
902  if (other->isTazConnector()) {
903  return other->myBoundary.distanceTo2D(getLanes()[0]->getShape()[-1]);
904  }
905  return getLanes()[0]->getShape()[-1].distanceTo2D(other->getLanes()[0]->getShape()[0]);
906 }
907 
908 
909 const Position
911  return MSLane::dictionary(stop.lane)->geometryPositionAtOffset((stop.endPos + stop.startPos) / 2.);
912 }
913 
914 
915 double
917  // @note lanes might have different maximum speeds in theory
918  return myLanes->empty() ? 1 : getLanes()[0]->getSpeedLimit();
919 }
920 
921 
922 double
924  return myLanes->empty() ? 1 : getLanes()[0]->getLengthGeometryFactor();
925 }
926 
927 double
929  // @note lanes might have different maximum speeds in theory
930  return myLanes->empty() ? 1 : getLanes()[0]->getVehicleMaxSpeed(veh);
931 }
932 
933 
934 void
935 MSEdge::setMaxSpeed(double val) const {
936  if (myLanes != nullptr) {
937  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
938  (*i)->setMaxSpeed(val);
939  }
940  }
941 }
942 
943 
944 
945 std::vector<MSTransportable*>
946 MSEdge::getSortedPersons(SUMOTime timestep, bool includeRiding) const {
947  std::vector<MSTransportable*> result(myPersons.begin(), myPersons.end());
948  if (includeRiding) {
949  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
950  const MSLane::VehCont& vehs = (*i)->getVehiclesSecure();
951  for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
952  const std::vector<MSTransportable*>& persons = (*j)->getPersons();
953  result.insert(result.end(), persons.begin(), persons.end());
954  }
955  (*i)->releaseVehicles();
956  }
957  }
958  sort(result.begin(), result.end(), transportable_by_position_sorter(timestep));
959  return result;
960 }
961 
962 
963 std::vector<MSTransportable*>
964 MSEdge::getSortedContainers(SUMOTime timestep, bool /* includeRiding */) const {
965  std::vector<MSTransportable*> result(myContainers.begin(), myContainers.end());
966  sort(result.begin(), result.end(), transportable_by_position_sorter(timestep));
967  return result;
968 }
969 
970 
971 int
973  const double pos1 = c1->getCurrentStage()->getEdgePos(myTime);
974  const double pos2 = c2->getCurrentStage()->getEdgePos(myTime);
975  if (pos1 != pos2) {
976  return pos1 < pos2;
977  }
978  return c1->getID() < c2->getID();
979 }
980 
981 
982 void
983 MSEdge::addSuccessor(MSEdge* edge, const MSEdge* via) {
984  mySuccessors.push_back(edge);
985  myViaSuccessors.push_back(std::make_pair(edge, via));
986  if (isTazConnector() && edge->getFromJunction() != nullptr) {
988  }
989 
990  edge->myPredecessors.push_back(this);
991  if (edge->isTazConnector() && getToJunction() != nullptr) {
992  edge->myBoundary.add(getToJunction()->getPosition());
993  }
994 }
995 
996 
997 const MSEdgeVector&
999  if (vClass == SVC_IGNORING || !MSNet::getInstance()->hasPermissions() || myFunction == EDGEFUNC_CONNECTOR) {
1000  return mySuccessors;
1001  }
1002 #ifdef HAVE_FOX
1003  if (MSRoutingEngine::isParallel()) {
1004  MSRoutingEngine::lock();
1005  }
1006 #endif
1007  std::map<SUMOVehicleClass, MSEdgeVector>::iterator i = myClassesSuccessorMap.find(vClass);
1008  if (i == myClassesSuccessorMap.end()) {
1009  // instantiate vector
1010  myClassesSuccessorMap[vClass];
1011  i = myClassesSuccessorMap.find(vClass);
1012  // this vClass is requested for the first time. rebuild all successors
1013  for (MSEdgeVector::const_iterator it = mySuccessors.begin(); it != mySuccessors.end(); ++it) {
1014  if ((*it)->isTazConnector()) {
1015  i->second.push_back(*it);
1016  } else {
1017  const std::vector<MSLane*>* allowed = allowedLanes(**it, vClass);
1018  if (allowed != nullptr && allowed->size() > 0) {
1019  i->second.push_back(*it);
1020  }
1021  }
1022  }
1023  }
1024  // can use cached value
1025 #ifdef HAVE_FOX
1026  if (MSRoutingEngine::isParallel()) {
1027  MSRoutingEngine::unlock();
1028  }
1029 #endif
1030  return i->second;
1031 }
1032 
1033 
1034 const MSConstEdgePairVector&
1036  if (vClass == SVC_IGNORING || !MSNet::getInstance()->hasPermissions() || myFunction == EDGEFUNC_CONNECTOR) {
1037  return myViaSuccessors;
1038  }
1039 #ifdef HAVE_FOX
1040  if (MSRoutingEngine::isParallel()) {
1041  MSRoutingEngine::lock();
1042  }
1043 #endif
1044  auto i = myClassesViaSuccessorMap.find(vClass);
1045  if (i != myClassesViaSuccessorMap.end()) {
1046  // can use cached value
1047 #ifdef HAVE_FOX
1048  if (MSRoutingEngine::isParallel()) {
1049  MSRoutingEngine::unlock();
1050  }
1051 #endif
1052  return i->second;
1053  }
1054  // instantiate vector
1056  // this vClass is requested for the first time. rebuild all successors
1057  for (const auto& viaPair : myViaSuccessors) {
1058  if (viaPair.first->isTazConnector()) {
1059  result.push_back(viaPair);
1060  } else {
1061  const std::vector<MSLane*>* allowed = allowedLanes(*viaPair.first, vClass);
1062  if (allowed != nullptr && allowed->size() > 0) {
1063  result.push_back(viaPair);
1064  }
1065  }
1066  }
1067 #ifdef HAVE_FOX
1068  if (MSRoutingEngine::isParallel()) {
1069  MSRoutingEngine::unlock();
1070  }
1071 #endif
1072  return result;
1073 }
1074 
1075 
1076 void
1078  myFromJunction = from;
1079  myToJunction = to;
1080  if (!isTazConnector()) {
1081  myBoundary.add(from->getPosition());
1082  myBoundary.add(to->getPosition());
1083  }
1084 }
1085 
1086 
1087 bool
1089  return (!myLanes->empty() && myLanes->back()->getOpposite() != nullptr &&
1090  // do not change on curved internal lanes
1091  (!isInternal() || myLanes->back()->getIncomingLanes()[0].viaLink->getDirection() == LINKDIR_STRAIGHT));
1092 }
1093 
1094 
1095 const MSEdge*
1097  if (!myLanes->empty() && myLanes->back()->getOpposite() != nullptr) {
1098  return &(myLanes->back()->getOpposite()->getEdge());
1099  } else {
1100  return nullptr;
1101  }
1102 }
1103 
1104 
1105 bool
1107  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
1108  const MSLinkCont& lc = (*i)->getLinkCont();
1109  for (MSLinkCont::const_iterator j = lc.begin(); j != lc.end(); ++j) {
1110  if (!(*j)->havePriority()) {
1111  return true;
1112  }
1113  }
1114  }
1115  return false;
1116 }
1117 
1118 
1119 void MSEdge::checkAndRegisterBiDirEdge(const std::string& bidiID) {
1120  if (bidiID != "") {
1121  myBidiEdge = dictionary(bidiID);
1122  if (myBidiEdge == nullptr) {
1123  WRITE_ERROR("Bidi-edge '" + bidiID + "' does not exist");
1124  }
1125  return;
1126  }
1127  if (getFunction() != EDGEFUNC_NORMAL) {
1128  return;
1129  }
1130  ConstMSEdgeVector candidates = myToJunction->getOutgoing();
1131  for (ConstMSEdgeVector::const_iterator it = candidates.begin(); it != candidates.end(); it++) {
1132  if ((*it)->getToJunction() == myFromJunction) { //reverse edge
1133  if (myBidiEdge != nullptr && isSuperposable(*it)) {
1134  WRITE_WARNING("Ambiguous superposable edges between junction '" + myToJunction->getID() + "' and '" + myFromJunction->getID() + "'.");
1135  break;
1136  }
1137  myBidiEdge = isSuperposable(*it) ? *it : nullptr;
1138  }
1139  }
1140 }
1141 
1142 
1143 bool MSEdge::isSuperposable(const MSEdge* other) {
1144  if (other == nullptr || other->getLanes().size() != myLanes->size()) {
1145  return false;
1146  }
1147  std::vector<MSLane*>::const_iterator it1 = myLanes->begin();
1148  std::vector<MSLane*>::const_reverse_iterator it2 = other->getLanes().rbegin();
1149  do {
1150  if ((*it1)->getShape().reverse() != (*it2)->getShape()) {
1151  return false;
1152  }
1153  it1++;
1154  it2++;
1155  } while (it1 != myLanes->end());
1156 
1157  return true;
1158 }
1159 
1160 
1161 /****************************************************************************/
double distanceTo2D(const Position &p) const
returns the euclidean distance in the x-y-plane
Definition: Boundary.cpp:223
void laneChange(SUMOTime t)
Start lane-change-process for all vehicles on the edge&#39;e lanes.
const SumoXMLEdgeFunc myFunction
the purpose of the edge
Definition: MSEdge.h:775
bool myAmDelayed
whether this edge had a vehicle with less than max speed on it
Definition: MSEdge.h:849
double getDepartPosBound(const MSVehicle &veh, bool upper=true) const
return upper bound for the depart position on this edge
Definition: MSEdge.cpp:476
double getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition: MSLane.cpp:2666
MESegment * getNextSegment() const
Returns the following segment on the same edge (0 if it is the last).
Definition: MESegment.h:152
double getLengthWithGap() const
Get vehicle&#39;s length including the minimum gap [m].
static double gLateralResolution
Definition: MSGlobals.h:85
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:2532
bool insertVehicle(SUMOVehicle &v, SUMOTime time, const bool checkOnly=false, const bool forceCheck=false) const
Tries to insert the given vehicle into the network.
Definition: MSEdge.cpp:583
std::set< MSTransportable * > myContainers
Containers on the edge.
Definition: MSEdge.h:807
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
std::string lane
The lane to stop at.
static void insertIDs(std::vector< std::string > &into)
Inserts IDs of all known edges into the given vector.
Definition: MSEdge.cpp:853
long long int SUMOTime
Definition: SUMOTime.h:35
void checkAndRegisterBiDirEdge(const std::string &bidiID="")
check and register the opposite superposable edge if any
Definition: MSEdge.cpp:1119
AllowedLanesByTarget myAllowedTargets
From target edge to lanes allowed to be used to reach it.
Definition: MSEdge.h:816
Sorts edges by their ids.
Definition: MSEdge.h:734
A vehicle from the mesoscopic point of view.
Definition: MEVehicle.h:45
MESegment * getSegmentForEdge(const MSEdge &e, double pos=0)
Get the segment for a given edge at a given position.
Definition: MELoop.cpp:293
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.
static double gMesoTLSPenalty
Definition: MSGlobals.h:100
double getLengthGeometryFactor() const
return shape.length() / myLength
Definition: MSEdge.cpp:923
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types...
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the maximum speed the vehicle may use on this edge.
Definition: MSEdge.cpp:928
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
static int dictSize()
Returns the number of edges.
Definition: MSEdge.cpp:831
void addSuccessor(MSEdge *edge, const MSEdge *via=nullptr)
Adds an edge to the list of edges which may be reached from this edge and to the incoming of the othe...
Definition: MSEdge.cpp:983
bool initialise(MEVehicle *veh, SUMOTime time)
Inserts (emits) vehicle into the segment.
Definition: MESegment.cpp:279
static void readEdgeVector(std::istream &in, std::vector< const E *> &edges, const std::string &rid)
Reads an edge vector binary.
Definition: FileHelpers.h:256
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
void recalcCache()
Recalculates the cached values.
Definition: MSEdge.cpp:129
This is an uncontrolled, minor link, has to stop.
const MSEdgeVector & getPredecessors() const
Definition: MSEdge.h:352
The base class for an intersection.
Definition: MSJunction.h:61
static MSEdgeVector myEdges
Static list of edges.
Definition: MSEdge.h:874
std::vector< std::pair< const MSEdge *, const MSEdge * > > MSConstEdgePairVector
Definition: MSEdge.h:74
double myTimePenalty
flat penalty when computing traveltime
Definition: MSEdge.h:846
The position is given.
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
double getPositionOnLane() const
Get the vehicle&#39;s position along the lane.
Definition: MSVehicle.h:397
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
const SUMOVehicleParameter & getParameter() const
Returns the vehicle&#39;s parameter (including departure definition)
The least occupied lane is used.
The link is a 180 degree turn.
void buildSegmentsFor(const MSEdge &e, const OptionsCont &oc)
Build the segments for a given edge.
Definition: MELoop.cpp:265
void closeBuilding()
Definition: MSEdge.cpp:166
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:65
virtual ~MSEdge()
Destructor.
Definition: MSEdge.cpp:89
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:398
This is a dead end link.
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
T MAX2(T a, T b)
Definition: StdDefs.h:80
std::vector< double > & getParameter()
Returns the parameters of this distribution.
double getMeanSpeed() const
get the mean speed
Definition: MSEdge.cpp:750
const MSRoute & getRoute() const
Returns the current route.
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn&#39;t already in the dictionary...
Definition: MSEdge.cpp:804
std::vector< double > mySublaneSides
the right side for each sublane on this edge
Definition: MSEdge.h:858
This is an uncontrolled, right-before-left link.
SUMOTime incVaporization(SUMOTime t)
Enables vaporization.
Definition: MSEdge.cpp:430
The lane is chosen randomly.
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:73
void initialize(const std::vector< MSLane *> *lanes)
Initialize the edge.
Definition: MSEdge.cpp:108
const std::string & getID() const
Returns the id.
Definition: Named.h:77
MSConstEdgePairVector myViaSuccessors
Definition: MSEdge.h:794
MSEdge(const std::string &id, int numericalID, const SumoXMLEdgeFunc function, const std::string &streetName, const std::string &edgeType, int priority, double distance)
Constructor.
Definition: MSEdge.cpp:64
const SVCPermissions SVCAll
all VClasses are allowed
int myVaporizationRequests
Vaporizer counter.
Definition: MSEdge.h:778
virtual double getChosenSpeedFactor() const =0
int operator()(const MSTransportable *const c1, const MSTransportable *const c2) const
comparing operator
Definition: MSEdge.cpp:972
double getLength() const
return the length of the edge
Definition: MSEdge.h:582
int size() const
Returns the number of edges to pass.
Definition: MSRoute.cpp:82
const MSJunction * getToJunction() const
Definition: MSEdge.h:361
std::vector< MSTransportable * > getSortedPersons(SUMOTime timestep, bool includeRiding=false) const
Returns this edge&#39;s persons sorted by pos.
Definition: MSEdge.cpp:946
The least occupied lane from best lanes.
The position is chosen randomly.
SUMOTime decVaporization(SUMOTime t)
Disables vaporization.
Definition: MSEdge.cpp:437
int getNumericalID() const
Returns the numerical id of the edge.
Definition: MSEdge.h:263
This is an uncontrolled, all-way stop link.
double getSpeedLimit() const
Returns the speed limit of the edge The speed limit of the first lane is retured; should probably be...
Definition: MSEdge.cpp:916
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:239
The speed is given.
std::map< std::string, MSEdge *> DictType
definition of the static dictionary type
Definition: MSEdge.h:864
The car-following model and parameter.
Definition: MSVehicleType.h:66
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:377
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
Performs lane changing of vehicles.
The lane is given.
double getCurrentTravelTime(const double minSpeed=NUMERICAL_EPS) const
Computes and returns the current travel time for this edge.
Definition: MSEdge.cpp:787
bool hasSpaceFor(const MEVehicle *veh, SUMOTime entryTime, bool init=false) const
Returns whether the given vehicle would still fit into the segment.
Definition: MESegment.cpp:252
The link is a straight direction.
void addToAllowed(const SVCPermissions permissions, const std::vector< MSLane *> *allowedLanes, AllowedLanesCont &laneCont) const
Definition: MSEdge.cpp:246
Performs lane changing of vehicles.
Definition: MSLaneChanger.h:48
double departSpeed
(optional) The initial speed of the vehicle
A road/street connecting two junctions.
Definition: MSEdge.h:76
bool insertVehicle(MSVehicle &v)
Tries to insert the given vehicle.
Definition: MSLane.cpp:533
SUMOTime myLastFailedInsertionTime
The time of last insertion failure.
Definition: MSEdge.h:781
MSTransportable::Stage * getCurrentStage() const
Return the current stage.
std::map< SUMOVehicleClass, MSEdgeVector > myClassesSuccessorMap
The successors available for a given vClass.
Definition: MSEdge.h:879
void rebuildAllowedLanes()
Definition: MSEdge.cpp:268
const int SUMOVehicleClass_MAX
int getIndex() const
Returns the lane&#39;s index.
Definition: MSLane.h:564
#define BEST_LANE_LOOKAHEAD
Definition: MSEdge.cpp:52
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle&#39;s initial speed shall be chosen.
virtual void setChosenSpeedFactor(const double factor)=0
double myLength
the length of the edge (cached value for speedup)
Definition: MSEdge.h:840
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:48
Representation of a vehicle.
Definition: SUMOVehicle.h:61
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
The least occupied lane from lanes which allow the continuation.
This is an uncontrolled, minor link, has to brake.
AllowedLanesCont myAllowed
Associative container from vehicle class to allowed-lanes.
Definition: MSEdge.h:813
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
bool hasMinorLink() const
whether any lane has a minor link
Definition: MSEdge.cpp:1106
private vehicles
const MSEdge * getOppositeEdge() const
Returns the opposite direction edge if on exists else a nullptr.
Definition: MSEdge.cpp:1096
void updateBestLanes(bool forceRebuild=false, const MSLane *startLane=0)
computes the best lanes to use in order to continue the route
Definition: MSVehicle.cpp:4627
static void clear()
Clears the dictionary.
Definition: MSEdge.cpp:843
SVCPermissions myMinimumPermissions
The intersection of lane permissions for this edge.
Definition: MSEdge.h:819
void rebuildAllowedTargets(const bool updateVehicles=true)
Definition: MSEdge.cpp:302
MSEdgeVector mySuccessors
The succeeding edges.
Definition: MSEdge.h:792
double getDistanceTo(const MSEdge *other, const bool doBoundaryEstimate=false) const
optimistic air distance heuristic for use in routing
Definition: MSEdge.cpp:891
MSJunction * myToJunction
Definition: MSEdge.h:801
MSLaneChanger * myLaneChanger
This member will do the lane-change.
Definition: MSEdge.h:772
double getRoutingSpeed() const
Returns the averaged speed used by the routing device.
Definition: MSEdge.cpp:797
#define STEPS2TIME(x)
Definition: SUMOTime.h:57
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
Boundary myBoundary
The bounding rectangle of end nodes incoming or outgoing edges for taz connectors or of my own start ...
Definition: MSEdge.h:885
MSLane * leftLane(const MSLane *const lane) const
Returns the lane left to the one given, 0 if the given lane is leftmost.
Definition: MSEdge.cpp:373
const MSEdge * getNormalBefore() const
if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself ...
Definition: MSEdge.cpp:740
static SUMOTime gMesoMinorPenalty
Definition: MSGlobals.h:103
T MIN2(T a, T b)
Definition: StdDefs.h:74
const Position & getPosition() const
Definition: MSJunction.cpp:69
const std::string & getID() const
returns the id of the transportable
bool myAmFringe
whether this edge is at the network fringe
Definition: MSEdge.h:855
MSLane * getDepartLane(MSVehicle &veh) const
Finds a depart lane for the given vehicle parameters.
Definition: MSEdge.cpp:520
const MSConstEdgePairVector & getViaSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges with internal vias, restricted by vClass.
Definition: MSEdge.cpp:1035
const std::vector< MSLane * > * myLanes
Container for the edge&#39;s lane; should be sorted: (right-hand-traffic) the more left the lane...
Definition: MSEdge.h:769
MSLane * getOpposite() const
return the opposite direction lane for lane changing or 0
Definition: MSLane.cpp:3499
double endPos
The stopping position end.
const MSEdge * myBidiEdge
the oppositing superposble edge
Definition: MSEdge.h:890
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:233
If a fixed number of random choices fails, a free position is chosen.
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:93
bool isSuperposable(const MSEdge *other)
Definition: MSEdge.cpp:1143
bool canChangeToOpposite()
whether this edge allows changing to the opposite direction edge
Definition: MSEdge.cpp:1088
Base class for objects which have an id.
Definition: Named.h:57
The rightmost lane the vehicle may use.
int departLane
(optional) The lane the vehicle shall depart from (index in edge)
const MSEdge * getInternalFollowingEdge(const MSEdge *followerAfterInternal) const
Definition: MSEdge.cpp:709
Definition of vehicle stop (position and duration)
const ConstMSEdgeVector & getOutgoing() const
Definition: MSJunction.h:108
std::vector< std::string > getVector()
return vector of strings
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:245
SVCPermissions myCombinedPermissions
The union of lane permissions for this edge.
Definition: MSEdge.h:821
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: MSEdge.cpp:998
No information given; use default.
void buildLaneChanger()
Has to be called after all sucessors and predecessors have been set (after closeBuilding()) ...
Definition: MSEdge.cpp:205
double departPos
(optional) The position the vehicle shall depart from
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:1855
double startPos
The stopping position start.
static const Position getStopPosition(const SUMOVehicleParameter::Stop &stop)
return the coordinates of the center of the given stop
Definition: MSEdge.cpp:910
Structure representing possible vehicle parameter.
Representation of a vehicle or person.
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
bool isTazConnector() const
Definition: MSEdge.h:256
std::map< SUMOVehicleClass, MSConstEdgePairVector > myClassesViaSuccessorMap
The successors available for a given vClass.
Definition: MSEdge.h:882
static double getAssumedSpeed(const MSEdge *edge)
return current travel speed assumption
static const MSEdgeVector & getAllEdges()
Returns all edges with a numerical id.
Definition: MSEdge.cpp:837
virtual void changeLanes(SUMOTime t)
Performs lane changing on this edge.
Definition: MSEdge.cpp:699
static const T & getRandomFrom(const std::vector< T > &v, std::mt19937 *rng=0)
Returns a random element from the given vector.
Definition: RandHelper.h:154
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle&#39;s parameter (including departure definition)
const MSJunction * getFromJunction() const
Definition: MSEdge.h:357
A single mesoscopic segment (cell)
Definition: MESegment.h:50
double myWidth
Edge width [m].
Definition: MSEdge.h:837
SumoXMLEdgeFunc
Numbers representing special SUMO-XML-attribute values for representing edge functions used in netbui...
MSJunction * myFromJunction
the junctions for this edge
Definition: MSEdge.h:800
double getInternalFollowingLengthTo(const MSEdge *followerAfterInternal) const
returns the length of all internal edges on the junction until reaching the non-internal edge followe...
Definition: MSEdge.cpp:726
MSLane * parallelLane(const MSLane *const lane, int offset, bool includeOpposite=true) const
Returns the lane with the given offset parallel to the given lane one or 0 if it does not exist...
Definition: MSEdge.cpp:385
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition: MSGlobals.h:106
double getLength() const
Get vehicle&#39;s length [m].
void setMaxSpeed(double val) const
Sets a new maximum speed for all lanes (used by TraCI and MSCalibrator)
Definition: MSEdge.cpp:935
void setJunctions(MSJunction *from, MSJunction *to)
Definition: MSEdge.cpp:1077
static DictType myDict
Static dictionary to associate string-ids with objects.
Definition: MSEdge.h:869
Sorts transportables by their positions.
Definition: MSEdge.h:749
static double gMinorPenalty
time penalty for passing a minor link when routing
Definition: MSGlobals.h:130
std::vector< std::pair< SVCPermissions, const std::vector< MSLane * > *> > AllowedLanesCont
"Map" from vehicle class to allowed lanes
Definition: MSEdge.h:79
#define NUMERICAL_EPS
Definition: config.h:145
int numSublanes() const
Definition: MSLeaderInfo.h:88
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:70
No information given; use default.
A free position is chosen.
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:72
Insert behind the last vehicle as close as possible to still allow the specified departSpeed. Fallback to DEPART_POS_BASE if there is no vehicle on the departLane yet.
double computeChosenSpeedDeviation(std::mt19937 *rng, const double minDev=-1.) const
Computes and returns the speed deviation.
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:2099
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:4621
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:79
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:82
MSEdgeVector myPredecessors
The preceeding edges.
Definition: MSEdge.h:797
static bool gUseMesoSim
Definition: MSGlobals.h:91
std::vector< MSTransportable * > getSortedContainers(SUMOTime timestep, bool includeRiding=false) const
Returns this edge&#39;s containers sorted by pos.
Definition: MSEdge.cpp:964
Representation of a lane in the micro simulation.
Definition: MSLane.h:83
bool allowsLaneChanging() const
Definition: MSEdge.cpp:223
MSLane * rightLane(const MSLane *const lane) const
Returns the lane right to the one given, 0 if the given lane is rightmost.
Definition: MSEdge.cpp:379
double myEmptyTraveltime
the traveltime on the empty edge (cached value for speedup)
Definition: MSEdge.h:843
MSLane * getFreeLane(const std::vector< MSLane *> *allowed, const SUMOVehicleClass vclass, double departPos) const
Finds the emptiest lane allowing the vehicle class.
Definition: MSEdge.cpp:444
const Distribution_Parameterized & getSpeedFactor() const
Returns this type&#39;s speed factor.
Back-at-zero position.
static void parseEdgesList(const std::string &desc, ConstMSEdgeVector &into, const std::string &rid)
Parses the given string assuming it contains a list of edge ids divided by spaces.
Definition: MSEdge.cpp:861
SumoXMLEdgeFunc getFunction() const
Returns the edge type (SumoXMLEdgeFunc)
Definition: MSEdge.h:223
vehicles ignoring classes
SUMOVehicleClass getVehicleClass() const
Get this vehicle type&#39;s vehicle class.
std::string id
The vehicle&#39;s id.
std::set< int > myFailedInsertionMemory
A cache for the rejected insertion attempts. Used to assure that no further insertion attempts are ma...
Definition: MSEdge.h:786
std::set< MSTransportable * > myPersons
Persons on the edge for drawing and pushbutton.
Definition: MSEdge.h:804