SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00011 // APIs for getting/setting vehicle 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 <microsim/MSNet.h> 00038 #include <microsim/MSInsertionControl.h> 00039 #include <microsim/MSVehicle.h> 00040 #include <microsim/MSLane.h> 00041 #include <microsim/MSEdge.h> 00042 #include <microsim/MSEdgeWeightsStorage.h> 00043 #include <microsim/MSAbstractLaneChangeModel.h> 00044 #include <utils/geom/PositionVector.h> 00045 #include <utils/common/DijkstraRouterTT.h> 00046 #include <utils/common/DijkstraRouterEffort.h> 00047 #include <utils/common/HelpersHBEFA.h> 00048 #include <utils/common/HelpersHarmonoise.h> 00049 #include <utils/common/SUMOVehicleParameter.h> 00050 #include "TraCIConstants.h" 00051 #include "TraCIServerAPI_Simulation.h" 00052 #include "TraCIServerAPI_Vehicle.h" 00053 #include "TraCIServerAPI_VehicleType.h" 00054 00055 #ifdef CHECK_MEMORY_LEAKS 00056 #include <foreign/nvwa/debug_new.h> 00057 #endif // CHECK_MEMORY_LEAKS 00058 00059 00060 // =========================================================================== 00061 // used namespaces 00062 // =========================================================================== 00063 using namespace traci; 00064 00065 00066 // =========================================================================== 00067 // method definitions 00068 // =========================================================================== 00069 bool 00070 TraCIServerAPI_Vehicle::processGet(TraCIServer& server, tcpip::Storage& inputStorage, 00071 tcpip::Storage& outputStorage) { 00072 std::string warning = ""; // additional description for response 00073 // variable & id 00074 int variable = inputStorage.readUnsignedByte(); 00075 std::string id = inputStorage.readString(); 00076 // check variable 00077 if (variable != ID_LIST && variable != VAR_SPEED && variable != VAR_SPEED_WITHOUT_TRACI && variable != VAR_POSITION && variable != VAR_ANGLE 00078 && variable != VAR_ROAD_ID && variable != VAR_LANE_ID && variable != VAR_LANE_INDEX 00079 && variable != VAR_TYPE && variable != VAR_ROUTE_ID && variable != VAR_COLOR 00080 && variable != VAR_LANEPOSITION 00081 && variable != VAR_CO2EMISSION && variable != VAR_COEMISSION && variable != VAR_HCEMISSION && variable != VAR_PMXEMISSION 00082 && variable != VAR_NOXEMISSION && variable != VAR_FUELCONSUMPTION && variable != VAR_NOISEEMISSION 00083 && variable != VAR_EDGE_TRAVELTIME && variable != VAR_EDGE_EFFORT 00084 && variable != VAR_ROUTE_VALID && variable != VAR_EDGES 00085 && variable != VAR_SIGNALS 00086 && variable != VAR_LENGTH && variable != VAR_MAXSPEED && variable != VAR_VEHICLECLASS 00087 && variable != VAR_SPEED_FACTOR && variable != VAR_SPEED_DEVIATION && variable != VAR_EMISSIONCLASS 00088 && variable != VAR_WIDTH && variable != VAR_MINGAP && variable != VAR_SHAPECLASS 00089 && variable != VAR_ACCEL && variable != VAR_DECEL && variable != VAR_IMPERFECTION 00090 && variable != VAR_TAU && variable != VAR_BEST_LANES && variable != DISTANCE_REQUEST 00091 && variable != ID_COUNT 00092 ) { 00093 server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_ERR, "Get Vehicle Variable: unsupported variable specified", outputStorage); 00094 return false; 00095 } 00096 // begin response building 00097 tcpip::Storage tempMsg; 00098 // response-code, variableID, objectID 00099 tempMsg.writeUnsignedByte(RESPONSE_GET_VEHICLE_VARIABLE); 00100 tempMsg.writeUnsignedByte(variable); 00101 tempMsg.writeString(id); 00102 // process request 00103 if (variable == ID_LIST || variable == ID_COUNT) { 00104 std::vector<std::string> ids; 00105 MSVehicleControl& c = MSNet::getInstance()->getVehicleControl(); 00106 for (MSVehicleControl::constVehIt i = c.loadedVehBegin(); i != c.loadedVehEnd(); ++i) { 00107 if ((*i).second->isOnRoad()) { 00108 ids.push_back((*i).first); 00109 } 00110 } 00111 if (variable == ID_LIST) { 00112 tempMsg.writeUnsignedByte(TYPE_STRINGLIST); 00113 tempMsg.writeStringList(ids); 00114 } else { 00115 tempMsg.writeUnsignedByte(TYPE_INTEGER); 00116 tempMsg.writeInt((int) ids.size()); 00117 } 00118 } else { 00119 MSVehicle* v = static_cast<MSVehicle*>(MSNet::getInstance()->getVehicleControl().getVehicle(id)); 00120 if (v == 0) { 00121 server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_ERR, "Vehicle '" + id + "' is not known", outputStorage); 00122 return false; 00123 } 00124 const bool onRoad = v->isOnRoad(); 00125 switch (variable) { 00126 case VAR_SPEED: 00127 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00128 tempMsg.writeDouble(onRoad ? v->getSpeed() : INVALID_DOUBLE_VALUE); 00129 break; 00130 case VAR_SPEED_WITHOUT_TRACI: 00131 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00132 tempMsg.writeDouble(onRoad ? v->getSpeedWithoutTraciInfluence() : INVALID_DOUBLE_VALUE); 00133 break; 00134 case VAR_POSITION: 00135 tempMsg.writeUnsignedByte(POSITION_2D); 00136 tempMsg.writeDouble(onRoad ? v->getPosition().x() : INVALID_DOUBLE_VALUE); 00137 tempMsg.writeDouble(onRoad ? v->getPosition().y() : INVALID_DOUBLE_VALUE); 00138 break; 00139 case VAR_ANGLE: 00140 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00141 tempMsg.writeDouble(onRoad ? v->getAngle() : INVALID_DOUBLE_VALUE); 00142 break; 00143 case VAR_ROAD_ID: 00144 tempMsg.writeUnsignedByte(TYPE_STRING); 00145 tempMsg.writeString(onRoad ? v->getLane()->getEdge().getID() : ""); 00146 break; 00147 case VAR_LANE_ID: 00148 tempMsg.writeUnsignedByte(TYPE_STRING); 00149 tempMsg.writeString(onRoad ? v->getLane()->getID() : ""); 00150 break; 00151 case VAR_LANE_INDEX: 00152 tempMsg.writeUnsignedByte(TYPE_INTEGER); 00153 if (onRoad) { 00154 const std::vector<MSLane*> &lanes = v->getLane()->getEdge().getLanes(); 00155 tempMsg.writeInt((int)std::distance(lanes.begin(), std::find(lanes.begin(), lanes.end(), v->getLane()))); 00156 } else { 00157 tempMsg.writeInt(INVALID_INT_VALUE); 00158 } 00159 break; 00160 case VAR_TYPE: 00161 tempMsg.writeUnsignedByte(TYPE_STRING); 00162 tempMsg.writeString(v->getVehicleType().getID()); 00163 break; 00164 case VAR_ROUTE_ID: 00165 tempMsg.writeUnsignedByte(TYPE_STRING); 00166 tempMsg.writeString(v->getRoute().getID()); 00167 break; 00168 case VAR_COLOR: 00169 tempMsg.writeUnsignedByte(TYPE_COLOR); 00170 tempMsg.writeUnsignedByte(static_cast<int>(v->getParameter().color.red() * 255. + 0.5)); 00171 tempMsg.writeUnsignedByte(static_cast<int>(v->getParameter().color.green() * 255. + 0.5)); 00172 tempMsg.writeUnsignedByte(static_cast<int>(v->getParameter().color.blue() * 255. + 0.5)); 00173 tempMsg.writeUnsignedByte(255); 00174 break; 00175 case VAR_LANEPOSITION: 00176 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00177 tempMsg.writeDouble(onRoad ? v->getPositionOnLane() : INVALID_DOUBLE_VALUE); 00178 break; 00179 case VAR_CO2EMISSION: 00180 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00181 tempMsg.writeDouble(onRoad ? HelpersHBEFA::computeCO2(v->getVehicleType().getEmissionClass(), v->getSpeed(), v->getPreDawdleAcceleration()) : INVALID_DOUBLE_VALUE); 00182 break; 00183 case VAR_COEMISSION: 00184 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00185 tempMsg.writeDouble(onRoad ? HelpersHBEFA::computeCO(v->getVehicleType().getEmissionClass(), v->getSpeed(), v->getPreDawdleAcceleration()) : INVALID_DOUBLE_VALUE); 00186 break; 00187 case VAR_HCEMISSION: 00188 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00189 tempMsg.writeDouble(onRoad ? HelpersHBEFA::computeHC(v->getVehicleType().getEmissionClass(), v->getSpeed(), v->getPreDawdleAcceleration()) : INVALID_DOUBLE_VALUE); 00190 break; 00191 case VAR_PMXEMISSION: 00192 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00193 tempMsg.writeDouble(onRoad ? HelpersHBEFA::computePMx(v->getVehicleType().getEmissionClass(), v->getSpeed(), v->getPreDawdleAcceleration()) : INVALID_DOUBLE_VALUE); 00194 break; 00195 case VAR_NOXEMISSION: 00196 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00197 tempMsg.writeDouble(onRoad ? HelpersHBEFA::computeNOx(v->getVehicleType().getEmissionClass(), v->getSpeed(), v->getPreDawdleAcceleration()) : INVALID_DOUBLE_VALUE); 00198 break; 00199 case VAR_FUELCONSUMPTION: 00200 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00201 tempMsg.writeDouble(onRoad ? HelpersHBEFA::computeFuel(v->getVehicleType().getEmissionClass(), v->getSpeed(), v->getPreDawdleAcceleration()) : INVALID_DOUBLE_VALUE); 00202 break; 00203 case VAR_NOISEEMISSION: 00204 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00205 tempMsg.writeDouble(onRoad ? HelpersHarmonoise::computeNoise(v->getVehicleType().getEmissionClass(), v->getSpeed(), v->getPreDawdleAcceleration()) : INVALID_DOUBLE_VALUE); 00206 break; 00207 case VAR_EDGE_TRAVELTIME: { 00208 if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) { 00209 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Retrieval of travel time requires a compound object.", outputStorage); 00210 return false; 00211 } 00212 if (inputStorage.readInt() != 2) { 00213 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Retrieval of travel time requires time, and edge as parameter.", outputStorage); 00214 return false; 00215 } 00216 // time 00217 if (inputStorage.readUnsignedByte() != TYPE_INTEGER) { 00218 server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_ERR, "Retrieval of travel time requires the referenced time as first parameter.", outputStorage); 00219 return false; 00220 } 00221 SUMOTime time = inputStorage.readInt(); 00222 // edge 00223 if (inputStorage.readUnsignedByte() != TYPE_STRING) { 00224 server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_ERR, "Retrieval of travel time requires the referenced edge as second parameter.", outputStorage); 00225 return false; 00226 } 00227 std::string edgeID = inputStorage.readString(); 00228 MSEdge* edge = MSEdge::dictionary(edgeID); 00229 if (edge == 0) { 00230 server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_ERR, "Referenced edge '" + edgeID + "' is not known.", outputStorage); 00231 return false; 00232 } 00233 // retrieve 00234 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00235 SUMOReal value; 00236 if (!v->getWeightsStorage().retrieveExistingTravelTime(edge, 0, time, value)) { 00237 tempMsg.writeDouble(INVALID_DOUBLE_VALUE); 00238 } else { 00239 tempMsg.writeDouble(value); 00240 } 00241 00242 } 00243 break; 00244 case VAR_EDGE_EFFORT: { 00245 if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) { 00246 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Retrieval of travel time requires a compound object.", outputStorage); 00247 return false; 00248 } 00249 if (inputStorage.readInt() != 2) { 00250 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Retrieval of travel time requires time, and edge as parameter.", outputStorage); 00251 return false; 00252 } 00253 // time 00254 if (inputStorage.readUnsignedByte() != TYPE_INTEGER) { 00255 server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_ERR, "Retrieval of effort requires the referenced time as first parameter.", outputStorage); 00256 return false; 00257 } 00258 SUMOTime time = inputStorage.readInt(); 00259 // edge 00260 if (inputStorage.readUnsignedByte() != TYPE_STRING) { 00261 server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_ERR, "Retrieval of effort requires the referenced edge as second parameter.", outputStorage); 00262 return false; 00263 } 00264 std::string edgeID = inputStorage.readString(); 00265 MSEdge* edge = MSEdge::dictionary(edgeID); 00266 if (edge == 0) { 00267 server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_ERR, "Referenced edge '" + edgeID + "' is not known.", outputStorage); 00268 return false; 00269 } 00270 // retrieve 00271 tempMsg.writeUnsignedByte(TYPE_DOUBLE); 00272 SUMOReal value; 00273 if (!v->getWeightsStorage().retrieveExistingEffort(edge, 0, time, value)) { 00274 tempMsg.writeDouble(INVALID_DOUBLE_VALUE); 00275 } else { 00276 tempMsg.writeDouble(value); 00277 } 00278 00279 } 00280 break; 00281 case VAR_ROUTE_VALID: { 00282 std::string msg; 00283 tempMsg.writeUnsignedByte(TYPE_UBYTE); 00284 tempMsg.writeUnsignedByte(v->hasValidRoute(msg)); 00285 } 00286 break; 00287 case VAR_EDGES: { 00288 const MSRoute& r = v->getRoute(); 00289 tempMsg.writeUnsignedByte(TYPE_STRINGLIST); 00290 tempMsg.writeInt(r.size()); 00291 for (MSRouteIterator i = r.begin(); i != r.end(); ++i) { 00292 tempMsg.writeString((*i)->getID()); 00293 } 00294 } 00295 break; 00296 case VAR_SIGNALS: 00297 tempMsg.writeUnsignedByte(TYPE_INTEGER); 00298 tempMsg.writeInt(v->getSignals()); 00299 break; 00300 case VAR_BEST_LANES: { 00301 tempMsg.writeUnsignedByte(TYPE_COMPOUND); 00302 tcpip::Storage tempContent; 00303 unsigned int cnt = 0; 00304 tempContent.writeUnsignedByte(TYPE_INTEGER); 00305 const std::vector<MSVehicle::LaneQ> &bestLanes = onRoad ? v->getBestLanes() : std::vector<MSVehicle::LaneQ>(); 00306 tempContent.writeInt((int) bestLanes.size()); 00307 ++cnt; 00308 for (std::vector<MSVehicle::LaneQ>::const_iterator i = bestLanes.begin(); i != bestLanes.end(); ++i) { 00309 const MSVehicle::LaneQ& lq = *i; 00310 tempContent.writeUnsignedByte(TYPE_STRING); 00311 tempContent.writeString(lq.lane->getID()); 00312 ++cnt; 00313 tempContent.writeUnsignedByte(TYPE_DOUBLE); 00314 tempContent.writeDouble(lq.length); 00315 ++cnt; 00316 tempContent.writeUnsignedByte(TYPE_DOUBLE); 00317 tempContent.writeDouble(lq.nextOccupation); 00318 ++cnt; 00319 tempContent.writeUnsignedByte(TYPE_BYTE); 00320 tempContent.writeByte(lq.bestLaneOffset); 00321 ++cnt; 00322 tempContent.writeUnsignedByte(TYPE_UBYTE); 00323 lq.allowsContinuation ? tempContent.writeUnsignedByte(1) : tempContent.writeUnsignedByte(0); 00324 ++cnt; 00325 std::vector<std::string> bestContIDs; 00326 for (std::vector<MSLane*>::const_iterator j = lq.bestContinuations.begin(); j != lq.bestContinuations.end(); ++j) { 00327 bestContIDs.push_back((*j)->getID()); 00328 } 00329 tempContent.writeUnsignedByte(TYPE_STRINGLIST); 00330 tempContent.writeStringList(bestContIDs); 00331 ++cnt; 00332 } 00333 tempMsg.writeInt((int) cnt); 00334 tempMsg.writeStorage(tempContent); 00335 } 00336 break; 00337 case DISTANCE_REQUEST: 00338 if (!commandDistanceRequest(server, inputStorage, tempMsg, v)) { 00339 return false; 00340 } 00341 break; 00342 default: 00343 TraCIServerAPI_VehicleType::getVariable(variable, v->getVehicleType(), tempMsg); 00344 break; 00345 } 00346 } 00347 server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_OK, warning, outputStorage); 00348 server.writeResponseWithLength(outputStorage, tempMsg); 00349 return true; 00350 } 00351 00352 00353 bool 00354 TraCIServerAPI_Vehicle::processSet(TraCIServer& server, tcpip::Storage& inputStorage, 00355 tcpip::Storage& outputStorage) { 00356 std::string warning = ""; // additional description for response 00357 // variable 00358 int variable = inputStorage.readUnsignedByte(); 00359 if (variable != CMD_STOP && variable != CMD_CHANGELANE 00360 && variable != CMD_SLOWDOWN && variable != CMD_CHANGETARGET 00361 && variable != VAR_ROUTE_ID && variable != VAR_ROUTE 00362 && variable != VAR_EDGE_TRAVELTIME && variable != VAR_EDGE_EFFORT 00363 && variable != CMD_REROUTE_TRAVELTIME && variable != CMD_REROUTE_EFFORT 00364 && variable != VAR_SIGNALS && variable != VAR_MOVE_TO 00365 && variable != VAR_LENGTH && variable != VAR_MAXSPEED && variable != VAR_VEHICLECLASS 00366 && variable != VAR_SPEED_FACTOR && variable != VAR_SPEED_DEVIATION && variable != VAR_EMISSIONCLASS 00367 && variable != VAR_WIDTH && variable != VAR_MINGAP && variable != VAR_SHAPECLASS 00368 && variable != VAR_ACCEL && variable != VAR_DECEL && variable != VAR_IMPERFECTION 00369 && variable != VAR_TAU 00370 && variable != VAR_SPEED && variable != VAR_SPEEDSETMODE && variable != VAR_COLOR 00371 && variable != ADD && variable != REMOVE 00372 ) { 00373 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Change Vehicle State: unsupported variable specified", outputStorage); 00374 return false; 00375 } 00376 // id 00377 std::string id = inputStorage.readString(); 00378 SUMOVehicle* v = MSNet::getInstance()->getVehicleControl().getVehicle(id); 00379 if (v == 0 && variable != ADD) { 00380 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Vehicle '" + id + "' is not known", outputStorage); 00381 return false; 00382 } 00383 // process 00384 int valueDataType = inputStorage.readUnsignedByte(); 00385 switch (variable) { 00386 case CMD_STOP: { 00387 if (valueDataType != TYPE_COMPOUND) { 00388 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Stop needs a compound object description.", outputStorage); 00389 return false; 00390 } 00391 if (inputStorage.readInt() != 4) { 00392 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Stop needs a compound object description of four items.", outputStorage); 00393 return false; 00394 } 00395 // read road map position 00396 valueDataType = inputStorage.readUnsignedByte(); 00397 if (valueDataType != TYPE_STRING) { 00398 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The first stop parameter must be the edge id given as a string.", outputStorage); 00399 return false; 00400 } 00401 std::string roadId = inputStorage.readString(); 00402 valueDataType = inputStorage.readUnsignedByte(); 00403 if (valueDataType != TYPE_DOUBLE) { 00404 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The second stop parameter must be the position along the edge given as a double.", outputStorage); 00405 return false; 00406 } 00407 SUMOReal pos = inputStorage.readDouble(); 00408 valueDataType = inputStorage.readUnsignedByte(); 00409 if (valueDataType != TYPE_BYTE) { 00410 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The third stop parameter must be the lane index given as a byte.", outputStorage); 00411 return false; 00412 } 00413 int laneIndex = inputStorage.readByte(); 00414 // waitTime 00415 valueDataType = inputStorage.readUnsignedByte(); 00416 if (valueDataType != TYPE_INTEGER) { 00417 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The fourth stop parameter must be the waiting time given as an integer.", outputStorage); 00418 return false; 00419 } 00420 SUMOTime waitTime = inputStorage.readInt(); 00421 // check 00422 if (pos < 0) { 00423 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Position on lane must not be negative", outputStorage); 00424 return false; 00425 } 00426 // get the actual lane that is referenced by laneIndex 00427 MSEdge* road = MSEdge::dictionary(roadId); 00428 if (road == 0) { 00429 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Unable to retrieve road with given id", outputStorage); 00430 return false; 00431 } 00432 const std::vector<MSLane*> &allLanes = road->getLanes(); 00433 if ((laneIndex < 0) || laneIndex >= (int)(allLanes.size())) { 00434 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "No lane existing with such id on the given road", outputStorage); 00435 return false; 00436 } 00437 // Forward command to vehicle 00438 if (!static_cast<MSVehicle*>(v)->addTraciStop(allLanes[laneIndex], pos, 0, waitTime)) { 00439 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Vehicle is too close or behind the stop on " + allLanes[laneIndex]->getID(), outputStorage); 00440 return false; 00441 } 00442 } 00443 break; 00444 case CMD_CHANGELANE: { 00445 if (valueDataType != TYPE_COMPOUND) { 00446 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Lane change needs a compound object description.", outputStorage); 00447 return false; 00448 } 00449 if (inputStorage.readInt() != 2) { 00450 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Lane change needs a compound object description of two items.", outputStorage); 00451 return false; 00452 } 00453 // Lane ID 00454 valueDataType = inputStorage.readUnsignedByte(); 00455 if (valueDataType != TYPE_BYTE) { 00456 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The first lane change parameter must be the lane index given as a byte.", outputStorage); 00457 return false; 00458 } 00459 int laneIndex = inputStorage.readByte(); 00460 // stickyTime 00461 valueDataType = inputStorage.readUnsignedByte(); 00462 if (valueDataType != TYPE_INTEGER) { 00463 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The second lane change parameter must be the duration given as an integer.", outputStorage); 00464 return false; 00465 } 00466 SUMOTime stickyTime = inputStorage.readInt(); 00467 if ((laneIndex < 0) || (laneIndex >= (int)(v->getEdge()->getLanes().size()))) { 00468 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "No lane existing with given id on the current road", outputStorage); 00469 return false; 00470 } 00471 // Forward command to vehicle 00472 std::vector<std::pair<SUMOTime, unsigned int> > laneTimeLine; 00473 laneTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), laneIndex)); 00474 laneTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep() + stickyTime, laneIndex)); 00475 static_cast<MSVehicle*>(v)->getInfluencer().setLaneTimeLine(laneTimeLine); 00476 MSVehicle::ChangeRequest req = static_cast<MSVehicle*>(v)->getInfluencer().checkForLaneChanges(MSNet::getInstance()->getCurrentTimeStep(), 00477 *static_cast<MSVehicle*>(v)->getEdge(), static_cast<MSVehicle*>(v)->getLaneIndex()); 00478 static_cast<MSVehicle*>(v)->getLaneChangeModel().requestLaneChange(req); 00479 } 00480 break; 00481 case CMD_SLOWDOWN: { 00482 if (valueDataType != TYPE_COMPOUND) { 00483 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Slow down needs a compound object description.", outputStorage); 00484 return false; 00485 } 00486 if (inputStorage.readInt() != 2) { 00487 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Slow down needs a compound object description of two items.", outputStorage); 00488 return false; 00489 } 00490 if (inputStorage.readUnsignedByte() != TYPE_DOUBLE) { 00491 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The first slow down parameter must be the speed given as a double.", outputStorage); 00492 return false; 00493 } 00494 SUMOReal newSpeed = MAX2(inputStorage.readDouble(), 0.0); 00495 if (newSpeed < 0) { 00496 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Speed must not be negative", outputStorage); 00497 return false; 00498 } 00499 if (inputStorage.readUnsignedByte() != TYPE_INTEGER) { 00500 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The second slow down parameter must be the duration given as an integer.", outputStorage); 00501 return false; 00502 } 00503 SUMOTime duration = inputStorage.readInt(); 00504 if (duration < 0) { 00505 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Invalid time interval", outputStorage); 00506 return false; 00507 } 00508 std::vector<std::pair<SUMOTime, SUMOReal> > speedTimeLine; 00509 speedTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), v->getSpeed())); 00510 speedTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep() + duration, newSpeed)); 00511 static_cast<MSVehicle*>(v)->getInfluencer().setSpeedTimeLine(speedTimeLine); 00512 } 00513 break; 00514 case CMD_CHANGETARGET: { 00515 if (valueDataType != TYPE_STRING) { 00516 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Change target requires a string containing the id of the new destination edge as parameter.", outputStorage); 00517 return false; 00518 } 00519 std::string edgeID = inputStorage.readString(); 00520 const MSEdge* destEdge = MSEdge::dictionary(edgeID); 00521 if (destEdge == 0) { 00522 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Can not retrieve road with ID " + edgeID, outputStorage); 00523 return false; 00524 } 00525 // build a new route between the vehicle's current edge and destination edge 00526 MSEdgeVector newRoute; 00527 const MSEdge* currentEdge = v->getEdge(); 00528 MSEdgeWeightsStorage empty; 00529 MSNet::EdgeWeightsProxi proxi(empty, MSNet::getInstance()->getWeightsStorage()); 00530 DijkstraRouterTT_ByProxi<MSEdge, SUMOVehicle, prohibited_withRestrictions<MSEdge, SUMOVehicle>, MSNet::EdgeWeightsProxi> router(MSEdge::dictSize(), true, &proxi, &MSNet::EdgeWeightsProxi::getTravelTime); 00531 router.compute(currentEdge, destEdge, (const MSVehicle * const) v, MSNet::getInstance()->getCurrentTimeStep(), newRoute); 00532 // replace the vehicle's route by the new one 00533 if (!v->replaceRouteEdges(newRoute)) { 00534 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Route replacement failed for " + v->getID(), outputStorage); 00535 return false; 00536 } 00537 } 00538 break; 00539 case VAR_ROUTE_ID: { 00540 if (valueDataType != TYPE_STRING) { 00541 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The route id must be given as a string.", outputStorage); 00542 return false; 00543 } 00544 std::string rid = inputStorage.readString(); 00545 const MSRoute* r = MSRoute::dictionary(rid); 00546 if (r == 0) { 00547 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The route '" + rid + "' is not known.", outputStorage); 00548 return false; 00549 } 00550 if (!v->replaceRoute(r)) { 00551 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Route replacement failed for " + v->getID(), outputStorage); 00552 return false; 00553 } 00554 } 00555 break; 00556 case VAR_ROUTE: { 00557 if (valueDataType != TYPE_STRINGLIST) { 00558 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "A route must be defined as a list of edge ids.", outputStorage); 00559 return false; 00560 } 00561 std::vector<std::string> edgeIDs = inputStorage.readStringList(); 00562 std::vector<const MSEdge*> edges; 00563 MSEdge::parseEdgesList(edgeIDs, edges, "<unknown>"); 00564 if (!v->replaceRouteEdges(edges)) { 00565 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Route replacement failed for " + v->getID(), outputStorage); 00566 return false; 00567 } 00568 } 00569 break; 00570 case VAR_EDGE_TRAVELTIME: { 00571 if (valueDataType != TYPE_COMPOUND) { 00572 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time requires a compound object.", outputStorage); 00573 return false; 00574 } 00575 int parameterCount = inputStorage.readInt(); 00576 if (parameterCount == 4) { 00577 // begin time 00578 if (inputStorage.readUnsignedByte() != TYPE_INTEGER) { 00579 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time using 4 parameters requires the begin time as first parameter.", outputStorage); 00580 return false; 00581 } 00582 SUMOTime begTime = inputStorage.readInt(); 00583 // begin time 00584 if (inputStorage.readUnsignedByte() != TYPE_INTEGER) { 00585 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time using 4 parameters requires the end time as second parameter.", outputStorage); 00586 return false; 00587 } 00588 SUMOTime endTime = inputStorage.readInt(); 00589 // edge 00590 if (inputStorage.readUnsignedByte() != TYPE_STRING) { 00591 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time using 4 parameters requires the referenced edge as third parameter.", outputStorage); 00592 return false; 00593 } 00594 std::string edgeID = inputStorage.readString(); 00595 MSEdge* edge = MSEdge::dictionary(edgeID); 00596 if (edge == 0) { 00597 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Referenced edge '" + edgeID + "' is not known.", outputStorage); 00598 return false; 00599 } 00600 // value 00601 if (inputStorage.readUnsignedByte() != TYPE_DOUBLE) { 00602 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time using 4 parameters requires the travel time as fourth parameter.", outputStorage); 00603 return false; 00604 } 00605 SUMOReal value = inputStorage.readDouble(); 00606 // retrieve 00607 static_cast<MSVehicle*>(v)->getWeightsStorage().addTravelTime(edge, begTime, endTime, value); 00608 } else if (parameterCount == 2) { 00609 // edge 00610 if (inputStorage.readUnsignedByte() != TYPE_STRING) { 00611 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time using 2 parameters requires the referenced edge as first parameter.", outputStorage); 00612 return false; 00613 } 00614 std::string edgeID = inputStorage.readString(); 00615 MSEdge* edge = MSEdge::dictionary(edgeID); 00616 if (edge == 0) { 00617 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Referenced edge '" + edgeID + "' is not known.", outputStorage); 00618 return false; 00619 } 00620 // value 00621 if (inputStorage.readUnsignedByte() != TYPE_DOUBLE) { 00622 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time using 2 parameters requires the travel time as second parameter.", outputStorage); 00623 return false; 00624 } 00625 SUMOReal value = inputStorage.readDouble(); 00626 // retrieve 00627 while (static_cast<MSVehicle*>(v)->getWeightsStorage().knowsTravelTime(edge)) { 00628 static_cast<MSVehicle*>(v)->getWeightsStorage().removeTravelTime(edge); 00629 } 00630 static_cast<MSVehicle*>(v)->getWeightsStorage().addTravelTime(edge, 0, SUMOTime_MAX, value); 00631 } else if (parameterCount == 1) { 00632 // edge 00633 if (inputStorage.readUnsignedByte() != TYPE_STRING) { 00634 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time using 1 parameter requires the referenced edge as first parameter.", outputStorage); 00635 return false; 00636 } 00637 std::string edgeID = inputStorage.readString(); 00638 MSEdge* edge = MSEdge::dictionary(edgeID); 00639 if (edge == 0) { 00640 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Referenced edge '" + edgeID + "' is not known.", outputStorage); 00641 return false; 00642 } 00643 // retrieve 00644 while (static_cast<MSVehicle*>(v)->getWeightsStorage().knowsTravelTime(edge)) { 00645 static_cast<MSVehicle*>(v)->getWeightsStorage().removeTravelTime(edge); 00646 } 00647 } else { 00648 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting travel time requires 1, 2, or 4 parameters.", outputStorage); 00649 return false; 00650 } 00651 } 00652 break; 00653 case VAR_EDGE_EFFORT: { 00654 if (valueDataType != TYPE_COMPOUND) { 00655 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort requires a compound object.", outputStorage); 00656 return false; 00657 } 00658 int parameterCount = inputStorage.readInt(); 00659 if (parameterCount == 4) { 00660 // begin time 00661 if (inputStorage.readUnsignedByte() != TYPE_INTEGER) { 00662 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort using 4 parameters requires the begin time as first parameter.", outputStorage); 00663 return false; 00664 } 00665 SUMOTime begTime = inputStorage.readInt(); 00666 // begin time 00667 if (inputStorage.readUnsignedByte() != TYPE_INTEGER) { 00668 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort using 4 parameters requires the end time as second parameter.", outputStorage); 00669 return false; 00670 } 00671 SUMOTime endTime = inputStorage.readInt(); 00672 // edge 00673 if (inputStorage.readUnsignedByte() != TYPE_STRING) { 00674 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort using 4 parameters requires the referenced edge as third parameter.", outputStorage); 00675 return false; 00676 } 00677 std::string edgeID = inputStorage.readString(); 00678 MSEdge* edge = MSEdge::dictionary(edgeID); 00679 if (edge == 0) { 00680 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Referenced edge '" + edgeID + "' is not known.", outputStorage); 00681 return false; 00682 } 00683 // value 00684 if (inputStorage.readUnsignedByte() != TYPE_DOUBLE) { 00685 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort using 4 parameters requires the travel time as fourth parameter.", outputStorage); 00686 return false; 00687 } 00688 SUMOReal value = inputStorage.readDouble(); 00689 // retrieve 00690 static_cast<MSVehicle*>(v)->getWeightsStorage().addEffort(edge, begTime, endTime, value); 00691 } else if (parameterCount == 2) { 00692 // edge 00693 if (inputStorage.readUnsignedByte() != TYPE_STRING) { 00694 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort using 2 parameters requires the referenced edge as first parameter.", outputStorage); 00695 return false; 00696 } 00697 std::string edgeID = inputStorage.readString(); 00698 MSEdge* edge = MSEdge::dictionary(edgeID); 00699 if (edge == 0) { 00700 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Referenced edge '" + edgeID + "' is not known.", outputStorage); 00701 return false; 00702 } 00703 // value 00704 if (inputStorage.readUnsignedByte() != TYPE_DOUBLE) { 00705 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort using 2 parameters requires the travel time as second parameter.", outputStorage); 00706 return false; 00707 } 00708 SUMOReal value = inputStorage.readDouble(); 00709 // retrieve 00710 while (static_cast<MSVehicle*>(v)->getWeightsStorage().knowsEffort(edge)) { 00711 static_cast<MSVehicle*>(v)->getWeightsStorage().removeEffort(edge); 00712 } 00713 static_cast<MSVehicle*>(v)->getWeightsStorage().addEffort(edge, 0, SUMOTime_MAX, value); 00714 } else if (parameterCount == 1) { 00715 // edge 00716 if (inputStorage.readUnsignedByte() != TYPE_STRING) { 00717 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort using 1 parameter requires the referenced edge as first parameter.", outputStorage); 00718 return false; 00719 } 00720 std::string edgeID = inputStorage.readString(); 00721 MSEdge* edge = MSEdge::dictionary(edgeID); 00722 if (edge == 0) { 00723 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Referenced edge '" + edgeID + "' is not known.", outputStorage); 00724 return false; 00725 } 00726 // retrieve 00727 while (static_cast<MSVehicle*>(v)->getWeightsStorage().knowsEffort(edge)) { 00728 static_cast<MSVehicle*>(v)->getWeightsStorage().removeEffort(edge); 00729 } 00730 } else { 00731 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting effort requires 1, 2, or 4 parameters.", outputStorage); 00732 return false; 00733 } 00734 } 00735 break; 00736 case CMD_REROUTE_TRAVELTIME: { 00737 if (valueDataType != TYPE_COMPOUND) { 00738 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Rerouting requires a compound object.", outputStorage); 00739 return false; 00740 } 00741 if (inputStorage.readInt() != 0) { 00742 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Rerouting should obtain an empty compound object.", outputStorage); 00743 return false; 00744 } 00745 MSNet::EdgeWeightsProxi proxi(static_cast<MSVehicle*>(v)->getWeightsStorage(), MSNet::getInstance()->getWeightsStorage()); 00746 DijkstraRouterTT_ByProxi<MSEdge, SUMOVehicle, prohibited_withRestrictions<MSEdge, SUMOVehicle>, MSNet::EdgeWeightsProxi> router(MSEdge::dictSize(), true, &proxi, &MSNet::EdgeWeightsProxi::getTravelTime); 00747 v->reroute(MSNet::getInstance()->getCurrentTimeStep(), router); 00748 } 00749 break; 00750 case CMD_REROUTE_EFFORT: { 00751 if (valueDataType != TYPE_COMPOUND) { 00752 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Rerouting requires a compound object.", outputStorage); 00753 return false; 00754 } 00755 if (inputStorage.readInt() != 0) { 00756 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Rerouting should obtain an empty compound object.", outputStorage); 00757 return false; 00758 } 00759 MSNet::EdgeWeightsProxi proxi(static_cast<MSVehicle*>(v)->getWeightsStorage(), MSNet::getInstance()->getWeightsStorage()); 00760 DijkstraRouterEffort_ByProxi<MSEdge, SUMOVehicle, prohibited_withRestrictions<MSEdge, SUMOVehicle>, MSNet::EdgeWeightsProxi> router(MSEdge::dictSize(), true, &proxi, &MSNet::EdgeWeightsProxi::getEffort, &MSNet::EdgeWeightsProxi::getTravelTime); 00761 v->reroute(MSNet::getInstance()->getCurrentTimeStep(), router); 00762 } 00763 break; 00764 case VAR_SIGNALS: 00765 if (valueDataType != TYPE_INTEGER) { 00766 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting signals requires an integer.", outputStorage); 00767 return false; 00768 } 00769 static_cast<MSVehicle*>(v)->switchOffSignal(0x0fffffff); 00770 static_cast<MSVehicle*>(v)->switchOnSignal(inputStorage.readInt()); 00771 break; 00772 case VAR_MOVE_TO: { 00773 if (valueDataType != TYPE_COMPOUND) { 00774 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting position requires a compound object.", outputStorage); 00775 return false; 00776 } 00777 if (inputStorage.readInt() != 2) { 00778 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting position should obtain the lane id and the position.", outputStorage); 00779 return false; 00780 } 00781 // lane ID 00782 if (inputStorage.readUnsignedByte() != TYPE_STRING) { 00783 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The first parameter for setting a position must be the lane ID given as a string.", outputStorage); 00784 return false; 00785 } 00786 std::string laneID = inputStorage.readString(); 00787 // position on lane 00788 if (inputStorage.readUnsignedByte() != TYPE_DOUBLE) { 00789 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The second parameter for setting a position must be the position given as a double.", outputStorage); 00790 return false; 00791 } 00792 SUMOReal position = inputStorage.readDouble(); 00793 // process 00794 MSLane* l = MSLane::dictionary(laneID); 00795 if (l == 0) { 00796 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Unknown lane '" + laneID + "'.", outputStorage); 00797 return false; 00798 } 00799 MSEdge& destinationEdge = l->getEdge(); 00800 if (!static_cast<MSVehicle*>(v)->willPass(&destinationEdge)) { 00801 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Vehicle '" + laneID + "' may be set onto an edge to pass only.", outputStorage); 00802 return false; 00803 } 00804 static_cast<MSVehicle*>(v)->onRemovalFromNet(MSMoveReminder::NOTIFICATION_TELEPORT); 00805 static_cast<MSVehicle*>(v)->getLane()->removeVehicle(static_cast<MSVehicle*>(v)); 00806 while (v->getEdge() != &destinationEdge) { 00807 const MSEdge* nextEdge = v->succEdge(1); 00808 // let the vehicle move to the next edge 00809 if (static_cast<MSVehicle*>(v)->enterLaneAtMove(nextEdge->getLanes()[0], true)) { 00810 MSNet::getInstance()->getVehicleControl().scheduleVehicleRemoval(v); 00811 continue; 00812 } 00813 } 00814 l->forceVehicleInsertion(static_cast<MSVehicle*>(v), position); 00815 } 00816 break; 00817 case VAR_SPEED: { 00818 if (valueDataType != TYPE_DOUBLE) { 00819 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting speed requires a double.", outputStorage); 00820 return false; 00821 } 00822 SUMOReal speed = inputStorage.readDouble(); 00823 std::vector<std::pair<SUMOTime, SUMOReal> > speedTimeLine; 00824 if (speed >= 0) { 00825 speedTimeLine.push_back(std::make_pair(MSNet::getInstance()->getCurrentTimeStep(), speed)); 00826 speedTimeLine.push_back(std::make_pair(SUMOTime_MAX, speed)); 00827 } 00828 static_cast<MSVehicle*>(v)->getInfluencer().setSpeedTimeLine(speedTimeLine); 00829 } 00830 break; 00831 case VAR_SPEEDSETMODE: { 00832 if (valueDataType != TYPE_INTEGER) { 00833 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Setting speed requires a double.", outputStorage); 00834 return false; 00835 } 00836 int speedMode = inputStorage.readInt(); 00837 static_cast<MSVehicle*>(v)->getInfluencer().setConsiderSafeVelocity((speedMode & 1) != 0); 00838 static_cast<MSVehicle*>(v)->getInfluencer().setConsiderMaxAcceleration((speedMode & 2) != 0); 00839 static_cast<MSVehicle*>(v)->getInfluencer().setConsiderMaxDeceleration((speedMode & 4) != 0); 00840 } 00841 break; 00842 case VAR_COLOR: { 00843 if (valueDataType != TYPE_COLOR) { 00844 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The color must be given using the according type.", outputStorage); 00845 return false; 00846 } 00847 SUMOReal r = (SUMOReal) inputStorage.readUnsignedByte() / 255.; 00848 SUMOReal g = (SUMOReal) inputStorage.readUnsignedByte() / 255.; 00849 SUMOReal b = (SUMOReal) inputStorage.readUnsignedByte() / 255.; 00850 inputStorage.readUnsignedByte(); // skip alpha level 00851 v->getParameter().color.set(r, g, b); 00852 } 00853 break; 00854 case ADD: { 00855 if (v != 0) { 00856 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "The vehicle " + id + " to add already exists.", outputStorage); 00857 return false; 00858 } 00859 if (valueDataType != TYPE_COMPOUND) { 00860 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Adding a vehicle requires a compound object.", outputStorage); 00861 return false; 00862 } 00863 if (inputStorage.readInt() != 6) { 00864 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Adding a vehicle needs six parameters.", outputStorage); 00865 return false; 00866 } 00867 SUMOVehicleParameter vehicleParams; 00868 vehicleParams.id = id; 00869 00870 if (inputStorage.readUnsignedByte() != TYPE_STRING) { 00871 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "First parameter (type) requires a string.", outputStorage); 00872 return false; 00873 } 00874 MSVehicleType* vehicleType = MSNet::getInstance()->getVehicleControl().getVType(inputStorage.readString()); 00875 if (!vehicleType) { 00876 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Invalid type for vehicle: '" + id + "'"); 00877 return false; 00878 } 00879 00880 if (inputStorage.readUnsignedByte() != TYPE_STRING) { 00881 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Second parameter (route) requires a string.", outputStorage); 00882 return false; 00883 } 00884 const std::string routeID = inputStorage.readString(); 00885 const MSRoute* route = MSRoute::dictionary(routeID); 00886 if (!route) { 00887 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Invalid route '" + routeID + "' for vehicle: '" + id + "'"); 00888 return false; 00889 } 00890 00891 if (inputStorage.readUnsignedByte() != TYPE_INTEGER) { 00892 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Third parameter (depart) requires an integer.", outputStorage); 00893 return false; 00894 } 00895 vehicleParams.depart = inputStorage.readInt(); 00896 if (vehicleParams.depart < 0) { 00897 const int proc = static_cast<int>(-vehicleParams.depart); 00898 if (proc >= static_cast<int>(DEPART_DEF_MAX)) { 00899 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Invalid departure time.", outputStorage); 00900 return false; 00901 } 00902 vehicleParams.departProcedure = (DepartDefinition)proc; 00903 } 00904 00905 if (inputStorage.readUnsignedByte() != TYPE_DOUBLE) { 00906 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Fourth parameter (position) requires a double.", outputStorage); 00907 return false; 00908 } 00909 vehicleParams.departPos = inputStorage.readDouble(); 00910 if (vehicleParams.departPos < 0) { 00911 const int proc = static_cast<int>(-vehicleParams.departPos); 00912 if (proc >= static_cast<int>(DEPART_POS_DEF_MAX)) { 00913 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Invalid departure position.", outputStorage); 00914 return false; 00915 } 00916 vehicleParams.departPosProcedure = (DepartPosDefinition)proc; 00917 } else { 00918 vehicleParams.departPosProcedure = DEPART_POS_GIVEN; 00919 } 00920 00921 if (inputStorage.readUnsignedByte() != TYPE_DOUBLE) { 00922 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Fifth parameter (speed) requires a double.", outputStorage); 00923 return false; 00924 } 00925 vehicleParams.departSpeed = inputStorage.readDouble(); 00926 if (vehicleParams.departSpeed < 0) { 00927 const int proc = static_cast<int>(-vehicleParams.departSpeed); 00928 if (proc >= static_cast<int>(DEPART_SPEED_DEF_MAX)) { 00929 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Invalid departure speed.", outputStorage); 00930 return false; 00931 } 00932 vehicleParams.departSpeedProcedure = (DepartSpeedDefinition)proc; 00933 } else { 00934 vehicleParams.departSpeedProcedure = DEPART_SPEED_GIVEN; 00935 } 00936 00937 if (inputStorage.readUnsignedByte() != TYPE_BYTE) { 00938 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Sixth parameter (lane) requires a byte.", outputStorage); 00939 return false; 00940 } 00941 vehicleParams.departLane = inputStorage.readByte(); 00942 if (vehicleParams.departLane < 0) { 00943 const int proc = static_cast<int>(-vehicleParams.departLane); 00944 if (proc >= static_cast<int>(DEPART_LANE_DEF_MAX)) { 00945 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Invalid departure lane.", outputStorage); 00946 return false; 00947 } 00948 vehicleParams.departLaneProcedure = (DepartLaneDefinition)proc; 00949 } else { 00950 vehicleParams.departLaneProcedure = DEPART_LANE_GIVEN; 00951 } 00952 00953 SUMOVehicleParameter* params = new SUMOVehicleParameter(); 00954 *params = vehicleParams; 00955 try { 00956 SUMOVehicle* vehicle = MSNet::getInstance()->getVehicleControl().buildVehicle(params, route, vehicleType); 00957 MSNet::getInstance()->getVehicleControl().addVehicle(vehicleParams.id, vehicle); 00958 MSNet::getInstance()->getInsertionControl().add(vehicle); 00959 } catch (ProcessError& e) { 00960 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, e.what(), outputStorage); 00961 return false; 00962 } 00963 } 00964 break; 00965 case REMOVE: { 00966 if (valueDataType != TYPE_BYTE) { 00967 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, "Removing a vehicle requires an int.", outputStorage); 00968 return false; 00969 } 00970 int why = (int) inputStorage.readByte(); 00971 MSMoveReminder::Notification n = MSMoveReminder::NOTIFICATION_ARRIVED; 00972 switch (why) { 00973 case 0: 00974 n = MSMoveReminder::NOTIFICATION_TELEPORT; 00975 break; 00976 case 1: 00977 n = MSMoveReminder::NOTIFICATION_PARKING; 00978 break; 00979 case 2: 00980 n = MSMoveReminder::NOTIFICATION_ARRIVED; 00981 break; 00982 case 3: 00983 n = MSMoveReminder::NOTIFICATION_VAPORIZED; 00984 break; 00985 case 4: 00986 default: 00987 n = MSMoveReminder::NOTIFICATION_TELEPORT_ARRIVED; 00988 break; 00989 } 00990 static_cast<MSVehicle*>(v)->onRemovalFromNet(n); 00991 static_cast<MSVehicle*>(v)->getLane()->removeVehicle(static_cast<MSVehicle*>(v)); 00992 MSNet::getInstance()->getVehicleControl().scheduleVehicleRemoval(static_cast<MSVehicle*>(v)); 00993 } 00994 break; 00995 default: 00996 try { 00997 if (!TraCIServerAPI_VehicleType::setVariable(CMD_SET_VEHICLE_VARIABLE, variable, valueDataType, 00998 getSingularType(v), server, inputStorage, outputStorage)) { 00999 return false; 01000 } 01001 } catch (ProcessError& e) { 01002 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_ERR, e.what(), outputStorage); 01003 return false; 01004 } 01005 break; 01006 } 01007 server.writeStatusCmd(CMD_SET_VEHICLE_VARIABLE, RTYPE_OK, warning, outputStorage); 01008 return true; 01009 } 01010 01011 01012 bool 01013 TraCIServerAPI_Vehicle::commandDistanceRequest(traci::TraCIServer& server, tcpip::Storage& inputStorage, 01014 tcpip::Storage& outputStorage, const MSVehicle* v) { 01015 if (inputStorage.readUnsignedByte() != TYPE_COMPOUND) { 01016 server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_ERR, "Retrieval of distance requires a compound object.", outputStorage); 01017 return false; 01018 } 01019 if (inputStorage.readInt() != 2) { 01020 server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_ERR, "Retrieval of distance requires position and distance type as parameter.", outputStorage); 01021 return false; 01022 } 01023 01024 Position pos; 01025 std::pair<const MSLane*, SUMOReal> roadPos; 01026 01027 // read position 01028 int posType = inputStorage.readUnsignedByte(); 01029 switch (posType) { 01030 case POSITION_ROADMAP: 01031 try { 01032 std::string roadID = inputStorage.readString(); 01033 roadPos.second = inputStorage.readDouble(); 01034 roadPos.first = TraCIServerAPI_Simulation::getLaneChecking(roadID, inputStorage.readUnsignedByte(), roadPos.second); 01035 pos = roadPos.first->getShape().positionAtLengthPosition(roadPos.second); 01036 } catch (TraCIException& e) { 01037 server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_ERR, e.what()); 01038 return false; 01039 } 01040 break; 01041 case POSITION_2D: 01042 case POSITION_3D: { 01043 const double p1x = inputStorage.readDouble(); 01044 const double p1y = inputStorage.readDouble(); 01045 pos.set(p1x, p1y); 01046 } 01047 if (posType == POSITION_3D) { 01048 inputStorage.readDouble(); // z value is ignored 01049 } 01050 roadPos = TraCIServerAPI_Simulation::convertCartesianToRoadMap(pos); 01051 break; 01052 default: 01053 server.writeStatusCmd(CMD_GET_VEHICLE_VARIABLE, RTYPE_ERR, "Unknown position format used for distance request"); 01054 return false; 01055 } 01056 01057 // read distance type 01058 int distType = inputStorage.readUnsignedByte(); 01059 01060 SUMOReal distance = INVALID_DOUBLE_VALUE; 01061 if (v->isOnRoad()) { 01062 if (distType == REQUEST_DRIVINGDIST) { 01063 distance = v->getRoute().getDistanceBetween(v->getPositionOnLane(), roadPos.second, 01064 v->getEdge(), &roadPos.first->getEdge()); 01065 if (distance == std::numeric_limits<SUMOReal>::max()) { 01066 distance = INVALID_DOUBLE_VALUE; 01067 } 01068 } else { 01069 // compute air distance (default) 01070 distance = v->getPosition().distanceTo(pos); 01071 } 01072 } 01073 // write response command 01074 outputStorage.writeUnsignedByte(TYPE_DOUBLE); 01075 outputStorage.writeDouble(distance); 01076 return true; 01077 } 01078 01079 // ------ helper functions ------ 01080 MSVehicleType& 01081 TraCIServerAPI_Vehicle::getSingularType(SUMOVehicle* const veh) { 01082 const MSVehicleType& oType = veh->getVehicleType(); 01083 std::string newID = oType.getID().find('@') == std::string::npos ? oType.getID() + "@" + veh->getID() : oType.getID(); 01084 MSVehicleType* type = MSVehicleType::build(newID, &oType); 01085 static_cast<MSVehicle*>(veh)->replaceVehicleType(type); 01086 return *type; 01087 } 01088 01089 #endif 01090 01091 01092 /****************************************************************************/ 01093