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