SUMO - Simulation of Urban MObility
TraCIServerAPI_Lane.cpp
Go to the documentation of this file.
00001 /****************************************************************************/
00010 // APIs for getting/setting lane values via TraCI
00011 /****************************************************************************/
00012 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00013 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00014 /****************************************************************************/
00015 //
00016 //   This file is part of SUMO.
00017 //   SUMO is free software: you can redistribute it and/or modify
00018 //   it under the terms of the GNU General Public License as published by
00019 //   the Free Software Foundation, either version 3 of the License, or
00020 //   (at your option) any later version.
00021 //
00022 /****************************************************************************/
00023 
00024 
00025 // ===========================================================================
00026 // included modules
00027 // ===========================================================================
00028 #ifdef _MSC_VER
00029 #include <windows_config.h>
00030 #else
00031 #include <config.h>
00032 #endif
00033 
00034 #ifndef NO_TRACI
00035 
00036 #include <microsim/MSEdge.h>
00037 #include <microsim/MSLane.h>
00038 #include "TraCIConstants.h"
00039 #include "TraCIServerAPI_Lane.h"
00040 
00041 #ifdef CHECK_MEMORY_LEAKS
00042 #include <foreign/nvwa/debug_new.h>
00043 #endif // CHECK_MEMORY_LEAKS
00044 
00045 
00046 // ===========================================================================
00047 // used namespaces
00048 // ===========================================================================
00049 using namespace traci;
00050 
00051 
00052 // ===========================================================================
00053 // method definitions
00054 // ===========================================================================
00055 bool
00056 TraCIServerAPI_Lane::processGet(TraCIServer& server, tcpip::Storage& inputStorage,
00057                                 tcpip::Storage& outputStorage) {
00058     std::string warning = "";   // additional description for response
00059     // variable
00060     int variable = inputStorage.readUnsignedByte();
00061     std::string id = inputStorage.readString();
00062     // check variable
00063     if (variable != ID_LIST && variable != LANE_LINK_NUMBER && variable != LANE_EDGE_ID && variable != VAR_LENGTH
00064             && variable != VAR_MAXSPEED && variable != LANE_LINKS && variable != VAR_SHAPE
00065             && variable != VAR_CO2EMISSION && variable != VAR_COEMISSION && variable != VAR_HCEMISSION && variable != VAR_PMXEMISSION
00066             && variable != VAR_NOXEMISSION && variable != VAR_FUELCONSUMPTION && variable != VAR_NOISEEMISSION
00067             && variable != LAST_STEP_MEAN_SPEED && variable != LAST_STEP_VEHICLE_NUMBER
00068             && variable != LAST_STEP_VEHICLE_ID_LIST && variable != LAST_STEP_OCCUPANCY && variable != LAST_STEP_VEHICLE_HALTING_NUMBER
00069             && variable != LAST_STEP_LENGTH && variable != VAR_CURRENT_TRAVELTIME
00070             && variable != LANE_ALLOWED && variable != LANE_DISALLOWED && variable != VAR_WIDTH && variable != ID_COUNT) {
00071         server.writeStatusCmd(CMD_GET_LANE_VARIABLE, RTYPE_ERR, "Get Lane Variable: unsupported variable specified", outputStorage);
00072         return false;
00073     }
00074     // begin response building
00075     tcpip::Storage tempMsg;
00076     //  response-code, variableID, objectID
00077     tempMsg.writeUnsignedByte(RESPONSE_GET_LANE_VARIABLE);
00078     tempMsg.writeUnsignedByte(variable);
00079     tempMsg.writeString(id);
00080     if (variable == ID_LIST) {
00081         std::vector<std::string> ids;
00082         MSLane::insertIDs(ids);
00083         tempMsg.writeUnsignedByte(TYPE_STRINGLIST);
00084         tempMsg.writeStringList(ids);
00085     } else if (variable == ID_COUNT) {
00086         std::vector<std::string> ids;
00087         MSLane::insertIDs(ids);
00088         tempMsg.writeUnsignedByte(TYPE_INTEGER);
00089         tempMsg.writeInt((int) ids.size());
00090     } else {
00091         MSLane* lane = MSLane::dictionary(id);
00092         if (lane == 0) {
00093             server.writeStatusCmd(CMD_GET_LANE_VARIABLE, RTYPE_ERR, "Lane '" + id + "' is not known", outputStorage);
00094             return false;
00095         }
00096         switch (variable) {
00097             case LANE_LINK_NUMBER:
00098                 tempMsg.writeUnsignedByte(TYPE_UBYTE);
00099                 tempMsg.writeUnsignedByte((int) lane->getLinkCont().size());
00100                 break;
00101             case LANE_EDGE_ID:
00102                 tempMsg.writeUnsignedByte(TYPE_STRING);
00103                 tempMsg.writeString(lane->getEdge().getID());
00104                 break;
00105             case VAR_LENGTH:
00106                 tempMsg.writeUnsignedByte(TYPE_DOUBLE);
00107                 tempMsg.writeDouble(lane->getLength());
00108                 break;
00109             case VAR_MAXSPEED:
00110                 tempMsg.writeUnsignedByte(TYPE_DOUBLE);
00111                 tempMsg.writeDouble(lane->getMaxSpeed());
00112                 break;
00113             case LANE_LINKS: {
00114                 tempMsg.writeUnsignedByte(TYPE_COMPOUND);
00115                 tcpip::Storage tempContent;
00116                 unsigned int cnt = 0;
00117                 tempContent.writeUnsignedByte(TYPE_INTEGER);
00118                 const MSLinkCont& links = lane->getLinkCont();
00119                 tempContent.writeInt((int) links.size());
00120                 ++cnt;
00121                 for (MSLinkCont::const_iterator i = links.begin(); i != links.end(); ++i) {
00122                     MSLink* link = (*i);
00123                     // approached non-internal lane (if any)
00124                     tempContent.writeUnsignedByte(TYPE_STRING);
00125                     tempContent.writeString(link->getLane() != 0 ? link->getLane()->getID() : "");
00126                     ++cnt;
00127                     // approached "via", internal lane (if any)
00128                     tempContent.writeUnsignedByte(TYPE_STRING);
00129 #ifdef HAVE_INTERNAL_LANES
00130                     tempContent.writeString(link->getViaLane() != 0 ? link->getViaLane()->getID() : "");
00131 #else
00132                     tempContent.writeString("");
00133 #endif
00134                     ++cnt;
00135                     // priority
00136                     tempContent.writeUnsignedByte(TYPE_UBYTE);
00137                     tempContent.writeUnsignedByte(link->havePriority() ? 1 : 0);
00138                     ++cnt;
00139                     // opened
00140                     tempContent.writeUnsignedByte(TYPE_UBYTE);
00141                     tempContent.writeUnsignedByte(link->opened(MSNet::getInstance()->getCurrentTimeStep(), MSNet::getInstance()->getCurrentTimeStep(), 0.) ? 1 : 0);
00142                     ++cnt;
00143                     // approaching foe
00144                     tempContent.writeUnsignedByte(TYPE_UBYTE);
00145                     tempContent.writeUnsignedByte(link->hasApproachingFoe(MSNet::getInstance()->getCurrentTimeStep(), MSNet::getInstance()->getCurrentTimeStep()) ? 1 : 0);
00146                     ++cnt;
00147                     // state (not implemented, yet)
00148                     tempContent.writeUnsignedByte(TYPE_STRING);
00149                     tempContent.writeString("");
00150                     ++cnt;
00151                     // direction (not implemented, yet)
00152                     tempContent.writeUnsignedByte(TYPE_STRING);
00153                     tempContent.writeString("");
00154                     ++cnt;
00155                     // length
00156                     tempContent.writeUnsignedByte(TYPE_DOUBLE);
00157                     tempContent.writeDouble(link->getLength());
00158                     ++cnt;
00159                 }
00160                 tempMsg.writeInt((int) cnt);
00161                 tempMsg.writeStorage(tempContent);
00162             }
00163             break;
00164             case LANE_ALLOWED: {
00165                 tempMsg.writeUnsignedByte(TYPE_STRINGLIST);
00166                 SVCPermissions permissions = lane->getPermissions();
00167                 if (permissions == SVCFreeForAll) {  // special case: write nothing
00168                     permissions = 0;
00169                 }
00170                 tempMsg.writeStringList(getAllowedVehicleClassNamesList(permissions));
00171             }
00172             case LANE_DISALLOWED: {
00173                 tempMsg.writeUnsignedByte(TYPE_STRINGLIST);
00174                 tempMsg.writeStringList(getAllowedVehicleClassNamesList(~(lane->getPermissions()))); // negation yields disallowed
00175             }
00176             break;
00177             case VAR_SHAPE:
00178                 tempMsg.writeUnsignedByte(TYPE_POLYGON);
00179                 tempMsg.writeUnsignedByte((int)MIN2(static_cast<size_t>(255), lane->getShape().size()));
00180                 for (unsigned int iPoint = 0; iPoint < MIN2(static_cast<size_t>(255), lane->getShape().size()); ++iPoint) {
00181                     tempMsg.writeDouble(lane->getShape()[iPoint].x());
00182                     tempMsg.writeDouble(lane->getShape()[iPoint].y());
00183                 }
00184                 break;
00185             case VAR_CO2EMISSION:
00186                 tempMsg.writeUnsignedByte(TYPE_DOUBLE);
00187                 tempMsg.writeDouble(lane->getHBEFA_CO2Emissions());
00188                 break;
00189             case VAR_COEMISSION:
00190                 tempMsg.writeUnsignedByte(TYPE_DOUBLE);
00191                 tempMsg.writeDouble(lane->getHBEFA_COEmissions());
00192                 break;
00193             case VAR_HCEMISSION:
00194                 tempMsg.writeUnsignedByte(TYPE_DOUBLE);
00195                 tempMsg.writeDouble(lane->getHBEFA_HCEmissions());
00196                 break;
00197             case VAR_PMXEMISSION:
00198                 tempMsg.writeUnsignedByte(TYPE_DOUBLE);
00199                 tempMsg.writeDouble(lane->getHBEFA_PMxEmissions());
00200                 break;
00201             case VAR_NOXEMISSION:
00202                 tempMsg.writeUnsignedByte(TYPE_DOUBLE);
00203                 tempMsg.writeDouble(lane->getHBEFA_NOxEmissions());
00204                 break;
00205             case VAR_FUELCONSUMPTION:
00206                 tempMsg.writeUnsignedByte(TYPE_DOUBLE);
00207                 tempMsg.writeDouble(lane->getHBEFA_FuelConsumption());
00208                 break;
00209             case VAR_NOISEEMISSION:
00210                 tempMsg.writeUnsignedByte(TYPE_DOUBLE);
00211                 tempMsg.writeDouble(lane->getHarmonoise_NoiseEmissions());
00212                 break;
00213             case LAST_STEP_VEHICLE_NUMBER:
00214                 tempMsg.writeUnsignedByte(TYPE_INTEGER);
00215                 tempMsg.writeInt((int) lane->getVehicleNumber());
00216                 break;
00217             case LAST_STEP_MEAN_SPEED:
00218                 tempMsg.writeUnsignedByte(TYPE_DOUBLE);
00219                 tempMsg.writeDouble(lane->getMeanSpeed());
00220                 break;
00221             case LAST_STEP_VEHICLE_ID_LIST: {
00222                 std::vector<std::string> vehIDs;
00223                 const std::deque<MSVehicle*> &vehs = lane->getVehiclesSecure();
00224                 for (std::deque<MSVehicle*>::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
00225                     vehIDs.push_back((*j)->getID());
00226                 }
00227                 lane->releaseVehicles();
00228                 tempMsg.writeUnsignedByte(TYPE_STRINGLIST);
00229                 tempMsg.writeStringList(vehIDs);
00230             }
00231             break;
00232             case LAST_STEP_OCCUPANCY:
00233                 tempMsg.writeUnsignedByte(TYPE_DOUBLE);
00234                 tempMsg.writeDouble(lane->getOccupancy());
00235                 break;
00236             case LAST_STEP_VEHICLE_HALTING_NUMBER: {
00237                 int halting = 0;
00238                 const std::deque<MSVehicle*> &vehs = lane->getVehiclesSecure();
00239                 for (std::deque<MSVehicle*>::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
00240                     if ((*j)->getSpeed() < 0.1) {
00241                         ++halting;
00242                     }
00243                 }
00244                 lane->releaseVehicles();
00245                 tempMsg.writeUnsignedByte(TYPE_INTEGER);
00246                 tempMsg.writeInt(halting);
00247             }
00248             break;
00249             case LAST_STEP_LENGTH: {
00250                 SUMOReal lengthSum = 0;
00251                 const std::deque<MSVehicle*> &vehs = lane->getVehiclesSecure();
00252                 for (std::deque<MSVehicle*>::const_iterator j = vehs.begin(); j != vehs.end(); ++j) {
00253                     lengthSum += (*j)->getVehicleType().getLength();
00254                 }
00255                 tempMsg.writeUnsignedByte(TYPE_DOUBLE);
00256                 if (vehs.size() == 0) {
00257                     tempMsg.writeDouble(0);
00258                 } else {
00259                     tempMsg.writeDouble(lengthSum / (SUMOReal) vehs.size());
00260                 }
00261                 lane->releaseVehicles();
00262             }
00263             break;
00264             case VAR_CURRENT_TRAVELTIME: {
00265                 SUMOReal meanSpeed = lane->getMeanSpeed();
00266                 tempMsg.writeUnsignedByte(TYPE_DOUBLE);
00267                 if (meanSpeed != 0) {
00268                     tempMsg.writeDouble(lane->getLength() / meanSpeed);
00269                 } else {
00270                     tempMsg.writeDouble(1000000.);
00271                 }
00272             }
00273             break;
00274             case VAR_WIDTH:
00275                 tempMsg.writeUnsignedByte(TYPE_DOUBLE);
00276                 tempMsg.writeDouble(lane->getWidth());
00277                 break;
00278             default:
00279                 break;
00280         }
00281     }
00282     server.writeStatusCmd(CMD_GET_LANE_VARIABLE, RTYPE_OK, warning, outputStorage);
00283     server.writeResponseWithLength(outputStorage, tempMsg);
00284     return true;
00285 }
00286 
00287 
00288 bool
00289 TraCIServerAPI_Lane::processSet(TraCIServer& server, tcpip::Storage& inputStorage,
00290                                 tcpip::Storage& outputStorage) {
00291     std::string warning = ""; // additional description for response
00292     // variable
00293     int variable = inputStorage.readUnsignedByte();
00294     if (variable != VAR_MAXSPEED && variable != VAR_LENGTH && variable != LANE_ALLOWED && variable != LANE_DISALLOWED) {
00295         server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_ERR, "Change Lane State: unsupported variable specified", outputStorage);
00296         return false;
00297     }
00298     // id
00299     std::string id = inputStorage.readString();
00300     MSLane* l = MSLane::dictionary(id);
00301     if (l == 0) {
00302         server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_ERR, "Lane '" + id + "' is not known", outputStorage);
00303         return false;
00304     }
00305     // process
00306     int valueDataType = inputStorage.readUnsignedByte();
00307     switch (variable) {
00308         case VAR_MAXSPEED: {
00309             // speed
00310             if (valueDataType != TYPE_DOUBLE) {
00311                 server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_ERR, "The speed must be given as a double.", outputStorage);
00312                 return false;
00313             }
00314             SUMOReal val = inputStorage.readDouble();
00315             l->setMaxSpeed(val);
00316         }
00317         break;
00318         case VAR_LENGTH: {
00319             // speed
00320             if (valueDataType != TYPE_DOUBLE) {
00321                 server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_ERR, "The length must be given as a double.", outputStorage);
00322                 return false;
00323             }
00324             SUMOReal val = inputStorage.readDouble();
00325             l->setLength(val);
00326         }
00327         break;
00328         case LANE_ALLOWED: {
00329             if (valueDataType != TYPE_STRINGLIST) {
00330                 server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_ERR, "Allowed classes must be given as a list of strings.", outputStorage);
00331                 return false;
00332             }
00333             l->setPermissions(parseVehicleClasses(inputStorage.readStringList()));
00334             l->getEdge().rebuildAllowedLanes();
00335         }
00336         break;
00337         case LANE_DISALLOWED: {
00338             if (valueDataType != TYPE_STRINGLIST) {
00339                 server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_ERR, "Not allowed classes must be given as a list of strings.", outputStorage);
00340                 return false;
00341             }
00342             l->setPermissions(~parseVehicleClasses(inputStorage.readStringList())); // negation yields allowed
00343             l->getEdge().rebuildAllowedLanes();
00344         }
00345         break;
00346         default:
00347             break;
00348     }
00349     server.writeStatusCmd(CMD_SET_LANE_VARIABLE, RTYPE_OK, warning, outputStorage);
00350     return true;
00351 }
00352 
00353 #endif
00354 
00355 
00356 /****************************************************************************/
00357 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines