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