SUMO - Simulation of Urban MObility

TraCIServerAPI_Vehicle.cpp

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