TraCIServer.h

Go to the documentation of this file.
00001 /****************************************************************************/
00010 /****************************************************************************/
00011 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00012 // Copyright 2001-2010 DLR (http://www.dlr.de/) and contributors
00013 /****************************************************************************/
00014 //
00015 //   This program is free software; you can redistribute it and/or modify
00016 //   it under the terms of the GNU General Public License as published by
00017 //   the Free Software Foundation; either version 2 of the License, or
00018 //   (at your option) any later version.
00019 //
00020 /****************************************************************************/
00021 #ifndef TRACISERVER_H
00022 #define TRACISERVER_H
00023 
00024 
00025 // ===========================================================================
00026 // included modules
00027 // ===========================================================================
00028 #ifdef _MSC_VER
00029 #include <windows_config.h>
00030 #else
00031 #include <config.h>
00032 #endif
00033 
00034 #ifndef NO_TRACI
00035 
00036 #include "TraCIConstants.h"
00037 
00038 #define BUILD_TCPIP
00039 #include <foreign/tcpip/socket.h>
00040 #include <foreign/tcpip/storage.h>
00041 #include <utils/common/SUMOTime.h>
00042 
00043 #include <utils/geom/Boundary.h>
00044 #include <utils/geom/Position2D.h>
00045 #include <utils/geom/GeomHelper.h>
00046 #include <utils/shapes/Polygon2D.h>
00047 #include <utils/shapes/PointOfInterest.h>
00048 #include <utils/options/OptionsCont.h>
00049 #include <microsim/MSVehicle.h>
00050 #include <microsim/MSNet.h>
00051 #include <microsim/traffic_lights/MSTrafficLightLogic.h>
00052 #include "TraCIException.h"
00053 
00054 #include <map>
00055 #include <string>
00056 #include <set>
00057 
00058 
00059 // ===========================================================================
00060 // class definitions
00061 // ===========================================================================
00065 namespace traci {
00066 // TraCIServer
00067 // Allows communication of sumo with external program. The external
00068 // program will control sumo.
00069 class TraCIServer : public MSNet::VehicleStateListener {
00070 public:
00071 
00072     struct RoadMapPos {
00073         std::string roadId;
00074         float pos;
00075         unsigned char laneId;
00076 
00077         RoadMapPos(): roadId(""), pos(0), laneId(0) {};
00078     };
00079 
00080     // process all commands until a simulation step is wanted
00081     static void processCommandsUntilSimStep(SUMOTime step) throw(ProcessError);
00082 
00083     // check whether close was requested
00084     static bool wasClosed();
00085 
00086     // check whether close was requested
00087     static void close();
00088 
00089     void vehicleStateChanged(const MSVehicle * const vehicle, MSNet::VehicleState to) throw();
00090 
00091 private:
00092 
00093     // Constructor
00094     // Reads the needed parameters out of static OptionsCont
00095     TraCIServer();
00096 
00097     // Destructor
00098     // final cleanup
00099     virtual ~TraCIServer(void) throw();
00100 
00101     int dispatchCommand() throw(TraCIException, std::invalid_argument);
00102 
00103     // process command setMaximumSpeed
00104     // This command causes the node given by nodeId to limit its speed to a maximum speed (float).
00105     // If maximum speed is set to a negative value, the individual speed limit for that node gets annihilated.
00106     // @param in contains unparsed parameters targetTime, ResultType
00107     // @param out contains node positions ready for output
00108     // @param length message length
00109     bool commandSetMaximumSpeed() throw(TraCIException, std::invalid_argument);
00110 
00111     // process command simStep
00112     // This is the basic comman that encourage the mobility generator to simulate up to the given TargetTime.
00113     // Normaly, the network simulator sends this command every time unit to gain actual node positions.
00114     // Probably, the node positions can be desribed in a x- and y-position in a simualated 2D-world.
00115     // But node positions can be represented in many more ways, e.g. 2.5D, 3D or as points on a road network.
00116     // The desired representation of positions is given by the entry ResultType.
00117     // If more than one representation is needed, the command simulation step can be sent several times with the same Target Time and different ResultTypes.
00118     void postProcessSimulationStep() throw(TraCIException, std::invalid_argument);
00119     void postProcessSimulationStep2() throw(TraCIException, std::invalid_argument);
00120 
00121     bool commandStopNode() throw(TraCIException, std::invalid_argument);
00122 
00123     bool commandChangeLane() throw(TraCIException, std::invalid_argument);
00124 
00125     bool commandChangeRoute() throw(TraCIException, std::invalid_argument);
00126 
00127     bool commandChangeTarget() throw(TraCIException, std::invalid_argument);
00128 
00129     bool commandCloseConnection() throw(TraCIException);
00130 
00131     bool commandSimulationParameter() throw(TraCIException);
00132 
00133     // process command getTLStatus
00134     // The traffic light with the given id is asked for all state transitions, that will occur  within
00135     // a given time interval. Each status change is returned by a TLSwitch command.
00136     bool commandGetTLStatus() throw(TraCIException);
00137 
00138     // process command slowDown
00139     // Tell the node given by nodeID to slow down to the given speed (float) within the time intervall
00140     // given by duration. This simulates different methods of slowing down, like instant braking, coasting...
00141     // It's assumed that the speed reduction is linear
00142     // @param in contains nodeID(integer), speed (float), duration(double)
00143     bool commandSlowDown() throw(TraCIException);
00144 
00145     // command getAllTLIds
00146     // Returns a list of strings representing the ids of all traffic lights in the simulation
00147     bool commandGetAllTLIds() throw(TraCIException);
00148 
00149     bool commandUpdateCalibrator() throw(TraCIException);
00150 
00151     bool commandPositionConversion() throw(TraCIException);
00152 
00153     bool commandScenario() throw(TraCIException);
00154 
00155     bool commandAddVehicle() throw(TraCIException);
00156 
00157     bool commandDistanceRequest() throw(TraCIException);
00158 
00159     bool commandSubscribeLifecycles() throw(TraCIException);
00160 
00161     bool commandUnsubscribeLifecycles() throw(TraCIException);
00162 
00163     bool commandSubscribeDomain() throw(TraCIException);
00164 
00165     bool commandUnsubscribeDomain() throw(TraCIException);
00166 
00167 
00168     void writeStatusCmd(int commandId, int status, std::string description);
00169 
00182     std::string handleRoadMapDomain(bool isWriteCommand, tcpip::Storage& response) throw(TraCIException);
00183 
00188     std::string handleVehicleDomain(bool isWriteCommand, tcpip::Storage& response) throw(TraCIException);
00189 
00194     std::string handleTrafficLightDomain(bool isWriteCommand, tcpip::Storage& response) throw(TraCIException);
00195 
00200     std::string handlePoiDomain(bool isWriteCommand, tcpip::Storage& response) throw(TraCIException);
00201 
00206     std::string handlePolygonDomain(bool isWriteCommand, tcpip::Storage& response) throw(TraCIException);
00207 
00211     void handleLifecycleSubscriptions() throw(TraCIException);
00212 
00216     void handleDomainSubscriptions(const SUMOTime& currentTime, const std::map<int, const MSVehicle*>& activeEquippedVehicles) throw(TraCIException);
00217 
00218 
00219     bool addSubscription(int commandId) throw(TraCIException);
00220 
00227     TraCIServer::RoadMapPos convertCartesianToRoadMap(Position2D pos);
00228 
00235     Position2D convertRoadMapToCartesian(TraCIServer::RoadMapPos pos) throw(TraCIException);
00236 
00237     // singleton instance of the server
00238     static TraCIServer* instance_;
00239 
00240     // socket on which server is listening on
00241     tcpip::Socket* socket_;
00242 
00243     // simulation begin and end time
00244     SUMOTime targetTime_;
00245 
00246     // penetration rate, measurement of equipped vehicles in simulation
00247     float penetration_;
00248 
00249     // routeFile name of file which contains vehicle routes
00250     std::string routeFile_;
00251 
00252     // maps all internal vehicle ids to external id if equipped else to -1
00253     // Set isMapChanged_ to true, if altering this map
00254     std::map<std::string, int> equippedVehicles_;
00255 
00256     // maps all external vehicle ids to internal id
00257     // use method convertExt2IntId instead of accessing the map directly!!!
00258     std::map<int, std::string> ext2intId;
00259     bool isMapChanged_;
00260     void convertExt2IntId(int extId, std::string& intId);
00261 
00262     // maps all internal traffic light ids to external ids
00263     std::map<int, std::string> trafficLightsExt2IntId;
00264     // maps all external traffic light ids to internal ids
00265     std::map<std::string, int> trafficLightsInt2ExtId;
00266 
00267     // maps all internal point of interest ids to external ids
00268     std::map<int, std::string> poiExt2IntId;
00269     // maps all external point of interest ids to internal ids
00270     std::map<std::string, int> poiInt2ExtId;
00271 
00272     // maps all internal polygon ids to external ids
00273     std::map<int, std::string> polygonExt2IntId;
00274     // maps all external polygon ids to internal ids
00275     std::map<std::string, int> polygonInt2ExtId;
00276 
00277     // return vehicle that is referenced by the given external id
00278     MSVehicle* getVehicleByExtId(int extId);
00279 
00280     // return traffic light logic that is referenced by the given external id
00281     MSTrafficLightLogic* getTLLogicByExtId(int extId);
00282 
00283     // return point of interest that is referenced by the given external id
00284     PointOfInterest* getPoiByExtId(int extId);
00285 
00286     // return polygon that is referenced by the given external id
00287     Polygon2D* getPolygonByExtId(int extId);
00288 
00289     // hold number of all equipped vehicles
00290     int numEquippedVehicles_;
00291 
00292     // maximum number of vehicles within the simulation
00293     int totalNumVehicles_;
00294 
00295     // holds all Domain Ids to whose objects' lifecycle the client subscribed
00296     std::set<int> myLifecycleSubscriptions;
00297 
00298     // holds all Domain Ids to whose objects the client subscribed, along with the variable/type pairs the client is subscribed to
00299     std::map<int, std::list<std::pair<int, int> > > myDomainSubscriptions;
00300 
00301     // external ids of all vehicles that are currently "living", i.e. have been created, but not yet destroyed
00302     std::set<int> myLivingVehicles;
00303 
00304     // external ids of all vehicles that have entered the simulation get inserted here
00305     std::set<int> myCreatedVehicles;
00306 
00307     // external ids of all vehicles that have quit the simulation get inserted here
00308     std::set<int> myDestroyedVehicles;
00309 
00310     static bool closeConnection_;
00311 
00312     Boundary* netBoundary_;
00313     const Boundary& getNetBoundary();
00314 
00315     tcpip::Storage myInputStorage;
00316     tcpip::Storage myOutputStorage;
00317     bool myDoingSimStep;
00318     int simStepCommand;
00319 
00320     std::set<MSVehicle*> myVehiclesToReroute;
00321 
00322     class Subscription {
00323     public:
00324         Subscription(int commandIdArg, const std::string &idArg, const std::vector<int> &variablesArg,
00325                      SUMOTime beginTimeArg, SUMOTime endTimeArg)
00326                 : commandId(commandIdArg), id(idArg), variables(variablesArg), beginTime(beginTimeArg), endTime(endTimeArg) {}
00327         int commandId;
00328         std::string id;
00329         std::vector<int> variables;
00330         SUMOTime beginTime;
00331         SUMOTime endTime;
00332 
00333     };
00334 
00335     std::vector<Subscription> mySubscriptions;
00336 
00337     bool processSingleSubscription(const TraCIServer::Subscription &s, tcpip::Storage &writeInto,
00338                                    std::string &errors) throw(TraCIException);
00339 
00340     std::map<MSNet::VehicleState, std::vector<std::string> > myVehicleStateChanges;
00341 
00342 };
00343 
00344 // Helper class for reading different data type values out of a storage message
00345 class DataTypeContainer {
00346 private:
00347     int intValue;
00348     double realValue;
00349     std::string stringValue;
00350     TraCIServer::RoadMapPos roadPosValue;
00351     float posXValue;
00352     float posYValue;
00353     float posZValue;
00354 
00355     int lastValueRead;
00356 
00357 public:
00358     DataTypeContainer() :lastValueRead(-1) {};
00359 
00360     void readValue(unsigned char dataType, tcpip::Storage& msg) throw(TraCIException) {
00361         switch (dataType) {
00362         case TYPE_UBYTE:
00363             intValue = msg.readUnsignedByte();
00364             break;
00365         case TYPE_BYTE:
00366             intValue = msg.readByte();
00367             break;
00368         case TYPE_INTEGER:
00369             intValue = msg.readInt();
00370             break;
00371         case TYPE_FLOAT:
00372             realValue = msg.readFloat();
00373             break;
00374         case TYPE_DOUBLE:
00375             realValue = msg.readDouble();
00376             break;
00377         case POSITION_ROADMAP:
00378             roadPosValue.roadId = msg.readString();
00379             roadPosValue.pos = msg.readFloat();
00380             roadPosValue.laneId = msg.readUnsignedByte();
00381             break;
00382         case POSITION_2D:
00383         case POSITION_2_5D:
00384         case POSITION_3D:
00385             posXValue = msg.readFloat();
00386             posYValue = msg.readFloat();
00387             if (dataType != POSITION_2D) {
00388                 posZValue = msg.readFloat();
00389             }
00390             break;
00391         case TYPE_STRING:
00392             stringValue = msg.readString();
00393             break;
00394         default:
00395             std::stringstream error;
00396             error << "Can't read value from request message: the data type " << (int)dataType << " is not known";
00397             throw TraCIException(error.str());
00398         }
00399         lastValueRead = dataType;
00400     };
00401 
00402     int getLastValueRead() {
00403         return lastValueRead;
00404     }
00405 
00406     unsigned char getUByte() throw(TraCIException) {
00407         if (lastValueRead == TYPE_UBYTE) {
00408             return static_cast<unsigned char>(intValue);
00409         } else {
00410             throw TraCIException("An unsigned byte value has not been read");
00411         }
00412     };
00413 
00414     char getByte() throw(TraCIException) {
00415         if (lastValueRead == TYPE_BYTE) {
00416             return static_cast<char>(intValue);
00417         } else {
00418             throw TraCIException("A byte value has not been read");
00419         }
00420     };
00421 
00422     int getInteger() throw(TraCIException) {
00423         if (lastValueRead == TYPE_INTEGER) {
00424             return intValue;
00425         } else {
00426             throw TraCIException("An integer value has not been read");
00427         }
00428     };
00429 
00430     float getFloat() throw(TraCIException) {
00431         if (lastValueRead == TYPE_FLOAT) {
00432             return static_cast<float>(realValue);
00433         } else {
00434             throw TraCIException("A float value has not been read");
00435         }
00436     };
00437 
00438     double getDouble() throw(TraCIException) {
00439         if (lastValueRead == TYPE_DOUBLE) {
00440             return intValue;
00441         } else {
00442             throw TraCIException("A double value has not been read");
00443         }
00444     };
00445 
00446     TraCIServer::RoadMapPos getRoadMapPosition() throw(TraCIException) {
00447         if (lastValueRead == POSITION_ROADMAP) {
00448             return roadPosValue;
00449         } else {
00450             throw TraCIException("A road map position has not been read");
00451         }
00452     };
00453 
00454     void get3DPosition(float& inX, float& inY, float& inZ) throw(TraCIException) {
00455         if (lastValueRead == POSITION_3D || lastValueRead == POSITION_2_5D) {
00456             inX = posXValue;
00457             inY = posYValue;
00458             inZ = posZValue;
00459         } else {
00460             throw TraCIException("A 3d position has not been read");
00461         }
00462     };
00463 
00464     void get2DPosition(float& inX, float& inY) throw(TraCIException) {
00465         if (lastValueRead == POSITION_2D) {
00466             inX = posXValue;
00467             inY = posYValue;
00468         } else {
00469             throw TraCIException("A 2d position has not been read");
00470         }
00471     };
00472 
00473     Position2D getAnyPosition() throw(TraCIException) {
00474         if (lastValueRead == POSITION_2D
00475                 || lastValueRead == POSITION_3D
00476                 || lastValueRead == POSITION_2_5D) {
00477             Position2D pos(static_cast<SUMOReal>(posXValue),
00478                            static_cast<SUMOReal>(posYValue));
00479             return pos;
00480         } else {
00481             throw TraCIException("No position has been read");
00482         }
00483     };
00484 
00485     std::string getString() throw(TraCIException) {
00486         if (lastValueRead == TYPE_STRING) {
00487             return stringValue;
00488         } else {
00489             throw TraCIException("A string value has not been read");
00490         }
00491     };
00492 };
00493 
00494 }
00495 
00496 
00497 #endif
00498 
00499 #endif

Generated on Wed May 5 00:06:37 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6