SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 
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)
A vehicle from the mesoscopic point of view.
Definition: MEVehicle.h:52
std::string vtypeid
The vehicle's type id.
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
SUMOReal getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
bool invalidJam() const
returns whether the segment is jammed although it should not be
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
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.
SUMOReal getFloat(const std::string &name) const
Returns the SUMOReal-value of the named option (only for Option_Float)
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 & getEdge() const
Returns the edge this segment belongs to.
Definition: MESegment.h:272
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
const std::string & getID() const
Returns the id.
Definition: Named.h:66
A road/street connecting two junctions.
Definition: MSEdge.h:80
MESegment * getNextSegment() const
Returns the following segment on the same edge (0 if it is the last).
Definition: MESegment.h:158
std::vector< AspiredState >::const_iterator myCurrentStateInterval
Iterator pointing to the current interval.
Definition: MSCalibrator.h:223
std::string routeid
The vehicle's route id.
void writeXMLOutput()
MESegment * mySegment
mesoscopic edge segment the calibrator lies on
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:307
bool contains(const MSEdge *const edge) const
Definition: MSRoute.h:110
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's departure time.
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
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 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
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
const MSRoute * getRoute() const
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
Structure representing possible vehicle parameter.
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
A single mesoscopic segment (cell)
Definition: MESegment.h:57
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 SUMOVehicleParameter & getParameter() const
Returns the vehicle's parameter (including departure definition)
const MSRouteProbe *const myProbe
the route probe to retrieve routes from
Definition: MSCalibrator.h:215
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
SUMOReal getBruttoOccupancy() const
Returns the occupany of the segment (the sum of the vehicle lengths + minGaps)
Definition: MESegment.h:174
#define SUMOReal
Definition: config.h:214
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 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
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:235
bool isCurrentStateActive(SUMOTime time)
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...
MSVehicleType * getVType(const std::string &id=DEFAULT_VTYPE_ID, MTRand *rng=0)
Returns the named vehicle type or a sample from the named distribution.
int remainingVehicleCapacity(const SUMOReal vehLength) const
return the remaining physical space on this segment
Definition: MESegment.h:352
void reset()
reset collected vehicle data
SUMOReal myDefaultSpeed
The default (maximum) speed on the segment.
Definition: MSCalibrator.h:251
int myInserted
The number of vehicles that were inserted in the current interval.
Definition: MSCalibrator.h:241
std::string id
The vehicle's id.
void setMaxSpeed(SUMOReal val) const
Sets a new maximum speed for all lanes (used by TraCI and MSCalibrator)
Definition: MSEdge.cpp:783
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:122