|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00007 // APIs for getting/setting traffic light values via TraCI 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 "TraCIConstants.h" 00031 #include <microsim/traffic_lights/MSTLLogicControl.h> 00032 #include <microsim/MSLane.h> 00033 #include "TraCIServerAPI_TLS.h" 00034 00035 #ifdef CHECK_MEMORY_LEAKS 00036 #include <foreign/nvwa/debug_new.h> 00037 #endif // CHECK_MEMORY_LEAKS 00038 00039 00040 // =========================================================================== 00041 // used namespaces 00042 // =========================================================================== 00043 using namespace traci; 00044 00045 00046 // =========================================================================== 00047 // method definitions 00048 // =========================================================================== 00049 bool 00050 TraCIServerAPI_TLS::processGet(TraCIServer& server, tcpip::Storage& inputStorage, 00051 tcpip::Storage& outputStorage) { 00052 std::string warning = ""; // additional description for response 00053 // variable & id 00054 int variable = inputStorage.readUnsignedByte(); 00055 std::string id = inputStorage.readString(); 00056 // check variable 00057 if (variable!=ID_LIST&&variable!=TL_RED_YELLOW_GREEN_STATE&&variable!=TL_COMPLETE_DEFINITION_RYG 00058 &&variable!=TL_CONTROLLED_LANES&&variable!=TL_CONTROLLED_LINKS 00059 &&variable!=TL_CURRENT_PHASE&&variable!=TL_CURRENT_PROGRAM 00060 &&variable!=TL_NEXT_SWITCH&&variable!=TL_PHASE_DURATION&&variable!=ID_COUNT) { 00061 server.writeStatusCmd(CMD_GET_TL_VARIABLE, RTYPE_ERR, "Get TLS Variable: unsupported variable specified", outputStorage); 00062 return false; 00063 } 00064 // begin response building 00065 tcpip::Storage tempMsg; 00066 // response-code, variableID, objectID 00067 tempMsg.writeUnsignedByte(RESPONSE_GET_TL_VARIABLE); 00068 tempMsg.writeUnsignedByte(variable); 00069 tempMsg.writeString(id); 00070 if (variable==ID_LIST) { 00071 std::vector<std::string> ids = MSNet::getInstance()->getTLSControl().getAllTLIds(); 00072 tempMsg.writeUnsignedByte(TYPE_STRINGLIST); 00073 tempMsg.writeStringList(ids); 00074 } else if (variable==ID_COUNT) { 00075 std::vector<std::string> ids = MSNet::getInstance()->getTLSControl().getAllTLIds(); 00076 tempMsg.writeUnsignedByte(TYPE_INTEGER); 00077 tempMsg.writeInt((int) ids.size()); 00078 } else { 00079 if (!MSNet::getInstance()->getTLSControl().knows(id)) { 00080 server.writeStatusCmd(CMD_GET_TL_VARIABLE, RTYPE_ERR, "Traffic light '" + id + "' is not known", outputStorage); 00081 return false; 00082 } 00083 MSTLLogicControl::TLSLogicVariants& vars = MSNet::getInstance()->getTLSControl().get(id); 00084 switch (variable) { 00085 case ID_LIST: 00086 break; 00087 case TL_RED_YELLOW_GREEN_STATE: { 00088 tempMsg.writeUnsignedByte(TYPE_STRING); 00089 std::string state = vars.getActive()->getCurrentPhaseDef().getState(); 00090 tempMsg.writeString(state); 00091 } 00092 break; 00093 case TL_COMPLETE_DEFINITION_RYG: { 00094 std::vector<MSTrafficLightLogic*> logics = vars.getAllLogics(); 00095 tempMsg.writeUnsignedByte(TYPE_COMPOUND); 00096 tcpip::Storage tempContent; 00097 unsigned int cnt = 0; 00098 tempContent.writeUnsignedByte(TYPE_INTEGER); 00099 tempContent.writeInt((int) logics.size()); 00100 ++cnt; 00101 for (unsigned int i=0; i<logics.size(); ++i) { 00102 MSTrafficLightLogic* logic = logics[i]; 00103 tempContent.writeUnsignedByte(TYPE_STRING); 00104 tempContent.writeString(logic->getProgramID()); 00105 ++cnt; 00106 // type (always 0 by now) 00107 tempContent.writeUnsignedByte(TYPE_INTEGER); 00108 tempContent.writeInt(0); 00109 ++cnt; 00110 // subparameter (always 0 by now) 00111 tempContent.writeUnsignedByte(TYPE_COMPOUND); 00112 tempContent.writeInt(0); 00113 ++cnt; 00114 // (current) phase index 00115 tempContent.writeUnsignedByte(TYPE_INTEGER); 00116 tempContent.writeInt((int) logic->getCurrentPhaseIndex()); 00117 ++cnt; 00118 // phase number 00119 unsigned int phaseNo = logic->getPhaseNumber(); 00120 tempContent.writeUnsignedByte(TYPE_INTEGER); 00121 tempContent.writeInt((int) phaseNo); 00122 ++cnt; 00123 for (unsigned int j=0; j<phaseNo; ++j) { 00124 MSPhaseDefinition phase = logic->getPhase(j); 00125 tempContent.writeUnsignedByte(TYPE_INTEGER); 00126 tempContent.writeInt(phase.duration); 00127 ++cnt; 00128 tempContent.writeUnsignedByte(TYPE_INTEGER); 00129 tempContent.writeInt(phase.minDuration); 00130 ++cnt; // not implemented 00131 tempContent.writeUnsignedByte(TYPE_INTEGER); 00132 tempContent.writeInt(phase.maxDuration); 00133 ++cnt; // not implemented 00134 const std::string& state = phase.getState(); 00135 //unsigned int linkNo = (unsigned int)(vars.getActive()->getLinks().size()); 00136 tempContent.writeUnsignedByte(TYPE_STRING); 00137 tempContent.writeString(state); 00138 ++cnt; 00139 } 00140 } 00141 tempMsg.writeInt((int) cnt); 00142 tempMsg.writeStorage(tempContent); 00143 } 00144 break; 00145 case TL_CONTROLLED_LANES: { 00146 const MSTrafficLightLogic::LaneVectorVector& lanes = vars.getActive()->getLanes(); 00147 tempMsg.writeUnsignedByte(TYPE_STRINGLIST); 00148 std::vector<std::string> laneIDs; 00149 for (MSTrafficLightLogic::LaneVectorVector::const_iterator i=lanes.begin(); i!=lanes.end(); ++i) { 00150 const MSTrafficLightLogic::LaneVector& llanes = (*i); 00151 for (MSTrafficLightLogic::LaneVector::const_iterator j=llanes.begin(); j!=llanes.end(); ++j) { 00152 laneIDs.push_back((*j)->getID()); 00153 } 00154 } 00155 tempMsg.writeStringList(laneIDs); 00156 } 00157 break; 00158 case TL_CONTROLLED_LINKS: { 00159 const MSTrafficLightLogic::LaneVectorVector& lanes = vars.getActive()->getLanes(); 00160 const MSTrafficLightLogic::LinkVectorVector& links = vars.getActive()->getLinks(); 00161 // 00162 tempMsg.writeUnsignedByte(TYPE_COMPOUND); 00163 tcpip::Storage tempContent; 00164 unsigned int cnt = 0; 00165 tempContent.writeUnsignedByte(TYPE_INTEGER); 00166 unsigned int no = (unsigned int) lanes.size(); 00167 tempContent.writeInt((int) no); 00168 for (unsigned int i=0; i<no; ++i) { 00169 const MSTrafficLightLogic::LaneVector& llanes = lanes[i]; 00170 const MSTrafficLightLogic::LinkVector& llinks = links[i]; 00171 // number of links controlled by this signal (signal i) 00172 tempContent.writeUnsignedByte(TYPE_INTEGER); 00173 unsigned int no2 = (unsigned int) llanes.size(); 00174 tempContent.writeInt((int) no2); 00175 ++cnt; 00176 for (unsigned int j=0; j<no2; ++j) { 00177 MSLink* link = llinks[j]; 00178 std::vector<std::string> def; 00179 // incoming lane 00180 def.push_back(llanes[j]->getID()); 00181 // approached non-internal lane (if any) 00182 def.push_back(link->getLane()!=0 ? link->getLane()->getID() : ""); 00183 // approached "via", internal lane (if any) 00184 #ifdef HAVE_INTERNAL_LANES 00185 def.push_back(link->getViaLane()!=0 ? link->getViaLane()->getID() : ""); 00186 #else 00187 def.push_back(""); 00188 #endif 00189 tempContent.writeUnsignedByte(TYPE_STRINGLIST); 00190 tempContent.writeStringList(def); 00191 ++cnt; 00192 } 00193 } 00194 tempMsg.writeInt((int) cnt); 00195 tempMsg.writeStorage(tempContent); 00196 } 00197 break; 00198 case TL_CURRENT_PHASE: 00199 tempMsg.writeUnsignedByte(TYPE_INTEGER); 00200 tempMsg.writeInt((int) vars.getActive()->getCurrentPhaseIndex()); 00201 break; 00202 case TL_CURRENT_PROGRAM: 00203 tempMsg.writeUnsignedByte(TYPE_STRING); 00204 tempMsg.writeString(vars.getActive()->getProgramID()); 00205 break; 00206 case TL_PHASE_DURATION: 00207 tempMsg.writeUnsignedByte(TYPE_INTEGER); 00208 tempMsg.writeInt((int) vars.getActive()->getCurrentPhaseDef().duration); 00209 break; 00210 case TL_NEXT_SWITCH: 00211 tempMsg.writeUnsignedByte(TYPE_INTEGER); 00212 tempMsg.writeInt((int) vars.getActive()->getNextSwitchTime()); 00213 break; 00214 case TL_CONTROLLED_JUNCTIONS: { 00215 } 00216 break; 00217 default: 00218 break; 00219 } 00220 } 00221 server.writeStatusCmd(CMD_GET_TL_VARIABLE, RTYPE_OK, warning, outputStorage); 00222 server.writeResponseWithLength(outputStorage, tempMsg); 00223 return true; 00224 } 00225 00226 00227 bool 00228 TraCIServerAPI_TLS::processSet(TraCIServer& server, tcpip::Storage& inputStorage, 00229 tcpip::Storage& outputStorage) { 00230 std::string warning = ""; // additional description for response 00231 // variable 00232 int variable = inputStorage.readUnsignedByte(); 00233 if (variable!=TL_PHASE_INDEX&&variable!=TL_PROGRAM 00234 &&variable!=TL_PHASE_DURATION&&variable!=TL_RED_YELLOW_GREEN_STATE&&variable!=TL_COMPLETE_PROGRAM_RYG) { 00235 server.writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "Change TLS State: unsupported variable specified", outputStorage); 00236 return false; 00237 } 00238 std::string id = inputStorage.readString(); 00239 if (!MSNet::getInstance()->getTLSControl().knows(id)) { 00240 server.writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "Traffic light '" + id + "' is not known", outputStorage); 00241 return false; 00242 } 00243 MSTLLogicControl& tlsControl = MSNet::getInstance()->getTLSControl(); 00244 SUMOTime cTime = MSNet::getInstance()->getCurrentTimeStep(); 00245 MSTLLogicControl::TLSLogicVariants& vars = tlsControl.get(id); 00246 int valueDataType = inputStorage.readUnsignedByte(); 00247 switch (variable) { 00248 case TL_PHASE_INDEX: { 00249 if (valueDataType!=TYPE_INTEGER) { 00250 server.writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "The phase index must be given as an integer.", outputStorage); 00251 return false; 00252 } 00253 int index = inputStorage.readInt(); 00254 if (index<0||vars.getActive()->getPhaseNumber()<=(unsigned int)index) { 00255 server.writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "The phase index is not in the allowed range.", outputStorage); 00256 return false; 00257 } 00258 int duration = vars.getActive()->getPhase(index).duration; 00259 vars.getActive()->changeStepAndDuration(tlsControl, cTime, index, duration); 00260 } 00261 break; 00262 case TL_PROGRAM: { 00263 if (valueDataType!=TYPE_STRING) { 00264 server.writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "The program must be given as a string.", outputStorage); 00265 return false; 00266 } 00267 std::string subID = inputStorage.readString(); 00268 try { 00269 vars.switchTo(tlsControl, subID); 00270 } catch (ProcessError& e) { 00271 server.writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, e.what(), outputStorage); 00272 return false; 00273 } 00274 } 00275 break; 00276 case TL_PHASE_DURATION: { 00277 if (valueDataType!=TYPE_INTEGER) { 00278 server.writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "The phase duration must be given as an integer.", outputStorage); 00279 return false; 00280 } 00281 int duration = inputStorage.readInt(); 00282 int index = vars.getActive()->getCurrentPhaseIndex(); 00283 vars.getActive()->changeStepAndDuration(tlsControl, cTime, index, duration); 00284 } 00285 break; 00286 case TL_RED_YELLOW_GREEN_STATE: { 00287 if (valueDataType!=TYPE_STRING) { 00288 server.writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "The phase must be given as a string.", outputStorage); 00289 return false; 00290 } 00291 // build only once... 00292 std::string state = inputStorage.readString(); 00293 MSPhaseDefinition* phase = new MSPhaseDefinition(DELTA_T, state); 00294 std::vector<MSPhaseDefinition*> phases; 00295 phases.push_back(phase); 00296 if (vars.getLogic("online")==0) { 00297 MSTrafficLightLogic* logic = new MSSimpleTrafficLightLogic(tlsControl, id, "online", phases, 0, cTime+DELTA_T); 00298 vars.addLogic("online", logic, true, true); 00299 vars.getActive()->setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep()); 00300 vars.executeOnSwitchActions(); 00301 } else { 00302 MSPhaseDefinition nphase(DELTA_T, state); 00303 *(static_cast<MSSimpleTrafficLightLogic*>(vars.getLogic("online"))->getPhases()[0]) = nphase; 00304 vars.getActive()->setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep()); 00305 vars.executeOnSwitchActions(); 00306 } 00307 } 00308 break; 00309 case TL_COMPLETE_PROGRAM_RYG: { 00310 if (valueDataType!=TYPE_COMPOUND) { 00311 server.writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "A compound object is needed for setting a new program.", outputStorage); 00312 return false; 00313 } 00314 //read itemNo 00315 inputStorage.readInt(); 00316 if (inputStorage.readUnsignedByte()!=TYPE_STRING) { 00317 server.writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "set program: 1. parameter (subid) must be a string.", outputStorage); 00318 return false; 00319 } 00320 std::string subid = inputStorage.readString(); 00321 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) { 00322 server.writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "set program: 2. parameter (type) must be an int.", outputStorage); 00323 return false; 00324 } 00325 //read type 00326 inputStorage.readInt(); 00327 if (inputStorage.readUnsignedByte()!=TYPE_COMPOUND) { 00328 server.writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "set program: 3. parameter (subparams) must be a compound object.", outputStorage); 00329 return false; 00330 } 00331 //read sublength 00332 inputStorage.readInt(); 00333 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) { 00334 server.writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "set program: 4. parameter (index) must be an int.", outputStorage); 00335 return false; 00336 } 00337 int index = inputStorage.readInt(); 00338 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) { 00339 server.writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "set program: 5. parameter (phase number) must be an int.", outputStorage); 00340 return false; 00341 } 00342 int phaseNo = inputStorage.readInt(); 00343 std::vector<MSPhaseDefinition*> phases; 00344 for (int j=0; j<phaseNo; ++j) { 00345 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) { 00346 server.writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "set program: 6.1. parameter (duration) must be an int.", outputStorage); 00347 return false; 00348 } 00349 int duration = inputStorage.readInt(); 00350 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) { 00351 server.writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "set program: 6.2. parameter (min duration) must be an int.", outputStorage); 00352 return false; 00353 } 00354 int minDuration = inputStorage.readInt(); 00355 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) { 00356 server.writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "set program: 6.3. parameter (max duration) must be an int.", outputStorage); 00357 return false; 00358 } 00359 int maxDuration = inputStorage.readInt(); 00360 if (inputStorage.readUnsignedByte()!=TYPE_STRING) { 00361 server.writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "set program: 6.4. parameter (phase) must be a string.", outputStorage); 00362 return false; 00363 } 00364 std::string state = inputStorage.readString(); 00365 MSPhaseDefinition* phase = new MSPhaseDefinition(duration, minDuration, maxDuration, state); 00366 phases.push_back(phase); 00367 } 00368 if (vars.getLogic(subid)==0) { 00369 MSTrafficLightLogic* logic = new MSSimpleTrafficLightLogic(tlsControl, id, subid, phases, index, 0); 00370 vars.addLogic(subid, logic, true, true); 00371 vars.getActive()->setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep()); 00372 vars.executeOnSwitchActions(); 00373 } else { 00374 static_cast<MSSimpleTrafficLightLogic*>(vars.getLogic(subid))->getPhases() = phases; 00375 vars.getActive()->setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep()); 00376 vars.executeOnSwitchActions(); 00377 } 00378 } 00379 break; 00380 default: 00381 break; 00382 } 00383 server.writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_OK, warning, outputStorage); 00384 return true; 00385 } 00386 00387 /****************************************************************************/ 00388