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