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 #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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines