00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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 "TraCIServerAPIHelper.h"
00037 #include "TraCIServerAPI_Edge.h"
00038 #include <microsim/MSEdgeWeightsStorage.h>
00039 #include <utils/common/HelpersHarmonoise.h>
00040
00041 #ifdef CHECK_MEMORY_LEAKS
00042 #include <foreign/nvwa/debug_new.h>
00043 #endif // CHECK_MEMORY_LEAKS
00044
00045
00046
00047
00048
00049 using namespace std;
00050 using namespace traci;
00051 using namespace tcpip;
00052
00053
00054
00055
00056
00057 bool
00058 TraCIServerAPI_Edge::processGet(tcpip::Storage &inputStorage,
00059 tcpip::Storage &outputStorage,
00060 bool withStatus) throw(TraCIException) {
00061 std::string warning = "";
00062
00063 int variable = inputStorage.readUnsignedByte();
00064 std::string id = inputStorage.readString();
00065
00066 if (variable!=ID_LIST&&variable!=VAR_EDGE_TRAVELTIME&&variable!=VAR_EDGE_EFFORT&&variable!=VAR_CURRENT_TRAVELTIME
00067 &&variable!=LANE_ALLOWED&&variable!=LANE_DISALLOWED
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) {
00073 TraCIServerAPIHelper::writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_ERR, "Get Edge Variable: unsupported variable specified", outputStorage);
00074 return false;
00075 }
00076
00077 Storage tempMsg;
00078
00079 tempMsg.writeUnsignedByte(RESPONSE_GET_EDGE_VARIABLE);
00080 tempMsg.writeUnsignedByte(variable);
00081 tempMsg.writeString(id);
00082
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 {
00089 MSEdge *e = MSEdge::dictionary(id);
00090 if (e==0) {
00091 TraCIServerAPIHelper::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
00097 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) {
00098 TraCIServerAPIHelper::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_FLOAT);
00103 SUMOReal value;
00104 if (!MSNet::getInstance()->getWeightsStorage().retrieveExistingTravelTime(e, 0, time, value)) {
00105 tempMsg.writeFloat(-1);
00106 } else {
00107 tempMsg.writeFloat(value);
00108 }
00109 }
00110 break;
00111 case VAR_EDGE_EFFORT: {
00112
00113 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) {
00114 TraCIServerAPIHelper::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_FLOAT);
00119 SUMOReal value;
00120 if (!MSNet::getInstance()->getWeightsStorage().retrieveExistingEffort(e, 0, time, value)) {
00121 tempMsg.writeFloat(-1);
00122 } else {
00123 tempMsg.writeFloat(value);
00124 }
00125 }
00126 break;
00127 case VAR_CURRENT_TRAVELTIME:
00128 tempMsg.writeUnsignedByte(TYPE_FLOAT);
00129 tempMsg.writeFloat(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_FLOAT);
00152 tempMsg.writeFloat(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_FLOAT);
00162 tempMsg.writeFloat(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_FLOAT);
00172 tempMsg.writeFloat(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_FLOAT);
00182 tempMsg.writeFloat(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_FLOAT);
00192 tempMsg.writeFloat(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_FLOAT);
00202 tempMsg.writeFloat(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_FLOAT);
00212 if (sum!=0) {
00213 tempMsg.writeFloat(HelpersHarmonoise::sum(sum));
00214 } else {
00215 tempMsg.writeFloat(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_FLOAT);
00236 tempMsg.writeFloat(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_FLOAT);
00246 tempMsg.writeFloat(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().getLength();
00273 }
00274 noVehicles += (int) vehs.size();
00275 (*i)->releaseVehicles();
00276 }
00277 tempMsg.writeUnsignedByte(TYPE_FLOAT);
00278 if (noVehicles==0) {
00279 tempMsg.writeFloat(0);
00280 } else {
00281 tempMsg.writeFloat(lengthSum / (SUMOReal) noVehicles);
00282 }
00283 }
00284 break;
00285 default:
00286 break;
00287 }
00288 }
00289 if (withStatus) {
00290 TraCIServerAPIHelper::writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_OK, warning, outputStorage);
00291 }
00292
00293 outputStorage.writeUnsignedByte(0);
00294 outputStorage.writeInt(1 + 4 + tempMsg.size());
00295 outputStorage.writeStorage(tempMsg);
00296 return true;
00297 }
00298
00299
00300 bool
00301 TraCIServerAPI_Edge::processSet(tcpip::Storage &inputStorage,
00302 tcpip::Storage &outputStorage) throw(TraCIException) {
00303 std::string warning = "";
00304
00305 int variable = inputStorage.readUnsignedByte();
00306 if (variable!=VAR_EDGE_TRAVELTIME&&variable!=VAR_EDGE_EFFORT&&variable!=VAR_MAXSPEED) {
00307 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "Change Edge State: unsupported variable specified", outputStorage);
00308 return false;
00309 }
00310
00311 std::string id = inputStorage.readString();
00312 MSEdge *e = MSEdge::dictionary(id);
00313 if (e==0) {
00314 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "Edge '" + id + "' is not known", outputStorage);
00315 return false;
00316 }
00317
00318 int valueDataType = inputStorage.readUnsignedByte();
00319 switch (variable) {
00320 case LANE_ALLOWED: {
00321 if (inputStorage.readUnsignedByte()!=TYPE_STRINGLIST) {
00322 TraCIServerAPIHelper::writeStatusCmd(CMD_GET_EDGE_VARIABLE, RTYPE_ERR, "Allowed vehicle classes must be given as a list of strings.", outputStorage);
00323 return false;
00324 }
00325 std::vector<SUMOVehicleClass> 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
00336 if (inputStorage.readUnsignedByte()!=TYPE_STRINGLIST) {
00337 TraCIServerAPIHelper::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 std::vector<SUMOVehicleClass> 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 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time requires a compund object.", outputStorage);
00352 return false;
00353 }
00354 if (inputStorage.readInt()!=3) {
00355 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time requires begin time, end time, and value as parameter.", outputStorage);
00356 return false;
00357 }
00358
00359 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) {
00360 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The first variable must be the begin time given as int.", outputStorage);
00361 return false;
00362 }
00363 SUMOTime begTime = inputStorage.readInt();
00364
00365 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) {
00366 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The second variable must be the end time given as int.", outputStorage);
00367 return false;
00368 }
00369 SUMOTime endTime = inputStorage.readInt();
00370
00371 if (inputStorage.readUnsignedByte()!=TYPE_FLOAT) {
00372 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The second variable must be the value given as float", outputStorage);
00373 return false;
00374 }
00375 SUMOReal value = inputStorage.readFloat();
00376
00377 MSNet::getInstance()->getWeightsStorage().addTravelTime(e, begTime, endTime, value);
00378 }
00379 break;
00380 case VAR_EDGE_EFFORT: {
00381 if (valueDataType!=TYPE_COMPOUND) {
00382 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort requires a compund object.", outputStorage);
00383 return false;
00384 }
00385 if (inputStorage.readInt()!=3) {
00386 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort requires begin time, end time, and value as parameter.", outputStorage);
00387 return false;
00388 }
00389
00390 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) {
00391 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The first variable must be the begin time given as int.", outputStorage);
00392 return false;
00393 }
00394 SUMOTime begTime = inputStorage.readInt();
00395
00396 if (inputStorage.readUnsignedByte()!=TYPE_INTEGER) {
00397 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The second variable must be the end time given as int.", outputStorage);
00398 return false;
00399 }
00400 SUMOTime endTime = inputStorage.readInt();
00401
00402 if (inputStorage.readUnsignedByte()!=TYPE_FLOAT) {
00403 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The second variable must be the value given as float", outputStorage);
00404 return false;
00405 }
00406 SUMOReal value = inputStorage.readFloat();
00407
00408 MSNet::getInstance()->getWeightsStorage().addEffort(e, begTime, endTime, value);
00409 }
00410 break;
00411 case VAR_MAXSPEED: {
00412
00413 if (valueDataType!=TYPE_FLOAT) {
00414 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_ERR, "The speed must be given as a float.", outputStorage);
00415 return false;
00416 }
00417 SUMOReal val = inputStorage.readFloat();
00418 const std::vector<MSLane*> &lanes = e->getLanes();
00419 for (std::vector<MSLane*>::const_iterator i=lanes.begin(); i!=lanes.end(); ++i) {
00420 (*i)->setMaxSpeed(val);
00421 }
00422 }
00423 break;
00424 default:
00425 break;
00426 }
00427 TraCIServerAPIHelper::writeStatusCmd(CMD_SET_EDGE_VARIABLE, RTYPE_OK, warning, outputStorage);
00428 return true;
00429 }
00430
00431
00432
00433
00434