SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00011 // Changes the speed allowed on a set of lanes 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 <utils/common/MsgHandler.h> 00037 #include <utils/common/WrappingCommand.h> 00038 #include <utils/xml/SUMOXMLDefinitions.h> 00039 #include <utils/common/UtilExceptions.h> 00040 #include <utils/xml/XMLSubSys.h> 00041 #include <utils/common/TplConvert.h> 00042 #include <microsim/MSEventControl.h> 00043 #include <microsim/MSLane.h> 00044 #include <microsim/MSNet.h> 00045 #include <microsim/MSEdge.h> 00046 #include "MSLaneSpeedTrigger.h" 00047 00048 #ifdef HAVE_MESOSIM 00049 #include <microsim/MSGlobals.h> 00050 #include <mesosim/MELoop.h> 00051 #include <mesosim/MESegment.h> 00052 #endif 00053 00054 #ifdef CHECK_MEMORY_LEAKS 00055 #include <foreign/nvwa/debug_new.h> 00056 #endif // CHECK_MEMORY_LEAKS 00057 00058 00059 // =========================================================================== 00060 // method definitions 00061 // =========================================================================== 00062 MSLaneSpeedTrigger::MSLaneSpeedTrigger(const std::string& id, 00063 const std::vector<MSLane*> &destLanes, 00064 const std::string& file) 00065 : MSTrigger(id), SUMOSAXHandler(file), 00066 myDestLanes(destLanes), myAmOverriding(false), myDidInit(false) { 00067 myCurrentSpeed = destLanes[0]->getMaxSpeed(); 00068 if (file != "") { 00069 if (!XMLSubSys::runParser(*this, file)) { 00070 throw ProcessError(); 00071 } 00072 if (!myDidInit) { 00073 init(); 00074 } 00075 } 00076 } 00077 00078 void 00079 MSLaneSpeedTrigger::init() { 00080 // set it to the right value 00081 // assert there is at least one 00082 if (myLoadedSpeeds.size() == 0) { 00083 myLoadedSpeeds.push_back(std::make_pair(100000, myCurrentSpeed)); 00084 } 00085 // set the process to the begin 00086 myCurrentEntry = myLoadedSpeeds.begin(); 00087 // pass previous time steps 00088 while ((*myCurrentEntry).first < MSNet::getInstance()->getCurrentTimeStep() && myCurrentEntry != myLoadedSpeeds.end()) { 00089 processCommand(true, MSNet::getInstance()->getCurrentTimeStep()); 00090 } 00091 00092 // add the processing to the event handler 00093 MSNet::getInstance()->getBeginOfTimestepEvents().addEvent( 00094 new WrappingCommand<MSLaneSpeedTrigger>(this, &MSLaneSpeedTrigger::execute), 00095 (*myCurrentEntry).first, MSEventControl::NO_CHANGE); 00096 myDidInit = true; 00097 } 00098 00099 00100 MSLaneSpeedTrigger::~MSLaneSpeedTrigger() {} 00101 00102 00103 SUMOTime 00104 MSLaneSpeedTrigger::execute(SUMOTime currentTime) { 00105 return processCommand(true, currentTime); 00106 } 00107 00108 00109 SUMOTime 00110 MSLaneSpeedTrigger::processCommand(bool move2next, SUMOTime currentTime) { 00111 UNUSED_PARAMETER(currentTime); 00112 std::vector<MSLane*>::iterator i; 00113 const SUMOReal speed = getCurrentSpeed(); 00114 for (i = myDestLanes.begin(); i != myDestLanes.end(); ++i) { 00115 #ifdef HAVE_MESOSIM 00116 if (MSGlobals::gUseMesoSim) { 00117 MESegment* first = MSGlobals::gMesoNet->getSegmentForEdge((*i)->getEdge()); 00118 while (first != 0) { 00119 first->setSpeed(speed, currentTime); 00120 first = first->getNextSegment(); 00121 } 00122 continue; 00123 } 00124 #endif 00125 (*i)->setMaxSpeed(speed); 00126 } 00127 if (!move2next) { 00128 // changed from the gui 00129 return 0; 00130 } 00131 if (myCurrentEntry != myLoadedSpeeds.end()) { 00132 ++myCurrentEntry; 00133 } 00134 if (myCurrentEntry != myLoadedSpeeds.end()) { 00135 return ((*myCurrentEntry).first) - ((*(myCurrentEntry - 1)).first); 00136 } else { 00137 return 0; 00138 } 00139 } 00140 00141 00142 void 00143 MSLaneSpeedTrigger::myStartElement(int element, 00144 const SUMOSAXAttributes& attrs) { 00145 // check whether the correct tag is read 00146 if (element != SUMO_TAG_STEP) { 00147 return; 00148 } 00149 // extract the values 00150 bool ok = true; 00151 SUMOTime next = attrs.getSUMOTimeReporting(SUMO_ATTR_TIME, getID().c_str(), ok); 00152 SUMOReal speed = attrs.getOptSUMORealReporting(SUMO_ATTR_SPEED, getID().c_str(), ok, -1); 00153 // check the values 00154 if (next < 0) { 00155 WRITE_ERROR("Wrong time in vss '" + getID() + "'."); 00156 return; 00157 } 00158 if (speed < 0) { 00159 WRITE_ERROR("Wrong speed in vss '" + getID() + "'."); 00160 return; 00161 } 00162 // set the values for the next step if they are valid 00163 if (myLoadedSpeeds.size() != 0 && myLoadedSpeeds.back().first == next) { 00164 WRITE_WARNING("Time " + time2string(next) + " was set twice for vss '" + getID() + "'; replacing first entry."); 00165 myLoadedSpeeds.back().second = speed; 00166 } else { 00167 myLoadedSpeeds.push_back(std::make_pair(next, speed)); 00168 } 00169 } 00170 00171 00172 void 00173 MSLaneSpeedTrigger::myEndElement(int element) { 00174 if (element == SUMO_TAG_VSS && !myDidInit) { 00175 init(); 00176 } 00177 } 00178 00179 00180 SUMOReal 00181 MSLaneSpeedTrigger::getDefaultSpeed() const { 00182 return myDefaultSpeed; 00183 } 00184 00185 00186 void 00187 MSLaneSpeedTrigger::setOverriding(bool val) { 00188 myAmOverriding = val; 00189 processCommand(false, MSNet::getInstance()->getCurrentTimeStep()); 00190 } 00191 00192 00193 void 00194 MSLaneSpeedTrigger::setOverridingValue(SUMOReal val) { 00195 mySpeedOverrideValue = val; 00196 processCommand(false, MSNet::getInstance()->getCurrentTimeStep()); 00197 } 00198 00199 00200 SUMOReal 00201 MSLaneSpeedTrigger::getLoadedSpeed() { 00202 if (myCurrentEntry != myLoadedSpeeds.begin()) { 00203 return (*(myCurrentEntry - 1)).second; 00204 } else { 00205 return (*myCurrentEntry).second; 00206 } 00207 } 00208 00209 00210 SUMOReal 00211 MSLaneSpeedTrigger::getCurrentSpeed() const { 00212 if (myAmOverriding) { 00213 return mySpeedOverrideValue; 00214 } else { 00215 // ok, maybe the first shall not yet be the valid one 00216 if (myCurrentEntry == myLoadedSpeeds.begin() && (*myCurrentEntry).first > MSNet::getInstance()->getCurrentTimeStep()) { 00217 return myDefaultSpeed; 00218 } 00219 // try the loaded 00220 if (myCurrentEntry != myLoadedSpeeds.end() && (*myCurrentEntry).first <= MSNet::getInstance()->getCurrentTimeStep()) { 00221 return (*myCurrentEntry).second; 00222 } else { 00223 return (*(myCurrentEntry - 1)).second; 00224 } 00225 } 00226 } 00227 00228 00229 /****************************************************************************/ 00230