SUMO - Simulation of Urban MObility
METriggeredCalibrator.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // Calibrates the flow on a segment to a specified one
8 /****************************************************************************/
9 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
10 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
11 /****************************************************************************/
12 //
13 // This file is part of SUMO.
14 // SUMO is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation, either version 3 of the License, or
17 // (at your option) any later version.
18 //
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #ifdef _MSC_VER
26 #include <windows_config.h>
27 #else
28 #include <config.h>
29 #endif
30 
31 #include <string>
32 #include <algorithm>
33 #include <cmath>
34 #include <microsim/MSGlobals.h>
35 #include <microsim/MSNet.h>
36 #include <microsim/MSEdge.h>
41 #include <utils/common/ToString.h>
44 #include <utils/xml/XMLSubSys.h>
50 #include "MELoop.h"
51 #include "MESegment.h"
52 #include "MEVehicle.h"
53 #include "METriggeredCalibrator.h"
54 
55 
56 // ===========================================================================
57 // method definitions
58 // ===========================================================================
60  const MSEdge* const edge, const double pos,
61  const std::string& aXMLFilename,
62  const std::string& outputFilename,
63  const SUMOTime freq, const double length,
64  const MSRouteProbe* probe) :
65  MSCalibrator(id, edge, (MSLane*)0, pos, aXMLFilename, outputFilename, freq, length, probe, false),
66  mySegment(MSGlobals::gMesoNet->getSegmentForEdge(*edge, pos)) {
67  myEdgeMeanData.setDescription("meandata_calibrator_" + getID());
69 }
70 
71 
73  if (myCurrentStateInterval != myIntervals.end()) {
74  // need to do it here and not in MSCalibrator because otherwise meandata is gone
76  // but avoid to call it again in MSCalibrator
78  }
80 }
81 
82 
83 bool
85  if (s->initialise(vehicle, vehicle->getParameter().depart)) {
86  if (!MSNet::getInstance()->getVehicleControl().addVehicle(vehicle->getID(), vehicle)) {
87  throw ProcessError("Emission of vehicle '" + vehicle->getID() + "' in calibrator '" + getID() + "'failed!");
88  }
89  return true;
90  }
91  return false;
92 }
93 
94 
97  // get current simulation values (valid for the last simulation second)
98  // XXX could we miss vehicle movements if this is called less often than every DELTA_T (default) ?
100 
101  // check whether an adaptation value exists
102  if (isCurrentStateActive(currentTime)) {
103  // all happens in isCurrentStateActive()
104  } else {
105  myEdgeMeanData.reset(); // discard collected values
106  if (!mySpeedIsDefault) {
107  // if not, reset adaptation values
110  const double jamThresh = OptionsCont::getOptions().getFloat("meso-jam-threshold");
111  while (first != 0) {
112  first->setSpeed(myDefaultSpeed, currentTime, jamThresh);
113  first = first->getNextSegment();
114  }
115  mySpeedIsDefault = true;
116  }
117  if (myCurrentStateInterval == myIntervals.end()) {
118  // keep calibrator alive but do not call again
119  return TIME2STEPS(86400);
120  }
121  return myFrequency;
122  }
123  // we are active
127  while (first != 0) {
128  first->setSpeed(myCurrentStateInterval->v, currentTime, -1);
129  first = first->getNextSegment();
130  }
131  mySpeedIsDefault = false;
132  myDidSpeedAdaption = true;
133  }
134  // clear invalid jams
135  bool hadInvalidJam = false;
136  while (invalidJam()) {
137  hadInvalidJam = true;
139  WRITE_WARNING("Clearing jam at calibrator '" + myID + "' at time " + time2string(currentTime));
140  }
141  // remove one vehicle currently on the segment
142  if (mySegment->vaporizeAnyCar(currentTime)) {
143  myClearedInJam++;
144  } else {
146  // this frequenly happens for very short edges
147  WRITE_WARNING("Could not clear jam at calibrator '" + myID + "' at time " + time2string(currentTime));
148  }
149  break;
150  }
152  }
153  if (myCurrentStateInterval->q >= 0) {
154  // flow calibration starts here ...
155  // compute the number of vehicles that should have passed the calibrator within the time
156  // rom begin of the interval
157  const double totalHourFraction = STEPS2TIME(myCurrentStateInterval->end - myCurrentStateInterval->begin) / (double) 3600.;
158  const int totalWishedNum = (int)std::floor(myCurrentStateInterval->q * totalHourFraction + 0.5); // round to closest int
159  int adaptedNum = passed() + myClearedInJam;
160  if (!hadInvalidJam) {
161  // only add vehicles if we do not have an invalid upstream jam to prevent spill-back
162  const double hourFraction = STEPS2TIME(currentTime - myCurrentStateInterval->begin + DELTA_T) / (double) 3600.;
163  const int wishedNum = (int)std::floor(myCurrentStateInterval->q * hourFraction + 0.5); // round to closest int
164  // only the difference between inflow and aspiredFlow should be added, thus
165  // we should not count vehicles vaporized from a jam here
166  // if we have enough time left we can add missing vehicles later
167  const int relaxedInsertion = (int)std::floor(STEPS2TIME(myCurrentStateInterval->end - currentTime) / 3);
168  const int insertionSlack = MAX2(0, adaptedNum + relaxedInsertion - totalWishedNum);
169  // increase number of vehicles
170  //std::cout << "time:" << STEPS2TIME(currentTime) << " w:" << wishedNum << " s:" << insertionSlack << " before:" << adaptedNum;
171  while (wishedNum > adaptedNum + insertionSlack && remainingVehicleCapacity() > maximumInflow()) {
172  SUMOVehicleParameter* pars = myCurrentStateInterval->vehicleParameter;
173  const MSRoute* route = myProbe != 0 ? myProbe->getRoute() : 0;
174  if (route == 0) {
175  route = MSRoute::dictionary(pars->routeid);
176  }
177  if (route == 0) {
178  WRITE_WARNING("No valid routes in calibrator '" + myID + "'.");
179  break;
180  }
181  if (!route->contains(myEdge)) {
182  WRITE_WARNING("Route '" + route->getID() + "' in calibrator '" + myID + "' does not contain edge '" + myEdge->getID() + "'.");
183  break;
184  }
186  assert(route != 0 && vtype != 0);
187  // build the vehicle
188  const SUMOTime depart = mySegment->getNextInsertionTime(currentTime);
189  SUMOVehicleParameter* newPars = new SUMOVehicleParameter(*pars);
190  newPars->id = myID + "." + toString(depart) + "." + toString(myInserted);
191  newPars->depart = depart;
192  newPars->routeid = route->getID();
193  MEVehicle* vehicle;
194  try {
195  vehicle = static_cast<MEVehicle*>(MSNet::getInstance()->getVehicleControl().buildVehicle(
196  newPars, route, vtype, false, false));
197  } catch (const ProcessError& e) {
199  WRITE_WARNING(e.what());
200  vehicle = 0;
201  break;
202  } else {
203  throw e;
204  }
205  }
206  vehicle->setSegment(mySegment); // needed or vehicle will not be registered (XXX why?)
207  vehicle->setEventTime(currentTime); // XXX superfluous?
208  // move vehicle forward when the route does not begin at the calibrator's edge
209  const MSEdge* myedge = &mySegment->getEdge();
210  bool atDest = false;
211  while (vehicle->getEdge() != myedge) {
212  // let the vehicle move to the next edge
213  atDest = vehicle->moveRoutePointer();
214  }
215  // insert vehicle into the net
216  if (atDest || !tryEmit(mySegment, vehicle)) {
217  //std::cout << "F ";
219  break;
220  }
221  //std::cout << "I ";
222  myInserted++;
223  adaptedNum++;
224  }
225  }
226  //std::cout << " after:" << adaptedNum << "\n";
227  // we only remove vehicles once we really have to
228  while (totalWishedNum < adaptedNum) {
229  if (!mySegment->vaporizeAnyCar(currentTime)) {
230  // @bug: short edges may be jumped in a single step, giving us no chance to remove a vehicle
231  break;
232  }
233  myRemoved++;
234  adaptedNum--;
235  }
236  }
237  if (myCurrentStateInterval->end <= currentTime + myFrequency) {
238  writeXMLOutput();
239  }
240  assert(!invalidJam());
241  return myFrequency;
242 }
243 
244 
245 bool
247  if (mySegment->getBruttoOccupancy() == 0.) {
248  return false;
249  }
250  // maxSpeed reflects the calibration target
251  const bool toSlow = mySegment->getMeanSpeed() < 0.8 * mySegment->getEdge().getSpeedLimit();
252  return toSlow && remainingVehicleCapacity() < maximumInflow();
253 }
254 
255 
256 int
258  const SUMOVehicleParameter* pars = myCurrentStateInterval->vehicleParameter;
261 }
262 
263 
264 void
267 }
268 
269 
270 /****************************************************************************/
271 
virtual void setSegment(MESegment *s, int idx=0)
Sets the current segment the vehicle is at together with its que.
Definition: MEVehicle.h:221
virtual void deleteVehicle(SUMOVehicle *v, bool discard=false)
Deletes the vehicle.
SUMOTime execute(SUMOTime currentTime)
A vehicle from the mesoscopic point of view.
Definition: MEVehicle.h:52
MESegment * getSegmentForEdge(const MSEdge &e, double pos=0)
Get the segment for a given edge at a given position.
Definition: MELoop.cpp:290
void setSpeed(double newSpeed, SUMOTime currentTime, double jamThresh=DO_NOT_PATCH_JAM_THRESHOLD)
reset mySpeed and patch the speed of all vehicles in it. Also set/recompute myJamThreshold ...
Definition: MESegment.cpp:613
double getBruttoOccupancy() const
Returns the occupany of the segment (the sum of the vehicle lengths + minGaps)
Definition: MESegment.h:173
std::string vtypeid
The vehicle&#39;s type id.
bool initialise(MEVehicle *veh, SUMOTime time)
Inserts (emits) vehicle into the segment.
Definition: MESegment.cpp:288
bool invalidJam() const
returns whether the segment is jammed although it should not be
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
Writes routes of vehicles passing a certain edge.
Definition: MSRouteProbe.h:68
bool myDidSpeedAdaption
The information whether speed was adapted in the current interval.
Definition: MSCalibrator.h:272
double getSpeedLimit() const
Returns the speed limit of the edge The speed limit of the first lane is retured; should probably be...
Definition: MSEdge.cpp:847
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:60
double getMeanSpeed(bool useCache) const
Returns the average speed of vehicles on the segment in meters per second. If there is no vehicle on ...
Definition: MESegment.cpp:313
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:169
T MAX2(T a, T b)
Definition: StdDefs.h:74
METriggeredCalibrator(const std::string &id, const MSEdge *const edge, const double pos, const std::string &aXMLFilename, const std::string &outputFilename, const SUMOTime freq, const double length, const MSRouteProbe *probe)
SUMOTime DELTA_T
Definition: SUMOTime.cpp:40
virtual bool addVehicle(const std::string &id, SUMOVehicle *v)
Tries to insert the vehicle into the internal vehicle container.
SUMOTime myFrequency
The frequeny with which to check for calibration.
Definition: MSCalibrator.h:262
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
bool tryEmit(MESegment *s, MEVehicle *vehicle)
int myRemoved
The number of vehicles that were removed in the current interval.
Definition: MSCalibrator.h:264
int myClearedInJam
The number of vehicles that were removed when clearin a jam.
Definition: MSCalibrator.h:268
const MSEdge & getEdge() const
Returns the edge this segment belongs to.
Definition: MESegment.h:271
const MSEdge *const myEdge
the edge on which this calibrator lies
Definition: MSCalibrator.h:234
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
The car-following model and parameter.
Definition: MSVehicleType.h:73
int remainingVehicleCapacity(const double vehLength) const
return the remaining physical space on this segment
Definition: MESegment.h:356
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:65
double getLengthWithGap() const
Get vehicle&#39;s length including the minimum gap [m].
const std::string & getID() const
Returns the id.
Definition: Named.h:66
A road/street connecting two junctions.
Definition: MSEdge.h:81
MESegment * getNextSegment() const
Returns the following segment on the same edge (0 if it is the last).
Definition: MESegment.h:157
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
std::vector< AspiredState >::const_iterator myCurrentStateInterval
Iterator pointing to the current interval.
Definition: MSCalibrator.h:248
std::string routeid
The vehicle&#39;s route id.
void writeXMLOutput()
static bool gCheckRoutes
Definition: MSGlobals.h:86
MESegment * mySegment
mesoscopic edge segment the calibrator lies on
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:305
bool contains(const MSEdge *const edge) const
Definition: MSRoute.h:110
SUMOTime depart
The vehicle&#39;s departure time.
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
double myDefaultSpeed
The default (maximum) speed on the segment.
Definition: MSCalibrator.h:276
void addDetector(MSMoveReminder *data)
Adds a data collector for a detector to this segment.
Definition: MESegment.cpp:205
bool mySpeedIsDefault
The information whether the speed adaption has been reset.
Definition: MSCalibrator.h:270
std::vector< AspiredState > myIntervals
List of adaptation intervals.
Definition: MSCalibrator.h:246
bool vaporizeAnyCar(SUMOTime currentTime)
tries to remove any car from this segment
Definition: MESegment.cpp:567
bool myHaveWarnedAboutClearingJam
The default (maximum) speed on the segment.
Definition: MSCalibrator.h:278
void removeDetector(MSMoveReminder *data)
Removes a data collector for a detector from this segment.
Definition: MESegment.cpp:216
void setDescription(const std::string &description)
MSVehicleType * getVType(const std::string &id=DEFAULT_VTYPE_ID, std::mt19937 *rng=0)
Returns the named vehicle type or a sample from the named distribution.
bool moveRoutePointer()
Update when the vehicle enters a new edge in the move step.
Definition: MEVehicle.cpp:142
const MSRoute * getRoute() const
std::string myID
The name of the object.
Definition: Named.h:136
Structure representing possible vehicle parameter.
A single mesoscopic segment (cell)
Definition: MESegment.h:57
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition: MSGlobals.h:113
const SUMOVehicleParameter & getParameter() const
Returns the vehicle&#39;s parameter (including departure definition)
const MSRouteProbe *const myProbe
the route probe to retrieve routes from
Definition: MSCalibrator.h:240
void setEventTime(SUMOTime t, bool hasDelay=true)
Sets the (planned) time at which the vehicle leaves his current cell.
Definition: MEVehicle.h:200
void setMaxSpeed(double val) const
Sets a new maximum speed for all lanes (used by TraCI and MSCalibrator)
Definition: MSEdge.cpp:866
Calibrates the flow on a segment to a specified one.
Definition: MSCalibrator.h:57
long long int SUMOTime
Definition: TraCIDefs.h:52
SUMOTime getNextInsertionTime(SUMOTime earliestEntry) const
return a time after earliestEntry at which a vehicle may be inserted at full speed ...
Definition: MESegment.cpp:380
void reset(bool afterWrite=false)
Resets values so they may be used for the next interval.
MSMeanData_Net::MSLaneMeanDataValues myEdgeMeanData
accumlated data for the whole edge
Definition: MSCalibrator.h:244
const MSEdge * getEdge() const
Returns the edge the vehicle is currently at.
void prepareDetectorForWriting(MSMoveReminder &data)
Updates data of a detector for all vehicle queues.
Definition: MESegment.cpp:247
bool isCurrentStateActive(SUMOTime time)
virtual SUMOVehicle * buildVehicle(SUMOVehicleParameter *defs, const MSRoute *route, MSVehicleType *type, const bool ignoreStopErrors, const bool fromRouteFile=true)
Builds a vehicle, increases the number of built vehicles.
int remainingVehicleCapacity() const
returns the number of vehicles (of the current type) that still fit onto the segment ...
int maximumInflow() const
returns the maximum number of vehicles that could enter from upstream until the calibrator is activat...
Representation of a lane in the micro simulation.
Definition: MSLane.h:79
void reset()
reset collected vehicle data
int myInserted
The number of vehicles that were inserted in the current interval.
Definition: MSCalibrator.h:266
std::string id
The vehicle&#39;s id.
const std::string & getID() const
Returns the name of the vehicle.
static bool dictionary(const std::string &id, const MSRoute *route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:118