SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSInductLoop.cpp
Go to the documentation of this file.
1 /****************************************************************************/
12 // An unextended detector measuring at a fixed position on a fixed lane.
13 /****************************************************************************/
14 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
15 // Copyright (C) 2001-2014 DLR (http://www.dlr.de/) and contributors
16 /****************************************************************************/
17 //
18 // This file is part of SUMO.
19 // SUMO is free software: you can redistribute it and/or modify
20 // it under the terms of the GNU General Public License as published by
21 // the Free Software Foundation, either version 3 of the License, or
22 // (at your option) any later version.
23 //
24 /****************************************************************************/
25 
26 
27 // ===========================================================================
28 // included modules
29 // ===========================================================================
30 #ifdef _MSC_VER
31 #include <windows_config.h>
32 #else
33 #include <config.h>
34 #endif
35 
36 #include "MSInductLoop.h"
37 #include <cassert>
38 #include <numeric>
39 #include <utility>
41 #include <utils/common/ToString.h>
43 #include <microsim/MSLane.h>
44 #include <microsim/MSVehicle.h>
45 #include <microsim/MSNet.h>
50 
51 #ifdef CHECK_MEMORY_LEAKS
52 #include <foreign/nvwa/debug_new.h>
53 #endif // CHECK_MEMORY_LEAKS
54 
55 
56 // ===========================================================================
57 // method definitions
58 // ===========================================================================
59 MSInductLoop::MSInductLoop(const std::string& id, MSLane* const lane,
60  SUMOReal positionInMeters, bool splitByType) :
61  MSMoveReminder(id, lane),
63  myPosition(positionInMeters), mySplitByType(splitByType),
64  myLastLeaveTime(STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep())),
65  myVehicleDataCont(),
66  myVehiclesOnDet() {
67  assert(myPosition >= 0 && myPosition <= myLane->getLength());
68  reset();
69 }
70 
71 
73 }
74 
75 
76 void
80  myVehicleDataCont.clear();
81 }
82 
83 
84 bool
86  SUMOReal newPos, SUMOReal newSpeed) {
87  if (newPos < myPosition) {
88  // detector not reached yet
89  return true;
90  }
91  if (newPos >= myPosition && oldPos < myPosition) {
92  // entered the detector by move
93  SUMOReal entryTime = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
94  if (newSpeed != 0) {
95  if (myPosition > oldPos) {
96  entryTime += (myPosition - oldPos) / newSpeed;
97  }
98  }
99  enterDetectorByMove(veh, entryTime);
100  }
101  if (newPos - veh.getVehicleType().getLength() > myPosition) {
102  // vehicle passed the detector (it may have changed onto this lane
103  // somewhere past the detector)
104  assert(newSpeed > 0 || myVehiclesOnDet.find(&veh) == myVehiclesOnDet.end());
105  SUMOReal leaveTime = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
106  if (newSpeed > 0) {
107  leaveTime += (myPosition - oldPos + veh.getVehicleType().getLength()) / newSpeed;
108  }
109  leaveDetectorByMove(veh, leaveTime);
110  return false;
111  }
112  // vehicle stays on the detector
113  return true;
114 }
115 
116 
117 bool
120  leaveDetectorByLaneChange(veh, lastPos);
121  return false;
122  }
123  return true;
124 }
125 
126 
127 SUMOReal
129  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
130  return d.size() != 0
131  ? accumulate(d.begin(), d.end(), (SUMOReal) 0.0, speedSum) / (SUMOReal) d.size()
132  : -1;
133 }
134 
135 
136 SUMOReal
138  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
139  return d.size() != 0
140  ? accumulate(d.begin(), d.end(), (SUMOReal) 0.0, lengthSum) / (SUMOReal) d.size()
141  : -1;
142 }
143 
144 
145 SUMOReal
148  std::vector<VehicleData> d = collectVehiclesOnDet(tbeg);
149  if (d.size() == 0) {
150  return -1;
151  }
152  SUMOReal occupancy = 0;
153  for (std::vector< VehicleData >::const_iterator i = d.begin(); i != d.end(); ++i) {
154  SUMOReal timeOnDetDuringInterval = (*i).leaveTimeM - MAX2(STEPS2TIME(tbeg), (*i).entryTimeM);
155  timeOnDetDuringInterval = MIN2(timeOnDetDuringInterval, TS);
156  occupancy += timeOnDetDuringInterval;
157  }
158  return occupancy / TS * (SUMOReal) 100.;
159 }
160 
161 
162 unsigned int
164  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
165  return (unsigned int) d.size();
166 }
167 
168 
169 std::vector<std::string>
171  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
172  std::vector<std::string> ret;
173  for (std::vector<VehicleData>::iterator i = d.begin(); i != d.end(); ++i) {
174  ret.push_back((*i).idM);
175  }
176  return ret;
177 }
178 
179 
180 SUMOReal
182  if (myVehiclesOnDet.size() != 0) {
183  // detector is occupied
184  return 0;
185  }
186  return STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()) - myLastLeaveTime;
187 }
188 
189 
190 void
192  dev.writeXMLHeader("detector", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo-sim.org/xsd/det_e1_file.xsd\"");
193 }
194 
195 
196 void
198  SUMOTime startTime, SUMOTime stopTime) {
199  writeTypedXMLOutput(dev, startTime, stopTime, "", myVehicleDataCont, myVehiclesOnDet);
200  if (mySplitByType) {
201  dev << ">\n";
202  std::map<std::string, std::pair<VehicleDataCont, VehicleMap> > types;
203  // collect / divide
204  for (std::deque< VehicleData >::const_iterator i = myVehicleDataCont.begin(); i != myVehicleDataCont.end(); ++i) {
205  if (types.find((*i).typeIDM) == types.end()) {
206  types[(*i).typeIDM] = make_pair(VehicleDataCont(), VehicleMap());
207  }
208  types[(*i).typeIDM].first.push_back(*i);
209  }
210  for (std::map< SUMOVehicle*, SUMOReal >::const_iterator i = myVehiclesOnDet.begin(); i != myVehiclesOnDet.end(); ++i) {
211  const std::string& type = (*i).first->getVehicleType().getID();
212  if (types.find(type) == types.end()) {
213  types[type] = make_pair(VehicleDataCont(), VehicleMap());
214  }
215  types[type].second[(*i).first] = (*i).second;
216  }
217  // write
218  for (std::map<std::string, std::pair<VehicleDataCont, VehicleMap> >::const_iterator i = types.begin(); i != types.end(); ++i) {
219  writeTypedXMLOutput(dev, startTime, stopTime, (*i).first, (*i).second.first, (*i).second.second);
220  dev << "/>\n";
221  }
222  dev << " </interval>\n";
223  } else {
224  dev << "/>\n";
225  }
226  reset();
227 }
228 
229 void
231  const std::string& type, const VehicleDataCont& vdc, const VehicleMap& vm) {
232  SUMOReal t(STEPS2TIME(stopTime - startTime));
233  unsigned nVehCrossed = (unsigned) vdc.size();
234  if (type == "") {
235  nVehCrossed += myDismissedVehicleNumber;
236  }
237  SUMOReal flow = ((SUMOReal) vdc.size() / (SUMOReal) t) * (SUMOReal) 3600.0;
238  SUMOReal occupancy = 0;
239  for (std::deque< VehicleData >::const_iterator i = vdc.begin(); i != vdc.end(); ++i) {
240  SUMOReal timeOnDetDuringInterval = (*i).leaveTimeM - MAX2(STEPS2TIME(startTime), (*i).entryTimeM);
241  timeOnDetDuringInterval = MIN2(timeOnDetDuringInterval, t);
242  occupancy += timeOnDetDuringInterval;
243  }
244  for (std::map< SUMOVehicle*, SUMOReal >::const_iterator i = vm.begin(); i != vm.end(); ++i) {
245  SUMOReal timeOnDetDuringInterval = STEPS2TIME(stopTime) - MAX2(STEPS2TIME(startTime), (*i).second);
246  occupancy += timeOnDetDuringInterval;
247  }
248  occupancy = occupancy / t * (SUMOReal) 100.;
249  SUMOReal meanSpeed = vdc.size() != 0
250  ? accumulate(vdc.begin(), vdc.end(), (SUMOReal) 0.0, speedSum) / (SUMOReal) vdc.size()
251  : -1;
252  SUMOReal meanLength = vdc.size() != 0
253  ? accumulate(vdc.begin(), vdc.end(), (SUMOReal) 0.0, lengthSum) / (SUMOReal) vdc.size()
254  : -1;
255  if (type != "") {
256  dev << " <typedInterval type=\"" + type + "\" ";
257  } else {
258  dev << " <interval ";
259  }
260  dev << "begin=\"" << time2string(startTime) << "\" end=\"" <<
261  time2string(stopTime) << "\" " << "id=\"" << StringUtils::escapeXML(getID()) << "\" ";
262  dev << "nVehContrib=\"" << vdc.size() << "\" flow=\"" << flow <<
263  "\" occupancy=\"" << occupancy << "\" speed=\"" << meanSpeed <<
264  "\" length=\"" << meanLength <<
265  "\" nVehEntered=\"" << nVehCrossed << "\"";
266 }
267 
268 
269 void
271  SUMOReal entryTimestep) {
272  myVehiclesOnDet.insert(std::make_pair(&veh, entryTimestep));
273 }
274 
275 
276 void
278  SUMOReal leaveTimestep) {
279  VehicleMap::iterator it = myVehiclesOnDet.find(&veh);
280  if (it != myVehiclesOnDet.end()) {
281  SUMOReal entryTimestep = it->second;
282  myVehiclesOnDet.erase(it);
283  assert(entryTimestep < leaveTimestep);
284  myVehicleDataCont.push_back(VehicleData(veh.getID(), veh.getVehicleType().getLength(), entryTimestep, leaveTimestep, veh.getVehicleType().getID()));
285  myLastOccupancy = leaveTimestep - entryTimestep;
286  }
287  myLastLeaveTime = leaveTimestep;
288 }
289 
290 
291 void
293  // Discard entry data
294  myVehiclesOnDet.erase(&veh);
295  if (lastPos > myPosition) {
296  // vehicle is on detector during lane change or arrival, or ...
298  }
299 }
300 
301 
302 std::vector<MSInductLoop::VehicleData>
304  SUMOReal t = STEPS2TIME(tMS);
305  std::vector<VehicleData> ret;
306  for (VehicleDataCont::const_iterator i = myVehicleDataCont.begin(); i != myVehicleDataCont.end(); ++i) {
307  if ((*i).leaveTimeM >= t) {
308  ret.push_back(*i);
309  }
310  }
311  for (VehicleDataCont::const_iterator i = myLastVehicleDataCont.begin(); i != myLastVehicleDataCont.end(); ++i) {
312  if ((*i).leaveTimeM >= t) {
313  ret.push_back(*i);
314  }
315  }
317  for (VehicleMap::const_iterator i = myVehiclesOnDet.begin(); i != myVehiclesOnDet.end(); ++i) {
318  SUMOVehicle* v = (*i).first;
319  VehicleData d(v->getID(), v->getVehicleType().getLength(), (*i).second, STEPS2TIME(ct), v->getVehicleType().getID());
320  d.speedM = v->getSpeed();
321  ret.push_back(d);
322  }
323  return ret;
324 }
325 
326 
327 /****************************************************************************/
328 
void writeXMLOutput(OutputDevice &dev, SUMOTime startTime, SUMOTime stopTime)
Writes collected values into the given stream.
unsigned myDismissedVehicleNumber
The number of dismissed vehicles.
Definition: MSInductLoop.h:340
MSInductLoop(const std::string &id, MSLane *const lane, SUMOReal positionInMeters, bool splitByType)
Constructor.
The vehicle arrived at a junction.
virtual void reset()
Resets all generated values to allow computation of next interval.
static std::string escapeXML(const std::string &orig)
Replaces the standard escapes by their XML entities.
Notification
Definition of a vehicle state.
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:61
SUMOReal getLength() const
Get vehicle's length [m].
virtual std::vector< VehicleData > collectVehiclesOnDet(SUMOTime t) const
Returns vehicle data for vehicles that have been on the detector starting at the given time...
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:72
SUMOReal getCurrentOccupancy() const
Returns the current occupancy.
#define TS
Definition: SUMOTime.h:52
VehicleMap myVehiclesOnDet
Data for vehicles that have entered the detector (vehicle -> enter time)
Definition: MSInductLoop.h:357
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:216
VehicleDataCont myLastVehicleDataCont
Data of vehicles that have completely passed the detector in the last time interval.
Definition: MSInductLoop.h:350
const SUMOReal myPosition
Detector's position on lane [m].
Definition: MSInductLoop.h:328
The simulated network and simulation perfomer.
Definition: MSNet.h:91
void writeXMLDetectorProlog(OutputDevice &dev) const
Opens the XML-output using "detector" as root element.
VehicleDataCont myVehicleDataCont
Data of vehicles that have completely passed the detector.
Definition: MSInductLoop.h:347
SUMOReal speedM
Speed of the vehicle in [m/s].
Definition: MSInductLoop.h:266
std::deque< VehicleData > VehicleDataCont
Type of myVehicleDataCont.
Definition: MSInductLoop.h:344
bool writeXMLHeader(const std::string &rootElement, const std::string &attrs="", const std::string &comment="")
Writes an XML header with optional configuration.
static SUMOReal lengthSum(SUMOReal sumSoFar, const MSInductLoop::VehicleData &data)
Adds up VehicleData::lengthM.
Definition: MSInductLoop.h:320
std::vector< std::string > getCurrentVehicleIDs() const
Returns the ids of vehicles that have passed the detector.
const std::string & getID() const
Returns the id.
Definition: Named.h:60
Representation of a vehicle.
Definition: SUMOVehicle.h:64
~MSInductLoop()
Destructor.
virtual void enterDetectorByMove(SUMOVehicle &veh, SUMOReal entryTimestep)
Introduces a vehicle to the detector's map myVehiclesOnDet.
static SUMOReal speedSum(SUMOReal sumSoFar, const MSInductLoop::VehicleData &data)
Adds up VehicleData::speedM.
Definition: MSInductLoop.h:315
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
bool mySplitByType
Whether additional information split by vehicle classes shall be generated.
Definition: MSInductLoop.h:331
T MIN2(T a, T b)
Definition: StdDefs.h:66
Something on a lane to be noticed about vehicle movement.
SUMOReal getCurrentSpeed() const
Returns the speed of the vehicle on the detector.
unsigned int getCurrentPassedNumber() const
Returns the number of vehicles that have passed the detector.
SUMOReal myLastOccupancy
Occupancy by the last vehicle detected.
Definition: MSInductLoop.h:337
virtual SUMOReal getSpeed() const =0
Returns the vehicle's current speed.
Struct to store the data of the counted vehicle internally.
Definition: MSInductLoop.h:243
virtual void leaveDetectorByLaneChange(SUMOVehicle &veh, SUMOReal lastPos)
Removes a vehicle from the detector's map myVehiclesOnDet.
const std::string & getID() const
Returns the name of the vehicle type.
SUMOReal getTimestepsSinceLastDetection() const
Returns the time since the last vehicle left the detector.
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
#define SUMOReal
Definition: config.h:215
SUMOReal myLastLeaveTime
Leave-time of the last vehicle detected [s].
Definition: MSInductLoop.h:334
void writeTypedXMLOutput(OutputDevice &dev, SUMOTime startTime, SUMOTime stopTime, const std::string &type, const VehicleDataCont &vdc, const VehicleMap &vm)
#define DELTA_T
Definition: SUMOTime.h:50
SUMOReal getCurrentLength() const
Returns the length of the vehicle on the detector.
virtual void leaveDetectorByMove(SUMOVehicle &veh, SUMOReal leaveTimestep)
Processes a vehicle that leaves the detector.
Representation of a lane in the micro simulation.
Definition: MSLane.h:77
virtual const std::string & getID() const =0
Get the vehicle's ID.
bool notifyLeave(SUMOVehicle &veh, SUMOReal lastPos, MSMoveReminder::Notification reason)
Dismisses the vehicle if it is on the detector due to a lane change.
std::map< SUMOVehicle *, SUMOReal > VehicleMap
Type of myVehiclesOnDet.
Definition: MSInductLoop.h:354
Base of value-generating classes (detectors)
bool notifyMove(SUMOVehicle &veh, SUMOReal oldPos, SUMOReal newPos, SUMOReal newSpeed)
Checks whether the vehicle shall be counted and/or shall still touch this MSMoveReminder.
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle's type.