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 && oldPos - 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  // vehicle is on detector during lane change or arrival, or ...
118  return false;
119  }
120  return true;
121 }
122 
123 
124 bool
126  return true;
127 }
128 
129 
130 SUMOReal
132  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
133  return d.size() != 0
134  ? accumulate(d.begin(), d.end(), (SUMOReal) 0.0, speedSum) / (SUMOReal) d.size()
135  : -1;
136 }
137 
138 
139 SUMOReal
141  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
142  return d.size() != 0
143  ? accumulate(d.begin(), d.end(), (SUMOReal) 0.0, lengthSum) / (SUMOReal) d.size()
144  : -1;
145 }
146 
147 
148 SUMOReal
151  std::vector<VehicleData> d = collectVehiclesOnDet(tbeg);
152  if (d.size() == 0) {
153  return -1;
154  }
155  SUMOReal occupancy = 0;
156  for (std::vector< VehicleData >::const_iterator i = d.begin(); i != d.end(); ++i) {
157  SUMOReal timeOnDetDuringInterval = (*i).leaveTimeM - MAX2(STEPS2TIME(tbeg), (*i).entryTimeM);
158  timeOnDetDuringInterval = MIN2(timeOnDetDuringInterval, TS);
159  occupancy += timeOnDetDuringInterval;
160  }
161  return occupancy / TS * (SUMOReal) 100.;
162 }
163 
164 
165 unsigned int
167  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
168  return (unsigned int) d.size();
169 }
170 
171 
172 std::vector<std::string>
174  std::vector<VehicleData> d = collectVehiclesOnDet(MSNet::getInstance()->getCurrentTimeStep() - DELTA_T);
175  std::vector<std::string> ret;
176  for (std::vector<VehicleData>::iterator i = d.begin(); i != d.end(); ++i) {
177  ret.push_back((*i).idM);
178  }
179  return ret;
180 }
181 
182 
183 SUMOReal
185  if (myVehiclesOnDet.size() != 0) {
186  // detector is occupied
187  return 0;
188  }
189  return STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()) - myLastLeaveTime;
190 }
191 
192 
193 void
195  dev.writeXMLHeader("detector", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.sf.net/xsd/det_e1_file.xsd\"");
196 }
197 
198 
199 void
201  SUMOTime startTime, SUMOTime stopTime) {
202  writeTypedXMLOutput(dev, startTime, stopTime, "", myVehicleDataCont, myVehiclesOnDet);
203  if (mySplitByType) {
204  dev << ">\n";
205  std::map<std::string, std::pair<VehicleDataCont, VehicleMap> > types;
206  // collect / divide
207  for (std::deque< VehicleData >::const_iterator i = myVehicleDataCont.begin(); i != myVehicleDataCont.end(); ++i) {
208  if (types.find((*i).typeIDM) == types.end()) {
209  types[(*i).typeIDM] = make_pair(VehicleDataCont(), VehicleMap());
210  }
211  types[(*i).typeIDM].first.push_back(*i);
212  }
213  for (std::map< SUMOVehicle*, SUMOReal >::const_iterator i = myVehiclesOnDet.begin(); i != myVehiclesOnDet.end(); ++i) {
214  const std::string& type = (*i).first->getVehicleType().getID();
215  if (types.find(type) == types.end()) {
216  types[type] = make_pair(VehicleDataCont(), VehicleMap());
217  }
218  types[type].second[(*i).first] = (*i).second;
219  }
220  // write
221  for (std::map<std::string, std::pair<VehicleDataCont, VehicleMap> >::const_iterator i = types.begin(); i != types.end(); ++i) {
222  writeTypedXMLOutput(dev, startTime, stopTime, (*i).first, (*i).second.first, (*i).second.second);
223  dev << "/>\n";
224  }
225  dev << " </interval>\n";
226  } else {
227  dev << "/>\n";
228  }
229  reset();
230 }
231 
232 void
234  const std::string& type, const VehicleDataCont& vdc, const VehicleMap& vm) {
235  SUMOReal t(STEPS2TIME(stopTime - startTime));
236  unsigned nVehCrossed = (unsigned) vdc.size();
237  if (type == "") {
238  nVehCrossed += myDismissedVehicleNumber;
239  }
240  SUMOReal flow = ((SUMOReal) vdc.size() / (SUMOReal) t) * (SUMOReal) 3600.0;
241  SUMOReal occupancy = 0;
242  for (std::deque< VehicleData >::const_iterator i = vdc.begin(); i != vdc.end(); ++i) {
243  SUMOReal timeOnDetDuringInterval = (*i).leaveTimeM - MAX2(STEPS2TIME(startTime), (*i).entryTimeM);
244  timeOnDetDuringInterval = MIN2(timeOnDetDuringInterval, t);
245  occupancy += timeOnDetDuringInterval;
246  }
247  for (std::map< SUMOVehicle*, SUMOReal >::const_iterator i = vm.begin(); i != vm.end(); ++i) {
248  SUMOReal timeOnDetDuringInterval = STEPS2TIME(stopTime) - MAX2(STEPS2TIME(startTime), (*i).second);
249  occupancy += timeOnDetDuringInterval;
250  }
251  occupancy = occupancy / t * (SUMOReal) 100.;
252  SUMOReal meanSpeed = vdc.size() != 0
253  ? accumulate(vdc.begin(), vdc.end(), (SUMOReal) 0.0, speedSum) / (SUMOReal) vdc.size()
254  : -1;
255  SUMOReal meanLength = vdc.size() != 0
256  ? accumulate(vdc.begin(), vdc.end(), (SUMOReal) 0.0, lengthSum) / (SUMOReal) vdc.size()
257  : -1;
258  if (type != "") {
259  dev << " <typedInterval type=\"" + type + "\" ";
260  } else {
261  dev << " <interval ";
262  }
263  dev << "begin=\"" << time2string(startTime) << "\" end=\"" <<
264  time2string(stopTime) << "\" " << "id=\"" << StringUtils::escapeXML(getID()) << "\" ";
265  dev << "nVehContrib=\"" << vdc.size() << "\" flow=\"" << flow <<
266  "\" occupancy=\"" << occupancy << "\" speed=\"" << meanSpeed <<
267  "\" length=\"" << meanLength <<
268  "\" nVehEntered=\"" << nVehCrossed << "\"";
269 }
270 
271 
272 void
274  SUMOReal entryTimestep) {
275  myVehiclesOnDet.insert(std::make_pair(&veh, entryTimestep));
276 }
277 
278 
279 void
281  SUMOReal leaveTimestep) {
282  VehicleMap::iterator it = myVehiclesOnDet.find(&veh);
283  if (it != myVehiclesOnDet.end()) {
284  SUMOReal entryTimestep = it->second;
285  myVehiclesOnDet.erase(it);
286  assert(entryTimestep < leaveTimestep);
287  myVehicleDataCont.push_back(VehicleData(veh.getID(), veh.getVehicleType().getLength(), entryTimestep, leaveTimestep, veh.getVehicleType().getID()));
288  myLastOccupancy = leaveTimestep - entryTimestep;
289  }
290  myLastLeaveTime = leaveTimestep;
291 }
292 
293 
294 void
296  // Discard entry data
297  myVehiclesOnDet.erase(&veh);
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:352
virtual void leaveDetectorByLaneChange(SUMOVehicle &veh)
Removes a vehicle from the detector&#39;s map myVehiclesOnDet.
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:369
SUMOTime getCurrentTimeStep() const
Returns the current simulation step (in s)
Definition: MSNet.cpp:500
VehicleDataCont myLastVehicleDataCont
Data of vehicles that have completely passed the detector in the last time interval.
Definition: MSInductLoop.h:362
const SUMOReal myPosition
Detector&#39;s position on lane [m].
Definition: MSInductLoop.h:340
The simulated network and simulation perfomer.
Definition: MSNet.h:87
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:359
SUMOReal speedM
Speed of the vehicle in [m/s].
Definition: MSInductLoop.h:279
std::deque< VehicleData > VehicleDataCont
Type of myVehicleDataCont.
Definition: MSInductLoop.h:356
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:332
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:327
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
bool mySplitByType
Whether additional information split by vehicle classes shall be generated.
Definition: MSInductLoop.h:343
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:349
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:256
bool notifyEnter(SUMOVehicle &veh, MSMoveReminder::Notification reason)
Returns whether the detector may has to be concerned during the vehicle&#39;s further movement...
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:221
SUMOReal myLastLeaveTime
Leave-time of the last vehicle detected [s].
Definition: MSInductLoop.h:346
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:73
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:366
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.