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