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-2013 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
103  SUMOReal leaveTime = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
104  leaveTime += (myPosition - oldPos + veh.getVehicleType().getLength()) / newSpeed;
105  leaveDetectorByMove(veh, leaveTime);
106  return false;
107  }
108  // vehicle stays on the detector
109  return true;
110 }
111 
112 
113 bool
116  leaveDetectorByLaneChange(veh, lastPos);
117  return false;
118  }
119  return true;
120 }
121 
122 
123 SUMOReal
125  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
126  return d.size() != 0
127  ? accumulate(d.begin(), d.end(), (SUMOReal) 0.0, speedSum) / (SUMOReal) d.size()
128  : -1;
129 }
130 
131 
132 SUMOReal
134  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
135  return d.size() != 0
136  ? accumulate(d.begin(), d.end(), (SUMOReal) 0.0, lengthSum) / (SUMOReal) d.size()
137  : -1;
138 }
139 
140 
141 SUMOReal
144  std::vector<VehicleData> d = collectVehiclesOnDet(tbeg);
145  if (d.size() == 0) {
146  return -1;
147  }
148  SUMOReal occupancy = 0;
149  for (std::vector< VehicleData >::const_iterator i = d.begin(); i != d.end(); ++i) {
150  SUMOReal timeOnDetDuringInterval = (*i).leaveTimeM - MAX2(STEPS2TIME(tbeg), (*i).entryTimeM);
151  timeOnDetDuringInterval = MIN2(timeOnDetDuringInterval, TS);
152  occupancy += timeOnDetDuringInterval;
153  }
154  return occupancy / TS * (SUMOReal) 100.;
155 }
156 
157 
158 unsigned int
160  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
161  return (unsigned int) d.size();
162 }
163 
164 
165 std::vector<std::string>
167  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
168  std::vector<std::string> ret;
169  for (std::vector<VehicleData>::iterator i = d.begin(); i != d.end(); ++i) {
170  ret.push_back((*i).idM);
171  }
172  return ret;
173 }
174 
175 
176 SUMOReal
178  if (myVehiclesOnDet.size() != 0) {
179  // detector is occupied
180  return 0;
181  }
182  return STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()) - myLastLeaveTime;
183 }
184 
185 
186 void
188  dev.writeXMLHeader("detector", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo-sim.org/xsd/det_e1_file.xsd\"");
189 }
190 
191 
192 void
194  SUMOTime startTime, SUMOTime stopTime) {
195  writeTypedXMLOutput(dev, startTime, stopTime, "", myVehicleDataCont, myVehiclesOnDet);
196  if (mySplitByType) {
197  dev << ">\n";
198  std::map<std::string, std::pair<VehicleDataCont, VehicleMap> > types;
199  // collect / divide
200  for (std::deque< VehicleData >::const_iterator i = myVehicleDataCont.begin(); i != myVehicleDataCont.end(); ++i) {
201  if (types.find((*i).typeIDM) == types.end()) {
202  types[(*i).typeIDM] = make_pair(VehicleDataCont(), VehicleMap());
203  }
204  types[(*i).typeIDM].first.push_back(*i);
205  }
206  for (std::map< SUMOVehicle*, SUMOReal >::const_iterator i = myVehiclesOnDet.begin(); i != myVehiclesOnDet.end(); ++i) {
207  const std::string& type = (*i).first->getVehicleType().getID();
208  if (types.find(type) == types.end()) {
209  types[type] = make_pair(VehicleDataCont(), VehicleMap());
210  }
211  types[type].second[(*i).first] = (*i).second;
212  }
213  // write
214  for (std::map<std::string, std::pair<VehicleDataCont, VehicleMap> >::const_iterator i = types.begin(); i != types.end(); ++i) {
215  writeTypedXMLOutput(dev, startTime, stopTime, (*i).first, (*i).second.first, (*i).second.second);
216  dev << "/>\n";
217  }
218  dev << " </interval>\n";
219  } else {
220  dev << "/>\n";
221  }
222  reset();
223 }
224 
225 void
227  const std::string& type, const VehicleDataCont& vdc, const VehicleMap& vm) {
228  SUMOReal t(STEPS2TIME(stopTime - startTime));
229  unsigned nVehCrossed = (unsigned) vdc.size();
230  if (type == "") {
231  nVehCrossed += myDismissedVehicleNumber;
232  }
233  SUMOReal flow = ((SUMOReal) vdc.size() / (SUMOReal) t) * (SUMOReal) 3600.0;
234  SUMOReal occupancy = 0;
235  for (std::deque< VehicleData >::const_iterator i = vdc.begin(); i != vdc.end(); ++i) {
236  SUMOReal timeOnDetDuringInterval = (*i).leaveTimeM - MAX2(STEPS2TIME(startTime), (*i).entryTimeM);
237  timeOnDetDuringInterval = MIN2(timeOnDetDuringInterval, t);
238  occupancy += timeOnDetDuringInterval;
239  }
240  for (std::map< SUMOVehicle*, SUMOReal >::const_iterator i = vm.begin(); i != vm.end(); ++i) {
241  SUMOReal timeOnDetDuringInterval = STEPS2TIME(stopTime) - MAX2(STEPS2TIME(startTime), (*i).second);
242  occupancy += timeOnDetDuringInterval;
243  }
244  occupancy = occupancy / t * (SUMOReal) 100.;
245  SUMOReal meanSpeed = vdc.size() != 0
246  ? accumulate(vdc.begin(), vdc.end(), (SUMOReal) 0.0, speedSum) / (SUMOReal) vdc.size()
247  : -1;
248  SUMOReal meanLength = vdc.size() != 0
249  ? accumulate(vdc.begin(), vdc.end(), (SUMOReal) 0.0, lengthSum) / (SUMOReal) vdc.size()
250  : -1;
251  if (type != "") {
252  dev << " <typedInterval type=\"" + type + "\" ";
253  } else {
254  dev << " <interval ";
255  }
256  dev << "begin=\"" << time2string(startTime) << "\" end=\"" <<
257  time2string(stopTime) << "\" " << "id=\"" << StringUtils::escapeXML(getID()) << "\" ";
258  dev << "nVehContrib=\"" << vdc.size() << "\" flow=\"" << flow <<
259  "\" occupancy=\"" << occupancy << "\" speed=\"" << meanSpeed <<
260  "\" length=\"" << meanLength <<
261  "\" nVehEntered=\"" << nVehCrossed << "\"";
262 }
263 
264 
265 void
267  SUMOReal entryTimestep) {
268  myVehiclesOnDet.insert(std::make_pair(&veh, entryTimestep));
269 }
270 
271 
272 void
274  SUMOReal leaveTimestep) {
275  VehicleMap::iterator it = myVehiclesOnDet.find(&veh);
276  if (it != myVehiclesOnDet.end()) {
277  SUMOReal entryTimestep = it->second;
278  myVehiclesOnDet.erase(it);
279  assert(entryTimestep < leaveTimestep);
280  myVehicleDataCont.push_back(VehicleData(veh.getID(), veh.getVehicleType().getLength(), entryTimestep, leaveTimestep, veh.getVehicleType().getID()));
281  myLastOccupancy = leaveTimestep - entryTimestep;
282  }
283  myLastLeaveTime = leaveTimestep;
284 }
285 
286 
287 void
289  // Discard entry data
290  myVehiclesOnDet.erase(&veh);
291  if (lastPos > myPosition) {
292  // vehicle is on detector during lane change or arrival, or ...
294  }
295 }
296 
297 
298 std::vector<MSInductLoop::VehicleData>
300  SUMOReal t = STEPS2TIME(tMS);
301  std::vector<VehicleData> ret;
302  for (VehicleDataCont::const_iterator i = myVehicleDataCont.begin(); i != myVehicleDataCont.end(); ++i) {
303  if ((*i).leaveTimeM >= t) {
304  ret.push_back(*i);
305  }
306  }
307  for (VehicleDataCont::const_iterator i = myLastVehicleDataCont.begin(); i != myLastVehicleDataCont.end(); ++i) {
308  if ((*i).leaveTimeM >= t) {
309  ret.push_back(*i);
310  }
311  }
313  for (VehicleMap::const_iterator i = myVehiclesOnDet.begin(); i != myVehiclesOnDet.end(); ++i) {
314  SUMOVehicle* v = (*i).first;
315  VehicleData d(v->getID(), v->getVehicleType().getLength(), (*i).second, STEPS2TIME(ct), v->getVehicleType().getID());
316  d.speedM = v->getSpeed();
317  ret.push_back(d);
318  }
319  return ret;
320 }
321 
322 
323 /****************************************************************************/
324 
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:339
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&#39;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:150
T MAX2(T a, T b)
Definition: StdDefs.h:63
SUMOReal getCurrentOccupancy() const
Returns the current occupancy.
#define TS
Definition: SUMOTime.h:52
VehicleMap myVehiclesOnDet
Data for vehicles that have entered the detector (vehicle -&gt; enter time)
Definition: MSInductLoop.h:356
SUMOTime getCurrentTimeStep() const
Returns the current simulation step (in s)
Definition: MSNet.cpp:502
VehicleDataCont myLastVehicleDataCont
Data of vehicles that have completely passed the detector in the last time interval.
Definition: MSInductLoop.h:349
const SUMOReal myPosition
Detector&#39;s position on lane [m].
Definition: MSInductLoop.h:327
The simulated network and simulation perfomer.
Definition: MSNet.h:89
void writeXMLDetectorProlog(OutputDevice &dev) const
Opens the XML-output using &quot;detector&quot; as root element.
VehicleDataCont myVehicleDataCont
Data of vehicles that have completely passed the detector.
Definition: MSInductLoop.h:346
SUMOReal speedM
Speed of the vehicle in [m/s].
Definition: MSInductLoop.h:265
std::deque< VehicleData > VehicleDataCont
Type of myVehicleDataCont.
Definition: MSInductLoop.h:343
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:319
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:63
~MSInductLoop()
Destructor.
virtual void enterDetectorByMove(SUMOVehicle &veh, SUMOReal entryTimestep)
Introduces a vehicle to the detector&#39;s map myVehiclesOnDet.
static SUMOReal speedSum(SUMOReal sumSoFar, const MSInductLoop::VehicleData &data)
Adds up VehicleData::speedM.
Definition: MSInductLoop.h:314
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
bool mySplitByType
Whether additional information split by vehicle classes shall be generated.
Definition: MSInductLoop.h:330
T MIN2(T a, T b)
Definition: StdDefs.h:57
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:336
virtual SUMOReal getSpeed() const =0
Returns the vehicle&#39;s current speed.
Struct to store the data of the counted vehicle internally.
Definition: MSInductLoop.h:242
virtual void leaveDetectorByLaneChange(SUMOVehicle &veh, SUMOReal lastPos)
Removes a vehicle from the detector&#39;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:70
#define SUMOReal
Definition: config.h:215
SUMOReal myLastLeaveTime
Leave-time of the last vehicle detected [s].
Definition: MSInductLoop.h:333
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&#39;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:353
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&#39;s type.