00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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 "TraCIServerAPIHelper.h"
00034 #include "TraCIServerAPI_TLS.h"
00035
00036 #ifdef CHECK_MEMORY_LEAKS
00037 #include <foreign/nvwa/debug_new.h>
00038 #endif // CHECK_MEMORY_LEAKS
00039
00040
00041
00042
00043
00044 using namespace std;
00045 using namespace traci;
00046 using namespace tcpip;
00047
00048
00049
00050
00051
00052 bool TraCIServerAPI_TLS::myHaveWarnedAboutDeprecatedPhases = false;
00053
00054
00055
00056
00057
00058 bool
00059 TraCIServerAPI_TLS::processGet(tcpip::Storage &inputStorage,
00060 tcpip::Storage &outputStorage,
00061 bool withStatus) throw(TraCIException) {
00062 std::string warning = "";
00063
00064 int variable = inputStorage.readUnsignedByte();
00065 std::string id = inputStorage.readString();
00066
00067 if (variable!=ID_LIST&&variable!=TL_RED_YELLOW_GREEN_STATE&&variable!=TL_PHASE_BRAKE_YELLOW_STATE
00068 &&variable!=TL_COMPLETE_DEFINITION_PBY&&variable!=TL_COMPLETE_DEFINITION_RYG
00069 &&variable!=TL_CONTROLLED_LANES&&variable!=TL_CONTROLLED_LINKS
00070 &&variable!=TL_CURRENT_PHASE&&variable!=TL_CURRENT_PROGRAM
00071 &&variable!=TL_NEXT_SWITCH&&variable!=TL_PHASE_DURATION) {
00072 TraCIServerAPIHelper::writeStatusCmd(CMD_GET_TL_VARIABLE, RTYPE_ERR, "Get TLS Variable: unsupported variable specified", outputStorage);
00073 return false;
00074 }
00075
00076 Storage tempMsg;
00077
00078 tempMsg.writeUnsignedByte(RESPONSE_GET_TL_VARIABLE);
00079 tempMsg.writeUnsignedByte(variable);
00080 tempMsg.writeString(id);
00081 if (variable==ID_LIST) {
00082 std::vector<std::string> ids = MSNet::getInstance()->getTLSControl().getAllTLIds();
00083 tempMsg.writeUnsignedByte(TYPE_STRINGLIST);
00084 tempMsg.writeStringList(ids);
00085 } else {
00086 if (!MSNet::getInstance()->getTLSControl().knows(id)) {
00087 TraCIServerAPIHelper::writeStatusCmd(CMD_GET_TL_VARIABLE, RTYPE_ERR, "Traffic light '" + id + "' is not known", outputStorage);
00088 return false;
00089 }
00090 MSTLLogicControl::TLSLogicVariants &vars = MSNet::getInstance()->getTLSControl().get(id);
00091 switch (variable) {
00092 case ID_LIST:
00093 break;
00094 case TL_RED_YELLOW_GREEN_STATE: {
00095 tempMsg.writeUnsignedByte(TYPE_STRING);
00096 std::string state = vars.getActive()->getCurrentPhaseDef().getState();
00097 tempMsg.writeString(state);
00098 }
00099 break;
00100 case TL_PHASE_BRAKE_YELLOW_STATE: {
00101 const std::string &state = vars.getActive()->getCurrentPhaseDef().getState();
00102 unsigned int linkNo = vars.getActive()->getLinks().size();
00103 tempMsg.writeUnsignedByte(TYPE_STRINGLIST);
00104 std::vector<std::string> phaseDef;
00105 phaseDef.push_back(MSPhaseDefinition::new2driveMask(state));
00106 phaseDef.push_back(MSPhaseDefinition::new2brakeMask(state));
00107 phaseDef.push_back(MSPhaseDefinition::new2yellowMask(state));
00108 tempMsg.writeStringList(phaseDef);
00109 if (!myHaveWarnedAboutDeprecatedPhases) {
00110 myHaveWarnedAboutDeprecatedPhases = true;
00111 warning = "Defining phases using drive/brake/yellow mask is deprecated. Move to states.";
00112 }
00113 }
00114 break;
00115 case TL_COMPLETE_DEFINITION_PBY: {
00116 std::vector<MSTrafficLightLogic*> logics = vars.getAllLogics();
00117 tempMsg.writeUnsignedByte(TYPE_COMPOUND);
00118 Storage tempContent;
00119 unsigned int cnt = 0;
00120 tempContent.writeUnsignedByte(TYPE_INTEGER);
00121 tempContent.writeInt((int) logics.size());
00122 ++cnt;
00123 for (unsigned int i=0; i<logics.size(); ++i) {
00124 MSTrafficLightLogic *logic = logics[i];
00125 tempContent.writeUnsignedByte(TYPE_STRING);
00126 tempContent.writeString(logic->getSubID());
00127 ++cnt;
00128
00129 tempContent.writeUnsignedByte(TYPE_INTEGER);
00130 tempContent.writeInt(0);
00131 ++cnt;
00132
00133 tempContent.writeUnsignedByte(TYPE_COMPOUND);
00134 tempContent.writeInt(0);
00135 ++cnt;
00136
00137 tempContent.writeUnsignedByte(TYPE_INTEGER);
00138 tempContent.writeInt((int) logic->getCurrentPhaseIndex());
00139 ++cnt;
00140
00141 unsigned int phaseNo = logic->getPhaseNumber();
00142 tempContent.writeUnsignedByte(TYPE_INTEGER);
00143 tempContent.writeInt((int) phaseNo);
00144 ++cnt;
00145 for (unsigned int j=0; j<phaseNo; ++j) {
00146 MSPhaseDefinition phase = logic->getPhase(j);
00147 tempContent.writeUnsignedByte(TYPE_INTEGER);
00148 tempContent.writeInt(phase.duration);
00149 ++cnt;
00150 tempContent.writeUnsignedByte(TYPE_INTEGER);
00151 tempContent.writeInt(phase.minDuration);
00152 ++cnt;
00153 tempContent.writeUnsignedByte(TYPE_INTEGER);
00154 tempContent.writeInt(phase.maxDuration);
00155 ++cnt;
00156 const std::string &state = phase.getState();
00157 unsigned int linkNo = vars.getActive()->getLinks().size();
00158 tempContent.writeUnsignedByte(TYPE_STRINGLIST);
00159 std::vector<std::string> phaseDef;
00160 phaseDef.push_back(MSPhaseDefinition::new2driveMask(state));
00161 phaseDef.push_back(MSPhaseDefinition::new2brakeMask(state));
00162 phaseDef.push_back(MSPhaseDefinition::new2yellowMask(state));
00163 tempContent.writeStringList(phaseDef);
00164 ++cnt;
00165 }
00166 }
00167 tempMsg.writeInt((int) cnt);
00168 tempMsg.writeStorage(tempContent);
00169 if (!myHaveWarnedAboutDeprecatedPhases) {
00170 myHaveWarnedAboutDeprecatedPhases = true;
00171 warning = "Defining phases using drive/brake/yellow mask is deprecated. Move to states.";
00172 }
00173 }
00174 break;
00175 case TL_COMPLETE_DEFINITION_RYG: {
00176 std::vector<MSTrafficLightLogic*> logics = vars.getAllLogics();
00177 tempMsg.writeUnsignedByte(TYPE_COMPOUND);
00178 Storage tempContent;
00179 unsigned int cnt = 0;
00180 tempContent.writeUnsignedByte(TYPE_INTEGER);
00181 tempContent.writeInt((int) logics.size());
00182 ++cnt;
00183 for (unsigned int i=0; i<logics.size(); ++i) {
00184 MSTrafficLightLogic *logic = logics[i];
00185 tempContent.writeUnsignedByte(TYPE_STRING);
00186 tempContent.writeString(logic->getSubID());
00187 ++cnt;
00188
00189 tempContent.writeUnsignedByte(TYPE_INTEGER);
00190 tempContent.writeInt(0);
00191 ++cnt;
00192
00193 tempContent.writeUnsignedByte(TYPE_COMPOUND);
00194 tempContent.writeInt(0);
00195 ++cnt;
00196
00197 tempContent.writeUnsignedByte(TYPE_INTEGER);
00198 tempContent.writeInt((int) logic->getCurrentPhaseIndex());
00199 ++cnt;
00200
00201 unsigned int phaseNo = logic->getPhaseNumber();
00202 tempContent.writeUnsignedByte(TYPE_INTEGER);
00203 tempContent.writeInt((int) phaseNo);
00204 ++cnt;
00205 for (unsigned int j=0; j<phaseNo; ++j) {
00206 MSPhaseDefinition phase = logic->getPhase(j);
00207 tempContent.writeUnsignedByte(TYPE_INTEGER);
00208 tempContent.writeInt(phase.duration);
00209 ++cnt;
00210 tempContent.writeUnsignedByte(TYPE_INTEGER);
00211 tempContent.writeInt(phase.minDuration);
00212 ++cnt;
00213 tempContent.writeUnsignedByte(TYPE_INTEGER);
00214 tempContent.writeInt(phase.maxDuration);
00215 ++cnt;
00216 const std::string &state = phase.getState();
00217 unsigned int linkNo = vars.getActive()->getLinks().size();
00218 tempContent.writeUnsignedByte(TYPE_STRING);
00219 tempContent.writeString(state);
00220 ++cnt;
00221 }
00222 }
00223 tempMsg.writeInt((int) cnt);
00224 tempMsg.writeStorage(tempContent);
00225 }
00226 break;
00227 case TL_CONTROLLED_LANES: {
00228 const MSTrafficLightLogic::LaneVectorVector &lanes = vars.getActive()->getLanes();
00229 tempMsg.writeUnsignedByte(TYPE_STRINGLIST);
00230 std::vector<std::string> laneIDs;
00231 for (MSTrafficLightLogic::LaneVectorVector::const_iterator i=lanes.begin(); i!=lanes.end(); ++i) {
00232 const MSTrafficLightLogic::LaneVector &llanes = (*i);
00233 for (MSTrafficLightLogic::LaneVector::const_iterator j=llanes.begin(); j!=llanes.end(); ++j) {
00234 laneIDs.push_back((*j)->getID());
00235 }
00236 }
00237 tempMsg.writeStringList(laneIDs);
00238 }
00239 break;
00240 case TL_CONTROLLED_LINKS: {
00241 const MSTrafficLightLogic::LaneVectorVector &lanes = vars.getActive()->getLanes();
00242 const MSTrafficLightLogic::LinkVectorVector &links = vars.getActive()->getLinks();
00243
00244 tempMsg.writeUnsignedByte(TYPE_COMPOUND);
00245 Storage tempContent;
00246 unsigned int cnt = 0;
00247 tempContent.writeUnsignedByte(TYPE_INTEGER);
00248 unsigned int no = (unsigned int) lanes.size();
00249 tempContent.writeInt((int) no);
00250 for (unsigned int i=0; i<no; ++i) {
00251 const MSTrafficLightLogic::LaneVector &llanes = lanes[i];
00252 const MSTrafficLightLogic::LinkVector &llinks = links[i];
00253
00254 tempContent.writeUnsignedByte(TYPE_INTEGER);
00255 unsigned int no2 = (unsigned int) llanes.size();
00256 tempContent.writeInt((int) no2);
00257 ++cnt;
00258 for (unsigned int j=0; j<no2; ++j) {
00259 MSLink *link = llinks[j];
00260 std::vector<std::string> def;
00261
00262 def.push_back(llanes[j]->getID());
00263
00264 def.push_back(link->getLane()!=0 ? link->getLane()->getID() : "");
00265
00266 #ifdef HAVE_INTERNAL_LANES
00267 def.push_back(link->getViaLane()!=0 ? link->getViaLane()->getID() : "");
00268 #else
00269 def.push_back("");
00270 #endif
00271 tempContent.writeUnsignedByte(TYPE_STRINGLIST);
00272 tempContent.writeStringList(def);
00273 ++cnt;
00274 }
00275 }
00276 tempMsg.writeInt((int) cnt);
00277 tempMsg.writeStorage(tempContent);
00278 }
00279 break;
00280 case TL_CURRENT_PHASE:
00281 tempMsg.writeUnsignedByte(TYPE_INTEGER);
00282 tempMsg.writeInt((int) vars.getActive()->getCurrentPhaseIndex());
00283 break;
00284 case TL_CURRENT_PROGRAM:
00285 tempMsg.writeUnsignedByte(TYPE_STRING);
00286 tempMsg.writeString(vars.getActive()->getSubID());
00287 break;
00288 case TL_PHASE_DURATION:
00289 tempMsg.writeUnsignedByte(TYPE_INTEGER);
00290 tempMsg.writeInt((int) vars.getActive()->getCurrentPhaseDef().duration);
00291 break;
00292 case TL_NEXT_SWITCH:
00293 tempMsg.writeUnsignedByte(TYPE_INTEGER);
00294 tempMsg.writeInt((int) vars.getActive()->getNextSwitchTime());
00295 break;
00296 case TL_CONTROLLED_JUNCTIONS: {
00297 }
00298 break;
00299 default:
00300 break;
00301 }
00302 }
00303 if (withStatus) {
00304 TraCIServerAPIHelper::writeStatusCmd(CMD_GET_TL_VARIABLE, RTYPE_OK, warning, outputStorage);
00305 }
00306
00307 outputStorage.writeUnsignedByte(0);
00308 outputStorage.writeInt(1 + 4 + tempMsg.size());
00309 outputStorage.writeStorage(tempMsg);
00310 return true;
00311 }
00312
00313
00314 bool
00315 TraCIServerAPI_TLS::processSet(tcpip::Storage &inputStorage,
00316 tcpip::Storage &outputStorage) throw(TraCIException) {
00317 std::string warning = "";
00318
00319 int variable = inputStorage.readUnsignedByte();
00320 if (variable!=TL_PHASE_BRAKE_YELLOW_STATE&&variable!=TL_PHASE_INDEX&&variable!=TL_PROGRAM
00321 &&variable!=TL_PHASE_DURATION&&variable!=TL_RED_YELLOW_GREEN_STATE&&variable!=TL_COMPLETE_PROGRAM_RYG) {
00322 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "Change TLS State: unsupported variable specified", outputStorage);
00323 return false;
00324 }
00325 std::string id = inputStorage.readString();
00326 if (!MSNet::getInstance()->getTLSControl().knows(id)) {
00327 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "Traffic light '" + id + "' is not known", outputStorage);
00328 return false;
00329 }
00330 MSTLLogicControl &tlsControl = MSNet::getInstance()->getTLSControl();
00331 SUMOTime cTime = MSNet::getInstance()->getCurrentTimeStep();
00332 MSTLLogicControl::TLSLogicVariants &vars = tlsControl.get(id);
00333 int valueDataType = inputStorage.readUnsignedByte();
00334 switch (variable) {
00335 case TL_PHASE_BRAKE_YELLOW_STATE: {
00336 if (valueDataType!=TYPE_STRINGLIST) {
00337 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "The phase must be given as three strings.", outputStorage);
00338 return false;
00339 }
00340 std::vector<std::string> defs = inputStorage.readStringList();
00341 if (defs.size()!=3) {
00342 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "The phase must be given as three strings.", outputStorage);
00343 return false;
00344 }
00345
00346 std::string state = MSPhaseDefinition::old2new(defs[0], defs[1], defs[2]);
00347 MSPhaseDefinition *phase = new MSPhaseDefinition(DELTA_T, state);
00348 std::vector<MSPhaseDefinition*> phases;
00349 phases.push_back(phase);
00350 MSTrafficLightLogic *logic = new MSSimpleTrafficLightLogic(tlsControl, id, "online", phases, 0, cTime+DELTA_T);
00351 if (!vars.addLogic("online", logic, true, true)) {
00352 delete logic;
00353 MSPhaseDefinition nphase(DELTA_T, state);
00354 *(static_cast<MSSimpleTrafficLightLogic*>(vars.getLogic("online"))->getPhases()[0]) = nphase;
00355 vars.getActive()->setLinkPriorities();
00356 }
00357 if (!myHaveWarnedAboutDeprecatedPhases) {
00358 myHaveWarnedAboutDeprecatedPhases = true;
00359 warning = "Defining phases using drive/brake/yellow mask is deprecated. Move to states.";
00360 }
00361 }
00362 break;
00363 case TL_PHASE_INDEX: {
00364 if (valueDataType!=TYPE_INTEGER) {
00365 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "The phase index must be given as an integer.", outputStorage);
00366 return false;
00367 }
00368 int index = inputStorage.readInt();
00369 if (index<0||vars.getActive()->getPhaseNumber()<=index) {
00370 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "The phase index is not in the allowed range.", outputStorage);
00371 return false;
00372 }
00373 int duration = vars.getActive()->getPhase(index).duration;
00374 vars.getActive()->changeStepAndDuration(tlsControl, cTime, index, duration);
00375 }
00376 break;
00377 case TL_PROGRAM: {
00378 if (valueDataType!=TYPE_STRING) {
00379 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "The program must be given as a string.", outputStorage);
00380 return false;
00381 }
00382 std::string subID = inputStorage.readString();
00383 try {
00384 vars.switchTo(tlsControl, subID);
00385 } catch (ProcessError &e) {
00386 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, e.what(), outputStorage);
00387 return false;
00388 }
00389 }
00390 break;
00391 case TL_PHASE_DURATION: {
00392 if (valueDataType!=TYPE_INTEGER) {
00393 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "The phase duration must be given as an integer.", outputStorage);
00394 return false;
00395 }
00396 int duration = inputStorage.readInt();
00397 int index = vars.getActive()->getCurrentPhaseIndex();
00398 vars.getActive()->changeStepAndDuration(tlsControl, cTime, index, duration);
00399 }
00400 break;
00401 case TL_RED_YELLOW_GREEN_STATE: {
00402 if (valueDataType!=TYPE_STRING) {
00403 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "The phase must be given as a string.", outputStorage);
00404 return false;
00405 }
00406
00407 std::string state = inputStorage.readString();
00408 MSPhaseDefinition *phase = new MSPhaseDefinition(DELTA_T, state);
00409 std::vector<MSPhaseDefinition*> phases;
00410 phases.push_back(phase);
00411 if (vars.getLogic("online")==0) {
00412 MSTrafficLightLogic *logic = new MSSimpleTrafficLightLogic(tlsControl, id, "online", phases, 0, cTime+DELTA_T);
00413 vars.addLogic("online", logic, true, true);
00414 vars.getActive()->setLinkPriorities();
00415 } else {
00416 MSPhaseDefinition nphase(DELTA_T, state);
00417 *(static_cast<MSSimpleTrafficLightLogic*>(vars.getLogic("online"))->getPhases()[0]) = nphase;
00418 vars.getActive()->setLinkPriorities();
00419 }
00420 }
00421 break;
00422 case TL_COMPLETE_PROGRAM_RYG: {
00423 if (valueDataType!=TYPE_COMPOUND) {
00424 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "A compound object is needed for setting a new program.", outputStorage);
00425 return false;
00426 }
00427 unsigned int itemNo = inputStorage.readInt();
00428 if (inputStorage.readUnsignedByte()!=TYPE_STRING) {
00429 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "set program: 1. parameter (subid) must be a string.", outputStorage);
00430 return false;
00431 }
00432 std::string subid = inputStorage.readString();
00433 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) {
00434 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "set program: 2. parameter (type) must be an int.", outputStorage);
00435 return false;
00436 }
00437 int type = inputStorage.readInt();
00438 if (inputStorage.readUnsignedByte()!=TYPE_COMPOUND) {
00439 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "set program: 3. parameter (subparams) must be a compound object.", outputStorage);
00440 return false;
00441 }
00442 int sublength = inputStorage.readInt();
00443 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) {
00444 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "set program: 4. parameter (index) must be an int.", outputStorage);
00445 return false;
00446 }
00447 int index = inputStorage.readInt();
00448 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) {
00449 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "set program: 5. parameter (phase number) must be an int.", outputStorage);
00450 return false;
00451 }
00452 int phaseNo = inputStorage.readInt();
00453 std::vector<MSPhaseDefinition*> phases;
00454 for (unsigned int j=0; j<phaseNo; ++j) {
00455 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) {
00456 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "set program: 6.1. parameter (duration) must be an int.", outputStorage);
00457 return false;
00458 }
00459 int duration = inputStorage.readInt();
00460 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) {
00461 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "set program: 6.2. parameter (min duration) must be an int.", outputStorage);
00462 return false;
00463 }
00464 int minDuration = inputStorage.readInt();
00465 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) {
00466 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "set program: 6.3. parameter (max duration) must be an int.", outputStorage);
00467 return false;
00468 }
00469 int maxDuration = inputStorage.readInt();
00470 if (inputStorage.readUnsignedByte()!=TYPE_STRING) {
00471 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_ERR, "set program: 6.4. parameter (phase) must be a string.", outputStorage);
00472 return false;
00473 }
00474 std::string state = inputStorage.readString();
00475 MSPhaseDefinition *phase = new MSPhaseDefinition(duration, minDuration, maxDuration, state);
00476 phases.push_back(phase);
00477 }
00478 if (vars.getLogic(subid)==0) {
00479 MSTrafficLightLogic *logic = new MSSimpleTrafficLightLogic(tlsControl, id, subid, phases, index, 0);
00480 vars.addLogic(subid, logic, true, true);
00481 vars.getActive()->setLinkPriorities();
00482 } else {
00483 static_cast<MSSimpleTrafficLightLogic*>(vars.getLogic(subid))->getPhases() = phases;
00484 vars.getActive()->setLinkPriorities();
00485 }
00486 }
00487 break;
00488 default:
00489 break;
00490 }
00491 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_TL_VARIABLE, RTYPE_OK, warning, outputStorage);
00492 return true;
00493 }
00494
00495
00496
00497
00498