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