SUMO - Simulation of Urban MObility
RODFDetector.cpp
Go to the documentation of this file.
1 /****************************************************************************/
13 // Class representing a detector within the DFROUTER
14 /****************************************************************************/
15 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
16 // Copyright (C) 2006-2016 DLR (http://www.dlr.de/) and contributors
17 /****************************************************************************/
18 //
19 // This file is part of SUMO.
20 // SUMO is free software: you can redistribute it and/or modify
21 // it under the terms of the GNU General Public License as published by
22 // the Free Software Foundation, either version 3 of the License, or
23 // (at your option) any later version.
24 //
25 /****************************************************************************/
26 
27 
28 // ===========================================================================
29 // included modules
30 // ===========================================================================
31 #ifdef _MSC_VER
32 #include <windows_config.h>
33 #else
34 #include <config.h>
35 #endif
36 
37 #include <cassert>
38 #include "RODFDetector.h"
42 #include <utils/common/ToString.h>
43 #include <router/ROEdge.h>
44 #include "RODFEdge.h"
45 #include "RODFRouteDesc.h"
46 #include "RODFRouteCont.h"
47 #include "RODFDetectorFlow.h"
50 #include <utils/common/StdDefs.h>
52 #include <utils/geom/GeomHelper.h>
53 #include "RODFNet.h"
57 
58 #ifdef CHECK_MEMORY_LEAKS
59 #include <foreign/nvwa/debug_new.h>
60 #endif // CHECK_MEMORY_LEAKS
61 
62 
63 // ===========================================================================
64 // method definitions
65 // ===========================================================================
66 RODFDetector::RODFDetector(const std::string& id, const std::string& laneID,
67  SUMOReal pos, const RODFDetectorType type)
68  : Named(id), myLaneID(laneID), myPosition(pos), myType(type), myRoutes(0) {}
69 
70 
71 RODFDetector::RODFDetector(const std::string& id, const RODFDetector& f)
73  myType(f.myType), myRoutes(0) {
74  if (f.myRoutes != 0) {
75  myRoutes = new RODFRouteCont(*(f.myRoutes));
76  }
77 }
78 
79 
81  delete myRoutes;
82 }
83 
84 
85 void
87  myType = type;
88 }
89 
90 
93  SUMOReal distance = rd.edges2Pass[0]->getFromJunction()->getPosition().distanceTo(rd.edges2Pass.back()->getToJunction()->getPosition());
94  SUMOReal length = 0;
95  for (ROEdgeVector::const_iterator i = rd.edges2Pass.begin(); i != rd.edges2Pass.end(); ++i) {
96  length += (*i)->getLength();
97  }
98  return (distance / length);
99 }
100 
101 
102 void
104  const RODFDetectorFlows& flows,
105  SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset) {
106  if (myRoutes == 0) {
107  return;
108  }
109  // compute edges to determine split probabilities
110  const std::vector<RODFRouteDesc>& routes = myRoutes->get();
111  std::vector<RODFEdge*> nextDetEdges;
112  std::set<ROEdge*> preSplitEdges;
113  for (std::vector<RODFRouteDesc>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
114  const RODFRouteDesc& rd = *i;
115  bool hadSplit = false;
116  for (ROEdgeVector::const_iterator j = rd.edges2Pass.begin(); j != rd.edges2Pass.end(); ++j) {
117  if (hadSplit && net->hasDetector(*j)) {
118  if (find(nextDetEdges.begin(), nextDetEdges.end(), *j) == nextDetEdges.end()) {
119  nextDetEdges.push_back(static_cast<RODFEdge*>(*j));
120  }
121  myRoute2Edge[rd.routename] = static_cast<RODFEdge*>(*j);
122  break;
123  }
124  if (!hadSplit) {
125  preSplitEdges.insert(*j);
126  }
127  if ((*j)->getNumSuccessors() > 1) {
128  hadSplit = true;
129  }
130  }
131  }
132  std::map<ROEdge*, SUMOReal> inFlows;
133  if (OptionsCont::getOptions().getBool("respect-concurrent-inflows")) {
134  for (std::vector<RODFEdge*>::const_iterator i = nextDetEdges.begin(); i != nextDetEdges.end(); ++i) {
135  std::set<ROEdge*> seen(preSplitEdges);
136  ROEdgeVector pending;
137  pending.push_back(*i);
138  seen.insert(*i);
139  while (!pending.empty()) {
140  ROEdge* e = pending.back();
141  pending.pop_back();
142  for (ROEdgeVector::const_iterator it = e->getPredecessors().begin(); it != e->getPredecessors().end(); it++) {
143  ROEdge* e2 = *it;
144  if (e2->getNumSuccessors() == 1 && seen.count(e2) == 0) {
145  if (net->hasDetector(e2)) {
146  inFlows[*i] += detectors.getAggFlowFor(e2, 0, 0, flows);
147  } else {
148  pending.push_back(e2);
149  }
150  seen.insert(e2);
151  }
152  }
153  }
154  }
155  }
156  // compute the probabilities to use a certain direction
157  int index = 0;
158  for (SUMOTime time = startTime; time < endTime; time += stepOffset, ++index) {
159  mySplitProbabilities.push_back(std::map<RODFEdge*, SUMOReal>());
160  SUMOReal overallProb = 0;
161  // retrieve the probabilities
162  for (std::vector<RODFEdge*>::const_iterator i = nextDetEdges.begin(); i != nextDetEdges.end(); ++i) {
163  SUMOReal flow = detectors.getAggFlowFor(*i, time, 60, flows) - inFlows[*i];
164  overallProb += flow;
165  mySplitProbabilities[index][*i] = flow;
166  }
167  // norm probabilities
168  if (overallProb > 0) {
169  for (std::vector<RODFEdge*>::const_iterator i = nextDetEdges.begin(); i != nextDetEdges.end(); ++i) {
170  mySplitProbabilities[index][*i] = mySplitProbabilities[index][*i] / overallProb;
171  }
172  }
173  }
174 }
175 
176 
177 void
179  SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset,
180  const RODFNet& net,
181  std::map<SUMOTime, RandomDistributor<int>* >& into) const {
182  if (myRoutes == 0) {
184  WRITE_ERROR("Missing routes for detector '" + myID + "'.");
185  }
186  return;
187  }
188  std::vector<RODFRouteDesc>& descs = myRoutes->get();
189  // iterate through time (in output interval steps)
190  for (SUMOTime time = startTime; time < endTime; time += stepOffset) {
191  into[time] = new RandomDistributor<int>();
192  std::map<ROEdge*, SUMOReal> flowMap;
193  // iterate through the routes
194  int index = 0;
195  for (std::vector<RODFRouteDesc>::iterator ri = descs.begin(); ri != descs.end(); ++ri, index++) {
196  SUMOReal prob = 1.;
197  for (ROEdgeVector::iterator j = (*ri).edges2Pass.begin(); j != (*ri).edges2Pass.end() && prob > 0;) {
198  if (!net.hasDetector(*j)) {
199  ++j;
200  continue;
201  }
202  const RODFDetector& det = detectors.getAnyDetectorForEdge(static_cast<RODFEdge*>(*j));
203  const std::vector<std::map<RODFEdge*, SUMOReal> >& probs = det.getSplitProbabilities();
204  if (probs.size() == 0) {
205  prob = 0;
206  ++j;
207  continue;
208  }
209  const std::map<RODFEdge*, SUMOReal>& tprobs = probs[(time - startTime) / stepOffset];
210  RODFEdge* splitEdge = 0;
211  for (std::map<RODFEdge*, SUMOReal>::const_iterator k = tprobs.begin(); k != tprobs.end(); ++k) {
212  if (find(j, (*ri).edges2Pass.end(), (*k).first) != (*ri).edges2Pass.end()) {
213  prob *= (*k).second;
214  splitEdge = (*k).first;
215  break;
216  }
217  }
218  if (splitEdge != 0) {
219  j = find(j, (*ri).edges2Pass.end(), splitEdge);
220  } else {
221  ++j;
222  }
223  }
224  into[time]->add(prob, index);
225  (*ri).overallProb = prob;
226  }
227  }
228 }
229 
230 
231 const std::vector<RODFRouteDesc>&
233  return myRoutes->get();
234 }
235 
236 
237 void
239  myPriorDetectors.insert(det);
240 }
241 
242 
243 void
245  myFollowingDetectors.insert(det);
246 }
247 
248 
249 const std::set<const RODFDetector*>&
251  return myPriorDetectors;
252 }
253 
254 
255 const std::set<const RODFDetector*>&
257  return myFollowingDetectors;
258 }
259 
260 
261 
262 void
264  delete myRoutes;
265  myRoutes = routes;
266 }
267 
268 
269 void
271  if (myRoutes == 0) {
272  myRoutes = new RODFRouteCont();
273  }
274  myRoutes->addRouteDesc(nrd);
275 }
276 
277 
278 bool
280  return myRoutes != 0 && myRoutes->get().size() != 0;
281 }
282 
283 
284 bool
285 RODFDetector::writeEmitterDefinition(const std::string& file,
286  const std::map<SUMOTime, RandomDistributor<int>* >& dists,
287  const RODFDetectorFlows& flows,
288  SUMOTime startTime, SUMOTime endTime,
289  SUMOTime stepOffset,
290  bool includeUnusedRoutes,
291  SUMOReal scale,
292  bool insertionsOnly,
293  SUMOReal defaultSpeed) const {
296  if (getType() != SOURCE_DETECTOR) {
297  out.writeXMLHeader("calibrator");
298  }
299  // routes
300  if (myRoutes != 0 && myRoutes->get().size() != 0) {
301  const std::vector<RODFRouteDesc>& routes = myRoutes->get();
303  bool isEmptyDist = true;
304  for (std::vector<RODFRouteDesc>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
305  if ((*i).overallProb > 0) {
306  isEmptyDist = false;
307  }
308  }
309  for (std::vector<RODFRouteDesc>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
310  if ((*i).overallProb > 0 || includeUnusedRoutes) {
311  out.openTag(SUMO_TAG_ROUTE).writeAttr(SUMO_ATTR_REFID, (*i).routename).writeAttr(SUMO_ATTR_PROB, (*i).overallProb).closeTag();
312  }
313  if (isEmptyDist) {
315  }
316  }
317  out.closeTag(); // routeDistribution
318  } else {
319  WRITE_ERROR("Detector '" + getID() + "' has no routes!?");
320  return false;
321  }
322  // insertions
323  if (insertionsOnly || flows.knows(myID)) {
324  // get the flows for this detector
325  const std::vector<FlowDef>& mflows = flows.getFlowDefs(myID);
326  // go through the simulation seconds
327  int index = 0;
328  for (SUMOTime time = startTime; time < endTime; time += stepOffset, index++) {
329  // get own (departure flow)
330  assert(index < (int)mflows.size());
331  const FlowDef& srcFD = mflows[index]; // !!! check stepOffset
332  // get flows at end
333  RandomDistributor<int>* destDist = dists.find(time) != dists.end() ? dists.find(time)->second : 0;
334  // go through the cars
335  int carNo = (int)((srcFD.qPKW + srcFD.qLKW) * scale);
336  for (int car = 0; car < carNo; ++car) {
337  // get the vehicle parameter
338  SUMOReal v = -1;
339  std::string vtype;
340  int destIndex = destDist != 0 && destDist->getOverallProb() > 0 ? (int) destDist->get() : -1;
341  if (srcFD.isLKW >= 1) {
342  srcFD.isLKW = srcFD.isLKW - (SUMOReal) 1.;
343  v = srcFD.vLKW;
344  vtype = "LKW";
345  } else {
346  v = srcFD.vPKW;
347  vtype = "PKW";
348  }
349  // compute insertion speed
350  if (v <= 0 || v > 250) {
351  v = defaultSpeed;
352  } else {
353  v = (SUMOReal)(v / 3.6);
354  }
355  // compute the departure time
356  SUMOTime ctime = (SUMOTime)(time + ((SUMOReal) stepOffset * (SUMOReal) car / (SUMOReal) carNo));
357 
358  // write
360  if (getType() == SOURCE_DETECTOR) {
361  out.writeAttr(SUMO_ATTR_ID, "emitter_" + myID + "_" + toString(ctime));
362  } else {
363  out.writeAttr(SUMO_ATTR_ID, "calibrator_" + myID + "_" + toString(ctime));
364  }
365  if (oc.getBool("vtype")) {
366  out.writeAttr(SUMO_ATTR_TYPE, vtype);
367  }
369  if (oc.isSet("departlane")) {
370  out.writeNonEmptyAttr(SUMO_ATTR_DEPARTLANE, oc.getString("departlane"));
371  } else {
372  out.writeAttr(SUMO_ATTR_DEPARTLANE, TplConvert::_2int(myLaneID.substr(myLaneID.rfind("_") + 1).c_str()));
373  }
374  if (oc.isSet("departpos")) {
375  std::string posDesc = oc.getString("departpos");
376  if (posDesc.substr(0, 8) == "detector") {
377  SUMOReal position = myPosition;
378  if (posDesc.length() > 8) {
379  if (posDesc[8] == '+') {
380  position += TplConvert::_2SUMOReal(posDesc.substr(9).c_str());
381  } else if (posDesc[8] == '-') {
382  position -= TplConvert::_2SUMOReal(posDesc.substr(9).c_str());
383  } else {
384  throw NumberFormatException();
385  }
386  }
387  out.writeAttr(SUMO_ATTR_DEPARTPOS, position);
388  } else {
390  }
391  } else {
393  }
394  if (oc.isSet("departspeed")) {
395  out.writeNonEmptyAttr(SUMO_ATTR_DEPARTSPEED, oc.getString("departspeed"));
396  } else {
398  }
399  if (oc.isSet("arrivallane")) {
400  out.writeNonEmptyAttr(SUMO_ATTR_ARRIVALLANE, oc.getString("arrivallane"));
401  }
402  if (oc.isSet("arrivalpos")) {
403  out.writeNonEmptyAttr(SUMO_ATTR_ARRIVALPOS, oc.getString("arrivalpos"));
404  }
405  if (oc.isSet("arrivalspeed")) {
406  out.writeNonEmptyAttr(SUMO_ATTR_ARRIVALSPEED, oc.getString("arrivalspeed"));
407  }
408  if (destIndex >= 0) {
409  out.writeAttr(SUMO_ATTR_ROUTE, myRoutes->get()[destIndex].routename);
410  } else {
412  }
413  out.closeTag();
414  srcFD.isLKW += srcFD.fLKW;
415  }
416  }
417  }
418  if (getType() != SOURCE_DETECTOR) {
419  out.close();
420  }
421  return true;
422 }
423 
424 
425 bool
426 RODFDetector::writeRoutes(std::vector<std::string>& saved,
427  OutputDevice& out) {
428  if (myRoutes != 0) {
429  return myRoutes->save(saved, "", out);
430  }
431  return false;
432 }
433 
434 
435 void
437  const RODFDetectorFlows& flows,
438  SUMOTime startTime, SUMOTime endTime,
439  SUMOTime stepOffset, SUMOReal defaultSpeed) {
441  out.writeXMLHeader("vss");
442  const std::vector<FlowDef>& mflows = flows.getFlowDefs(myID);
443  int index = 0;
444  for (SUMOTime t = startTime; t < endTime; t += stepOffset, index++) {
445  assert(index < (int)mflows.size());
446  const FlowDef& srcFD = mflows[index];
447  SUMOReal speed = MAX2(srcFD.vLKW, srcFD.vPKW);
448  if (speed <= 0 || speed > 250) {
449  speed = defaultSpeed;
450  } else {
451  speed = (SUMOReal)(speed / 3.6);
452  }
454  }
455  out.close();
456 }
457 
458 
459 
460 
461 
462 
463 
464 
465 
466 
468 
469 
471  for (std::vector<RODFDetector*>::iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
472  delete *i;
473  }
474 }
475 
476 
477 bool
479  if (myDetectorMap.find(dfd->getID()) != myDetectorMap.end()) {
480  return false;
481  }
482  myDetectorMap[dfd->getID()] = dfd;
483  myDetectors.push_back(dfd);
484  std::string edgeid = dfd->getLaneID().substr(0, dfd->getLaneID().rfind('_'));
485  if (myDetectorEdgeMap.find(edgeid) == myDetectorEdgeMap.end()) {
486  myDetectorEdgeMap[edgeid] = std::vector<RODFDetector*>();
487  }
488  myDetectorEdgeMap[edgeid].push_back(dfd);
489  return true; // !!!
490 }
491 
492 
493 bool
495  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
496  if ((*i)->getType() == TYPE_NOT_DEFINED) {
497  return false;
498  }
499  }
500  return true;
501 }
502 
503 
504 bool
506  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
507  if ((*i)->hasRoutes()) {
508  return true;
509  }
510  }
511  return false;
512 }
513 
514 
515 const std::vector< RODFDetector*>&
517  return myDetectors;
518 }
519 
520 
521 void
522 RODFDetectorCon::save(const std::string& file) const {
524  out.writeXMLHeader("detectors");
525  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
526  out.openTag(SUMO_TAG_DETECTOR_DEFINITION).writeAttr(SUMO_ATTR_ID, StringUtils::escapeXML((*i)->getID())).writeAttr(SUMO_ATTR_LANE, (*i)->getLaneID()).writeAttr(SUMO_ATTR_POSITION, (*i)->getPos());
527  switch ((*i)->getType()) {
528  case BETWEEN_DETECTOR:
529  out.writeAttr(SUMO_ATTR_TYPE, "between");
530  break;
531  case SOURCE_DETECTOR:
532  out.writeAttr(SUMO_ATTR_TYPE, "source");
533  break;
534  case SINK_DETECTOR:
535  out.writeAttr(SUMO_ATTR_TYPE, "sink");
536  break;
537  case DISCARDED_DETECTOR:
538  out.writeAttr(SUMO_ATTR_TYPE, "discarded");
539  break;
540  default:
541  throw 1;
542  }
543  out.closeTag();
544  }
545  out.close();
546 }
547 
548 
549 void
550 RODFDetectorCon::saveAsPOIs(const std::string& file) const {
552  out.writeXMLHeader("pois");
553  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
555  switch ((*i)->getType()) {
556  case BETWEEN_DETECTOR:
557  out.writeAttr(SUMO_ATTR_TYPE, "between_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor::BLUE);
558  break;
559  case SOURCE_DETECTOR:
560  out.writeAttr(SUMO_ATTR_TYPE, "source_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor::GREEN);
561  break;
562  case SINK_DETECTOR:
563  out.writeAttr(SUMO_ATTR_TYPE, "sink_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor::RED);
564  break;
565  case DISCARDED_DETECTOR:
566  out.writeAttr(SUMO_ATTR_TYPE, "discarded_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor(51, 51, 51, 255));
567  break;
568  default:
569  throw 1;
570  }
571  out.writeAttr(SUMO_ATTR_LANE, (*i)->getLaneID()).writeAttr(SUMO_ATTR_POSITION, (*i)->getPos()).closeTag();
572  }
573  out.close();
574 }
575 
576 
577 void
578 RODFDetectorCon::saveRoutes(const std::string& file) const {
580  out.writeXMLHeader("routes");
581  std::vector<std::string> saved;
582  // write for source detectors
583  bool lastWasSaved = true;
584  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
585  if ((*i)->getType() != SOURCE_DETECTOR) {
586  // do not build routes for other than sources
587  continue;
588  }
589  if (lastWasSaved) {
590  out << "\n";
591  }
592  lastWasSaved = (*i)->writeRoutes(saved, out);
593  }
594  out << "\n";
595  out.close();
596 }
597 
598 
599 const RODFDetector&
600 RODFDetectorCon::getDetector(const std::string& id) const {
601  return *(myDetectorMap.find(id)->second);
602 }
603 
604 
606 RODFDetectorCon::getModifiableDetector(const std::string& id) const {
607  return *(myDetectorMap.find(id)->second);
608 }
609 
610 
611 bool
612 RODFDetectorCon::knows(const std::string& id) const {
613  return myDetectorMap.find(id) != myDetectorMap.end();
614 }
615 
616 
617 void
618 RODFDetectorCon::writeEmitters(const std::string& file,
619  const RODFDetectorFlows& flows,
620  SUMOTime startTime, SUMOTime endTime,
621  SUMOTime stepOffset, const RODFNet& net,
622  bool writeCalibrators,
623  bool includeUnusedRoutes,
624  SUMOReal scale,
625  bool insertionsOnly) {
626  // compute turn probabilities at detector
627  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
628  (*i)->computeSplitProbabilities(&net, *this, flows, startTime, endTime, stepOffset);
629  }
630  //
632  out.writeXMLHeader("additional", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.dlr.de/xsd/additional_file.xsd\"");
633  // write vType(s)
634  const bool separateVTypeOutput = OptionsCont::getOptions().getString("vtype-output") != "";
635  OutputDevice& vTypeOut = separateVTypeOutput ? OutputDevice::getDevice(OptionsCont::getOptions().getString("vtype-output")) : out;
636  if (separateVTypeOutput) {
637  vTypeOut.writeXMLHeader("additional", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.dlr.de/xsd/additional_file.xsd\"");
638  }
639  const bool forceDev = !OptionsCont::getOptions().isDefault("speeddev");
640  const SUMOReal speedDev = OptionsCont::getOptions().getFloat("speeddev");
641  if (OptionsCont::getOptions().getBool("vtype")) {
642  // write separate types
644  setSpeedFactorAndDev(pkwType, net.getMaxSpeedFactorPKW(), net.getAvgSpeedFactorPKW(), speedDev, forceDev);
646  pkwType.write(vTypeOut);
648  setSpeedFactorAndDev(lkwType, net.getMaxSpeedFactorLKW(), net.getAvgSpeedFactorLKW(), speedDev, forceDev);
650  lkwType.write(vTypeOut);
651  } else {
652  // patch default type
654  setSpeedFactorAndDev(type, MAX2(net.getMaxSpeedFactorPKW(), net.getMaxSpeedFactorLKW()), net.getAvgSpeedFactorPKW(), speedDev, forceDev);
655  if (type.setParameter != 0) {
656  type.write(vTypeOut);
657  }
658  }
659 
660 
661  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
662  RODFDetector* det = *i;
663  // get file name for values (emitter/calibrator definition)
664  std::string escapedID = StringUtils::escapeXML(det->getID());
665  std::string defFileName;
666  if (det->getType() == SOURCE_DETECTOR) {
667  defFileName = file;
668  } else if (writeCalibrators && det->getType() == BETWEEN_DETECTOR) {
669  defFileName = FileHelpers::getFilePath(file) + "calibrator_" + escapedID + ".def.xml";
670  } else {
671  defFileName = FileHelpers::getFilePath(file) + "other_" + escapedID + ".def.xml";
672  continue;
673  }
674  // try to write the definition
675  SUMOReal defaultSpeed = net.getEdge(det->getEdgeID())->getSpeed();
676  // ... compute routes' distribution over time
677  std::map<SUMOTime, RandomDistributor<int>* > dists;
678  if (!insertionsOnly && flows.knows(det->getID())) {
679  det->buildDestinationDistribution(*this, startTime, endTime, stepOffset, net, dists);
680  }
681  // ... write the definition
682  if (!det->writeEmitterDefinition(defFileName, dists, flows, startTime, endTime, stepOffset, includeUnusedRoutes, scale, insertionsOnly, defaultSpeed)) {
683  // skip if something failed... (!!!)
684  continue;
685  }
686  // ... clear temporary values
687  clearDists(dists);
688  // write the declaration into the file
689  if (writeCalibrators && det->getType() == BETWEEN_DETECTOR) {
690  out.openTag(SUMO_TAG_CALIBRATOR).writeAttr(SUMO_ATTR_ID, "calibrator_" + escapedID).writeAttr(SUMO_ATTR_POSITION, det->getPos());
691  out.writeAttr(SUMO_ATTR_LANE, det->getLaneID()).writeAttr(SUMO_ATTR_FRIENDLY_POS, true).writeAttr(SUMO_ATTR_FILE, defFileName).closeTag();
692  }
693  }
694  out.close();
695  if (separateVTypeOutput) {
696  vTypeOut.close();
697  }
698 }
699 
700 void
701 RODFDetectorCon::setSpeedFactorAndDev(SUMOVTypeParameter& type, SUMOReal maxFactor, SUMOReal avgFactor, SUMOReal dev, bool forceDev) {
702  if (avgFactor > 1) {
703  // systematically low speeds can easily be caused by traffic
704  // conditions. Whereas elevated speeds probably reflect speeding
705  type.speedFactor = avgFactor;
707  }
708  if (forceDev || (maxFactor > 1 && maxFactor > type.speedFactor + NUMERICAL_EPS)) {
709  // setting a non-zero speed deviation causes the simulation to recompute
710  // individual speedFactors to match departSpeed (MSEdge::insertVehicle())
711  type.speedDev = dev;
713  }
714 }
715 
716 
717 void
718 RODFDetectorCon::writeEmitterPOIs(const std::string& file,
719  const RODFDetectorFlows& flows) {
721  out.writeXMLHeader("additional", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.dlr.de/xsd/additional_file.xsd\"");
722  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
723  RODFDetector* det = *i;
724  SUMOReal flow = flows.getFlowSumSecure(det->getID());
725  const unsigned char col = static_cast<unsigned char>(128 * flow / flows.getMaxDetectorFlow() + 128);
726  out.openTag(SUMO_TAG_POI).writeAttr(SUMO_ATTR_ID, StringUtils::escapeXML((*i)->getID()) + ":" + toString(flow));
727  switch ((*i)->getType()) {
728  case BETWEEN_DETECTOR:
729  out.writeAttr(SUMO_ATTR_TYPE, "between_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor(0, 0, col, 255));
730  break;
731  case SOURCE_DETECTOR:
732  out.writeAttr(SUMO_ATTR_TYPE, "source_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor(0, col, 0, 255));
733  break;
734  case SINK_DETECTOR:
735  out.writeAttr(SUMO_ATTR_TYPE, "sink_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor(col, 0, 0, 255));
736  break;
737  case DISCARDED_DETECTOR:
738  out.writeAttr(SUMO_ATTR_TYPE, "discarded_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor(51, 51, 51, 255));
739  break;
740  default:
741  throw 1;
742  }
743  out.writeAttr(SUMO_ATTR_LANE, (*i)->getLaneID()).writeAttr(SUMO_ATTR_POSITION, (*i)->getPos()).closeTag();
744  }
745  out.close();
746 }
747 
748 
749 int
751  const RODFDetectorFlows&) const {
752  UNUSED_PARAMETER(period);
753  UNUSED_PARAMETER(time);
754  if (edge == 0) {
755  return 0;
756  }
757 // SUMOReal stepOffset = 60; // !!!
758 // SUMOReal startTime = 0; // !!!
759 // cout << edge->getID() << endl;
760  assert(myDetectorEdgeMap.find(edge->getID()) != myDetectorEdgeMap.end());
761  const std::vector<FlowDef>& flows = static_cast<const RODFEdge*>(edge)->getFlows();
762  SUMOReal agg = 0;
763  for (std::vector<FlowDef>::const_iterator i = flows.begin(); i != flows.end(); ++i) {
764  const FlowDef& srcFD = *i;
765  if (srcFD.qLKW >= 0) {
766  agg += srcFD.qLKW;
767  }
768  if (srcFD.qPKW >= 0) {
769  agg += srcFD.qPKW;
770  }
771  }
772  return (int) agg;
773  /* !!! make this time variable
774  if (flows.size()!=0) {
775  SUMOReal agg = 0;
776  int beginIndex = (int)((time/stepOffset) - startTime); // !!! falsch!!!
777  for (SUMOTime t=0; t<period&&beginIndex<flows.size(); t+=(SUMOTime) stepOffset) {
778  const FlowDef &srcFD = flows[beginIndex++];
779  if (srcFD.qLKW>=0) {
780  agg += srcFD.qLKW;
781  }
782  if (srcFD.qPKW>=0) {
783  agg += srcFD.qPKW;
784  }
785  }
786  return (int) agg;
787  }
788  */
789 // return -1;
790 }
791 
792 
793 void
795  const std::string& file,
796  const RODFDetectorFlows& flows,
797  SUMOTime startTime, SUMOTime endTime,
798  SUMOTime stepOffset) {
800  out.writeXMLHeader("additional", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.dlr.de/xsd/additional_file.xsd\"");
801  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
802  RODFDetector* det = *i;
803  // write the declaration into the file
804  if (det->getType() == SINK_DETECTOR && flows.knows(det->getID())) {
805  std::string filename = FileHelpers::getFilePath(file) + "vss_" + det->getID() + ".def.xml";
807  SUMOReal defaultSpeed = net != 0 ? net->getEdge(det->getEdgeID())->getSpeed() : (SUMOReal) 200.;
808  det->writeSingleSpeedTrigger(filename, flows, startTime, endTime, stepOffset, defaultSpeed);
809  }
810  }
811  out.close();
812 }
813 
814 
815 void
818  out.writeXMLHeader("additional", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.dlr.de/xsd/additional_file.xsd\"");
819  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
820  RODFDetector* det = *i;
821  // write the declaration into the file
822  if (det->getType() == SINK_DETECTOR) {
824  out.writeAttr(SUMO_ATTR_POSITION, SUMOReal(0)).writeAttr(SUMO_ATTR_FILE, "endrerouter_" + det->getID() + ".def.xml").closeTag();
825  }
826  }
827  out.close();
828 }
829 
830 
831 void
833  bool includeSources,
834  bool singleFile, bool friendly) {
836  out.writeXMLHeader("additional");
837  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
838  RODFDetector* det = *i;
839  // write the declaration into the file
840  if (det->getType() != SOURCE_DETECTOR || includeSources) {
841  SUMOReal pos = det->getPos();
842  if (det->getType() == SOURCE_DETECTOR) {
843  pos += 1;
844  }
847  if (friendly) {
849  }
850  if (!singleFile) {
851  out.writeAttr(SUMO_ATTR_FILE, "validation_det_" + StringUtils::escapeXML(det->getID()) + ".xml");
852  } else {
853  out.writeAttr(SUMO_ATTR_FILE, "validation_dets.xml");
854  }
855  out.closeTag();
856  }
857  }
858  out.close();
859 }
860 
861 
862 void
863 RODFDetectorCon::removeDetector(const std::string& id) {
864  //
865  std::map<std::string, RODFDetector*>::iterator ri1 = myDetectorMap.find(id);
866  RODFDetector* oldDet = (*ri1).second;
867  myDetectorMap.erase(ri1);
868  //
869  std::vector<RODFDetector*>::iterator ri2 =
870  find(myDetectors.begin(), myDetectors.end(), oldDet);
871  myDetectors.erase(ri2);
872  //
873  bool found = false;
874  for (std::map<std::string, std::vector<RODFDetector*> >::iterator rr3 = myDetectorEdgeMap.begin(); !found && rr3 != myDetectorEdgeMap.end(); ++rr3) {
875  std::vector<RODFDetector*>& dets = (*rr3).second;
876  for (std::vector<RODFDetector*>::iterator ri3 = dets.begin(); !found && ri3 != dets.end();) {
877  if (*ri3 == oldDet) {
878  found = true;
879  ri3 = dets.erase(ri3);
880  } else {
881  ++ri3;
882  }
883  }
884  }
885  delete oldDet;
886 }
887 
888 
889 void
891  // routes must be built (we have ensured this in main)
892  // detector followers/prior must be build (we have ensured this in main)
893  //
894  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
895  RODFDetector* det = *i;
896  const std::set<const RODFDetector*>& prior = det->getPriorDetectors();
897  const std::set<const RODFDetector*>& follower = det->getFollowerDetectors();
898  int noFollowerWithRoutes = 0;
899  int noPriorWithRoutes = 0;
900  // count occurences of detectors with/without routes
901  std::set<const RODFDetector*>::const_iterator j;
902  for (j = prior.begin(); j != prior.end(); ++j) {
903  if (flows.knows((*j)->getID())) {
904  ++noPriorWithRoutes;
905  }
906  }
907  for (j = follower.begin(); j != follower.end(); ++j) {
908  if (flows.knows((*j)->getID())) {
909  ++noFollowerWithRoutes;
910  }
911  }
912 
913  // do not process detectors which have no routes
914  if (!flows.knows(det->getID())) {
915  continue;
916  }
917 
918  // plain case: all of the prior detectors have routes
919  if (noPriorWithRoutes == (int)prior.size()) {
920  // the number of vehicles is the sum of all vehicles on prior
921  continue;
922  }
923 
924  // plain case: all of the follower detectors have routes
925  if (noFollowerWithRoutes == (int)follower.size()) {
926  // the number of vehicles is the sum of all vehicles on follower
927  continue;
928  }
929 
930  }
931 }
932 
933 
934 const RODFDetector&
936  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
937  if ((*i)->getEdgeID() == edge->getID()) {
938  return **i;
939  }
940  }
941  throw 1;
942 }
943 
944 
945 void
947  for (std::map<SUMOTime, RandomDistributor<int>* >::iterator i = dists.begin(); i != dists.end(); ++i) {
948  delete(*i).second;
949  }
950 }
951 
952 
953 void
954 RODFDetectorCon::mesoJoin(const std::string& nid,
955  const std::vector<std::string>& oldids) {
956  // build the new detector
957  const RODFDetector& first = getDetector(*(oldids.begin()));
958  RODFDetector* newDet = new RODFDetector(nid, first);
959  addDetector(newDet);
960  // delete previous
961  for (std::vector<std::string>::const_iterator i = oldids.begin(); i != oldids.end(); ++i) {
962  removeDetector(*i);
963  }
964 }
965 
966 
967 /****************************************************************************/
RODFDetector & getModifiableDetector(const std::string &id) const
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:257
static const RGBColor BLUE
Definition: RGBColor.h:191
void close()
Closes the device and removes it from the dictionary.
bool writeEmitterDefinition(const std::string &file, const std::map< SUMOTime, RandomDistributor< int > * > &dists, const RODFDetectorFlows &flows, SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset, bool includeUnusedRoutes, SUMOReal scale, bool insertionsOnly, SUMOReal defaultSpeed) const
const ROEdgeVector & getPredecessors() const
Returns the edge at the given position from the list of incoming edges.
Definition: ROEdge.h:331
bool detectorsHaveRoutes() const
long long int SUMOTime
Definition: SUMOTime.h:43
void addRoute(RODFRouteDesc &nrd)
std::string getEdgeID() const
Returns the id of the edge this detector is placed on.
Definition: RODFDetector.h:134
void removeDetector(const std::string &id)
void saveRoutes(const std::string &file) const
int getNumSuccessors() const
Returns the number of edges this edge is connected to.
Definition: ROEdge.cpp:219
RODFDetectorType
Numerical representation of different detector types.
Definition: RODFDetector.h:66
void save(const std::string &file) const
Represents a generic random distribution.
static SUMOReal _2SUMOReal(const E *const data)
converts a char-type array into the SUMOReal value described by it
Definition: TplConvert.h:290
SUMOReal getAvgSpeedFactorPKW() const
Definition: RODFNet.h:102
Structure representing possible vehicle parameter.
bool addDetector(RODFDetector *dfd)
void addRoutes(RODFRouteCont *routes)
A source detector.
Definition: RODFDetector.h:77
const RODFDetector & getDetector(const std::string &id) const
SUMOReal speedDev
The standard deviation for speed variations.
RODFDetector(const std::string &id, const std::string &laneID, SUMOReal pos, const RODFDetectorType type)
Constructor.
static std::string escapeXML(const std::string &orig)
Replaces the standard escapes by their XML entities.
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:59
ROEdgeVector edges2Pass
The edges the route is made of.
Definition: RODFRouteDesc.h:56
T MAX2(T a, T b)
Definition: StdDefs.h:75
int getAggFlowFor(const ROEdge *edge, SUMOTime time, SUMOTime period, const RODFDetectorFlows &flows) const
SUMOReal getMaxSpeedFactorPKW() const
Definition: RODFNet.h:94
void addPriorDetector(const RODFDetector *det)
bool hasDetector(ROEdge *edge) const
Definition: RODFNet.cpp:665
const std::vector< RODFDetector * > & getDetectors() const
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
SUMOReal getAvgSpeedFactorLKW() const
Definition: RODFNet.h:106
const std::string & getID() const
Returns the id.
Definition: Named.h:66
void writeSpeedTrigger(const RODFNet *const net, const std::string &file, const RODFDetectorFlows &flows, SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset)
RODFDetectorType getType() const
Returns the type of the detector.
Definition: RODFDetector.h:151
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
const std::vector< RODFRouteDesc > & getRouteVector() const
bool knows(const std::string &det_id) const
const std::string DEFAULT_VTYPE_ID
std::vector< RODFRouteDesc > & get()
Returns the container of stored routes.
A container for flows.
A container for RODFDetectors.
Definition: RODFDetector.h:228
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:39
const std::set< const RODFDetector * > & getFollowerDetectors() const
void computeSplitProbabilities(const RODFNet *net, const RODFDetectorCon &detectors, const RODFDetectorFlows &flows, SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset)
RODFRouteCont * myRoutes
Definition: RODFDetector.h:208
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:69
SUMOReal getMaxSpeedFactorLKW() const
Definition: RODFNet.h:98
vehicle is a large transport vehicle
bool writeXMLHeader(const std::string &rootElement, const std::string &attrs="", const std::string &comment="")
Writes an XML header with optional configuration.
SUMOReal getFlowSumSecure(const std::string &id) const
void writeEmitters(const std::string &file, const RODFDetectorFlows &flows, SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset, const RODFNet &net, bool writeCalibrators, bool includeUnusedRoutes, SUMOReal scale, bool insertionsOnly)
A not yet defined detector.
Definition: RODFDetector.h:68
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
bool hasRoutes() const
SUMOReal myPosition
Definition: RODFDetector.h:206
bool writeRoutes(std::vector< std::string > &saved, OutputDevice &out)
SUMOReal speedFactor
The factor by which the maximum speed may deviate from the allowed max speed on the street...
static const RGBColor GREEN
Definition: RGBColor.h:190
SUMOReal getMaxDetectorFlow() const
the edges of a route
An in-between detector.
Definition: RODFDetector.h:74
SUMOReal getPos() const
Returns the position at which the detector lies.
Definition: RODFDetector.h:142
OutputDevice & writeNonEmptyAttr(const SumoXMLAttr attr, const std::string &val)
writes a string attribute only if it is not the empty string and not the string "default" ...
Definition: OutputDevice.h:290
bool knows(const std::string &id) const
const std::set< const RODFDetector * > & getPriorDetectors() const
std::vector< ROEdge * > ROEdgeVector
Definition: RODFRouteDesc.h:43
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
A detector which had to be discarded (!!!)
Definition: RODFDetector.h:71
const RODFDetector & getAnyDetectorForEdge(const RODFEdge *const edge) const
A DFROUTER-network.
Definition: RODFNet.h:52
void writeValidationDetectors(const std::string &file, bool includeSources, bool singleFile, bool friendly)
~RODFDetector()
Destructor.
void setSpeedFactorAndDev(SUMOVTypeParameter &type, SUMOReal maxFactor, SUMOReal avgFactor, SUMOReal dev, bool forceDev)
void clearDists(std::map< SUMOTime, RandomDistributor< int > * > &dists) const
Clears the given distributions map, deleting the timed distributions.
std::string myLaneID
Definition: RODFDetector.h:205
void saveAsPOIs(const std::string &file) const
const int VTYPEPARS_SPEEDDEVIATION_SET
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:55
void writeSingleSpeedTrigger(const std::string &file, const RODFDetectorFlows &flows, SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset, SUMOReal defaultSpeed)
Definition of the traffic during a certain time containing the flows and speeds.
vehicle is a passenger car (a "normal" car)
A route within the DFROUTER.
Definition: RODFRouteDesc.h:54
A basic edge for routing applications.
Definition: ROEdge.h:77
std::vector< std::map< RODFEdge *, SUMOReal > > mySplitProbabilities
Definition: RODFDetector.h:210
Base class for objects which have an id.
Definition: Named.h:46
const int VTYPEPARS_SPEEDFACTOR_SET
T get(MTRand *which=0) const
Draw a sample of the distribution.
SUMOReal computeDistanceFactor(const RODFRouteDesc &rd) const
const std::string & getLaneID() const
Returns the id of the lane this detector is placed on.
Definition: RODFDetector.h:126
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:206
int setParameter
Information for the router which parameter were set.
bool detectorsHaveCompleteTypes() const
static int _2int(const E *const data)
converts a char-type array into the integer value described by it
Definition: TplConvert.h:149
std::string myID
The name of the object.
Definition: Named.h:136
void write(OutputDevice &dev) const
Writes the vtype.
static const RGBColor RED
Definition: RGBColor.h:189
const std::vector< std::map< RODFEdge *, SUMOReal > > & getSplitProbabilities() const
Definition: RODFDetector.h:195
RODFDetectorType myType
Definition: RODFDetector.h:207
std::map< std::string, RODFEdge * > myRoute2Edge
Definition: RODFDetector.h:211
static OutputDevice & getDevice(const std::string &name)
Returns the described OutputDevice.
void guessEmptyFlows(RODFDetectorFlows &flows)
Class representing a detector within the DFROUTER.
Definition: RODFDetector.h:89
A storage for options typed value containers)
Definition: OptionsCont.h:99
A container for DFROUTER-routes.
Definition: RODFRouteCont.h:63
SUMOReal qPKW
std::string routename
The name of the route.
Definition: RODFRouteDesc.h:58
void buildDestinationDistribution(const RODFDetectorCon &detectors, SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset, const RODFNet &net, std::map< SUMOTime, RandomDistributor< int > * > &into) const
const std::vector< FlowDef > & getFlowDefs(const std::string &id) const
void writeEmitterPOIs(const std::string &file, const RODFDetectorFlows &flows)
void setType(RODFDetectorType type)
std::set< const RODFDetector * > myPriorDetectors
Definition: RODFDetector.h:209
A variable speed sign.
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
bool closeTag()
Closes the most recently opened tag.
#define SUMOReal
Definition: config.h:213
#define NUMERICAL_EPS
Definition: config.h:160
static std::string getFilePath(const std::string &path)
Removes the file information from the given path.
Definition: FileHelpers.cpp:76
std::set< const RODFDetector * > myFollowingDetectors
Definition: RODFDetector.h:209
void writeEndRerouterDetectors(const std::string &file)
ROEdge * getEdge(const std::string &name) const
Retrieves an edge from the network.
Definition: RONet.h:165
void mesoJoin(const std::string &nid, const std::vector< std::string > &oldids)
void addRouteDesc(RODFRouteDesc &desc)
Adds a route to the container.
SUMOReal qLKW
const int VTYPEPARS_VEHICLECLASS_SET
A color information.
void addFollowingDetector(const RODFDetector *det)
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
bool save(std::vector< std::string > &saved, const std::string &prependix, OutputDevice &out)
Saves routes.
SUMOReal getFloat(const std::string &name) const
Returns the SUMOReal-value of the named option (only for Option_Float)
SUMOReal getOverallProb() const
Return the sum of the probabilites assigned to the members.