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  int carNo = (int)((srcFD.qPKW + srcFD.qLKW) * scale);
332  for (int car = 0; car < carNo; ++car) {
333  // get the vehicle parameter
334  double v = -1;
335  std::string vtype;
336  int destIndex = destDist != 0 && destDist->getOverallProb() > 0 ? (int) destDist->get() : -1;
337  if (srcFD.isLKW >= 1) {
338  srcFD.isLKW = srcFD.isLKW - (double) 1.;
339  v = srcFD.vLKW;
340  vtype = "LKW";
341  } else {
342  v = srcFD.vPKW;
343  vtype = "PKW";
344  }
345  // compute insertion speed
346  if (v <= 0 || v > 250) {
347  v = defaultSpeed;
348  } else {
349  v = (double)(v / 3.6);
350  }
351  // compute the departure time
352  SUMOTime ctime = (SUMOTime)(time + ((double) stepOffset * (double) car / (double) carNo));
353 
354  // write
356  if (getType() == SOURCE_DETECTOR) {
357  out.writeAttr(SUMO_ATTR_ID, "emitter_" + myID + "_" + toString(ctime));
358  } else {
359  out.writeAttr(SUMO_ATTR_ID, "calibrator_" + myID + "_" + toString(ctime));
360  }
361  if (oc.getBool("vtype")) {
362  out.writeAttr(SUMO_ATTR_TYPE, vtype);
363  }
365  if (oc.isSet("departlane")) {
366  out.writeNonEmptyAttr(SUMO_ATTR_DEPARTLANE, oc.getString("departlane"));
367  } else {
368  out.writeAttr(SUMO_ATTR_DEPARTLANE, TplConvert::_2int(myLaneID.substr(myLaneID.rfind("_") + 1).c_str()));
369  }
370  if (oc.isSet("departpos")) {
371  std::string posDesc = oc.getString("departpos");
372  if (posDesc.substr(0, 8) == "detector") {
373  double position = myPosition;
374  if (posDesc.length() > 8) {
375  if (posDesc[8] == '+') {
376  position += TplConvert::_2double(posDesc.substr(9).c_str());
377  } else if (posDesc[8] == '-') {
378  position -= TplConvert::_2double(posDesc.substr(9).c_str());
379  } else {
380  throw NumberFormatException();
381  }
382  }
383  out.writeAttr(SUMO_ATTR_DEPARTPOS, position);
384  } else {
386  }
387  } else {
389  }
390  if (oc.isSet("departspeed")) {
391  out.writeNonEmptyAttr(SUMO_ATTR_DEPARTSPEED, oc.getString("departspeed"));
392  } else {
394  }
395  if (oc.isSet("arrivallane")) {
396  out.writeNonEmptyAttr(SUMO_ATTR_ARRIVALLANE, oc.getString("arrivallane"));
397  }
398  if (oc.isSet("arrivalpos")) {
399  out.writeNonEmptyAttr(SUMO_ATTR_ARRIVALPOS, oc.getString("arrivalpos"));
400  }
401  if (oc.isSet("arrivalspeed")) {
402  out.writeNonEmptyAttr(SUMO_ATTR_ARRIVALSPEED, oc.getString("arrivalspeed"));
403  }
404  if (destIndex >= 0) {
405  out.writeAttr(SUMO_ATTR_ROUTE, myRoutes->get()[destIndex].routename);
406  } else {
408  }
409  out.closeTag();
410  srcFD.isLKW += srcFD.fLKW;
411  }
412  }
413  }
414  if (getType() != SOURCE_DETECTOR) {
415  out.close();
416  }
417  return true;
418 }
419 
420 
421 bool
422 RODFDetector::writeRoutes(std::vector<std::string>& saved,
423  OutputDevice& out) {
424  if (myRoutes != 0) {
425  return myRoutes->save(saved, "", out);
426  }
427  return false;
428 }
429 
430 
431 void
433  const RODFDetectorFlows& flows,
434  SUMOTime startTime, SUMOTime endTime,
435  SUMOTime stepOffset, double defaultSpeed) {
437  out.writeXMLHeader("additional", "additional_file.xsd");
438  const std::vector<FlowDef>& mflows = flows.getFlowDefs(myID);
439  int index = 0;
440  for (SUMOTime t = startTime; t < endTime; t += stepOffset, index++) {
441  assert(index < (int)mflows.size());
442  const FlowDef& srcFD = mflows[index];
443  double speed = MAX2(srcFD.vLKW, srcFD.vPKW);
444  if (speed <= 0 || speed > 250) {
445  speed = defaultSpeed;
446  } else {
447  speed = (double)(speed / 3.6);
448  }
450  }
451  out.close();
452 }
453 
454 
455 
456 
457 
458 
459 
460 
461 
462 
464 
465 
467  for (std::vector<RODFDetector*>::iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
468  delete *i;
469  }
470 }
471 
472 
473 bool
475  if (myDetectorMap.find(dfd->getID()) != myDetectorMap.end()) {
476  return false;
477  }
478  myDetectorMap[dfd->getID()] = dfd;
479  myDetectors.push_back(dfd);
480  std::string edgeid = dfd->getLaneID().substr(0, dfd->getLaneID().rfind('_'));
481  if (myDetectorEdgeMap.find(edgeid) == myDetectorEdgeMap.end()) {
482  myDetectorEdgeMap[edgeid] = std::vector<RODFDetector*>();
483  }
484  myDetectorEdgeMap[edgeid].push_back(dfd);
485  return true; // !!!
486 }
487 
488 
489 bool
491  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
492  if ((*i)->getType() == TYPE_NOT_DEFINED) {
493  return false;
494  }
495  }
496  return true;
497 }
498 
499 
500 bool
502  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
503  if ((*i)->hasRoutes()) {
504  return true;
505  }
506  }
507  return false;
508 }
509 
510 
511 const std::vector< RODFDetector*>&
513  return myDetectors;
514 }
515 
516 
517 void
518 RODFDetectorCon::save(const std::string& file) const {
520  out.writeXMLHeader("detectors", "detectors_file.xsd");
521  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
522  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());
523  switch ((*i)->getType()) {
524  case BETWEEN_DETECTOR:
525  out.writeAttr(SUMO_ATTR_TYPE, "between");
526  break;
527  case SOURCE_DETECTOR:
528  out.writeAttr(SUMO_ATTR_TYPE, "source");
529  break;
530  case SINK_DETECTOR:
531  out.writeAttr(SUMO_ATTR_TYPE, "sink");
532  break;
533  case DISCARDED_DETECTOR:
534  out.writeAttr(SUMO_ATTR_TYPE, "discarded");
535  break;
536  default:
537  throw 1;
538  }
539  out.closeTag();
540  }
541  out.close();
542 }
543 
544 
545 void
546 RODFDetectorCon::saveAsPOIs(const std::string& file) const {
548  out.writeXMLHeader("additional", "additional_file.xsd");
549  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
551  switch ((*i)->getType()) {
552  case BETWEEN_DETECTOR:
553  out.writeAttr(SUMO_ATTR_TYPE, "between_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor::BLUE);
554  break;
555  case SOURCE_DETECTOR:
556  out.writeAttr(SUMO_ATTR_TYPE, "source_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor::GREEN);
557  break;
558  case SINK_DETECTOR:
559  out.writeAttr(SUMO_ATTR_TYPE, "sink_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor::RED);
560  break;
561  case DISCARDED_DETECTOR:
562  out.writeAttr(SUMO_ATTR_TYPE, "discarded_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor(51, 51, 51, 255));
563  break;
564  default:
565  throw 1;
566  }
567  out.writeAttr(SUMO_ATTR_LANE, (*i)->getLaneID()).writeAttr(SUMO_ATTR_POSITION, (*i)->getPos()).closeTag();
568  }
569  out.close();
570 }
571 
572 
573 void
574 RODFDetectorCon::saveRoutes(const std::string& file) const {
576  out.writeXMLHeader("routes", "routes_file.xsd");
577  std::vector<std::string> saved;
578  // write for source detectors
579  bool lastWasSaved = true;
580  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
581  if ((*i)->getType() != SOURCE_DETECTOR) {
582  // do not build routes for other than sources
583  continue;
584  }
585  if (lastWasSaved) {
586  out << "\n";
587  }
588  lastWasSaved = (*i)->writeRoutes(saved, out);
589  }
590  out << "\n";
591  out.close();
592 }
593 
594 
595 const RODFDetector&
596 RODFDetectorCon::getDetector(const std::string& id) const {
597  return *(myDetectorMap.find(id)->second);
598 }
599 
600 
602 RODFDetectorCon::getModifiableDetector(const std::string& id) const {
603  return *(myDetectorMap.find(id)->second);
604 }
605 
606 
607 bool
608 RODFDetectorCon::knows(const std::string& id) const {
609  return myDetectorMap.find(id) != myDetectorMap.end();
610 }
611 
612 
613 void
614 RODFDetectorCon::writeEmitters(const std::string& file,
615  const RODFDetectorFlows& flows,
616  SUMOTime startTime, SUMOTime endTime,
617  SUMOTime stepOffset, const RODFNet& net,
618  bool writeCalibrators,
619  bool includeUnusedRoutes,
620  double scale,
621  bool insertionsOnly) {
622  // compute turn probabilities at detector
623  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
624  (*i)->computeSplitProbabilities(&net, *this, flows, startTime, endTime, stepOffset);
625  }
626  //
628  out.writeXMLHeader("additional", "additional_file.xsd");
629  // write vType(s)
630  const bool separateVTypeOutput = OptionsCont::getOptions().getString("vtype-output") != "";
631  OutputDevice& vTypeOut = separateVTypeOutput ? OutputDevice::getDevice(OptionsCont::getOptions().getString("vtype-output")) : out;
632  if (separateVTypeOutput) {
633  vTypeOut.writeXMLHeader("additional", "additional_file.xsd");
634  }
635  const bool forceDev = !OptionsCont::getOptions().isDefault("speeddev");
636  const double speedDev = OptionsCont::getOptions().getFloat("speeddev");
637  if (OptionsCont::getOptions().getBool("vtype")) {
638  // write separate types
640  setSpeedFactorAndDev(pkwType, net.getMaxSpeedFactorPKW(), net.getAvgSpeedFactorPKW(), speedDev, forceDev);
642  pkwType.write(vTypeOut);
644  setSpeedFactorAndDev(lkwType, net.getMaxSpeedFactorLKW(), net.getAvgSpeedFactorLKW(), speedDev, forceDev);
646  lkwType.write(vTypeOut);
647  } else {
648  // patch default type
650  setSpeedFactorAndDev(type, MAX2(net.getMaxSpeedFactorPKW(), net.getMaxSpeedFactorLKW()), net.getAvgSpeedFactorPKW(), speedDev, forceDev);
651  if (type.setParameter != 0) {
652  type.write(vTypeOut);
653  }
654  }
655 
656 
657  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
658  RODFDetector* det = *i;
659  // get file name for values (emitter/calibrator definition)
660  std::string escapedID = StringUtils::escapeXML(det->getID());
661  std::string defFileName;
662  if (det->getType() == SOURCE_DETECTOR) {
663  defFileName = file;
664  } else if (writeCalibrators && det->getType() == BETWEEN_DETECTOR) {
665  defFileName = FileHelpers::getFilePath(file) + "calibrator_" + escapedID + ".def.xml";
666  } else {
667  defFileName = FileHelpers::getFilePath(file) + "other_" + escapedID + ".def.xml";
668  continue;
669  }
670  // try to write the definition
671  double defaultSpeed = net.getEdge(det->getEdgeID())->getSpeedLimit();
672  // ... compute routes' distribution over time
673  std::map<SUMOTime, RandomDistributor<int>* > dists;
674  if (!insertionsOnly && flows.knows(det->getID())) {
675  det->buildDestinationDistribution(*this, startTime, endTime, stepOffset, net, dists);
676  }
677  // ... write the definition
678  if (!det->writeEmitterDefinition(defFileName, dists, flows, startTime, endTime, stepOffset, includeUnusedRoutes, scale, insertionsOnly, defaultSpeed)) {
679  // skip if something failed... (!!!)
680  continue;
681  }
682  // ... clear temporary values
683  clearDists(dists);
684  // write the declaration into the file
685  if (writeCalibrators && det->getType() == BETWEEN_DETECTOR) {
686  out.openTag(SUMO_TAG_CALIBRATOR).writeAttr(SUMO_ATTR_ID, "calibrator_" + escapedID).writeAttr(SUMO_ATTR_POSITION, det->getPos());
687  out.writeAttr(SUMO_ATTR_LANE, det->getLaneID()).writeAttr(SUMO_ATTR_FRIENDLY_POS, true).writeAttr(SUMO_ATTR_FILE, defFileName).closeTag();
688  }
689  }
690  out.close();
691  if (separateVTypeOutput) {
692  vTypeOut.close();
693  }
694 }
695 
696 void
697 RODFDetectorCon::setSpeedFactorAndDev(SUMOVTypeParameter& type, double maxFactor, double avgFactor, double dev, bool forceDev) {
698  if (avgFactor > 1) {
699  // systematically low speeds can easily be caused by traffic
700  // conditions. Whereas elevated speeds probably reflect speeding
701  type.speedFactor.getParameter()[0] = avgFactor;
703  }
704  if (forceDev || (maxFactor > 1 && maxFactor > type.speedFactor.getParameter()[0] + NUMERICAL_EPS)) {
705  // setting a non-zero speed deviation causes the simulation to recompute
706  // individual speedFactors to match departSpeed (MSEdge::insertVehicle())
707  type.speedFactor.getParameter()[1] = dev;
709  }
710 }
711 
712 
713 void
714 RODFDetectorCon::writeEmitterPOIs(const std::string& file,
715  const RODFDetectorFlows& flows) {
717  out.writeXMLHeader("additional", "additional_file.xsd");
718  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
719  RODFDetector* det = *i;
720  double flow = flows.getFlowSumSecure(det->getID());
721  const unsigned char col = static_cast<unsigned char>(128 * flow / flows.getMaxDetectorFlow() + 128);
722  out.openTag(SUMO_TAG_POI).writeAttr(SUMO_ATTR_ID, StringUtils::escapeXML((*i)->getID()) + ":" + toString(flow));
723  switch ((*i)->getType()) {
724  case BETWEEN_DETECTOR:
725  out.writeAttr(SUMO_ATTR_TYPE, "between_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor(0, 0, col, 255));
726  break;
727  case SOURCE_DETECTOR:
728  out.writeAttr(SUMO_ATTR_TYPE, "source_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor(0, col, 0, 255));
729  break;
730  case SINK_DETECTOR:
731  out.writeAttr(SUMO_ATTR_TYPE, "sink_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor(col, 0, 0, 255));
732  break;
733  case DISCARDED_DETECTOR:
734  out.writeAttr(SUMO_ATTR_TYPE, "discarded_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor(51, 51, 51, 255));
735  break;
736  default:
737  throw 1;
738  }
739  out.writeAttr(SUMO_ATTR_LANE, (*i)->getLaneID()).writeAttr(SUMO_ATTR_POSITION, (*i)->getPos()).closeTag();
740  }
741  out.close();
742 }
743 
744 
745 int
747  const RODFDetectorFlows&) const {
748  UNUSED_PARAMETER(period);
749  UNUSED_PARAMETER(time);
750  if (edge == 0) {
751  return 0;
752  }
753 // double stepOffset = 60; // !!!
754 // double startTime = 0; // !!!
755 // cout << edge->getID() << endl;
756  assert(myDetectorEdgeMap.find(edge->getID()) != myDetectorEdgeMap.end());
757  const std::vector<FlowDef>& flows = static_cast<const RODFEdge*>(edge)->getFlows();
758  double agg = 0;
759  for (std::vector<FlowDef>::const_iterator i = flows.begin(); i != flows.end(); ++i) {
760  const FlowDef& srcFD = *i;
761  if (srcFD.qLKW >= 0) {
762  agg += srcFD.qLKW;
763  }
764  if (srcFD.qPKW >= 0) {
765  agg += srcFD.qPKW;
766  }
767  }
768  return (int) agg;
769  /* !!! make this time variable
770  if (flows.size()!=0) {
771  double agg = 0;
772  int beginIndex = (int)((time/stepOffset) - startTime); // !!! falsch!!!
773  for (SUMOTime t=0; t<period&&beginIndex<flows.size(); t+=(SUMOTime) stepOffset) {
774  const FlowDef &srcFD = flows[beginIndex++];
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  }
784  */
785 // return -1;
786 }
787 
788 
789 void
791  const std::string& file,
792  const RODFDetectorFlows& flows,
793  SUMOTime startTime, SUMOTime endTime,
794  SUMOTime stepOffset) {
796  out.writeXMLHeader("additional", "additional_file.xsd");
797  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
798  RODFDetector* det = *i;
799  // write the declaration into the file
800  if (det->getType() == SINK_DETECTOR && flows.knows(det->getID())) {
801  std::string filename = FileHelpers::getFilePath(file) + "vss_" + det->getID() + ".def.xml";
803  double defaultSpeed = net != 0 ? net->getEdge(det->getEdgeID())->getSpeedLimit() : (double) 200.;
804  det->writeSingleSpeedTrigger(filename, flows, startTime, endTime, stepOffset, defaultSpeed);
805  }
806  }
807  out.close();
808 }
809 
810 
811 void
814  out.writeXMLHeader("additional", "additional_file.xsd");
815  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
816  RODFDetector* det = *i;
817  // write the declaration into the file
818  if (det->getType() == SINK_DETECTOR) {
820  out.writeAttr(SUMO_ATTR_POSITION, 0.).writeAttr(SUMO_ATTR_FILE, "endrerouter_" + det->getID() + ".def.xml").closeTag();
821  }
822  }
823  out.close();
824 }
825 
826 
827 void
829  bool includeSources,
830  bool singleFile, bool friendly) {
832  out.writeXMLHeader("additional", "additional_file.xsd");
833  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
834  RODFDetector* det = *i;
835  // write the declaration into the file
836  if (det->getType() != SOURCE_DETECTOR || includeSources) {
837  double pos = det->getPos();
838  if (det->getType() == SOURCE_DETECTOR) {
839  pos += 1;
840  }
843  if (friendly) {
845  }
846  if (!singleFile) {
847  out.writeAttr(SUMO_ATTR_FILE, "validation_det_" + StringUtils::escapeXML(det->getID()) + ".xml");
848  } else {
849  out.writeAttr(SUMO_ATTR_FILE, "validation_dets.xml");
850  }
851  out.closeTag();
852  }
853  }
854  out.close();
855 }
856 
857 
858 void
859 RODFDetectorCon::removeDetector(const std::string& id) {
860  //
861  std::map<std::string, RODFDetector*>::iterator ri1 = myDetectorMap.find(id);
862  RODFDetector* oldDet = (*ri1).second;
863  myDetectorMap.erase(ri1);
864  //
865  std::vector<RODFDetector*>::iterator ri2 =
866  find(myDetectors.begin(), myDetectors.end(), oldDet);
867  myDetectors.erase(ri2);
868  //
869  bool found = false;
870  for (std::map<std::string, std::vector<RODFDetector*> >::iterator rr3 = myDetectorEdgeMap.begin(); !found && rr3 != myDetectorEdgeMap.end(); ++rr3) {
871  std::vector<RODFDetector*>& dets = (*rr3).second;
872  for (std::vector<RODFDetector*>::iterator ri3 = dets.begin(); !found && ri3 != dets.end();) {
873  if (*ri3 == oldDet) {
874  found = true;
875  ri3 = dets.erase(ri3);
876  } else {
877  ++ri3;
878  }
879  }
880  }
881  delete oldDet;
882 }
883 
884 
885 void
887  // routes must be built (we have ensured this in main)
888  // detector followers/prior must be build (we have ensured this in main)
889  //
890  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
891  RODFDetector* det = *i;
892  const std::set<const RODFDetector*>& prior = det->getPriorDetectors();
893  const std::set<const RODFDetector*>& follower = det->getFollowerDetectors();
894  int noFollowerWithRoutes = 0;
895  int noPriorWithRoutes = 0;
896  // count occurences of detectors with/without routes
897  std::set<const RODFDetector*>::const_iterator j;
898  for (j = prior.begin(); j != prior.end(); ++j) {
899  if (flows.knows((*j)->getID())) {
900  ++noPriorWithRoutes;
901  }
902  }
903  for (j = follower.begin(); j != follower.end(); ++j) {
904  if (flows.knows((*j)->getID())) {
905  ++noFollowerWithRoutes;
906  }
907  }
908 
909  // do not process detectors which have no routes
910  if (!flows.knows(det->getID())) {
911  continue;
912  }
913 
914  // plain case: all of the prior detectors have routes
915  if (noPriorWithRoutes == (int)prior.size()) {
916  // the number of vehicles is the sum of all vehicles on prior
917  continue;
918  }
919 
920  // plain case: all of the follower detectors have routes
921  if (noFollowerWithRoutes == (int)follower.size()) {
922  // the number of vehicles is the sum of all vehicles on follower
923  continue;
924  }
925 
926  }
927 }
928 
929 
930 const RODFDetector&
932  for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
933  if ((*i)->getEdgeID() == edge->getID()) {
934  return **i;
935  }
936  }
937  throw 1;
938 }
939 
940 
941 void
943  for (std::map<SUMOTime, RandomDistributor<int>* >::iterator i = dists.begin(); i != dists.end(); ++i) {
944  delete(*i).second;
945  }
946 }
947 
948 
949 void
950 RODFDetectorCon::mesoJoin(const std::string& nid,
951  const std::vector<std::string>& oldids) {
952  // build the new detector
953  const RODFDetector& first = getDetector(*(oldids.begin()));
954  RODFDetector* newDet = new RODFDetector(nid, first);
955  addDetector(newDet);
956  // delete previous
957  for (std::vector<std::string>::const_iterator i = oldids.begin(); i != oldids.end(); ++i) {
958  removeDetector(*i);
959  }
960 }
961 
962 
963 /****************************************************************************/
double getFlowSumSecure(const std::string &id) const
RODFDetector & getModifiableDetector(const std::string &id) const
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:256
static const RGBColor BLUE
Definition: RGBColor.h:191
void close()
Closes the device and removes it from the dictionary.
const ROEdgeVector & getPredecessors() const
Returns the edge at the given position from the list of incoming edges.
Definition: ROEdge.h:341
bool detectorsHaveRoutes() const
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
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:215
RODFDetectorType
Numerical representation of different detector types.
Definition: RODFDetector.h:66
void save(const std::string &file) const
Structure representing possible vehicle parameter.
distribution of a route
bool addDetector(RODFDetector *dfd)
double getAvgSpeedFactorPKW() const
Definition: RODFNet.h:102
void addRoutes(RODFRouteCont *routes)
A source detector.
Definition: RODFDetector.h:77
const RODFDetector & getDetector(const std::string &id) const
std::vector< double > & getParameter()
Returns the parameters of this distribution.
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:60
ROEdgeVector edges2Pass
The edges the route is made of.
Definition: RODFRouteDesc.h:56
T MAX2(T a, T b)
Definition: StdDefs.h:70
double getMaxSpeedFactorPKW() const
Definition: RODFNet.h:94
int getAggFlowFor(const ROEdge *edge, SUMOTime time, SUMOTime period, const RODFDetectorFlows &flows) const
void addPriorDetector(const RODFDetector *det)
bool hasDetector(ROEdge *edge) const
Definition: RODFNet.cpp:661
begin/end of the description of a polygon
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)
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
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:38
const std::set< const RODFDetector * > & getFollowerDetectors() const
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
vehicle is a large transport vehicle
A not yet defined detector.
Definition: RODFDetector.h:68
double getMaxDetectorFlow() const
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
bool hasRoutes() const
bool writeRoutes(std::vector< std::string > &saved, OutputDevice &out)
double getMaxSpeedFactorLKW() const
Definition: RODFNet.h:98
static const RGBColor GREEN
Definition: RGBColor.h:190
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
const std::vector< std::map< RODFEdge *, double > > & getSplitProbabilities() const
Definition: RODFDetector.h:195
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:289
bool knows(const std::string &id) const
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.
const std::set< const RODFDetector * > & getPriorDetectors() const
std::vector< ROEdge * > ROEdgeVector
Definition: RODFRouteDesc.h:43
double computeDistanceFactor(const RODFRouteDesc &rd) const
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
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)
~RODFDetector()
Destructor.
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
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.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
double qPKW
vehicle is a passenger car (a "normal" car)
A route within the DFROUTER.
Definition: RODFRouteDesc.h:54
double getAvgSpeedFactorLKW() const
Definition: RODFNet.h:106
A basic edge for routing applications.
Definition: ROEdge.h:77
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)
T get(MTRand *which=0) const
Draw a sample of the distribution.
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.
void writeSingleSpeedTrigger(const std::string &file, const RODFDetectorFlows &flows, SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset, double defaultSpeed)
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.
trigger: the time of the step
static const RGBColor RED
Definition: RGBColor.h:189
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)
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:297
A container for DFROUTER-routes.
Definition: RODFRouteCont.h:63
double getOverallProb() const
Return the sum of the probabilites assigned to the members.
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)
description of a vehicle
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.
long long int SUMOTime
Definition: TraCIDefs.h:52
#define NUMERICAL_EPS
Definition: config.h:151
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)
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.
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...
double getPos() const
Returns the position at which the detector lies.
Definition: RODFDetector.h:142
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.
trigger: a step description