00001
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef TRACISERVER_H
00022 #define TRACISERVER_H
00023
00024
00025
00026
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
00061
00065 namespace traci {
00066
00067
00068
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
00081 static void processCommandsUntilSimStep(SUMOTime step) throw(ProcessError);
00082
00083
00084 static bool wasClosed();
00085
00086
00087 static void close();
00088
00089 void vehicleStateChanged(const MSVehicle * const vehicle, MSNet::VehicleState to) throw();
00090
00091 private:
00092
00093
00094
00095 TraCIServer();
00096
00097
00098
00099 virtual ~TraCIServer(void) throw();
00100
00101 int dispatchCommand() throw(TraCIException, std::invalid_argument);
00102
00103
00104
00105
00106
00107
00108
00109 bool commandSetMaximumSpeed() throw(TraCIException, std::invalid_argument);
00110
00111
00112
00113
00114
00115
00116
00117
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
00134
00135
00136 bool commandGetTLStatus() throw(TraCIException);
00137
00138
00139
00140
00141
00142
00143 bool commandSlowDown() throw(TraCIException);
00144
00145
00146
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
00238 static TraCIServer* instance_;
00239
00240
00241 tcpip::Socket* socket_;
00242
00243
00244 SUMOTime targetTime_;
00245
00246
00247 float penetration_;
00248
00249
00250 std::string routeFile_;
00251
00252
00253
00254 std::map<std::string, int> equippedVehicles_;
00255
00256
00257
00258 std::map<int, std::string> ext2intId;
00259 bool isMapChanged_;
00260 void convertExt2IntId(int extId, std::string& intId);
00261
00262
00263 std::map<int, std::string> trafficLightsExt2IntId;
00264
00265 std::map<std::string, int> trafficLightsInt2ExtId;
00266
00267
00268 std::map<int, std::string> poiExt2IntId;
00269
00270 std::map<std::string, int> poiInt2ExtId;
00271
00272
00273 std::map<int, std::string> polygonExt2IntId;
00274
00275 std::map<std::string, int> polygonInt2ExtId;
00276
00277
00278 MSVehicle* getVehicleByExtId(int extId);
00279
00280
00281 MSTrafficLightLogic* getTLLogicByExtId(int extId);
00282
00283
00284 PointOfInterest* getPoiByExtId(int extId);
00285
00286
00287 Polygon2D* getPolygonByExtId(int extId);
00288
00289
00290 int numEquippedVehicles_;
00291
00292
00293 int totalNumVehicles_;
00294
00295
00296 std::set<int> myLifecycleSubscriptions;
00297
00298
00299 std::map<int, std::list<std::pair<int, int> > > myDomainSubscriptions;
00300
00301
00302 std::set<int> myLivingVehicles;
00303
00304
00305 std::set<int> myCreatedVehicles;
00306
00307
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
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