Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
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-2026 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>
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>
43#include "MEVehicle.h"
44#include "MELoop.h"
45#include "MESegment.h"
46
47#define DEFAULT_VEH_LENGTH_WITH_GAP (SUMOVTypeParameter::getDefault().length + SUMOVTypeParameter::getDefault().minGap)
48// avoid division by zero when driving very slowly
49#define MESO_MIN_SPEED (0.05)
50
51//#define DEBUG_OPENED
52//#define DEBUG_JAMTHRESHOLD
53//#define DEBUG_COND (getID() == "blocker")
54//#define DEBUG_COND (true)
55#define DEBUG_COND (myEdge.isSelected())
56#define DEBUG_COND2(obj) ((obj != 0 && (obj)->isSelected()))
57
58
59// ===========================================================================
60// static member definition
61// ===========================================================================
62MSEdge MESegment::myDummyParent("MESegmentDummyParent", -1, SumoXMLEdgeFunc::UNKNOWN, "", "", "", -1, 0);
63MESegment MESegment::myVaporizationTarget("vaporizationTarget");
64const double MESegment::DO_NOT_PATCH_JAM_THRESHOLD(std::numeric_limits<double>::max());
65const std::string MESegment::OVERRIDE_TLS_PENALTIES("meso.tls.control");
66
67
68// ===========================================================================
69// MESegment::Queue method definitions
70// ===========================================================================
74 assert(std::find(myVehicles.begin(), myVehicles.end(), v) != myVehicles.end());
75 if (v == myVehicles.back()) {
76 myVehicles.pop_back();
77 if (myVehicles.empty()) {
78 myOccupancy = 0.;
79 } else {
80 return myVehicles.back();
81 }
82 } else {
83 myVehicles.erase(std::find(myVehicles.begin(), myVehicles.end(), v));
84 }
85 return nullptr;
86}
87
88void
90 myDetectorData.push_back(data);
91 for (MEVehicle* const v : myVehicles) {
92 v->addReminder(data);
93 }
94}
95
96void
98 for (MSMoveReminder* rem : myDetectorData) {
99 veh->addReminder(rem);
100 }
101}
102
103// ===========================================================================
104// MESegment method definitions
105// ===========================================================================
106MESegment::MESegment(const std::string& id,
107 const MSEdge& parent, MESegment* next,
108 const double length, const double speed,
109 const int idx,
110 const bool multiQueue,
111 const MesoEdgeType& edgeType):
112 Named(id), myEdge(parent), myNextSegment(next),
113 myLength(length), myIndex(idx),
115 myNumVehicles(0),
117 myMeanSpeed(speed),
119
120 const std::vector<MSLane*>& lanes = parent.getLanes();
121 int usableLanes = 0;
122 for (MSLane* const l : lanes) {
123 const SVCPermissions allow = MSEdge::getMesoPermissions(l->getPermissions());
124 if (multiQueue) {
125 myQueues.push_back(Queue(allow));
126 }
127 if (allow != 0) {
128 usableLanes++;
129 }
130 }
131 if (usableLanes == 0) {
132 // cars won't drive here. Give sensible tau values capacity for the ignored classes
133 usableLanes = 1;
134 }
135 if (multiQueue) {
136 if (next == nullptr) {
137 for (const MSEdge* const edge : parent.getSuccessors()) {
138 if (edge->isTazConnector()) {
139 continue;
140 }
141 const std::vector<MSLane*>* const allowed = parent.allowedLanes(*edge);
142 assert(allowed != nullptr);
143 assert(allowed->size() > 0);
144 for (MSLane* const l : *allowed) {
145 std::vector<MSLane*>::const_iterator it = std::find(lanes.begin(), lanes.end(), l);
146 myFollowerMap[edge] |= (1 << distance(lanes.begin(), it));
147 }
148 }
149 }
150 myQueueCapacity = length;
151 } else {
152 myQueues.push_back(Queue(parent.getPermissions()));
153 }
154
155 initSegment(edgeType, parent, length * usableLanes);
156}
157
158void
159MESegment::initSegment(const MesoEdgeType& edgeType, const MSEdge& parent, const double capacity) {
160
161 myCapacity = capacity;
162 if (myQueues.size() == 1) {
163 const double laneScale = capacity / myLength;
164 myQueueCapacity = capacity;
166 // Eissfeldt p. 90 and 151 ff.
167 myTau_ff = (SUMOTime)((double)edgeType.tauff / laneScale);
168 myTau_fj = (SUMOTime)((double)edgeType.taufj / laneScale);
169 myTau_jf = (SUMOTime)((double)edgeType.taujf / laneScale);
170 myTau_jj = (SUMOTime)((double)edgeType.taujj / laneScale);
171 } else {
172 myTau_ff = edgeType.tauff;
173 myTau_fj = edgeType.taufj;
174 myTau_jf = edgeType.taujf;
175 myTau_jj = edgeType.taujj;
176 }
177
179 myTLSPenalty = ((edgeType.tlsPenalty > 0 || edgeType.tlsFlowPenalty > 0) &&
180 // only apply to the last segment of a tls-controlled edge
181 myNextSegment == nullptr && (
185
186 // only apply to the last segment of an uncontrolled edge that has at least 1 minor link
187 myCheckMinorPenalty = (edgeType.minorPenalty > 0 &&
188 myNextSegment == nullptr &&
192 parent.hasMinorLink());
193 myMinorPenalty = edgeType.minorPenalty;
195
196 //std::cout << getID() << " myMinorPenalty=" << myMinorPenalty << " myTLSPenalty=" << myTLSPenalty << " myJunctionControl=" << myJunctionControl << " myOvertaking=" << myOvertaking << "\n";
197
199}
200
201MESegment::MESegment(const std::string& id):
202 Named(id),
203 myEdge(myDummyParent), // arbitrary edge needed to supply the needed reference
204 myNextSegment(nullptr), myLength(0), myIndex(0),
205 myTau_ff(0), myTau_fj(0), myTau_jf(0), myTau_jj(0),
206 myTLSPenalty(false),
207 myCheckMinorPenalty(false),
208 myMinorPenalty(0),
209 myJunctionControl(false),
210 myOvertaking(false),
211 myTau_length(1) {
212}
213
214
215void
217 if (myQueues.size() > 1) {
218 for (MSLane* lane : myEdge.getLanes()) {
219 myQueues[lane->getIndex()].setPermissions(lane->getPermissions());
220 }
221 } else {
222 myQueues.back().setPermissions(myEdge.getPermissions());
223 }
224}
225
226
227void
229 if (jamThresh == DO_NOT_PATCH_JAM_THRESHOLD) {
230 return;
231 }
232 if (jamThresh < 0) {
233 // compute based on speed
235 } else {
236 // compute based on specified percentage
237 myJamThreshold = jamThresh * myCapacity;
238 }
239}
240
241
242double
243MESegment::jamThresholdForSpeed(double speed, double jamThresh) const {
244 // vehicles driving freely at maximum speed should not jam
245 // we compute how many vehicles could possible enter the segment until the first vehicle leaves
246 // and multiply by the space these vehicles would occupy
247 // the jamThresh parameter is scale the resulting value
248 if (speed == 0) {
249 return std::numeric_limits<double>::max(); // never jam. Irrelevant at speed 0 anyway
250 }
251#ifdef DEBUG_JAMTHRESHOLD
252 if (true || DEBUG_COND) {
253 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
254 << "\n";
255 }
256#endif
258}
259
260
261void
263 if (queueIndex == -1) {
264 for (Queue& q : myQueues) {
265 q.addDetector(data);
266 }
267 } else {
268 assert(queueIndex < (int)myQueues.size());
269 myQueues[queueIndex].addDetector(data);
270 }
271}
272
273
274/*
275void
276MESegment::removeDetector(MSMoveReminder* data) {
277 std::vector<MSMoveReminder*>::iterator it = std::find(myDetectorData.begin(), myDetectorData.end(), data);
278 if (it != myDetectorData.end()) {
279 myDetectorData.erase(it);
280 }
281 for (const Queue& q : myQueues) {
282 for (MEVehicle* const v : q.getVehicles()) {
283 v->removeReminder(data);
284 }
285 }
286}
287*/
288
289
290void
292 const SUMOTime currentTime = MSNet::getInstance()->getCurrentTimeStep();
293 if (queueIndex == -1) {
294 for (const Queue& q : myQueues) {
295 SUMOTime earliestExitTime = currentTime;
296 for (std::vector<MEVehicle*>::const_reverse_iterator i = q.getVehicles().rbegin(); i != q.getVehicles().rend(); ++i) {
297 const SUMOTime exitTime = MAX2(earliestExitTime, (*i)->getEventTime());
298 (*i)->updateDetectorForWriting(&data, currentTime, exitTime);
299 earliestExitTime = exitTime + tauWithVehLength(myTau_ff, (*i)->getVehicleType().getLengthWithGap(), (*i)->getVehicleType().getCarFollowModel().getHeadwayTime());
300 }
301 }
302 } else {
303 SUMOTime earliestExitTime = currentTime;
304 for (std::vector<MEVehicle*>::const_reverse_iterator i = myQueues[queueIndex].getVehicles().rbegin(); i != myQueues[queueIndex].getVehicles().rend(); ++i) {
305 const SUMOTime exitTime = MAX2(earliestExitTime, (*i)->getEventTime());
306 (*i)->updateDetectorForWriting(&data, currentTime, exitTime);
307 earliestExitTime = exitTime + tauWithVehLength(myTau_ff, (*i)->getVehicleType().getLengthWithGap(), (*i)->getVehicleType().getCarFollowModel().getHeadwayTime());
308 }
309 }
310}
311
312
314MESegment::hasSpaceFor(const MEVehicle* const veh, const SUMOTime entryTime, int& qIdx, const bool init) const {
315 SUMOTime earliestEntry = SUMOTime_MAX;
316 qIdx = 0;
317 if (myNumVehicles == 0 && myQueues.size() == 1) {
318 // we have always space for at least one vehicle
319 if (myQueues.front().allows(veh->getVClass())) {
320 return entryTime;
321 } else {
322 return earliestEntry;
323 }
324 }
325 const SUMOVehicleClass svc = veh->getVClass();
326 int minSize = std::numeric_limits<int>::max();
327 const MSEdge* const succ = myNextSegment == nullptr ? veh->succEdge(veh->getEdge() == &myEdge ? 1 : 2) : nullptr;
328 for (int i = 0; i < (int)myQueues.size(); i++) {
329 const Queue& q = myQueues[i];
330 const double newOccupancy = q.size() == 0 ? 0. : q.getOccupancy() + veh->getVehicleType().getLengthWithGap();
331 if (newOccupancy <= myQueueCapacity) { // we must ensure that occupancy remains below capacity
332 if (succ == nullptr || myFollowerMap.count(succ) == 0 || ((myFollowerMap.find(succ)->second & (1 << i)) != 0)) {
333 if (q.allows(svc) && q.size() < minSize) {
334 if (init) {
335 // regular insertions and initial insertions must respect different constraints:
336 // - regular insertions must respect entryBlockTime
337 // - initial insertions should not cause additional jamming
338 // - inserted vehicle should be able to continue at the current speed
339 if (veh->getInsertionChecks() == (int)InsertionCheck::NONE) {
340 qIdx = i;
341 minSize = q.size();
342 } else if (q.getOccupancy() <= myJamThreshold && !hasBlockedLeader() && !myTLSPenalty) {
343 if (newOccupancy <= myJamThreshold) {
344 qIdx = i;
345 minSize = q.size();
346 }
347 } else {
348 if (newOccupancy <= jamThresholdForSpeed(getMeanSpeed(false), -1)) {
349 qIdx = i;
350 minSize = q.size();
351 }
352 }
353 } else if (entryTime >= q.getEntryBlockTime()) {
354 qIdx = i;
355 minSize = q.size();
356 } else {
357 earliestEntry = MIN2(earliestEntry, q.getEntryBlockTime());
358 }
359 }
360 }
361 }
362 }
363 if (minSize == std::numeric_limits<int>::max()) {
364 return earliestEntry;
365 }
366 return entryTime;
367}
368
369
370bool
372 int qIdx = 0;
373 if (hasSpaceFor(veh, time, qIdx, true) == time) {
374 const bool isRail = veh->isRail();
375 // see MSLane::isInsertionSuccess
376 if (isRail && veh->getInsertionChecks() != (int)InsertionCheck::NONE
381 MSEdgeVector occupied;
382 if (dw->foeDriveWayOccupied(false, veh, occupied)) {
383 myEdge.getLanes()[0]->setParameter("insertionBlocked:" + veh->getID(), dw->getID());
384 return false;
385 }
386 }
387 receive(veh, qIdx, time, true);
388 if (isRail) {
389 myEdge.getLanes()[0]->unsetParameter("insertionConstraint:" + veh->getID());
390 //unsetParameter("insertionOrder:" + veh->getID());
391 //unsetParameter("insertionBlocked:" + veh->getID());
394 //if (firstRailSignal != nullptr && firstRailSignal->getJunction()->getType() == SumoXMLNodeType::RAIL_SIGNAL) {
395 // veh->registerInsertionApproach(firstRailSignal, firstRailSignalDist);
396 //}
397 }
398 // we can check only after insertion because insertion may change the route via devices
399 std::string msg;
400 if (MSGlobals::gCheckRoutes && !veh->hasValidRoute(msg)) {
401 throw ProcessError(TLF("Vehicle '%' has no valid route. %", veh->getID(), msg));
402 }
403 return true;
404 }
405 return false;
406}
407
408
409double
410MESegment::getMeanSpeed(bool useCached) const {
411 const SUMOTime currentTime = MSNet::getInstance()->getCurrentTimeStep();
412 if (currentTime != myLastMeanSpeedUpdate || !useCached) {
413 myLastMeanSpeedUpdate = currentTime;
414 double v = 0;
415 int count = 0;
416 for (const Queue& q : myQueues) {
417 const SUMOTime tau = q.getOccupancy() < myJamThreshold ? myTau_ff : myTau_jf;
418 SUMOTime earliestExitTime = currentTime;
419 count += q.size();
420 for (std::vector<MEVehicle*>::const_reverse_iterator veh = q.getVehicles().rbegin(); veh != q.getVehicles().rend(); ++veh) {
421 v += (*veh)->getConservativeSpeed(earliestExitTime); // earliestExitTime is updated!
422 earliestExitTime += tauWithVehLength(tau, (*veh)->getVehicleType().getLengthWithGap(), (*veh)->getVehicleType().getCarFollowModel().getHeadwayTime());
423 }
424 }
425 if (count == 0) {
427 } else {
428 myMeanSpeed = v / (double) count;
429 }
430 }
431 return myMeanSpeed;
432}
433
434
435void
439
440void
442 for (const Queue& q : myQueues) {
443 for (const MEVehicle* const veh : q.getVehicles()) {
445 }
446 }
447}
448
449
452 Queue& q = myQueues[v->getQueIndex()];
453 // One could be tempted to do v->setSegment(next); here but position on lane will be invalid if next == 0
454 v->updateDetectors(leaveTime, v->getEventTime(), true, reason);
456 myEdge.lock();
457 MEVehicle* nextLeader = q.remove(v);
458 myEdge.unlock();
459 return nextLeader;
460}
461
462
465 // since we do not know which queue will be used we give a conservative estimate
466 SUMOTime earliestLeave = earliestEntry;
467 SUMOTime latestEntry = -1;
468 for (const Queue& q : myQueues) {
469 earliestLeave = MAX2(earliestLeave, q.getBlockTime());
470 latestEntry = MAX2(latestEntry, q.getEntryBlockTime());
471 }
472 if (myEdge.getSpeedLimit() == 0) {
473 return MAX2(earliestEntry, latestEntry); // FIXME: This line is just an adhoc-fix to avoid division by zero (Leo)
474 } else {
475 return MAX3(earliestEntry, earliestLeave - TIME2STEPS(myLength / myEdge.getSpeedLimit()), latestEntry);
476 }
477}
478
479
480MSLink*
481MESegment::getLink(const MEVehicle* veh, bool penalty) const {
482 if (myJunctionControl || penalty) {
483 const MSEdge* const nextEdge = veh->succEdge(1);
484 if (nextEdge == nullptr || veh->getQueIndex() == PARKING_QUEUE) {
485 return nullptr;
486 }
487 // try to find any link leading to our next edge, start with the lane pointed to by the que index
488 const MSLane* const bestLane = myEdge.getLanes()[veh->getQueIndex()];
489 for (MSLink* const link : bestLane->getLinkCont()) {
490 if (&link->getLane()->getEdge() == nextEdge) {
491 return link;
492 }
493 }
494 // this is for the non-multique case, maybe we should use caching here !!!
495 for (const MSLane* const lane : myEdge.getLanes()) {
496 if (lane != bestLane) {
497 for (MSLink* const link : lane->getLinkCont()) {
498 if (&link->getLane()->getEdge() == nextEdge) {
499 return link;
500 }
501 }
502 }
503 }
504 }
505 return nullptr;
506}
507
508
509bool
510MESegment::isOpen(const MEVehicle* veh) const {
511#ifdef DEBUG_OPENED
512 if (DEBUG_COND || DEBUG_COND2(veh)) {
513 gDebugFlag1 = true;
514 std::cout << SIMTIME << " opened seg=" << getID() << " veh=" << Named::getIDSecure(veh)
515 << " tlsPenalty=" << myTLSPenalty;
516 const MSLink* link = getLink(veh);
517 if (link == 0) {
518 std::cout << " link=0";
519 } else {
520 std::cout << " prio=" << link->havePriority()
521 << " override=" << limitedControlOverride(link)
522 << " isOpen=" << link->opened(veh->getEventTime(), veh->getSpeed(), veh->estimateLeaveSpeed(link),
525 0, nullptr, false, veh)
526 << " et=" << veh->getEventTime()
527 << " v=" << veh->getSpeed()
528 << " vLeave=" << veh->estimateLeaveSpeed(link)
529 << " impatience=" << veh->getImpatience()
530 << " tWait=" << veh->getWaitingTime();
531 }
532 std::cout << "\n";
533 gDebugFlag1 = false;
534 }
535#endif
536 if (myTLSPenalty) {
537 // XXX should limited control take precedence over tls penalty?
538 return true;
539 }
540 const MSLink* link = getLink(veh);
541 return (link == nullptr
542 || link->havePriority()
544 || link->opened(veh->getEventTime(), veh->getSpeed(), veh->estimateLeaveSpeed(link),
547 0, nullptr, false, veh));
548}
549
550
551bool
553 assert(link != nullptr);
555 return false;
556 }
557 // if the target segment of this link is not saturated junction control is disabled
558 const MSEdge& targetEdge = link->getLane()->getEdge();
559 const MESegment* target = MSGlobals::gMesoNet->getSegmentForEdge(targetEdge);
560 return (target->getBruttoOccupancy() * 2 < target->myJamThreshold) && !targetEdge.isRoundabout();
561}
562
563
564void
565MESegment::send(MEVehicle* veh, MESegment* const next, const int nextQIdx, SUMOTime time, const MSMoveReminder::Notification reason) {
566 Queue& q = myQueues[veh->getQueIndex()];
567 assert(isInvalid(next) || time >= q.getBlockTime());
568 MSLink* const link = getLink(veh);
569 if (link != nullptr) {
570 link->removeApproaching(veh);
571 }
572 if (veh->isStopped()) {
573 veh->processStop();
574 }
575 MEVehicle* lc = removeCar(veh, time, reason); // new leaderCar
576 q.setBlockTime(time);
577 if (!isInvalid(next)) {
578 const bool nextFree = next->myQueues[nextQIdx].getOccupancy() <= next->myJamThreshold;
579 const SUMOTime tau = (q.getOccupancy() <= myJamThreshold
580 ? (nextFree ? myTau_ff : myTau_fj)
581 : (nextFree ? myTau_jf : getTauJJ((double)next->myQueues[nextQIdx].size(), next->myQueueCapacity, next->myJamThreshold)));
582 assert(tau >= 0);
584 if (myTLSPenalty) {
585 const MSLink* const tllink = getLink(veh, true);
586 if (tllink != nullptr && tllink->isTLSControlled()) {
587 assert(tllink->getGreenFraction() > 0);
588 myLastHeadway = (SUMOTime)((double)myLastHeadway / tllink->getGreenFraction());
589 }
590 }
592 }
593 if (lc != nullptr) {
596 }
597}
598
600MESegment::getTauJJ(double nextQueueSize, double nextQueueCapacity, double nextJamThreshold) const {
601 // compute coefficients for the jam-jam headway function
602 // this function models the effect that "empty space" needs to move
603 // backwards through the downstream segment before the upstream segment may
604 // send annother vehicle.
605 // this allows jams to clear and move upstream.
606 // the headway function f(x) depends on the number of vehicles in the
607 // downstream segment x
608 // f is a linear function that passes through the following fixed points:
609 // f(n_jam_threshold) = tau_jf_withLength (for continuity)
610 // f(headwayCapacity) = myTau_jj * headwayCapacity
611
612 const SUMOTime tau_jf_withLength = tauWithVehLength(myTau_jf, DEFAULT_VEH_LENGTH_WITH_GAP, 1.);
613 // number of vehicles that fit into the NEXT queue (could be larger than expected with DEFAULT_VEH_LENGTH_WITH_GAP!)
614 const double headwayCapacity = MAX2(nextQueueSize, nextQueueCapacity / DEFAULT_VEH_LENGTH_WITH_GAP);
615 // number of vehicles above which the NEXT queue is jammed
616 const double n_jam_threshold = headwayCapacity * nextJamThreshold / nextQueueCapacity;
617
618 // slope a and axis offset b for the jam-jam headway function
619 // solving f(x) = a * x + b
620 const double a = (STEPS2TIME(myTau_jj) * headwayCapacity - STEPS2TIME(tau_jf_withLength)) / (headwayCapacity - n_jam_threshold);
621 const double b = headwayCapacity * (STEPS2TIME(myTau_jj) - a);
622
623 // it is only well defined for nextQueueSize >= n_jam_threshold (which may not be the case for longer vehicles), so we take the MAX
624 return TIME2STEPS(a * MAX2(nextQueueSize, n_jam_threshold) + b);
625}
626
627
628bool
632
633
634void
636 if (veh->getQueIndex() != PARKING_QUEUE) {
637 myQueues[veh->getQueIndex()].addReminders(veh);
638 }
639}
640
641
642void
643MESegment::receive(MEVehicle* veh, const int qIdx, SUMOTime time, const bool isDepart, const bool isTeleport, const bool newEdge) {
644 const double speed = isDepart ? -1 : MAX2(veh->getSpeed(), MESO_MIN_SPEED); // on the previous segment
645 veh->setSegment(this); // for arrival checking
646 veh->setLastEntryTime(time);
648 if (!isDepart && (
649 // arrival on entering a new edge
650 (newEdge && myEdge.isNormal() && veh->moveRoutePointer())
651 // arrival on entering a new segment
652 || veh->hasArrived())) {
653 // route has ended
654 veh->setEventTime(time + TIME2STEPS(myLength / speed)); // for correct arrival speed
655 addReminders(veh);
657 veh->updateDetectors(time, veh->getEventTime(), true,
660 return;
661 }
662 assert(veh->getEdge() == &getEdge() || getEdge().isInternal());
663 // route continues
664 Queue& q = myQueues[qIdx];
665 const double maxSpeedOnEdge = veh->getEdge()->getLanes()[qIdx]->getVehicleMaxSpeed(veh);
666 const double uspeed = MAX2(maxSpeedOnEdge, MESO_MIN_SPEED);
667 std::vector<MEVehicle*>& cars = q.getModifiableVehicles();
668 MEVehicle* newLeader = nullptr; // first vehicle in the current queue
669 const SUMOTime stopTime = veh->checkStop(time);
670 SUMOTime tleave = MAX2(stopTime + TIME2STEPS(myLength / uspeed) + getLinkPenalty(veh), q.getBlockTime());
671 if (veh->isStopped()) {
672 myEdge.addWaiting(veh);
673 }
674 if (veh->isParking()) {
675 // parking stops should take at least 1ms
676 veh->setEventTime(MAX2(stopTime, veh->getEventTime() + 1));
677 veh->setSegment(this, PARKING_QUEUE);
678 myEdge.getLanes()[0]->addParking(veh); // TODO for GUI only
679 } else {
680 myEdge.lock();
681 if (cars.empty()) {
682 cars.push_back(veh);
683 newLeader = veh;
684 } else {
685 SUMOTime leaderOut = cars[0]->getEventTime();
686 if (!isDepart && leaderOut > tleave && overtake()) {
687 if (cars.size() == 1) {
689 newLeader = veh;
690 }
691 cars.insert(cars.begin() + 1, veh);
692 } else {
693 tleave = MAX2(leaderOut + tauWithVehLength(myTau_ff, cars[0]->getVehicleType().getLengthWithGap(), cars[0]->getVehicleType().getCarFollowModel().getHeadwayTime()), tleave);
694 cars.insert(cars.begin(), veh);
695 }
696 }
697 myEdge.unlock();
699 if (!isDepart && !isTeleport) {
700 // departs and teleports could take place anywhere on the edge so they should not block regular flow
701 // the -1 facilitates interleaving of multiple streams
703 }
705 veh->setEventTime(tleave);
706 veh->setSegment(this, qIdx);
707 }
708 addReminders(veh);
709 if (isDepart) {
710 veh->onDepart();
712 } else if (newEdge) {
714 } else {
716 }
717 if (veh->isParking()) {
718 MSGlobals::gMesoNet->addLeaderCar(veh, nullptr);
719 } else {
720 if (newLeader != nullptr) {
721 MSGlobals::gMesoNet->addLeaderCar(newLeader, getLink(newLeader));
722 }
723 }
724}
725
726
727bool
729 for (const Queue& q : myQueues) {
730 if (q.size() > 0) {
731 for (MEVehicle* const veh : q.getVehicles()) {
732 if (filter->vehicleApplies(*veh)) {
735 return true;
736 }
737 }
738 }
739 }
740 return false;
741}
742
743
744void
745MESegment::setSpeedForQueue(double newSpeed, SUMOTime currentTime, SUMOTime blockTime, const std::vector<MEVehicle*>& vehs) {
746 MEVehicle* v = vehs.back();
747 SUMOTime oldEarliestExitTime = currentTime;
748 const SUMOTime oldExit = MAX2(oldEarliestExitTime, v->getEventTime());
749 v->updateDetectors(currentTime, oldExit, false);
751 SUMOTime newEvent = MAX2(newArrival(v, newSpeed, currentTime), blockTime);
752 if (v->getEventTime() != newEvent) {
754 v->setEventTime(newEvent);
756 }
757 for (std::vector<MEVehicle*>::const_reverse_iterator i = vehs.rbegin() + 1; i != vehs.rend(); ++i) {
758 const SUMOTime oldExitTime = MAX2(oldEarliestExitTime, (*i)->getEventTime());
759 (*i)->updateDetectors(currentTime, oldExitTime, false);
760 const SUMOTime minTau = tauWithVehLength(myTau_ff, (*i)->getVehicleType().getLengthWithGap(), (*i)->getVehicleType().getCarFollowModel().getHeadwayTime());
761 oldEarliestExitTime = oldExitTime + minTau;
762 newEvent = MAX2(newArrival(*i, newSpeed, currentTime), newEvent + minTau);
763 (*i)->setEventTime(newEvent);
764 }
765}
766
767
769MESegment::newArrival(const MEVehicle* const v, double newSpeed, SUMOTime currentTime) {
770 // since speed is only an upper bound, pos may be too optimistic
771 const double pos = MIN2(myLength, STEPS2TIME(currentTime - v->getLastEntryTime()) * v->getSpeed());
772 // traveltime may not be 0
773 double tt = (myLength - pos) / MAX2(newSpeed, MESO_MIN_SPEED);
774 return currentTime + MAX2(TIME2STEPS(tt), SUMOTime(1));
775}
776
777
778void
779MESegment::setSpeed(double newSpeed, SUMOTime currentTime, double jamThresh, int qIdx) {
780 recomputeJamThreshold(jamThresh);
781 //myTau_length = MAX2(MESO_MIN_SPEED, newSpeed) * myEdge.getLanes().size() / TIME2STEPS(1);
782 int i = 0;
783 for (const Queue& q : myQueues) {
784 if (q.size() != 0) {
785 if (qIdx == -1 || qIdx == i) {
786 setSpeedForQueue(newSpeed, currentTime, q.getBlockTime(), q.getVehicles());
787 }
788 }
789 i++;
790 }
791}
792
793
796 SUMOTime result = SUMOTime_MAX;
797 for (const Queue& q : myQueues) {
798 if (q.size() != 0 && q.getVehicles().back()->getEventTime() < result) {
799 result = q.getVehicles().back()->getEventTime();
800 }
801 }
802 if (result < SUMOTime_MAX) {
803 return result;
804 }
805 return -1;
806}
807
808
809void
811 bool write = false;
812 for (const Queue& q : myQueues) {
813 if (q.getBlockTime() != -1 || !q.getVehicles().empty()) {
814 write = true;
815 break;
816 }
817 }
818 if (write) {
820 for (const Queue& q : myQueues) {
822 out.writeAttr(SUMO_ATTR_TIME, toString<SUMOTime>(q.getBlockTime()));
823 out.writeAttr(SUMO_ATTR_BLOCKTIME, toString<SUMOTime>(q.getEntryBlockTime()));
824 out.writeAttr(SUMO_ATTR_VALUE, q.getVehicles());
825 out.closeTag();
826 }
827 out.closeTag();
828 }
829}
830
831
832void
834 for (Queue& q : myQueues) {
835 q.getModifiableVehicles().clear();
836 }
837}
838
839void
840MESegment::loadState(const std::vector<SUMOVehicle*>& vehs, const SUMOTime blockTime, const SUMOTime entryBlockTime, const int queIdx) {
841 Queue& q = myQueues[queIdx];
842 for (SUMOVehicle* veh : vehs) {
843 MEVehicle* v = static_cast<MEVehicle*>(veh);
844 assert(v->getSegment() == this || myEdge.isInternal());
845 if (myEdge.isInternal()) {
846 v->setSegment(this, v->getQueIndex());
847 }
848 q.getModifiableVehicles().push_back(v);
851 addReminders(v);
852 }
853 if (q.size() != 0) {
854 // add the last vehicle of this queue
855 // !!! one question - what about the previously added vehicle? Is it stored twice?
856 MEVehicle* veh = q.getVehicles().back();
858 }
859 q.setBlockTime(blockTime);
860 q.setEntryBlockTime(entryBlockTime);
862}
863
864
865std::vector<const MEVehicle*>
867 std::vector<const MEVehicle*> result;
868 for (const Queue& q : myQueues) {
869 result.insert(result.end(), q.getVehicles().begin(), q.getVehicles().end());
870 }
871 return result;
872}
873
874
875bool
877 for (const Queue& q : myQueues) {
878 if (q.size() > 0 && q.getVehicles().back()->getWaitingTime() > 0) {
879 return true;
880 }
881 }
882 return false;
883}
884
885
886double
888 return 3600 * getCarNumber() * getMeanSpeed() / myLength;
889}
890
891
894 const MSLink* link = getLink(veh, myTLSPenalty || myCheckMinorPenalty);
895 if (link != nullptr) {
896 SUMOTime result = 0;
897 if (link->isTLSControlled() && myTLSPenalty) {
898 result += link->getMesoTLSPenalty();
899 }
900 // minor tls links may get an additional penalty
901 if (!link->havePriority() &&
902 // do not apply penalty on top of tLSPenalty
903 !myTLSPenalty &&
904 // do not apply penalty if limited control is active
906 result += myMinorPenalty;
907 }
908 return result;
909 } else {
910 return 0;
911 }
912}
913
914
915double
917 double result = 0;
918 for (const Queue& q : myQueues) {
919 // @note: only the leader currently accumulates waitingTime but this might change in the future
920 for (const MEVehicle* veh : q.getVehicles()) {
921 result += veh->getWaitingSeconds();
922 }
923 }
924 return result;
925}
926
927
928/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
#define MESO_MIN_SPEED
Definition MESegment.cpp:49
#define DEFAULT_VEH_LENGTH_WITH_GAP
Definition MESegment.cpp:47
#define DEBUG_COND2(obj)
Definition MESegment.cpp:56
std::vector< MSEdge * > MSEdgeVector
Definition MSEdge.h:73
#define TLF(string,...)
Definition MsgHandler.h:306
#define STEPS2TIME(x)
Definition SUMOTime.h:58
#define SUMOTime_MAX
Definition SUMOTime.h:34
#define SUMOTime_MIN
Definition SUMOTime.h:35
#define SIMTIME
Definition SUMOTime.h:65
#define TIME2STEPS(x)
Definition SUMOTime.h:60
bool isRailwayOrShared(SVCPermissions permissions)
Returns whether an edge with the given permissions is a railway edge or a shared road/rail edge.
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.
@ SPLIT
The departure is triggered by a train split.
@ SUMO_TAG_VIEWSETTINGS_VEHICLES
@ SUMO_TAG_SEGMENT
segment of a lane
@ SUMO_ATTR_VALUE
@ SUMO_ATTR_BLOCKTIME
@ SUMO_ATTR_ID
@ SUMO_ATTR_TIME
trigger: the time of the step
bool gDebugFlag1
global utility flags for debugging
Definition StdDefs.cpp:44
T MIN2(T a, T b)
Definition StdDefs.h:80
T MAX2(T a, T b)
Definition StdDefs.h:86
T MAX3(T a, T b, T c)
Definition StdDefs.h:100
static bool isEnteringRoundabout(const MSEdge &e)
whether the given edge is entering a roundabout
Definition MELoop.cpp:356
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:339
bool removeLeaderCar(MEVehicle *v)
Removes the given car from the leading vehicles.
Definition MELoop.cpp:254
void addLeaderCar(MEVehicle *veh, MSLink *link)
Adds the given car to the leading vehicles.
Definition MELoop.cpp:241
int size() const
Definition MESegment.h:77
void setOccupancy(const double occ)
Definition MESegment.h:90
MEVehicle * remove(MEVehicle *v)
Definition MESegment.cpp:72
void setBlockTime(SUMOTime t)
Definition MESegment.h:110
SUMOTime getBlockTime() const
Definition MESegment.h:107
double myOccupancy
The occupied space (in m) in the queue.
Definition MESegment.h:129
bool allows(SUMOVehicleClass vclass) const
Definition MESegment.h:93
std::vector< MEVehicle * > & getModifiableVehicles()
Definition MESegment.h:84
void addReminders(MEVehicle *veh) const
Definition MESegment.cpp:97
void addDetector(MSMoveReminder *data)
Definition MESegment.cpp:89
void setEntryBlockTime(SUMOTime entryBlockTime)
set the next time at which a vehicle may enter this queue
Definition MESegment.h:103
double getOccupancy() const
Definition MESegment.h:87
std::vector< MEVehicle * > myVehicles
Definition MESegment.h:126
const std::vector< MEVehicle * > & getVehicles() const
Definition MESegment.h:80
SUMOTime getEntryBlockTime() const
return the next time at which a vehicle may enter this queue
Definition MESegment.h:98
A single mesoscopic segment (cell)
Definition MESegment.h:50
void addReminders(MEVehicle *veh) const
add this lanes MoveReminders to the given vehicle
double myQueueCapacity
The number of lanes represented by the queue * the length of the lane.
Definition MESegment.h:574
bool overtake()
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:528
SUMOTime myTau_ff
The time headway parameters, see the Eissfeldt thesis.
Definition MESegment.h:551
bool initialise(MEVehicle *veh, SUMOTime time)
Inserts (emits) vehicle into the segment.
std::vector< Queue > myQueues
The car queues. Vehicles are inserted in the front and removed in the back.
Definition MESegment.h:580
double getBruttoOccupancy() const
Returns the occupany of the segment (the sum of the vehicle lengths + minGaps)
Definition MESegment.h:267
SUMOTime myLastHeadway
the last headway
Definition MESegment.h:589
static const int PARKING_QUEUE
Definition MESegment.h:53
bool limitedControlOverride(const MSLink *link) const
whether the given link may be passed because the option meso-junction-control.limited is set
bool isOpen(const MEVehicle *veh) const
Returns whether the vehicle may use the next link.
void addDetector(MSMoveReminder *data, int queueIndex=-1)
Adds a data collector for a detector to this segment.
void clearState()
Remove all vehicles before quick-loading state.
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.
SUMOTime getLinkPenalty(const MEVehicle *veh) const
Returns the penalty time for passing a link (if using gMesoTLSPenalty > 0 or gMesoMinorPenalty > 0)
void writeVehicles(OutputDevice &of) const
std::map< const MSEdge *, int > myFollowerMap
The follower edge to allowed que index mapping for multi queue segments.
Definition MESegment.h:586
MSLink * getLink(const MEVehicle *veh, bool tlsPenalty=false) const
Returns the link the given car will use when passing the next junction.
int myNumVehicles
The cached value for the number of vehicles.
Definition MESegment.h:583
void setSpeedForQueue(double newSpeed, SUMOTime currentTime, SUMOTime blockTime, const std::vector< MEVehicle * > &vehs)
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.
void updatePermissions()
called when permissions change due to Rerouter or TraCI
void saveState(OutputDevice &out) const
Saves the state of this segment into the given stream.
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)
void resetCachedSpeeds()
reset myLastMeanSpeedUpdate
const MSEdge & getEdge() const
Returns the edge this segment belongs to.
Definition MESegment.h:371
static MESegment myVaporizationTarget
Definition MESegment.h:594
double myJamThreshold
The space (in m) which needs to be occupied before the segment is considered jammed.
Definition MESegment.h:577
const int myIndex
Running number of the segment in the edge.
Definition MESegment.h:545
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.
SUMOTime myMinorPenalty
Definition MESegment.h:558
double myMeanSpeed
the mean speed on this segment. Updated at event time or on demand
Definition MESegment.h:597
bool myCheckMinorPenalty
penalty for minor links
Definition MESegment.h:557
double jamThresholdForSpeed(double speed, double jamThresh) const
compute jam threshold for the given speed and jam-threshold option
SUMOTime myLastMeanSpeedUpdate
the time at which myMeanSpeed was last updated
Definition MESegment.h:600
SUMOTime myTau_jf
Definition MESegment.h:551
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
MESegment * myNextSegment
The next segment of this edge, 0 if this is the last segment of this edge.
Definition MESegment.h:539
bool hasBlockedLeader() const
whether a leader in any queue is blocked
double getWaitingSeconds() const
Get the waiting time for vehicles in all queues.
const double myLength
The segment's length.
Definition MESegment.h:542
SUMOTime getEventTime() const
Returns the (planned) time at which the next vehicle leaves this segment.
const MSEdge & myEdge
The microsim edge this segment belongs to.
Definition MESegment.h:536
static const std::string OVERRIDE_TLS_PENALTIES
special param value
Definition MESegment.h:55
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
MEVehicle * removeCar(MEVehicle *v, SUMOTime leaveTime, const MSMoveReminder::Notification reason)
Removes the given car from the edge's que.
std::vector< const MEVehicle * > getVehicles() const
returns all vehicles (for debugging)
static MSEdge myDummyParent
Definition MESegment.h:593
void recomputeJamThreshold(double jamThresh)
compute a value for myJamThreshold if jamThresh is negative, compute a value which allows free flow a...
double getMeanSpeed() const
wrapper to satisfy the FunctionBinding signature
Definition MESegment.h:306
int getCarNumber() const
Returns the total number of cars on the segment.
Definition MESegment.h:210
void loadState(const std::vector< SUMOVehicle * > &vehs, const SUMOTime blockTime, const SUMOTime entryBlockTime, const int queIdx)
Loads the state of this segment with the given parameters.
double myTau_length
Headway parameter for computing gross time headyway from net time headway, length and edge speed.
Definition MESegment.h:568
SUMOTime myTau_jj
Definition MESegment.h:551
SUMOTime newArrival(const MEVehicle *const v, double newSpeed, SUMOTime currentTime)
compute the new arrival time when switching speed
bool myJunctionControl
Whether junction control is enabled.
Definition MESegment.h:561
bool myTLSPenalty
Whether tls penalty is enabled.
Definition MESegment.h:554
static const double DO_NOT_PATCH_JAM_THRESHOLD
Definition MESegment.h:52
double getFlow() const
returns flow based on headway
static bool isInvalid(const MESegment *segment)
whether the given segment is 0 or encodes vaporization
Definition MESegment.h:454
SUMOTime getNextInsertionTime(SUMOTime earliestEntry) const
return a time after earliestEntry at which a vehicle may be inserted at full speed
double myCapacity
The number of lanes represented by the queue * the length of the lane.
Definition MESegment.h:571
bool myOvertaking
Whether overtaking is permitted on this segment.
Definition MESegment.h:564
void prepareDetectorForWriting(MSMoveReminder &data, int queueIndex=-1)
Removes a data collector for a detector from this segment.
bool vaporizeAnyCar(SUMOTime currentTime, const MSDetectorFileOutput *filter)
tries to remove any car from this segment
SUMOTime myTau_fj
Definition MESegment.h:551
SUMOTime getTauJJ(double nextQueueSize, double nextQueueCapacity, double nextJamThreshold) const
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 across the link.
void processStop()
ends the current stop and performs loading/unloading
SUMOTime getWaitingTime(const bool accumulated=false) const
Returns the duration for which the vehicle was blocked.
Definition MEVehicle.h:289
bool hasArrived() const
Returns whether this vehicle has already arrived (reached the arrivalPosition on its final edge)
bool moveRoutePointer()
Update when the vehicle enters a new edge in the move step.
void updateDetectors(const SUMOTime currentTime, const SUMOTime exitTime, const bool isLeave, const MSMoveReminder::Notification reason=MSMoveReminder::NOTIFICATION_JUNCTION)
Updates all vehicle detectors.
SUMOTime checkStop(SUMOTime time)
Returns until when to stop at the current segment and sets the information that the stop has been rea...
SUMOTime getLastEntryTime() const
Returns the time the vehicle entered the current segment.
Definition MEVehicle.h:260
void setEventTime(SUMOTime t, bool hasDelay=true)
Sets the (planned) time at which the vehicle leaves its current segment.
Definition MEVehicle.h:199
MESegment * getSegment() const
Returns the current segment the vehicle is on.
Definition MEVehicle.h:229
void setLastEntryTime(SUMOTime t)
Sets the entry time for the current segment.
Definition MEVehicle.h:252
int getQueIndex() const
Returns the index of the que the vehicle is in.
Definition MEVehicle.h:238
virtual void setSegment(MESegment *s, int idx=0)
Sets the current segment the vehicle is at together with its que.
Definition MEVehicle.h:220
SUMOTime getEventTime() const
Returns the (planned) time at which the vehicle leaves its current segment.
Definition MEVehicle.h:211
void setBlockTime(const SUMOTime t)
Sets the time at which the vehicle was blocked.
Definition MEVehicle.h:274
double getSpeed() const
Returns the vehicle's estimated speed assuming no delays.
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.
int getInsertionChecks() const
const SUMOVehicleParameter & getParameter() const
Returns the vehicle's parameter (including departure definition)
bool isRail() const
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.
void addReminder(MSMoveReminder *rem, double pos=0)
Adds a MoveReminder dynamically.
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.
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
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:269
virtual double getHeadwayTime() const
Get the driver's desired headway [s].
Definition MSCFModel.h:339
Base of value-generating classes (detectors)
bool vehicleApplies(const SUMOTrafficObject &veh) const
Checks whether the detector measures vehicles of the given type.
static const MSDriveWay * getDepartureDriveway(const SUMOVehicle *veh, bool init=false)
bool foeDriveWayOccupied(bool store, const SUMOVehicle *ego, MSEdgeVector &occupied) const
whether any of myFoes is occupied (vehicles that are the target of a join must be ignored)
A road/street connecting two junctions.
Definition MSEdge.h:77
virtual void unlock() const
release exclusive access to the mesoscopic state
Definition MSEdge.h:791
SVCPermissions getPermissions() const
Returns the combined permissions of all lanes of this edge.
Definition MSEdge.h:658
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition MSEdge.h:168
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:480
bool isNormal() const
return whether this edge is an internal edge
Definition MSEdge.h:264
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:1192
const MSJunction * getToJunction() const
Definition MSEdge.h:427
static SVCPermissions getMesoPermissions(SVCPermissions p, SVCPermissions ignoreIgnored=0)
Definition MSEdge.cpp:316
bool isRoundabout() const
Definition MSEdge.h:732
bool isInternal() const
return whether this edge is an internal edge
Definition MSEdge.h:269
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition MSEdge.h:443
void addWaiting(SUMOVehicle *vehicle) const
Adds a vehicle to the list of waiting vehicles.
Definition MSEdge.cpp:1485
bool hasMinorLink() const
whether any lane has a minor link
Definition MSEdge.cpp:1384
virtual void lock() const
grant exclusive access to the mesoscopic state
Definition MSEdge.h:788
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition MSEdge.cpp:1292
static bool gCheckRoutes
Definition MSGlobals.h:91
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition MSGlobals.h:115
static bool gMesoLimitedJunctionControl
Definition MSGlobals.h:109
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
MSEdge & getEdge() const
Returns the lane's edge.
Definition MSLane.h:775
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
Definition MSLane.h:735
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:199
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition MSNet.h:334
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition MSNet.h:402
static bool isSignalized(SUMOVehicleClass svc)
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.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const ATTR_TYPE &attr, const T &val, const bool isNull=false)
writes a named attribute
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)
Representation of a vehicle.
Definition SUMOVehicle.h:63
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
#define DEBUG_COND
edge type specific meso parameters
Definition MESegment.h:58