SUMO - Simulation of Urban MObility

TraCIServerAPI_TLS.cpp

Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines