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-2016 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>
40 #include <utils/common/ToString.h>
43 #include <utils/xml/XMLSubSys.h>
49 #include "MELoop.h"
50 #include "MESegment.h"
51 #include "MEVehicle.h"
52 #include "METriggeredCalibrator.h"
53 
54 #ifdef CHECK_MEMORY_LEAKS
55 #include <foreign/nvwa/debug_new.h>
56 #endif // CHECK_MEMORY_LEAKS
57 
58 
59 // ===========================================================================
60 // method definitions
61 // ===========================================================================
63  const MSEdge* const edge, const SUMOReal pos,
64  const std::string& aXMLFilename,
65  const std::string& outputFilename,
66  const SUMOTime freq, const SUMOReal length,
67  const MSRouteProbe* probe)
68  : MSCalibrator(id, edge, pos, aXMLFilename, outputFilename, freq, length, probe, false),
69  mySegment(MSGlobals::gMesoNet->getSegmentForEdge(*edge, pos)) {
70  myEdgeMeanData.setDescription("meandata_calibrator_" + getID());
72 }
73 
74 
76  if (myCurrentStateInterval != myIntervals.end()) {
79  }
81 }
82 
83 
84 bool
86  if (s->initialise(vehicle, vehicle->getParameter().depart)) {
87  if (!MSNet::getInstance()->getVehicleControl().addVehicle(vehicle->getID(), vehicle)) {
88  throw ProcessError("Emission of vehicle '" + vehicle->getID() + "' in calibrator '" + getID() + "'failed!");
89  }
90  return true;
91  }
92  return false;
93 }
94 
95 
98  // get current simulation values (valid for the last simulation second)
99  // XXX could we miss vehicle movements if this is called less often than every DELTA_T (default) ?
101 
102  // check whether an adaptation value exists
103  if (isCurrentStateActive(currentTime)) {
104  // all happens in isCurrentStateActive()
105  } else {
106  myEdgeMeanData.reset(); // discard collected values
107  if (!mySpeedIsDefault) {
108  // if not, reset adaptation values
111  const SUMOReal jamThresh = OptionsCont::getOptions().getFloat("meso-jam-threshold");
112  while (first != 0) {
113  first->setSpeed(myDefaultSpeed, currentTime, jamThresh);
114  first = first->getNextSegment();
115  }
116  mySpeedIsDefault = true;
117  }
118  if (myCurrentStateInterval == myIntervals.end()) {
119  // keep calibrator alive but do not call again
120  return TIME2STEPS(86400);
121  }
122  return myFrequency;
123  }
124  // we are active
128  while (first != 0) {
129  first->setSpeed(myCurrentStateInterval->v, currentTime, -1);
130  first = first->getNextSegment();
131  }
132  mySpeedIsDefault = false;
133  myDidSpeedAdaption = true;
134  }
135  // clear invalid jams
136  bool hadInvalidJam = false;
137  while (invalidJam()) {
138  hadInvalidJam = true;
140  WRITE_WARNING("Clearing jam at calibrator '" + myID + "' at time " + time2string(currentTime));
141  }
142  // remove one vehicle currently on the segment
143  if (mySegment->vaporizeAnyCar(currentTime)) {
144  myClearedInJam++;
145  } else {
147  // this frequenly happens for very short edges
148  WRITE_WARNING("Could not clear jam at calibrator '" + myID + "' at time " + time2string(currentTime));
149  }
150  break;
151  }
153  }
154  if (myCurrentStateInterval->q >= 0) {
155  // flow calibration starts here ...
156  // compute the number of vehicles that should have passed the calibrator within the time
157  // rom begin of the interval
158  const SUMOReal totalHourFraction = STEPS2TIME(myCurrentStateInterval->end - myCurrentStateInterval->begin) / (SUMOReal) 3600.;
159  const int totalWishedNum = (int)std::floor(myCurrentStateInterval->q * totalHourFraction + 0.5); // round to closest int
160  int adaptedNum = passed() + myClearedInJam;
161  if (!hadInvalidJam) {
162  // only add vehicles if we do not have an invalid upstream jam to prevent spill-back
163  const SUMOReal hourFraction = STEPS2TIME(currentTime - myCurrentStateInterval->begin + DELTA_T) / (SUMOReal) 3600.;
164  const int wishedNum = (int)std::floor(myCurrentStateInterval->q * hourFraction + 0.5); // round to closest int
165  // only the difference between inflow and aspiredFlow should be added, thus
166  // we should not count vehicles vaporized from a jam here
167  // if we have enough time left we can add missing vehicles later
168  const int relaxedInsertion = (int)std::floor(STEPS2TIME(myCurrentStateInterval->end - currentTime) / 3);
169  const int insertionSlack = MAX2(0, adaptedNum + relaxedInsertion - totalWishedNum);
170  // increase number of vehicles
171  //std::cout << "time:" << STEPS2TIME(currentTime) << " w:" << wishedNum << " s:" << insertionSlack << " before:" << adaptedNum;
172  while (wishedNum > adaptedNum + insertionSlack && remainingVehicleCapacity() > maximumInflow()) {
173  SUMOVehicleParameter* pars = myCurrentStateInterval->vehicleParameter;
174  const MSRoute* route = myProbe != 0 ? myProbe->getRoute() : 0;
175  if (route == 0) {
176  route = MSRoute::dictionary(pars->routeid);
177  }
178  if (route == 0) {
179  WRITE_WARNING("No valid routes in calibrator '" + myID + "'.");
180  break;
181  }
182  if (!route->contains(myEdge)) {
183  WRITE_WARNING("Route '" + route->getID() + "' in calibrator '" + myID + "' does not contain edge '" + myEdge->getID() + "'.");
184  break;
185  }
187  assert(route != 0 && vtype != 0);
188  // build the vehicle
189  const SUMOTime depart = mySegment->getNextInsertionTime(currentTime);
190  SUMOVehicleParameter* newPars = new SUMOVehicleParameter(*pars);
191  newPars->id = myID + "." + toString(depart) + "." + toString(myInserted);
192  newPars->depart = depart;
193  newPars->routeid = route->getID();
195  newPars, route, vtype, false, false));
196  vehicle->setSegment(mySegment); // needed or vehicle will not be registered (XXX why?)
197  vehicle->setEventTime(currentTime); // XXX superfluous?
198  // move vehicle forward when the route does not begin at the calibrator's edge
199  const MSEdge* myedge = &mySegment->getEdge();
200  bool atDest = false;
201  while (vehicle->getEdge() != myedge) {
202  // let the vehicle move to the next edge
203  atDest = vehicle->moveRoutePointer();
204  }
205  // insert vehicle into the net
206  if (atDest || !tryEmit(mySegment, vehicle)) {
207  //std::cout << "F ";
209  break;
210  }
211  //std::cout << "I ";
212  myInserted++;
213  adaptedNum++;
214  }
215  }
216  //std::cout << " after:" << adaptedNum << "\n";
217  // we only remove vehicles once we really have to
218  while (totalWishedNum < adaptedNum) {
219  if (!mySegment->vaporizeAnyCar(currentTime)) {
220  // @bug: short edges may be jumped in a single step, giving us no chance to remove a vehicle
221  break;
222  }
223  myRemoved++;
224  adaptedNum--;
225  }
226  }
227  if (myCurrentStateInterval->end <= currentTime + myFrequency) {
228  writeXMLOutput();
229  }
230  assert(!invalidJam());
231  return myFrequency;
232 }
233 
234 
235 bool
237  if (mySegment->getBruttoOccupancy() == 0.) {
238  return false;
239  }
240  // maxSpeed reflects the calibration target
241  const bool toSlow = mySegment->getMeanSpeed() < 0.8 * mySegment->getEdge().getSpeedLimit();
242  return toSlow && remainingVehicleCapacity() < maximumInflow();
243 }
244 
245 
246 int
248  const SUMOVehicleParameter* pars = myCurrentStateInterval->vehicleParameter;
251 }
252 
253 
254 void
257 }
258 
259 
260 /****************************************************************************/
261 
MESegment * getNextSegment() const
Returns the following segment on the same edge (0 if it is the last).
Definition: MESegment.h:158
virtual void setSegment(MESegment *s, int idx=0)
Sets the current segment the vehicle is at together with its que.
Definition: MEVehicle.h:204
virtual void deleteVehicle(SUMOVehicle *v, bool discard=false)
Deletes the vehicle.
long long int SUMOTime
Definition: SUMOTime.h:43
SUMOTime execute(SUMOTime currentTime)
int maximumInflow() const
returns the maximum number of vehicles that could enter from upstream until the calibrator is activat...
A vehicle from the mesoscopic point of view.
Definition: MEVehicle.h:52
std::string vtypeid
The vehicle&#39;s type id.
const MSRoute * getRoute() const
METriggeredCalibrator(const std::string &id, const MSEdge *const edge, const SUMOReal pos, const std::string &aXMLFilename, const std::string &outputFilename, const SUMOTime freq, const SUMOReal length, const MSRouteProbe *probe)
bool initialise(MEVehicle *veh, SUMOTime time)
Inserts (emits) vehicle into the segment.
Definition: MESegment.cpp:272
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:247
const SUMOVehicleParameter & getParameter() const
Returns the vehicle&#39;s parameter (including departure definition)
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:59
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:159
T MAX2(T a, T b)
Definition: StdDefs.h:75
SUMOTime DELTA_T
Definition: SUMOTime.cpp:39
virtual bool addVehicle(const std::string &id, SUMOVehicle *v)
Tries to insert the vehicle into the internal vehicle container.
const std::string & getID() const
Returns the id.
Definition: Named.h:66
SUMOTime myFrequency
The frequeny with which to check for calibration.
Definition: MSCalibrator.h:237
#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:239
int myClearedInJam
The number of vehicles that were removed when clearin a jam.
Definition: MSCalibrator.h:243
const MSEdge *const myEdge
the edge on which this calibrator lies
Definition: MSCalibrator.h:211
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
The car-following model and parameter.
Definition: MSVehicleType.h:74
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:69
SUMOReal getSpeedLimit() const
Returns the speed limit of the edge The speed limit of the first lane is retured; should probably be...
Definition: MSEdge.cpp:769
A road/street connecting two junctions.
Definition: MSEdge.h:80
std::vector< AspiredState >::const_iterator myCurrentStateInterval
Iterator pointing to the current interval.
Definition: MSCalibrator.h:223
std::string routeid
The vehicle&#39;s route id.
void writeXMLOutput()
MESegment * mySegment
mesoscopic edge segment the calibrator lies on
const MSEdge * getEdge() const
Returns the edge the vehicle is currently at.
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:307
virtual SUMOVehicle * buildVehicle(SUMOVehicleParameter *defs, const MSRoute *route, const MSVehicleType *type, const bool ignoreStopErrors, const bool fromRouteFile=true)
Builds a vehicle, increases the number of built vehicles.
SUMOTime depart
The vehicle&#39;s departure time.
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
int remainingVehicleCapacity(const SUMOReal vehLength) const
return the remaining physical space on this segment
Definition: MESegment.h:352
void addDetector(MSMoveReminder *data)
Adds a data collector for a detector to this segment.
Definition: MESegment.cpp:193
bool mySpeedIsDefault
The information whether the speed adaption has been reset.
Definition: MSCalibrator.h:245
std::vector< AspiredState > myIntervals
List of adaptation intervals.
Definition: MSCalibrator.h:221
bool vaporizeAnyCar(SUMOTime currentTime)
tries to remove any car from this segment
Definition: MESegment.cpp:557
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:55
SUMOReal getBruttoOccupancy() const
Returns the occupany of the segment (the sum of the vehicle lengths + minGaps)
Definition: MESegment.h:174
bool myHaveWarnedAboutClearingJam
The default (maximum) speed on the segment.
Definition: MSCalibrator.h:253
void removeDetector(MSMoveReminder *data)
Removes a data collector for a detector from this segment.
Definition: MESegment.cpp:204
void setDescription(const std::string &description)
bool moveRoutePointer()
Update when the vehicle enters a new edge in the move step.
Definition: MEVehicle.cpp:145
SUMOTime getNextInsertionTime(SUMOTime earliestEntry) const
return a time after earliestEntry at which a vehicle may be inserted at full speed ...
Definition: MESegment.cpp:371
void setSpeed(SUMOReal newSpeed, SUMOTime currentTime, SUMOReal jamThresh=DO_NOT_PATCH_JAM_THRESHOLD)
reset mySpeed and patch the speed of all vehicles in it. Also set/recompute myJamThreshold ...
Definition: MESegment.cpp:603
std::string myID
The name of the object.
Definition: Named.h:136
int remainingVehicleCapacity() const
returns the number of vehicles (of the current type) that still fit onto the segment ...
Structure representing possible vehicle parameter.
A single mesoscopic segment (cell)
Definition: MESegment.h:57
bool invalidJam() const
returns whether the segment is jammed although it should not be
MESegment * getSegmentForEdge(const MSEdge &e, SUMOReal pos=0)
Get the segment for a given edge at a given position.
Definition: MELoop.cpp:295
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition: MSGlobals.h:107
const MSRouteProbe *const myProbe
the route probe to retrieve routes from
Definition: MSCalibrator.h:215
void setMaxSpeed(SUMOReal val) const
Sets a new maximum speed for all lanes (used by TraCI and MSCalibrator)
Definition: MSEdge.cpp:783
void setEventTime(SUMOTime t, bool hasDelay=true)
Sets the (planned) time at which the vehicle leaves his current cell.
Definition: MEVehicle.h:183
Calibrates the flow on a segment to a specified one.
Definition: MSCalibrator.h:57
#define SUMOReal
Definition: config.h:213
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:219
void prepareDetectorForWriting(MSMoveReminder &data)
Updates data of a detector for all vehicle queues.
Definition: MESegment.cpp:235
bool isCurrentStateActive(SUMOTime time)
MSVehicleType * getVType(const std::string &id=DEFAULT_VTYPE_ID, MTRand *rng=0)
Returns the named vehicle type or a sample from the named distribution.
const std::string & getID() const
Returns the name of the vehicle.
const MSEdge & getEdge() const
Returns the edge this segment belongs to.
Definition: MESegment.h:272
void reset()
reset collected vehicle data
SUMOReal myDefaultSpeed
The default (maximum) speed on the segment.
Definition: MSCalibrator.h:251
bool contains(const MSEdge *const edge) const
Definition: MSRoute.h:110
int myInserted
The number of vehicles that were inserted in the current interval.
Definition: MSCalibrator.h:241
SUMOReal getFloat(const std::string &name) const
Returns the SUMOReal-value of the named option (only for Option_Float)
SUMOReal getLengthWithGap() const
Get vehicle&#39;s length including the minimum gap [m].
std::string id
The vehicle&#39;s id.
SUMOReal 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:297
static bool dictionary(const std::string &id, const MSRoute *route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:122