Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netload/NLDetectorBuilder.cpp
193873 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2002-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 NLDetectorBuilder.cpp
15
/// @author Daniel Krajzewicz
16
/// @author Laura Bieker
17
/// @author Clemens Honomichl
18
/// @author Michael Behrisch
19
/// @author Christian Roessel
20
/// @author Jakob Erdmann
21
/// @date Mon, 15 Apr 2002
22
///
23
// Builds detectors for microsim
24
/****************************************************************************/
25
#include <config.h>
26
27
#include <string>
28
#include <iostream>
29
#include <microsim/MSNet.h>
30
#include <microsim/MSLane.h>
31
#include <microsim/MSEdge.h>
32
#include <microsim/output/MSInductLoop.h>
33
#include <microsim/output/MSE2Collector.h>
34
// #include <microsim/output/MSMultiLaneE2Collector.h>
35
#include <microsim/output/MSVTypeProbe.h>
36
#include <microsim/output/MSRouteProbe.h>
37
#include <microsim/output/MSMeanData_Net.h>
38
#include <microsim/output/MSMeanData_Emissions.h>
39
#include <microsim/output/MSMeanData_Harmonoise.h>
40
#include <microsim/output/MSMeanData_Amitran.h>
41
#include <microsim/output/MSInstantInductLoop.h>
42
#include <microsim/MSGlobals.h>
43
#include <microsim/actions/Command_SaveTLCoupledDet.h>
44
#include <microsim/actions/Command_SaveTLCoupledLaneDet.h>
45
#include <utils/common/UtilExceptions.h>
46
#include <utils/common/FileHelpers.h>
47
#include <utils/common/StringUtils.h>
48
#include <utils/common/StringTokenizer.h>
49
#include <utils/common/StringUtils.h>
50
#include "NLDetectorBuilder.h"
51
#include <microsim/output/MSDetectorControl.h>
52
53
#include <mesosim/MEInductLoop.h>
54
#include <mesosim/MELoop.h>
55
#include <mesosim/MESegment.h>
56
57
58
// ===========================================================================
59
// method definitions
60
// ===========================================================================
61
/* -------------------------------------------------------------------------
62
* NLDetectorBuilder::E3DetectorDefinition-methods
63
* ----------------------------------------------------------------------- */
64
NLDetectorBuilder::E3DetectorDefinition::E3DetectorDefinition(const std::string& id,
65
const std::string& device, double haltingSpeedThreshold,
66
SUMOTime haltingTimeThreshold, SUMOTime splInterval,
67
const std::string name, const std::string& vTypes,
68
const std::string& nextEdges,
69
int detectPersons, bool openEntry, bool expectArrival) :
70
myID(id), myDevice(device),
71
myHaltingSpeedThreshold(haltingSpeedThreshold),
72
myHaltingTimeThreshold(haltingTimeThreshold),
73
mySampleInterval(splInterval),
74
myName(name),
75
myVehicleTypes(vTypes),
76
myNextEdges(nextEdges),
77
myDetectPersons(detectPersons),
78
myOpenEntry(openEntry),
79
myExpectArrival(expectArrival) {
80
}
81
82
83
NLDetectorBuilder::E3DetectorDefinition::~E3DetectorDefinition() {}
84
85
86
/* -------------------------------------------------------------------------
87
* NLDetectorBuilder-methods
88
* ----------------------------------------------------------------------- */
89
NLDetectorBuilder::NLDetectorBuilder(MSNet& net)
90
: myNet(net), myE3Definition(nullptr) {}
91
92
93
NLDetectorBuilder::~NLDetectorBuilder() {
94
delete myE3Definition;
95
}
96
97
98
Parameterised*
99
NLDetectorBuilder::buildInductLoop(const std::string& id,
100
const std::string& lane, double pos, double length, SUMOTime splInterval,
101
const std::string& device, bool friendlyPos,
102
const std::string name,
103
const std::string& vTypes,
104
const std::string& nextEdges,
105
int detectPersons) {
106
checkSampleInterval(splInterval, SUMO_TAG_E1DETECTOR, id);
107
// get and check the lane
108
MSLane* clane = getLaneChecking(lane, SUMO_TAG_E1DETECTOR, id);
109
// get and check the position
110
pos = getPositionChecking(pos, clane, friendlyPos, SUMO_TAG_E1DETECTOR, id);
111
if (length < 0) {
112
throw InvalidArgument("The length of " + toString(SUMO_TAG_E1DETECTOR) + " '" + id + "' cannot be negative");
113
} else if (length > 0 && pos + length > clane->getLength()) {
114
if (friendlyPos) {
115
length = MIN2(length, clane->getLength());
116
pos = clane->getLength() - length;
117
} else {
118
throw InvalidArgument("The length of " + toString(SUMO_TAG_E1DETECTOR) + " '" + id + "' puts it beyond the lane's '" + clane->getID() + "' end.");
119
}
120
}
121
// build the loop
122
MSDetectorFileOutput* loop = createInductLoop(id, clane, pos, length, name, vTypes, nextEdges, detectPersons, true);
123
// add the file output
124
myNet.getDetectorControl().add(SUMO_TAG_INDUCTION_LOOP, loop, device, splInterval);
125
return loop;
126
}
127
128
129
Parameterised*
130
NLDetectorBuilder::buildInstantInductLoop(const std::string& id,
131
const std::string& lane, double pos,
132
const std::string& device, bool friendlyPos,
133
const std::string name,
134
const std::string& vTypes,
135
const std::string& nextEdges,
136
int detectPersons) {
137
// get and check the lane
138
MSLane* clane = getLaneChecking(lane, SUMO_TAG_INSTANT_INDUCTION_LOOP, id);
139
// get and check the position
140
pos = getPositionChecking(pos, clane, friendlyPos, SUMO_TAG_INSTANT_INDUCTION_LOOP, id);
141
// build the loop
142
MSDetectorFileOutput* loop = createInstantInductLoop(id, clane, pos, device, name, vTypes, nextEdges, detectPersons);
143
// add the file output
144
myNet.getDetectorControl().add(SUMO_TAG_INSTANT_INDUCTION_LOOP, loop);
145
return loop;
146
}
147
148
149
Parameterised*
150
NLDetectorBuilder::buildE2Detector(const std::string& id, MSLane* lane, double pos, double endPos, double length,
151
const std::string& device, SUMOTime frequency,
152
SUMOTime haltingTimeThreshold, double haltingSpeedThreshold, double jamDistThreshold,
153
const std::string name, const std::string& vTypes,
154
const std::string& nextEdges,
155
int detectPersons, bool friendlyPos, bool showDetector,
156
MSTLLogicControl::TLSLogicVariants* tlls, MSLane* toLane) {
157
158
bool tlsGiven = tlls != nullptr;
159
bool toLaneGiven = toLane != nullptr;
160
bool posGiven = pos != std::numeric_limits<double>::max();
161
bool endPosGiven = endPos != std::numeric_limits<double>::max();
162
163
assert(posGiven || endPosGiven);
164
165
// Check positioning
166
if (posGiven) {
167
if (pos >= lane->getLength() || (pos < 0 && -pos > lane->getLength())) {
168
std::stringstream ss;
169
ss << "The given position (=" << pos << ") for detector '" << id
170
<< "' does not lie on the given lane '" << lane->getID()
171
<< "' with length " << lane->getLength();
172
if (friendlyPos) {
173
double newPos = pos > 0 ? lane->getLength() - POSITION_EPS : 0.;
174
ss << " (adjusting to new position " << newPos;
175
WRITE_WARNING(ss.str());
176
pos = newPos;
177
} else {
178
ss << " (0 <= pos < lane->getLength() is required)";
179
throw InvalidArgument(ss.str());
180
}
181
}
182
}
183
if (endPosGiven) {
184
if (endPos > lane->getLength() || (endPos <= 0 && -endPos >= lane->getLength())) {
185
std::stringstream ss;
186
ss << "The given end position (=" << endPos << ") for detector '" << id
187
<< "' does not lie on the given lane '" << lane->getID()
188
<< "' with length " << lane->getLength();
189
if (friendlyPos) {
190
double newEndPos = endPos > 0 ? lane->getLength() : POSITION_EPS;
191
ss << " (adjusting to new position " << newEndPos;
192
WRITE_WARNING(ss.str());
193
pos = newEndPos;
194
} else {
195
ss << " (0 <= pos < lane->getLength() is required)";
196
throw InvalidArgument(ss.str());
197
}
198
}
199
}
200
201
MSE2Collector* det = nullptr;
202
if (tlsGiven) {
203
// Detector connected to TLS
204
det = createE2Detector(id, DU_USER_DEFINED, lane, pos, endPos, length, haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold, name, vTypes, nextEdges, detectPersons, showDetector);
205
myNet.getDetectorControl().add(SUMO_TAG_LANE_AREA_DETECTOR, det);
206
// add the file output (XXX: Where's the corresponding delete?)
207
if (toLaneGiven) {
208
// Detector also associated to specific link
209
const MSLane* const lastLane = det->getLastLane();
210
const MSLink* const link = lastLane->getLinkTo(toLane);
211
if (link == nullptr) {
212
throw InvalidArgument(
213
"The detector '" + id + "' cannot be build as no connection between lanes '"
214
+ lastLane->getID() + "' and '" + toLane->getID() + "' exists.");
215
}
216
new Command_SaveTLCoupledLaneDet(*tlls, det, myNet.getCurrentTimeStep(), OutputDevice::getDevice(device), link);
217
} else {
218
// detector for tls but without specific link
219
new Command_SaveTLCoupledDet(*tlls, det, myNet.getCurrentTimeStep(), OutputDevice::getDevice(device));
220
}
221
} else {
222
// User specified detector for xml-output
223
checkSampleInterval(frequency, SUMO_TAG_E2DETECTOR, id);
224
det = createE2Detector(id, DU_USER_DEFINED, lane, pos, endPos, length, haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold, name, vTypes, nextEdges, detectPersons, showDetector);
225
myNet.getDetectorControl().add(SUMO_TAG_LANE_AREA_DETECTOR, det, device, frequency);
226
}
227
return det;
228
}
229
230
231
Parameterised*
232
NLDetectorBuilder::buildE2Detector(const std::string& id, std::vector<MSLane*> lanes, double pos, double endPos,
233
const std::string& device, SUMOTime frequency,
234
SUMOTime haltingTimeThreshold, double haltingSpeedThreshold, double jamDistThreshold,
235
const std::string name, const std::string& vTypes,
236
const std::string& nextEdges,
237
int detectPersons, bool friendlyPos, bool showDetector,
238
MSTLLogicControl::TLSLogicVariants* tlls, MSLane* toLane) {
239
240
bool tlsGiven = tlls != nullptr;
241
bool toLaneGiven = toLane != nullptr;
242
assert(pos != std::numeric_limits<double>::max());
243
assert(endPos != std::numeric_limits<double>::max());
244
assert(lanes.size() != 0);
245
246
const MSLane* const firstLane = lanes[0];
247
const MSLane* const lastLane = lanes.back();
248
249
// Check positioning
250
if (pos >= firstLane->getLength() || (pos < 0 && -pos > firstLane->getLength())) {
251
std::stringstream ss;
252
ss << "The given position (=" << pos << ") for detector '" << id
253
<< "' does not lie on the given lane '" << firstLane->getID()
254
<< "' with length " << firstLane->getLength();
255
if (friendlyPos) {
256
double newPos = pos > 0 ? firstLane->getLength() - POSITION_EPS : 0.;
257
ss << " (adjusting to new position " << newPos;
258
WRITE_WARNING(ss.str());
259
pos = newPos;
260
} else {
261
ss << " (0 <= pos < lane->getLength() is required)";
262
throw InvalidArgument(ss.str());
263
}
264
}
265
if (endPos > lastLane->getLength() || (endPos <= 0 && -endPos >= lastLane->getLength())) {
266
std::stringstream ss;
267
ss << "The given end position (=" << endPos << ") for detector '" << id
268
<< "' does not lie on the given lane '" << lastLane->getID()
269
<< "' with length " << lastLane->getLength();
270
if (friendlyPos) {
271
double newEndPos = endPos > 0 ? lastLane->getLength() : POSITION_EPS;
272
ss << " (adjusting to new position " << newEndPos;
273
WRITE_WARNING(ss.str());
274
pos = newEndPos;
275
} else {
276
ss << " (0 <= pos < lane->getLength() is required)";
277
throw InvalidArgument(ss.str());
278
}
279
}
280
281
MSE2Collector* det = nullptr;
282
if (tlsGiven) {
283
// Detector connected to TLS
284
det = createE2Detector(id, DU_USER_DEFINED, lanes, pos, endPos, haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold, name, vTypes, nextEdges, detectPersons, showDetector);
285
myNet.getDetectorControl().add(SUMO_TAG_LANE_AREA_DETECTOR, det);
286
// add the file output (XXX: Where's the corresponding delete?)
287
if (toLaneGiven) {
288
// Detector also associated to specific link
289
const MSLane* const lastDetLane = det->getLastLane();
290
const MSLink* const link = lastDetLane->getLinkTo(toLane);
291
if (link == nullptr) {
292
throw InvalidArgument(
293
"The detector '" + id + "' cannot be build as no connection between lanes '"
294
+ lastDetLane->getID() + "' and '" + toLane->getID() + "' exists.");
295
}
296
new Command_SaveTLCoupledLaneDet(*tlls, det, myNet.getCurrentTimeStep(), OutputDevice::getDevice(device), link);
297
} else {
298
// detector for tls but without specific link
299
new Command_SaveTLCoupledDet(*tlls, det, myNet.getCurrentTimeStep(), OutputDevice::getDevice(device));
300
}
301
} else {
302
// User specified detector for xml-output
303
checkSampleInterval(frequency, SUMO_TAG_E2DETECTOR, id);
304
305
det = createE2Detector(id, DU_USER_DEFINED, lanes, pos, endPos, haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold, name, vTypes, nextEdges, detectPersons, showDetector);
306
myNet.getDetectorControl().add(SUMO_TAG_LANE_AREA_DETECTOR, det, device, frequency);
307
}
308
return det;
309
}
310
311
312
313
Parameterised*
314
NLDetectorBuilder::beginE3Detector(const std::string& id,
315
const std::string& device, SUMOTime splInterval,
316
double haltingSpeedThreshold,
317
SUMOTime haltingTimeThreshold,
318
const std::string name,
319
const std::string& vTypes,
320
const std::string& nextEdges,
321
int detectPersons, bool openEntry, bool expectArrival) {
322
checkSampleInterval(splInterval, SUMO_TAG_E3DETECTOR, id);
323
myE3Definition = new E3DetectorDefinition(id, device, haltingSpeedThreshold, haltingTimeThreshold, splInterval, name, vTypes, nextEdges, detectPersons, openEntry, expectArrival);
324
return myE3Definition;
325
}
326
327
328
void
329
NLDetectorBuilder::addE3Entry(const std::string& lane,
330
double pos, bool friendlyPos) {
331
if (myE3Definition == nullptr) {
332
return;
333
}
334
MSLane* clane = getLaneChecking(lane, SUMO_TAG_E3DETECTOR, myE3Definition->myID);
335
// get and check the position
336
pos = getPositionChecking(pos, clane, friendlyPos, SUMO_TAG_DET_ENTRY, myE3Definition->myID);
337
// build and save the entry
338
myE3Definition->myEntries.push_back(MSCrossSection(clane, pos));
339
}
340
341
342
void
343
NLDetectorBuilder::addE3Exit(const std::string& lane,
344
double pos, bool friendlyPos) {
345
if (myE3Definition == nullptr) {
346
return;
347
}
348
MSLane* clane = getLaneChecking(lane, SUMO_TAG_E3DETECTOR, myE3Definition->myID);
349
// get and check the position
350
pos = getPositionChecking(pos, clane, friendlyPos, SUMO_TAG_DET_EXIT, myE3Definition->myID);
351
// build and save the exit
352
myE3Definition->myExits.push_back(MSCrossSection(clane, pos));
353
}
354
355
356
std::string
357
NLDetectorBuilder::getCurrentE3ID() const {
358
if (myE3Definition == nullptr) {
359
return "<unknown>";
360
}
361
return myE3Definition->myID;
362
}
363
364
365
void
366
NLDetectorBuilder::endE3Detector() {
367
if (myE3Definition == nullptr) {
368
return;
369
}
370
// If E3 own entry or exit detectors
371
if (myE3Definition->myEntries.size() > 0 || myE3Definition->myExits.size() > 0) {
372
// create E3 detector
373
MSDetectorFileOutput* det = createE3Detector(myE3Definition->myID,
374
myE3Definition->myEntries, myE3Definition->myExits,
375
myE3Definition->myHaltingSpeedThreshold, myE3Definition->myHaltingTimeThreshold,
376
myE3Definition->myName,
377
myE3Definition->myVehicleTypes,
378
myE3Definition->myNextEdges,
379
myE3Definition->myDetectPersons,
380
myE3Definition->myOpenEntry,
381
myE3Definition->myExpectArrival);
382
det->updateParameters(myE3Definition->getParametersMap());
383
// add to net
384
myNet.getDetectorControl().add(SUMO_TAG_ENTRY_EXIT_DETECTOR, det, myE3Definition->myDevice, myE3Definition->mySampleInterval);
385
} else {
386
WRITE_WARNING(toString(SUMO_TAG_E3DETECTOR) + " with id = '" + myE3Definition->myID + "' will not be created because is empty (no " + toString(SUMO_TAG_DET_ENTRY) + " or " + toString(SUMO_TAG_DET_EXIT) + " was defined)")
387
}
388
// clean up
389
delete myE3Definition;
390
myE3Definition = nullptr;
391
}
392
393
394
void
395
NLDetectorBuilder::buildVTypeProbe(const std::string& id,
396
const std::string& vtype, SUMOTime frequency,
397
const std::string& device) {
398
checkSampleInterval(frequency, SUMO_TAG_VTYPEPROBE, id);
399
new MSVTypeProbe(id, vtype, OutputDevice::getDevice(device), frequency);
400
}
401
402
403
void
404
NLDetectorBuilder::buildRouteProbe(const std::string& id, const std::string& edge,
405
SUMOTime frequency, SUMOTime begin,
406
const std::string& device,
407
const std::string& vTypes) {
408
checkSampleInterval(frequency, SUMO_TAG_ROUTEPROBE, id);
409
MSEdge* e = getEdgeChecking(edge, SUMO_TAG_ROUTEPROBE, id);
410
MSRouteProbe* probe = new MSRouteProbe(id, e, id + "_" + toString(begin), id + "_" + toString(begin - frequency), vTypes);
411
// add the file output
412
myNet.getDetectorControl().add(SUMO_TAG_ROUTEPROBE, probe, device, frequency, begin);
413
}
414
415
416
MSDetectorFileOutput*
417
NLDetectorBuilder::createInductLoop(const std::string& id,
418
MSLane* lane, double pos,
419
double length,
420
const std::string name,
421
const std::string& vTypes,
422
const std::string& nextEdges,
423
int detectPersons,
424
bool /*show*/) {
425
if (MSGlobals::gUseMesoSim) {
426
return new MEInductLoop(id, MSGlobals::gMesoNet->getSegmentForEdge(lane->getEdge(), pos), pos, name, vTypes, nextEdges, detectPersons);
427
}
428
return new MSInductLoop(id, lane, pos, length, name, vTypes, nextEdges, detectPersons, false);
429
}
430
431
432
MSDetectorFileOutput*
433
NLDetectorBuilder::createInstantInductLoop(const std::string& id,
434
MSLane* lane, double pos, const std::string& od,
435
const std::string name, const std::string& vTypes,
436
const std::string& nextEdges,
437
int detectPersons) {
438
return new MSInstantInductLoop(id, OutputDevice::getDevice(od), lane, pos, name, vTypes, nextEdges, detectPersons);
439
}
440
441
442
MSE2Collector*
443
NLDetectorBuilder::createE2Detector(const std::string& id,
444
DetectorUsage usage, MSLane* lane, double pos, double endPos, double length,
445
SUMOTime haltingTimeThreshold, double haltingSpeedThreshold, double jamDistThreshold,
446
const std::string name, const std::string& vTypes,
447
const std::string& nextEdges,
448
int detectPersons, bool /* showDetector */) {
449
return new MSE2Collector(id, usage, lane, pos, endPos, length, haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold, name, vTypes, nextEdges, detectPersons);
450
}
451
452
MSE2Collector*
453
NLDetectorBuilder::createE2Detector(const std::string& id,
454
DetectorUsage usage, std::vector<MSLane*> lanes, double pos, double endPos,
455
SUMOTime haltingTimeThreshold, double haltingSpeedThreshold, double jamDistThreshold,
456
const std::string name, const std::string& vTypes,
457
const std::string& nextEdges,
458
int detectPersons, bool /* showDetector */) {
459
return new MSE2Collector(id, usage, lanes, pos, endPos, haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold, name, vTypes, nextEdges, detectPersons);
460
}
461
462
MSDetectorFileOutput*
463
NLDetectorBuilder::createE3Detector(const std::string& id,
464
const CrossSectionVector& entries,
465
const CrossSectionVector& exits,
466
double haltingSpeedThreshold,
467
SUMOTime haltingTimeThreshold,
468
const std::string name, const std::string& vTypes,
469
const std::string& nextEdges,
470
int detectPersons,
471
bool openEntry,
472
bool expectArrival) {
473
return new MSE3Collector(id, entries, exits, haltingSpeedThreshold, haltingTimeThreshold, name, vTypes, nextEdges, detectPersons, openEntry, expectArrival);
474
}
475
476
477
double
478
NLDetectorBuilder::getPositionChecking(double pos, MSLane* lane, bool friendlyPos,
479
SumoXMLTag tag,
480
const std::string& detid) {
481
// check whether it is given from the end
482
if (pos < 0) {
483
pos += lane->getLength();
484
}
485
// check whether it is on the lane
486
if (pos > lane->getLength()) {
487
if (friendlyPos) {
488
pos = lane->getLength();
489
} else {
490
throw InvalidArgument("The position of " + toString(tag) + " '" + detid + "' lies beyond the lane's '" + lane->getID() + "' end.");
491
}
492
}
493
if (pos < 0) {
494
if (friendlyPos) {
495
pos = 0.;
496
} else {
497
throw InvalidArgument("The position of " + toString(tag) + " '" + detid + "' lies before the lane's '" + lane->getID() + "' begin.");
498
}
499
}
500
return pos;
501
}
502
503
504
void
505
NLDetectorBuilder::createEdgeLaneMeanData(const std::string& id, SUMOTime frequency,
506
SUMOTime begin, SUMOTime end, const std::string& type,
507
const bool useLanes, const bool withEmpty, const bool printDefaults,
508
const bool withInternal, const bool trackVehicles, const int detectPersons,
509
const double maxTravelTime, const double minSamples,
510
const double haltSpeed, const std::string& vTypes,
511
const std::string& writeAttributes,
512
std::vector<MSEdge*> edges,
513
AggregateType aggregate,
514
const std::string& device) {
515
if (begin < 0) {
516
throw InvalidArgument("Negative begin time for meandata dump '" + id + "'.");
517
}
518
if (end < 0) {
519
end = SUMOTime_MAX;
520
}
521
if (end <= begin) {
522
throw InvalidArgument("End before or at begin for meandata dump '" + id + "'.");
523
}
524
checkStepLengthMultiple(begin, " for meandata dump '" + id + "'");
525
MSMeanData* det = nullptr;
526
if ((type == SUMOXMLDefinitions::MeanDataTypes.getString(MeanDataType::DEFAULT)) ||
527
(type == SUMOXMLDefinitions::MeanDataTypes.getString(MeanDataType::TRAFFIC)) ||
528
(type == "performance")) {
529
det = new MSMeanData_Net(id, begin, end, useLanes, withEmpty,
530
printDefaults, withInternal, trackVehicles, detectPersons, maxTravelTime, minSamples, haltSpeed, vTypes, writeAttributes, edges, aggregate);
531
} else if ((type == SUMOXMLDefinitions::MeanDataTypes.getString(MeanDataType::EMISSIONS)) || (type == "hbefa")) {
532
if (type == "hbefa") {
533
WRITE_WARNING(TL("The netstate type 'hbefa' is deprecated. Please use the type 'emissions' instead."));
534
}
535
det = new MSMeanData_Emissions(id, begin, end, useLanes, withEmpty,
536
printDefaults, withInternal, trackVehicles, maxTravelTime, minSamples, vTypes, writeAttributes, edges, aggregate);
537
} else if (type == SUMOXMLDefinitions::MeanDataTypes.getString(MeanDataType::HARMONOISE)) {
538
det = new MSMeanData_Harmonoise(id, begin, end, useLanes, withEmpty,
539
printDefaults, withInternal, trackVehicles, maxTravelTime, minSamples, vTypes, writeAttributes, edges, aggregate);
540
} else if (type == SUMOXMLDefinitions::MeanDataTypes.getString(MeanDataType::AMITRAN)) {
541
det = new MSMeanData_Amitran(id, begin, end, useLanes, withEmpty,
542
printDefaults, withInternal, trackVehicles, detectPersons, maxTravelTime, minSamples, haltSpeed, vTypes, writeAttributes, edges, aggregate);
543
} else {
544
throw InvalidArgument("Invalid type '" + type + "' for meandata dump '" + id + "'.");
545
}
546
if (det != nullptr) {
547
if (frequency < 0) {
548
frequency = end - begin;
549
} else {
550
checkStepLengthMultiple(frequency, " for meandata dump '" + id + "'");
551
}
552
MSNet::getInstance()->getDetectorControl().add(det, device, frequency, begin);
553
}
554
}
555
556
557
558
559
// ------ Value checking/adapting methods ------
560
MSEdge*
561
NLDetectorBuilder::getEdgeChecking(const std::string& edgeID, SumoXMLTag type,
562
const std::string& detid) {
563
// get and check the lane
564
MSEdge* edge = MSEdge::dictionary(edgeID);
565
if (edge == nullptr) {
566
throw InvalidArgument("The lane with the id '" + edgeID + "' is not known (while building " + toString(type) + " '" + detid + "').");
567
}
568
return edge;
569
}
570
571
572
MSLane*
573
NLDetectorBuilder::getLaneChecking(const std::string& laneID, SumoXMLTag type,
574
const std::string& detid) {
575
// get and check the lane
576
MSLane* lane = MSLane::dictionary(laneID);
577
if (lane == nullptr) {
578
throw InvalidArgument("The lane with the id '" + laneID + "' is not known (while building " + toString(type) + " '" + detid + "').");
579
}
580
return lane;
581
}
582
583
584
void
585
NLDetectorBuilder::checkSampleInterval(SUMOTime splInterval, SumoXMLTag type, const std::string& id) {
586
if (splInterval < 0) {
587
throw InvalidArgument("Negative sampling frequency (in " + toString(type) + " '" + id + "').");
588
}
589
if (splInterval == 0) {
590
throw InvalidArgument("Sampling frequency must not be zero (in " + toString(type) + " '" + id + "').");
591
}
592
checkStepLengthMultiple(splInterval, " (in " + toString(type) + " '" + id + "')");
593
}
594
595
596
/****************************************************************************/
597
598