Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/dfrouter/RODFNet.cpp
169665 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2025 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 RODFNet.cpp
15
/// @author Daniel Krajzewicz
16
/// @author Eric Nicolay
17
/// @author Jakob Erdmann
18
/// @author Michael Behrisch
19
/// @date Thu, 16.03.2006
20
///
21
// A DFROUTER-network
22
/****************************************************************************/
23
#include <config.h>
24
25
#include <cassert>
26
#include <iostream>
27
#include <map>
28
#include <queue>
29
#include <vector>
30
#include <iterator>
31
#include "RODFNet.h"
32
#include "RODFDetector.h"
33
#include "RODFRouteDesc.h"
34
#include "RODFDetectorFlow.h"
35
#include "RODFEdge.h"
36
#include <cmath>
37
#include <utils/common/MsgHandler.h>
38
#include <utils/common/ToString.h>
39
#include <utils/common/UtilExceptions.h>
40
#include <utils/geom/GeomHelper.h>
41
42
43
// ===========================================================================
44
// method definitions
45
// ===========================================================================
46
RODFNet::RODFNet(bool amInHighwayMode) :
47
RONet(), myAmInHighwayMode(amInHighwayMode),
48
mySourceNumber(0), mySinkNumber(0), myInBetweenNumber(0), myInvalidNumber(0),
49
myMaxSpeedFactorPKW(1),
50
myMaxSpeedFactorLKW(1),
51
myAvgSpeedFactorPKW(1),
52
myAvgSpeedFactorLKW(1) {
53
myDisallowedEdges = OptionsCont::getOptions().getStringVector("disallowed-edges");
54
myAllowedVClass = getVehicleClassID(OptionsCont::getOptions().getString("vclass"));
55
myKeepTurnarounds = OptionsCont::getOptions().getBool("keep-turnarounds");
56
}
57
58
59
RODFNet::~RODFNet() {
60
}
61
62
63
bool
64
RODFNet::isAllowed(const ROEdge* const edge) const {
65
return (!edge->isInternal() && !edge->isWalkingArea() && !edge->isCrossing() &&
66
(edge->getPermissions() & myAllowedVClass) == myAllowedVClass &&
67
find(myDisallowedEdges.begin(), myDisallowedEdges.end(), edge->getID()) == myDisallowedEdges.end());
68
69
}
70
71
72
void
73
RODFNet::buildApproachList() {
74
for (const auto& rit : getEdgeMap()) {
75
ROEdge* const ce = rit.second;
76
if (!isAllowed(ce)) {
77
continue;
78
}
79
for (ROEdge* const help : ce->getSuccessors()) {
80
if (!isAllowed(help)) {
81
// blocked edges will not be used
82
continue;
83
}
84
if (!myKeepTurnarounds && help->getToJunction() == ce->getFromJunction()) {
85
// do not use turnarounds
86
continue;
87
}
88
// add the connection help->ce to myApproachingEdges
89
myApproachingEdges[help].push_back(ce);
90
// add the connection ce->help to myApproachingEdges
91
myApproachedEdges[ce].push_back(help);
92
}
93
}
94
}
95
96
97
void
98
RODFNet::buildDetectorEdgeDependencies(RODFDetectorCon& detcont) const {
99
myDetectorsOnEdges.clear();
100
myDetectorEdges.clear();
101
const std::vector<RODFDetector*>& dets = detcont.getDetectors();
102
for (std::vector<RODFDetector*>::const_iterator i = dets.begin(); i != dets.end(); ++i) {
103
ROEdge* e = getDetectorEdge(**i);
104
myDetectorsOnEdges[e].push_back((*i)->getID());
105
myDetectorEdges[(*i)->getID()] = e;
106
}
107
}
108
109
110
void
111
RODFNet::computeTypes(RODFDetectorCon& detcont,
112
bool sourcesStrict) const {
113
PROGRESS_BEGIN_MESSAGE(TL("Computing detector types"));
114
const std::vector< RODFDetector*>& dets = detcont.getDetectors();
115
// build needed information. first
116
buildDetectorEdgeDependencies(detcont);
117
// compute detector types then
118
for (std::vector< RODFDetector*>::const_iterator i = dets.begin(); i != dets.end(); ++i) {
119
if (isSource(**i, detcont, sourcesStrict)) {
120
(*i)->setType(SOURCE_DETECTOR);
121
mySourceNumber++;
122
}
123
if (isDestination(**i, detcont)) {
124
(*i)->setType(SINK_DETECTOR);
125
mySinkNumber++;
126
}
127
if ((*i)->getType() == TYPE_NOT_DEFINED) {
128
(*i)->setType(BETWEEN_DETECTOR);
129
myInBetweenNumber++;
130
}
131
}
132
// recheck sources
133
for (std::vector< RODFDetector*>::const_iterator i = dets.begin(); i != dets.end(); ++i) {
134
if ((*i)->getType() == SOURCE_DETECTOR && isFalseSource(**i, detcont)) {
135
(*i)->setType(DISCARDED_DETECTOR);
136
myInvalidNumber++;
137
mySourceNumber--;
138
}
139
}
140
// print results
141
PROGRESS_DONE_MESSAGE();
142
WRITE_MESSAGE(TL("Computed detector types:"));
143
WRITE_MESSAGEF(TL(" % source detectors"), toString(mySourceNumber));
144
WRITE_MESSAGEF(TL(" % sink detectors"), toString(mySinkNumber));
145
WRITE_MESSAGEF(TL(" % in-between detectors"), toString(myInBetweenNumber));
146
WRITE_MESSAGEF(TL(" % invalid detectors"), toString(myInvalidNumber));
147
}
148
149
150
bool
151
RODFNet::hasInBetweenDetectorsOnly(ROEdge* edge,
152
const RODFDetectorCon& detectors) const {
153
assert(myDetectorsOnEdges.find(edge) != myDetectorsOnEdges.end());
154
const std::vector<std::string>& detIDs = myDetectorsOnEdges.find(edge)->second;
155
std::vector<std::string>::const_iterator i;
156
for (i = detIDs.begin(); i != detIDs.end(); ++i) {
157
const RODFDetector& det = detectors.getDetector(*i);
158
if (det.getType() != BETWEEN_DETECTOR) {
159
return false;
160
}
161
}
162
return true;
163
}
164
165
166
bool
167
RODFNet::hasSourceDetector(ROEdge* edge,
168
const RODFDetectorCon& detectors) const {
169
assert(myDetectorsOnEdges.find(edge) != myDetectorsOnEdges.end());
170
const std::vector<std::string>& detIDs = myDetectorsOnEdges.find(edge)->second;
171
std::vector<std::string>::const_iterator i;
172
for (i = detIDs.begin(); i != detIDs.end(); ++i) {
173
const RODFDetector& det = detectors.getDetector(*i);
174
if (det.getType() == SOURCE_DETECTOR) {
175
return true;
176
}
177
}
178
return false;
179
}
180
181
182
183
void
184
RODFNet::computeRoutesFor(ROEdge* edge, RODFRouteDesc& base, int /*no*/,
185
bool keepUnfoundEnds,
186
bool keepShortestOnly,
187
ROEdgeVector& /*visited*/,
188
const RODFDetector& det, RODFRouteCont& into,
189
const RODFDetectorCon& detectors,
190
int maxFollowingLength,
191
ROEdgeVector& seen) const {
192
std::vector<RODFRouteDesc> unfoundEnds;
193
std::priority_queue<RODFRouteDesc, std::vector<RODFRouteDesc>, DFRouteDescByTimeComperator> toSolve;
194
std::map<ROEdge*, ROEdgeVector > dets2Follow;
195
dets2Follow[edge] = ROEdgeVector();
196
base.passedNo = 0;
197
double minDist = OptionsCont::getOptions().getFloat("min-route-length");
198
toSolve.push(base);
199
while (!toSolve.empty()) {
200
RODFRouteDesc current = toSolve.top();
201
toSolve.pop();
202
ROEdge* last = *(current.edges2Pass.end() - 1);
203
if (hasDetector(last)) {
204
if (dets2Follow.find(last) == dets2Follow.end()) {
205
dets2Follow[last] = ROEdgeVector();
206
}
207
for (ROEdgeVector::reverse_iterator i = current.edges2Pass.rbegin() + 1; i != current.edges2Pass.rend(); ++i) {
208
if (hasDetector(*i)) {
209
dets2Follow[*i].push_back(last);
210
break;
211
}
212
}
213
}
214
215
// do not process an edge twice
216
if (find(seen.begin(), seen.end(), last) != seen.end() && keepShortestOnly) {
217
continue;
218
}
219
seen.push_back(last);
220
// end if the edge has no further connections
221
if (!hasApproached(last)) {
222
// ok, no further connections to follow
223
current.factor = 1.;
224
double cdist = current.edges2Pass[0]->getFromJunction()->getPosition().distanceTo(current.edges2Pass.back()->getToJunction()->getPosition());
225
if (minDist < cdist) {
226
into.addRouteDesc(current);
227
}
228
continue;
229
}
230
// check for passing detectors:
231
// if the current last edge is not the one the detector is placed on ...
232
bool addNextNoFurther = false;
233
if (last != getDetectorEdge(det)) {
234
// ... if there is a detector ...
235
if (hasDetector(last)) {
236
if (!hasInBetweenDetectorsOnly(last, detectors)) {
237
// ... and it's not an in-between-detector
238
// -> let's add this edge and the following, but not any further
239
addNextNoFurther = true;
240
current.lastDetectorEdge = last;
241
current.duration2Last = (SUMOTime) current.duration_2;
242
current.distance2Last = current.distance;
243
current.endDetectorEdge = last;
244
if (hasSourceDetector(last, detectors)) {
245
///!!! //toDiscard.push_back(current);
246
}
247
current.factor = 1.;
248
double cdist = current.edges2Pass[0]->getFromJunction()->getPosition().distanceTo(current.edges2Pass.back()->getToJunction()->getPosition());
249
if (minDist < cdist) {
250
into.addRouteDesc(current);
251
}
252
continue;
253
} else {
254
// ... if it's an in-between-detector
255
// -> mark the current route as to be continued
256
current.passedNo = 0;
257
current.duration2Last = (SUMOTime) current.duration_2;
258
current.distance2Last = current.distance;
259
current.lastDetectorEdge = last;
260
}
261
}
262
}
263
// check for highway off-ramps
264
if (myAmInHighwayMode) {
265
// if it's beside the highway...
266
if (last->getSpeedLimit() < 19.4 && last != getDetectorEdge(det)) {
267
// ... and has more than one following edge
268
if (myApproachedEdges.find(last)->second.size() > 1) {
269
// -> let's add this edge and the following, but not any further
270
addNextNoFurther = true;
271
}
272
273
}
274
}
275
// check for missing end connections
276
if (!addNextNoFurther) {
277
// ... if this one would be processed, but already too many edge
278
// without a detector occurred
279
if (current.passedNo > maxFollowingLength) {
280
// mark not to process any further
281
WRITE_WARNINGF(TL("Could not close route for '%'"), det.getID());
282
unfoundEnds.push_back(current);
283
current.factor = 1.;
284
double cdist = current.edges2Pass[0]->getFromJunction()->getPosition().distanceTo(current.edges2Pass.back()->getToJunction()->getPosition());
285
if (minDist < cdist) {
286
into.addRouteDesc(current);
287
}
288
continue;
289
}
290
}
291
// ... else: loop over the next edges
292
const ROEdgeVector& appr = myApproachedEdges.find(last)->second;
293
bool hadOne = false;
294
for (int i = 0; i < (int)appr.size(); i++) {
295
if (find(current.edges2Pass.begin(), current.edges2Pass.end(), appr[i]) != current.edges2Pass.end()) {
296
// do not append an edge twice (do not build loops)
297
continue;
298
}
299
RODFRouteDesc t(current);
300
t.duration_2 += (appr[i]->getLength() / appr[i]->getSpeedLimit()); //!!!
301
t.distance += appr[i]->getLength();
302
t.edges2Pass.push_back(appr[i]);
303
if (!addNextNoFurther) {
304
t.passedNo++;
305
toSolve.push(t);
306
} else {
307
if (!hadOne) {
308
t.factor = (double) 1. / (double) appr.size();
309
double cdist = current.edges2Pass[0]->getFromJunction()->getPosition().distanceTo(current.edges2Pass.back()->getToJunction()->getPosition());
310
if (minDist < cdist) {
311
into.addRouteDesc(t);
312
}
313
hadOne = true;
314
}
315
}
316
}
317
}
318
//
319
if (!keepUnfoundEnds) {
320
std::vector<RODFRouteDesc>::iterator i;
321
ConstROEdgeVector lastDetEdges;
322
for (i = unfoundEnds.begin(); i != unfoundEnds.end(); ++i) {
323
if (find(lastDetEdges.begin(), lastDetEdges.end(), (*i).lastDetectorEdge) == lastDetEdges.end()) {
324
lastDetEdges.push_back((*i).lastDetectorEdge);
325
} else {
326
bool ok = into.removeRouteDesc(*i);
327
assert(ok);
328
UNUSED_PARAMETER(ok); // only used for assertion
329
}
330
}
331
} else {
332
// !!! patch the factors
333
}
334
while (!toSolve.empty()) {
335
// RODFRouteDesc d = toSolve.top();
336
toSolve.pop();
337
// delete d;
338
}
339
}
340
341
342
void
343
RODFNet::buildRoutes(RODFDetectorCon& detcont, bool keepUnfoundEnds, bool includeInBetween,
344
bool keepShortestOnly, int maxFollowingLength) const {
345
// build needed information first
346
buildDetectorEdgeDependencies(detcont);
347
// then build the routes
348
std::map<ROEdge*, RODFRouteCont* > doneEdges;
349
const std::vector< RODFDetector*>& dets = detcont.getDetectors();
350
for (std::vector< RODFDetector*>::const_iterator i = dets.begin(); i != dets.end(); ++i) {
351
ROEdge* e = getDetectorEdge(**i);
352
if (doneEdges.find(e) != doneEdges.end()) {
353
// use previously build routes
354
(*i)->addRoutes(new RODFRouteCont(*doneEdges[e]));
355
continue;
356
}
357
ROEdgeVector seen;
358
RODFRouteCont* routes = new RODFRouteCont();
359
doneEdges[e] = routes;
360
RODFRouteDesc rd;
361
rd.edges2Pass.push_back(e);
362
rd.duration_2 = (e->getLength() / e->getSpeedLimit()); //!!!;
363
rd.endDetectorEdge = nullptr;
364
rd.lastDetectorEdge = nullptr;
365
rd.distance = e->getLength();
366
rd.distance2Last = 0;
367
rd.duration2Last = 0;
368
369
rd.overallProb = 0;
370
371
ROEdgeVector visited;
372
visited.push_back(e);
373
computeRoutesFor(e, rd, 0, keepUnfoundEnds, keepShortestOnly,
374
visited, **i, *routes, detcont, maxFollowingLength, seen);
375
//!!!routes->removeIllegal(illegals);
376
(*i)->addRoutes(routes);
377
378
// add routes to in-between detectors if wished
379
if (includeInBetween) {
380
// go through the routes
381
const std::vector<RODFRouteDesc>& r = routes->get();
382
for (std::vector<RODFRouteDesc>::const_iterator j = r.begin(); j != r.end(); ++j) {
383
const RODFRouteDesc& mrd = *j;
384
double duration = mrd.duration_2;
385
double distance = mrd.distance;
386
// go through each route's edges
387
ROEdgeVector::const_iterator routeend = mrd.edges2Pass.end();
388
for (ROEdgeVector::const_iterator k = mrd.edges2Pass.begin(); k != routeend; ++k) {
389
// check whether any detectors lies on the current edge
390
if (myDetectorsOnEdges.find(*k) == myDetectorsOnEdges.end()) {
391
duration -= (*k)->getLength() / (*k)->getSpeedLimit();
392
distance -= (*k)->getLength();
393
continue;
394
}
395
// go through the detectors
396
for (const std::string& l : myDetectorsOnEdges.find(*k)->second) {
397
const RODFDetector& m = detcont.getDetector(l);
398
if (m.getType() == BETWEEN_DETECTOR) {
399
RODFRouteDesc nrd;
400
copy(k, routeend, back_inserter(nrd.edges2Pass));
401
nrd.duration_2 = duration;//!!!;
402
nrd.endDetectorEdge = mrd.endDetectorEdge;
403
nrd.lastDetectorEdge = mrd.lastDetectorEdge;
404
nrd.distance = distance;
405
nrd.distance2Last = mrd.distance2Last;
406
nrd.duration2Last = mrd.duration2Last;
407
nrd.overallProb = mrd.overallProb;
408
nrd.factor = mrd.factor;
409
((RODFDetector&) m).addRoute(nrd);
410
}
411
}
412
duration -= (*k)->getLength() / (*k)->getSpeedLimit();
413
distance -= (*k)->getLength();
414
}
415
}
416
}
417
418
}
419
}
420
421
422
void
423
RODFNet::revalidateFlows(const RODFDetector* detector,
424
RODFDetectorFlows& flows,
425
SUMOTime startTime, SUMOTime endTime,
426
SUMOTime stepOffset) {
427
{
428
if (flows.knows(detector->getID())) {
429
const std::vector<FlowDef>& detFlows = flows.getFlowDefs(detector->getID());
430
for (std::vector<FlowDef>::const_iterator j = detFlows.begin(); j != detFlows.end(); ++j) {
431
if ((*j).qPKW > 0 || (*j).qLKW > 0) {
432
return;
433
}
434
}
435
}
436
}
437
// ok, there is no information for the whole time;
438
// lets find preceding detectors and rebuild the flows if possible
439
WRITE_WARNINGF(TL("Detector '%' has no flows.\n Trying to rebuild."), detector->getID());
440
// go back and collect flows
441
ROEdgeVector previous;
442
{
443
std::vector<IterationEdge> missing;
444
IterationEdge ie;
445
ie.depth = 0;
446
ie.edge = getDetectorEdge(*detector);
447
missing.push_back(ie);
448
bool maxDepthReached = false;
449
while (!missing.empty() && !maxDepthReached) {
450
IterationEdge last = missing.back();
451
missing.pop_back();
452
ROEdgeVector approaching = myApproachingEdges[last.edge];
453
for (ROEdgeVector::const_iterator j = approaching.begin(); j != approaching.end(); ++j) {
454
if (hasDetector(*j)) {
455
previous.push_back(*j);
456
} else {
457
ie.depth = last.depth + 1;
458
ie.edge = *j;
459
missing.push_back(ie);
460
if (ie.depth > 5) {
461
maxDepthReached = true;
462
}
463
}
464
}
465
}
466
if (maxDepthReached) {
467
WRITE_WARNING(TL(" Could not build list of previous flows."));
468
}
469
}
470
// Edges with previous detectors are now in "previous";
471
// compute following
472
ROEdgeVector latter;
473
{
474
std::vector<IterationEdge> missing;
475
for (ROEdgeVector::const_iterator k = previous.begin(); k != previous.end(); ++k) {
476
IterationEdge ie;
477
ie.depth = 0;
478
ie.edge = *k;
479
missing.push_back(ie);
480
}
481
bool maxDepthReached = false;
482
while (!missing.empty() && !maxDepthReached) {
483
IterationEdge last = missing.back();
484
missing.pop_back();
485
ROEdgeVector approached = myApproachedEdges[last.edge];
486
for (ROEdgeVector::const_iterator j = approached.begin(); j != approached.end(); ++j) {
487
if (*j == getDetectorEdge(*detector)) {
488
continue;
489
}
490
if (hasDetector(*j)) {
491
latter.push_back(*j);
492
} else {
493
IterationEdge ie;
494
ie.depth = last.depth + 1;
495
ie.edge = *j;
496
missing.push_back(ie);
497
if (ie.depth > 5) {
498
maxDepthReached = true;
499
}
500
}
501
}
502
}
503
if (maxDepthReached) {
504
WRITE_WARNING(TL(" Could not build list of latter flows."));
505
return;
506
}
507
}
508
// Edges with latter detectors are now in "latter";
509
510
// lets not validate them by now - surely this should be done
511
// for each time step: collect incoming flows; collect outgoing;
512
std::vector<FlowDef> mflows;
513
int index = 0;
514
for (SUMOTime t = startTime; t < endTime; t += stepOffset, index++) {
515
// collect incoming
516
FlowDef inFlow;
517
inFlow.qLKW = 0;
518
inFlow.qPKW = 0;
519
inFlow.vLKW = 0;
520
inFlow.vPKW = 0;
521
// !! time difference is missing
522
for (const ROEdge* const e : previous) {
523
const std::vector<FlowDef>& eflows = static_cast<const RODFEdge*>(e)->getFlows();
524
if (eflows.size() != 0) {
525
const FlowDef& srcFD = eflows[index];
526
inFlow.qLKW += srcFD.qLKW;
527
inFlow.qPKW += srcFD.qPKW;
528
inFlow.vLKW += srcFD.vLKW;
529
inFlow.vPKW += srcFD.vPKW;
530
}
531
}
532
inFlow.vLKW /= (double) previous.size();
533
inFlow.vPKW /= (double) previous.size();
534
// collect outgoing
535
FlowDef outFlow;
536
outFlow.qLKW = 0;
537
outFlow.qPKW = 0;
538
outFlow.vLKW = 0;
539
outFlow.vPKW = 0;
540
// !! time difference is missing
541
for (const ROEdge* const e : latter) {
542
const std::vector<FlowDef>& eflows = static_cast<const RODFEdge*>(e)->getFlows();
543
if (eflows.size() != 0) {
544
const FlowDef& srcFD = eflows[index];
545
outFlow.qLKW += srcFD.qLKW;
546
outFlow.qPKW += srcFD.qPKW;
547
outFlow.vLKW += srcFD.vLKW;
548
outFlow.vPKW += srcFD.vPKW;
549
}
550
}
551
outFlow.vLKW /= (double) latter.size();
552
outFlow.vPKW /= (double) latter.size();
553
//
554
FlowDef mFlow;
555
mFlow.qLKW = inFlow.qLKW - outFlow.qLKW;
556
mFlow.qPKW = inFlow.qPKW - outFlow.qPKW;
557
mFlow.vLKW = (inFlow.vLKW + outFlow.vLKW) / (double) 2.;
558
mFlow.vPKW = (inFlow.vPKW + outFlow.vPKW) / (double) 2.;
559
mflows.push_back(mFlow);
560
}
561
static_cast<RODFEdge*>(getDetectorEdge(*detector))->setFlows(mflows);
562
flows.setFlows(detector->getID(), mflows);
563
}
564
565
566
void
567
RODFNet::revalidateFlows(const RODFDetectorCon& detectors,
568
RODFDetectorFlows& flows,
569
SUMOTime startTime, SUMOTime endTime,
570
SUMOTime stepOffset) {
571
const std::vector<RODFDetector*>& dets = detectors.getDetectors();
572
for (std::vector<RODFDetector*>::const_iterator i = dets.begin(); i != dets.end(); ++i) {
573
// check whether there is at least one entry with a flow larger than zero
574
revalidateFlows(*i, flows, startTime, endTime, stepOffset);
575
}
576
}
577
578
579
580
void
581
RODFNet::removeEmptyDetectors(RODFDetectorCon& detectors,
582
RODFDetectorFlows& flows) {
583
const std::vector<RODFDetector*>& dets = detectors.getDetectors();
584
for (std::vector<RODFDetector*>::const_iterator i = dets.begin(); i != dets.end();) {
585
bool remove = true;
586
// check whether there is at least one entry with a flow larger than zero
587
if (flows.knows((*i)->getID())) {
588
remove = false;
589
}
590
if (remove) {
591
WRITE_MESSAGEF(TL("Removed detector '%' because no flows for him exist."), (*i)->getID());
592
flows.removeFlow((*i)->getID());
593
detectors.removeDetector((*i)->getID());
594
i = dets.begin();
595
} else {
596
i++;
597
}
598
}
599
}
600
601
602
603
void
604
RODFNet::reportEmptyDetectors(RODFDetectorCon& detectors,
605
RODFDetectorFlows& flows) {
606
const std::vector<RODFDetector*>& dets = detectors.getDetectors();
607
for (std::vector<RODFDetector*>::const_iterator i = dets.begin(); i != dets.end(); ++i) {
608
bool remove = true;
609
// check whether there is at least one entry with a flow larger than zero
610
if (flows.knows((*i)->getID())) {
611
remove = false;
612
}
613
if (remove) {
614
WRITE_MESSAGEF(TL("Detector '%' has no flow."), (*i)->getID());
615
}
616
}
617
}
618
619
620
621
ROEdge*
622
RODFNet::getDetectorEdge(const RODFDetector& det) const {
623
const std::string edgeName = SUMOXMLDefinitions::getEdgeIDFromLane(det.getLaneID());
624
ROEdge* ret = getEdge(edgeName);
625
if (ret == nullptr) {
626
throw ProcessError("Edge '" + edgeName + "' used by detector '" + det.getID() + "' is not known.");
627
}
628
return ret;
629
}
630
631
632
bool
633
RODFNet::hasApproaching(ROEdge* edge) const {
634
return myApproachingEdges.find(edge) != myApproachingEdges.end()
635
&& myApproachingEdges.find(edge)->second.size() != 0;
636
}
637
638
639
bool
640
RODFNet::hasApproached(ROEdge* edge) const {
641
return myApproachedEdges.find(edge) != myApproachedEdges.end()
642
&& myApproachedEdges.find(edge)->second.size() != 0;
643
}
644
645
646
bool
647
RODFNet::hasDetector(ROEdge* edge) const {
648
return myDetectorsOnEdges.find(edge) != myDetectorsOnEdges.end()
649
&& myDetectorsOnEdges.find(edge)->second.size() != 0;
650
}
651
652
653
const std::vector<std::string>&
654
RODFNet::getDetectorList(ROEdge* edge) const {
655
return myDetectorsOnEdges.find(edge)->second;
656
}
657
658
659
double
660
RODFNet::getAbsPos(const RODFDetector& det) const {
661
if (det.getPos() >= 0) {
662
return det.getPos();
663
}
664
return getDetectorEdge(det)->getLength() + det.getPos();
665
}
666
667
bool
668
RODFNet::isSource(const RODFDetector& det, const RODFDetectorCon& detectors,
669
bool strict) const {
670
ROEdgeVector seen;
671
return isSource(det, getDetectorEdge(det), seen, detectors, strict);
672
}
673
674
bool
675
RODFNet::isFalseSource(const RODFDetector& det, const RODFDetectorCon& detectors) const {
676
ROEdgeVector seen;
677
return isFalseSource(det, getDetectorEdge(det), seen, detectors);
678
}
679
680
bool
681
RODFNet::isDestination(const RODFDetector& det, const RODFDetectorCon& detectors) const {
682
ROEdgeVector seen;
683
return isDestination(det, getDetectorEdge(det), seen, detectors);
684
}
685
686
687
bool
688
RODFNet::isSource(const RODFDetector& det, ROEdge* edge,
689
ROEdgeVector& seen,
690
const RODFDetectorCon& detectors,
691
bool strict) const {
692
if (seen.size() == 1000) { // !!!
693
WRITE_WARNINGF(TL("Quitting checking for being a source for detector '%' due to seen edge limit."), det.getID());
694
return false;
695
}
696
if (edge == getDetectorEdge(det)) {
697
// maybe there is another detector at the same edge
698
// get the list of this/these detector(s)
699
const std::vector<std::string>& detsOnEdge = myDetectorsOnEdges.find(edge)->second;
700
for (std::vector<std::string>::const_iterator i = detsOnEdge.begin(); i != detsOnEdge.end(); ++i) {
701
if ((*i) == det.getID()) {
702
continue;
703
}
704
const RODFDetector& sec = detectors.getDetector(*i);
705
if (getAbsPos(sec) < getAbsPos(det)) {
706
// ok, there is another detector on the same edge and it is
707
// before this one -> no source
708
return false;
709
}
710
}
711
}
712
// it's a source if no edges are approaching the edge
713
if (!hasApproaching(edge)) {
714
if (edge != getDetectorEdge(det)) {
715
if (hasDetector(edge)) {
716
return false;
717
}
718
}
719
return true;
720
}
721
if (edge != getDetectorEdge(det)) {
722
// ok, we are at one of the edges in front
723
if (myAmInHighwayMode) {
724
if (edge->getSpeedLimit() >= 19.4) {
725
if (hasDetector(edge)) {
726
// we are still on the highway and there is another detector
727
return false;
728
}
729
// the next is a hack for the A100 scenario...
730
// We have to look into further edges herein edges
731
const ROEdgeVector& appr = myApproachingEdges.find(edge)->second;
732
int noFalse = 0;
733
int noSkipped = 0;
734
for (int i = 0; i < (int)appr.size(); i++) {
735
if (hasDetector(appr[i])) {
736
noFalse++;
737
}
738
}
739
if (noFalse + noSkipped == (int)appr.size()) {
740
return false;
741
}
742
}
743
}
744
}
745
746
if (myAmInHighwayMode) {
747
if (edge->getSpeedLimit() < 19.4 && edge != getDetectorEdge(det)) {
748
// we have left the highway already
749
// -> the detector will be a highway source
750
if (!hasDetector(edge)) {
751
return true;
752
}
753
}
754
}
755
if (myDetectorsOnEdges.find(edge) != myDetectorsOnEdges.end()
756
&&
757
myDetectorEdges.find(det.getID())->second != edge) {
758
return false;
759
}
760
761
// let's check the edges in front
762
const ROEdgeVector& appr = myApproachingEdges.find(edge)->second;
763
int numOk = 0;
764
int numFalse = 0;
765
int numSkipped = 0;
766
seen.push_back(edge);
767
for (int i = 0; i < (int)appr.size(); i++) {
768
bool had = std::find(seen.begin(), seen.end(), appr[i]) != seen.end();
769
if (!had) {
770
if (isSource(det, appr[i], seen, detectors, strict)) {
771
numOk++;
772
} else {
773
numFalse++;
774
}
775
} else {
776
numSkipped++;
777
}
778
}
779
if (strict) {
780
return numOk + numSkipped == (int)appr.size();
781
}
782
return numFalse + numSkipped != (int)appr.size();
783
}
784
785
786
bool
787
RODFNet::isDestination(const RODFDetector& det, ROEdge* edge, ROEdgeVector& seen,
788
const RODFDetectorCon& detectors) const {
789
if (seen.size() == 1000) { // !!!
790
WRITE_WARNINGF(TL("Quitting checking for being a destination for detector '%' due to seen edge limit."), det.getID());
791
return false;
792
}
793
if (edge == getDetectorEdge(det)) {
794
// maybe there is another detector at the same edge
795
// get the list of this/these detector(s)
796
const std::vector<std::string>& detsOnEdge = myDetectorsOnEdges.find(edge)->second;
797
for (std::vector<std::string>::const_iterator i = detsOnEdge.begin(); i != detsOnEdge.end(); ++i) {
798
if ((*i) == det.getID()) {
799
continue;
800
}
801
const RODFDetector& sec = detectors.getDetector(*i);
802
if (getAbsPos(sec) > getAbsPos(det)) {
803
// ok, there is another detector on the same edge and it is
804
// after this one -> no destination
805
return false;
806
}
807
}
808
}
809
if (!hasApproached(edge)) {
810
if (edge != getDetectorEdge(det)) {
811
if (hasDetector(edge)) {
812
return false;
813
}
814
}
815
return true;
816
}
817
if (edge != getDetectorEdge(det)) {
818
// ok, we are at one of the edges coming behind
819
if (myAmInHighwayMode) {
820
if (edge->getSpeedLimit() >= 19.4) {
821
if (hasDetector(edge)) {
822
// we are still on the highway and there is another detector
823
return false;
824
}
825
}
826
}
827
}
828
829
if (myAmInHighwayMode) {
830
if (edge->getSpeedLimit() < 19.4 && edge != getDetectorEdge(det)) {
831
if (hasDetector(edge)) {
832
return true;
833
}
834
if (myApproachedEdges.find(edge)->second.size() > 1) {
835
return true;
836
}
837
838
}
839
}
840
841
if (myDetectorsOnEdges.find(edge) != myDetectorsOnEdges.end()
842
&&
843
myDetectorEdges.find(det.getID())->second != edge) {
844
return false;
845
}
846
const ROEdgeVector& appr = myApproachedEdges.find(edge)->second;
847
bool isall = true;
848
seen.push_back(edge);
849
for (int i = 0; i < (int)appr.size() && isall; i++) {
850
bool had = std::find(seen.begin(), seen.end(), appr[i]) != seen.end();
851
if (!had) {
852
if (!isDestination(det, appr[i], seen, detectors)) {
853
isall = false;
854
}
855
}
856
}
857
return isall;
858
}
859
860
bool
861
RODFNet::isFalseSource(const RODFDetector& det, ROEdge* edge, ROEdgeVector& seen,
862
const RODFDetectorCon& detectors) const {
863
if (seen.size() == 1000) { // !!!
864
WRITE_WARNINGF(TL("Quitting checking for being a false source for detector '%' due to seen edge limit."), det.getID());
865
return false;
866
}
867
seen.push_back(edge);
868
if (edge != getDetectorEdge(det)) {
869
// ok, we are at one of the edges coming behind
870
if (hasDetector(edge)) {
871
const std::vector<std::string>& dets = myDetectorsOnEdges.find(edge)->second;
872
for (std::vector<std::string>::const_iterator i = dets.begin(); i != dets.end(); ++i) {
873
if (detectors.getDetector(*i).getType() == SINK_DETECTOR) {
874
return false;
875
}
876
if (detectors.getDetector(*i).getType() == BETWEEN_DETECTOR) {
877
return false;
878
}
879
if (detectors.getDetector(*i).getType() == SOURCE_DETECTOR) {
880
return true;
881
}
882
}
883
} else {
884
if (myAmInHighwayMode && edge->getSpeedLimit() < 19.) {
885
return false;
886
}
887
}
888
}
889
890
if (myApproachedEdges.find(edge) == myApproachedEdges.end()) {
891
return false;
892
}
893
894
const ROEdgeVector& appr = myApproachedEdges.find(edge)->second;
895
bool isall = false;
896
for (int i = 0; i < (int)appr.size() && !isall; i++) {
897
//printf("checking %s->\n", appr[i].c_str());
898
bool had = std::find(seen.begin(), seen.end(), appr[i]) != seen.end();
899
if (!had) {
900
if (isFalseSource(det, appr[i], seen, detectors)) {
901
isall = true;
902
}
903
}
904
}
905
return isall;
906
}
907
908
909
void
910
RODFNet::buildEdgeFlowMap(const RODFDetectorFlows& flows,
911
const RODFDetectorCon& detectors,
912
SUMOTime startTime, SUMOTime endTime,
913
SUMOTime stepOffset) {
914
std::map<ROEdge*, std::vector<std::string>, idComp>::iterator i;
915
double speedFactorSumPKW = 0;
916
double speedFactorSumLKW = 0;
917
double speedFactorCountPKW = 0;
918
double speedFactorCountLKW = 0;
919
for (i = myDetectorsOnEdges.begin(); i != myDetectorsOnEdges.end(); ++i) {
920
ROEdge* into = (*i).first;
921
const double maxSpeedPKW = into->getVClassMaxSpeed(SVC_PASSENGER);
922
const double maxSpeedLKW = into->getVClassMaxSpeed(SVC_TRUCK);
923
924
const std::vector<std::string>& dets = (*i).second;
925
std::map<double, std::vector<std::string> > cliques;
926
std::vector<std::string>* maxClique = nullptr;
927
for (std::vector<std::string>::const_iterator j = dets.begin(); j != dets.end(); ++j) {
928
if (!flows.knows(*j)) {
929
continue;
930
}
931
const RODFDetector& det = detectors.getDetector(*j);
932
bool found = false;
933
for (auto& k : cliques) {
934
if (fabs(k.first - det.getPos()) < 1) {
935
k.second.push_back(*j);
936
if (maxClique == nullptr || k.second.size() > maxClique->size()) {
937
maxClique = &k.second;
938
}
939
found = true;
940
break;
941
}
942
}
943
if (!found) {
944
cliques[det.getPos()].push_back(*j);
945
maxClique = &cliques[det.getPos()];
946
}
947
}
948
if (maxClique == nullptr) {
949
continue;
950
}
951
std::vector<FlowDef> mflows; // !!! reserve
952
for (SUMOTime t = startTime; t < endTime; t += stepOffset) {
953
FlowDef fd;
954
fd.qPKW = 0;
955
fd.qLKW = 0;
956
fd.vLKW = 0;
957
fd.vPKW = 0;
958
fd.fLKW = 0;
959
fd.isLKW = 0;
960
mflows.push_back(fd);
961
}
962
for (std::vector<std::string>::iterator l = maxClique->begin(); l != maxClique->end(); ++l) {
963
bool didWarn = false;
964
const std::vector<FlowDef>& dflows = flows.getFlowDefs(*l);
965
int index = 0;
966
for (SUMOTime t = startTime; t < endTime; t += stepOffset, index++) {
967
const FlowDef& srcFD = dflows[index];
968
FlowDef& fd = mflows[index];
969
fd.qPKW += srcFD.qPKW;
970
fd.qLKW += srcFD.qLKW;
971
fd.vLKW += srcFD.vLKW / (double) maxClique->size();
972
fd.vPKW += srcFD.vPKW / (double) maxClique->size();
973
fd.fLKW += srcFD.fLKW / (double) maxClique->size();
974
fd.isLKW += srcFD.isLKW / (double) maxClique->size();
975
const double speedFactorPKW = srcFD.vPKW / 3.6 / maxSpeedPKW;
976
const double speedFactorLKW = srcFD.vLKW / 3.6 / maxSpeedLKW;
977
myMaxSpeedFactorPKW = MAX2(myMaxSpeedFactorPKW, speedFactorPKW);
978
myMaxSpeedFactorLKW = MAX2(myMaxSpeedFactorLKW, speedFactorLKW);
979
speedFactorCountPKW += srcFD.qPKW;
980
speedFactorCountLKW += srcFD.qLKW;
981
speedFactorSumPKW += srcFD.qPKW * speedFactorPKW;
982
speedFactorSumLKW += srcFD.qLKW * speedFactorLKW;
983
if (!didWarn && srcFD.vPKW > 0 && srcFD.vPKW < 255 && srcFD.vPKW / 3.6 > into->getSpeedLimit()) {
984
WRITE_MESSAGE("Detected PKW speed (" + toString(srcFD.vPKW / 3.6, 3) + ") higher than allowed speed (" + toString(into->getSpeedLimit(), 3) + ") at '" + (*l) + "' on edge '" + into->getID() + "'.");
985
didWarn = true;
986
}
987
if (!didWarn && srcFD.vLKW > 0 && srcFD.vLKW < 255 && srcFD.vLKW / 3.6 > into->getSpeedLimit()) {
988
WRITE_MESSAGE("Detected LKW speed (" + toString(srcFD.vLKW / 3.6, 3) + ") higher than allowed speed (" + toString(into->getSpeedLimit(), 3) + ") at '" + (*l) + "' on edge '" + into->getID() + "'.");
989
didWarn = true;
990
}
991
}
992
}
993
static_cast<RODFEdge*>(into)->setFlows(mflows);
994
}
995
// @note: this assumes that the speedFactors are independent of location and time
996
if (speedFactorCountPKW > 0) {
997
myAvgSpeedFactorPKW = speedFactorSumPKW / speedFactorCountPKW;
998
WRITE_MESSAGEF(TL("Average speedFactor for PKW is % maximum speedFactor is %."), toString(myAvgSpeedFactorPKW), toString(myMaxSpeedFactorPKW));
999
}
1000
if (speedFactorCountLKW > 0) {
1001
myAvgSpeedFactorLKW = speedFactorSumLKW / speedFactorCountLKW;
1002
WRITE_MESSAGEF(TL("Average speedFactor for LKW is % maximum speedFactor is %."), toString(myAvgSpeedFactorLKW), toString(myMaxSpeedFactorLKW));
1003
}
1004
1005
}
1006
1007
1008
void
1009
RODFNet::buildDetectorDependencies(RODFDetectorCon& detectors) {
1010
// !!! this will not work when several detectors are lying on the same edge on different positions
1011
1012
1013
buildDetectorEdgeDependencies(detectors);
1014
// for each detector, compute the lists of predecessor and following detectors
1015
std::map<std::string, ROEdge*>::const_iterator i;
1016
for (i = myDetectorEdges.begin(); i != myDetectorEdges.end(); ++i) {
1017
const RODFDetector& det = detectors.getDetector((*i).first);
1018
if (!det.hasRoutes()) {
1019
continue;
1020
}
1021
// mark current detectors
1022
std::vector<RODFDetector*> last;
1023
{
1024
const std::vector<std::string>& detNames = myDetectorsOnEdges.find((*i).second)->second;
1025
for (std::vector<std::string>::const_iterator j = detNames.begin(); j != detNames.end(); ++j) {
1026
last.push_back(&detectors.getModifiableDetector(*j));
1027
}
1028
}
1029
// iterate over the current detector's routes
1030
const std::vector<RODFRouteDesc>& routes = det.getRouteVector();
1031
for (std::vector<RODFRouteDesc>::const_iterator j = routes.begin(); j != routes.end(); ++j) {
1032
const ROEdgeVector& edges2Pass = (*j).edges2Pass;
1033
for (ROEdgeVector::const_iterator k = edges2Pass.begin() + 1; k != edges2Pass.end(); ++k) {
1034
if (myDetectorsOnEdges.find(*k) != myDetectorsOnEdges.end()) {
1035
const std::vector<std::string>& detNames = myDetectorsOnEdges.find(*k)->second;
1036
// ok, consecutive detector found
1037
for (std::vector<RODFDetector*>::iterator l = last.begin(); l != last.end(); ++l) {
1038
// mark as follower of current
1039
for (std::vector<std::string>::const_iterator m = detNames.begin(); m != detNames.end(); ++m) {
1040
detectors.getModifiableDetector(*m).addPriorDetector(*l);
1041
(*l)->addFollowingDetector(&detectors.getDetector(*m));
1042
}
1043
}
1044
last.clear();
1045
for (std::vector<std::string>::const_iterator m = detNames.begin(); m != detNames.end(); ++m) {
1046
last.push_back(&detectors.getModifiableDetector(*m));
1047
}
1048
}
1049
}
1050
}
1051
}
1052
}
1053
1054
1055
void
1056
RODFNet::mesoJoin(RODFDetectorCon& detectors, RODFDetectorFlows& flows) {
1057
buildDetectorEdgeDependencies(detectors);
1058
std::map<ROEdge*, std::vector<std::string>, idComp>::iterator i;
1059
for (i = myDetectorsOnEdges.begin(); i != myDetectorsOnEdges.end(); ++i) {
1060
const std::vector<std::string>& dets = (*i).second;
1061
std::map<double, std::vector<std::string> > cliques;
1062
// compute detector cliques
1063
for (std::vector<std::string>::const_iterator j = dets.begin(); j != dets.end(); ++j) {
1064
const RODFDetector& det = detectors.getDetector(*j);
1065
bool found = false;
1066
for (std::map<double, std::vector<std::string> >::iterator k = cliques.begin(); !found && k != cliques.end(); ++k) {
1067
if (fabs((*k).first - det.getPos()) < 10.) {
1068
(*k).second.push_back(*j);
1069
found = true;
1070
}
1071
}
1072
if (!found) {
1073
cliques[det.getPos()] = std::vector<std::string>();
1074
cliques[det.getPos()].push_back(*j);
1075
}
1076
}
1077
// join detector cliques
1078
for (std::map<double, std::vector<std::string> >::iterator m = cliques.begin(); m != cliques.end(); ++m) {
1079
std::vector<std::string> clique = (*m).second;
1080
// do not join if only one
1081
if (clique.size() == 1) {
1082
continue;
1083
}
1084
std::string nid;
1085
for (std::vector<std::string>::iterator n = clique.begin(); n != clique.end(); ++n) {
1086
std::cout << *n << " ";
1087
if (n != clique.begin()) {
1088
nid = nid + "_";
1089
}
1090
nid = nid + *n;
1091
}
1092
std::cout << ":" << nid << std::endl;
1093
flows.mesoJoin(nid, (*m).second);
1094
detectors.mesoJoin(nid, (*m).second);
1095
}
1096
}
1097
}
1098
1099
1100
/****************************************************************************/
1101
1102