SUMO - Simulation of Urban MObility

TraCIServerAPI_TLS.cpp

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