Eclipse SUMO - Simulation of Urban MObility
MESegment.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2001-2024 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 /****************************************************************************/
18 // A single mesoscopic segment (cell)
19 /****************************************************************************/
20 #include <config.h>
21 
22 #include <algorithm>
23 #include <limits>
24 #include <utils/common/StdDefs.h>
25 #include <microsim/MSGlobals.h>
26 #include <microsim/MSEdge.h>
27 #include <microsim/MSJunction.h>
28 #include <microsim/MSNet.h>
29 #include <microsim/MSLane.h>
30 #include <microsim/MSLink.h>
39 #include "MEVehicle.h"
40 #include "MELoop.h"
41 #include "MESegment.h"
42 
43 #define DEFAULT_VEH_LENGTH_WITH_GAP (SUMOVTypeParameter::getDefault().length + SUMOVTypeParameter::getDefault().minGap)
44 // avoid division by zero when driving very slowly
45 #define MESO_MIN_SPEED (0.05)
46 
47 //#define DEBUG_OPENED
48 //#define DEBUG_JAMTHRESHOLD
49 //#define DEBUG_COND (getID() == "blocker")
50 //#define DEBUG_COND (true)
51 #define DEBUG_COND (myEdge.isSelected())
52 #define DEBUG_COND2(obj) ((obj != 0 && (obj)->isSelected()))
53 
54 
55 // ===========================================================================
56 // static member definition
57 // ===========================================================================
58 MSEdge MESegment::myDummyParent("MESegmentDummyParent", -1, SumoXMLEdgeFunc::UNKNOWN, "", "", -1, 0);
59 MESegment MESegment::myVaporizationTarget("vaporizationTarget");
60 const double MESegment::DO_NOT_PATCH_JAM_THRESHOLD(std::numeric_limits<double>::max());
61 
62 
63 // ===========================================================================
64 // MESegment::Queue method definitions
65 // ===========================================================================
66 MEVehicle*
69  assert(std::find(myVehicles.begin(), myVehicles.end(), v) != myVehicles.end());
70  if (v == myVehicles.back()) {
71  myVehicles.pop_back();
72  if (myVehicles.empty()) {
73  myOccupancy = 0.;
74  } else {
75  return myVehicles.back();
76  }
77  } else {
78  myVehicles.erase(std::find(myVehicles.begin(), myVehicles.end(), v));
79  }
80  return nullptr;
81 }
82 
83 void
85  myDetectorData.push_back(data);
86  for (MEVehicle* const v : myVehicles) {
87  v->addReminder(data);
88  }
89 }
90 
91 void
93  for (MSMoveReminder* rem : myDetectorData) {
94  veh->addReminder(rem);
95  }
96 }
97 
98 // ===========================================================================
99 // MESegment method definitions
100 // ===========================================================================
101 MESegment::MESegment(const std::string& id,
102  const MSEdge& parent, MESegment* next,
103  const double length, const double speed,
104  const int idx,
105  const bool multiQueue,
106  const MesoEdgeType& edgeType):
107  Named(id), myEdge(parent), myNextSegment(next),
108  myLength(length), myIndex(idx),
110  myNumVehicles(0),
112  myMeanSpeed(speed),
114 
115  const std::vector<MSLane*>& lanes = parent.getLanes();
116  int usableLanes = 0;
117  for (MSLane* const l : lanes) {
118  const SVCPermissions allow = MSEdge::getMesoPermissions(l->getPermissions());
119  if (multiQueue) {
120  myQueues.push_back(Queue(allow));
121  }
122  if (allow != 0) {
123  usableLanes++;
124  }
125  }
126  if (multiQueue) {
127  if (next == nullptr) {
128  for (const MSEdge* const edge : parent.getSuccessors()) {
129  const std::vector<MSLane*>* const allowed = parent.allowedLanes(*edge);
130  assert(allowed != nullptr);
131  assert(allowed->size() > 0);
132  for (MSLane* const l : *allowed) {
133  std::vector<MSLane*>::const_iterator it = std::find(lanes.begin(), lanes.end(), l);
134  myFollowerMap[edge] |= (1 << distance(lanes.begin(), it));
135  }
136  }
137  }
138  myQueueCapacity = length;
139  } else {
140  myQueues.push_back(Queue(parent.getPermissions()));
141  }
142 
143  initSegment(edgeType, parent, length * usableLanes);
144 }
145 
146 void
147 MESegment::initSegment(const MesoEdgeType& edgeType, const MSEdge& parent, const double capacity) {
148 
149  myCapacity = capacity;
150  if (myQueues.size() == 1) {
151  const double laneScale = capacity / myLength;
152  myQueueCapacity = capacity;
154  // Eissfeldt p. 90 and 151 ff.
155  myTau_ff = (SUMOTime)((double)edgeType.tauff / laneScale);
156  myTau_fj = (SUMOTime)((double)edgeType.taufj / laneScale);
157  myTau_jf = (SUMOTime)((double)edgeType.taujf / laneScale);
158  myTau_jj = (SUMOTime)((double)edgeType.taujj / laneScale);
159  } else {
160  myTau_ff = edgeType.tauff;
161  myTau_fj = edgeType.taufj;
162  myTau_jf = edgeType.taujf;
163  myTau_jj = edgeType.taujj;
164  }
165 
166  myJunctionControl = myNextSegment == nullptr && (edgeType.junctionControl || MELoop::isEnteringRoundabout(parent));
167  myTLSPenalty = ((edgeType.tlsPenalty > 0 || edgeType.tlsFlowPenalty > 0) &&
168  // only apply to the last segment of a tls-controlled edge
169  myNextSegment == nullptr && (
173 
174  // only apply to the last segment of an uncontrolled edge that has at least 1 minor link
175  myCheckMinorPenalty = (edgeType.minorPenalty > 0 &&
176  myNextSegment == nullptr &&
180  parent.hasMinorLink());
181  myMinorPenalty = edgeType.minorPenalty;
182  myOvertaking = edgeType.overtaking && myCapacity > myLength;
183 
184  //std::cout << getID() << " myMinorPenalty=" << myMinorPenalty << " myTLSPenalty=" << myTLSPenalty << " myJunctionControl=" << myJunctionControl << " myOvertaking=" << myOvertaking << "\n";
185 
187 }
188 
189 MESegment::MESegment(const std::string& id):
190  Named(id),
191  myEdge(myDummyParent), // arbitrary edge needed to supply the needed reference
192  myNextSegment(nullptr), myLength(0), myIndex(0),
193  myTau_ff(0), myTau_fj(0), myTau_jf(0), myTau_jj(0),
194  myTLSPenalty(false),
195  myCheckMinorPenalty(false),
196  myMinorPenalty(0),
197  myJunctionControl(false),
198  myOvertaking(false),
199  myTau_length(1) {
200 }
201 
202 
203 void
205  if (myQueues.size() > 1) {
206  for (MSLane* lane : myEdge.getLanes()) {
207  myQueues[lane->getIndex()].setPermissions(lane->getPermissions());
208  }
209  } else {
210  myQueues.back().setPermissions(myEdge.getPermissions());
211  }
212 }
213 
214 
215 void
217  if (jamThresh == DO_NOT_PATCH_JAM_THRESHOLD) {
218  return;
219  }
220  if (jamThresh < 0) {
221  // compute based on speed
223  } else {
224  // compute based on specified percentage
225  myJamThreshold = jamThresh * myCapacity;
226  }
227 }
228 
229 
230 double
231 MESegment::jamThresholdForSpeed(double speed, double jamThresh) const {
232  // vehicles driving freely at maximum speed should not jam
233  // we compute how many vehicles could possible enter the segment until the first vehicle leaves
234  // and multiply by the space these vehicles would occupy
235  // the jamThresh parameter is scale the resulting value
236  if (speed == 0) {
237  return std::numeric_limits<double>::max(); // never jam. Irrelevant at speed 0 anyway
238  }
239 #ifdef DEBUG_JAMTHRESHOLD
240  if (true || DEBUG_COND) {
241  std::cout << "jamThresholdForSpeed seg=" << getID() << " speed=" << speed << " jamThresh=" << jamThresh << " ffVehs=" << std::ceil(myLength / (-jamThresh * speed * STEPS2TIME(tauWithVehLength(myTau_ff, DEFAULT_VEH_LENGTH_WITH_GAP)))) << " thresh=" << std::ceil(myLength / (-jamThresh * speed * STEPS2TIME(tauWithVehLength(myTau_ff, DEFAULT_VEH_LENGTH_WITH_GAP)))) * DEFAULT_VEH_LENGTH_WITH_GAP
242  << "\n";
243  }
244 #endif
245  return std::ceil(myLength / (-jamThresh * speed * STEPS2TIME(tauWithVehLength(myTau_ff, DEFAULT_VEH_LENGTH_WITH_GAP, 1.)))) * DEFAULT_VEH_LENGTH_WITH_GAP;
246 }
247 
248 
249 void
250 MESegment::addDetector(MSMoveReminder* data, int queueIndex) {
251  if (queueIndex == -1) {
252  for (Queue& q : myQueues) {
253  q.addDetector(data);
254  }
255  } else {
256  assert(queueIndex < (int)myQueues.size());
257  myQueues[queueIndex].addDetector(data);
258  }
259 }
260 
261 
262 /*
263 void
264 MESegment::removeDetector(MSMoveReminder* data) {
265  std::vector<MSMoveReminder*>::iterator it = std::find(myDetectorData.begin(), myDetectorData.end(), data);
266  if (it != myDetectorData.end()) {
267  myDetectorData.erase(it);
268  }
269  for (const Queue& q : myQueues) {
270  for (MEVehicle* const v : q.getVehicles()) {
271  v->removeReminder(data);
272  }
273  }
274 }
275 */
276 
277 
278 void
280  const SUMOTime currentTime = MSNet::getInstance()->getCurrentTimeStep();
281  if (queueIndex == -1) {
282  for (const Queue& q : myQueues) {
283  SUMOTime earliestExitTime = currentTime;
284  for (std::vector<MEVehicle*>::const_reverse_iterator i = q.getVehicles().rbegin(); i != q.getVehicles().rend(); ++i) {
285  const SUMOTime exitTime = MAX2(earliestExitTime, (*i)->getEventTime());
286  (*i)->updateDetectorForWriting(&data, currentTime, exitTime);
287  earliestExitTime = exitTime + tauWithVehLength(myTau_ff, (*i)->getVehicleType().getLengthWithGap(), (*i)->getVehicleType().getCarFollowModel().getHeadwayTime());
288  }
289  }
290  } else {
291  SUMOTime earliestExitTime = currentTime;
292  for (std::vector<MEVehicle*>::const_reverse_iterator i = myQueues[queueIndex].getVehicles().rbegin(); i != myQueues[queueIndex].getVehicles().rend(); ++i) {
293  const SUMOTime exitTime = MAX2(earliestExitTime, (*i)->getEventTime());
294  (*i)->updateDetectorForWriting(&data, currentTime, exitTime);
295  earliestExitTime = exitTime + tauWithVehLength(myTau_ff, (*i)->getVehicleType().getLengthWithGap(), (*i)->getVehicleType().getCarFollowModel().getHeadwayTime());
296  }
297  }
298 }
299 
300 
301 SUMOTime
302 MESegment::hasSpaceFor(const MEVehicle* const veh, const SUMOTime entryTime, int& qIdx, const bool init) const {
303  SUMOTime earliestEntry = SUMOTime_MAX;
304  qIdx = 0;
305  if (myNumVehicles == 0 && myQueues.size() == 1) {
306  // we have always space for at least one vehicle
307  if (myQueues.front().allows(veh->getVClass())) {
308  return entryTime;
309  } else {
310  return earliestEntry;
311  }
312  }
313  const SUMOVehicleClass svc = veh->getVClass();
314  int minSize = std::numeric_limits<int>::max();
315  const MSEdge* const succ = myNextSegment == nullptr ? veh->succEdge(1) : nullptr;
316  for (int i = 0; i < (int)myQueues.size(); i++) {
317  const Queue& q = myQueues[i];
318  const double newOccupancy = q.size() == 0 ? 0. : q.getOccupancy() + veh->getVehicleType().getLengthWithGap();
319  if (newOccupancy <= myQueueCapacity) { // we must ensure that occupancy remains below capacity
320  if (succ == nullptr || myFollowerMap.count(succ) == 0 || ((myFollowerMap.find(succ)->second & (1 << i)) != 0)) {
321  if (q.allows(svc) && q.size() < minSize) {
322  if (init) {
323  // regular insertions and initial insertions must respect different constraints:
324  // - regular insertions must respect entryBlockTime
325  // - initial insertions should not cause additional jamming
326  // - inserted vehicle should be able to continue at the current speed
328  if (newOccupancy <= myJamThreshold) {
329  qIdx = i;
330  minSize = q.size();
331  }
332  } else {
333  if (newOccupancy <= jamThresholdForSpeed(getMeanSpeed(false), -1)) {
334  qIdx = i;
335  minSize = q.size();
336  }
337  }
338  } else if (entryTime >= q.getEntryBlockTime()) {
339  qIdx = i;
340  minSize = q.size();
341  } else {
342  earliestEntry = MIN2(earliestEntry, q.getEntryBlockTime());
343  }
344  }
345  }
346  }
347  }
348  if (minSize == std::numeric_limits<int>::max()) {
349  return earliestEntry;
350  }
351  return entryTime;
352 }
353 
354 
355 bool
357  int qIdx = 0;
358  if (hasSpaceFor(veh, time, qIdx, true) == time) {
359  receive(veh, qIdx, time, true);
360  // we can check only after insertion because insertion may change the route via devices
361  std::string msg;
362  if (MSGlobals::gCheckRoutes && !veh->hasValidRoute(msg)) {
363  throw ProcessError("Vehicle '" + veh->getID() + "' has no valid route. " + msg);
364  }
365  return true;
366  }
367  return false;
368 }
369 
370 
371 double
372 MESegment::getMeanSpeed(bool useCached) const {
373  const SUMOTime currentTime = MSNet::getInstance()->getCurrentTimeStep();
374  if (currentTime != myLastMeanSpeedUpdate || !useCached) {
375  myLastMeanSpeedUpdate = currentTime;
376  double v = 0;
377  int count = 0;
378  for (const Queue& q : myQueues) {
379  const SUMOTime tau = q.getOccupancy() < myJamThreshold ? myTau_ff : myTau_jf;
380  SUMOTime earliestExitTime = currentTime;
381  count += q.size();
382  for (std::vector<MEVehicle*>::const_reverse_iterator veh = q.getVehicles().rbegin(); veh != q.getVehicles().rend(); ++veh) {
383  v += (*veh)->getConservativeSpeed(earliestExitTime); // earliestExitTime is updated!
384  earliestExitTime += tauWithVehLength(tau, (*veh)->getVehicleType().getLengthWithGap(), (*veh)->getVehicleType().getCarFollowModel().getHeadwayTime());
385  }
386  }
387  if (count == 0) {
389  } else {
390  myMeanSpeed = v / (double) count;
391  }
392  }
393  return myMeanSpeed;
394 }
395 
396 
397 void
399  for (const Queue& q : myQueues) {
400  for (const MEVehicle* const veh : q.getVehicles()) {
401  MSXMLRawOut::writeVehicle(of, *veh);
402  }
403  }
404 }
405 
406 
407 MEVehicle*
409  Queue& q = myQueues[v->getQueIndex()];
410  // One could be tempted to do v->setSegment(next); here but position on lane will be invalid if next == 0
411  v->updateDetectors(leaveTime, true, reason);
412  myNumVehicles--;
413  myEdge.lock();
414  MEVehicle* nextLeader = q.remove(v);
415  myEdge.unlock();
416  return nextLeader;
417 }
418 
419 
420 SUMOTime
422  // since we do not know which queue will be used we give a conservative estimate
423  SUMOTime earliestLeave = earliestEntry;
424  SUMOTime latestEntry = -1;
425  for (const Queue& q : myQueues) {
426  earliestLeave = MAX2(earliestLeave, q.getBlockTime());
427  latestEntry = MAX2(latestEntry, q.getEntryBlockTime());
428  }
429  if (myEdge.getSpeedLimit() == 0) {
430  return MAX2(earliestEntry, latestEntry); // FIXME: This line is just an adhoc-fix to avoid division by zero (Leo)
431  } else {
432  return MAX3(earliestEntry, earliestLeave - TIME2STEPS(myLength / myEdge.getSpeedLimit()), latestEntry);
433  }
434 }
435 
436 
437 MSLink*
438 MESegment::getLink(const MEVehicle* veh, bool penalty) const {
439  if (myJunctionControl || penalty) {
440  const MSEdge* const nextEdge = veh->succEdge(1);
441  if (nextEdge == nullptr || veh->getQueIndex() == PARKING_QUEUE) {
442  return nullptr;
443  }
444  // try to find any link leading to our next edge, start with the lane pointed to by the que index
445  const MSLane* const bestLane = myEdge.getLanes()[veh->getQueIndex()];
446  for (MSLink* const link : bestLane->getLinkCont()) {
447  if (&link->getLane()->getEdge() == nextEdge) {
448  return link;
449  }
450  }
451  // this is for the non-multique case, maybe we should use caching here !!!
452  for (const MSLane* const lane : myEdge.getLanes()) {
453  if (lane != bestLane) {
454  for (MSLink* const link : lane->getLinkCont()) {
455  if (&link->getLane()->getEdge() == nextEdge) {
456  return link;
457  }
458  }
459  }
460  }
461  }
462  return nullptr;
463 }
464 
465 
466 bool
467 MESegment::isOpen(const MEVehicle* veh) const {
468 #ifdef DEBUG_OPENED
469  if (DEBUG_COND || DEBUG_COND2(veh)) {
470  gDebugFlag1 = true;
471  std::cout << SIMTIME << " opened seg=" << getID() << " veh=" << Named::getIDSecure(veh)
472  << " tlsPenalty=" << myTLSPenalty;
473  const MSLink* link = getLink(veh);
474  if (link == 0) {
475  std::cout << " link=0";
476  } else {
477  std::cout << " prio=" << link->havePriority()
478  << " override=" << limitedControlOverride(link)
479  << " isOpen=" << link->opened(veh->getEventTime(), veh->getSpeed(), veh->estimateLeaveSpeed(link),
482  << " et=" << veh->getEventTime()
483  << " v=" << veh->getSpeed()
484  << " vLeave=" << veh->estimateLeaveSpeed(link)
485  << " impatience=" << veh->getImpatience()
486  << " tWait=" << veh->getWaitingTime();
487  }
488  std::cout << "\n";
489  gDebugFlag1 = false;
490  }
491 #endif
492  if (myTLSPenalty) {
493  // XXX should limited control take precedence over tls penalty?
494  return true;
495  }
496  const MSLink* link = getLink(veh);
497  return (link == nullptr
498  || link->havePriority()
499  || limitedControlOverride(link)
500  || link->opened(veh->getEventTime(), veh->getSpeed(), veh->estimateLeaveSpeed(link),
503 }
504 
505 
506 bool
508  assert(link != nullptr);
510  return false;
511  }
512  // if the target segment of this link is not saturated junction control is disabled
513  const MSEdge& targetEdge = link->getLane()->getEdge();
514  const MESegment* target = MSGlobals::gMesoNet->getSegmentForEdge(targetEdge);
515  return (target->getBruttoOccupancy() * 2 < target->myJamThreshold) && !targetEdge.isRoundabout();
516 }
517 
518 
519 void
520 MESegment::send(MEVehicle* veh, MESegment* const next, const int nextQIdx, SUMOTime time, const MSMoveReminder::Notification reason) {
521  Queue& q = myQueues[veh->getQueIndex()];
522  assert(isInvalid(next) || time >= q.getBlockTime());
523  MSLink* const link = getLink(veh);
524  if (link != nullptr) {
525  link->removeApproaching(veh);
526  }
527  if (veh->isStopped()) {
528  veh->processStop();
529  }
530  MEVehicle* lc = removeCar(veh, time, reason); // new leaderCar
531  q.setBlockTime(time);
532  if (!isInvalid(next)) {
533  const bool nextFree = next->myQueues[nextQIdx].getOccupancy() <= next->myJamThreshold;
534  const SUMOTime tau = (q.getOccupancy() <= myJamThreshold
535  ? (nextFree ? myTau_ff : myTau_fj)
536  : (nextFree ? myTau_jf : getTauJJ((double)next->myQueues[nextQIdx].size(), next->myQueueCapacity, next->myJamThreshold)));
537  assert(tau >= 0);
539  if (myTLSPenalty) {
540  const MSLink* const tllink = getLink(veh, true);
541  if (tllink != nullptr && tllink->isTLSControlled()) {
542  assert(tllink->getGreenFraction() > 0);
543  myLastHeadway = (SUMOTime)((double)myLastHeadway / tllink->getGreenFraction());
544  }
545  }
547  }
548  if (lc != nullptr) {
549  lc->setEventTime(MAX2(lc->getEventTime(), q.getBlockTime()));
551  }
552 }
553 
554 SUMOTime
555 MESegment::getTauJJ(double nextQueueSize, double nextQueueCapacity, double nextJamThreshold) const {
556  // compute coefficients for the jam-jam headway function
557  // this function models the effect that "empty space" needs to move
558  // backwards through the downstream segment before the upstream segment may
559  // send annother vehicle.
560  // this allows jams to clear and move upstream.
561  // the headway function f(x) depends on the number of vehicles in the
562  // downstream segment x
563  // f is a linear function that passes through the following fixed points:
564  // f(n_jam_threshold) = tau_jf_withLength (for continuity)
565  // f(headwayCapacity) = myTau_jj * headwayCapacity
566 
567  const SUMOTime tau_jf_withLength = tauWithVehLength(myTau_jf, DEFAULT_VEH_LENGTH_WITH_GAP, 1.);
568  // number of vehicles that fit into the NEXT queue (could be larger than expected with DEFAULT_VEH_LENGTH_WITH_GAP!)
569  const double headwayCapacity = MAX2(nextQueueSize, nextQueueCapacity / DEFAULT_VEH_LENGTH_WITH_GAP);
570  // number of vehicles above which the NEXT queue is jammed
571  const double n_jam_threshold = headwayCapacity * nextJamThreshold / nextQueueCapacity;
572 
573  // slope a and axis offset b for the jam-jam headway function
574  // solving f(x) = a * x + b
575  const double a = (STEPS2TIME(myTau_jj) * headwayCapacity - STEPS2TIME(tau_jf_withLength)) / (headwayCapacity - n_jam_threshold);
576  const double b = headwayCapacity * (STEPS2TIME(myTau_jj) - a);
577 
578  // it is only well defined for nextQueueSize >= n_jam_threshold (which may not be the case for longer vehicles), so we take the MAX
579  return TIME2STEPS(a * MAX2(nextQueueSize, n_jam_threshold) + b);
580 }
581 
582 
583 bool
586 }
587 
588 
589 void
591  if (veh->getQueIndex() != PARKING_QUEUE) {
592  myQueues[veh->getQueIndex()].addReminders(veh);
593  }
594 }
595 
596 
597 void
598 MESegment::receive(MEVehicle* veh, const int qIdx, SUMOTime time, const bool isDepart, const bool isTeleport, const bool newEdge) {
599  const double speed = isDepart ? -1 : MAX2(veh->getSpeed(), MESO_MIN_SPEED); // on the previous segment
600  veh->setSegment(this); // for arrival checking
601  veh->setLastEntryTime(time);
603  if (!isDepart && (
604  // arrival on entering a new edge
605  (newEdge && veh->moveRoutePointer())
606  // arrival on entering a new segment
607  || veh->hasArrived())) {
608  // route has ended
609  veh->setEventTime(time + TIME2STEPS(myLength / speed)); // for correct arrival speed
610  addReminders(veh);
612  veh->updateDetectors(time, true,
615  return;
616  }
617  assert(veh->getEdge() == &getEdge());
618  // route continues
619  Queue& q = myQueues[qIdx];
620  const double maxSpeedOnEdge = veh->getEdge()->getLanes()[qIdx]->getVehicleMaxSpeed(veh);
621  const double uspeed = MAX2(maxSpeedOnEdge, MESO_MIN_SPEED);
622  std::vector<MEVehicle*>& cars = q.getModifiableVehicles();
623  MEVehicle* newLeader = nullptr; // first vehicle in the current queue
624  const SUMOTime stopTime = veh->checkStop(time);
625  SUMOTime tleave = MAX2(stopTime + TIME2STEPS(myLength / uspeed) + getLinkPenalty(veh), q.getBlockTime());
626  if (veh->isStopped()) {
627  myEdge.addWaiting(veh);
628  }
629  if (veh->isParking()) {
630  veh->setEventTime(stopTime);
631  veh->setSegment(this, PARKING_QUEUE);
632  myEdge.getLanes()[0]->addParking(veh); // TODO for GUI only
633  } else {
634  myEdge.lock();
635  if (cars.empty()) {
636  cars.push_back(veh);
637  newLeader = veh;
638  } else {
639  SUMOTime leaderOut = cars[0]->getEventTime();
640  if (!isDepart && leaderOut > tleave && overtake()) {
641  if (cars.size() == 1) {
643  newLeader = veh;
644  }
645  cars.insert(cars.begin() + 1, veh);
646  } else {
647  tleave = MAX2(leaderOut + tauWithVehLength(myTau_ff, cars[0]->getVehicleType().getLengthWithGap(), cars[0]->getVehicleType().getCarFollowModel().getHeadwayTime()), tleave);
648  cars.insert(cars.begin(), veh);
649  }
650  }
651  myEdge.unlock();
652  myNumVehicles++;
653  if (!isDepart && !isTeleport) {
654  // departs and teleports could take place anywhere on the edge so they should not block regular flow
655  // the -1 facilitates interleaving of multiple streams
657  }
659  veh->setEventTime(tleave);
660  veh->setSegment(this, qIdx);
661  }
662  addReminders(veh);
663  if (isDepart) {
664  veh->onDepart();
666  } else if (newEdge) {
668  } else {
670  }
671  if (veh->isParking()) {
672  MSGlobals::gMesoNet->addLeaderCar(veh, nullptr);
673  } else {
674  if (newLeader != nullptr) {
675  MSGlobals::gMesoNet->addLeaderCar(newLeader, getLink(newLeader));
676  }
677  }
678 }
679 
680 
681 bool
683  for (const Queue& q : myQueues) {
684  if (q.size() > 0) {
685  for (MEVehicle* const veh : q.getVehicles()) {
686  if (filter->vehicleApplies(*veh)) {
689  return true;
690  }
691  }
692  }
693  }
694  return false;
695 }
696 
697 
698 void
699 MESegment::setSpeedForQueue(double newSpeed, SUMOTime currentTime, SUMOTime blockTime, const std::vector<MEVehicle*>& vehs) {
700  MEVehicle* v = vehs.back();
701  v->updateDetectors(currentTime, false);
702  SUMOTime newEvent = MAX2(newArrival(v, newSpeed, currentTime), blockTime);
703  if (v->getEventTime() != newEvent) {
705  v->setEventTime(newEvent);
707  }
708  for (std::vector<MEVehicle*>::const_reverse_iterator i = vehs.rbegin() + 1; i != vehs.rend(); ++i) {
709  (*i)->updateDetectors(currentTime, false);
710  newEvent = MAX2(newArrival(*i, newSpeed, currentTime), newEvent + myTau_ff);
711  //newEvent = MAX2(newArrival(*i, newSpeed, currentTime), newEvent + myTau_ff + (SUMOTime)((*(i - 1))->getVehicleType().getLength() / myTau_length));
712  (*i)->setEventTime(newEvent);
713  }
714 }
715 
716 
717 SUMOTime
718 MESegment::newArrival(const MEVehicle* const v, double newSpeed, SUMOTime currentTime) {
719  // since speed is only an upper bound pos may be to optimistic
720  const double pos = MIN2(myLength, STEPS2TIME(currentTime - v->getLastEntryTime()) * v->getSpeed());
721  // traveltime may not be 0
722  double tt = (myLength - pos) / MAX2(newSpeed, MESO_MIN_SPEED);
723  return currentTime + MAX2(TIME2STEPS(tt), SUMOTime(1));
724 }
725 
726 
727 void
728 MESegment::setSpeed(double newSpeed, SUMOTime currentTime, double jamThresh, int qIdx) {
729  recomputeJamThreshold(jamThresh);
730  //myTau_length = MAX2(MESO_MIN_SPEED, newSpeed) * myEdge.getLanes().size() / TIME2STEPS(1);
731  int i = 0;
732  for (const Queue& q : myQueues) {
733  if (q.size() != 0) {
734  if (qIdx == -1 || qIdx == i) {
735  setSpeedForQueue(newSpeed, currentTime, q.getBlockTime(), q.getVehicles());
736  }
737  }
738  i++;
739  }
740 }
741 
742 
743 SUMOTime
745  SUMOTime result = SUMOTime_MAX;
746  for (const Queue& q : myQueues) {
747  if (q.size() != 0 && q.getVehicles().back()->getEventTime() < result) {
748  result = q.getVehicles().back()->getEventTime();
749  }
750  }
751  if (result < SUMOTime_MAX) {
752  return result;
753  }
754  return -1;
755 }
756 
757 
758 void
760  bool write = false;
761  for (const Queue& q : myQueues) {
762  if (q.getBlockTime() != -1 || !q.getVehicles().empty()) {
763  write = true;
764  break;
765  }
766  }
767  if (write) {
769  for (const Queue& q : myQueues) {
770  out.openTag(SUMO_TAG_VIEWSETTINGS_VEHICLES).writeAttr(SUMO_ATTR_TIME, toString<SUMOTime>(q.getBlockTime()));
771  out.writeAttr(SUMO_ATTR_VALUE, q.getVehicles());
772  out.closeTag();
773  }
774  out.closeTag();
775  }
776 }
777 
778 
779 void
781  for (Queue& q : myQueues) {
782  q.getModifiableVehicles().clear();
783  }
784 }
785 
786 void
787 MESegment::loadState(const std::vector<std::string>& vehIds, MSVehicleControl& vc, const SUMOTime block, const int queIdx) {
788  Queue& q = myQueues[queIdx];
789  for (const std::string& id : vehIds) {
790  MEVehicle* v = static_cast<MEVehicle*>(vc.getVehicle(id));
791  // vehicle could be removed due to options
792  if (v != nullptr) {
793  assert(v->getSegment() == this);
794  q.getModifiableVehicles().push_back(v);
795  myNumVehicles++;
797  }
798  }
799  if (q.size() != 0) {
800  // add the last vehicle of this queue
801  // !!! one question - what about the previously added vehicle? Is it stored twice?
802  MEVehicle* veh = q.getVehicles().back();
804  }
805  q.setBlockTime(block);
807 }
808 
809 
810 std::vector<const MEVehicle*>
812  std::vector<const MEVehicle*> result;
813  for (const Queue& q : myQueues) {
814  result.insert(result.end(), q.getVehicles().begin(), q.getVehicles().end());
815  }
816  return result;
817 }
818 
819 
820 bool
822  for (const Queue& q : myQueues) {
823  if (q.size() > 0 && q.getVehicles().back()->getWaitingTime() > 0) {
824  return true;
825  }
826  }
827  return false;
828 }
829 
830 
831 double
833  return 3600 * getCarNumber() * getMeanSpeed() / myLength;
834 }
835 
836 
837 SUMOTime
839  const MSLink* link = getLink(veh, myTLSPenalty || myCheckMinorPenalty);
840  if (link != nullptr) {
841  SUMOTime result = 0;
842  if (link->isTLSControlled()) {
843  result += link->getMesoTLSPenalty();
844  }
845  // minor tls links may get an additional penalty
846  if (!link->havePriority() &&
847  // do not apply penalty on top of tLSPenalty
848  !myTLSPenalty &&
849  // do not apply penalty if limited control is active
851  result += myMinorPenalty;
852  }
853  return result;
854  } else {
855  return 0;
856  }
857 }
858 
859 
860 double
862  double result = 0;
863  for (const Queue& q : myQueues) {
864  // @note: only the leader currently accumulates waitingTime but this might change in the future
865  for (const MEVehicle* veh : q.getVehicles()) {
866  result += veh->getWaitingSeconds();
867  }
868  }
869  return result;
870 }
871 
872 
873 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
#define MESO_MIN_SPEED
Definition: MESegment.cpp:45
#define DEFAULT_VEH_LENGTH_WITH_GAP
Definition: MESegment.cpp:43
#define DEBUG_COND
Definition: MESegment.cpp:51
#define DEBUG_COND2(obj)
Definition: MESegment.cpp:52
#define STEPS2TIME(x)
Definition: SUMOTime.h:55
#define SUMOTime_MAX
Definition: SUMOTime.h:34
#define SUMOTime_MIN
Definition: SUMOTime.h:35
#define SIMTIME
Definition: SUMOTime.h:62
#define TIME2STEPS(x)
Definition: SUMOTime.h:57
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SUMO_TAG_VIEWSETTINGS_VEHICLES
@ SUMO_TAG_SEGMENT
segment of a lane
@ SUMO_ATTR_VALUE
@ SUMO_ATTR_ID
@ SUMO_ATTR_TIME
trigger: the time of the step
bool gDebugFlag1
global utility flags for debugging
Definition: StdDefs.cpp:35
T MIN2(T a, T b)
Definition: StdDefs.h:76
T MAX2(T a, T b)
Definition: StdDefs.h:82
T MAX3(T a, T b, T c)
Definition: StdDefs.h:96
static bool isEnteringRoundabout(const MSEdge &e)
whether the given edge is entering a roundabout
Definition: MELoop.cpp:342
SUMOTime changeSegment(MEVehicle *veh, SUMOTime leaveTime, MESegment *const toSegment, MSMoveReminder::Notification reason, const bool ignoreLink=false) const
change to the next segment this handles combinations of the following cases: (ending / continuing rou...
Definition: MELoop.cpp:79
MESegment * getSegmentForEdge(const MSEdge &e, double pos=0)
Get the segment for a given edge at a given position.
Definition: MELoop.cpp:325
bool removeLeaderCar(MEVehicle *v)
Removes the given car from the leading vehicles.
Definition: MELoop.cpp:236
void addLeaderCar(MEVehicle *veh, MSLink *link)
Adds the given car to the leading vehicles.
Definition: MELoop.cpp:223
int size() const
Definition: MESegment.h:73
void setOccupancy(const double occ)
Definition: MESegment.h:86
MEVehicle * remove(MEVehicle *v)
Definition: MESegment.cpp:67
void setBlockTime(SUMOTime t)
Definition: MESegment.h:106
SUMOTime getBlockTime() const
Definition: MESegment.h:103
double myOccupancy
The occupied space (in m) in the queue.
Definition: MESegment.h:125
bool allows(SUMOVehicleClass vclass) const
Definition: MESegment.h:89
void addReminders(MEVehicle *veh) const
Definition: MESegment.cpp:92
void addDetector(MSMoveReminder *data)
Definition: MESegment.cpp:84
void setEntryBlockTime(SUMOTime entryBlockTime)
set the next time at which a vehicle may enter this queue
Definition: MESegment.h:99
double getOccupancy() const
Definition: MESegment.h:83
const std::vector< MEVehicle * > & getVehicles() const
Definition: MESegment.h:76
std::vector< MEVehicle * > myVehicles
Definition: MESegment.h:122
SUMOTime getEntryBlockTime() const
return the next time at which a vehicle may enter this queue
Definition: MESegment.h:94
std::vector< MEVehicle * > & getModifiableVehicles()
Definition: MESegment.h:80
A single mesoscopic segment (cell)
Definition: MESegment.h:49
void addReminders(MEVehicle *veh) const
add this lanes MoveReminders to the given vehicle
Definition: MESegment.cpp:590
double myQueueCapacity
The number of lanes represented by the queue * the length of the lane.
Definition: MESegment.h:553
bool overtake()
Definition: MESegment.cpp:584
SUMOTime tauWithVehLength(SUMOTime tau, double lengthWithGap, double vehicleTau) const
convert net time gap (leader back to follower front) to gross time gap (leader front to follower fron...
Definition: MESegment.h:507
SUMOTime myTau_ff
The time headway parameters, see the Eissfeldt thesis.
Definition: MESegment.h:530
bool initialise(MEVehicle *veh, SUMOTime time)
Inserts (emits) vehicle into the segment.
Definition: MESegment.cpp:356
std::vector< Queue > myQueues
The car queues. Vehicles are inserted in the front and removed in the back.
Definition: MESegment.h:559
double getBruttoOccupancy() const
Returns the occupany of the segment (the sum of the vehicle lengths + minGaps)
Definition: MESegment.h:258
SUMOTime myLastHeadway
the last headway
Definition: MESegment.h:568
static const int PARKING_QUEUE
Definition: MESegment.h:52
bool limitedControlOverride(const MSLink *link) const
whether the given link may be passed because the option meso-junction-control.limited is set
Definition: MESegment.cpp:507
bool isOpen(const MEVehicle *veh) const
Returns whether the vehicle may use the next link.
Definition: MESegment.cpp:467
void addDetector(MSMoveReminder *data, int queueIndex=-1)
Adds a data collector for a detector to this segment.
Definition: MESegment.cpp:250
void clearState()
Remove all vehicles before quick-loading state.
Definition: MESegment.cpp:780
void receive(MEVehicle *veh, const int qIdx, SUMOTime time, const bool isDepart=false, const bool isTeleport=false, const bool newEdge=false)
Adds the vehicle to the segment, adapting its parameters.
Definition: MESegment.cpp:598
SUMOTime getLinkPenalty(const MEVehicle *veh) const
Returns the penalty time for passing a link (if using gMesoTLSPenalty > 0 or gMesoMinorPenalty > 0)
Definition: MESegment.cpp:838
void writeVehicles(OutputDevice &of) const
Definition: MESegment.cpp:398
std::map< const MSEdge *, int > myFollowerMap
The follower edge to allowed que index mapping for multi queue segments.
Definition: MESegment.h:565
MSLink * getLink(const MEVehicle *veh, bool tlsPenalty=false) const
Returns the link the given car will use when passing the next junction.
Definition: MESegment.cpp:438
int myNumVehicles
The cached value for the number of vehicles.
Definition: MESegment.h:562
void setSpeedForQueue(double newSpeed, SUMOTime currentTime, SUMOTime blockTime, const std::vector< MEVehicle * > &vehs)
Definition: MESegment.cpp:699
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:302
void updatePermissions()
called when permissions change due to Rerouter or TraCI
Definition: MESegment.cpp:204
void saveState(OutputDevice &out) const
Saves the state of this segment into the given stream.
Definition: MESegment.cpp:759
void initSegment(const MesoEdgeType &edgeType, const MSEdge &parent, const double capacity)
set model parameters (may be updated from additional file after network loading is complete)
Definition: MESegment.cpp:147
static MESegment myVaporizationTarget
Definition: MESegment.h:573
double myJamThreshold
The space (in m) which needs to be occupied before the segment is considered jammed.
Definition: MESegment.h:556
const int myIndex
Running number of the segment in the edge.
Definition: MESegment.h:524
void send(MEVehicle *veh, MESegment *const next, const int nextQIdx, SUMOTime time, const MSMoveReminder::Notification reason)
Removes the vehicle from the segment, adapting its parameters.
Definition: MESegment.cpp:520
SUMOTime myMinorPenalty
Definition: MESegment.h:537
double myMeanSpeed
the mean speed on this segment. Updated at event time or on demand
Definition: MESegment.h:576
bool myCheckMinorPenalty
penalty for minor links
Definition: MESegment.h:536
double jamThresholdForSpeed(double speed, double jamThresh) const
compute jam threshold for the given speed and jam-threshold option
Definition: MESegment.cpp:231
SUMOTime myLastMeanSpeedUpdate
the time at which myMeanSpeed was last updated
Definition: MESegment.h:579
SUMOTime myTau_jf
Definition: MESegment.h:530
void setSpeed(double newSpeed, SUMOTime currentTime, double jamThresh=DO_NOT_PATCH_JAM_THRESHOLD, int qIdx=-1)
reset mySpeed and patch the speed of all vehicles in it. Also set/recompute myJamThreshold
Definition: MESegment.cpp:728
MESegment * myNextSegment
The next segment of this edge, 0 if this is the last segment of this edge.
Definition: MESegment.h:518
const MSEdge & getEdge() const
Returns the edge this segment belongs to.
Definition: MESegment.h:359
bool hasBlockedLeader() const
whether a leader in any queue is blocked
Definition: MESegment.cpp:821
double getWaitingSeconds() const
Get the waiting time for vehicles in all queues.
Definition: MESegment.cpp:861
const double myLength
The segment's length.
Definition: MESegment.h:521
SUMOTime getEventTime() const
Returns the (planned) time at which the next vehicle leaves this segment.
Definition: MESegment.cpp:744
const MSEdge & myEdge
The microsim edge this segment belongs to.
Definition: MESegment.h:515
MESegment(const std::string &id, const MSEdge &parent, MESegment *next, const double length, const double speed, const int idx, const bool multiQueue, const MesoEdgeType &edgeType)
constructor
Definition: MESegment.cpp:101
MEVehicle * removeCar(MEVehicle *v, SUMOTime leaveTime, const MSMoveReminder::Notification reason)
Removes the given car from the edge's que.
Definition: MESegment.cpp:408
std::vector< const MEVehicle * > getVehicles() const
returns all vehicles (for debugging)
Definition: MESegment.cpp:811
static MSEdge myDummyParent
Definition: MESegment.h:572
void recomputeJamThreshold(double jamThresh)
compute a value for myJamThreshold if jamThresh is negative, compute a value which allows free flow a...
Definition: MESegment.cpp:216
double getMeanSpeed() const
wrapper to satisfy the FunctionBinding signature
Definition: MESegment.h:294
int getCarNumber() const
Returns the total number of cars on the segment.
Definition: MESegment.h:206
void loadState(const std::vector< std::string > &vehIDs, MSVehicleControl &vc, const SUMOTime blockTime, const int queIdx)
Loads the state of this segment with the given parameters.
Definition: MESegment.cpp:787
double myTau_length
Headway parameter for computing gross time headyway from net time headway, length and edge speed.
Definition: MESegment.h:547
SUMOTime myTau_jj
Definition: MESegment.h:530
SUMOTime newArrival(const MEVehicle *const v, double newSpeed, SUMOTime currentTime)
compute the new arrival time when switching speed
Definition: MESegment.cpp:718
bool myJunctionControl
Whether junction control is enabled.
Definition: MESegment.h:540
bool myTLSPenalty
Whether tls penalty is enabled.
Definition: MESegment.h:533
static const double DO_NOT_PATCH_JAM_THRESHOLD
Definition: MESegment.h:51
double getFlow() const
returns flow based on headway
Definition: MESegment.cpp:832
static bool isInvalid(const MESegment *segment)
whether the given segment is 0 or encodes vaporization
Definition: MESegment.h:443
SUMOTime getNextInsertionTime(SUMOTime earliestEntry) const
return a time after earliestEntry at which a vehicle may be inserted at full speed
Definition: MESegment.cpp:421
double myCapacity
The number of lanes represented by the queue * the length of the lane.
Definition: MESegment.h:550
bool myOvertaking
Whether overtaking is permitted on this segment.
Definition: MESegment.h:543
void prepareDetectorForWriting(MSMoveReminder &data, int queueIndex=-1)
Removes a data collector for a detector from this segment.
Definition: MESegment.cpp:279
bool vaporizeAnyCar(SUMOTime currentTime, const MSDetectorFileOutput *filter)
tries to remove any car from this segment
Definition: MESegment.cpp:682
SUMOTime myTau_fj
Definition: MESegment.h:530
SUMOTime getTauJJ(double nextQueueSize, double nextQueueCapacity, double nextJamThreshold) const
Definition: MESegment.cpp:555
A vehicle from the mesoscopic point of view.
Definition: MEVehicle.h:42
double estimateLeaveSpeed(const MSLink *link) const
Returns the vehicle's estimated speed after driving accross the link.
Definition: MEVehicle.cpp:121
void processStop()
ends the current stop and performs loading/unloading
Definition: MEVehicle.cpp:316
SUMOTime getWaitingTime(const bool accumulated=false) const
Returns the duration for which the vehicle was blocked.
Definition: MEVehicle.h:271
bool hasArrived() const
Returns whether this vehicle has already arived (reached the arrivalPosition on its final edge)
Definition: MEVehicle.cpp:155
bool moveRoutePointer()
Update when the vehicle enters a new edge in the move step.
Definition: MEVehicle.cpp:137
SUMOTime checkStop(SUMOTime time)
Returns until when to stop at the current segment and sets the information that the stop has been rea...
Definition: MEVehicle.cpp:211
void updateDetectors(SUMOTime currentTime, const bool isLeave, const MSMoveReminder::Notification reason=MSMoveReminder::NOTIFICATION_JUNCTION)
Updates all vehicle detectors.
Definition: MEVehicle.cpp:441
SUMOTime getLastEntryTime() const
Returns the time the vehicle entered the current segment.
Definition: MEVehicle.h:248
void setEventTime(SUMOTime t, bool hasDelay=true)
Sets the (planned) time at which the vehicle leaves its current segment.
Definition: MEVehicle.h:188
MESegment * getSegment() const
Returns the current segment the vehicle is on.
Definition: MEVehicle.h:218
void setLastEntryTime(SUMOTime t)
Sets the entry time for the current segment.
Definition: MEVehicle.h:240
int getQueIndex() const
Returns the index of the que the vehicle is in.
Definition: MEVehicle.h:226
virtual void setSegment(MESegment *s, int idx=0)
Sets the current segment the vehicle is at together with its que.
Definition: MEVehicle.h:209
SUMOTime getEventTime() const
Returns the (planned) time at which the vehicle leaves its current segment.
Definition: MEVehicle.h:200
void setBlockTime(const SUMOTime t)
Sets the time at which the vehicle was blocked.
Definition: MEVehicle.h:256
double getSpeed() const
Returns the vehicle's estimated speed assuming no delays.
Definition: MEVehicle.cpp:100
double getImpatience() const
Returns this vehicles impatience.
const MSEdge * succEdge(int nSuccs) const
Returns the nSuccs'th successor of edge the vehicle is currently at.
void addReminder(MSMoveReminder *rem)
Adds a MoveReminder dynamically.
bool hasValidRoute(std::string &msg, ConstMSRoutePtr route=0) const
Validates the current or given route.
bool isParking() const
Returns whether the vehicle is parking.
const MSEdge * getEdge() const
Returns the edge the vehicle is currently at.
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
virtual void activateReminders(const MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
"Activates" all current move reminder
SUMOVehicleClass getVClass() const
Returns the vehicle's access class.
void onDepart()
Called when the vehicle is inserted into the network.
bool isStopped() const
Returns whether the vehicle is at a stop.
double getMaxDecel() const
Get the vehicle type's maximal comfortable deceleration [m/s^2].
Definition: MSCFModel.h:264
virtual double getHeadwayTime() const
Get the driver's desired headway [s].
Definition: MSCFModel.h:311
Base of value-generating classes (detectors)
bool vehicleApplies(const SUMOTrafficObject &veh) const
Checks whether the detector measures vehicles of the given type.
A road/street connecting two junctions.
Definition: MSEdge.h:77
virtual void unlock() const
release exclusive access to the mesoscopic state
Definition: MSEdge.h:751
SVCPermissions getPermissions() const
Returns the combined permissions of all lanes of this edge.
Definition: MSEdge.h:626
const std::vector< MSLane * > * allowedLanes(const MSEdge &destination, SUMOVehicleClass vclass=SVC_IGNORING, bool ignoreTransientPermissions=false) const
Get the allowed lanes to reach the destination-edge.
Definition: MSEdge.cpp:474
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:168
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:1094
static SVCPermissions getMesoPermissions(SVCPermissions p, SVCPermissions ignoreIgnored=0)
Definition: MSEdge.cpp:310
bool isRoundabout() const
Definition: MSEdge.h:698
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:431
void addWaiting(SUMOVehicle *vehicle) const
Adds a vehicle to the list of waiting vehicles.
Definition: MSEdge.cpp:1373
bool hasMinorLink() const
whether any lane has a minor link
Definition: MSEdge.cpp:1286
const MSJunction * getToJunction() const
Definition: MSEdge.h:415
virtual void lock() const
grant exclusive access to the mesoscopic state
Definition: MSEdge.h:748
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: MSEdge.cpp:1194
static bool gCheckRoutes
Definition: MSGlobals.h:88
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition: MSGlobals.h:109
static bool gMesoLimitedJunctionControl
Definition: MSGlobals.h:106
SumoXMLNodeType getType() const
return the type of this Junction
Definition: MSJunction.h:133
Representation of a lane in the micro simulation.
Definition: MSLane.h:84
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.h:712
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:752
Something on a lane to be noticed about vehicle movement.
Notification
Definition of a vehicle state.
@ NOTIFICATION_ARRIVED
The vehicle arrived at its destination (is deleted)
@ NOTIFICATION_VAPORIZED_CALIBRATOR
The vehicle got removed by a calibrator.
@ NOTIFICATION_DEPARTED
The vehicle has departed (was inserted into the network)
@ NOTIFICATION_SEGMENT
The vehicle changes the segment (meso only)
@ NOTIFICATION_VAPORIZED_VAPORIZER
The vehicle got vaporized with a vaporizer.
@ NOTIFICATION_JUNCTION
The vehicle arrived at a junction.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:182
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:378
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:320
The class responsible for building and deletion of vehicles.
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
void scheduleVehicleRemoval(SUMOVehicle *veh, bool checkDuplicate=false)
Removes a vehicle after it has ended.
double getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
const MSCFModel & getCarFollowModel() const
Returns the vehicle type's car following model definition (const version)
static void writeVehicle(OutputDevice &of, const MSBaseVehicle &veh)
Writes the dump of the given vehicle into the given device.
Base class for objects which have an id.
Definition: Named.h:54
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
Definition: Named.h:67
const std::string & getID() const
Returns the id.
Definition: Named.h:74
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:254
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
Definition: RandHelper.cpp:94
edge type specific meso parameters
Definition: MESegment.h:55