SUMO - Simulation of Urban MObility

TraCIServerAPI_Edge.cpp

Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines