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-2020 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
24 // A road/street connecting two junctions
25 /****************************************************************************/
26 #include <config.h>
27 
28 #include <algorithm>
29 #include <iostream>
30 #include <cassert>
34 #include <mesosim/MELoop.h>
35 #include <mesosim/MESegment.h>
36 #include <mesosim/MEVehicle.h>
37 #include "MSInsertionControl.h"
38 #include "MSJunction.h"
39 #include "MSLane.h"
40 #include "MSLaneChanger.h"
41 #include "MSLaneChangerSublane.h"
42 #include "MSGlobals.h"
43 #include "MSNet.h"
44 #include "MSVehicle.h"
45 #include "MSLeaderInfo.h"
47 #include "MSEdgeWeightsStorage.h"
48 #include "MSEdge.h"
49 
50 #define BEST_LANE_LOOKAHEAD 3000.0
51 
52 // ===========================================================================
53 // static member definitions
54 // ===========================================================================
57 
58 
59 // ===========================================================================
60 // member method definitions
61 // ===========================================================================
62 MSEdge::MSEdge(const std::string& id, int numericalID,
63  const SumoXMLEdgeFunc function,
64  const std::string& streetName,
65  const std::string& edgeType,
66  int priority,
67  double distance) :
68  Named(id), myNumericalID(numericalID), myLanes(nullptr),
69  myLaneChanger(nullptr), myFunction(function), myVaporizationRequests(0),
70  myLastFailedInsertionTime(-1),
71  myFromJunction(nullptr), myToJunction(nullptr),
72  myOtherTazConnector(nullptr),
73  myStreetName(streetName),
74  myEdgeType(edgeType),
75  myPriority(priority),
76  myDistance(distance),
77  myWidth(0.),
78  myLength(0.),
79  myEmptyTraveltime(0.),
80  myTimePenalty(0.),
81  myAmDelayed(false),
82  myAmRoundabout(false),
83  myAmFringe(true),
84  myBidiEdge(nullptr)
85 { }
86 
87 
89  delete myLaneChanger;
90 }
91 
92 
93 void
94 MSEdge::initialize(const std::vector<MSLane*>* lanes) {
95  assert(lanes != 0);
96  myLanes = std::shared_ptr<const std::vector<MSLane*> >(lanes);
99  }
100  for (MSLane* const lane : *lanes) {
101  lane->setRightSideOnEdge(myWidth, (int)mySublaneSides.size());
102  MSLeaderInfo ahead(lane);
103  for (int j = 0; j < ahead.numSublanes(); ++j) {
105  }
106  myWidth += lane->getWidth();
107  }
108 }
109 
110 
112  if (myLanes->empty()) {
113  return;
114  }
115  myLength = myLanes->front()->getLength();
116  myEmptyTraveltime = myLength / MAX2(getSpeedLimit(), NUMERICAL_EPS);
119  if (edgeType.tlsPenalty > 0 || edgeType.minorPenalty > 0) {
120  // add tls penalties to the minimum travel time
121  SUMOTime minPenalty = -1;
122  for (const MSLane* const l : *myLanes) {
123  for (const MSLink* const link : l->getLinkCont()) {
124  SUMOTime linkPenalty = link->getMesoTLSPenalty() + (link->havePriority() ? 0 : edgeType.minorPenalty);
125  if (minPenalty == -1) {
126  minPenalty = linkPenalty;
127  } else {
128  minPenalty = MIN2(minPenalty, linkPenalty);
129  }
130  }
131  }
132  if (minPenalty > 0) {
133  myEmptyTraveltime += STEPS2TIME(minPenalty);
134  }
135  }
136  } else if (isInternal() && MSGlobals::gUsingInternalLanes) {
137  const MSLink* link = myLanes->front()->getIncomingLanes()[0].viaLink;
138  if (!link->isTLSControlled() && !link->havePriority()) {
141  }
142  }
143 }
144 
145 
146 void
148  for (MSLane* const lane : *myLanes) {
149  for (MSLink* const link : lane->getLinkCont()) {
150  link->initParallelLinks();
151  MSLane* const toL = link->getLane();
152  MSLane* const viaL = link->getViaLane();
153  if (toL != nullptr) {
154  MSEdge& to = toL->getEdge();
155  if (std::find(mySuccessors.begin(), mySuccessors.end(), &to) == mySuccessors.end()) {
156  mySuccessors.push_back(&to);
157  myViaSuccessors.push_back(std::make_pair(&to, (viaL == nullptr ? nullptr : &viaL->getEdge())));
158  }
159  if (std::find(to.myPredecessors.begin(), to.myPredecessors.end(), this) == to.myPredecessors.end()) {
160  to.myPredecessors.push_back(this);
161  }
162  if (link->getDirection() != LinkDirection::TURN) {
163  myAmFringe = false;
164  }
165  }
166  if (viaL != nullptr) {
167  MSEdge& to = viaL->getEdge();
168  if (std::find(to.myPredecessors.begin(), to.myPredecessors.end(), this) == to.myPredecessors.end()) {
169  to.myPredecessors.push_back(this);
170  }
171  }
172  }
173  lane->checkBufferType();
174  }
175  std::sort(mySuccessors.begin(), mySuccessors.end(), by_id_sorter());
177  recalcCache();
178  // segment building depends on the finished list of successors (for multi-queue)
179  if (MSGlobals::gUseMesoSim && !myLanes->empty()) {
181  }
182 }
183 
184 
185 void
187  assert(MSGlobals::gUseMesoSim);
188  if (!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.get(), allowChanging);
201  } else {
203  myLaneChanger = new MSLaneChanger(myLanes.get(), allowChanging);
204  } else if (myLanes->size() > 1 || canChangeToOpposite()) {
205  myLaneChanger = new MSLaneChanger(myLanes.get(), allowChanging);
206  }
207  }
208  }
209 }
210 
211 
212 bool
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 (const MSLane* const lane : *myLanes) {
218  const MSLink* const link = lane->getLogicalPredecessorLane()->getLinkTo(lane);
219  assert(link != nullptr);
220  const LinkState state = link->getState();
221  if (state == LINKSTATE_MINOR
222  || state == LINKSTATE_EQUAL
223  || state == LINKSTATE_STOP
224  || state == LINKSTATE_ALLWAY_STOP
225  || state == LINKSTATE_DEADEND) {
226  return false;
227  }
228  }
229  }
230  return true;
231 }
232 
233 
234 void
235 MSEdge::addToAllowed(const SVCPermissions permissions, std::shared_ptr<const std::vector<MSLane*> > allowedLanes, AllowedLanesCont& laneCont) const {
236  if (!allowedLanes->empty()) {
237  // recheck whether we had this list to save memory
238  for (auto& allowed : laneCont) {
239  if (*allowed.second == *allowedLanes) {
240  allowed.first |= permissions;
241  return;
242  }
243  }
244  laneCont.push_back(std::make_pair(permissions, allowedLanes));
245  }
246 }
247 
248 
249 void
251  // rebuild myMinimumPermissions and myCombinedPermissions
254  for (MSLane* const lane : *myLanes) {
255  myMinimumPermissions &= lane->getPermissions();
256  myCombinedPermissions |= lane->getPermissions();
257  }
258  // rebuild myAllowed
259  myAllowed.clear();
261  myAllowed.push_back(std::make_pair(SVC_IGNORING, myLanes));
262  for (int vclass = SVC_PRIVATE; vclass <= SUMOVehicleClass_MAX; vclass *= 2) {
263  if ((myCombinedPermissions & vclass) == vclass) {
264  std::shared_ptr<std::vector<MSLane*> > allowedLanes = std::make_shared<std::vector<MSLane*> >();
265  for (MSLane* const lane : *myLanes) {
266  if (lane->allowsVehicleClass((SUMOVehicleClass)vclass)) {
267  allowedLanes->push_back(lane);
268  }
269  }
271  }
272  }
273  }
274  rebuildAllowedTargets(false);
275 }
276 
277 
278 void
279 MSEdge::rebuildAllowedTargets(const bool updateVehicles) {
280  myAllowedTargets.clear();
281  for (const MSEdge* target : mySuccessors) {
282  bool universalMap = true; // whether the mapping for SVC_IGNORING is also valid for all vehicle classes
283  std::shared_ptr<std::vector<MSLane*> > allLanes = std::make_shared<std::vector<MSLane*> >();
284  // compute the mapping for SVC_IGNORING
285  for (MSLane* const lane : *myLanes) {
286  SVCPermissions combinedTargetPermissions = 0;
287  for (const MSLink* const link : lane->getLinkCont()) {
288  if (&link->getLane()->getEdge() == target) {
289  allLanes->push_back(lane);
290  combinedTargetPermissions |= link->getLane()->getPermissions();
291  }
292  }
293  if (combinedTargetPermissions == 0 || (lane->getPermissions() & combinedTargetPermissions) != lane->getPermissions()) {
294  universalMap = false;
295  }
296  }
297  if (universalMap) {
298  if (myAllowed.empty()) {
299  // we have no lane specific permissions
300  myAllowedTargets[target].push_back(std::make_pair(myMinimumPermissions, myLanes));
301  } else {
302  for (const auto& i : myAllowed) {
303  addToAllowed(i.first, i.second, myAllowedTargets[target]);
304  }
305  }
306  } else {
307  addToAllowed(SVC_IGNORING, allLanes, myAllowedTargets[target]);
308  // compute the vclass specific mapping
309  for (int vclass = SVC_PRIVATE; vclass <= SUMOVehicleClass_MAX; vclass *= 2) {
310  if ((myCombinedPermissions & vclass) == vclass) {
311  std::shared_ptr<std::vector<MSLane*> > allowedLanes = std::make_shared<std::vector<MSLane*> >();
312  for (MSLane* const lane : *myLanes) {
313  if (lane->allowsVehicleClass((SUMOVehicleClass)vclass)) {
314  for (const MSLink* const link : lane->getLinkCont()) {
315  if (link->getLane()->allowsVehicleClass((SUMOVehicleClass)vclass) && &link->getLane()->getEdge() == target && (link->getViaLane() == nullptr || link->getViaLane()->allowsVehicleClass((SUMOVehicleClass)vclass))) {
316  allowedLanes->push_back(lane);
317  }
318  }
319  }
320  }
321  addToAllowed(vclass, allowedLanes, myAllowedTargets[target]);
322  }
323  }
324  }
325  }
326  if (updateVehicles) {
327  for (const MSLane* const lane : *myLanes) {
328  const MSLane::VehCont& vehs = lane->getVehiclesSecure();
329  for (MSVehicle* veh : vehs) {
330  veh->updateBestLanes(true);
331  }
332  lane->releaseVehicles();
333  }
334  }
335  myClassesSuccessorMap.clear();
336 }
337 
338 
339 // ------------ Access to the edge's lanes
340 MSLane*
341 MSEdge::leftLane(const MSLane* const lane) const {
342  return parallelLane(lane, 1);
343 }
344 
345 
346 MSLane*
347 MSEdge::rightLane(const MSLane* const lane) const {
348  return parallelLane(lane, -1);
349 }
350 
351 
352 MSLane*
353 MSEdge::parallelLane(const MSLane* const lane, int offset, bool includeOpposite) const {
354  const int resultIndex = lane->getIndex() + offset;
355  if (resultIndex == (int)myLanes->size() && includeOpposite) {
356  return lane->getOpposite();
357  } else if (resultIndex >= (int)myLanes->size() || resultIndex < 0) {
358  return nullptr;
359  } else {
360  return (*myLanes)[resultIndex];
361  }
362 }
363 
364 
365 const std::vector<MSLane*>*
366 MSEdge::allowedLanes(const MSEdge& destination, SUMOVehicleClass vclass) const {
367  AllowedLanesByTarget::const_iterator i = myAllowedTargets.find(&destination);
368  if (i != myAllowedTargets.end()) {
369  for (const auto& allowed : i->second) {
370  if ((allowed.first & vclass) == vclass) {
371  return allowed.second.get();
372  }
373  }
374  }
375  return nullptr;
376 }
377 
378 
379 const std::vector<MSLane*>*
381  if ((myMinimumPermissions & vclass) == vclass) {
382  return myLanes.get();
383  } else {
384  if ((myCombinedPermissions & vclass) == vclass) {
385  for (const auto& allowed : myAllowed) {
386  if ((allowed.first & vclass) == vclass) {
387  return allowed.second.get();
388  }
389  }
390  }
391  return nullptr;
392  }
393 }
394 
395 
396 // ------------
397 SUMOTime
400  return 0;
401 }
402 
403 
404 SUMOTime
407  return 0;
408 }
409 
410 
411 MSLane*
412 MSEdge::getFreeLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass, double departPos) const {
413  if (allowed == nullptr) {
414  allowed = allowedLanes(vclass);
415  }
416  MSLane* res = nullptr;
417  if (allowed != nullptr) {
418  double largestGap = 0;
419  MSLane* resByGap = nullptr;
420  double leastOccupancy = std::numeric_limits<double>::max();
421  for (std::vector<MSLane*>::const_iterator i = allowed->begin(); i != allowed->end(); ++i) {
422  const double occupancy = (*i)->getBruttoOccupancy();
423  if (occupancy < leastOccupancy) {
424  res = (*i);
425  leastOccupancy = occupancy;
426  }
427  const MSVehicle* last = (*i)->getLastFullVehicle();
428  const double lastGap = (last != nullptr ? last->getPositionOnLane() : myLength) - departPos;
429  if (lastGap > largestGap) {
430  largestGap = lastGap;
431  resByGap = (*i);
432  }
433  }
434  if (resByGap != nullptr) {
435  //if (res != resByGap) std::cout << SIMTIME << " edge=" << getID() << " departPos=" << departPos << " res=" << Named::getIDSecure(res) << " resByGap=" << Named::getIDSecure(resByGap) << " largestGap=" << largestGap << "\n";
436  res = resByGap;
437  }
438  }
439  return res;
440 }
441 
442 
443 double
444 MSEdge::getDepartPosBound(const MSVehicle& veh, bool upper) const {
445  const SUMOVehicleParameter& pars = veh.getParameter();
446  double pos = getLength();
447  // determine the position
448  switch (pars.departPosProcedure) {
450  pos = pars.departPos;
451  if (pos < 0.) {
452  pos += myLength;
453  }
454  break;
456  // could be any position on the edge
457  break;
459  // could be any position on the edge due to multiple random attempts
460  break;
462  // many candidate positions, upper bound could be computed exactly
463  // with much effort
464  break;
466  if (upper) {
467  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
468  MSVehicle* last = (*i)->getLastFullVehicle();
469  if (last != nullptr) {
470  pos = MIN2(pos, last->getPositionOnLane());
471  }
472  }
473  } else {
474  pos = 0;
475  }
478  break;
479  default:
480  pos = MIN2(pos, veh.getVehicleType().getLength());
481  break;
482  }
483  return pos;
484 }
485 
486 
487 MSLane*
489  switch (veh.getParameter().departLaneProcedure) {
491  if ((int) myLanes->size() <= veh.getParameter().departLane || !(*myLanes)[veh.getParameter().departLane]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
492  return nullptr;
493  }
494  return (*myLanes)[veh.getParameter().departLane];
498  return getFreeLane(nullptr, veh.getVehicleType().getVehicleClass(), getDepartPosBound(veh, false));
500  if (veh.getRoute().size() == 1) {
501  return getFreeLane(nullptr, veh.getVehicleType().getVehicleClass(), getDepartPosBound(veh, false));
502  } else {
504  }
506  veh.updateBestLanes(false, myLanes->front());
507  const std::vector<MSVehicle::LaneQ>& bl = veh.getBestLanes();
508  double bestLength = -1;
509  for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
510  if ((*i).length > bestLength) {
511  bestLength = (*i).length;
512  }
513  }
514  // beyond a certain length, all lanes are suitable
515  // however, we still need to check departPos to avoid unsuitable insertion
516  // (this is only possible in some cases)
517  double departPos = 0;
518  if (bestLength > BEST_LANE_LOOKAHEAD) {
519  departPos = getDepartPosBound(veh);
520  bestLength = MIN2(bestLength - departPos, BEST_LANE_LOOKAHEAD);
521  }
522  std::vector<MSLane*>* bestLanes = new std::vector<MSLane*>();
523  for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
524  if (((*i).length - departPos) >= bestLength) {
525  bestLanes->push_back((*i).lane);
526  }
527  }
528  MSLane* ret = getFreeLane(bestLanes, veh.getVehicleType().getVehicleClass(), getDepartPosBound(veh, false));
529  delete bestLanes;
530  return ret;
531  }
534  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
535  if ((*i)->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
536  return *i;
537  }
538  }
539  return nullptr;
540  default:
541  break;
542  }
543  if (!(*myLanes)[0]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
544  return nullptr;
545  }
546  return (*myLanes)[0];
547 }
548 
549 bool
551  const SUMOVehicleParameter& pars = v.getParameter();
552  const MSVehicleType& type = v.getVehicleType();
553  if (pars.departSpeedProcedure == DepartSpeedDefinition::GIVEN && pars.departSpeed > getVehicleMaxSpeed(&v) + NUMERICAL_EPS) {
554  const std::vector<double>& speedFactorParams = type.getSpeedFactor().getParameter();
555  if (speedFactorParams[1] > 0.) {
557  if (v.getChosenSpeedFactor() > speedFactorParams[0] + 2 * speedFactorParams[1]) {
558  // only warn for significant deviation
559  WRITE_WARNING("Choosing new speed factor " + toString(v.getChosenSpeedFactor()) + " for vehicle '" + pars.id + "' to match departure speed.");
560  }
561  } else {
562  return false;
563  }
564  }
565  return true;
566 }
567 
568 
569 bool
570 MSEdge::insertVehicle(SUMOVehicle& v, SUMOTime time, const bool checkOnly, const bool forceCheck) const {
571  // when vaporizing, no vehicles are inserted, but checking needs to be successful to trigger removal
572  if (isVaporizing() || isTazConnector()
573  || v.getRouteValidity(true, checkOnly) != MSBaseVehicle::ROUTE_VALID) {
574  return checkOnly;
575  }
576  const SUMOVehicleParameter& pars = v.getParameter();
577  if (!validateDepartSpeed(v)) {
578  const std::string errorMsg = "Departure speed for vehicle '" + pars.id + "' is too high for the departure edge '" + getID() + "'.";
580  throw ProcessError(errorMsg);
581  } else {
582  WRITE_WARNING(errorMsg);
583  }
584  }
586  if (!forceCheck && myLastFailedInsertionTime == time) {
587  return false;
588  }
589  double pos = 0.0;
590  switch (pars.departPosProcedure) {
592  if (pars.departPos >= 0.) {
593  pos = pars.departPos;
594  } else {
595  pos = pars.departPos + getLength();
596  }
597  if (pos < 0 || pos > getLength()) {
598  WRITE_WARNING("Invalid departPos " + toString(pos) + " given for vehicle '" +
599  v.getID() + "'. Inserting at lane end instead.");
600  pos = getLength();
601  }
602  break;
605  pos = RandHelper::rand(getLength());
606  break;
607  default:
608  break;
609  }
610  bool result = false;
611  MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this, pos);
612  MEVehicle* veh = static_cast<MEVehicle*>(&v);
613  int qIdx;
615  while (segment != nullptr && !result) {
616  if (checkOnly) {
617  result = segment->hasSpaceFor(veh, time, qIdx, true) == time;
618  } else {
619  result = segment->initialise(veh, time);
620  }
621  segment = segment->getNextSegment();
622  }
623  } else {
624  if (checkOnly) {
625  result = segment->hasSpaceFor(veh, time, qIdx, true) == time;
626  } else {
627  result = segment->initialise(veh, time);
628  }
629  }
630  return result;
631  }
632  if (checkOnly) {
633  switch (v.getParameter().departLaneProcedure) {
637  MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v));
638  if (insertionLane == nullptr) {
639  WRITE_WARNING("could not insert vehicle '" + v.getID() + "' on any lane of edge '" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()));
640  return false;
641  }
642  const double occupancy = insertionLane->getBruttoOccupancy();
643  return occupancy == 0 || occupancy * myLength + v.getVehicleType().getLengthWithGap() <= myLength;
644  }
645  default:
646  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
647  const double occupancy = (*i)->getBruttoOccupancy();
648  if (occupancy == 0 || occupancy * myLength + v.getVehicleType().getLengthWithGap() <= myLength) {
649  return true;
650  }
651  }
652  }
653  return false;
654  }
655  MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v));
656  if (insertionLane == nullptr) {
657  return false;
658  }
659 
660  if (!forceCheck) {
661  if (myLastFailedInsertionTime == time) {
662  if (myFailedInsertionMemory.count(insertionLane->getIndex())) {
663  // A vehicle was already rejected for the proposed insertionLane in this timestep
664  return false;
665  }
666  } else {
667  // last rejection occurred in a previous timestep, clear cache
668  myFailedInsertionMemory.clear();
669  }
670  }
671 
672  bool success = insertionLane->insertVehicle(static_cast<MSVehicle&>(v));
673 
674  if (!success) {
675  myFailedInsertionMemory.insert(insertionLane->getIndex());
676  }
677  return success;
678 }
679 
680 
681 void
683  if (myLaneChanger != nullptr) {
685  }
686 }
687 
688 
689 const MSEdge*
690 MSEdge::getInternalFollowingEdge(const MSEdge* followerAfterInternal) const {
691  //@todo to be optimized
692  for (const MSLane* const l : *myLanes) {
693  for (const MSLink* const link : l->getLinkCont()) {
694  if (&link->getLane()->getEdge() == followerAfterInternal) {
695  if (link->getViaLane() != nullptr) {
696  return &link->getViaLane()->getEdge();
697  } else {
698  return nullptr; // network without internal links
699  }
700  }
701  }
702  }
703  return nullptr;
704 }
705 
706 
707 double
708 MSEdge::getInternalFollowingLengthTo(const MSEdge* followerAfterInternal) const {
709  assert(followerAfterInternal != 0);
710  assert(!followerAfterInternal->isInternal());
711  double dist = 0.;
712  const MSEdge* edge = getInternalFollowingEdge(followerAfterInternal);
713  // Take into account non-internal lengths until next non-internal edge
714  while (edge != nullptr && edge->isInternal()) {
715  dist += edge->getLength();
716  edge = edge->getInternalFollowingEdge(followerAfterInternal);
717  }
718  return dist;
719 }
720 
721 
722 const MSEdge*
724  const MSEdge* result = this;
725  while (result->isInternal() && MSGlobals::gUsingInternalLanes) {
726  assert(result->getPredecessors().size() == 1);
727  result = result->getPredecessors().front();
728  }
729  return result;
730 }
731 
732 const MSEdge*
734  const MSEdge* result = this;
735  while (result->isInternal()) {
736  assert(result->getSuccessors().size() == 1);
737  result = result->getSuccessors().front();
738  }
739  return result;
740 }
741 
742 double
744  double v = 0;
745  double no = 0;
747  for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
748  const int vehNo = segment->getCarNumber();
749  if (vehNo > 0) {
750  v += vehNo * segment->getMeanSpeed();
751  no += vehNo;
752  }
753  }
754  if (no == 0) {
755  return getLength() / myEmptyTraveltime; // may include tls-penalty
756  }
757  } else {
758  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
759  const double vehNo = (double)(*i)->getVehicleNumber();
760  v += vehNo * (*i)->getMeanSpeed();
761  no += vehNo;
762  }
763  if (myBidiEdge != nullptr) {
764  for (const MSLane* lane : myBidiEdge->getLanes()) {
765  if (lane->getVehicleNumber() > 0) {
766  // do not route across edges which are already occupied in reverse direction
767  return 0;
768  }
769  }
770  }
771  if (no == 0) {
772  return getSpeedLimit();
773  }
774  }
775  return v / no;
776 }
777 
778 double
781  // no separate bicycle speeds in meso
782  return getMeanSpeed();
783  }
784  double v = 0;
785  double no = 0;
786  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
787  const double vehNo = (double)(*i)->getVehicleNumber();
788  v += vehNo * (*i)->getMeanSpeedBike();
789  no += vehNo;
790  }
791  if (no == 0) {
792  return getSpeedLimit();
793  }
794  return v / no;
795 }
796 
797 double
798 MSEdge::getCurrentTravelTime(double minSpeed) const {
799  assert(minSpeed > 0);
800  if (!myAmDelayed) {
801  return myEmptyTraveltime;
802  }
803  return getLength() / MAX2(minSpeed, getMeanSpeed());
804 }
805 
806 
807 double
809  return MSRoutingEngine::getAssumedSpeed(this, nullptr);
810 }
811 
812 
813 bool
814 MSEdge::dictionary(const std::string& id, MSEdge* ptr) {
815  DictType::iterator it = myDict.find(id);
816  if (it == myDict.end()) {
817  // id not in myDict.
818  myDict[id] = ptr;
819  while ((int)myEdges.size() < ptr->getNumericalID() + 1) {
820  myEdges.push_back(0);
821  }
822  myEdges[ptr->getNumericalID()] = ptr;
823  return true;
824  }
825  return false;
826 }
827 
828 
829 MSEdge*
830 MSEdge::dictionary(const std::string& id) {
831  DictType::iterator it = myDict.find(id);
832  if (it == myDict.end()) {
833  // id not in myDict.
834  return nullptr;
835  }
836  return it->second;
837 }
838 
839 
840 int
842  return (int)myDict.size();
843 }
844 
845 
846 const MSEdgeVector&
848  return myEdges;
849 }
850 
851 
852 void
854  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
855  delete (*i).second;
856  }
857  myDict.clear();
858  myEdges.clear();
859 }
860 
861 
862 void
863 MSEdge::insertIDs(std::vector<std::string>& into) {
864  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
865  into.push_back((*i).first);
866  }
867 }
868 
869 
870 void
871 MSEdge::parseEdgesList(const std::string& desc, ConstMSEdgeVector& into,
872  const std::string& rid) {
873  StringTokenizer st(desc);
874  parseEdgesList(st.getVector(), into, rid);
875 }
876 
877 
878 void
879 MSEdge::parseEdgesList(const std::vector<std::string>& desc, ConstMSEdgeVector& into,
880  const std::string& rid) {
881  for (std::vector<std::string>::const_iterator i = desc.begin(); i != desc.end(); ++i) {
882  const MSEdge* edge = MSEdge::dictionary(*i);
883  // check whether the edge exists
884  if (edge == nullptr) {
885  throw ProcessError("The edge '" + *i + "' within the route " + rid + " is not known."
886  + "\n The route can not be build.");
887  }
888  into.push_back(edge);
889  }
890 }
891 
892 
893 double
894 MSEdge::getDistanceTo(const MSEdge* other, const bool doBoundaryEstimate) const {
895  assert(this != other);
896  if (doBoundaryEstimate) {
897  return myBoundary.distanceTo2D(other->myBoundary);
898  }
899  if (isTazConnector()) {
900  if (other->isTazConnector()) {
901  return myBoundary.distanceTo2D(other->myBoundary);
902  }
903  return myBoundary.distanceTo2D(other->getLanes()[0]->getShape()[0]);
904  }
905  if (other->isTazConnector()) {
906  return other->myBoundary.distanceTo2D(getLanes()[0]->getShape()[-1]);
907  }
908  return getLanes()[0]->getShape()[-1].distanceTo2D(other->getLanes()[0]->getShape()[0]);
909 }
910 
911 
912 const Position
914  return MSLane::dictionary(stop.lane)->geometryPositionAtOffset((stop.endPos + stop.startPos) / 2.);
915 }
916 
917 
918 double
920  // @note lanes might have different maximum speeds in theory
921  return myLanes->empty() ? 1 : getLanes()[0]->getSpeedLimit();
922 }
923 
924 
925 double
927  return myLanes->empty() ? 1 : getLanes()[0]->getLengthGeometryFactor();
928 }
929 
930 double
932  // @note lanes might have different maximum speeds in theory
933  return myLanes->empty() ? 1 : getLanes()[0]->getVehicleMaxSpeed(veh);
934 }
935 
936 
937 void
938 MSEdge::setMaxSpeed(double val) const {
939  if (myLanes != nullptr) {
940  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
941  (*i)->setMaxSpeed(val);
942  }
943  }
944 }
945 
946 
947 void
949  myPersons.insert(p);
950 }
951 
952 void
954  std::set<MSTransportable*>::iterator i = myPersons.find(p);
955  if (i != myPersons.end()) {
956  myPersons.erase(i);
957  }
958 }
959 
960 std::vector<MSTransportable*>
961 MSEdge::getSortedPersons(SUMOTime timestep, bool includeRiding) const {
962  std::vector<MSTransportable*> result(myPersons.begin(), myPersons.end());
963  if (includeRiding) {
964  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
965  const MSLane::VehCont& vehs = (*i)->getVehiclesSecure();
966  for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
967  const std::vector<MSTransportable*>& persons = (*j)->getPersons();
968  result.insert(result.end(), persons.begin(), persons.end());
969  }
970  (*i)->releaseVehicles();
971  }
972  }
973  sort(result.begin(), result.end(), transportable_by_position_sorter(timestep));
974  return result;
975 }
976 
977 
978 std::vector<MSTransportable*>
979 MSEdge::getSortedContainers(SUMOTime timestep, bool /* includeRiding */) const {
980  std::vector<MSTransportable*> result(myContainers.begin(), myContainers.end());
981  sort(result.begin(), result.end(), transportable_by_position_sorter(timestep));
982  return result;
983 }
984 
985 
986 int
988  const double pos1 = c1->getCurrentStage()->getEdgePos(myTime);
989  const double pos2 = c2->getCurrentStage()->getEdgePos(myTime);
990  if (pos1 != pos2) {
991  return pos1 < pos2;
992  }
993  return c1->getID() < c2->getID();
994 }
995 
996 
997 void
998 MSEdge::addSuccessor(MSEdge* edge, const MSEdge* via) {
999  mySuccessors.push_back(edge);
1000  myViaSuccessors.push_back(std::make_pair(edge, via));
1001  if (isTazConnector() && edge->getFromJunction() != nullptr) {
1003  }
1004 
1005  edge->myPredecessors.push_back(this);
1006  if (edge->isTazConnector() && getToJunction() != nullptr) {
1007  edge->myBoundary.add(getToJunction()->getPosition());
1008  }
1009 }
1010 
1011 
1012 const MSEdgeVector&
1014  if (vClass == SVC_IGNORING || !MSNet::getInstance()->hasPermissions() || myFunction == SumoXMLEdgeFunc::CONNECTOR) {
1015  return mySuccessors;
1016  }
1017 #ifdef HAVE_FOX
1018  FXConditionalLock lock(mySuccessorMutex, MSGlobals::gNumThreads > 1);
1019 #endif
1020  std::map<SUMOVehicleClass, MSEdgeVector>::iterator i = myClassesSuccessorMap.find(vClass);
1021  if (i == myClassesSuccessorMap.end()) {
1022  // instantiate vector
1023  myClassesSuccessorMap[vClass];
1024  i = myClassesSuccessorMap.find(vClass);
1025  // this vClass is requested for the first time. rebuild all successors
1026  for (MSEdgeVector::const_iterator it = mySuccessors.begin(); it != mySuccessors.end(); ++it) {
1027  if ((*it)->isTazConnector()) {
1028  i->second.push_back(*it);
1029  } else {
1030  const std::vector<MSLane*>* allowed = allowedLanes(**it, vClass);
1031  if (allowed != nullptr && allowed->size() > 0) {
1032  i->second.push_back(*it);
1033  }
1034  }
1035  }
1036  }
1037  // can use cached value
1038  return i->second;
1039 }
1040 
1041 
1042 const MSConstEdgePairVector&
1044  if (vClass == SVC_IGNORING || !MSNet::getInstance()->hasPermissions() || myFunction == SumoXMLEdgeFunc::CONNECTOR) {
1045  return myViaSuccessors;
1046  }
1047 #ifdef HAVE_FOX
1048  FXConditionalLock lock(mySuccessorMutex, MSGlobals::gNumThreads > 1);
1049 #endif
1050  auto i = myClassesViaSuccessorMap.find(vClass);
1051  if (i != myClassesViaSuccessorMap.end()) {
1052  // can use cached value
1053  return i->second;
1054  }
1055  // instantiate vector
1057  // this vClass is requested for the first time. rebuild all successors
1058  for (const auto& viaPair : myViaSuccessors) {
1059  if (viaPair.first->isTazConnector()) {
1060  result.push_back(viaPair);
1061  } else {
1062  const std::vector<MSLane*>* allowed = allowedLanes(*viaPair.first, vClass);
1063  if (allowed != nullptr && allowed->size() > 0) {
1064  result.push_back(viaPair);
1065  }
1066  }
1067  }
1068  return result;
1069 }
1070 
1071 
1072 void
1074  myFromJunction = from;
1075  myToJunction = to;
1076  if (!isTazConnector()) {
1077  myBoundary.add(from->getPosition());
1078  myBoundary.add(to->getPosition());
1079  }
1080 }
1081 
1082 
1083 bool
1085  return (!myLanes->empty() && myLanes->back()->getOpposite() != nullptr &&
1086  // do not change on curved internal lanes
1087  (!isInternal() || myLanes->back()->getIncomingLanes()[0].viaLink->getDirection() == LinkDirection::STRAIGHT));
1088 }
1089 
1090 
1091 const MSEdge*
1093  if (!myLanes->empty() && myLanes->back()->getOpposite() != nullptr) {
1094  return &(myLanes->back()->getOpposite()->getEdge());
1095  } else {
1096  return nullptr;
1097  }
1098 }
1099 
1100 
1101 bool
1103  for (const MSLane* const l : *myLanes) {
1104  for (const MSLink* const link : l->getLinkCont()) {
1105  if (!link->havePriority()) {
1106  return true;
1107  }
1108  }
1109  }
1110  return false;
1111 }
1112 
1113 
1114 void
1115 MSEdge::checkAndRegisterBiDirEdge(const std::string& bidiID) {
1116  if (bidiID != "") {
1117  myBidiEdge = dictionary(bidiID);
1118  if (myBidiEdge == nullptr) {
1119  WRITE_ERROR("Bidi-edge '" + bidiID + "' does not exist");
1120  }
1121  return;
1122  }
1124  return;
1125  }
1126  ConstMSEdgeVector candidates = myToJunction->getOutgoing();
1127  for (ConstMSEdgeVector::const_iterator it = candidates.begin(); it != candidates.end(); it++) {
1128  if ((*it)->getToJunction() == myFromJunction) { //reverse edge
1129  if (myBidiEdge != nullptr && isSuperposable(*it)) {
1130  WRITE_WARNING("Ambiguous superposable edges between junction '" + myToJunction->getID() + "' and '" + myFromJunction->getID() + "'.");
1131  break;
1132  }
1133  myBidiEdge = isSuperposable(*it) ? *it : nullptr;
1134  }
1135  }
1136 }
1137 
1138 
1139 bool
1141  if (other == nullptr || other->getLanes().size() != myLanes->size()) {
1142  return false;
1143  }
1144  std::vector<MSLane*>::const_iterator it1 = myLanes->begin();
1145  std::vector<MSLane*>::const_reverse_iterator it2 = other->getLanes().rbegin();
1146  do {
1147  if ((*it1)->getShape().reverse() != (*it2)->getShape()) {
1148  return false;
1149  }
1150  it1++;
1151  it2++;
1152  } while (it1 != myLanes->end());
1153 
1154  return true;
1155 }
1156 
1157 
1158 void
1160 #ifdef HAVE_FOX
1161  FXConditionalLock lock(myWaitingMutex, MSGlobals::gNumSimThreads > 1);
1162 #endif
1163  myWaiting.push_back(vehicle);
1164 }
1165 
1166 
1167 void
1168 MSEdge::removeWaiting(const SUMOVehicle* vehicle) const {
1169 #ifdef HAVE_FOX
1170  FXConditionalLock lock(myWaitingMutex, MSGlobals::gNumSimThreads > 1);
1171 #endif
1172  std::vector<SUMOVehicle*>::iterator it = std::find(myWaiting.begin(), myWaiting.end(), vehicle);
1173  if (it != myWaiting.end()) {
1174  myWaiting.erase(it);
1175  }
1176 }
1177 
1178 
1179 SUMOVehicle*
1180 MSEdge::getWaitingVehicle(MSTransportable* transportable, const double position) const {
1181 #ifdef HAVE_FOX
1182  FXConditionalLock lock(myWaitingMutex, MSGlobals::gNumSimThreads > 1);
1183 #endif
1184  for (SUMOVehicle* const vehicle : myWaiting) {
1185  if (transportable->isWaitingFor(vehicle)) {
1186  if (vehicle->isStoppedInRange(position, MSGlobals::gStopTolerance) ||
1187  (!vehicle->hasDeparted() &&
1188  (vehicle->getParameter().departProcedure == DEPART_TRIGGERED ||
1189  vehicle->getParameter().departProcedure == DEPART_CONTAINER_TRIGGERED))) {
1190  return vehicle;
1191  }
1192  if (!vehicle->isLineStop(position) && vehicle->allowsBoarding(transportable)) {
1193  WRITE_WARNING((transportable->isPerson() ? "Person '" : "Container '")
1194  + transportable->getID() + "' at edge '" + getID() + "' position " + toString(position) + " cannot use waiting vehicle '"
1195  + vehicle->getID() + "' at position " + toString(vehicle->getPositionOnLane()) + " because it is too far away.");
1196  }
1197  }
1198  }
1199  return nullptr;
1200 }
1201 
1202 std::vector<const SUMOVehicle*>
1204  std::vector<const SUMOVehicle*> result;
1205  if (MSGlobals::gUseMesoSim) {
1206  for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
1207  std::vector<const MEVehicle*> segmentVehs = segment->getVehicles();
1208  result.insert(result.end(), segmentVehs.begin(), segmentVehs.end());
1209  }
1210  } else {
1211  for (MSLane* lane : getLanes()) {
1212  for (auto veh : lane->getVehiclesSecure()) {
1213  result.push_back(veh);
1214  }
1215  lane->releaseVehicles();
1216  }
1217  }
1218  return result;
1219 }
1220 
1221 
1222 int
1224  return (int)getVehicles().size();
1225 }
1226 
1227 
1228 double
1230  double wtime = 0;
1231  if (MSGlobals::gUseMesoSim) {
1232  for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
1233  wtime += segment->getWaitingSeconds();
1234  }
1235  } else {
1236  for (MSLane* lane : getLanes()) {
1237  wtime += lane->getWaitingSeconds();
1238  }
1239  }
1240  return wtime;
1241 }
1242 
1243 
1244 double
1246  if (MSGlobals::gUseMesoSim) {
1248  double sum = 0;
1249  for (const SUMOVehicle* veh : getVehicles()) {
1250  sum += dynamic_cast<const MEVehicle*>(veh)->getVehicleType().getLength();
1251  }
1252  return sum / (myLength * myLanes->size());
1253  } else {
1254  double sum = 0;
1255  for (auto lane : getLanes()) {
1256  sum += lane->getNettoOccupancy();
1257  }
1258  return sum / myLanes->size();
1259  }
1260 }
1261 
1262 
1263 double
1265  double flow = 0;
1266  for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
1267  flow += (double) segment->getCarNumber() * segment->getMeanSpeed();
1268  }
1269  return 3600 * flow / (*myLanes)[0]->getLength();
1270 }
1271 
1272 
1273 double
1275  double occ = 0;
1276  for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
1277  occ += segment->getBruttoOccupancy();
1278  }
1279  return occ / (*myLanes)[0]->getLength() / (double)(myLanes->size());
1280 }
1281 
1282 double
1283 MSEdge::getTravelTimeAggregated(const MSEdge* const edge, const SUMOVehicle* const veh, double /*time*/) {
1284  return edge->getLength() / MIN2(MSRoutingEngine::getAssumedSpeed(edge, veh), veh->getMaxSpeed());
1285 }
1286 
1287 /****************************************************************************/
#define BEST_LANE_LOOKAHEAD
Definition: MSEdge.cpp:50
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:74
std::vector< std::pair< const MSEdge *, const MSEdge * > > MSConstEdgePairVector
Definition: MSEdge.h:75
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:73
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:284
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:276
std::string time2string(SUMOTime t)
convert SUMOTime to string
Definition: SUMOTime.cpp:68
#define STEPS2TIME(x)
Definition: SUMOTime.h:53
long long int SUMOTime
Definition: SUMOTime.h:31
const SVCPermissions SVCAll
all VClasses are allowed
const SUMOVehicleClass SUMOVehicleClass_MAX
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_PRIVATE
private vehicles
@ SVC_IGNORING
vehicles ignoring classes
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
@ RANDOM
The lane is chosen randomly.
@ BEST_FREE
The least occupied lane from best lanes.
@ GIVEN
The lane is given.
@ ALLOWED_FREE
The least occupied lane from lanes which allow the continuation.
@ DEFAULT
No information given; use default.
@ FIRST_ALLOWED
The rightmost lane the vehicle may use.
@ FREE
The least occupied lane is used.
@ RANDOM
The position is chosen randomly.
@ GIVEN
The position is given.
@ DEFAULT
No information given; use default.
@ FREE
A free position is chosen.
@ BASE
Back-at-zero position.
@ LAST
Insert behind the last vehicle as close as possible to still allow the specified departSpeed....
@ RANDOM_FREE
If a fixed number of random choices fails, a free position is chosen.
@ GIVEN
The speed is given.
@ DEPART_CONTAINER_TRIGGERED
The departure is container triggered.
@ DEPART_TRIGGERED
The departure is person triggered.
@ TURN
The link is a 180 degree turn.
@ STRAIGHT
The link is a straight direction.
SumoXMLEdgeFunc
Numbers representing special SUMO-XML-attribute values for representing edge functions used in netbui...
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic,...
@ LINKSTATE_ALLWAY_STOP
This is an uncontrolled, all-way stop link.
@ LINKSTATE_STOP
This is an uncontrolled, minor link, has to stop.
@ LINKSTATE_EQUAL
This is an uncontrolled, right-before-left link.
@ LINKSTATE_DEADEND
This is a dead end link.
@ LINKSTATE_MINOR
This is an uncontrolled, minor link, has to brake.
T MIN2(T a, T b)
Definition: StdDefs.h:73
T MAX2(T a, T b)
Definition: StdDefs.h:79
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:44
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:77
double distanceTo2D(const Position &p) const
returns the euclidean distance in the x-y-plane
Definition: Boundary.cpp:221
std::vector< double > & getParameter()
Returns the parameters of this distribution.
A scoped lock which only triggers on condition.
void updateSegementsForEdge(const MSEdge &e)
Update segments after loading meso edge type parameters from additional file.
Definition: MELoop.cpp:289
MESegment * getSegmentForEdge(const MSEdge &e, double pos=0)
Get the segment for a given edge at a given position.
Definition: MELoop.cpp:302
void buildSegmentsFor(const MSEdge &e, const OptionsCont &oc)
Build the segments for a given edge.
Definition: MELoop.cpp:266
A single mesoscopic segment (cell)
Definition: MESegment.h:47
bool initialise(MEVehicle *veh, SUMOTime time)
Inserts (emits) vehicle into the segment.
Definition: MESegment.cpp:333
SUMOTime hasSpaceFor(const MEVehicle *const veh, const SUMOTime entryTime, int &qIdx, const bool init=false) const
Returns whether the given vehicle would still fit into the segment.
Definition: MESegment.cpp:283
MESegment * getNextSegment() const
Returns the following segment on the same edge (0 if it is the last).
Definition: MESegment.h:208
A vehicle from the mesoscopic point of view.
Definition: MEVehicle.h:42
const SUMOVehicleParameter & getParameter() const
Returns the vehicle's parameter (including departure definition)
double getLength() const
Returns the vehicle's length.
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
const MSRoute & getRoute() const
Returns the current route.
Sorts edges by their ids.
Definition: MSEdge.h:807
Sorts transportables by their positions.
Definition: MSEdge.h:822
int operator()(const MSTransportable *const c1, const MSTransportable *const c2) const
comparing operator
Definition: MSEdge.cpp:987
A road/street connecting two junctions.
Definition: MSEdge.h:77
static const MSEdgeVector & getAllEdges()
Returns all edges with a numerical id.
Definition: MSEdge.cpp:847
SUMOVehicle * getWaitingVehicle(MSTransportable *transportable, const double position) const
Definition: MSEdge.cpp:1180
void addToAllowed(const SVCPermissions permissions, std::shared_ptr< const std::vector< MSLane * > > allowedLanes, AllowedLanesCont &laneCont) const
Definition: MSEdge.cpp:235
void changeLanes(SUMOTime t) const
Performs lane changing on this edge.
Definition: MSEdge.cpp:682
double getBruttoOccupancy() const
Definition: MSEdge.cpp:1274
SVCPermissions myCombinedPermissions
The union of lane permissions for this edge.
Definition: MSEdge.h:894
double getFlow() const
return flow based on meanSpead
Definition: MSEdge.cpp:1264
Boundary myBoundary
The bounding rectangle of end nodes incoming or outgoing edges for taz connectors or of my own start ...
Definition: MSEdge.h:961
double myWidth
Edge width [m].
Definition: MSEdge.h:913
AllowedLanesByTarget myAllowedTargets
From target edge to lanes allowed to be used to reach it.
Definition: MSEdge.h:889
MSLane * getDepartLane(MSVehicle &veh) const
Finds a depart lane for the given vehicle parameters.
Definition: MSEdge.cpp:488
SUMOTime myLastFailedInsertionTime
The time of last insertion failure.
Definition: MSEdge.h:854
static void clear()
Clears the dictionary.
Definition: MSEdge.cpp:853
bool canChangeToOpposite()
whether this edge allows changing to the opposite direction edge
Definition: MSEdge.cpp:1084
void setJunctions(MSJunction *from, MSJunction *to)
Definition: MSEdge.cpp:1073
double getMeanSpeedBike() const
get the mean speed of all bicycles on this edge
Definition: MSEdge.cpp:779
static MSEdgeVector myEdges
Static list of edges.
Definition: MSEdge.h:950
AllowedLanesCont myAllowed
Associative container from vehicle class to allowed-lanes.
Definition: MSEdge.h:886
const MSEdgeVector & getPredecessors() const
Definition: MSEdge.h:383
double myEmptyTraveltime
the traveltime on the empty edge (cached value for speedup)
Definition: MSEdge.h:919
void updateMesoType()
update meso segment parameters
Definition: MSEdge.cpp:186
bool myAmFringe
whether this edge is at the network fringe
Definition: MSEdge.h:931
static double getTravelTimeAggregated(const MSEdge *const edge, const SUMOVehicle *const veh, double time)
Definition: MSEdge.cpp:1283
MSJunction * myToJunction
Definition: MSEdge.h:874
void checkAndRegisterBiDirEdge(const std::string &bidiID="")
check and register the opposite superposable edge if any
Definition: MSEdge.cpp:1115
static int dictSize()
Returns the number of edges.
Definition: MSEdge.cpp:841
virtual ~MSEdge()
Destructor.
Definition: MSEdge.cpp:88
double getDepartPosBound(const MSVehicle &veh, bool upper=true) const
return upper bound for the depart position on this edge
Definition: MSEdge.cpp:444
const MSEdge * myBidiEdge
the oppositing superposable edge
Definition: MSEdge.h:977
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:341
const MSEdge * getInternalFollowingEdge(const MSEdge *followerAfterInternal) const
Definition: MSEdge.cpp:690
const MSEdge * getOppositeEdge() const
Returns the opposite direction edge if on exists else a nullptr.
Definition: MSEdge.cpp:1092
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:871
double getLengthGeometryFactor() const
return shape.length() / myLength
Definition: MSEdge.cpp:926
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:998
std::vector< SUMOVehicle * > myWaiting
List of waiting vehicles.
Definition: MSEdge.h:964
const MSEdge * getNormalSuccessor() const
if this edge is an internal edge, return its first normal successor, otherwise the edge itself
Definition: MSEdge.cpp:733
virtual void addPerson(MSTransportable *p) const
Definition: MSEdge.cpp:948
std::vector< MSTransportable * > getSortedPersons(SUMOTime timestep, bool includeRiding=false) const
Returns this edge's persons sorted by pos.
Definition: MSEdge.cpp:961
bool isSuperposable(const MSEdge *other)
Definition: MSEdge.cpp:1140
bool validateDepartSpeed(SUMOVehicle &v) const
check whether the given departSpeed is valid for this edge
Definition: MSEdge.cpp:550
const std::vector< MSLane * > * allowedLanes(const MSEdge &destination, SUMOVehicleClass vclass=SVC_IGNORING) const
Get the allowed lanes to reach the destination-edge.
Definition: MSEdge.cpp:366
double getDistanceTo(const MSEdge *other, const bool doBoundaryEstimate=false) const
optimistic air distance heuristic for use in routing
Definition: MSEdge.cpp:894
const MSConstEdgePairVector & getViaSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges with internal vias, restricted by vClass.
Definition: MSEdge.cpp:1043
MSLaneChanger * myLaneChanger
This member will do the lane-change.
Definition: MSEdge.h:845
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:166
double getOccupancy() const
return mean occupancy on this edges lanes or segments
Definition: MSEdge.cpp:1245
std::vector< MSTransportable * > getSortedContainers(SUMOTime timestep, bool includeRiding=false) const
Returns this edge's containers sorted by pos.
Definition: MSEdge.cpp:979
const SumoXMLEdgeFunc myFunction
the purpose of the edge
Definition: MSEdge.h:848
std::set< MSTransportable * > myContainers
Containers on the edge.
Definition: MSEdge.h:880
void recalcCache()
Recalculates the cached values.
Definition: MSEdge.cpp:111
double getSpeedLimit() const
Returns the speed limit of the edge @caution The speed limit of the first lane is retured; should pro...
Definition: MSEdge.cpp:919
const MSJunction * getFromJunction() const
Definition: MSEdge.h:388
bool myAmDelayed
whether this edge had a vehicle with less than max speed on it
Definition: MSEdge.h:925
std::map< SUMOVehicleClass, MSEdgeVector > myClassesSuccessorMap
The successors available for a given vClass.
Definition: MSEdge.h:955
SUMOTime decVaporization(SUMOTime t)
Disables vaporization.
Definition: MSEdge.cpp:405
MSEdgeVector myPredecessors
The preceeding edges.
Definition: MSEdge.h:870
void rebuildAllowedTargets(const bool updateVehicles=true)
Definition: MSEdge.cpp:279
std::vector< std::pair< SVCPermissions, std::shared_ptr< const std::vector< MSLane * > > > > AllowedLanesCont
"Map" from vehicle class to allowed lanes
Definition: MSEdge.h:80
void rebuildAllowedLanes()
Definition: MSEdge.cpp:250
double getLength() const
return the length of the edge
Definition: MSEdge.h:630
void initialize(const std::vector< MSLane * > *lanes)
Initialize the edge.
Definition: MSEdge.cpp:94
virtual void closeBuilding()
Definition: MSEdge.cpp:147
std::set< int > myFailedInsertionMemory
A cache for the rejected insertion attempts. Used to assure that no further insertion attempts are ma...
Definition: MSEdge.h:859
double getMeanSpeed() const
get the mean speed
Definition: MSEdge.cpp:743
static DictType myDict
Static dictionary to associate string-ids with objects.
Definition: MSEdge.h:945
bool isTazConnector() const
Definition: MSEdge.h:279
MSConstEdgePairVector myViaSuccessors
Definition: MSEdge.h:867
MSEdgeVector mySuccessors
The succeeding edges.
Definition: MSEdge.h:865
std::set< MSTransportable * > myPersons
Persons on the edge for drawing and pushbutton.
Definition: MSEdge.h:877
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:256
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:347
double getCurrentTravelTime(const double minSpeed=NUMERICAL_EPS) const
Computes and returns the current travel time for this edge.
Definition: MSEdge.cpp:798
int getNumericalID() const
Returns the numerical id of the edge.
Definition: MSEdge.h:294
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:408
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:570
static const Position getStopPosition(const SUMOVehicleParameter::Stop &stop)
return the coordinates of the center of the given stop
Definition: MSEdge.cpp:913
void addWaiting(SUMOVehicle *vehicle) const
Adds a vehicle to the list of waiting vehicles.
Definition: MSEdge.cpp:1159
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:353
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn't already in the dictionary....
Definition: MSEdge.cpp:814
std::vector< const SUMOVehicle * > getVehicles() const
return vehicles on this edges lanes or segments
Definition: MSEdge.cpp:1203
static void insertIDs(std::vector< std::string > &into)
Inserts IDs of all known edges into the given vector.
Definition: MSEdge.cpp:863
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the maximum speed the vehicle may use on this edge.
Definition: MSEdge.cpp:931
SUMOTime incVaporization(SUMOTime t)
Enables vaporization.
Definition: MSEdge.cpp:398
MSJunction * myFromJunction
the junctions for this edge
Definition: MSEdge.h:873
std::map< std::string, MSEdge * > DictType
definition of the static dictionary type
Definition: MSEdge.h:940
bool hasMinorLink() const
whether any lane has a minor link
Definition: MSEdge.cpp:1102
std::map< SUMOVehicleClass, MSConstEdgePairVector > myClassesViaSuccessorMap
The successors available for a given vClass.
Definition: MSEdge.h:958
const MSEdge * getNormalBefore() const
if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself
Definition: MSEdge.cpp:723
int getVehicleNumber() const
return total number of vehicles on this edges lanes or segments
Definition: MSEdge.cpp:1223
const std::string & getEdgeType() const
Returns the type of the edge.
Definition: MSEdge.h:307
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:708
const MSJunction * getToJunction() const
Definition: MSEdge.h:392
SumoXMLEdgeFunc getFunction() const
Returns the edge type (SumoXMLEdgeFunc)
Definition: MSEdge.h:246
bool allowsLaneChanging() const
Definition: MSEdge.cpp:213
void setMaxSpeed(double val) const
Sets a new maximum speed for all lanes (used by TraCI and MSCalibrator)
Definition: MSEdge.cpp:938
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:62
void buildLaneChanger()
Has to be called after all sucessors and predecessors have been set (after closeBuilding())
Definition: MSEdge.cpp:195
double getRoutingSpeed() const
Returns the averaged speed used by the routing device.
Definition: MSEdge.cpp:808
virtual void lock() const
grant exclusive access to the mesoscopic state
Definition: MSEdge.h:721
void removeWaiting(const SUMOVehicle *vehicle) const
Removes a vehicle from the list of waiting vehicles.
Definition: MSEdge.cpp:1168
std::vector< double > mySublaneSides
the right side for each sublane on this edge
Definition: MSEdge.h:934
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: MSEdge.cpp:1013
std::shared_ptr< const std::vector< MSLane * > > myLanes
Container for the edge's lane; should be sorted: (right-hand-traffic) the more left the lane,...
Definition: MSEdge.h:842
double getWaitingSeconds() const
return accumated waiting time for all vehicles on this edges lanes or segments
Definition: MSEdge.cpp:1229
int myVaporizationRequests
Vaporizer counter.
Definition: MSEdge.h:851
double myTimePenalty
flat penalty when computing traveltime
Definition: MSEdge.h:922
SVCPermissions myMinimumPermissions
The intersection of lane permissions for this edge.
Definition: MSEdge.h:892
MSLane * getFreeLane(const std::vector< MSLane * > *allowed, const SUMOVehicleClass vclass, double departPos) const
Finds the emptiest lane allowing the vehicle class.
Definition: MSEdge.cpp:412
virtual void removePerson(MSTransportable *p) const
Definition: MSEdge.cpp:953
double myLength
the length of the edge (cached value for speedup)
Definition: MSEdge.h:916
static double gStopTolerance
The tolerance to apply when matching waiting persons and vehicles.
Definition: MSGlobals.h:133
static bool gUseMesoSim
Definition: MSGlobals.h:88
static double gMinorPenalty
time penalty for passing a minor link when routing
Definition: MSGlobals.h:124
static bool gCheckRoutes
Definition: MSGlobals.h:76
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition: MSGlobals.h:94
static double gLateralResolution
Definition: MSGlobals.h:82
static int gNumSimThreads
how many threads to use for simulation
Definition: MSGlobals.h:115
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:79
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:66
static int gNumThreads
how many threads to use
Definition: MSGlobals.h:118
The base class for an intersection.
Definition: MSJunction.h:58
const ConstMSEdgeVector & getOutgoing() const
Definition: MSJunction.h:111
const Position & getPosition() const
Definition: MSJunction.cpp:68
Performs lane changing of vehicles.
Definition: MSLaneChanger.h:45
void laneChange(SUMOTime t)
Start lane-change-process for all vehicles on the edge'e lanes.
Performs lane changing of vehicles.
Representation of a lane in the micro simulation.
Definition: MSLane.h:82
bool insertVehicle(MSVehicle &v)
Tries to insert the given vehicle.
Definition: MSLane.cpp:544
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:92
int getIndex() const
Returns the lane's index.
Definition: MSLane.h:562
double getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition: MSLane.cpp:2693
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:1908
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:673
MSLane * getOpposite() const
return the opposite direction lane for lane changing or 0
Definition: MSLane.cpp:3612
int numSublanes() const
Definition: MSLeaderInfo.h:85
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:171
const MesoEdgeType & getMesoType(const std::string &typeID)
Returns edge type specific meso parameters if no type specific parameters have been loaded,...
Definition: MSNet.cpp:347
int size() const
Returns the number of edges to pass.
Definition: MSRoute.cpp:81
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:69
static double getAssumedSpeed(const MSEdge *edge, const SUMOVehicle *veh)
return current travel speed assumption
virtual double getEdgePos(SUMOTime now) const
Definition: MSStage.cpp:88
bool isPerson() const
Whether it is a person.
MSStage * getCurrentStage() const
Return the current stage.
bool isWaitingFor(const SUMOVehicle *vehicle) const
Whether the transportable waits for the given vehicle in the current step.
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:77
void updateBestLanes(bool forceRebuild=false, const MSLane *startLane=0)
computes the best lanes to use in order to continue the route
Definition: MSVehicle.cpp:4717
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:4711
double getPositionOnLane() const
Get the vehicle's position along the lane.
Definition: MSVehicle.h:374
The car-following model and parameter.
Definition: MSVehicleType.h:62
double getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
const Distribution_Parameterized & getSpeedFactor() const
Returns this type's speed factor.
double computeChosenSpeedDeviation(std::mt19937 *rng, const double minDev=-1.) const
Computes and returns the speed deviation.
double getLength() const
Get vehicle's length [m].
Base class for objects which have an id.
Definition: Named.h:53
const std::string & getID() const
Returns the id.
Definition: Named.h:73
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:36
static double rand(std::mt19937 *rng=nullptr)
Returns a random real number in [0, 1)
Definition: RandHelper.h:51
static const T & getRandomFrom(const std::vector< T > &v, std::mt19937 *rng=0)
Returns a random element from the given vector.
Definition: RandHelper.h:147
Representation of a vehicle, person, or container.
virtual double getChosenSpeedFactor() const =0
virtual double getMaxSpeed() const =0
Returns the object's maximum speed.
virtual const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle's parameter (including departure definition)
Representation of a vehicle.
Definition: SUMOVehicle.h:58
virtual void setChosenSpeedFactor(const double factor)=0
virtual int getRouteValidity(bool update=true, bool silent=false)=0
computes validity attributes for the current route
Definition of vehicle stop (position and duration)
std::string lane
The lane to stop at.
double startPos
The stopping position start.
double endPos
The stopping position end.
Structure representing possible vehicle parameter.
int departLane
(optional) The lane the vehicle shall depart from (index in edge)
double departSpeed
(optional) The initial speed of the vehicle
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
double departPos
(optional) The position the vehicle shall depart from
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle's initial speed shall be chosen.
std::string id
The vehicle's id.
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
std::vector< std::string > getVector()
return vector of strings
edge type specific meso parameters
Definition: MSNet.h:117
double tlsPenalty
Definition: MSNet.h:124
SUMOTime minorPenalty
Definition: MSNet.h:126