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