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 #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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines