SUMO - Simulation of Urban MObility
|
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