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