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