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 #ifndef NO_TRACI 00036 00037 #include <utils/common/StdDefs.h> 00038 #include <microsim/MSNet.h> 00039 #include <microsim/MSEdge.h> 00040 #include <microsim/MSLane.h> 00041 #include <microsim/MSVehicle.h> 00042 #include "TraCIConstants.h" 00043 #include "TraCIServerAPI_Edge.h" 00044 #include <microsim/MSEdgeWeightsStorage.h> 00045 #include <utils/common/HelpersHarmonoise.h> 00046 00047 #ifdef CHECK_MEMORY_LEAKS 00048 #include <foreign/nvwa/debug_new.h> 00049 #endif // CHECK_MEMORY_LEAKS 00050 00051 00052 // =========================================================================== 00053 // used namespaces 00054 // =========================================================================== 00055 using namespace traci; 00056 00057 00058 // =========================================================================== 00059 // method definitions 00060 // =========================================================================== 00061 bool 00062 TraCIServerAPI_Edge::processGet(TraCIServer& server, tcpip::Storage& inputStorage, 00063 tcpip::Storage& outputStorage) { 00064 std::string warning = ""; // additional description for response 00065 // variable & id 00066 int variable = inputStorage.readUnsignedByte(); 00067 std::string id = inputStorage.readString(); 00068 // check variable 00069 if (variable != ID_LIST && variable != VAR_EDGE_TRAVELTIME && variable != VAR_EDGE_EFFORT && variable != VAR_CURRENT_TRAVELTIME 00070 && variable != VAR_CO2EMISSION && variable != VAR_COEMISSION && variable != VAR_HCEMISSION && variable != VAR_PMXEMISSION 00071 && variable != VAR_NOXEMISSION && variable != VAR_FUELCONSUMPTION && variable != VAR_NOISEEMISSION 00072 && variable != LAST_STEP_VEHICLE_NUMBER && variable != LAST_STEP_MEAN_SPEED && variable != LAST_STEP_OCCUPANCY 00073 && variable != LAST_STEP_VEHICLE_HALTING_NUMBER && variable != LAST_STEP_LENGTH 00074 && variable != LAST_STEP_VEHICLE_ID_LIST && variable != ID_COUNT) { 00075 server.writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_ERR, "Get Edge Variable: unsupported variable specified", outputStorage); 00076 return false; 00077 } 00078 // begin response building 00079 tcpip::Storage tempMsg; 00080 // response-code, variableID, objectID 00081 tempMsg.writeUnsignedByte(RESPONSE_GET_EDGE_VARIABLE); 00082 tempMsg.writeUnsignedByte(variable); 00083 tempMsg.writeString(id); 00084 // process request 00085 if (variable == ID_LIST) { 00086 std::vector<std::string> ids; 00087 MSEdge::insertIDs(ids); 00088 tempMsg.writeUnsignedByte(TYPE_STRINGLIST); 00089 tempMsg.writeStringList(ids); 00090 } else if (variable == ID_COUNT) { 00091 std::vector<std::string> ids; 00092 MSEdge::insertIDs(ids); 00093 tempMsg.writeUnsignedByte(TYPE_INTEGER); 00094 tempMsg.writeInt((int) ids.size()); 00095 } else { 00096 MSEdge* e = MSEdge::dictionary(id); 00097 if (e == 0) { 00098 server.writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_ERR, "Edge '" + id + "' is not known", outputStorage); 00099 return false; 00100 } 00101 switch (variable) { 00102 case VAR_EDGE_TRAVELTIME: { 00103 // time 00104 if (inputStorage.readUnsignedByte() != TYPE_INTEGER) { 00105 server.writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_ERR, "The message must contain the time definition.", outputStorage); 00106 return false; 00107 } 00108 SUMOTime time = inputStorage.readInt(); 00109 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00110 SUMOReal value; 00111 if (!MSNet::getInstance()->getWeightsStorage().retrieveExistingTravelTime(e, 0, time, value)) { 00112 tempMsg.writeDouble(-1); 00113 } else { 00114 tempMsg.writeDouble(value); 00115 } 00116 } 00117 break; 00118 case VAR_EDGE_EFFORT: { 00119 // time 00120 if (inputStorage.readUnsignedByte() != TYPE_INTEGER) { 00121 server.writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_ERR, "The message must contain the time definition.", outputStorage); 00122 return false; 00123 } 00124 SUMOTime time = inputStorage.readInt(); 00125 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00126 SUMOReal value; 00127 if (!MSNet::getInstance()->getWeightsStorage().retrieveExistingEffort(e, 0, time, value)) { 00128 tempMsg.writeDouble(-1); 00129 } else { 00130 tempMsg.writeDouble(value); 00131 } 00132 } 00133 break; 00134 case VAR_CURRENT_TRAVELTIME: 00135 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00136 tempMsg.writeDouble(e->getCurrentTravelTime()); 00137 break; 00138 case LAST_STEP_VEHICLE_ID_LIST: { 00139 std::vector<std::string> vehIDs; 00140 const std::vector<MSLane*> &lanes = e->getLanes(); 00141 for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) { 00142 const std::deque<MSVehicle*> &vehs = (*i)->getVehiclesSecure(); 00143 for (std::deque<MSVehicle*>::const_iterator j = vehs.begin(); j != vehs.end(); ++j) { 00144 vehIDs.push_back((*j)->getID()); 00145 } 00146 (*i)->releaseVehicles(); 00147 } 00148 tempMsg.writeUnsignedByte(TYPE_STRINGLIST); 00149 tempMsg.writeStringList(vehIDs); 00150 } 00151 break; 00152 case VAR_CO2EMISSION: { 00153 SUMOReal sum = 0; 00154 const std::vector<MSLane*> &lanes = e->getLanes(); 00155 for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) { 00156 sum += (*i)->getHBEFA_CO2Emissions(); 00157 } 00158 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00159 tempMsg.writeDouble(sum); 00160 } 00161 break; 00162 case VAR_COEMISSION: { 00163 SUMOReal sum = 0; 00164 const std::vector<MSLane*> &lanes = e->getLanes(); 00165 for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) { 00166 sum += (*i)->getHBEFA_COEmissions(); 00167 } 00168 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00169 tempMsg.writeDouble(sum); 00170 } 00171 break; 00172 case VAR_HCEMISSION: { 00173 SUMOReal sum = 0; 00174 const std::vector<MSLane*> &lanes = e->getLanes(); 00175 for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) { 00176 sum += (*i)->getHBEFA_HCEmissions(); 00177 } 00178 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00179 tempMsg.writeDouble(sum); 00180 } 00181 break; 00182 case VAR_PMXEMISSION: { 00183 SUMOReal sum = 0; 00184 const std::vector<MSLane*> &lanes = e->getLanes(); 00185 for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) { 00186 sum += (*i)->getHBEFA_PMxEmissions(); 00187 } 00188 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00189 tempMsg.writeDouble(sum); 00190 } 00191 break; 00192 case VAR_NOXEMISSION: { 00193 SUMOReal sum = 0; 00194 const std::vector<MSLane*> &lanes = e->getLanes(); 00195 for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) { 00196 sum += (*i)->getHBEFA_NOxEmissions(); 00197 } 00198 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00199 tempMsg.writeDouble(sum); 00200 } 00201 break; 00202 case VAR_FUELCONSUMPTION: { 00203 SUMOReal sum = 0; 00204 const std::vector<MSLane*> &lanes = e->getLanes(); 00205 for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) { 00206 sum += (*i)->getHBEFA_FuelConsumption(); 00207 } 00208 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00209 tempMsg.writeDouble(sum); 00210 } 00211 break; 00212 case VAR_NOISEEMISSION: { 00213 SUMOReal sum = 0; 00214 const std::vector<MSLane*> &lanes = e->getLanes(); 00215 for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) { 00216 sum += (SUMOReal) pow(10., ((*i)->getHarmonoise_NoiseEmissions() / 10.)); 00217 } 00218 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00219 if (sum != 0) { 00220 tempMsg.writeDouble(HelpersHarmonoise::sum(sum)); 00221 } else { 00222 tempMsg.writeDouble(0); 00223 } 00224 } 00225 break; 00226 case LAST_STEP_VEHICLE_NUMBER: { 00227 int sum = 0; 00228 const std::vector<MSLane*> &lanes = e->getLanes(); 00229 for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) { 00230 sum += (*i)->getVehicleNumber(); 00231 } 00232 tempMsg.writeUnsignedByte(TYPE_INTEGER); 00233 tempMsg.writeInt(sum); 00234 } 00235 break; 00236 case LAST_STEP_MEAN_SPEED: { 00237 SUMOReal sum = 0; 00238 const std::vector<MSLane*> &lanes = e->getLanes(); 00239 for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) { 00240 sum += (*i)->getMeanSpeed(); 00241 } 00242 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00243 tempMsg.writeDouble(sum / (SUMOReal) lanes.size()); 00244 } 00245 break; 00246 case LAST_STEP_OCCUPANCY: { 00247 SUMOReal sum = 0; 00248 const std::vector<MSLane*> &lanes = e->getLanes(); 00249 for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) { 00250 sum += (*i)->getOccupancy(); 00251 } 00252 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00253 tempMsg.writeDouble(sum / (SUMOReal) lanes.size()); 00254 } 00255 break; 00256 case LAST_STEP_VEHICLE_HALTING_NUMBER: { 00257 int halting = 0; 00258 const std::vector<MSLane*> &lanes = e->getLanes(); 00259 for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) { 00260 const std::deque<MSVehicle*> &vehs = (*i)->getVehiclesSecure(); 00261 for (std::deque<MSVehicle*>::const_iterator j = vehs.begin(); j != vehs.end(); ++j) { 00262 if ((*j)->getSpeed() < 0.1) { 00263 ++halting; 00264 } 00265 } 00266 (*i)->releaseVehicles(); 00267 } 00268 tempMsg.writeUnsignedByte(TYPE_INTEGER); 00269 tempMsg.writeInt(halting); 00270 } 00271 break; 00272 case LAST_STEP_LENGTH: { 00273 SUMOReal lengthSum = 0; 00274 int noVehicles = 0; 00275 const std::vector<MSLane*> &lanes = e->getLanes(); 00276 for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) { 00277 const std::deque<MSVehicle*> &vehs = (*i)->getVehiclesSecure(); 00278 for (std::deque<MSVehicle*>::const_iterator j = vehs.begin(); j != vehs.end(); ++j) { 00279 lengthSum += (*j)->getVehicleType().getLength(); 00280 } 00281 noVehicles += (int) vehs.size(); 00282 (*i)->releaseVehicles(); 00283 } 00284 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00285 if (noVehicles == 0) { 00286 tempMsg.writeDouble(0); 00287 } else { 00288 tempMsg.writeDouble(lengthSum / (SUMOReal) noVehicles); 00289 } 00290 } 00291 break; 00292 default: 00293 break; 00294 } 00295 } 00296 server.writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_OK, warning, outputStorage); 00297 server.writeResponseWithLength(outputStorage, tempMsg); 00298 return true; 00299 } 00300 00301 00302 bool 00303 TraCIServerAPI_Edge::processSet(TraCIServer& server, tcpip::Storage& inputStorage, 00304 tcpip::Storage& outputStorage) { 00305 std::string warning = ""; // additional description for response 00306 // variable 00307 int variable = inputStorage.readUnsignedByte(); 00308 if (variable != VAR_EDGE_TRAVELTIME && variable != VAR_EDGE_EFFORT && variable != VAR_MAXSPEED) { 00309 server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "Change Edge State: unsupported variable specified", outputStorage); 00310 return false; 00311 } 00312 // id 00313 std::string id = inputStorage.readString(); 00314 MSEdge* e = MSEdge::dictionary(id); 00315 if (e == 0) { 00316 server.writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "Edge '" + id + "' is not known", outputStorage); 00317 return false; 00318 } 00319 // process 00320 int valueDataType = inputStorage.readUnsignedByte(); 00321 switch (variable) { 00322 case LANE_ALLOWED: { 00323 if (inputStorage.readUnsignedByte() != TYPE_STRINGLIST) { 00324 server.writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_ERR, "Allowed vehicle classes must be given as a list of strings.", outputStorage); 00325 return false; 00326 } 00327 SVCPermissions permissions = parseVehicleClasses(inputStorage.readStringList()); 00328 const std::vector<MSLane*> &lanes = e->getLanes(); 00329 for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) { 00330 (*i)->setPermissions(permissions); 00331 } 00332 e->rebuildAllowedLanes(); 00333 } 00334 break; 00335 case LANE_DISALLOWED: { 00336 // time 00337 if (inputStorage.readUnsignedByte() != TYPE_STRINGLIST) { 00338 server.writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_ERR, "Not allowed vehicle classes must be given as a list of strings.", outputStorage); 00339 return false; 00340 } 00341 SVCPermissions permissions = ~parseVehicleClasses(inputStorage.readStringList()); // negation yields allowed 00342 const std::vector<MSLane*> &lanes = e->getLanes(); 00343 for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) { 00344 (*i)->setPermissions(permissions); 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 #endif 00455 00456 00457 /****************************************************************************/ 00458