SUMO - Simulation of Urban MObility

TraCIServerAPI_Edge.cpp

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