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");
65const double MESegment::DO_NOT_PATCH_JAM_THRESHOLD(std::numeric_limits<double>::max());
66const std::string MESegment::OVERRIDE_TLS_PENALTIES("meso.tls.control");
67
68
69// ===========================================================================
70// MESegment::Queue method definitions
71// ===========================================================================
75 assert(std::find(myVehicles.begin(), myVehicles.end(), v) != myVehicles.end());
76 if (v == myVehicles.back()) {
77 myVehicles.pop_back();
78 if (myVehicles.empty()) {
79 myOccupancy = 0.;
80 } else {
81 return myVehicles.back();
82 }
83 } else {
84 myVehicles.erase(std::find(myVehicles.begin(), myVehicles.end(), v));
85 }
86 return nullptr;
87}
88
89void
91 myDetectorData.push_back(data);
92 for (MEVehicle* const v : myVehicles) {
93 v->addReminder(data);
94 }
95}
96
97void
99 for (MSMoveReminder* rem : myDetectorData) {
100 veh->addReminder(rem);
101 }
102}
103
104// ===========================================================================
105// MESegment method definitions
106// ===========================================================================
107MESegment::MESegment(const std::string& id,
108 const MSEdge& parent, MESegment* next,
109 const double length, const double speed,
110 const int idx,
111 const bool multiQueue,
112 const MesoEdgeType& edgeType):
113 Named(id), myEdge(parent), myNextSegment(next),
114 myLength(length), myIndex(idx),
116 myNumVehicles(0),
118 myMeanSpeed(speed),
120
121 const std::vector<MSLane*>& lanes = parent.getLanes();
122 int usableLanes = 0;
123 SVCPermissions maxAllow = 0;
124 SVCPermissions minAllow = SVCAll;
125 for (MSLane* const l : lanes) {
126 const SVCPermissions allow = MSEdge::getMesoPermissions(l->getPermissions());
127 if (multiQueue) {
128 myQueues.push_back(Queue(allow));
129 }
130 if (allow != 0) {
131 usableLanes++;
132 maxAllow |= allow;
133 minAllow &= allow;
134 }
135 }
136 if (usableLanes == 0) {
137 // cars won't drive here. Give sensible tau values capacity for the ignored classes
138 usableLanes = 1;
139 }
140 if (multiQueue) {
141 if (next == nullptr) {
142 for (const MSEdge* const edge : parent.getSuccessors()) {
143 if (edge->isTazConnector()) {
144 continue;
145 }
146 const std::vector<MSLane*>* const allowed = parent.allowedLanes(*edge);
147 assert(allowed != nullptr);
148 assert(allowed->size() > 0);
149 for (MSLane* const l : *allowed) {
150 std::vector<MSLane*>::const_iterator it = std::find(lanes.begin(), lanes.end(), l);
151 myFollowerMap[edge] |= (1 << distance(lanes.begin(), it));
152 }
153 }
154 }
155 myQueueCapacity = length;
156 } else {
157 myQueues.push_back(Queue(parent.getPermissions()));
158 maxAllow &= ~minAllow;
159 if ((maxAllow & ~myMultiModalWarnings) != 0) {
160 WRITE_WARNINGF("Mismodelled capacity on edge '%'. Not all lanes are usable by vClass '%'. Use option --meso-lane-queue or add unused class to option --meso-ignore-lanes-by-vclass.",
162 myMultiModalWarnings |= maxAllow;
163 }
164 }
165
166 initSegment(edgeType, parent, length * usableLanes);
167}
168
169void
170MESegment::initSegment(const MesoEdgeType& edgeType, const MSEdge& parent, const double capacity) {
171
172 myCapacity = capacity;
173 if (myQueues.size() == 1) {
174 const double laneScale = capacity / myLength;
175 myQueueCapacity = capacity;
177 // Eissfeldt p. 90 and 151 ff.
178 myTau_ff = (SUMOTime)((double)edgeType.tauff / laneScale);
179 myTau_fj = (SUMOTime)((double)edgeType.taufj / laneScale);
180 myTau_jf = (SUMOTime)((double)edgeType.taujf / laneScale);
181 myTau_jj = (SUMOTime)((double)edgeType.taujj / laneScale);
182 } else {
183 myTau_ff = edgeType.tauff;
184 myTau_fj = edgeType.taufj;
185 myTau_jf = edgeType.taujf;
186 myTau_jj = edgeType.taujj;
187 }
188
190 myTLSPenalty = ((edgeType.tlsPenalty > 0 || edgeType.tlsFlowPenalty > 0) &&
191 // only apply to the last segment of a tls-controlled edge
192 myNextSegment == nullptr && (
196
197 // only apply to the last segment of an uncontrolled edge that has at least 1 minor link
198 myCheckMinorPenalty = (edgeType.minorPenalty > 0 &&
199 myNextSegment == nullptr &&
203 parent.hasMinorLink());
204 myMinorPenalty = edgeType.minorPenalty;
206
207 //std::cout << getID() << " myMinorPenalty=" << myMinorPenalty << " myTLSPenalty=" << myTLSPenalty << " myJunctionControl=" << myJunctionControl << " myOvertaking=" << myOvertaking << "\n";
208
210}
211
212MESegment::MESegment(const std::string& id):
213 Named(id),
214 myEdge(myDummyParent), // arbitrary edge needed to supply the needed reference
215 myNextSegment(nullptr), myLength(0), myIndex(0),
216 myTau_ff(0), myTau_fj(0), myTau_jf(0), myTau_jj(0),
217 myTLSPenalty(false),
218 myCheckMinorPenalty(false),
219 myMinorPenalty(0),
220 myJunctionControl(false),
221 myOvertaking(false),
222 myTau_length(1) {
223}
224
225
226void
228 if (myQueues.size() > 1) {
229 for (MSLane* lane : myEdge.getLanes()) {
230 myQueues[lane->getIndex()].setPermissions(lane->getPermissions());
231 }
232 } else {
233 myQueues.back().setPermissions(myEdge.getPermissions());
234 }
235}
236
237
238void
240 if (jamThresh == DO_NOT_PATCH_JAM_THRESHOLD) {
241 return;
242 }
243 if (jamThresh < 0) {
244 // compute based on speed
246 } else {
247 // compute based on specified percentage
248 myJamThreshold = jamThresh * myCapacity;
249 }
250}
251
252
253double
254MESegment::jamThresholdForSpeed(double speed, double jamThresh) const {
255 // vehicles driving freely at maximum speed should not jam
256 // we compute how many vehicles could possible enter the segment until the first vehicle leaves
257 // and multiply by the space these vehicles would occupy
258 // the jamThresh parameter is scale the resulting value
259 if (speed == 0) {
260 return std::numeric_limits<double>::max(); // never jam. Irrelevant at speed 0 anyway
261 }
262#ifdef DEBUG_JAMTHRESHOLD
263 if (true || DEBUG_COND) {
264 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
265 << "\n";
266 }
267#endif
269}
270
271
272void
274 if (queueIndex == -1) {
275 for (Queue& q : myQueues) {
276 q.addDetector(data);
277 }
278 } else {
279 assert(queueIndex < (int)myQueues.size());
280 myQueues[queueIndex].addDetector(data);
281 }
282}
283
284
285/*
286void
287MESegment::removeDetector(MSMoveReminder* data) {
288 std::vector<MSMoveReminder*>::iterator it = std::find(myDetectorData.begin(), myDetectorData.end(), data);
289 if (it != myDetectorData.end()) {
290 myDetectorData.erase(it);
291 }
292 for (const Queue& q : myQueues) {
293 for (MEVehicle* const v : q.getVehicles()) {
294 v->removeReminder(data);
295 }
296 }
297}
298*/
299
300
301void
303 const SUMOTime currentTime = MSNet::getInstance()->getCurrentTimeStep();
304 if (queueIndex == -1) {
305 for (const Queue& q : myQueues) {
306 SUMOTime earliestExitTime = currentTime;
307 for (std::vector<MEVehicle*>::const_reverse_iterator i = q.getVehicles().rbegin(); i != q.getVehicles().rend(); ++i) {
308 const SUMOTime exitTime = MAX2(earliestExitTime, (*i)->getEventTime());
309 (*i)->updateDetectorForWriting(&data, currentTime, exitTime);
310 earliestExitTime = exitTime + tauWithVehLength(myTau_ff, (*i)->getVehicleType().getLengthWithGap(), (*i)->getVehicleType().getCarFollowModel().getHeadwayTime());
311 }
312 }
313 } else {
314 SUMOTime earliestExitTime = currentTime;
315 for (std::vector<MEVehicle*>::const_reverse_iterator i = myQueues[queueIndex].getVehicles().rbegin(); i != myQueues[queueIndex].getVehicles().rend(); ++i) {
316 const SUMOTime exitTime = MAX2(earliestExitTime, (*i)->getEventTime());
317 (*i)->updateDetectorForWriting(&data, currentTime, exitTime);
318 earliestExitTime = exitTime + tauWithVehLength(myTau_ff, (*i)->getVehicleType().getLengthWithGap(), (*i)->getVehicleType().getCarFollowModel().getHeadwayTime());
319 }
320 }
321}
322
323
325MESegment::hasSpaceFor(const MEVehicle* const veh, const SUMOTime entryTime, int& qIdx, const bool init) const {
326 SUMOTime earliestEntry = SUMOTime_MAX;
327 qIdx = 0;
328 if (myNumVehicles == 0 && myQueues.size() == 1) {
329 // we have always space for at least one vehicle
330 if (myQueues.front().allows(veh->getVClass())) {
331 return entryTime;
332 } else {
333 return earliestEntry;
334 }
335 }
336 const SUMOVehicleClass svc = veh->getVClass();
337 int minSize = std::numeric_limits<int>::max();
338 const MSEdge* const succ = myNextSegment == nullptr ? veh->succEdge(veh->getEdge() == &myEdge ? 1 : 2) : nullptr;
339 for (int i = 0; i < (int)myQueues.size(); i++) {
340 const Queue& q = myQueues[i];
341 const double newOccupancy = q.size() == 0 ? 0. : q.getOccupancy() + veh->getVehicleType().getLengthWithGap();
342 if (newOccupancy <= myQueueCapacity) { // we must ensure that occupancy remains below capacity
343 if (succ == nullptr || myFollowerMap.count(succ) == 0 || ((myFollowerMap.find(succ)->second & (1 << i)) != 0)) {
344 if (q.allows(svc) && q.size() < minSize) {
345 if (init) {
346 // regular insertions and initial insertions must respect different constraints:
347 if (veh->getInsertionChecks() == (int)InsertionCheck::NONE || hasSpaceForInsertion(q, i, newOccupancy, entryTime)) {
348 qIdx = i;
349 minSize = q.size();
350 }
351 } else if (entryTime >= q.getEntryBlockTime()) {
352 qIdx = i;
353 minSize = q.size();
354 } else {
355 earliestEntry = MIN2(earliestEntry, q.getEntryBlockTime());
356 }
357 }
358 }
359 }
360 }
361 if (minSize == std::numeric_limits<int>::max()) {
362 return earliestEntry;
363 }
364 return entryTime;
365}
366
367
368bool
369MESegment::hasSpaceForInsertion(const Queue& q, int /*qIdx*/, double newOccupancy, SUMOTime /*entryTime*/) const {
370 // - regular insertions must respect entryBlockTime
371 // - initial insertions should not cause additional jamming
372 // - inserted vehicle should be able to continue at the current speed
374 return newOccupancy <= myJamThreshold;
375 } else {
376 return newOccupancy <= jamThresholdForSpeed(getMeanSpeed(false), -1);
377 }
378}
379
380
381bool
383 int qIdx = 0;
384 if (hasSpaceFor(veh, time, qIdx, true) == time) {
385 const bool isRail = veh->isRail();
386 // see MSLane::isInsertionSuccess
387 if (isRail && veh->getInsertionChecks() != (int)InsertionCheck::NONE
392 MSEdgeVector occupied;
393 if (dw->foeDriveWayOccupied(false, veh, occupied)) {
394 myEdge.getLanes()[0]->setParameter("insertionBlocked:" + veh->getID(), dw->getID());
395 return false;
396 }
397 }
398 receive(veh, qIdx, time, true);
399 if (isRail) {
400 myEdge.getLanes()[0]->unsetParameter("insertionConstraint:" + veh->getID());
401 //unsetParameter("insertionOrder:" + veh->getID());
402 //unsetParameter("insertionBlocked:" + veh->getID());
405 //if (firstRailSignal != nullptr && firstRailSignal->getJunction()->getType() == SumoXMLNodeType::RAIL_SIGNAL) {
406 // veh->registerInsertionApproach(firstRailSignal, firstRailSignalDist);
407 //}
408 }
409 // we can check only after insertion because insertion may change the route via devices
410 std::string msg;
411 if (MSGlobals::gCheckRoutes && !veh->hasValidRoute(msg)) {
412 throw ProcessError(TLF("Vehicle '%' has no valid route. %", veh->getID(), msg));
413 }
414 return true;
415 }
416 return false;
417}
418
419
420double
421MESegment::getMeanSpeed(bool useCached) const {
422 const SUMOTime currentTime = MSNet::getInstance()->getCurrentTimeStep();
423 if (currentTime != myLastMeanSpeedUpdate || !useCached) {
424 myLastMeanSpeedUpdate = currentTime;
425 double v = 0;
426 int count = 0;
427 for (const Queue& q : myQueues) {
428 const SUMOTime tau = q.getOccupancy() < myJamThreshold ? myTau_ff : myTau_jf;
429 SUMOTime earliestExitTime = currentTime;
430 count += q.size();
431 for (std::vector<MEVehicle*>::const_reverse_iterator veh = q.getVehicles().rbegin(); veh != q.getVehicles().rend(); ++veh) {
432 v += (*veh)->getConservativeSpeed(earliestExitTime); // earliestExitTime is updated!
433 earliestExitTime += tauWithVehLength(tau, (*veh)->getVehicleType().getLengthWithGap(), (*veh)->getVehicleType().getCarFollowModel().getHeadwayTime());
434 }
435 }
436 if (count == 0) {
438 } else {
439 myMeanSpeed = v / (double) count;
440 }
441 }
442 return myMeanSpeed;
443}
444
445
446void
450
451void
453 for (const Queue& q : myQueues) {
454 for (const MEVehicle* const veh : q.getVehicles()) {
456 }
457 }
458}
459
460
463 Queue& q = myQueues[v->getQueIndex()];
464 // One could be tempted to do v->setSegment(next); here but position on lane will be invalid if next == 0
465 v->updateDetectors(leaveTime, v->getEventTime(), true, reason);
467 myEdge.lock();
468 MEVehicle* nextLeader = q.remove(v);
470 myEdge.unlock();
471 return nextLeader;
472}
473
474
477 // since we do not know which queue will be used we give a conservative estimate
478 SUMOTime earliestLeave = earliestEntry;
479 SUMOTime latestEntry = -1;
480 for (const Queue& q : myQueues) {
481 earliestLeave = MAX2(earliestLeave, q.getBlockTime());
482 latestEntry = MAX2(latestEntry, q.getEntryBlockTime());
483 }
484 if (myEdge.getSpeedLimit() == 0) {
485 return MAX2(earliestEntry, latestEntry); // FIXME: This line is just an adhoc-fix to avoid division by zero (Leo)
486 } else {
487 return MAX3(earliestEntry, earliestLeave - TIME2STEPS(myLength / myEdge.getSpeedLimit()), latestEntry);
488 }
489}
490
491
492MSLink*
493MESegment::getLink(const MEVehicle* veh, bool penalty) const {
494 if (myJunctionControl || penalty) {
495 const MSEdge* const nextEdge = veh->succEdge(1);
496 if (nextEdge == nullptr || veh->getQueIndex() == PARKING_QUEUE) {
497 return nullptr;
498 }
499 // try to find any link leading to our next edge, start with the lane pointed to by the que index
500 const MSLane* const bestLane = myEdge.getLanes()[veh->getQueIndex()];
501 for (MSLink* const link : bestLane->getLinkCont()) {
502 if (&link->getLane()->getEdge() == nextEdge) {
503 return link;
504 }
505 }
506 // this is for the non-multique case, maybe we should use caching here !!!
507 for (const MSLane* const lane : myEdge.getLanes()) {
508 if (lane != bestLane) {
509 for (MSLink* const link : lane->getLinkCont()) {
510 if (&link->getLane()->getEdge() == nextEdge) {
511 return link;
512 }
513 }
514 }
515 }
516 }
517 return nullptr;
518}
519
520
521bool
522MESegment::isOpen(const MEVehicle* veh) const {
523#ifdef DEBUG_OPENED
524 if (DEBUG_COND || DEBUG_COND2(veh)) {
525 gDebugFlag1 = true;
526 std::cout << SIMTIME << " opened seg=" << getID() << " veh=" << Named::getIDSecure(veh)
527 << " tlsPenalty=" << myTLSPenalty;
528 const MSLink* link = getLink(veh);
529 if (link == 0) {
530 std::cout << " link=0";
531 } else {
532 std::cout << " prio=" << link->havePriority()
533 << " override=" << limitedControlOverride(link)
534 << " isOpen=" << link->opened(veh->getEventTime(), veh->getSpeed(), veh->estimateLeaveSpeed(link),
537 0, nullptr, false, veh)
538 << " et=" << veh->getEventTime()
539 << " v=" << veh->getSpeed()
540 << " vLeave=" << veh->estimateLeaveSpeed(link)
541 << " impatience=" << veh->getImpatience()
542 << " tWait=" << veh->getWaitingTime();
543 }
544 std::cout << "\n";
545 gDebugFlag1 = false;
546 }
547#endif
548 if (myTLSPenalty) {
549 // XXX should limited control take precedence over tls penalty?
550 return true;
551 }
552 const MSLink* link = getLink(veh);
553 return (link == nullptr
554 || link->havePriority()
556 || link->opened(veh->getEventTime(), veh->getSpeed(), veh->estimateLeaveSpeed(link),
559 0, nullptr, false, veh));
560}
561
562
563bool
565 assert(link != nullptr);
567 return false;
568 }
569 // if the target segment of this link is not saturated junction control is disabled
570 const MSEdge& targetEdge = link->getLane()->getEdge();
571 const MESegment* target = MSGlobals::gMesoNet->getSegmentForEdge(targetEdge);
572 return (target->getBruttoOccupancy() * 2 < target->myJamThreshold) && !targetEdge.isRoundabout();
573}
574
575
577MESegment::computeHeadway(Queue& /*q*/, const Queue& qNext, const MESegment* const next, const MEVehicle* veh) const {
578 const bool nextFree = qNext.getOccupancy() <= next->myJamThreshold;
579 const SUMOTime tau = (!veh->wasJammed()
580 ? (nextFree ? myTau_ff : myTau_fj)
581 : (nextFree ? myTau_jf : getTauJJ((double)qNext.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 headway = (SUMOTime)((double)headway / tllink->getGreenFraction());
589 }
590 }
591 return headway;
592}
593
594
595void
596MESegment::send(MEVehicle* veh, MESegment* const next, const int nextQIdx, SUMOTime time, const MSMoveReminder::Notification reason) {
597 Queue& q = myQueues[veh->getQueIndex()];
598 assert(isInvalid(next) || time >= q.getBlockTime());
599 MSLink* const link = getLink(veh);
600 if (link != nullptr) {
601 link->removeApproaching(veh);
602 }
603 if (veh->isStopped()) {
604 veh->processStop();
605 }
606 MEVehicle* lc = removeCar(veh, time, reason); // new leaderCar
607 q.setBlockTime(time);
608 if (myEdge.isNormal() && myCapacity >= 22.5 ) {
610 }
611 if (!isInvalid(next)) {
612 myLastHeadway = computeHeadway(q, next->myQueues[nextQIdx], next, veh);
613 q.setBlockTime(time + myLastHeadway);
614 }
615 if (lc != nullptr) {
618 }
619}
620
621
623MESegment::getTauJJ(double nextQueueSize, double nextQueueCapacity, double nextJamThreshold) const {
624 // compute coefficients for the jam-jam headway function
625 // this function models the effect that "empty space" needs to move
626 // backwards through the downstream segment before the upstream segment may
627 // send annother vehicle.
628 // this allows jams to clear and move upstream.
629 // the headway function f(x) depends on the number of vehicles in the
630 // downstream segment x
631 // f is a linear function that passes through the following fixed points:
632 // f(n_jam_threshold) = tau_jf_withLength (for continuity)
633 // f(headwayCapacity) = myTau_jj * headwayCapacity
634
635 const SUMOTime tau_jf_withLength = tauWithVehLength(myTau_jf, DEFAULT_VEH_LENGTH_WITH_GAP, 1.);
636 // number of vehicles that fit into the NEXT queue (could be larger than expected with DEFAULT_VEH_LENGTH_WITH_GAP!)
637 const double headwayCapacity = MAX2(nextQueueSize, nextQueueCapacity / DEFAULT_VEH_LENGTH_WITH_GAP);
638 // number of vehicles above which the NEXT queue is jammed
639 const double n_jam_threshold = headwayCapacity * nextJamThreshold / nextQueueCapacity;
640
641 // slope a and axis offset b for the jam-jam headway function
642 // solving f(x) = a * x + b
643 const double a = (STEPS2TIME(myTau_jj) * headwayCapacity - STEPS2TIME(tau_jf_withLength)) / (headwayCapacity - n_jam_threshold);
644 const double b = headwayCapacity * (STEPS2TIME(myTau_jj) - a);
645
646 // it is only well defined for nextQueueSize >= n_jam_threshold (which may not be the case for longer vehicles), so we take the MAX
647 return TIME2STEPS(a * MAX2(nextQueueSize, n_jam_threshold) + b);
648}
649
650
651bool
655
656
657void
659 if (veh->getQueIndex() != PARKING_QUEUE) {
660 myQueues[veh->getQueIndex()].addReminders(veh);
661 }
662}
663
664
665void
666MESegment::receive(MEVehicle* veh, const int qIdx, SUMOTime time, const bool isDepart, const bool isTeleport, const bool newEdge) {
667 const double speed = isDepart ? -1 : MAX2(veh->getSpeed(), MESO_MIN_SPEED); // on the previous segment
668 veh->setSegment(this); // for arrival checking
669 veh->setLastEntryTime(time);
671 if (!isDepart && (
672 // arrival on entering a new edge
673 (newEdge && myEdge.isNormal() && veh->moveRoutePointer())
674 // arrival on entering a new segment
675 || veh->hasArrived())) {
676 // route has ended
677 veh->setEventTime(time + TIME2STEPS(myLength / speed)); // for correct arrival speed
678 addReminders(veh);
680 veh->updateDetectors(time, veh->getEventTime(), true,
683 return;
684 }
685 assert(veh->getEdge() == &getEdge() || getEdge().isInternal());
686 // route continues
687 Queue& q = myQueues[qIdx];
688 const double maxSpeedOnEdge = veh->getEdge()->getLanes()[qIdx]->getVehicleMaxSpeed(veh);
689 const double uspeed = MAX2(maxSpeedOnEdge, MESO_MIN_SPEED);
690 std::vector<MEVehicle*>& cars = q.getModifiableVehicles();
691 MEVehicle* newLeader = nullptr; // first vehicle in the current queue
692 const SUMOTime stopTime = veh->checkStop(time);
693 SUMOTime tleave = MAX2(stopTime + TIME2STEPS(myLength / uspeed) + getLinkPenalty(veh), q.getBlockTime());
694 if (veh->isStopped()) {
695 myEdge.addWaiting(veh);
696 }
697 if (veh->isParking()) {
698 // parking stops should take at least 1ms
699 veh->setEventTime(MAX2(stopTime, veh->getEventTime() + 1));
700 veh->setSegment(this, PARKING_QUEUE);
701 myEdge.getLanes()[0]->addParking(veh); // TODO for GUI only
702 } else {
703 myEdge.lock();
704 if (cars.empty()) {
705 cars.push_back(veh);
706 newLeader = veh;
707 } else {
708 SUMOTime leaderOut = cars[0]->getEventTime();
709 if (!isDepart && leaderOut > tleave && overtake()) {
710 if (cars.size() == 1) {
712 newLeader = veh;
713 }
714 cars.insert(cars.begin() + 1, veh);
715 } else {
716 tleave = MAX2(leaderOut + tauWithVehLength(myTau_ff, cars[0]->getVehicleType().getLengthWithGap(), cars[0]->getVehicleType().getCarFollowModel().getHeadwayTime()), tleave);
717 cars.insert(cars.begin(), veh);
718 }
719 }
721 myEdge.unlock();
723 if (!isDepart && !isTeleport) {
724 // departs and teleports could take place anywhere on the edge so they should not block regular flow
725 // the -1 facilitates interleaving of multiple streams
727 }
729 veh->setEventTime(tleave);
730 veh->setUnqueuedEventTime(tleave);
731 veh->setSegment(this, qIdx);
732 }
733 addReminders(veh);
734 if (isDepart) {
735 veh->onDepart();
737 } else if (newEdge) {
739 } else {
741 }
742 if (veh->isParking()) {
743 MSGlobals::gMesoNet->addLeaderCar(veh, nullptr);
744 } else {
745 if (newLeader != nullptr) {
746 MSGlobals::gMesoNet->addLeaderCar(newLeader, getLink(newLeader));
747 }
748 }
749}
750
751
752bool
754 for (const Queue& q : myQueues) {
755 if (q.size() > 0) {
756 for (MEVehicle* const veh : q.getVehicles()) {
757 if (filter->vehicleApplies(*veh)) {
760 return true;
761 }
762 }
763 }
764 }
765 return false;
766}
767
768
769void
770MESegment::setSpeedForQueue(double newSpeed, SUMOTime currentTime, SUMOTime blockTime, const std::vector<MEVehicle*>& vehs) {
771 MEVehicle* v = vehs.back();
772 SUMOTime oldEarliestExitTime = currentTime;
773 const SUMOTime oldExit = MAX2(oldEarliestExitTime, v->getEventTime());
774 v->updateDetectors(currentTime, oldExit, false);
776 SUMOTime newEvent = MAX2(newArrival(v, newSpeed, currentTime), blockTime);
777 if (v->getEventTime() != newEvent) {
779 v->setEventTime(newEvent);
781 }
782 for (std::vector<MEVehicle*>::const_reverse_iterator i = vehs.rbegin() + 1; i != vehs.rend(); ++i) {
783 const SUMOTime oldExitTime = MAX2(oldEarliestExitTime, (*i)->getEventTime());
784 (*i)->updateDetectors(currentTime, oldExitTime, false);
785 const SUMOTime minTau = tauWithVehLength(myTau_ff, (*i)->getVehicleType().getLengthWithGap(), (*i)->getVehicleType().getCarFollowModel().getHeadwayTime());
786 oldEarliestExitTime = oldExitTime + minTau;
787 newEvent = MAX2(newArrival(*i, newSpeed, currentTime), newEvent + minTau);
788 (*i)->setEventTime(newEvent);
789 }
790}
791
792
794MESegment::newArrival(const MEVehicle* const v, double newSpeed, SUMOTime currentTime) {
795 // since speed is only an upper bound, pos may be too optimistic
796 const double pos = MIN2(myLength, STEPS2TIME(currentTime - v->getLastEntryTime()) * v->getSpeed());
797 // traveltime may not be 0
798 double tt = (myLength - pos) / MAX2(newSpeed, MESO_MIN_SPEED);
799 return currentTime + MAX2(TIME2STEPS(tt), SUMOTime(1));
800}
801
802
803void
804MESegment::setSpeed(double newSpeed, SUMOTime currentTime, double jamThresh, int qIdx) {
805 recomputeJamThreshold(jamThresh);
806 //myTau_length = MAX2(MESO_MIN_SPEED, newSpeed) * myEdge.getLanes().size() / TIME2STEPS(1);
807 int i = 0;
808 for (const Queue& q : myQueues) {
809 if (q.size() != 0) {
810 if (qIdx == -1 || qIdx == i) {
811 setSpeedForQueue(newSpeed, currentTime, q.getBlockTime(), q.getVehicles());
812 }
813 }
814 i++;
815 }
816}
817
818
821 SUMOTime result = SUMOTime_MAX;
822 for (const Queue& q : myQueues) {
823 if (q.size() != 0 && q.getVehicles().back()->getEventTime() < result) {
824 result = q.getVehicles().back()->getEventTime();
825 }
826 }
827 if (result < SUMOTime_MAX) {
828 return result;
829 }
830 return -1;
831}
832
833
834void
836 bool write = false;
837 for (const Queue& q : myQueues) {
838 if (q.getBlockTime() != -1 || !q.getVehicles().empty()) {
839 write = true;
840 break;
841 }
842 }
843 if (write) {
845 for (const Queue& q : myQueues) {
847 out.writeAttr(SUMO_ATTR_TIME, toString<SUMOTime>(q.getBlockTime()));
848 out.writeAttr(SUMO_ATTR_BLOCKTIME, toString<SUMOTime>(q.getEntryBlockTime()));
849 out.writeAttr(SUMO_ATTR_VALUE, q.getVehicles());
850 out.closeTag();
851 }
852 out.closeTag();
853 }
854}
855
856
857void
859 for (Queue& q : myQueues) {
860 q.getModifiableVehicles().clear();
861 }
862}
863
864void
865MESegment::loadState(const std::vector<SUMOVehicle*>& vehs, const SUMOTime blockTime, const SUMOTime entryBlockTime, const int queIdx) {
866 Queue& q = myQueues[queIdx];
867 for (SUMOVehicle* veh : vehs) {
868 MEVehicle* v = static_cast<MEVehicle*>(veh);
869 assert(v->getSegment() == this || myEdge.isInternal());
870 if (myEdge.isInternal()) {
871 v->setSegment(this, v->getQueIndex());
872 }
873 q.getModifiableVehicles().push_back(v);
876 addReminders(v);
877 }
878 if (q.size() != 0) {
879 // add the last vehicle of this queue
880 // !!! one question - what about the previously added vehicle? Is it stored twice?
881 MEVehicle* veh = q.getVehicles().back();
883 }
884 q.setBlockTime(blockTime);
885 q.setEntryBlockTime(entryBlockTime);
887}
888
889
890std::vector<const MEVehicle*>
892 std::vector<const MEVehicle*> result;
893 for (const Queue& q : myQueues) {
894 result.insert(result.end(), q.getVehicles().begin(), q.getVehicles().end());
895 }
896 return result;
897}
898
899
900bool
902 for (const Queue& q : myQueues) {
903 if (q.size() > 0 && q.getVehicles().back()->getWaitingTime() > 0) {
904 return true;
905 }
906 }
907 return false;
908}
909
910
911double
913 return 3600 * getCarNumber() * getMeanSpeed() / myLength;
914}
915
916
919 const MSLink* link = getLink(veh, myTLSPenalty || myCheckMinorPenalty);
920 if (link != nullptr) {
921 SUMOTime result = 0;
922 if (link->isTLSControlled() && myTLSPenalty) {
923 result += link->getMesoTLSPenalty();
924 }
925 // minor tls links may get an additional penalty
926 if (!link->havePriority() &&
927 // do not apply penalty on top of tLSPenalty
928 !myTLSPenalty &&
929 // do not apply penalty if limited control is active
931 result += myMinorPenalty;
932 }
933 return result;
934 } else {
935 return 0;
936 }
937}
938
939
940double
942 double result = 0;
943 for (const Queue& q : myQueues) {
944 // @note: only the leader currently accumulates waitingTime but this might change in the future
945 for (const MEVehicle* veh : q.getVehicles()) {
946 result += veh->getWaitingSeconds();
947 }
948 }
949 return result;
950}
951
952
953/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
#define DEFAULT_VEH_LENGTH_WITH_GAP
#define DEBUG_COND2(obj)
#define MESO_MIN_SPEED
Definition MESegment.cpp:49
std::vector< MSEdge * > MSEdgeVector
Definition MSEdge.h:73
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:287
#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
const SVCPermissions SVCAll
all VClasses are allowed
const std::string & getVehicleClassNames(SVCPermissions permissions, bool expand)
Returns the ids of the given classes, divided using a ' '.
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:361
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:88
MESegment * getSegmentForEdge(const MSEdge &e, double pos=0)
Get the segment for a given edge at a given position.
Definition MELoop.cpp:344
void addLeaderCar(MEVehicle *veh, MSLink *link)
Adds the given car to the leading vehicles.
Definition MELoop.cpp:251
void removeLeaderCar(MEVehicle *v)
Removes the given car from the leading vehicles.
Definition MELoop.cpp:265
int size() const
Definition MESegment.h:77
void setOccupancy(const double occ)
Definition MESegment.h:90
MEVehicle * remove(MEVehicle *v)
Definition MESegment.cpp:73
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:98
void addDetector(MSMoveReminder *data)
Definition MESegment.cpp:90
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:590
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:538
SUMOTime myTau_ff
The time headway parameters, see the Eissfeldt thesis.
Definition MESegment.h:567
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:596
double getBruttoOccupancy() const
Returns the occupany of the segment (the sum of the vehicle lengths + minGaps)
Definition MESegment.h:270
SUMOTime myLastHeadway
the last headway
Definition MESegment.h:605
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.
static SVCPermissions myMultiModalWarnings
Definition MESegment.h:612
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:602
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:599
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:374
static MESegment myVaporizationTarget
Definition MESegment.h:610
double myJamThreshold
The space (in m) which needs to be occupied before the segment is considered jammed.
Definition MESegment.h:593
const int myIndex
Running number of the segment in the edge.
Definition MESegment.h:561
virtual 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:574
double myMeanSpeed
the mean speed on this segment. Updated at event time or on demand
Definition MESegment.h:615
bool myCheckMinorPenalty
penalty for minor links
Definition MESegment.h:573
virtual SUMOTime computeHeadway(Queue &q, const Queue &qNext, const MESegment *const next, const MEVehicle *veh) const
compute current headway depending on traffic state
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:618
SUMOTime myTau_jf
Definition MESegment.h:567
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:555
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:558
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:552
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:609
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:309
int getCarNumber() const
Returns the total number of cars on the segment.
Definition MESegment.h:213
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:584
SUMOTime myTau_jj
Definition MESegment.h:567
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:577
virtual bool hasSpaceForInsertion(const Queue &q, int qIdx, double newOccupancy, SUMOTime entryTime) const
check jam-avoidance constraints during insertion
bool myTLSPenalty
Whether tls penalty is enabled.
Definition MESegment.h:570
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:457
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:587
bool myOvertaking
Whether overtaking is permitted on this segment.
Definition MESegment.h:580
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:567
SUMOTime getTauJJ(double nextQueueSize, double nextQueueCapacity, double nextJamThreshold) const
A vehicle from the mesoscopic point of view.
Definition MEVehicle.h:42
void markJammed(bool jammed)
Definition MEVehicle.h:372
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:306
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...
void setUnqueuedEventTime(SUMOTime t)
Sets the minimum time at which the vehicle leaves its current segment (this includes planned stops)
Definition MEVehicle.h:222
SUMOTime getLastEntryTime() const
Returns the time the vehicle entered the current segment.
Definition MEVehicle.h:277
void setEventTime(SUMOTime t, bool hasDelay=true)
Sets the (planned) time at which the vehicle leaves its current segment.
Definition MEVehicle.h:203
MESegment * getSegment() const
Returns the current segment the vehicle is on.
Definition MEVehicle.h:246
bool wasJammed() const
Definition MEVehicle.h:376
void setLastEntryTime(SUMOTime t)
Sets the entry time for the current segment.
Definition MEVehicle.h:269
int getQueIndex() const
Returns the index of the que the vehicle is in.
Definition MEVehicle.h:255
virtual void setSegment(MESegment *s, int idx=0)
Sets the current segment the vehicle is at together with its que.
Definition MEVehicle.h:237
SUMOTime getEventTime() const
Returns the (planned) time at which the vehicle leaves its current segment.
Definition MEVehicle.h:215
void setBlockTime(const SUMOTime t)
Sets the time at which the vehicle was blocked.
Definition MEVehicle.h:291
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:285
virtual double getHeadwayTime() const
Get the driver's desired headway [s].
Definition MSCFModel.h:355
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:801
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:488
void invalidateMesoCache() const
Definition MSEdge.h:897
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:1200
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:742
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:1500
bool hasMinorLink() const
whether any lane has a minor link
Definition MSEdge.cpp:1399
virtual void lock() const
grant exclusive access to the mesoscopic state
Definition MSEdge.h:798
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition MSEdge.cpp:1307
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:790
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
Definition MSLane.h:750
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:53
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:66
const std::string & getID() const
Returns the id.
Definition Named.h:73
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, const bool escape=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