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