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-2022 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>
31 #ifdef HAVE_FOX
33 #endif
37 #include <mesosim/MELoop.h>
38 #include <mesosim/MESegment.h>
39 #include <mesosim/MEVehicle.h>
40 #include "MSInsertionControl.h"
41 #include "MSJunction.h"
42 #include "MSLane.h"
43 #include "MSLaneChanger.h"
44 #include "MSLaneChangerSublane.h"
45 #include "MSLink.h"
46 #include "MSGlobals.h"
47 #include "MSNet.h"
48 #include "MSVehicle.h"
49 #include "MSLeaderInfo.h"
51 #include "MSEdgeWeightsStorage.h"
52 #include "MSEdge.h"
53 
54 #define BEST_LANE_LOOKAHEAD 3000.0
55 
56 // ===========================================================================
57 // static member definitions
58 // ===========================================================================
62 
63 
64 // ===========================================================================
65 // member method definitions
66 // ===========================================================================
67 MSEdge::MSEdge(const std::string& id, int numericalID,
68  const SumoXMLEdgeFunc function,
69  const std::string& streetName,
70  const std::string& edgeType,
71  int priority,
72  double distance) :
73  Named(id), myNumericalID(numericalID), myLanes(nullptr),
74  myLaneChanger(nullptr), myFunction(function), myVaporizationRequests(0),
75  myLastFailedInsertionTime(-1),
76  myFromJunction(nullptr), myToJunction(nullptr),
77  myOtherTazConnector(nullptr),
78  myStreetName(streetName),
79  myEdgeType(edgeType),
80  myPriority(priority),
81  myDistance(distance),
82  myWidth(0.),
83  myLength(0.),
84  myEmptyTraveltime(0.),
85  myTimePenalty(0.),
86  myAmDelayed(false),
87  myAmRoundabout(false),
88  myAmFringe(true),
89  myBidiEdge(nullptr)
90 { }
91 
92 
94  delete myLaneChanger;
95 }
96 
97 
98 void
99 MSEdge::initialize(const std::vector<MSLane*>* lanes) {
100  assert(lanes != 0);
101  myLanes = std::shared_ptr<const std::vector<MSLane*> >(lanes);
104  }
105  for (MSLane* const lane : *lanes) {
106  lane->setRightSideOnEdge(myWidth, (int)mySublaneSides.size());
107  MSLeaderInfo ahead(lane);
108  for (int j = 0; j < ahead.numSublanes(); ++j) {
110  }
111  myWidth += lane->getWidth();
112  }
113 }
114 
115 
117  if (myLanes->empty()) {
118  return;
119  }
120  myLength = myLanes->front()->getLength();
121  myEmptyTraveltime = myLength / MAX2(getSpeedLimit(), NUMERICAL_EPS);
124  if (edgeType.tlsPenalty > 0 || edgeType.minorPenalty > 0) {
125  // add tls penalties to the minimum travel time
126  SUMOTime minPenalty = -1;
127  for (const MSLane* const l : *myLanes) {
128  for (const MSLink* const link : l->getLinkCont()) {
129  SUMOTime linkPenalty = link->getMesoTLSPenalty() + (link->havePriority() ? 0 : edgeType.minorPenalty);
130  if (minPenalty == -1) {
131  minPenalty = linkPenalty;
132  } else {
133  minPenalty = MIN2(minPenalty, linkPenalty);
134  }
135  }
136  }
137  if (minPenalty > 0) {
138  myEmptyTraveltime += STEPS2TIME(minPenalty);
139  }
140  }
141  } else if (isInternal() && MSGlobals::gUsingInternalLanes) {
142  const MSLink* link = myLanes->front()->getIncomingLanes()[0].viaLink;
143  if (!link->isTLSControlled() && !link->havePriority()) {
146  }
147  }
148 }
149 
150 
151 void
153  for (MSLane* const lane : *myLanes) {
154  for (MSLink* const link : lane->getLinkCont()) {
155  link->initParallelLinks();
156  MSLane* const toL = link->getLane();
157  MSLane* const viaL = link->getViaLane();
158  if (toL != nullptr) {
159  MSEdge& to = toL->getEdge();
160  if (std::find(mySuccessors.begin(), mySuccessors.end(), &to) == mySuccessors.end()) {
161  mySuccessors.push_back(&to);
162  myViaSuccessors.push_back(std::make_pair(&to, (viaL == nullptr ? nullptr : &viaL->getEdge())));
163  }
164  if (std::find(to.myPredecessors.begin(), to.myPredecessors.end(), this) == to.myPredecessors.end()) {
165  to.myPredecessors.push_back(this);
166  }
167  if (link->getDirection() != LinkDirection::TURN) {
168  myAmFringe = false;
169  }
170  }
171  if (viaL != nullptr) {
172  MSEdge& to = viaL->getEdge();
173  if (std::find(to.myPredecessors.begin(), to.myPredecessors.end(), this) == to.myPredecessors.end()) {
174  to.myPredecessors.push_back(this);
175  }
176  }
177  }
178  lane->checkBufferType();
179  }
180  std::sort(mySuccessors.begin(), mySuccessors.end(), by_id_sorter());
182  recalcCache();
183  // segment building depends on the finished list of successors (for multi-queue)
184  if (MSGlobals::gUseMesoSim && !myLanes->empty()) {
186  }
187 
188  // extend lookup table for sublane model after all edges are read
189  if (myLanes->back()->getOpposite() != nullptr) {
190  MSLane* opposite = myLanes->back()->getOpposite();
191  MSLeaderInfo ahead(opposite);
192  for (int j = 0; j < ahead.numSublanes(); ++j) {
194  }
195  }
196 }
197 
198 
199 void
201  assert(MSGlobals::gUseMesoSim);
202  if (!myLanes->empty()) {
204  }
205 }
206 
207 
208 void
210  if (!myLanes->empty()) {
211  const bool allowChanging = allowsLaneChanging();
213  // may always initiate sublane-change
214  myLaneChanger = new MSLaneChangerSublane(myLanes.get(), allowChanging);
215  } else {
217  myLaneChanger = new MSLaneChanger(myLanes.get(), allowChanging);
218  } else if (myLanes->size() > 1 || canChangeToOpposite()) {
219  myLaneChanger = new MSLaneChanger(myLanes.get(), allowChanging);
220  }
221  }
222  }
223 }
224 
225 
226 bool
229  // allow changing only if all links leading to this internal lane have priority
230  // or they are controlled by a traffic light
231  for (const MSLane* const lane : *myLanes) {
232  const MSLink* const link = lane->getLogicalPredecessorLane()->getLinkTo(lane);
233  assert(link != nullptr);
234  const LinkState state = link->getState();
235  if (state == LINKSTATE_MINOR
236  || state == LINKSTATE_EQUAL
237  || state == LINKSTATE_STOP
238  || state == LINKSTATE_ALLWAY_STOP
239  || state == LINKSTATE_DEADEND) {
240  return false;
241  }
242  }
243  }
244  return true;
245 }
246 
247 
248 void
249 MSEdge::addToAllowed(const SVCPermissions permissions, std::shared_ptr<const std::vector<MSLane*> > allowedLanes, AllowedLanesCont& laneCont) const {
250  if (!allowedLanes->empty()) {
251  // recheck whether we had this list to save memory
252  for (auto& allowed : laneCont) {
253  if (*allowed.second == *allowedLanes) {
254  allowed.first |= permissions;
255  return;
256  }
257  }
258  laneCont.push_back(std::make_pair(permissions, allowedLanes));
259  }
260 }
261 
262 
265  SVCPermissions ignored = myMesoIgnoredVClasses & ~ignoreIgnored;
266  return (p | ignored) == ignored ? 0 : p;
267 }
268 
269 
270 void
272  // rebuild myMinimumPermissions and myCombinedPermissions
275  for (MSLane* const lane : *myLanes) {
276  // same dedicated lanes are ignored in meso to avoid capacity errors.
277  // Here we have to make sure that vehicles which are set to depart on
278  // such lanes trigger an error.
279  SVCPermissions allow = getMesoPermissions(lane->getPermissions(), SVC_PEDESTRIAN);
280  myMinimumPermissions &= allow;
281  myCombinedPermissions |= allow;
282  }
283  // rebuild myAllowed
284  myAllowed.clear();
286  myAllowed.push_back(std::make_pair(SVC_IGNORING, myLanes));
287  for (int vclass = SVC_PRIVATE; vclass <= SUMOVehicleClass_MAX; vclass *= 2) {
288  if ((myCombinedPermissions & vclass) == vclass) {
289  std::shared_ptr<std::vector<MSLane*> > allowedLanes = std::make_shared<std::vector<MSLane*> >();
290  for (MSLane* const lane : *myLanes) {
291  if (lane->allowsVehicleClass((SUMOVehicleClass)vclass)) {
292  allowedLanes->push_back(lane);
293  }
294  }
296  }
297  }
298  }
299  rebuildAllowedTargets(false);
300  for (MSEdge* pred : myPredecessors) {
301  pred->rebuildAllowedTargets(false);
302  }
304  for (MESegment* s = MSGlobals::gMesoNet->getSegmentForEdge(*this); s != nullptr; s = s->getNextSegment()) {
305  s->updatePermissions();
306  }
307  }
308 }
309 
310 
311 void
312 MSEdge::rebuildAllowedTargets(const bool updateVehicles) {
313  myAllowedTargets.clear();
314  for (const MSEdge* target : mySuccessors) {
315  bool universalMap = true; // whether the mapping for SVC_IGNORING is also valid for all vehicle classes
316  std::shared_ptr<std::vector<MSLane*> > allLanes = std::make_shared<std::vector<MSLane*> >();
317  // compute the mapping for SVC_IGNORING
318  for (MSLane* const lane : *myLanes) {
319  SVCPermissions combinedTargetPermissions = 0;
320  for (const MSLink* const link : lane->getLinkCont()) {
321  if (&link->getLane()->getEdge() == target) {
322  allLanes->push_back(lane);
323  combinedTargetPermissions |= link->getLane()->getPermissions();
324  if (link->getViaLane() != nullptr &&
325  ((lane->getPermissions() & link->getLane()->getPermissions()) != link->getViaLane()->getPermissions())) {
326  // custom connection permissions
327  universalMap = false;
328  }
329  }
330  }
331  if (combinedTargetPermissions == 0 || (lane->getPermissions() & combinedTargetPermissions) != lane->getPermissions()) {
332  universalMap = false;
333  }
334  }
335  if (universalMap) {
336  if (myAllowed.empty()) {
337  // we have no lane specific permissions
338  myAllowedTargets[target].push_back(std::make_pair(myMinimumPermissions, myLanes));
339  } else {
340  for (const auto& i : myAllowed) {
341  addToAllowed(i.first, i.second, myAllowedTargets[target]);
342  }
343  }
344  } else {
345  addToAllowed(SVC_IGNORING, allLanes, myAllowedTargets[target]);
346  // compute the vclass specific mapping
347  for (int vclass = SVC_PRIVATE; vclass <= SUMOVehicleClass_MAX; vclass *= 2) {
348  if ((myCombinedPermissions & vclass) == vclass) {
349  std::shared_ptr<std::vector<MSLane*> > allowedLanes = std::make_shared<std::vector<MSLane*> >();
350  for (MSLane* const lane : *myLanes) {
351  if (lane->allowsVehicleClass((SUMOVehicleClass)vclass)) {
352  for (const MSLink* const link : lane->getLinkCont()) {
353  if (link->getLane()->allowsVehicleClass((SUMOVehicleClass)vclass) && &link->getLane()->getEdge() == target && (link->getViaLane() == nullptr || link->getViaLane()->allowsVehicleClass((SUMOVehicleClass)vclass))) {
354  allowedLanes->push_back(lane);
355  }
356  }
357  }
358  }
359  addToAllowed(vclass, allowedLanes, myAllowedTargets[target]);
360  }
361  }
362  }
363  }
364  if (updateVehicles) {
365  for (const MSLane* const lane : *myLanes) {
366  const MSLane::VehCont& vehs = lane->getVehiclesSecure();
367  for (MSVehicle* veh : vehs) {
368  veh->updateBestLanes(true);
369  }
370  lane->releaseVehicles();
371  }
372  }
373  myClassesSuccessorMap.clear();
374 }
375 
376 
377 // ------------ Access to the edge's lanes
378 MSLane*
379 MSEdge::leftLane(const MSLane* const lane) const {
380  return parallelLane(lane, 1);
381 }
382 
383 
384 MSLane*
385 MSEdge::rightLane(const MSLane* const lane) const {
386  return parallelLane(lane, -1);
387 }
388 
389 
390 MSLane*
391 MSEdge::parallelLane(const MSLane* const lane, int offset, bool includeOpposite) const {
392  const int resultIndex = lane->getIndex() + offset;
393  if (resultIndex >= getNumLanes() && includeOpposite) {
394  const MSEdge* opposite = getOppositeEdge();
395  if (opposite != nullptr && resultIndex < getNumLanes() + opposite->getNumLanes()) {
396  return opposite->getLanes()[opposite->getNumLanes() + getNumLanes() - resultIndex - 1];
397  }
398  return nullptr;
399  } else if (resultIndex >= (int)myLanes->size() || resultIndex < 0) {
400  return nullptr;
401  } else {
402  return (*myLanes)[resultIndex];
403  }
404 }
405 
406 
407 const std::vector<MSLane*>*
408 MSEdge::allowedLanes(const MSEdge& destination, SUMOVehicleClass vclass) const {
409  AllowedLanesByTarget::const_iterator i = myAllowedTargets.find(&destination);
410  if (i != myAllowedTargets.end()) {
411  for (const auto& allowed : i->second) {
412  if ((allowed.first & vclass) == vclass) {
413  return allowed.second.get();
414  }
415  }
416  }
417  return nullptr;
418 }
419 
420 
421 const std::vector<MSLane*>*
423  if ((myMinimumPermissions & vclass) == vclass) {
424  return myLanes.get();
425  } else {
426  if ((myCombinedPermissions & vclass) == vclass) {
427  for (const auto& allowed : myAllowed) {
428  if ((allowed.first & vclass) == vclass) {
429  return allowed.second.get();
430  }
431  }
432  }
433  return nullptr;
434  }
435 }
436 
437 
438 // ------------
439 SUMOTime
442  return 0;
443 }
444 
445 
446 SUMOTime
449  return 0;
450 }
451 
452 
453 MSLane*
454 MSEdge::getFreeLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass, double departPos) const {
455  if (allowed == nullptr) {
456  allowed = allowedLanes(vclass);
457  }
458  MSLane* res = nullptr;
459  if (allowed != nullptr) {
460  double largestGap = 0;
461  MSLane* resByGap = nullptr;
462  double leastOccupancy = std::numeric_limits<double>::max();
463  for (std::vector<MSLane*>::const_iterator i = allowed->begin(); i != allowed->end(); ++i) {
464  const double occupancy = (*i)->getBruttoOccupancy();
465  if (occupancy < leastOccupancy) {
466  res = (*i);
467  leastOccupancy = occupancy;
468  }
469  const MSVehicle* last = (*i)->getLastFullVehicle();
470  const double lastGap = (last != nullptr ? last->getPositionOnLane() : myLength) - departPos;
471  if (lastGap > largestGap) {
472  largestGap = lastGap;
473  resByGap = (*i);
474  }
475  }
476  if (resByGap != nullptr) {
477  //if (res != resByGap) std::cout << SIMTIME << " edge=" << getID() << " departPos=" << departPos << " res=" << Named::getIDSecure(res) << " resByGap=" << Named::getIDSecure(resByGap) << " largestGap=" << largestGap << "\n";
478  res = resByGap;
479  }
480  }
481  return res;
482 }
483 
484 
485 double
486 MSEdge::getDepartPosBound(const MSVehicle& veh, bool upper) const {
487  const SUMOVehicleParameter& pars = veh.getParameter();
488  double pos = getLength();
489  // determine the position
490  switch (pars.departPosProcedure) {
492  pos = pars.departPos;
493  if (pos < 0.) {
494  pos += myLength;
495  }
496  break;
498  // could be any position on the edge
499  break;
501  // could be any position on the edge due to multiple random attempts
502  break;
504  // many candidate positions, upper bound could be computed exactly
505  // with much effort
506  break;
508  if (upper) {
509  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
510  MSVehicle* last = (*i)->getLastFullVehicle();
511  if (last != nullptr) {
512  pos = MIN2(pos, last->getPositionOnLane());
513  }
514  }
515  } else {
516  pos = 0;
517  }
518  break;
521  break;
522  default:
523  pos = MIN2(pos, veh.getVehicleType().getLength());
524  break;
525  }
526  return pos;
527 }
528 
529 MSLane*
532  if ((int) myLanes->size() <= veh.getParameter().departLane || !(*myLanes)[veh.getParameter().departLane]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
533  return nullptr;
534  }
535  return (*myLanes)[veh.getParameter().departLane];
536  }
537  return (*myLanes)[0];
538 }
539 
540 MSLane*
542  switch (veh.getParameter().departLaneProcedure) {
544  if ((int) myLanes->size() <= veh.getParameter().departLane || !(*myLanes)[veh.getParameter().departLane]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
545  return nullptr;
546  }
547  return (*myLanes)[veh.getParameter().departLane];
551  return getFreeLane(nullptr, veh.getVehicleType().getVehicleClass(), getDepartPosBound(veh, false));
553  if (veh.getRoute().size() == 1) {
554  return getFreeLane(nullptr, veh.getVehicleType().getVehicleClass(), getDepartPosBound(veh, false));
555  } else {
557  }
559  veh.updateBestLanes(false, myLanes->front());
560  const std::vector<MSVehicle::LaneQ>& bl = veh.getBestLanes();
561  double bestLength = -1;
562  for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
563  if ((*i).length > bestLength) {
564  bestLength = (*i).length;
565  }
566  }
567  // beyond a certain length, all lanes are suitable
568  // however, we still need to check departPos to avoid unsuitable insertion
569  // (this is only possible in some cases)
570  double departPos = 0;
571  if (bestLength > BEST_LANE_LOOKAHEAD) {
572  departPos = getDepartPosBound(veh);
573  bestLength = MIN2(bestLength - departPos, BEST_LANE_LOOKAHEAD);
574  }
575  std::vector<MSLane*>* bestLanes = new std::vector<MSLane*>();
576  for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
577  if (((*i).length - departPos) >= bestLength) {
578  bestLanes->push_back((*i).lane);
579  }
580  }
581  MSLane* ret = getFreeLane(bestLanes, veh.getVehicleType().getVehicleClass(), getDepartPosBound(veh, false));
582  delete bestLanes;
583  return ret;
584  }
587  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
588  if ((*i)->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
589  return *i;
590  }
591  }
592  return nullptr;
593  default:
594  break;
595  }
596  if (!(*myLanes)[0]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
597  return nullptr;
598  }
599  return (*myLanes)[0];
600 }
601 
602 bool
604  const SUMOVehicleParameter& pars = v.getParameter();
605  const MSVehicleType& type = v.getVehicleType();
607  // departSpeed could have been rounded down in the output
608  double vMax = getVehicleMaxSpeed(&v) + SPEED_EPS;
609  if (pars.departSpeed > vMax) {
610  // check departLane (getVehicleMaxSpeed checks lane 0)
611  MSLane* departLane = MSGlobals::gMesoNet ? getDepartLaneMeso(v) : getDepartLane(dynamic_cast<MSVehicle&>(v));
612  if (departLane != nullptr) {
613  vMax = departLane->getVehicleMaxSpeed(&v);
614  if (pars.wasSet(VEHPARS_SPEEDFACTOR_SET)) {
615  // speedFactor could have been rounded down in the output
616  vMax *= (1 + SPEED_EPS);
617  }
618  // additive term must come after multiplication!
619  vMax += SPEED_EPS;
620  if (pars.departSpeed > vMax) {
621  const std::vector<double>& speedFactorParams = type.getSpeedFactor().getParameter();
622  if (speedFactorParams[1] > 0.) {
624  if (v.getChosenSpeedFactor() > speedFactorParams[0] + 2 * speedFactorParams[1]) {
625  // only warn for significant deviation
626  WRITE_WARNINGF("Choosing new speed factor % for vehicle '%' to match departure speed % (max %).",
627  toString(v.getChosenSpeedFactor()), pars.id, pars.departSpeed, vMax);
628  }
629  } else {
630  return false;
631  }
632  }
633  }
634  }
635  }
636  return true;
637 }
638 
639 
640 bool
641 MSEdge::insertVehicle(SUMOVehicle& v, SUMOTime time, const bool checkOnly, const bool forceCheck) const {
642  // when vaporizing, no vehicles are inserted, but checking needs to be successful to trigger removal
643  if (isVaporizing() || isTazConnector()
644  || v.getRouteValidity(true, checkOnly) != MSBaseVehicle::ROUTE_VALID) {
645  return checkOnly;
646  }
647  const SUMOVehicleParameter& pars = v.getParameter();
648  if (!validateDepartSpeed(v)) {
649  const std::string errorMsg = "Departure speed for vehicle '" + pars.id + "' is too high for the departure edge '" + getID() + "'.";
651  throw ProcessError(errorMsg);
652  } else {
653  WRITE_WARNING(errorMsg);
654  }
655  }
657  if (!forceCheck && myLastFailedInsertionTime == time) {
658  return false;
659  }
660  double pos = 0.0;
661  switch (pars.departPosProcedure) {
663  if (pars.departPos >= 0.) {
664  pos = pars.departPos;
665  } else {
666  pos = pars.departPos + getLength();
667  }
668  if (pos < 0 || pos > getLength()) {
669  WRITE_WARNING("Invalid departPos " + toString(pos) + " given for vehicle '" +
670  v.getID() + "'. Inserting at lane end instead.");
671  pos = getLength();
672  }
673  break;
676  pos = RandHelper::rand(getLength());
677  break;
678  default:
679  break;
680  }
681  bool result = false;
682  MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this, pos);
683  MEVehicle* veh = static_cast<MEVehicle*>(&v);
684  int qIdx;
686  while (segment != nullptr && !result) {
687  if (checkOnly) {
688  result = segment->hasSpaceFor(veh, time, qIdx, true) == time;
689  } else {
690  result = segment->initialise(veh, time);
691  }
692  segment = segment->getNextSegment();
693  }
694  } else {
695  if (checkOnly) {
696  result = segment->hasSpaceFor(veh, time, qIdx, true) == time;
697  } else {
698  result = segment->initialise(veh, time);
699  }
700  }
701  return result;
702  }
703  if (checkOnly) {
704  switch (v.getParameter().departLaneProcedure) {
708  MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v));
709  if (insertionLane == nullptr) {
710  WRITE_WARNING("could not insert vehicle '" + v.getID() + "' on any lane of edge '" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()));
711  return false;
712  }
713  const double occupancy = insertionLane->getBruttoOccupancy();
714  return occupancy == 0 || occupancy * myLength + v.getVehicleType().getLengthWithGap() <= myLength;
715  }
716  default:
717  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
718  const double occupancy = (*i)->getBruttoOccupancy();
719  if (occupancy == 0 || occupancy * myLength + v.getVehicleType().getLengthWithGap() <= myLength) {
720  return true;
721  }
722  }
723  }
724  return false;
725  }
726  MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v));
727  if (insertionLane == nullptr) {
728  return false;
729  }
730 
731  if (!forceCheck) {
732  if (myLastFailedInsertionTime == time) {
733  if (myFailedInsertionMemory.count(insertionLane->getIndex())) {
734  // A vehicle was already rejected for the proposed insertionLane in this timestep
735  return false;
736  }
737  } else {
738  // last rejection occurred in a previous timestep, clear cache
739  myFailedInsertionMemory.clear();
740  }
741  }
742 
743  bool success = insertionLane->insertVehicle(static_cast<MSVehicle&>(v));
744 
745  if (!success) {
746  myFailedInsertionMemory.insert(insertionLane->getIndex());
747  }
748  return success;
749 }
750 
751 
752 void
754  if (myLaneChanger != nullptr) {
756  }
757 }
758 
759 
760 const MSEdge*
761 MSEdge::getInternalFollowingEdge(const MSEdge* followerAfterInternal) const {
762  //@todo to be optimized
763  for (const MSLane* const l : *myLanes) {
764  for (const MSLink* const link : l->getLinkCont()) {
765  if (&link->getLane()->getEdge() == followerAfterInternal) {
766  if (link->getViaLane() != nullptr) {
767  return &link->getViaLane()->getEdge();
768  } else {
769  return nullptr; // network without internal links
770  }
771  }
772  }
773  }
774  return nullptr;
775 }
776 
777 
778 double
779 MSEdge::getInternalFollowingLengthTo(const MSEdge* followerAfterInternal) const {
780  assert(followerAfterInternal != 0);
781  assert(!followerAfterInternal->isInternal());
782  double dist = 0.;
783  const MSEdge* edge = getInternalFollowingEdge(followerAfterInternal);
784  // Take into account non-internal lengths until next non-internal edge
785  while (edge != nullptr && edge->isInternal()) {
786  dist += edge->getLength();
787  edge = edge->getInternalFollowingEdge(followerAfterInternal);
788  }
789  return dist;
790 }
791 
792 
793 const MSEdge*
795  const MSEdge* result = this;
796  while (result->isInternal() && MSGlobals::gUsingInternalLanes) {
797  assert(result->getPredecessors().size() == 1);
798  result = result->getPredecessors().front();
799  }
800  return result;
801 }
802 
803 const MSEdge*
805  const MSEdge* result = this;
806  while (result->isInternal()) {
807  assert(result->getSuccessors().size() == 1);
808  result = result->getSuccessors().front();
809  }
810  return result;
811 }
812 
813 double
815  double v = 0;
816  double no = 0;
818  for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
819  const int vehNo = segment->getCarNumber();
820  if (vehNo > 0) {
821  v += vehNo * segment->getMeanSpeed();
822  no += vehNo;
823  }
824  }
825  if (no == 0) {
826  return getLength() / myEmptyTraveltime; // may include tls-penalty
827  }
828  } else {
829  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
830  const double vehNo = (double)(*i)->getVehicleNumber();
831  v += vehNo * (*i)->getMeanSpeed();
832  no += vehNo;
833  }
834  if (myBidiEdge != nullptr) {
835  for (const MSLane* lane : myBidiEdge->getLanes()) {
836  if (lane->getVehicleNumber() > 0) {
837  // do not route across edges which are already occupied in reverse direction
838  return 0;
839  }
840  }
841  }
842  if (no == 0) {
843  return getSpeedLimit();
844  }
845  }
846  return v / no;
847 }
848 
849 double
852  // no separate bicycle speeds in meso
853  return getMeanSpeed();
854  }
855  double v = 0;
856  double no = 0;
857  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
858  const double vehNo = (double)(*i)->getVehicleNumber();
859  v += vehNo * (*i)->getMeanSpeedBike();
860  no += vehNo;
861  }
862  if (no == 0) {
863  return getSpeedLimit();
864  }
865  return v / no;
866 }
867 
868 double
869 MSEdge::getCurrentTravelTime(double minSpeed) const {
870  assert(minSpeed > 0);
871  if (!myAmDelayed) {
872  return myEmptyTraveltime;
873  }
874  return getLength() / MAX2(minSpeed, getMeanSpeed());
875 }
876 
877 
878 double
880  return MSRoutingEngine::getAssumedSpeed(this, nullptr);
881 }
882 
883 
884 bool
885 MSEdge::dictionary(const std::string& id, MSEdge* ptr) {
886  DictType::iterator it = myDict.find(id);
887  if (it == myDict.end()) {
888  // id not in myDict.
889  myDict[id] = ptr;
890  while ((int)myEdges.size() < ptr->getNumericalID() + 1) {
891  myEdges.push_back(0);
892  }
893  myEdges[ptr->getNumericalID()] = ptr;
894  return true;
895  }
896  return false;
897 }
898 
899 
900 MSEdge*
901 MSEdge::dictionary(const std::string& id) {
902  DictType::iterator it = myDict.find(id);
903  if (it == myDict.end()) {
904  // id not in myDict.
905  return nullptr;
906  }
907  return it->second;
908 }
909 
910 
911 int
913  return (int)myDict.size();
914 }
915 
916 
917 const MSEdgeVector&
919  return myEdges;
920 }
921 
922 
923 void
925  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
926  delete (*i).second;
927  }
928  myDict.clear();
929  myEdges.clear();
930 }
931 
932 
933 void
934 MSEdge::insertIDs(std::vector<std::string>& into) {
935  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
936  into.push_back((*i).first);
937  }
938 }
939 
940 
941 void
942 MSEdge::parseEdgesList(const std::string& desc, ConstMSEdgeVector& into,
943  const std::string& rid) {
944  StringTokenizer st(desc);
945  parseEdgesList(st.getVector(), into, rid);
946 }
947 
948 
949 void
950 MSEdge::parseEdgesList(const std::vector<std::string>& desc, ConstMSEdgeVector& into,
951  const std::string& rid) {
952  for (std::vector<std::string>::const_iterator i = desc.begin(); i != desc.end(); ++i) {
953  const MSEdge* edge = MSEdge::dictionary(*i);
954  // check whether the edge exists
955  if (edge == nullptr) {
956  throw ProcessError("The edge '" + *i + "' within the route " + rid + " is not known."
957  + "\n The route can not be build.");
958  }
959  into.push_back(edge);
960  }
961 }
962 
963 
964 double
965 MSEdge::getDistanceTo(const MSEdge* other, const bool doBoundaryEstimate) const {
966  assert(this != other);
967  if (doBoundaryEstimate) {
968  return myBoundary.distanceTo2D(other->myBoundary);
969  }
970  if (isTazConnector()) {
971  if (other->isTazConnector()) {
972  return myBoundary.distanceTo2D(other->myBoundary);
973  }
974  return myBoundary.distanceTo2D(other->getLanes()[0]->getShape()[0]);
975  }
976  if (other->isTazConnector()) {
977  return other->myBoundary.distanceTo2D(getLanes()[0]->getShape()[-1]);
978  }
979  return getLanes()[0]->getShape()[-1].distanceTo2D(other->getLanes()[0]->getShape()[0]);
980 }
981 
982 
983 const Position
985  return MSLane::dictionary(stop.lane)->geometryPositionAtOffset((stop.endPos + stop.startPos) / 2.);
986 }
987 
988 
989 double
991  // @note lanes might have different maximum speeds in theory
992  return myLanes->empty() ? 1 : getLanes()[0]->getSpeedLimit();
993 }
994 
995 
996 double
998  return myLanes->empty() ? 1 : getLanes()[0]->getLengthGeometryFactor();
999 }
1000 
1001 double
1003  // @note lanes might have different maximum speeds in theory
1004  return myLanes->empty() ? 1 : getLanes()[0]->getVehicleMaxSpeed(veh);
1005 }
1006 
1007 
1008 void
1009 MSEdge::setMaxSpeed(double val) const {
1010  if (myLanes != nullptr) {
1011  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
1012  (*i)->setMaxSpeed(val);
1013  }
1014  }
1015 }
1016 
1017 
1018 void
1020  myPersons.insert(p);
1021 }
1022 
1023 void
1025  std::set<MSTransportable*>::iterator i = myPersons.find(p);
1026  if (i != myPersons.end()) {
1027  myPersons.erase(i);
1028  }
1029 }
1030 
1031 std::vector<MSTransportable*>
1032 MSEdge::getSortedPersons(SUMOTime timestep, bool includeRiding) const {
1033  std::vector<MSTransportable*> result(myPersons.begin(), myPersons.end());
1034  if (includeRiding) {
1035  for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
1036  const MSLane::VehCont& vehs = (*i)->getVehiclesSecure();
1037  for (MSLane::VehCont::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
1038  const std::vector<MSTransportable*>& persons = (*j)->getPersons();
1039  result.insert(result.end(), persons.begin(), persons.end());
1040  }
1041  (*i)->releaseVehicles();
1042  }
1043  }
1044  sort(result.begin(), result.end(), transportable_by_position_sorter(timestep));
1045  return result;
1046 }
1047 
1048 
1049 std::vector<MSTransportable*>
1050 MSEdge::getSortedContainers(SUMOTime timestep, bool /* includeRiding */) const {
1051  std::vector<MSTransportable*> result(myContainers.begin(), myContainers.end());
1052  sort(result.begin(), result.end(), transportable_by_position_sorter(timestep));
1053  return result;
1054 }
1055 
1056 
1057 int
1059  const double pos1 = c1->getCurrentStage()->getEdgePos(myTime);
1060  const double pos2 = c2->getCurrentStage()->getEdgePos(myTime);
1061  if (pos1 != pos2) {
1062  return pos1 < pos2;
1063  }
1064  return c1->getID() < c2->getID();
1065 }
1066 
1067 
1068 void
1069 MSEdge::addSuccessor(MSEdge* edge, const MSEdge* via) {
1070  mySuccessors.push_back(edge);
1071  myViaSuccessors.push_back(std::make_pair(edge, via));
1072  if (isTazConnector() && edge->getFromJunction() != nullptr) {
1074  }
1075 
1076  edge->myPredecessors.push_back(this);
1077  if (edge->isTazConnector() && getToJunction() != nullptr) {
1078  edge->myBoundary.add(getToJunction()->getPosition());
1079  }
1080 }
1081 
1082 
1083 const MSEdgeVector&
1085  if (vClass == SVC_IGNORING || !MSNet::getInstance()->hasPermissions() || myFunction == SumoXMLEdgeFunc::CONNECTOR) {
1086  return mySuccessors;
1087  }
1088 #ifdef HAVE_FOX
1089  ScopedLocker<> lock(mySuccessorMutex, MSGlobals::gNumThreads > 1);
1090 #endif
1091  std::map<SUMOVehicleClass, MSEdgeVector>::iterator i = myClassesSuccessorMap.find(vClass);
1092  if (i == myClassesSuccessorMap.end()) {
1093  // instantiate vector
1094  myClassesSuccessorMap[vClass];
1095  i = myClassesSuccessorMap.find(vClass);
1096  // this vClass is requested for the first time. rebuild all successors
1097  for (MSEdgeVector::const_iterator it = mySuccessors.begin(); it != mySuccessors.end(); ++it) {
1098  if ((*it)->isTazConnector()) {
1099  i->second.push_back(*it);
1100  } else {
1101  const std::vector<MSLane*>* allowed = allowedLanes(**it, vClass);
1102  if (allowed != nullptr && allowed->size() > 0) {
1103  i->second.push_back(*it);
1104  }
1105  }
1106  }
1107  }
1108  // can use cached value
1109  return i->second;
1110 }
1111 
1112 
1113 const MSConstEdgePairVector&
1115  if (vClass == SVC_IGNORING || !MSNet::getInstance()->hasPermissions() || myFunction == SumoXMLEdgeFunc::CONNECTOR) {
1116  return myViaSuccessors;
1117  }
1118 #ifdef HAVE_FOX
1119  ScopedLocker<> lock(mySuccessorMutex, MSGlobals::gNumThreads > 1);
1120 #endif
1121  auto i = myClassesViaSuccessorMap.find(vClass);
1122  if (i != myClassesViaSuccessorMap.end()) {
1123  // can use cached value
1124  return i->second;
1125  }
1126  // instantiate vector
1128  // this vClass is requested for the first time. rebuild all successors
1129  for (const auto& viaPair : myViaSuccessors) {
1130  if (viaPair.first->isTazConnector()) {
1131  result.push_back(viaPair);
1132  } else {
1133  const std::vector<MSLane*>* allowed = allowedLanes(*viaPair.first, vClass);
1134  if (allowed != nullptr && allowed->size() > 0) {
1135  result.push_back(viaPair);
1136  }
1137  }
1138  }
1139  return result;
1140 }
1141 
1142 
1143 void
1145  myFromJunction = from;
1146  myToJunction = to;
1147  if (!isTazConnector()) {
1148  myBoundary.add(from->getPosition());
1149  myBoundary.add(to->getPosition());
1150  }
1151 }
1152 
1153 
1154 bool
1156  return (!myLanes->empty() && myLanes->back()->getOpposite() != nullptr &&
1157  // do not change on curved internal lanes
1158  (!isInternal() || myLanes->back()->getIncomingLanes()[0].viaLink->getDirection() == LinkDirection::STRAIGHT));
1159 }
1160 
1161 
1162 const MSEdge*
1164  if (!myLanes->empty() && myLanes->back()->getOpposite() != nullptr) {
1165  return &(myLanes->back()->getOpposite()->getEdge());
1166  } else {
1167  return nullptr;
1168  }
1169 }
1170 
1171 
1172 bool
1174  for (const MSLane* const l : *myLanes) {
1175  for (const MSLink* const link : l->getLinkCont()) {
1176  if (!link->havePriority()) {
1177  return true;
1178  }
1179  }
1180  }
1181  return false;
1182 }
1183 
1184 
1185 void
1186 MSEdge::checkAndRegisterBiDirEdge(const std::string& bidiID) {
1187  if (bidiID != "") {
1188  myBidiEdge = dictionary(bidiID);
1189  if (myBidiEdge == nullptr) {
1190  WRITE_ERROR("Bidi-edge '" + bidiID + "' does not exist");
1191  }
1192  return;
1193  }
1195  return;
1196  }
1197  ConstMSEdgeVector candidates = myToJunction->getOutgoing();
1198  for (ConstMSEdgeVector::const_iterator it = candidates.begin(); it != candidates.end(); it++) {
1199  if ((*it)->getToJunction() == myFromJunction) { //reverse edge
1200  if (myBidiEdge != nullptr && isSuperposable(*it)) {
1201  WRITE_WARNING("Ambiguous superposable edges between junction '" + myToJunction->getID() + "' and '" + myFromJunction->getID() + "'.");
1202  break;
1203  }
1204  myBidiEdge = isSuperposable(*it) ? *it : nullptr;
1205  }
1206  }
1207 }
1208 
1209 
1210 bool
1212  if (other == nullptr || other->getLanes().size() != myLanes->size()) {
1213  return false;
1214  }
1215  std::vector<MSLane*>::const_iterator it1 = myLanes->begin();
1216  std::vector<MSLane*>::const_reverse_iterator it2 = other->getLanes().rbegin();
1217  do {
1218  if ((*it1)->getShape().reverse() != (*it2)->getShape()) {
1219  return false;
1220  }
1221  it1++;
1222  it2++;
1223  } while (it1 != myLanes->end());
1224 
1225  return true;
1226 }
1227 
1228 
1229 void
1231 #ifdef HAVE_FOX
1232  ScopedLocker<> lock(myWaitingMutex, MSGlobals::gNumSimThreads > 1);
1233 #endif
1234  myWaiting.push_back(vehicle);
1235 }
1236 
1237 
1238 void
1239 MSEdge::removeWaiting(const SUMOVehicle* vehicle) const {
1240 #ifdef HAVE_FOX
1241  ScopedLocker<> lock(myWaitingMutex, MSGlobals::gNumSimThreads > 1);
1242 #endif
1243  std::vector<SUMOVehicle*>::iterator it = std::find(myWaiting.begin(), myWaiting.end(), vehicle);
1244  if (it != myWaiting.end()) {
1245  myWaiting.erase(it);
1246  }
1247 }
1248 
1249 
1250 SUMOVehicle*
1251 MSEdge::getWaitingVehicle(MSTransportable* transportable, const double position) const {
1252 #ifdef HAVE_FOX
1253  ScopedLocker<> lock(myWaitingMutex, MSGlobals::gNumSimThreads > 1);
1254 #endif
1255  for (SUMOVehicle* const vehicle : myWaiting) {
1256  if (transportable->isWaitingFor(vehicle)) {
1257  if (vehicle->isStoppedInRange(position, MSGlobals::gStopTolerance) ||
1258  (!vehicle->hasDeparted() &&
1259  (vehicle->getParameter().departProcedure == DEPART_TRIGGERED ||
1260  vehicle->getParameter().departProcedure == DEPART_CONTAINER_TRIGGERED))) {
1261  return vehicle;
1262  }
1263  if (!vehicle->isLineStop(position) && vehicle->allowsBoarding(transportable)) {
1264  WRITE_WARNING((transportable->isPerson() ? "Person '" : "Container '")
1265  + transportable->getID() + "' at edge '" + getID() + "' position " + toString(position) + " cannot use waiting vehicle '"
1266  + vehicle->getID() + "' at position " + toString(vehicle->getPositionOnLane()) + " because it is too far away.");
1267  }
1268  }
1269  }
1270  return nullptr;
1271 }
1272 
1273 std::vector<const SUMOVehicle*>
1275  std::vector<const SUMOVehicle*> result;
1276  if (MSGlobals::gUseMesoSim) {
1277  for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
1278  std::vector<const MEVehicle*> segmentVehs = segment->getVehicles();
1279  result.insert(result.end(), segmentVehs.begin(), segmentVehs.end());
1280  }
1281  } else {
1282  for (MSLane* lane : getLanes()) {
1283  for (auto veh : lane->getVehiclesSecure()) {
1284  result.push_back(veh);
1285  }
1286  lane->releaseVehicles();
1287  }
1288  }
1289  return result;
1290 }
1291 
1292 
1293 int
1295  return (int)getVehicles().size();
1296 }
1297 
1298 
1299 double
1301  double wtime = 0;
1302  if (MSGlobals::gUseMesoSim) {
1303  for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
1304  wtime += segment->getWaitingSeconds();
1305  }
1306  } else {
1307  for (MSLane* lane : getLanes()) {
1308  wtime += lane->getWaitingSeconds();
1309  }
1310  }
1311  return wtime;
1312 }
1313 
1314 
1315 double
1317  if (myLanes->size() == 0) {
1318  return 0;
1319  }
1320  if (MSGlobals::gUseMesoSim) {
1322  double sum = 0;
1323  for (const SUMOVehicle* veh : getVehicles()) {
1324  sum += dynamic_cast<const MEVehicle*>(veh)->getVehicleType().getLength();
1325  }
1326  return sum / (myLength * myLanes->size());
1327  } else {
1328  double sum = 0;
1329  for (auto lane : getLanes()) {
1330  sum += lane->getNettoOccupancy();
1331  }
1332  return sum / myLanes->size();
1333  }
1334 }
1335 
1336 
1337 double
1339  if (myLanes->size() == 0) {
1340  return 0;
1341  }
1342  double flow = 0;
1343  for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
1344  flow += (double) segment->getCarNumber() * segment->getMeanSpeed();
1345  }
1346  return 3600 * flow / (*myLanes)[0]->getLength();
1347 }
1348 
1349 
1350 double
1352  if (myLanes->size() == 0) {
1353  return 0;
1354  }
1355  double occ = 0;
1356  for (MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this); segment != nullptr; segment = segment->getNextSegment()) {
1357  occ += segment->getBruttoOccupancy();
1358  }
1359  return occ / (*myLanes)[0]->getLength() / (double)(myLanes->size());
1360 }
1361 
1362 double
1363 MSEdge::getTravelTimeAggregated(const MSEdge* const edge, const SUMOVehicle* const veh, double /*time*/) {
1364  return edge->getLength() / MIN2(MSRoutingEngine::getAssumedSpeed(edge, veh), veh->getMaxSpeed());
1365 }
1366 
1367 
1368 void
1370  // @note must be called after closeBuilding() to ensure successors and
1371  // predecessors are set
1372  if (isInternal() && myEdgeType == "") {
1373  const std::string typeBefore = getNormalBefore()->getEdgeType();
1374  if (typeBefore != "") {
1375  const std::string typeAfter = getNormalSuccessor()->getEdgeType();
1376  if (typeBefore == typeAfter) {
1377  myEdgeType = typeBefore;
1378  } else if (typeAfter != "") {
1379  MSNet* net = MSNet::getInstance();
1380  auto resBefore = net->getRestrictions(typeBefore);
1381  auto resAfter = net->getRestrictions(typeAfter);
1382  if (resBefore != nullptr && resAfter != nullptr) {
1383  // create new restrictions for this type-combination
1384  myEdgeType = typeBefore + "|" + typeAfter;
1385  if (net->getRestrictions(myEdgeType) == nullptr) {
1386  for (const auto& item : *resBefore) {
1387  const SUMOVehicleClass svc = item.first;
1388  const double speed = item.second;
1389  const auto it = (*resAfter).find(svc);
1390  if (it != (*resAfter).end()) {
1391  const double speed2 = it->second;
1392  const double newSpeed = (MSNet::getInstance()->hasJunctionHigherSpeeds()
1393  ? MAX2(speed, speed2) : (speed + speed2) / 2);
1394  net->addRestriction(myEdgeType, svc, newSpeed);
1395  }
1396  }
1397  }
1398  }
1399  }
1400  }
1401  }
1402 }
1403 
1404 /****************************************************************************/
#define BEST_LANE_LOOKAHEAD
Definition: MSEdge.cpp:54
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_WARNINGF(...)
Definition: MsgHandler.h:281
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:288
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:280
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:32
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
@ SVC_PEDESTRIAN
pedestrian
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.
const int VEHPARS_SPEEDFACTOR_SET
@ 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:74
T MAX2(T a, T b)
Definition: StdDefs.h:80
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
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.
void updateSegmentsForEdge(const MSEdge &e)
Update segments after loading meso edge type parameters from additional file.
Definition: MELoop.cpp:301
MESegment * getSegmentForEdge(const MSEdge &e, double pos=0)
Get the segment for a given edge at a given position.
Definition: MELoop.cpp:314
void buildSegmentsFor(const MSEdge &e, const OptionsCont &oc)
Build the segments for a given edge.
Definition: MELoop.cpp:278
A single mesoscopic segment (cell)
Definition: MESegment.h:49
bool initialise(MEVehicle *veh, SUMOTime time)
Inserts (emits) vehicle into the segment.
Definition: MESegment.cpp:329
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:275
MESegment * getNextSegment() const
Returns the following segment on the same edge (0 if it is the last).
Definition: MESegment.h:227
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:823
Sorts transportables by their positions.
Definition: MSEdge.h:838
int operator()(const MSTransportable *const c1, const MSTransportable *const c2) const
comparing operator
Definition: MSEdge.cpp:1058
A road/street connecting two junctions.
Definition: MSEdge.h:77
static const MSEdgeVector & getAllEdges()
Returns all edges with a numerical id.
Definition: MSEdge.cpp:918
SUMOVehicle * getWaitingVehicle(MSTransportable *transportable, const double position) const
Definition: MSEdge.cpp:1251
void addToAllowed(const SVCPermissions permissions, std::shared_ptr< const std::vector< MSLane * > > allowedLanes, AllowedLanesCont &laneCont) const
Definition: MSEdge.cpp:249
void changeLanes(SUMOTime t) const
Performs lane changing on this edge.
Definition: MSEdge.cpp:753
double getBruttoOccupancy() const
Definition: MSEdge.cpp:1351
SVCPermissions myCombinedPermissions
The union of lane permissions for this edge.
Definition: MSEdge.h:910
double getFlow() const
return flow based on meanSpead
Definition: MSEdge.cpp:1338
Boundary myBoundary
The bounding rectangle of end nodes incoming or outgoing edges for taz connectors or of my own start ...
Definition: MSEdge.h:979
double myWidth
Edge width [m].
Definition: MSEdge.h:929
AllowedLanesByTarget myAllowedTargets
From target edge to lanes allowed to be used to reach it.
Definition: MSEdge.h:905
MSLane * getDepartLane(MSVehicle &veh) const
Finds a depart lane for the given vehicle parameters.
Definition: MSEdge.cpp:541
SUMOTime myLastFailedInsertionTime
The time of last insertion failure.
Definition: MSEdge.h:870
static void clear()
Clears the dictionary.
Definition: MSEdge.cpp:924
void inferEdgeType()
Definition: MSEdge.cpp:1369
void setJunctions(MSJunction *from, MSJunction *to)
Definition: MSEdge.cpp:1144
double getMeanSpeedBike() const
get the mean speed of all bicycles on this edge
Definition: MSEdge.cpp:850
static MSEdgeVector myEdges
Static list of edges.
Definition: MSEdge.h:966
AllowedLanesCont myAllowed
Associative container from vehicle class to allowed-lanes.
Definition: MSEdge.h:902
const MSEdgeVector & getPredecessors() const
Definition: MSEdge.h:392
double myEmptyTraveltime
the traveltime on the empty edge (cached value for speedup)
Definition: MSEdge.h:935
void updateMesoType()
update meso segment parameters
Definition: MSEdge.cpp:200
bool myAmFringe
whether this edge is at the network fringe
Definition: MSEdge.h:947
static double getTravelTimeAggregated(const MSEdge *const edge, const SUMOVehicle *const veh, double time)
Definition: MSEdge.cpp:1363
MSJunction * myToJunction
Definition: MSEdge.h:890
void checkAndRegisterBiDirEdge(const std::string &bidiID="")
check and register the opposite superposable edge if any
Definition: MSEdge.cpp:1186
static int dictSize()
Returns the number of edges.
Definition: MSEdge.cpp:912
virtual ~MSEdge()
Destructor.
Definition: MSEdge.cpp:93
double getDepartPosBound(const MSVehicle &veh, bool upper=true) const
return upper bound for the depart position on this edge
Definition: MSEdge.cpp:486
MSLane * getDepartLaneMeso(SUMOVehicle &veh) const
consider given departLane parameter (only for validating speeds)
Definition: MSEdge.cpp:530
const MSEdge * myBidiEdge
the oppositing superposable edge
Definition: MSEdge.h:995
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:379
const MSEdge * getInternalFollowingEdge(const MSEdge *followerAfterInternal) const
Definition: MSEdge.cpp:761
std::string myEdgeType
the type of the edge (optionally used during network creation)
Definition: MSEdge.h:920
const MSEdge * getOppositeEdge() const
Returns the opposite direction edge if on exists else a nullptr.
Definition: MSEdge.cpp:1163
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:942
double getLengthGeometryFactor() const
return shape.length() / myLength
Definition: MSEdge.cpp:997
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:1069
friend class MSLaneChangerSublane
Definition: MSEdge.h:87
std::vector< SUMOVehicle * > myWaiting
List of waiting vehicles.
Definition: MSEdge.h:982
const MSEdge * getNormalSuccessor() const
if this edge is an internal edge, return its first normal successor, otherwise the edge itself
Definition: MSEdge.cpp:804
virtual void addPerson(MSTransportable *p) const
Definition: MSEdge.cpp:1019
std::vector< MSTransportable * > getSortedPersons(SUMOTime timestep, bool includeRiding=false) const
Returns this edge's persons sorted by pos.
Definition: MSEdge.cpp:1032
bool isSuperposable(const MSEdge *other)
Definition: MSEdge.cpp:1211
bool validateDepartSpeed(SUMOVehicle &v) const
check whether the given departSpeed is valid for this edge
Definition: MSEdge.cpp:603
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:408
double getDistanceTo(const MSEdge *other, const bool doBoundaryEstimate=false) const
optimistic air distance heuristic for use in routing
Definition: MSEdge.cpp:965
const MSConstEdgePairVector & getViaSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges with internal vias, restricted by vClass.
Definition: MSEdge.cpp:1114
MSLaneChanger * myLaneChanger
This member will do the lane-change.
Definition: MSEdge.h:861
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:168
double getOccupancy() const
return mean occupancy on this edges lanes or segments
Definition: MSEdge.cpp:1316
std::vector< MSTransportable * > getSortedContainers(SUMOTime timestep, bool includeRiding=false) const
Returns this edge's containers sorted by pos.
Definition: MSEdge.cpp:1050
const SumoXMLEdgeFunc myFunction
the purpose of the edge
Definition: MSEdge.h:864
std::set< MSTransportable * > myContainers
Containers on the edge.
Definition: MSEdge.h:896
void recalcCache()
Recalculates the cached values.
Definition: MSEdge.cpp:116
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:990
const MSJunction * getFromJunction() const
Definition: MSEdge.h:397
bool myAmDelayed
whether this edge had a vehicle with less than max speed on it
Definition: MSEdge.h:941
std::map< SUMOVehicleClass, MSEdgeVector > myClassesSuccessorMap
The successors available for a given vClass.
Definition: MSEdge.h:973
SUMOTime decVaporization(SUMOTime t)
Disables vaporization.
Definition: MSEdge.cpp:447
MSEdgeVector myPredecessors
The preceeding edges.
Definition: MSEdge.h:886
void rebuildAllowedTargets(const bool updateVehicles=true)
Definition: MSEdge.cpp:312
static SVCPermissions myMesoIgnoredVClasses
Definition: MSEdge.h:968
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:271
double getLength() const
return the length of the edge
Definition: MSEdge.h:641
void initialize(const std::vector< MSLane * > *lanes)
Initialize the edge.
Definition: MSEdge.cpp:99
virtual void closeBuilding()
Definition: MSEdge.cpp:152
static SVCPermissions getMesoPermissions(SVCPermissions p, SVCPermissions ignoreIgnored=0)
Definition: MSEdge.cpp:264
bool canChangeToOpposite() const
whether this edge allows changing to the opposite direction edge
Definition: MSEdge.cpp:1155
std::set< int > myFailedInsertionMemory
A cache for the rejected insertion attempts. Used to assure that no further insertion attempts are ma...
Definition: MSEdge.h:875
double getMeanSpeed() const
get the mean speed
Definition: MSEdge.cpp:814
static DictType myDict
Static dictionary to associate string-ids with objects.
Definition: MSEdge.h:961
bool isTazConnector() const
Definition: MSEdge.h:285
int getNumLanes() const
Definition: MSEdge.h:172
MSConstEdgePairVector myViaSuccessors
Definition: MSEdge.h:883
MSEdgeVector mySuccessors
The succeeding edges.
Definition: MSEdge.h:881
std::set< MSTransportable * > myPersons
Persons on the edge for drawing and pushbutton.
Definition: MSEdge.h:893
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:262
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:385
double getCurrentTravelTime(const double minSpeed=NUMERICAL_EPS) const
Computes and returns the current travel time for this edge.
Definition: MSEdge.cpp:869
int getNumericalID() const
Returns the numerical id of the edge.
Definition: MSEdge.h:300
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:417
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:641
static const Position getStopPosition(const SUMOVehicleParameter::Stop &stop)
return the coordinates of the center of the given stop
Definition: MSEdge.cpp:984
void addWaiting(SUMOVehicle *vehicle) const
Adds a vehicle to the list of waiting vehicles.
Definition: MSEdge.cpp:1230
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:391
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:885
std::vector< const SUMOVehicle * > getVehicles() const
return vehicles on this edges lanes or segments
Definition: MSEdge.cpp:1274
static void insertIDs(std::vector< std::string > &into)
Inserts IDs of all known edges into the given vector.
Definition: MSEdge.cpp:934
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the maximum speed the vehicle may use on this edge.
Definition: MSEdge.cpp:1002
SUMOTime incVaporization(SUMOTime t)
Enables vaporization.
Definition: MSEdge.cpp:440
MSJunction * myFromJunction
the junctions for this edge
Definition: MSEdge.h:889
std::map< std::string, MSEdge * > DictType
definition of the static dictionary type
Definition: MSEdge.h:956
bool hasMinorLink() const
whether any lane has a minor link
Definition: MSEdge.cpp:1173
std::map< SUMOVehicleClass, MSConstEdgePairVector > myClassesViaSuccessorMap
The successors available for a given vClass.
Definition: MSEdge.h:976
const MSEdge * getNormalBefore() const
if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself
Definition: MSEdge.cpp:794
int getVehicleNumber() const
return total number of vehicles on this edges lanes or segments
Definition: MSEdge.cpp:1294
const std::string & getEdgeType() const
Returns the type of the edge.
Definition: MSEdge.h:313
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:779
const MSJunction * getToJunction() const
Definition: MSEdge.h:401
SumoXMLEdgeFunc getFunction() const
Returns the edge type (SumoXMLEdgeFunc)
Definition: MSEdge.h:252
bool allowsLaneChanging() const
Definition: MSEdge.cpp:227
void setMaxSpeed(double val) const
Sets a new maximum speed for all lanes (used by TraCI and MSCalibrator)
Definition: MSEdge.cpp:1009
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:67
void buildLaneChanger()
Has to be called after all sucessors and predecessors have been set (after closeBuilding())
Definition: MSEdge.cpp:209
double getRoutingSpeed() const
Returns the averaged speed used by the routing device.
Definition: MSEdge.cpp:879
virtual void lock() const
grant exclusive access to the mesoscopic state
Definition: MSEdge.h:732
void removeWaiting(const SUMOVehicle *vehicle) const
Removes a vehicle from the list of waiting vehicles.
Definition: MSEdge.cpp:1239
std::vector< double > mySublaneSides
the right side for each sublane on this edge
Definition: MSEdge.h:950
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: MSEdge.cpp:1084
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:858
double getWaitingSeconds() const
return accumated waiting time for all vehicles on this edges lanes or segments
Definition: MSEdge.cpp:1300
int myVaporizationRequests
Vaporizer counter.
Definition: MSEdge.h:867
double myTimePenalty
flat penalty when computing traveltime
Definition: MSEdge.h:938
SVCPermissions myMinimumPermissions
The intersection of lane permissions for this edge.
Definition: MSEdge.h:908
MSLane * getFreeLane(const std::vector< MSLane * > *allowed, const SUMOVehicleClass vclass, double departPos) const
Finds the emptiest lane allowing the vehicle class.
Definition: MSEdge.cpp:454
virtual void removePerson(MSTransportable *p) const
Definition: MSEdge.cpp:1024
double myLength
the length of the edge (cached value for speedup)
Definition: MSEdge.h:932
static double gStopTolerance
The tolerance to apply when matching waiting persons and vehicles.
Definition: MSGlobals.h:151
static bool gUseMesoSim
Definition: MSGlobals.h:94
static double gMinorPenalty
time penalty for passing a minor link when routing
Definition: MSGlobals.h:142
static bool gCheckRoutes
Definition: MSGlobals.h:82
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition: MSGlobals.h:100
static double gLateralResolution
Definition: MSGlobals.h:88
static int gNumSimThreads
how many threads to use for simulation
Definition: MSGlobals.h:133
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:85
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:72
static int gNumThreads
how many threads to use
Definition: MSGlobals.h:136
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.
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:565
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:92
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the lane's maximum speed, given a vehicle's speed limit adaptation.
Definition: MSLane.h:519
int getIndex() const
Returns the lane's index.
Definition: MSLane.h:563
double getBruttoOccupancy() const
Returns the brutto (including minGaps) occupancy of this lane during the last step.
Definition: MSLane.cpp:2788
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:1991
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:674
int numSublanes() const
Definition: MSLeaderInfo.h:85
The simulated network and simulation perfomer.
Definition: MSNet.h:88
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:174
bool hasJunctionHigherSpeeds() const
return whether the network was built with higher junction speeds
Definition: MSNet.h:773
const std::map< SUMOVehicleClass, double > * getRestrictions(const std::string &id) const
Returns the restrictions for an edge type If no restrictions are present, 0 is returned.
Definition: MSNet.cpp:340
void addRestriction(const std::string &id, const SUMOVehicleClass svc, const double speed)
Adds a restriction for an edge type.
Definition: MSNet.cpp:334
const MESegment::MesoEdgeType & getMesoType(const std::string &typeID)
Returns edge type specific meso parameters if no type specific parameters have been loaded,...
Definition: MSNet.cpp:354
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:75
void updateBestLanes(bool forceRebuild=false, const MSLane *startLane=0)
computes the best lanes to use in order to continue the route
Definition: MSVehicle.cpp:5069
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:5063
double getPositionOnLane() const
Get the vehicle's position along the lane.
Definition: MSVehicle.h:372
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 getLength() const
Get vehicle's length [m].
double computeChosenSpeedDeviation(SumoRNG *rng, const double minDev=-1.) const
Computes and returns the speed deviation.
Base class for objects which have an id.
Definition: Named.h:54
const std::string & getID() const
Returns the id.
Definition: Named.h:74
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
static const T & getRandomFrom(const std::vector< T > &v, SumoRNG *rng=nullptr)
Returns a random element from the given vector.
Definition: RandHelper.h:208
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
Definition: RandHelper.h:119
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:60
virtual int getRouteValidity(bool update=true, bool silent=false, std::string *msgReturn=nullptr)=0
computes validity attributes for the current route
virtual void setChosenSpeedFactor(const double factor)=0
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.
bool wasSet(int what) const
Returns whether the given parameter was set.
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
A scoped lock which only triggers on condition.
Definition: ScopedLocker.h:40
std::vector< std::string > getVector()
return vector of strings
edge type specific meso parameters
Definition: MESegment.h:55