|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00007 // APIs for getting/setting edge 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 <utils/common/StdDefs.h> 00031 #include <microsim/MSNet.h> 00032 #include <microsim/MSEdge.h> 00033 #include <microsim/MSLane.h> 00034 #include <microsim/MSVehicle.h> 00035 #include "TraCIConstants.h" 00036 #include "TraCIServerAPI_Edge.h" 00037 #include <microsim/MSEdgeWeightsStorage.h> 00038 #include <utils/common/HelpersHarmonoise.h> 00039 00040 #ifdef CHECK_MEMORY_LEAKS 00041 #include <foreign/nvwa/debug_new.h> 00042 #endif // CHECK_MEMORY_LEAKS 00043 00044 00045 // =========================================================================== 00046 // used namespaces 00047 // =========================================================================== 00048 using namespace traci; 00049 00050 00051 // =========================================================================== 00052 // method definitions 00053 // =========================================================================== 00054 bool 00055 TraCIServerAPI_Edge::processGet(TraCIServer& server, tcpip::Storage& inputStorage, 00056 tcpip::Storage& outputStorage) { 00057 std::string warning = ""; // additional description for response 00058 // variable & id 00059 int variable = inputStorage.readUnsignedByte(); 00060 std::string id = inputStorage.readString(); 00061 // check variable 00062 if (variable!=ID_LIST&&variable!=VAR_EDGE_TRAVELTIME&&variable!=VAR_EDGE_EFFORT&&variable!=VAR_CURRENT_TRAVELTIME 00063 &&variable!=VAR_CO2EMISSION&&variable!=VAR_COEMISSION&&variable!=VAR_HCEMISSION&&variable!=VAR_PMXEMISSION 00064 &&variable!=VAR_NOXEMISSION&&variable!=VAR_FUELCONSUMPTION&&variable!=VAR_NOISEEMISSION 00065 &&variable!=LAST_STEP_VEHICLE_NUMBER&&variable!=LAST_STEP_MEAN_SPEED&&variable!=LAST_STEP_OCCUPANCY 00066 &&variable!=LAST_STEP_VEHICLE_HALTING_NUMBER&&variable!=LAST_STEP_LENGTH 00067 &&variable!=LAST_STEP_VEHICLE_ID_LIST&&variable!=ID_COUNT) { 00068 server.writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_ERR, "Get Edge Variable: unsupported variable specified", outputStorage); 00069 return false; 00070 } 00071 // begin response building 00072 tcpip::Storage tempMsg; 00073 // response-code, variableID, objectID 00074 tempMsg.writeUnsignedByte(RESPONSE_GET_EDGE_VARIABLE); 00075 tempMsg.writeUnsignedByte(variable); 00076 tempMsg.writeString(id); 00077 // process request 00078 if (variable==ID_LIST) { 00079 std::vector<std::string> ids; 00080 MSEdge::insertIDs(ids); 00081 tempMsg.writeUnsignedByte(TYPE_STRINGLIST); 00082 tempMsg.writeStringList(ids); 00083 } else if (variable==ID_COUNT) { 00084 std::vector<std::string> ids; 00085 MSEdge::insertIDs(ids); 00086 tempMsg.writeUnsignedByte(TYPE_INTEGER); 00087 tempMsg.writeInt((int) ids.size()); 00088 } else { 00089 MSEdge* e = MSEdge::dictionary(id); 00090 if (e==0) { 00091 server.writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_ERR, "Edge '" + id + "' is not known", outputStorage); 00092 return false; 00093 } 00094 switch (variable) { 00095 case VAR_EDGE_TRAVELTIME: { 00096 // time 00097 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) { 00098 server.writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_ERR, "The message must contain the time definition.", outputStorage); 00099 return false; 00100 } 00101 SUMOTime time = inputStorage.readInt(); 00102 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00103 SUMOReal value; 00104 if (!MSNet::getInstance()->getWeightsStorage().retrieveExistingTravelTime(e, 0, time, value)) { 00105 tempMsg.writeDouble(-1); 00106 } else { 00107 tempMsg.writeDouble(value); 00108 } 00109 } 00110 break; 00111 case VAR_EDGE_EFFORT: { 00112 // time 00113 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) { 00114 server.writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_ERR, "The message must contain the time definition.", outputStorage); 00115 return false; 00116 } 00117 SUMOTime time = inputStorage.readInt(); 00118 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00119 SUMOReal value; 00120 if (!MSNet::getInstance()->getWeightsStorage().retrieveExistingEffort(e, 0, time, value)) { 00121 tempMsg.writeDouble(-1); 00122 } else { 00123 tempMsg.writeDouble(value); 00124 } 00125 } 00126 break; 00127 case VAR_CURRENT_TRAVELTIME: 00128 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00129 tempMsg.writeDouble(e->getCurrentTravelTime()); 00130 break; 00131 case LAST_STEP_VEHICLE_ID_LIST: { 00132 std::vector<std::string> vehIDs; 00133 const std::vector<MSLane*> &lanes = e->getLanes(); 00134 for (std::vector<MSLane*>::const_iterator i=lanes.begin(); i!=lanes.end(); ++i) { 00135 const std::deque<MSVehicle*> &vehs = (*i)->getVehiclesSecure(); 00136 for (std::deque<MSVehicle*>::const_iterator j=vehs.begin(); j!=vehs.end(); ++j) { 00137 vehIDs.push_back((*j)->getID()); 00138 } 00139 (*i)->releaseVehicles(); 00140 } 00141 tempMsg.writeUnsignedByte(TYPE_STRINGLIST); 00142 tempMsg.writeStringList(vehIDs); 00143 } 00144 break; 00145 case VAR_CO2EMISSION: { 00146 SUMOReal sum = 0; 00147 const std::vector<MSLane*> &lanes = e->getLanes(); 00148 for (std::vector<MSLane*>::const_iterator i=lanes.begin(); i!=lanes.end(); ++i) { 00149 sum += (*i)->getHBEFA_CO2Emissions(); 00150 } 00151 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00152 tempMsg.writeDouble(sum); 00153 } 00154 break; 00155 case VAR_COEMISSION: { 00156 SUMOReal sum = 0; 00157 const std::vector<MSLane*> &lanes = e->getLanes(); 00158 for (std::vector<MSLane*>::const_iterator i=lanes.begin(); i!=lanes.end(); ++i) { 00159 sum += (*i)->getHBEFA_COEmissions(); 00160 } 00161 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00162 tempMsg.writeDouble(sum); 00163 } 00164 break; 00165 case VAR_HCEMISSION: { 00166 SUMOReal sum = 0; 00167 const std::vector<MSLane*> &lanes = e->getLanes(); 00168 for (std::vector<MSLane*>::const_iterator i=lanes.begin(); i!=lanes.end(); ++i) { 00169 sum += (*i)->getHBEFA_HCEmissions(); 00170 } 00171 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00172 tempMsg.writeDouble(sum); 00173 } 00174 break; 00175 case VAR_PMXEMISSION: { 00176 SUMOReal sum = 0; 00177 const std::vector<MSLane*> &lanes = e->getLanes(); 00178 for (std::vector<MSLane*>::const_iterator i=lanes.begin(); i!=lanes.end(); ++i) { 00179 sum += (*i)->getHBEFA_PMxEmissions(); 00180 } 00181 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00182 tempMsg.writeDouble(sum); 00183 } 00184 break; 00185 case VAR_NOXEMISSION: { 00186 SUMOReal sum = 0; 00187 const std::vector<MSLane*> &lanes = e->getLanes(); 00188 for (std::vector<MSLane*>::const_iterator i=lanes.begin(); i!=lanes.end(); ++i) { 00189 sum += (*i)->getHBEFA_NOxEmissions(); 00190 } 00191 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00192 tempMsg.writeDouble(sum); 00193 } 00194 break; 00195 case VAR_FUELCONSUMPTION: { 00196 SUMOReal sum = 0; 00197 const std::vector<MSLane*> &lanes = e->getLanes(); 00198 for (std::vector<MSLane*>::const_iterator i=lanes.begin(); i!=lanes.end(); ++i) { 00199 sum += (*i)->getHBEFA_FuelConsumption(); 00200 } 00201 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00202 tempMsg.writeDouble(sum); 00203 } 00204 break; 00205 case VAR_NOISEEMISSION: { 00206 SUMOReal sum = 0; 00207 const std::vector<MSLane*> &lanes = e->getLanes(); 00208 for (std::vector<MSLane*>::const_iterator i=lanes.begin(); i!=lanes.end(); ++i) { 00209 sum += (SUMOReal) pow(10., ((*i)->getHarmonoise_NoiseEmissions()/10.)); 00210 } 00211 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00212 if (sum!=0) { 00213 tempMsg.writeDouble(HelpersHarmonoise::sum(sum)); 00214 } else { 00215 tempMsg.writeDouble(0); 00216 } 00217 } 00218 break; 00219 case LAST_STEP_VEHICLE_NUMBER: { 00220 int sum = 0; 00221 const std::vector<MSLane*> &lanes = e->getLanes(); 00222 for (std::vector<MSLane*>::const_iterator i=lanes.begin(); i!=lanes.end(); ++i) { 00223 sum += (*i)->getVehicleNumber(); 00224 } 00225 tempMsg.writeUnsignedByte(TYPE_INTEGER); 00226 tempMsg.writeInt(sum); 00227 } 00228 break; 00229 case LAST_STEP_MEAN_SPEED: { 00230 SUMOReal sum = 0; 00231 const std::vector<MSLane*> &lanes = e->getLanes(); 00232 for (std::vector<MSLane*>::const_iterator i=lanes.begin(); i!=lanes.end(); ++i) { 00233 sum += (*i)->getMeanSpeed(); 00234 } 00235 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00236 tempMsg.writeDouble(sum / (SUMOReal) lanes.size()); 00237 } 00238 break; 00239 case LAST_STEP_OCCUPANCY: { 00240 SUMOReal sum = 0; 00241 const std::vector<MSLane*> &lanes = e->getLanes(); 00242 for (std::vector<MSLane*>::const_iterator i=lanes.begin(); i!=lanes.end(); ++i) { 00243 sum += (*i)->getOccupancy(); 00244 } 00245 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00246 tempMsg.writeDouble(sum / (SUMOReal) lanes.size()); 00247 } 00248 break; 00249 case LAST_STEP_VEHICLE_HALTING_NUMBER: { 00250 int halting = 0; 00251 const std::vector<MSLane*> &lanes = e->getLanes(); 00252 for (std::vector<MSLane*>::const_iterator i=lanes.begin(); i!=lanes.end(); ++i) { 00253 const std::deque<MSVehicle*> &vehs = (*i)->getVehiclesSecure(); 00254 for (std::deque<MSVehicle*>::const_iterator j=vehs.begin(); j!=vehs.end(); ++j) { 00255 if ((*j)->getSpeed()<0.1) { 00256 ++halting; 00257 } 00258 } 00259 (*i)->releaseVehicles(); 00260 } 00261 tempMsg.writeUnsignedByte(TYPE_INTEGER); 00262 tempMsg.writeInt(halting); 00263 } 00264 break; 00265 case LAST_STEP_LENGTH: { 00266 SUMOReal lengthSum = 0; 00267 int noVehicles = 0; 00268 const std::vector<MSLane*> &lanes = e->getLanes(); 00269 for (std::vector<MSLane*>::const_iterator i=lanes.begin(); i!=lanes.end(); ++i) { 00270 const std::deque<MSVehicle*> &vehs = (*i)->getVehiclesSecure(); 00271 for (std::deque<MSVehicle*>::const_iterator j=vehs.begin(); j!=vehs.end(); ++j) { 00272 lengthSum += (*j)->getVehicleType().getLengthWithGap(); 00273 } 00274 noVehicles += (int) vehs.size(); 00275 (*i)->releaseVehicles(); 00276 } 00277 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00278 if (noVehicles==0) { 00279 tempMsg.writeDouble(0); 00280 } else { 00281 tempMsg.writeDouble(lengthSum / (SUMOReal) noVehicles); 00282 } 00283 } 00284 break; 00285 default: 00286 break; 00287 } 00288 } 00289 server.writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_OK, warning, outputStorage); 00290 server.writeResponseWithLength(outputStorage, tempMsg); 00291 return true; 00292 } 00293 00294 00295 bool 00296 TraCIServerAPI_Edge::processSet(TraCIServer& server, tcpip::Storage& inputStorage, 00297 tcpip::Storage& outputStorage) { 00298 std::string warning = ""; // additional description for response 00299 // variable 00300 int variable = inputStorage.readUnsignedByte(); 00301 if (variable!=VAR_EDGE_TRAVELTIME&&variable!=VAR_EDGE_EFFORT&&variable!=VAR_MAXSPEED) { 00302 server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "Change Edge State: unsupported variable specified", outputStorage); 00303 return false; 00304 } 00305 // id 00306 std::string id = inputStorage.readString(); 00307 MSEdge* e = MSEdge::dictionary(id); 00308 if (e==0) { 00309 server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "Edge '" + id + "' is not known", outputStorage); 00310 return false; 00311 } 00312 // process 00313 int valueDataType = inputStorage.readUnsignedByte(); 00314 switch (variable) { 00315 case LANE_ALLOWED: { 00316 if (inputStorage.readUnsignedByte()!=TYPE_STRINGLIST) { 00317 server.writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_ERR, "Allowed vehicle classes must be given as a list of strings.", outputStorage); 00318 return false; 00319 } 00320 SUMOVehicleClasses allowed; 00321 parseVehicleClasses(inputStorage.readStringList(), allowed); 00322 const std::vector<MSLane*> &lanes = e->getLanes(); 00323 for (std::vector<MSLane*>::const_iterator i=lanes.begin(); i!=lanes.end(); ++i) { 00324 (*i)->setAllowedClasses(allowed); 00325 } 00326 e->rebuildAllowedLanes(); 00327 } 00328 break; 00329 case LANE_DISALLOWED: { 00330 // time 00331 if (inputStorage.readUnsignedByte()!=TYPE_STRINGLIST) { 00332 server.writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_ERR, "Not allowed vehicle classes must be given as a list of strings.", outputStorage); 00333 return false; 00334 } 00335 SUMOVehicleClasses disallowed; 00336 parseVehicleClasses(inputStorage.readStringList(), disallowed); 00337 const std::vector<MSLane*> &lanes = e->getLanes(); 00338 for (std::vector<MSLane*>::const_iterator i=lanes.begin(); i!=lanes.end(); ++i) { 00339 (*i)->setNotAllowedClasses(disallowed); 00340 } 00341 e->rebuildAllowedLanes(); 00342 } 00343 break; 00344 case VAR_EDGE_TRAVELTIME: { 00345 if (valueDataType!=TYPE_COMPOUND) { 00346 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time requires a compound object.", outputStorage); 00347 return false; 00348 } 00349 int parameterCount = inputStorage.readInt(); 00350 if (parameterCount == 3) { 00351 // begin 00352 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) { 00353 server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The first variable must be the begin time given as int.", outputStorage); 00354 return false; 00355 } 00356 SUMOTime begTime = inputStorage.readInt(); 00357 // end 00358 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) { 00359 server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The second variable must be the end time given as int.", outputStorage); 00360 return false; 00361 } 00362 SUMOTime endTime = inputStorage.readInt(); 00363 // value 00364 if (inputStorage.readUnsignedByte()!=TYPE_DOUBLE) { 00365 server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The second variable must be the value given as double", outputStorage); 00366 return false; 00367 } 00368 SUMOReal value = inputStorage.readDouble(); 00369 // set 00370 MSNet::getInstance()->getWeightsStorage().addTravelTime(e, begTime, endTime, value); 00371 } else if (parameterCount == 1) { 00372 // value 00373 if (inputStorage.readUnsignedByte()!=TYPE_DOUBLE) { 00374 server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The variable must be the value given as double", outputStorage); 00375 return false; 00376 } 00377 SUMOReal value = inputStorage.readDouble(); 00378 // set 00379 MSNet::getInstance()->getWeightsStorage().addTravelTime(e, 0, SUMOTime_MAX, value); 00380 } else { 00381 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time requires either begin time, end time, and value, or only value as parameter.", outputStorage); 00382 return false; 00383 } 00384 } 00385 break; 00386 case VAR_EDGE_EFFORT: { 00387 if (valueDataType!=TYPE_COMPOUND) { 00388 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort requires a compound object.", outputStorage); 00389 return false; 00390 } 00391 int parameterCount = inputStorage.readInt(); 00392 if (parameterCount==3) { 00393 // begin 00394 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) { 00395 server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The first variable must be the begin time given as int.", outputStorage); 00396 return false; 00397 } 00398 SUMOTime begTime = inputStorage.readInt(); 00399 // end 00400 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) { 00401 server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The second variable must be the end time given as int.", outputStorage); 00402 return false; 00403 } 00404 SUMOTime endTime = inputStorage.readInt(); 00405 // value 00406 if (inputStorage.readUnsignedByte()!=TYPE_DOUBLE) { 00407 server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The second variable must be the value given as double", outputStorage); 00408 return false; 00409 } 00410 SUMOReal value = inputStorage.readDouble(); 00411 // set 00412 MSNet::getInstance()->getWeightsStorage().addEffort(e, begTime, endTime, value); 00413 } else if (parameterCount == 1) { 00414 // value 00415 if (inputStorage.readUnsignedByte()!=TYPE_DOUBLE) { 00416 server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The variable must be the value given as double", outputStorage); 00417 return false; 00418 } 00419 SUMOReal value = inputStorage.readDouble(); 00420 // set 00421 MSNet::getInstance()->getWeightsStorage().addEffort(e, 0, SUMOTime_MAX, value); 00422 } else { 00423 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort requires either begin time, end time, and value, or only value as parameter.", outputStorage); 00424 return false; 00425 } 00426 } 00427 break; 00428 case VAR_MAXSPEED: { 00429 // speed 00430 if (valueDataType!=TYPE_DOUBLE) { 00431 server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The speed must be given as a double.", outputStorage); 00432 return false; 00433 } 00434 SUMOReal val = inputStorage.readDouble(); 00435 const std::vector<MSLane*> &lanes = e->getLanes(); 00436 for (std::vector<MSLane*>::const_iterator i=lanes.begin(); i!=lanes.end(); ++i) { 00437 (*i)->setMaxSpeed(val); 00438 } 00439 } 00440 break; 00441 default: 00442 break; 00443 } 00444 server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_OK, warning, outputStorage); 00445 return true; 00446 } 00447 00448 00449 00450 /****************************************************************************/ 00451