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