Eclipse SUMO - Simulation of Urban MObility
MSCalibrator.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3// Copyright (C) 2005-2022 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
20// Calibrates the flow on an edge by removing an inserting vehicles
21/****************************************************************************/
22#include <config.h>
23
24#include <string>
25#include <algorithm>
26#include <cmath>
27#include <microsim/MSNet.h>
28#include <microsim/MSEdge.h>
29#include <microsim/MSLane.h>
37#include <utils/xml/XMLSubSys.h>
43#include "MSCalibrator.h"
44
45//#define MSCalibrator_DEBUG
46
47#define DEBUGID ""
48#define DEBUGCOND (getID() == DEBUGID)
49#define DEBUGCOND2(id) ((id) == DEBUGID)
50
51// ===========================================================================
52// static members
53// ===========================================================================
54std::vector<MSMoveReminder*> MSCalibrator::myLeftoverReminders;
55std::vector<SUMOVehicleParameter*> MSCalibrator::myLeftoverVehicleParameters;
56std::map<std::string, MSCalibrator*> MSCalibrator::myInstances;
57
58// ===========================================================================
59// CalibratorCommand method definitions
60// ===========================================================================
61
64 UNUSED_PARAMETER(currentTime);
65 UNUSED_PARAMETER(execTime);
66 UNUSED_PARAMETER(newTime);
68 return 0;
69}
70
71
72// ===========================================================================
73// method definitions
74// ===========================================================================
75MSCalibrator::MSCalibrator(const std::string& id,
76 const MSEdge* const edge,
77 MSLane* lane,
78 const double pos,
79 const std::string& aXMLFilename,
80 const std::string& outputFilename,
81 const SUMOTime freq, const double length,
82 const MSRouteProbe* probe,
83 const double invalidJamThreshold,
84 const std::string& vTypes,
85 bool addLaneMeanData) :
86 MSRouteHandler(aXMLFilename, true),
87 MSDetectorFileOutput(id, vTypes, "", (int)PersonMode::NONE), // detecting persons not yet supported
88 myEdge(edge),
89 myLane(lane),
90 myPos(pos), myProbe(probe),
91 myMeanDataParent(id + "_dummyMeanData", 0, 0, false, false, false, false, false, false, 1, 0, 0, vTypes, "",
92 std::vector<MSEdge*>(), false),
93 myEdgeMeanData(nullptr, length, false, &myMeanDataParent),
95 myOutput(nullptr), myFrequency(freq), myRemoved(0),
96 myInserted(0),
98 mySpeedIsDefault(true), myDidSpeedAdaption(false), myDidInit(false),
99 myDefaultSpeed(myLane == nullptr ? myEdge->getSpeedLimit() : myLane->getSpeedLimit()),
101 myAmActive(false),
102 myInvalidJamThreshold(invalidJamThreshold),
103 myHaveInvalidJam(false) {
104 myInstances[id] = this;
105 if (outputFilename != "") {
106 myOutput = &OutputDevice::getDevice(outputFilename);
108 }
109 if (aXMLFilename != "") {
110 XMLSubSys::runParser(*this, aXMLFilename);
111 if (!myDidInit) {
112 init();
113 }
114 }
115 if (addLaneMeanData) {
116 // disabled for METriggeredCalibrator
117 for (MSLane* const eLane : myEdge->getLanes()) {
118 if (myLane == nullptr || myLane == eLane) {
119 //std::cout << " cali=" << getID() << " myLane=" << Named::getIDSecure(myLane) << " checkLane=" << i << "\n";
120 MSMeanData_Net::MSLaneMeanDataValues* laneData = new MSMeanData_Net::MSLaneMeanDataValues(eLane, eLane->getLength(), true, &myMeanDataParent);
121 laneData->setDescription("meandata_calibrator_" + eLane->getID());
122 myLeftoverReminders.push_back(laneData);
123 myLaneMeanData.push_back(laneData);
124 VehicleRemover* remover = new VehicleRemover(eLane, this);
125 myLeftoverReminders.push_back(remover);
126 myVehicleRemovers.push_back(remover);
127 }
128 }
129 }
130}
131
132
133void
135 if (myIntervals.size() > 0) {
136 if (myIntervals.back().end == -1) {
137 myIntervals.back().end = SUMOTime_MAX;
138 }
139 // calibration should happen after regular insertions have taken place
141 } else {
142 WRITE_WARNING("No flow intervals in calibrator '" + getID() + "'.");
143 }
144 myDidInit = true;
145}
146
147
149 if (myCurrentStateInterval != myIntervals.end()) {
150 intervalEnd();
151 }
152 for (VehicleRemover* const remover : myVehicleRemovers) {
153 remover->disable();
154 }
155 myInstances.erase(getID());
156}
157
160 if (myCurrentStateInterval == myIntervals.end()) {
161 throw ProcessError("Calibrator '" + getID() + "' has no active or upcoming interval");
162 }
164}
165
166void
168 const SUMOSAXAttributes& attrs) {
169 if (element == SUMO_TAG_FLOW) {
170 AspiredState state;
171 SUMOTime lastEnd = -1;
172 if (myIntervals.size() > 0) {
173 lastEnd = myIntervals.back().end;
174 if (lastEnd == -1) {
175 lastEnd = myIntervals.back().begin;
176 }
177 }
178 try {
179 bool ok = true;
180 state.q = attrs.getOpt<double>(SUMO_ATTR_VEHSPERHOUR, nullptr, ok, -1.);
181 state.v = attrs.getOpt<double>(SUMO_ATTR_SPEED, nullptr, ok, -1.);
182 state.begin = attrs.getSUMOTimeReporting(SUMO_ATTR_BEGIN, getID().c_str(), ok);
183 if (state.begin < lastEnd) {
184 WRITE_ERROR("Overlapping or unsorted intervals in calibrator '" + getID() + "'.");
185 }
186 state.end = attrs.getOptSUMOTimeReporting(SUMO_ATTR_END, getID().c_str(), ok, -1);
187 state.vehicleParameter = SUMOVehicleParserHelper::parseVehicleAttributes(element, attrs, true, true, true);
188 state.vehicleParameter->parametersSet &= ~VEHPARS_CALIBRATORSPEED_SET;
190 // vehicles should be inserted with max speed unless stated otherwise
193 }
194 // vehicles should be inserted on any lane unless stated otherwise
196 if (myLane == nullptr) {
198 } else {
201 }
202 } else if (myLane != nullptr && (
204 || state.vehicleParameter->departLane != myLane->getIndex())) {
205 WRITE_WARNING("Insertion lane may differ from calibrator lane for calibrator '" + getID() + "'.");
206 }
209 WRITE_ERROR("Unknown vehicle type '" + state.vehicleParameter->vtypeid + "' in calibrator '" + getID() + "'.");
210 }
211 } catch (EmptyData&) {
212 WRITE_ERROR("Mandatory attribute missing in definition of calibrator '" + getID() + "'.");
213 } catch (NumberFormatException&) {
214 WRITE_ERROR("Non-numeric value for numeric attribute in definition of calibrator '" + getID() + "'.");
215 }
216 if (state.q < 0 && state.v < 0 && state.vehicleParameter->vtypeid == DEFAULT_VTYPE_ID) {
217 WRITE_ERROR("Either 'vehsPerHour', 'speed' or 'type' has to be set in flow definition of calibrator '" + getID() + "'.");
218 }
219 if (MSGlobals::gUseMesoSim && state.q < 0 && state.vehicleParameter->vtypeid != DEFAULT_VTYPE_ID) {
220 WRITE_ERROR("Type calibration is not supported in meso for calibrator '" + getID() + "'.");
221 }
222 if (myIntervals.size() > 0 && myIntervals.back().end == -1) {
223 myIntervals.back().end = state.begin;
224 }
225 myIntervals.push_back(state);
227 } else {
228 MSRouteHandler::myStartElement(element, attrs);
229 }
230}
231
232
233void
235 if (element == SUMO_TAG_CALIBRATOR) {
236 if (!myDidInit) {
237 init();
238 }
239 // ensure correct state of SUMORouteHandler::myElementStack
240 callParentEnd(element);
241 } else if (element != SUMO_TAG_FLOW) {
243 }
244}
245
246
247void
249 if (myOutput != nullptr) {
251 }
252 myDidSpeedAdaption = false;
253 myInserted = 0;
254 myRemoved = 0;
255 myClearedInJam = 0;
257 reset();
258}
259
260
261bool
263 while (myCurrentStateInterval != myIntervals.end() && myCurrentStateInterval->end <= time) {
264 // XXX what about skipped intervals?
266 }
267 return myCurrentStateInterval != myIntervals.end() &&
268 myCurrentStateInterval->begin <= time && myCurrentStateInterval->end > time;
269}
270
271
272int
274 if (myCurrentStateInterval != myIntervals.end()) {
275 const double totalHourFraction = STEPS2TIME(myCurrentStateInterval->end - myCurrentStateInterval->begin) / (double) 3600.;
276 return (int)std::floor(myCurrentStateInterval->q * totalHourFraction + 0.5); // round to closest int
277 } else {
278 return -1;
279 }
280}
281
282
283double
285 const double totalHourFraction = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep() - myCurrentStateInterval->begin) / (double) 3600.;
286 return passed() / totalHourFraction;
287}
288
289
290double
292 if (myEdgeMeanData.getSamples() > 0) {
294 } else {
295 return -1;
296 }
297}
298
299
300bool
302 if (myToRemove.size() > 0) {
304 // it is not save to remove the vehicles inside
305 // VehicleRemover::notifyEnter so we do it here
306 for (std::set<std::string>::iterator it = myToRemove.begin(); it != myToRemove.end(); ++it) {
307 MSVehicle* vehicle = dynamic_cast<MSVehicle*>(vc.getVehicle(*it));
308 if (vehicle != nullptr) {
309 MSLane* lane = vehicle->getMutableLane();
312 vc.scheduleVehicleRemoval(vehicle, true);
313 } else {
314 WRITE_WARNING("Calibrator '" + getID() + "' could not remove vehicle '" + *it + "' time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
315 }
316 }
317 myToRemove.clear();
318 return true;
319 }
320 return false;
321}
322
323
326 const bool calibrateFlow = myCurrentStateInterval->q >= 0;
327 const bool calibrateSpeed = myCurrentStateInterval->v >= 0;
328 // get current simulation values (valid for the last simulation second)
329 myHaveInvalidJam = (calibrateFlow || calibrateSpeed) && invalidJam(myLane == 0 ? -1 : myLane->getIndex());
330 // XXX could we miss vehicle movements if this is called less often than every DELTA_T (default) ?
332 const bool hadRemovals = removePending();
333 // check whether an adaptation value exists
334 if (isCurrentStateActive(currentTime)) {
335 myAmActive = true;
336 // all happens in isCurrentStateActive()
337 } else {
338 myAmActive = false;
339 reset();
340 if (!mySpeedIsDefault) {
341 // reset speed to default
342 if (myLane == nullptr) {
344 } else {
346 }
347 mySpeedIsDefault = true;
348 }
349 if (myCurrentStateInterval == myIntervals.end()) {
350 // keep calibrator alive for gui but do not call again
351 return TIME2STEPS(86400);
352 }
353 return myFrequency;
354 }
355 // we are active
356 if (!myDidSpeedAdaption && calibrateSpeed) {
357 if (myLane == nullptr) {
359 } else {
361 }
362 mySpeedIsDefault = false;
363 myDidSpeedAdaption = true;
364 }
365
366 const int totalWishedNum = totalWished();
367 int adaptedNum = passed() + myClearedInJam;
368#ifdef MSCalibrator_DEBUG
369 if (DEBUGCOND) {
370 std::cout << time2string(currentTime) << " " << getID()
371 << " q=" << myCurrentStateInterval->q
372 << " totalWished=" << totalWishedNum
373 << " adapted=" << adaptedNum
374 << " jam=" << myHaveInvalidJam
375 << " entered=" << myEdgeMeanData.nVehEntered
376 << " departed=" << myEdgeMeanData.nVehDeparted
377 << " arrived=" << myEdgeMeanData.nVehArrived
378 << " left=" << myEdgeMeanData.nVehLeft
379 << " waitSecs=" << myEdgeMeanData.waitSeconds
380 << " vaporized=" << myEdgeMeanData.nVehVaporized
381 << "\n";
382 }
383#endif
384 if (calibrateFlow && adaptedNum < totalWishedNum && !hadRemovals) {
385 // we need to insert some vehicles
386 const double hourFraction = STEPS2TIME(currentTime - myCurrentStateInterval->begin + DELTA_T) / (double) 3600.;
387 const int wishedNum = (int)std::floor(myCurrentStateInterval->q * hourFraction + 0.5); // round to closest int
388 // only the difference between inflow and aspiredFlow should be added, thus
389 // we should not count vehicles vaporized from a jam here
390 // if we have enough time left we can add missing vehicles later
391 const int relaxedInsertion = (int)std::floor(STEPS2TIME(myCurrentStateInterval->end - currentTime) / 3);
392 const int insertionSlack = MAX2(0, adaptedNum + relaxedInsertion - totalWishedNum);
393 // increase number of vehicles
394#ifdef MSCalibrator_DEBUG
395 if (DEBUGCOND) {
396 std::cout << " wished:" << wishedNum
397 << " slack:" << insertionSlack
398 << " before:" << adaptedNum
399 << "\n";
400 }
401#endif
403 while (wishedNum > adaptedNum + insertionSlack) {
404 SUMOVehicleParameter* pars = myCurrentStateInterval->vehicleParameter;
405 const MSRoute* route = myProbe != nullptr ? myProbe->sampleRoute() : nullptr;
406 if (route == nullptr) {
407 route = MSRoute::dictionary(pars->routeid);
408 }
409 if (route == nullptr) {
410 WRITE_WARNING("No valid routes in calibrator '" + getID() + "'.");
411 break;
412 }
413 if (!route->contains(myEdge)) {
414 WRITE_WARNING("Route '" + route->getID() + "' in calibrator '" + getID() + "' does not contain edge '" + myEdge->getID() + "'.");
415 break;
416 }
417 const int routeIndex = (int)std::distance(route->begin(),
418 std::find(route->begin(), route->end(), myEdge));
419 MSVehicleType* vtype = vc.getVType(pars->vtypeid);
420 assert(route != 0 && vtype != 0);
421 // build the vehicle
422 const std::string newID = getNewVehicleID();
423 if (vc.getVehicle(newID) != nullptr) {
424 ;
425 // duplicate ids could come from loading state
426 myInserted++;
427 break;
428 }
429 SUMOVehicleParameter* newPars = new SUMOVehicleParameter(*pars);
430 newPars->id = newID;
431 newPars->depart = currentTime;
432 newPars->routeid = route->getID();
433 newPars->departLaneProcedure = DepartLaneDefinition::FIRST_ALLOWED; // ensure successful vehicle creation
434 MSVehicle* vehicle;
435 try {
436 vehicle = dynamic_cast<MSVehicle*>(vc.buildVehicle(newPars, route, vtype, true, false));
437 } catch (const ProcessError& e) {
439 WRITE_WARNING(e.what());
440 vehicle = nullptr;
441 break;
442 } else {
443 throw e;
444 }
445 }
446#ifdef MSCalibrator_DEBUG
447 if (DEBUGCOND) {
448 std::cout << " resetting route pos: " << routeIndex << "\n";
449 }
450#endif
451 vehicle->resetRoutePosition(routeIndex, pars->departLaneProcedure);
452 if (myEdge->insertVehicle(*vehicle, currentTime)) {
453 if (!MSNet::getInstance()->getVehicleControl().addVehicle(vehicle->getID(), vehicle)) {
454 throw ProcessError("Emission of vehicle '" + vehicle->getID() + "' in calibrator '" + getID() + "'failed!");
455 }
456 myInserted++;
457 adaptedNum++;
458#ifdef MSCalibrator_DEBUG
459 if (DEBUGCOND) {
460 std::cout << "I ";
461 }
462#endif
463 } else {
464 // could not insert vehicle
465#ifdef MSCalibrator_DEBUG
466 if (DEBUGCOND) {
467 std::cout << "F ";
468 }
469#endif
471 break;
472 }
473 }
474 }
475 if (myCurrentStateInterval->end <= currentTime + myFrequency) {
476 intervalEnd();
477 }
478 return myFrequency;
479}
480
481void
485 val->reset();
486 }
487}
488
489
490bool
491MSCalibrator::invalidJam(int laneIndex) const {
492 if (laneIndex < 0) {
493 const int numLanes = (int)myEdge->getLanes().size();
494 for (int i = 0; i < numLanes; ++i) {
495 if (invalidJam(i)) {
496 return true;
497 }
498 }
499 return false;
500 }
501 assert(laneIndex < (int)myEdge->getLanes().size());
502 const MSLane* const lane = myEdge->getLanes()[laneIndex];
503 if (lane->getVehicleNumber() < 4) {
504 // cannot reliably detect invalid jams
505 return false;
506 }
507 // maxSpeed reflects the calibration target
508 const bool toSlow = lane->getMeanSpeed() < myInvalidJamThreshold * myEdge->getSpeedLimit();
509 return toSlow && remainingVehicleCapacity(laneIndex) < 1;
510}
511
512
513int
515 if (laneIndex < 0) {
516 const int numLanes = (int)myEdge->getLanes().size();
517 int result = 0;
518 for (int i = 0; i < numLanes; ++i) {
519 result = MAX2(result, remainingVehicleCapacity(i));
520 }
521 return result;
522 }
523 assert(laneIndex < (int)myEdge->getLanes().size());
524 MSLane* lane = myEdge->getLanes()[laneIndex];
525 MSVehicle* last = lane->getLastFullVehicle();
526 const SUMOVehicleParameter* pars = myCurrentStateInterval->vehicleParameter;
528 const double spacePerVehicle = vtype->getLengthWithGap() + myEdge->getSpeedLimit() * vtype->getCarFollowModel().getHeadwayTime();
529 int overallSpaceLeft = (int)ceil(lane->getLength() / spacePerVehicle) - lane->getVehicleNumber();
530 if (last != nullptr) {
531 int entrySpaceLeft = (int)(last->getPositionOnLane() / spacePerVehicle);
532 return MAX2(overallSpaceLeft, entrySpaceLeft);
533 } else {
534 return overallSpaceLeft;
535 }
536}
537
538
539void
541 while (!myInstances.empty()) {
542 delete myInstances.begin()->second;
543 }
545 delete rem;
546 }
547 myLeftoverReminders.clear();
549 delete par;
550 }
552}
553
554
555void
558 for (std::vector<MSMeanData_Net::MSLaneMeanDataValues*>::iterator it = myLaneMeanData.begin();
559 it != myLaneMeanData.end(); ++it) {
560 (*it)->addTo(myEdgeMeanData);
561 }
562}
563
564
565bool
567 if (myParent == nullptr) {
568 return false;
569 }
570 if (!myParent->vehicleApplies(veh)) {
571 return false;
572 }
573 if (myParent->isActive()) {
575 const bool calibrateFlow = myParent->myCurrentStateInterval->q >= 0;
576 const int totalWishedNum = myParent->totalWished();
577 int adaptedNum = myParent->passed() + myParent->myClearedInJam;
578 if (calibrateFlow && adaptedNum > totalWishedNum) {
579#ifdef MSCalibrator_DEBUG
580 if (DEBUGCOND2(myParent->getID())) std::cout << time2string(MSNet::getInstance()->getCurrentTimeStep()) << " " << myParent->getID()
581 << " vaporizing " << vehicle->getID() << " to reduce flow\n";
582#endif
583 if (myParent->scheduleRemoval(&veh)) {
585 }
586 } else if (myParent->myHaveInvalidJam) {
587#ifdef MSCalibrator_DEBUG
588 if (DEBUGCOND2(myParent->getID())) std::cout << time2string(MSNet::getInstance()->getCurrentTimeStep()) << " " << myParent->getID()
589 << " vaporizing " << vehicle->getID() << " to clear jam\n";
590#endif
592 WRITE_WARNINGF(TL("Clearing jam at calibrator '%' at time=%."), myParent->getID(), time2string(SIMSTEP));
594 }
595 if (myParent->scheduleRemoval(&veh)) {
597 }
598 }
599 const std::string typeID = myParent->myCurrentStateInterval->vehicleParameter->vtypeid;
600 if (!calibrateFlow && typeID != DEFAULT_VTYPE_ID) {
601 // calibrate type
602 const std::string origType = veh.getParameter().vtypeid; // could by id of vTypeDistribution
604 const RandomDistributor<MSVehicleType*>* oldDist = vc.getVTypeDistribution(origType);
606 bool matchDistribution = false;
607 if (oldDist != nullptr && newDist != nullptr && oldDist->getVals().size() == newDist->getVals().size()) {
608 auto it = std::find(oldDist->getVals().begin(), oldDist->getVals().end(), &veh.getVehicleType());
609 if (it != oldDist->getVals().end()) {
610 matchDistribution = true;
611 const int distIndex = (int)(it - oldDist->getVals().begin());
612 veh.replaceVehicleType(newDist->getVals()[distIndex]);
613 }
614 }
615 if (!matchDistribution) {
617 if (vehicleType == nullptr) {
618 throw ProcessError("Unknown vehicle type '" + typeID + "' in calibrator '" + myParent->getID() + "'");
619 }
620 veh.replaceVehicleType(vehicleType);
621 }
622 }
623 }
624 return true;
625}
626
627
628void
631 const int p = passed();
632 // meandata will be off if vehicles are removed on the next edge instead of this one
634 //assert(discrepancy >= 0); may go negative for lane calibrator when vehicles change lane before removal
635 const std::string ds = (discrepancy > 0 ? "\" vaporizedOnNextEdge=\"" + toString(discrepancy) : "");
636 const double durationSeconds = STEPS2TIME(stopTime - startTime);
638 dev.writeAttr(SUMO_ATTR_BEGIN, time2string(startTime));
639 dev.writeAttr(SUMO_ATTR_END, time2string(stopTime));
641 dev.writeAttr("nVehContrib", p);
642 dev.writeAttr("removed", myRemoved);
643 dev.writeAttr("inserted", myInserted);
644 dev.writeAttr("cleared", myClearedInJam);
645 dev.writeAttr("flow", p * 3600.0 / durationSeconds);
646 dev.writeAttr("aspiredFlow", myCurrentStateInterval->q);
649 dev.writeAttr("aspiredSpeed", myCurrentStateInterval->v);
650 if (discrepancy > 0) {
651 dev.writeAttr("vaporizedOnNextEdge", discrepancy);
652 }
653 dev.closeTag();
654}
655
656void
658 dev.writeXMLHeader("calibratorstats", "calibratorstats_file.xsd");
659}
660
661std::string
663 // avoid name clash for subsecond interval spacing
664 const double beginS = STEPS2TIME(myCurrentStateInterval->begin);
665 const int precision = beginS == int(beginS) ? 0 : 2;
666 return getID() + "." + toString(beginS, precision) + "." + toString(myInserted);
667}
668
669void
670MSCalibrator::setFlow(SUMOTime begin, SUMOTime end, double vehsPerHour, double speed, SUMOVehicleParameter vehicleParameter) {
671 auto it = myCurrentStateInterval;
672 while (it != myIntervals.end()) {
673 if (it->begin > begin) {
674 throw ProcessError("Cannot set flow for calibrator '" + getID() + "' with begin time=" + time2string(begin) + " in the past.");
675 } else if (it->begin == begin && it->end == end) {
676 // update current interval
677 AspiredState& state = const_cast<AspiredState&>(*it);
678 state.q = vehsPerHour;
679 state.v = speed;
680 state.vehicleParameter->vtypeid = vehicleParameter.vtypeid;
681 state.vehicleParameter->routeid = vehicleParameter.routeid;
682 state.vehicleParameter->departLane = vehicleParameter.departLane;
684 state.vehicleParameter->departSpeed = vehicleParameter.departSpeed;
686 return;
687 } else if (begin < it->end) {
688 throw ProcessError("Cannot set flow for calibrator '" + getID() + "' with overlapping interval.");
689 } else if (begin >= end) {
690 throw ProcessError("Cannot set flow for calibrator '" + getID() + "' with negative interval.");
691 }
692 it++;
693 }
694 // add interval at the end of the known intervals
695 const int intervalIndex = (int)(myCurrentStateInterval - myIntervals.begin());
696 AspiredState state;
697 state.begin = begin;
698 state.end = end;
699 state.q = vehsPerHour;
700 state.v = speed;
701 state.vehicleParameter = new SUMOVehicleParameter(vehicleParameter);
702 myIntervals.push_back(state);
703 // fix iterator
704 myCurrentStateInterval = myIntervals.begin() + intervalIndex;
705}
706
707/****************************************************************************/
long long int SUMOTime
Definition: GUI.h:36
#define DEBUGCOND
#define DEBUGCOND2(id)
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:266
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:274
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:265
#define TL(string)
Definition: MsgHandler.h:282
SUMOTime DELTA_T
Definition: SUMOTime.cpp:37
std::string time2string(SUMOTime t)
convert SUMOTime to string
Definition: SUMOTime.cpp:68
#define STEPS2TIME(x)
Definition: SUMOTime.h:54
#define SIMSTEP
Definition: SUMOTime.h:60
#define SUMOTime_MAX
Definition: SUMOTime.h:33
#define TIME2STEPS(x)
Definition: SUMOTime.h:56
const std::string DEFAULT_VTYPE_ID
@ GIVEN
The lane is given.
@ ALLOWED_FREE
The least occupied lane from lanes which allow the continuation.
@ DEFAULT
No information given; use default.
@ FIRST_ALLOWED
The rightmost lane the vehicle may use.
@ MAX
The maximum safe speed is used.
@ DEFAULT
No information given; use default.
@ SUMO_TAG_INTERVAL
an aggreagated-output interval
@ SUMO_TAG_FLOW
a flow definitio nusing a from-to edges instead of a route (used by router)
@ SUMO_TAG_CALIBRATOR
A calibrator placed over edge.
PersonMode
travel modes for persons
@ SUMO_ATTR_VEHSPERHOUR
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_BEGIN
weights: time range begin
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_ID
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:30
T MAX2(T a, T b)
Definition: StdDefs.h:77
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
void callParentEnd(int element)
signal endElement to the parent handler (special case for MSCalibrator)
void resetRoutePosition(int index, DepartLaneDefinition departLaneProcedure)
reset index of edge within route
virtual double getHeadwayTime() const
Get the driver's desired headway [s].
Definition: MSCFModel.h:309
SUMOTime shiftTime(SUMOTime currentTime, SUMOTime execTime, SUMOTime newTime)
Reschedule or deschedule the command when quick-loading state.
virtual bool notifyEnter(SUMOTrafficObject &veh, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Checks whether the reminder is activated by a vehicle entering the lane.
static std::map< std::string, MSCalibrator * > myInstances
Definition: MSCalibrator.h:349
OutputDevice * myOutput
The device for xml statistics.
Definition: MSCalibrator.h:315
double myInvalidJamThreshold
relative speed threshold for detecting and clearing invalid jam
Definition: MSCalibrator.h:340
double currentSpeed() const
measured speed in the current interval
const MSEdge *const myEdge
the edge on which this calibrator lies
Definition: MSCalibrator.h:287
MSMeanData_Net myMeanDataParent
dummy parent to retrieve vType filter
Definition: MSCalibrator.h:295
static void cleanup()
cleanup remaining data structures
bool isActive() const
Definition: MSCalibrator.h:221
bool mySpeedIsDefault
The information whether the speed adaption has been reset.
Definition: MSCalibrator.h:326
virtual void updateMeanData()
aggregate lane values
int myRemoved
The number of vehicles that were removed in the current interval.
Definition: MSCalibrator.h:320
virtual int passed() const
Definition: MSCalibrator.h:119
const MSRouteProbe *const myProbe
the route probe to retrieve routes from
Definition: MSCalibrator.h:293
bool myAmActive
whether the calibrator was active when last checking
Definition: MSCalibrator.h:337
std::set< std::string > myToRemove
set of vehicle ids to remove
Definition: MSCalibrator.h:312
static std::vector< MSMoveReminder * > myLeftoverReminders
Definition: MSCalibrator.h:347
void setFlow(SUMOTime begin, SUMOTime end, double vehsPerHour, double speed, SUMOVehicleParameter vehicleParameter)
bool myHaveInvalidJam
whether the calibrator has registered an invalid jam in the last execution step
Definition: MSCalibrator.h:343
std::vector< MSMeanData_Net::MSLaneMeanDataValues * > myLaneMeanData
data collector for the calibrator
Definition: MSCalibrator.h:297
std::vector< AspiredState >::const_iterator myCurrentStateInterval
Iterator pointing to the current interval.
Definition: MSCalibrator.h:304
double currentFlow() const
flow in the current interval in veh/h
static std::vector< SUMOVehicleParameter * > myLeftoverVehicleParameters
Definition: MSCalibrator.h:348
bool removePending()
remove any vehicles which are scheduled for removal. return true if removals took place
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
int myInserted
The number of vehicles that were inserted in the current interval.
Definition: MSCalibrator.h:322
bool myHaveWarnedAboutClearingJam
The default (maximum) speed on the segment.
Definition: MSCalibrator.h:334
std::vector< AspiredState > myIntervals
List of adaptation intervals.
Definition: MSCalibrator.h:302
const double myPos
the position on the edge where this calibrator lies
Definition: MSCalibrator.h:291
virtual void myEndElement(int element)
Called on the closing of a tag;.
int totalWished() const
number of vehicles expected to pass this interval
std::vector< VehicleRemover * > myVehicleRemovers
Definition: MSCalibrator.h:306
void writeXMLOutput(OutputDevice &dev, SUMOTime startTime, SUMOTime stopTime)
Write the generated output to the given device.
std::string getNewVehicleID()
determine id of new vehicle from calibrator state
MSMeanData_Net::MSLaneMeanDataValues myEdgeMeanData
accumlated data for the whole edge
Definition: MSCalibrator.h:299
friend class VehicleRemover
Definition: MSCalibrator.h:217
bool invalidJam(int laneIndex) const
int myClearedInJam
The number of vehicles that were removed when clearin a jam.
Definition: MSCalibrator.h:324
void writeXMLDetectorProlog(OutputDevice &dev) const
Open the XML-output.
virtual ~MSCalibrator()
double myDefaultSpeed
The default (maximum) speed on the segment.
Definition: MSCalibrator.h:332
virtual SUMOTime execute(SUMOTime currentTime)
MSLane *const myLane
the lane on which this calibrator lies (0 if the whole edge is covered at once)
Definition: MSCalibrator.h:289
bool scheduleRemoval(SUMOTrafficObject *veh)
try to schedule the given vehicle for removal. return true if it isn't already scheduled
Definition: MSCalibrator.h:273
bool myDidInit
The information whether init was called.
Definition: MSCalibrator.h:330
void intervalEnd()
AspiredState getCurrentStateInterval() const
bool isCurrentStateActive(SUMOTime time)
SUMOTime myFrequency
The frequeny with which to check for calibration.
Definition: MSCalibrator.h:318
MSCalibrator(const std::string &id, const MSEdge *const edge, MSLane *lane, const double pos, const std::string &aXMLFilename, const std::string &outputFilename, const SUMOTime freq, const double length, const MSRouteProbe *probe, const double invalidJamThreshold, const std::string &vTypes, bool addLaneMeanData=true)
virtual void reset()
reset collected vehicle data
int remainingVehicleCapacity(int laneIndex) const
bool myDidSpeedAdaption
The information whether speed was adapted in the current interval.
Definition: MSCalibrator.h:328
Base of value-generating classes (detectors)
bool vehicleApplies(const SUMOTrafficObject &veh) const
Checks whether the detector measures vehicles of the given type.
A road/street connecting two junctions.
Definition: MSEdge.h:77
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:168
double getSpeedLimit() const
Returns the speed limit of the edge @caution The speed limit of the first lane is retured; should pro...
Definition: MSEdge.cpp:1056
bool insertVehicle(SUMOVehicle &v, SUMOTime time, const bool checkOnly=false, const bool forceCheck=false) const
Tries to insert the given vehicle into the network.
Definition: MSEdge.cpp:675
void setMaxSpeed(double val) const
Sets a new maximum speed for all lanes (used by TraCI and MSCalibrator)
Definition: MSEdge.cpp:1075
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
static bool gUseMesoSim
Definition: MSGlobals.h:103
static bool gCheckRoutes
Definition: MSGlobals.h:88
Representation of a lane in the micro simulation.
Definition: MSLane.h:84
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify=true)
Definition: MSLane.cpp:2503
int getVehicleNumber() const
Returns the number of vehicles on this lane (for which this lane is responsible)
Definition: MSLane.h:429
MSVehicle * getLastFullVehicle() const
returns the last vehicle for which this lane is responsible or 0
Definition: MSLane.cpp:2342
double getLength() const
Returns the lane's length.
Definition: MSLane.h:575
int getIndex() const
Returns the lane's index.
Definition: MSLane.h:597
void setMaxSpeed(double val)
Sets a new maximum speed for the lane (used by TraCI and MSCalibrator)
Definition: MSLane.cpp:2468
double getMeanSpeed() const
Returns the mean speed on this lane.
Definition: MSLane.cpp:3079
double getTravelledDistance() const
Returns the total travelled distance.
Definition: MSMeanData.h:156
virtual double getSamples() const
Returns the number of collected sample seconds.
Definition: MSMeanData.cpp:280
Data structure for mean (aggregated) edge/lane values.
int nVehVaporized
The number of vehicles that left this lane via vaporization within the sample interval.
int nVehLeft
The number of vehicles that left this lane within the sample interval.
int nVehTeleported
The number of vehicles that left this lane via teleporting within the sample interval.
int nVehArrived
The number of vehicles that finished on the lane.
double waitSeconds
The number of vehicle probes with small speed.
int nVehEntered
The number of vehicles that entered this lane within the sample interval.
void reset(bool afterWrite=false)
Resets values so they may be used for the next interval.
Something on a lane to be noticed about vehicle movement.
void setDescription(const std::string &description)
Notification
Definition of a vehicle state.
@ NOTIFICATION_VAPORIZED_CALIBRATOR
The vehicle got removed by a calibrator.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:183
MSEventControl * getEndOfTimestepEvents()
Returns the event control for events executed at the end of a time step.
Definition: MSNet.h:482
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:379
Parser and container for routes during their loading.
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:80
static bool dictionary(const std::string &id, const MSRoute *route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:118
bool contains(const MSEdge *const edge) const
Definition: MSRoute.h:103
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:74
Writes routes of vehicles passing a certain edge.
Definition: MSRouteProbe.h:58
const MSRoute * sampleRoute(bool last=true) const
The class responsible for building and deletion of vehicles.
virtual void deleteVehicle(SUMOVehicle *v, bool discard=false)
Deletes the vehicle.
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
virtual SUMOVehicle * buildVehicle(SUMOVehicleParameter *defs, const MSRoute *route, MSVehicleType *type, const bool ignoreStopErrors, const bool fromRouteFile=true, bool addRouteStops=true)
Builds a vehicle, increases the number of built vehicles.
MSVehicleType * getVType(const std::string &id=DEFAULT_VTYPE_ID, SumoRNG *rng=nullptr, bool readOnly=false)
Returns the named vehicle type or a sample from the named distribution.
const RandomDistributor< MSVehicleType * > * getVTypeDistribution(const std::string &typeDistID) const
return the vehicle type distribution with the given id
void scheduleVehicleRemoval(SUMOVehicle *veh, bool checkDuplicate=false)
Removes a vehicle after it has ended.
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:77
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
Definition: MSVehicle.cpp:1015
MSLane * getMutableLane() const
Returns the lane the vehicle is on Non const version indicates that something volatile is going on.
Definition: MSVehicle.h:585
double getPositionOnLane() const
Get the vehicle's position along the lane.
Definition: MSVehicle.h:377
The car-following model and parameter.
Definition: MSVehicleType.h:63
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)
const std::string & getID() const
Returns the id.
Definition: Named.h:74
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:251
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
static OutputDevice & getDevice(const std::string &name, bool usePrefix=true)
Returns the described OutputDevice.
bool writeXMLHeader(const std::string &rootElement, const std::string &schemaFile, std::map< SumoXMLAttr, std::string > attrs=std::map< SumoXMLAttr, std::string >(), bool includeConfig=true)
Writes an XML header with optional configuration.
const std::vector< T > & getVals() const
Returns the members of the distribution.
virtual void myEndElement(int element)
Called when a closing tag occurs.
Encapsulated SAX-Attributes.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue=T(), bool report=true) const
Tries to read given attribute assuming it is an int.
SUMOTime getOptSUMOTimeReporting(int attr, const char *objectid, bool &ok, SUMOTime defaultValue, bool report=true) const
Tries to read given attribute assuming it is a SUMOTime.
SUMOTime getSUMOTimeReporting(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is a SUMOTime.
Representation of a vehicle, person, or container.
virtual const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle's parameter (including departure definition)
virtual void replaceVehicleType(MSVehicleType *type)=0
Replaces the current vehicle type by the one given.
Structure representing possible vehicle parameter.
int parametersSet
Information for the router which parameter were set, TraCI may modify this (when changing color)
int departLane
(optional) The lane the vehicle shall depart from (index in edge)
double departSpeed
(optional) The initial speed of the vehicle
std::string vtypeid
The vehicle's type id.
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle's initial speed shall be chosen.
std::string routeid
The vehicle's route id.
std::string id
The vehicle's id.
static SUMOVehicleParameter * parseVehicleAttributes(int element, const SUMOSAXAttributes &attrs, const bool hardFail, const bool optionalID=false, const bool skipDepart=false)
Parses a vehicle's attributes.
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false, const bool isRoute=false)
Runs the given handler on the given file; returns if everything's ok.
Definition: XMLSubSys.cpp:137
Definition: json.hpp:4471
SUMOVehicleParameter * vehicleParameter
Definition: MSCalibrator.h:102