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