|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00011 // Builds detectors for microsim 00012 /****************************************************************************/ 00013 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/ 00014 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors 00015 /****************************************************************************/ 00016 // 00017 // This file is part of SUMO. 00018 // SUMO is free software: you can redistribute it and/or modify 00019 // it under the terms of the GNU General Public License as published by 00020 // the Free Software Foundation, either version 3 of the License, or 00021 // (at your option) any later version. 00022 // 00023 /****************************************************************************/ 00024 00025 00026 // =========================================================================== 00027 // included modules 00028 // =========================================================================== 00029 #ifdef _MSC_VER 00030 #include <windows_config.h> 00031 #else 00032 #include <config.h> 00033 #endif 00034 00035 #include <string> 00036 #include <iostream> 00037 #include <microsim/MSNet.h> 00038 #include <microsim/MSLane.h> 00039 #include <microsim/output/MSInductLoop.h> 00040 #include <microsim/output/MSE2Collector.h> 00041 #include <microsim/output/MS_E2_ZS_CollectorOverLanes.h> 00042 #include <microsim/output/MSVTypeProbe.h> 00043 #include <microsim/output/MSRouteProbe.h> 00044 #include <microsim/output/MSMeanData_Net.h> 00045 #include <microsim/output/MSMeanData_HBEFA.h> 00046 #include <microsim/output/MSMeanData_Harmonoise.h> 00047 #include <microsim/output/MSInstantInductLoop.h> 00048 #include <microsim/MSGlobals.h> 00049 #include <microsim/actions/Command_SaveTLCoupledDet.h> 00050 #include <microsim/actions/Command_SaveTLCoupledLaneDet.h> 00051 #include <utils/common/UtilExceptions.h> 00052 #include <utils/common/FileHelpers.h> 00053 #include <utils/common/StringUtils.h> 00054 #include <utils/common/StringTokenizer.h> 00055 #include <utils/common/TplConvert.h> 00056 #include "NLDetectorBuilder.h" 00057 #include <microsim/output/MSDetectorControl.h> 00058 00059 #ifdef HAVE_MESOSIM 00060 #include <mesosim/MEInductLoop.h> 00061 #include <mesosim/MELoop.h> 00062 #include <mesosim/MESegment.h> 00063 #endif 00064 00065 #ifdef CHECK_MEMORY_LEAKS 00066 #include <foreign/nvwa/debug_new.h> 00067 #endif // CHECK_MEMORY_LEAKS 00068 00069 00070 // =========================================================================== 00071 // method definitions 00072 // =========================================================================== 00073 /* ------------------------------------------------------------------------- 00074 * NLDetectorBuilder::E3DetectorDefinition-methods 00075 * ----------------------------------------------------------------------- */ 00076 NLDetectorBuilder::E3DetectorDefinition::E3DetectorDefinition(const std::string& id, 00077 OutputDevice& device, SUMOReal haltingSpeedThreshold, 00078 SUMOTime haltingTimeThreshold, int splInterval) 00079 : myID(id), myDevice(device), 00080 myHaltingSpeedThreshold(haltingSpeedThreshold), 00081 myHaltingTimeThreshold(haltingTimeThreshold), 00082 mySampleInterval(splInterval) {} 00083 00084 00085 NLDetectorBuilder::E3DetectorDefinition::~E3DetectorDefinition() {} 00086 00087 00088 /* ------------------------------------------------------------------------- 00089 * NLDetectorBuilder-methods 00090 * ----------------------------------------------------------------------- */ 00091 NLDetectorBuilder::NLDetectorBuilder(MSNet& net) 00092 : myNet(net), myE3Definition(0) {} 00093 00094 00095 NLDetectorBuilder::~NLDetectorBuilder() {} 00096 00097 00098 void 00099 NLDetectorBuilder::buildInductLoop(const std::string& id, 00100 const std::string& lane, SUMOReal pos, int splInterval, 00101 OutputDevice& device, bool friendlyPos, bool splitByType) throw(InvalidArgument) { 00102 checkSampleInterval(splInterval, SUMO_TAG_E1DETECTOR, id); 00103 // get and check the lane 00104 MSLane* clane = getLaneChecking(lane, SUMO_TAG_E1DETECTOR, id); 00105 #ifdef HAVE_MESOSIM 00106 if (!MSGlobals::gUseMesoSim) { 00107 #endif 00108 // get and check the position 00109 pos = getPositionChecking(pos, clane, friendlyPos, id); 00110 // build the loop 00111 MSDetectorFileOutput* loop = createInductLoop(id, clane, pos, splitByType); 00112 // add the file output 00113 myNet.getDetectorControl().add(SUMO_TAG_INDUCTION_LOOP, loop, device, splInterval); 00114 #ifdef HAVE_MESOSIM 00115 } else { 00116 if (pos < 0) { 00117 pos = clane->getLength() + pos; 00118 } 00119 MESegment* s = MSGlobals::gMesoNet->getSegmentForEdge(clane->getEdge()); 00120 MESegment* prev = s; 00121 SUMOReal cpos = 0; 00122 while (cpos + prev->getLength() < pos && s != 0) { 00123 prev = s; 00124 cpos += s->getLength(); 00125 s = s->getNextSegment(); 00126 } 00127 SUMOReal rpos = pos - cpos; //-prev->getLength(); 00128 if (rpos > prev->getLength() || rpos < 0) { 00129 if (friendlyPos) { 00130 rpos = prev->getLength() - (SUMOReal) 0.1; 00131 } else { 00132 throw InvalidArgument("The position of detector '" + id + "' lies beyond the lane's '" + lane + "' length."); 00133 } 00134 } 00135 MEInductLoop* loop = 00136 createMEInductLoop(id, prev, rpos); 00137 myNet.getDetectorControl().add(SUMO_TAG_INDUCTION_LOOP, loop, device, splInterval); 00138 } 00139 #endif 00140 } 00141 00142 00143 void 00144 NLDetectorBuilder::buildInstantInductLoop(const std::string& id, 00145 const std::string& lane, SUMOReal pos, 00146 OutputDevice& device, bool friendlyPos) throw(InvalidArgument) { 00147 // get and check the lane 00148 MSLane* clane = getLaneChecking(lane, SUMO_TAG_INSTANT_INDUCTION_LOOP, id); 00149 // get and check the position 00150 pos = getPositionChecking(pos, clane, friendlyPos, id); 00151 // build the loop 00152 MSDetectorFileOutput* loop = createInstantInductLoop(id, clane, pos, device); 00153 // add the file output 00154 myNet.getDetectorControl().add(SUMO_TAG_INDUCTION_LOOP, loop); 00155 } 00156 00157 00158 void 00159 NLDetectorBuilder::buildE2Detector(const std::string& id, 00160 const std::string& lane, SUMOReal pos, SUMOReal length, 00161 bool cont, int splInterval, 00162 OutputDevice& device, 00163 SUMOTime haltingTimeThreshold, 00164 SUMOReal haltingSpeedThreshold, 00165 SUMOReal jamDistThreshold, bool friendlyPos) throw(InvalidArgument) { 00166 checkSampleInterval(splInterval, SUMO_TAG_E2DETECTOR, id); 00167 MSLane* clane = getLaneChecking(lane, SUMO_TAG_E2DETECTOR, id); 00168 // check whether the detector may lie over more than one lane 00169 MSDetectorFileOutput* det = 0; 00170 if (!cont) { 00171 convUncontE2PosLength(id, clane, pos, length, friendlyPos); 00172 det = buildSingleLaneE2Det(id, DU_USER_DEFINED, clane, pos, length, haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold); 00173 myNet.getDetectorControl().add(SUMO_TAG_LANE_AREA_DETECTOR, det, device, splInterval); 00174 } else { 00175 convContE2PosLength(id, clane, pos, length, friendlyPos); 00176 det = buildMultiLaneE2Det(id, DU_USER_DEFINED, clane, pos, length, haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold); 00177 myNet.getDetectorControl().add(SUMO_TAG_LANE_AREA_DETECTOR, det, device, splInterval); 00178 } 00179 } 00180 00181 00182 void 00183 NLDetectorBuilder::buildE2Detector(const std::string& id, 00184 const std::string& lane, SUMOReal pos, SUMOReal length, 00185 bool cont, 00186 MSTLLogicControl::TLSLogicVariants& tlls, 00187 OutputDevice& device, 00188 SUMOTime haltingTimeThreshold, 00189 SUMOReal haltingSpeedThreshold, 00190 SUMOReal jamDistThreshold, bool friendlyPos) throw(InvalidArgument) { 00191 if (tlls.getActive() == 0) { 00192 throw InvalidArgument("The detector '" + id + "' refers to the unknown lsa."); 00193 } 00194 MSLane* clane = getLaneChecking(lane, SUMO_TAG_E2DETECTOR, id); 00195 // check whether the detector may lie over more than one lane 00196 MSDetectorFileOutput* det = 0; 00197 if (!cont) { 00198 convUncontE2PosLength(id, clane, pos, length, friendlyPos); 00199 det = buildSingleLaneE2Det(id, DU_USER_DEFINED, clane, pos, length, haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold); 00200 myNet.getDetectorControl().add(SUMO_TAG_LANE_AREA_DETECTOR, det); 00201 } else { 00202 convContE2PosLength(id, clane, pos, length, friendlyPos); 00203 det = buildMultiLaneE2Det(id, DU_USER_DEFINED, clane, pos, length, haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold); 00204 myNet.getDetectorControl().add(SUMO_TAG_LANE_AREA_DETECTOR, det); 00205 } 00206 // add the file output 00207 new Command_SaveTLCoupledDet(tlls, det, myNet.getCurrentTimeStep(), device); 00208 } 00209 00210 00211 void 00212 NLDetectorBuilder::buildE2Detector(const std::string& id, 00213 const std::string& lane, SUMOReal pos, SUMOReal length, 00214 bool cont, 00215 MSTLLogicControl::TLSLogicVariants& tlls, 00216 const std::string& tolane, 00217 OutputDevice& device, 00218 SUMOTime haltingTimeThreshold, 00219 SUMOReal haltingSpeedThreshold, 00220 SUMOReal jamDistThreshold, bool friendlyPos) throw(InvalidArgument) { 00221 if (tlls.getActive() == 0) { 00222 throw InvalidArgument("The detector '" + id + "' refers to the unknown lsa."); 00223 } 00224 MSLane* clane = getLaneChecking(lane, SUMO_TAG_E2DETECTOR, id); 00225 MSLane* ctoLane = getLaneChecking(tolane, SUMO_TAG_E2DETECTOR, id); 00226 MSLink* link = MSLinkContHelper::getConnectingLink(*clane, *ctoLane); 00227 if (link == 0) { 00228 throw InvalidArgument( 00229 "The detector output can not be build as no connection between lanes '" 00230 + lane + "' and '" + tolane + "' exists."); 00231 } 00232 if (pos < 0) { 00233 pos = -pos; 00234 } 00235 // check whether the detector may lie over more than one lane 00236 MSDetectorFileOutput* det = 0; 00237 if (!cont) { 00238 convUncontE2PosLength(id, clane, pos, length, friendlyPos); 00239 det = buildSingleLaneE2Det(id, DU_USER_DEFINED, clane, pos, length, haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold); 00240 myNet.getDetectorControl().add(SUMO_TAG_LANE_AREA_DETECTOR, det); 00241 } else { 00242 convContE2PosLength(id, clane, pos, length, friendlyPos); 00243 det = buildMultiLaneE2Det(id, DU_USER_DEFINED, clane, pos, length, haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold); 00244 myNet.getDetectorControl().add(SUMO_TAG_LANE_AREA_DETECTOR, det); 00245 } 00246 // add the file output 00247 new Command_SaveTLCoupledLaneDet(tlls, det, myNet.getCurrentTimeStep(), device, link); 00248 } 00249 00250 00251 void 00252 NLDetectorBuilder::convUncontE2PosLength(const std::string& id, MSLane* clane, 00253 SUMOReal& pos, SUMOReal& length, 00254 bool friendlyPos) throw(InvalidArgument) { 00255 // get and check the position 00256 pos = getPositionChecking(pos, clane, friendlyPos, id); 00257 // check length 00258 if (length < 0) { 00259 length = clane->getLength() + length; 00260 } 00261 if (length + pos > clane->getLength()) { 00262 if (friendlyPos) { 00263 length = clane->getLength() - pos - (SUMOReal) 0.1; 00264 } else { 00265 throw InvalidArgument("The length of detector '" + id + "' lies beyond the lane's '" + clane->getID() + "' length."); 00266 } 00267 } 00268 if (length < 0) { 00269 if (friendlyPos) { 00270 length = (SUMOReal) 0.1; 00271 } else { 00272 throw InvalidArgument("The length of detector '" + id + "' is almost 0."); 00273 } 00274 } 00275 } 00276 00277 00278 void 00279 NLDetectorBuilder::convContE2PosLength(const std::string& id, MSLane* clane, 00280 SUMOReal& pos, SUMOReal& /*length*/, 00281 bool friendlyPos) throw(InvalidArgument) { 00282 // get and check the position 00283 pos = getPositionChecking(pos, clane, friendlyPos, id); 00284 // length will be kept as is 00285 } 00286 00287 00288 void 00289 NLDetectorBuilder::beginE3Detector(const std::string& id, 00290 OutputDevice& device, int splInterval, 00291 SUMOReal haltingSpeedThreshold, 00292 SUMOTime haltingTimeThreshold) throw(InvalidArgument) { 00293 checkSampleInterval(splInterval, SUMO_TAG_E3DETECTOR, id); 00294 myE3Definition = new E3DetectorDefinition(id, device, haltingSpeedThreshold, haltingTimeThreshold, splInterval); 00295 } 00296 00297 00298 void 00299 NLDetectorBuilder::addE3Entry(const std::string& lane, 00300 SUMOReal pos, bool friendlyPos) throw(InvalidArgument) { 00301 if (myE3Definition == 0) { 00302 return; 00303 } 00304 MSLane* clane = getLaneChecking(lane, SUMO_TAG_E3DETECTOR, myE3Definition->myID); 00305 // get and check the position 00306 pos = getPositionChecking(pos, clane, friendlyPos, myE3Definition->myID); 00307 // build and save the entry 00308 myE3Definition->myEntries.push_back(MSCrossSection(clane, pos)); 00309 } 00310 00311 00312 void 00313 NLDetectorBuilder::addE3Exit(const std::string& lane, 00314 SUMOReal pos, bool friendlyPos) throw(InvalidArgument) { 00315 if (myE3Definition == 0) { 00316 return; 00317 } 00318 MSLane* clane = getLaneChecking(lane, SUMO_TAG_E3DETECTOR, myE3Definition->myID); 00319 // get and check the position 00320 pos = getPositionChecking(pos, clane, friendlyPos, myE3Definition->myID); 00321 // build and save the exit 00322 myE3Definition->myExits.push_back(MSCrossSection(clane, pos)); 00323 } 00324 00325 00326 std::string 00327 NLDetectorBuilder::getCurrentE3ID() const { 00328 if (myE3Definition == 0) { 00329 return "<unknown>"; 00330 } 00331 return myE3Definition->myID; 00332 } 00333 00334 00335 void 00336 NLDetectorBuilder::endE3Detector() throw(InvalidArgument) { 00337 if (myE3Definition == 0) { 00338 return; 00339 } 00340 MSDetectorFileOutput* det = createE3Detector(myE3Definition->myID, 00341 myE3Definition->myEntries, myE3Definition->myExits, 00342 myE3Definition->myHaltingSpeedThreshold, myE3Definition->myHaltingTimeThreshold); 00343 // add to net 00344 myNet.getDetectorControl().add(SUMO_TAG_ENTRY_EXIT_DETECTOR, det, myE3Definition->myDevice, myE3Definition->mySampleInterval); 00345 // clean up 00346 delete myE3Definition; 00347 myE3Definition = 0; 00348 } 00349 00350 00351 void 00352 NLDetectorBuilder::buildVTypeProbe(const std::string& id, 00353 const std::string& vtype, SUMOTime frequency, 00354 OutputDevice& device) throw(InvalidArgument) { 00355 checkSampleInterval(frequency, SUMO_TAG_VTYPEPROBE, id); 00356 new MSVTypeProbe(id, vtype, device, frequency); 00357 } 00358 00359 00360 void 00361 NLDetectorBuilder::buildRouteProbe(const std::string& id, const std::string& edge, 00362 SUMOTime frequency, SUMOTime begin, 00363 OutputDevice& device) throw(InvalidArgument) { 00364 checkSampleInterval(frequency, SUMO_TAG_ROUTEPROBE, id); 00365 MSEdge* e = getEdgeChecking(edge, SUMO_TAG_ROUTEPROBE, id); 00366 MSRouteProbe* probe = new MSRouteProbe(id, e, begin); 00367 // add the file output 00368 myNet.getDetectorControl().add(SUMO_TAG_ROUTEPROBE, probe, device, frequency, begin); 00369 } 00370 00371 00372 // ------------------- 00373 MSDetectorFileOutput* 00374 NLDetectorBuilder::buildSingleLaneE2Det(const std::string& id, 00375 DetectorUsage usage, 00376 MSLane* lane, SUMOReal pos, SUMOReal length, 00377 SUMOTime haltingTimeThreshold, 00378 SUMOReal haltingSpeedThreshold, 00379 SUMOReal jamDistThreshold) { 00380 return createSingleLaneE2Detector(id, usage, lane, pos, 00381 length, haltingTimeThreshold, haltingSpeedThreshold, 00382 jamDistThreshold); 00383 } 00384 00385 00386 MSDetectorFileOutput* 00387 NLDetectorBuilder::buildMultiLaneE2Det(const std::string& id, DetectorUsage usage, 00388 MSLane* lane, SUMOReal pos, SUMOReal length, 00389 SUMOTime haltingTimeThreshold, 00390 SUMOReal haltingSpeedThreshold, 00391 SUMOReal jamDistThreshold) { 00392 MSDetectorFileOutput* ret = createMultiLaneE2Detector(id, usage, 00393 lane, pos, haltingTimeThreshold, haltingSpeedThreshold, 00394 jamDistThreshold); 00395 static_cast<MS_E2_ZS_CollectorOverLanes*>(ret)->init(lane, length); 00396 return ret; 00397 } 00398 00399 00400 MSDetectorFileOutput* 00401 NLDetectorBuilder::createInductLoop(const std::string& id, 00402 MSLane* lane, SUMOReal pos, bool splitByType) { 00403 return new MSInductLoop(id, lane, pos, splitByType); 00404 } 00405 00406 00407 MSDetectorFileOutput* 00408 NLDetectorBuilder::createInstantInductLoop(const std::string& id, 00409 MSLane* lane, SUMOReal pos, OutputDevice& od) { 00410 return new MSInstantInductLoop(id, od, lane, pos); 00411 } 00412 00413 00414 #ifdef HAVE_MESOSIM 00415 MEInductLoop* 00416 NLDetectorBuilder::createMEInductLoop(const std::string& id, 00417 MESegment* s, SUMOReal pos) { 00418 return new MEInductLoop(id, s, pos); 00419 } 00420 #endif 00421 00422 00423 MSDetectorFileOutput* 00424 NLDetectorBuilder::createSingleLaneE2Detector(const std::string& id, 00425 DetectorUsage usage, MSLane* lane, SUMOReal pos, SUMOReal length, 00426 SUMOTime haltingTimeThreshold, SUMOReal haltingSpeedThreshold, SUMOReal jamDistThreshold) { 00427 return new MSE2Collector(id, usage, lane, pos, length, haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold); 00428 } 00429 00430 00431 MSDetectorFileOutput* 00432 NLDetectorBuilder::createMultiLaneE2Detector(const std::string& id, 00433 DetectorUsage usage, MSLane* lane, SUMOReal pos, 00434 SUMOTime haltingTimeThreshold, SUMOReal haltingSpeedThreshold, SUMOReal jamDistThreshold) { 00435 return new MS_E2_ZS_CollectorOverLanes(id, usage, lane, pos, haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold); 00436 } 00437 00438 00439 MSDetectorFileOutput* 00440 NLDetectorBuilder::createE3Detector(const std::string& id, 00441 const CrossSectionVector& entries, 00442 const CrossSectionVector& exits, 00443 SUMOReal haltingSpeedThreshold, 00444 SUMOTime haltingTimeThreshold) { 00445 return new MSE3Collector(id, entries, exits, haltingSpeedThreshold, haltingTimeThreshold); 00446 } 00447 00448 00449 SUMOReal 00450 NLDetectorBuilder::getPositionChecking(SUMOReal pos, MSLane* lane, bool friendlyPos, 00451 const std::string& detid) throw(InvalidArgument) { 00452 // check whether it is given from the end 00453 if (pos < 0) { 00454 pos = lane->getLength() + pos; 00455 } 00456 // check whether it is on the lane 00457 if (pos > lane->getLength()) { 00458 if (friendlyPos) { 00459 pos = lane->getLength() - (SUMOReal) 0.1; 00460 } else { 00461 throw InvalidArgument("The position of detector '" + detid + "' lies beyond the lane's '" + lane->getID() + "' length."); 00462 } 00463 } 00464 if (pos < 0) { 00465 if (friendlyPos) { 00466 pos = (SUMOReal) 0.1; 00467 } else { 00468 throw InvalidArgument("The position of detector '" + detid + "' lies beyond the lane's '" + lane->getID() + "' length."); 00469 } 00470 } 00471 return pos; 00472 } 00473 00474 00475 void 00476 NLDetectorBuilder::createEdgeLaneMeanData(const std::string& id, SUMOTime frequency, 00477 SUMOTime begin, SUMOTime end, const std::string& type, 00478 const bool useLanes, const bool withEmpty, const bool withInternal, const bool trackVehicles, 00479 const SUMOReal maxTravelTime, const SUMOReal minSamples, 00480 const SUMOReal haltSpeed, const std::string& vTypes, 00481 OutputDevice& device) throw(InvalidArgument) { 00482 if (begin < 0) { 00483 throw InvalidArgument("Negative begin time for meandata dump '" + id + "'."); 00484 } 00485 if (end < 0) { 00486 end = SUMOTime_MAX; 00487 } 00488 if (end <= begin) { 00489 throw InvalidArgument("End before or at begin for meandata dump '" + id + "'."); 00490 } 00491 std::set<std::string> vt; 00492 StringTokenizer st(vTypes); 00493 while (st.hasNext()) { 00494 vt.insert(st.next()); 00495 } 00496 MSMeanData* det = 0; 00497 if (type == "" || type == "performance" || type == "traffic") { 00498 det = new MSMeanData_Net(id, begin, end, useLanes, withEmpty, withInternal, trackVehicles, 00499 maxTravelTime, minSamples, haltSpeed, vt); 00500 } else if (type == "hbefa") { 00501 det = new MSMeanData_HBEFA(id, begin, end, useLanes, withEmpty, withInternal, trackVehicles, 00502 maxTravelTime, minSamples, vt); 00503 } else if (type == "harmonoise") { 00504 det = new MSMeanData_Harmonoise(id, begin, end, useLanes, withEmpty, withInternal, trackVehicles, 00505 maxTravelTime, minSamples, vt); 00506 } else { 00507 throw InvalidArgument("Invalid type '" + type + "' for meandata dump '" + id + "'."); 00508 } 00509 if (det != 0) { 00510 if (frequency < 0) { 00511 frequency = end - begin; 00512 } 00513 MSNet::getInstance()->getDetectorControl().add(det, device, frequency, begin); 00514 } 00515 } 00516 00517 00518 00519 00520 // ------ Value checking/adapting methods ------ 00521 MSEdge* 00522 NLDetectorBuilder::getEdgeChecking(const std::string& edgeID, SumoXMLTag type, 00523 const std::string& detid) throw(InvalidArgument) { 00524 // get and check the lane 00525 MSEdge* edge = MSEdge::dictionary(edgeID); 00526 if (edge == 0) { 00527 throw InvalidArgument("The lane with the id '" + edgeID + "' is not known (while building " + toString(type) + " '" + detid + "')."); 00528 } 00529 return edge; 00530 } 00531 00532 00533 MSLane* 00534 NLDetectorBuilder::getLaneChecking(const std::string& laneID, SumoXMLTag type, 00535 const std::string& detid) throw(InvalidArgument) { 00536 // get and check the lane 00537 MSLane* lane = MSLane::dictionary(laneID); 00538 if (lane == 0) { 00539 throw InvalidArgument("The lane with the id '" + laneID + "' is not known (while building " + toString(type) + " '" + detid + "')."); 00540 } 00541 return lane; 00542 } 00543 00544 00545 void 00546 NLDetectorBuilder::checkSampleInterval(int splInterval, SumoXMLTag type, const std::string& id) throw(InvalidArgument) { 00547 if (splInterval < 0) { 00548 throw InvalidArgument("Negative sampling frequency (in " + toString(type) + " '" + id + "')."); 00549 } 00550 if (splInterval == 0) { 00551 throw InvalidArgument("Sampling frequency must not be zero (in " + toString(type) + " '" + id + "')."); 00552 } 00553 } 00554 00555 00556 /****************************************************************************/ 00557