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