SUMO - Simulation of Urban MObility
TraCIServer.cpp
Go to the documentation of this file.
1 /****************************************************************************/
17 /****************************************************************************/
18 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
19 // Copyright (C) 2007-2016 DLR (http://www.dlr.de/) and contributors
20 /****************************************************************************/
21 //
22 // This file is part of SUMO.
23 // SUMO is free software: you can redistribute it and/or modify
24 // it under the terms of the GNU General Public License as published by
25 // the Free Software Foundation, either version 3 of the License, or
26 // (at your option) any later version.
27 //
28 /****************************************************************************/
29 
30 // ===========================================================================
31 // included modules
32 // ===========================================================================
33 #ifdef _MSC_VER
34 #include <windows_config.h>
35 #else
36 #include <config.h>
37 #endif
38 
39 #ifdef HAVE_VERSION_H
40 #include <version.h>
41 #endif
42 
43 #ifndef NO_TRACI
44 
45 #ifdef HAVE_PYTHON
46 #include <Python.h>
47 #endif
48 
49 #include <string>
50 #include <map>
51 #include <iostream>
52 #include <algorithm>
53 #include <foreign/tcpip/socket.h>
54 #include <foreign/tcpip/storage.h>
55 #include <utils/common/SUMOTime.h>
63 #include <utils/shapes/Polygon.h>
64 #include <utils/xml/XMLSubSys.h>
65 #include <microsim/MSNet.h>
67 #include <microsim/MSVehicle.h>
68 #include <microsim/MSEdge.h>
70 #include <microsim/MSJunction.h>
71 #include <microsim/MSEdgeControl.h>
72 #include <microsim/MSLane.h>
73 #include <microsim/MSGlobals.h>
75 #include "TraCIConstants.h"
76 #include "TraCIServer.h"
79 #include "TraCIServerAPI_Lane.h"
82 #include "TraCIServerAPI_TLS.h"
83 #include "TraCIServerAPI_Vehicle.h"
85 #include "TraCIServerAPI_Route.h"
86 #include "TraCIServerAPI_POI.h"
87 #include "TraCIServerAPI_Polygon.h"
88 #include "TraCIServerAPI_Edge.h"
90 #include "TraCIServerAPI_Person.h"
91 
92 #ifdef CHECK_MEMORY_LEAKS
93 #include <foreign/nvwa/debug_new.h>
94 #endif // CHECK_MEMORY_LEAKS
95 
96 
97 // ===========================================================================
98 // static member definitions
99 // ===========================================================================
102 
103 
104 // ===========================================================================
105 // method definitions
106 // ===========================================================================
107 TraCIServer::TraCIServer(const SUMOTime begin, const int port)
108  : mySocket(0), myTargetTime(begin), myDoingSimStep(false), myAmEmbedded(port == 0), myLaneTree(0) {
109 
110  myVehicleStateChanges[MSNet::VEHICLE_STATE_BUILT] = std::vector<std::string>();
111  myVehicleStateChanges[MSNet::VEHICLE_STATE_DEPARTED] = std::vector<std::string>();
112  myVehicleStateChanges[MSNet::VEHICLE_STATE_STARTING_TELEPORT] = std::vector<std::string>();
113  myVehicleStateChanges[MSNet::VEHICLE_STATE_ENDING_TELEPORT] = std::vector<std::string>();
114  myVehicleStateChanges[MSNet::VEHICLE_STATE_ARRIVED] = std::vector<std::string>();
115  myVehicleStateChanges[MSNet::VEHICLE_STATE_NEWROUTE] = std::vector<std::string>();
116  myVehicleStateChanges[MSNet::VEHICLE_STATE_STARTING_PARKING] = std::vector<std::string>();
117  myVehicleStateChanges[MSNet::VEHICLE_STATE_ENDING_PARKING] = std::vector<std::string>();
118  myVehicleStateChanges[MSNet::VEHICLE_STATE_STARTING_STOP] = std::vector<std::string>();
119  myVehicleStateChanges[MSNet::VEHICLE_STATE_ENDING_STOP] = std::vector<std::string>();
121 
125 
147 
149 
150  myDoCloseConnection = false;
151 
152  // display warning if internal lanes are not used
154  WRITE_WARNING("Starting TraCI without using internal lanes!");
155  MsgHandler::getWarningInstance()->inform("Vehicles will jump over junctions.", false);
156  MsgHandler::getWarningInstance()->inform("Use without option --no-internal-links to avoid unexpected behavior", false);
157  }
158 
159  if (!myAmEmbedded) {
160  try {
161  WRITE_MESSAGE("***Starting server on port " + toString(port) + " ***");
162  mySocket = new tcpip::Socket(port);
163  mySocket->accept();
164  // When got here, a client has connected
165  } catch (tcpip::SocketException& e) {
166  throw ProcessError(e.what());
167  }
168  }
169 }
170 
171 
174  if (mySocket != NULL) {
175  mySocket->close();
176  delete mySocket;
177  }
178  for (std::map<int, NamedRTree*>::const_iterator i = myObjects.begin(); i != myObjects.end(); ++i) {
179  delete(*i).second;
180  }
181  delete myLaneTree;
182 }
183 
184 
185 // ---------- Initialisation and Shutdown
186 void
187 TraCIServer::openSocket(const std::map<int, CmdExecutor>& execs) {
188  if (myInstance != 0) {
189  return;
190  }
191  if (!myDoCloseConnection && OptionsCont::getOptions().getInt("remote-port") != 0) {
192  myInstance = new TraCIServer(string2time(OptionsCont::getOptions().getString("begin")),
193  OptionsCont::getOptions().getInt("remote-port"));
194  for (std::map<int, CmdExecutor>::const_iterator i = execs.begin(); i != execs.end(); ++i) {
195  myInstance->myExecutors[i->first] = i->second;
196  }
197  }
198 }
199 
200 
201 void
203  if (myInstance == 0) {
204  return;
205  }
206  if (myDoCloseConnection) {
209  }
210  delete myInstance;
211  myInstance = 0;
212  myDoCloseConnection = true;
213 }
214 
215 
216 bool
218  return myDoCloseConnection;
219 }
220 
221 
222 void
224  int edgeOffset, ConstMSEdgeVector route, SUMOTime t) {
225  myVTDControlledVehicles[v->getID()] = v;
226  v->getInfluencer().setVTDControlled(xyPos, l, pos, posLat, angle, edgeOffset, route, t);
227 }
228 
229 
230 void
232  for (std::map<std::string, MSVehicle*>::const_iterator i = myVTDControlledVehicles.begin(); i != myVTDControlledVehicles.end(); ++i) {
233  if (MSNet::getInstance()->getVehicleControl().getVehicle((*i).first) != 0) {
234  (*i).second->getInfluencer().postProcessVTD((*i).second);
235  } else {
236  WRITE_WARNING("Vehicle '" + (*i).first + "' was removed though being controlled by VTD");
237  }
238  }
239  myVTDControlledVehicles.clear();
240 }
241 
242 
243 // ---------- Initialisation and Shutdown
244 
245 
246 void
248  if (!myDoCloseConnection) {
249  myVehicleStateChanges[to].push_back(vehicle->getID());
250  }
251 }
252 
253 
254 void
256  if (myInstance == 0) {
257  return;
258  }
259  try {
260  if (myInstance->myAmEmbedded || step < myInstance->myTargetTime) {
261  return;
262  }
263  // Simulation should run until
264  // 1. end time reached or
265  // 2. got CMD_CLOSE or
266  // 3. Client closes socket connection
267  if (myInstance->myDoingSimStep) {
269  myInstance->myDoingSimStep = false;
270  }
271  while (!myDoCloseConnection) {
273  if (myInstance->myOutputStorage.size() > 0) {
274  // send out all answers as one storage
276  }
279  // Read a message
281  }
283  // dispatch each command
284  int cmd = myInstance->dispatchCommand();
285  if (cmd == CMD_SIMSTEP2) {
286  myInstance->myDoingSimStep = true;
287  for (std::map<MSNet::VehicleState, std::vector<std::string> >::iterator i = myInstance->myVehicleStateChanges.begin(); i != myInstance->myVehicleStateChanges.end(); ++i) {
288  (*i).second.clear();
289  }
290  return;
291  }
292  }
293  }
295  // send out all answers as one storage
297  }
298  for (std::map<MSNet::VehicleState, std::vector<std::string> >::iterator i = myInstance->myVehicleStateChanges.begin(); i != myInstance->myVehicleStateChanges.end(); ++i) {
299  (*i).second.clear();
300  }
301  } catch (std::invalid_argument& e) {
302  throw ProcessError(e.what());
303  } catch (TraCIException& e) {
304  throw ProcessError(e.what());
305  } catch (tcpip::SocketException& e) {
306  throw ProcessError(e.what());
307  }
308 }
309 
310 
311 
312 
313 #ifdef HAVE_PYTHON
314 // ===========================================================================
315 // python functions (traciemb module)
316 // ===========================================================================
317 static PyObject*
318 traciemb_execute(PyObject* /* self */, PyObject* args) {
319  const char* msg;
320  int size;
321  if (!PyArg_ParseTuple(args, "s#", &msg, &size)) {
322  return NULL;
323  }
324  std::string result = TraCIServer::execute(std::string(msg, size));
325  return Py_BuildValue("s#", result.c_str(), result.size());
326 }
327 
328 static PyMethodDef EmbMethods[] = {
329  {
330  "execute", traciemb_execute, METH_VARARGS,
331  "Execute the given TraCI command and return the result."
332  },
333  {NULL, NULL, 0, NULL}
334 };
335 
336 
337 std::string
338 TraCIServer::execute(std::string cmd) {
339  try {
340  if (myInstance == 0) {
341  if (!myDoCloseConnection) {
342  myInstance = new TraCIServer(string2time(OptionsCont::getOptions().getString("begin")));
343  } else {
344  return "";
345  }
346  }
349  for (std::string::iterator i = cmd.begin(); i != cmd.end(); ++i) {
351  }
353  return std::string(myInstance->myOutputStorage.begin(), myInstance->myOutputStorage.end());
354  } catch (std::invalid_argument& e) {
355  throw ProcessError(e.what());
356  } catch (TraCIException& e) {
357  throw ProcessError(e.what());
358  } catch (tcpip::SocketException& e) {
359  throw ProcessError(e.what());
360  }
361 }
362 
363 
364 void
365 TraCIServer::runEmbedded(std::string pyFile) {
366  PyObject* pName, *pModule;
367  Py_Initialize();
368  Py_InitModule("traciemb", EmbMethods);
369  if (pyFile.length() > 3 && !pyFile.compare(pyFile.length() - 3, 3, ".py")) {
370  PyObject* sys_path, *path;
371  char pathstr[] = "path";
372  sys_path = PySys_GetObject(pathstr);
373  if (sys_path == NULL || !PyList_Check(sys_path)) {
374  throw ProcessError("Could not access python sys.path!");
375  }
376  path = PyString_FromString(FileHelpers::getFilePath(pyFile).c_str());
377  PyList_Insert(sys_path, 0, path);
378  Py_DECREF(path);
379  FILE* pFile = fopen(pyFile.c_str(), "r");
380  if (pFile == NULL) {
381  throw ProcessError("Failed to load \"" + pyFile + "\"!");
382  }
383  PyRun_SimpleFile(pFile, pyFile.c_str());
384  fclose(pFile);
385  } else {
386  pName = PyString_FromString(pyFile.c_str());
387  /* Error checking of pName left out */
388  pModule = PyImport_Import(pName);
389  Py_DECREF(pName);
390  if (pModule == NULL) {
391  PyErr_Print();
392  throw ProcessError("Failed to load \"" + pyFile + "\"!");
393  }
394  }
395  Py_Finalize();
396 }
397 #endif
398 
399 
400 int
402  int commandStart = myInputStorage.position();
403  int commandLength = myInputStorage.readUnsignedByte();
404  if (commandLength == 0) {
405  commandLength = myInputStorage.readInt();
406  }
407 
408  int commandId = myInputStorage.readUnsignedByte();
409  bool success = false;
410  // dispatch commands
411  if (myExecutors.find(commandId) != myExecutors.end()) {
412  success = myExecutors[commandId](*this, myInputStorage, myOutputStorage);
413  } else {
414  switch (commandId) {
415  case CMD_GETVERSION:
416  success = commandGetVersion();
417  break;
418  case CMD_SIMSTEP2: {
419  SUMOTime nextT = myInputStorage.readInt();
420  success = true;
421  if (nextT != 0) {
422  myTargetTime = nextT;
423  } else {
425  }
426  if (myAmEmbedded) {
429  for (std::map<MSNet::VehicleState, std::vector<std::string> >::iterator i = myInstance->myVehicleStateChanges.begin(); i != myInstance->myVehicleStateChanges.end(); ++i) {
430  (*i).second.clear();
431  }
432  }
433  return commandId;
434  }
435  case CMD_CLOSE:
436  myDoCloseConnection = true;
437  success = true;
438  break;
454  success = addObjectVariableSubscription(commandId, false);
455  break;
471  success = addObjectVariableSubscription(commandId, true);
472  break;
473  default:
474  writeStatusCmd(commandId, RTYPE_NOTIMPLEMENTED, "Command not implemented in sumo");
475  }
476  }
477  if (!success) {
478  while (myInputStorage.valid_pos() && (int)myInputStorage.position() < commandStart + commandLength) {
480  }
481  }
482  if ((int)myInputStorage.position() != commandStart + commandLength) {
483  std::ostringstream msg;
484  msg << "Wrong position in requestMessage after dispatching command.";
485  msg << " Expected command length was " << commandLength;
486  msg << " but " << myInputStorage.position() - commandStart << " Bytes were read.";
487  writeStatusCmd(commandId, RTYPE_ERR, msg.str());
488  myDoCloseConnection = true;
489  }
490  return commandId;
491 }
492 
493 
494 // ---------- Server-internal command handling
495 bool
497  std::string sumoVersion = VERSION_STRING;
498  // Prepare response
499  tcpip::Storage answerTmp;
500  answerTmp.writeInt(TRACI_VERSION);
501  answerTmp.writeString(std::string("SUMO ") + sumoVersion);
502  // When we get here, the response is stored in answerTmp -> put into myOutputStorage
504  // command length
505  myOutputStorage.writeUnsignedByte(1 + 1 + static_cast<int>(answerTmp.size()));
506  // command type
508  // and the parameter dependant part
509  myOutputStorage.writeStorage(answerTmp);
510  return true;
511 }
512 
513 
514 void
518  int noActive = 0;
519  for (std::vector<Subscription>::iterator i = mySubscriptions.begin(); i != mySubscriptions.end();) {
520  const Subscription& s = *i;
523  if ((s.endTime < t) || isArrivedVehicle) {
524  i = mySubscriptions.erase(i);
525  continue;
526  }
527  ++i;
528  if (s.beginTime > t) {
529  continue;
530  }
531  ++noActive;
532  }
533  myOutputStorage.writeInt(noActive);
534  for (std::vector<Subscription>::iterator i = mySubscriptions.begin(); i != mySubscriptions.end();) {
535  const Subscription& s = *i;
536  if (s.beginTime > t) {
537  ++i;
538  continue;
539  }
540  tcpip::Storage into;
541  std::string errors;
542  bool ok = processSingleSubscription(s, into, errors);
544  if (ok) {
545  ++i;
546  } else {
547  i = mySubscriptions.erase(i);
548  }
549  }
550 }
551 
552 
553 void
554 TraCIServer::writeStatusCmd(int commandId, int status, const std::string& description) {
555  writeStatusCmd(commandId, status, description, myOutputStorage);
556 }
557 
558 
559 void
560 TraCIServer::writeStatusCmd(int commandId, int status, const std::string& description, tcpip::Storage& outputStorage) {
561  if (status == RTYPE_ERR) {
562  WRITE_ERROR("Answered with error to command " + toHex(commandId, 2) + ": " + description);
563  } else if (status == RTYPE_NOTIMPLEMENTED) {
564  WRITE_ERROR("Requested command not implemented (" + toHex(commandId, 2) + "): " + description);
565  }
566  outputStorage.writeUnsignedByte(1 + 1 + 1 + 4 + static_cast<int>(description.length())); // command length
567  outputStorage.writeUnsignedByte(commandId); // command type
568  outputStorage.writeUnsignedByte(status); // status
569  outputStorage.writeString(description); // description
570 }
571 
572 
573 bool
574 TraCIServer::writeErrorStatusCmd(int commandId, const std::string& description, tcpip::Storage& outputStorage) {
575  writeStatusCmd(commandId, RTYPE_ERR, description, outputStorage);
576  return false;
577 }
578 
579 
580 void
582  tcpip::Storage writeInto;
583  std::string errors;
584  if (processSingleSubscription(s, writeInto, errors)) {
586  writeStatusCmd(s.commandId, RTYPE_ERR, "Subscription has ended.");
587  } else {
588  bool needNewSubscription = true;
589  for (std::vector<Subscription>::iterator i = mySubscriptions.begin(); i != mySubscriptions.end(); ++i) {
590  if (s.commandId == i->commandId && s.id == i->id &&
591  s.beginTime == i->beginTime && s.endTime == i->endTime &&
592  s.contextVars == i->contextVars && s.contextDomain == i->contextDomain && s.range == i->range) {
593  std::vector<std::vector<unsigned char> >::const_iterator k = s.parameters.begin();
594  for (std::vector<int>::const_iterator j = s.variables.begin(); j != s.variables.end(); ++j, ++k) {
595  const int offset = std::find(i->variables.begin(), i->variables.end(), *j) - i->variables.begin();
596  if (offset == (int)i->variables.size() || i->parameters[offset] != *k) {
597  i->variables.push_back(*j);
598  i->parameters.push_back(*k);
599  }
600  }
601  needNewSubscription = false;
602  break;
603  }
604  }
605  if (needNewSubscription) {
606  mySubscriptions.push_back(s);
607  }
609  }
610  } else {
611  writeStatusCmd(s.commandId, RTYPE_ERR, "Could not add subscription (" + errors + ").");
612  }
613  myOutputStorage.writeStorage(writeInto);
614 }
615 
616 
617 void
618 TraCIServer::removeSubscription(int commandId, const std::string& id, int domain) {
619  bool found = false;
620  for (std::vector<Subscription>::iterator j = mySubscriptions.begin(); j != mySubscriptions.end();) {
621  if ((*j).id == id && (*j).commandId == commandId && (domain < 0 || (*j).contextDomain == domain)) {
622  j = mySubscriptions.erase(j);
623  found = true;
624  continue;
625  }
626  ++j;
627  }
628  // try unsubscribe
629  if (found) {
630  writeStatusCmd(commandId, RTYPE_OK, "");
631  } else {
632  writeStatusCmd(commandId, RTYPE_OK, "The subscription to remove was not found.");
633  }
634 }
635 
636 
637 bool
638 TraCIServer::findObjectShape(int domain, const std::string& id, PositionVector& shape) {
639  Position p;
640  switch (domain) {
643  shape.push_back(p);
644  return true;
645  }
646  break;
648  break;
650  break;
652  if (TraCIServerAPI_Lane::getShape(id, shape)) {
653  return true;
654  }
655  break;
658  shape.push_back(p);
659  return true;
660  }
661  break;
664  shape.push_back(p);
665  return true;
666  }
667  break;
669  break;
671  break;
673  if (TraCIServerAPI_POI::getPosition(id, p)) {
674  shape.push_back(p);
675  return true;
676  }
677  return false;
679  if (TraCIServerAPI_Polygon::getShape(id, shape)) {
680  return true;
681  }
682  break;
685  shape.push_back(p);
686  return true;
687  }
688  break;
690  if (TraCIServerAPI_Edge::getShape(id, shape)) {
691  return true;
692  }
693  break;
695  return false;
697  break;
698  default:
699  break;
700  }
701  return false;
702 }
703 
704 void
705 TraCIServer::collectObjectsInRange(int domain, const PositionVector& shape, SUMOReal range, std::set<std::string>& into) {
706  // build the look-up tree if not yet existing
707  if (myObjects.find(domain) == myObjects.end()) {
708  switch (domain) {
711  break;
720  break;
723  break;
726  break;
729  break;
730  default:
731  break;
732  }
733  }
734  const Boundary b = shape.getBoxBoundary().grow(range);
735  const float cmin[2] = {(float) b.xmin(), (float) b.ymin()};
736  const float cmax[2] = {(float) b.xmax(), (float) b.ymax()};
737  switch (domain) {
742  Named::StoringVisitor sv(into);
743  myObjects[domain]->Search(cmin, cmax, sv);
744  }
745  break;
749  TraCIServerAPI_Lane::StoringVisitor sv(into, shape, range, domain);
750  myLaneTree->Search(cmin, cmax, sv);
751  }
752  break;
753  default:
754  break;
755  }
756 }
757 
758 
759 bool
761  std::string& errors) {
762  bool ok = true;
763  tcpip::Storage outputStorage;
764  const int getCommandId = s.contextVars ? s.contextDomain : s.commandId - 0x30;
765  std::set<std::string> objIDs;
766  if (s.contextVars) {
767  PositionVector shape;
768  if (!findObjectShape(s.commandId, s.id, shape)) {
769  return false;
770  }
771  collectObjectsInRange(s.contextDomain, shape, s.range, objIDs);
772  } else {
773  objIDs.insert(s.id);
774  }
775  const int numVars = s.contextVars && s.variables.size() == 1 && s.variables[0] == ID_LIST ? 0 : (int)s.variables.size();
776  for (std::set<std::string>::iterator j = objIDs.begin(); j != objIDs.end(); ++j) {
777  if (s.contextVars) {
778  outputStorage.writeString(*j);
779  }
780  if (numVars > 0) {
781  std::vector<std::vector<unsigned char> >::const_iterator k = s.parameters.begin();
782  for (std::vector<int>::const_iterator i = s.variables.begin(); i != s.variables.end(); ++i, ++k) {
783  tcpip::Storage message;
784  message.writeUnsignedByte(*i);
785  message.writeString(*j);
786  message.writePacket(*k);
787  tcpip::Storage tmpOutput;
788  if (myExecutors.find(getCommandId) != myExecutors.end()) {
789  ok &= myExecutors[getCommandId](*this, message, tmpOutput);
790  } else {
791  writeStatusCmd(s.commandId, RTYPE_NOTIMPLEMENTED, "Unsupported command specified", tmpOutput);
792  ok = false;
793  }
794  // copy response part
795  if (ok) {
796  int length = tmpOutput.readUnsignedByte();
797  while (--length > 0) {
798  tmpOutput.readUnsignedByte();
799  }
800  int lengthLength = 1;
801  length = tmpOutput.readUnsignedByte();
802  if (length == 0) {
803  lengthLength = 5;
804  length = tmpOutput.readInt();
805  }
806  //read responseType
807  tmpOutput.readUnsignedByte();
808  int variable = tmpOutput.readUnsignedByte();
809  std::string id = tmpOutput.readString();
810  outputStorage.writeUnsignedByte(variable);
811  outputStorage.writeUnsignedByte(RTYPE_OK);
812  length -= (lengthLength + 1 + 4 + (int)id.length());
813  while (--length > 0) {
814  outputStorage.writeUnsignedByte(tmpOutput.readUnsignedByte());
815  }
816  } else {
817  //read length
818  tmpOutput.readUnsignedByte();
819  //read cmd
820  tmpOutput.readUnsignedByte();
821  //read status
822  tmpOutput.readUnsignedByte();
823  std::string msg = tmpOutput.readString();
824  outputStorage.writeUnsignedByte(*i);
825  outputStorage.writeUnsignedByte(RTYPE_ERR);
826  outputStorage.writeUnsignedByte(TYPE_STRING);
827  outputStorage.writeString(msg);
828  errors = errors + msg;
829  }
830  }
831  }
832  }
833  int length = (1 + 4) + 1 + (4 + (int)(s.id.length())) + 1 + (int)outputStorage.size();
834  if (s.contextVars) {
835  length += 4;
836  }
837  writeInto.writeUnsignedByte(0); // command length -> extended
838  writeInto.writeInt(length);
839  writeInto.writeUnsignedByte(s.commandId + 0x10);
840  writeInto.writeString(s.id);
841  if (s.contextVars) {
842  writeInto.writeUnsignedByte(s.contextDomain);
843  }
844  writeInto.writeUnsignedByte(numVars);
845  if (s.contextVars) {
846  writeInto.writeInt((int)objIDs.size());
847  }
848  if (!s.contextVars || objIDs.size() != 0) {
849  writeInto.writeStorage(outputStorage);
850  }
851  return ok;
852 }
853 
854 
855 bool
856 TraCIServer::addObjectVariableSubscription(const int commandId, const bool hasContext) {
857  const SUMOTime beginTime = myInputStorage.readInt();
858  const SUMOTime endTime = myInputStorage.readInt();
859  const std::string id = myInputStorage.readString();
860  const int domain = hasContext ? myInputStorage.readUnsignedByte() : 0;
861  const SUMOReal range = hasContext ? myInputStorage.readDouble() : 0.;
862  const int num = myInputStorage.readUnsignedByte();
863  std::vector<int> variables;
864  std::vector<std::vector<unsigned char> > parameters;
865  for (int i = 0; i < num; ++i) {
866  const int varID = myInputStorage.readUnsignedByte();
867  variables.push_back(varID);
868  parameters.push_back(std::vector<unsigned char>());
869  for (int j = 0; j < myParameterSizes[varID]; j++) {
870  parameters.back().push_back(myInputStorage.readChar());
871  }
872  }
873  // check subscribe/unsubscribe
874  if (variables.size() == 0) {
875  removeSubscription(commandId, id, -1);
876  return true;
877  }
878  // process subscription
879  Subscription s(commandId, id, variables, parameters, beginTime, endTime, hasContext, domain, range);
881  return true;
882 }
883 
884 
885 void
887  if (tempMsg.size() < 254) {
888  outputStorage.writeUnsignedByte(1 + (int)tempMsg.size()); // command length -> short
889  } else {
890  outputStorage.writeUnsignedByte(0); // command length -> extended
891  outputStorage.writeInt(1 + 4 + (int)tempMsg.size());
892  }
893  outputStorage.writeStorage(tempMsg);
894 }
895 
896 
897 bool
899  if (inputStorage.readUnsignedByte() != TYPE_INTEGER) {
900  return false;
901  }
902  into = inputStorage.readInt();
903  return true;
904 }
905 
906 
907 bool
909  if (inputStorage.readUnsignedByte() != TYPE_DOUBLE) {
910  return false;
911  }
912  into = inputStorage.readDouble();
913  return true;
914 }
915 
916 
917 bool
918 TraCIServer::readTypeCheckingString(tcpip::Storage& inputStorage, std::string& into) {
919  if (inputStorage.readUnsignedByte() != TYPE_STRING) {
920  return false;
921  }
922  into = inputStorage.readString();
923  return true;
924 }
925 
926 
927 bool
928 TraCIServer::readTypeCheckingStringList(tcpip::Storage& inputStorage, std::vector<std::string>& into) {
929  if (inputStorage.readUnsignedByte() != TYPE_STRINGLIST) {
930  return false;
931  }
932  into = inputStorage.readStringList();
933  return true;
934 }
935 
936 
937 bool
939  if (inputStorage.readUnsignedByte() != TYPE_COLOR) {
940  return false;
941  }
942  unsigned char r = static_cast<unsigned char>(inputStorage.readUnsignedByte());
943  unsigned char g = static_cast<unsigned char>(inputStorage.readUnsignedByte());
944  unsigned char b = static_cast<unsigned char>(inputStorage.readUnsignedByte());
945  unsigned char a = static_cast<unsigned char>(inputStorage.readUnsignedByte());
946  into.set(r, g, b, a);
947  return true;
948 }
949 
950 
951 bool
953  if (inputStorage.readUnsignedByte() != POSITION_2D) {
954  return false;
955  }
956  SUMOReal x = inputStorage.readDouble();
957  SUMOReal y = inputStorage.readDouble();
958  into.set(x, y, 0);
959  return true;
960 }
961 
962 
963 bool
965  if (inputStorage.readUnsignedByte() != TYPE_BOUNDINGBOX) {
966  return false;
967  }
968  const SUMOReal xmin = inputStorage.readDouble();
969  const SUMOReal ymin = inputStorage.readDouble();
970  const SUMOReal xmax = inputStorage.readDouble();
971  const SUMOReal ymax = inputStorage.readDouble();
972  into.set(xmin, ymin, xmax, ymax);
973  return true;
974 }
975 
976 
977 bool
979  if (inputStorage.readUnsignedByte() != TYPE_BYTE) {
980  return false;
981  }
982  into = inputStorage.readByte();
983  return true;
984 }
985 
986 
987 bool
989  if (inputStorage.readUnsignedByte() != TYPE_UBYTE) {
990  return false;
991  }
992  into = inputStorage.readUnsignedByte();
993  return true;
994 }
995 
996 
997 bool
999  if (inputStorage.readUnsignedByte() != TYPE_POLYGON) {
1000  return false;
1001  }
1002  into.clear();
1003  int noEntries = inputStorage.readUnsignedByte();
1004  PositionVector shape;
1005  for (int i = 0; i < noEntries; ++i) {
1006  SUMOReal x = inputStorage.readDouble();
1007  SUMOReal y = inputStorage.readDouble();
1008  into.push_back(Position(x, y));
1009  }
1010  return true;
1011 }
1012 
1013 #endif
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa3: Get Lane Variable)
bool processSingleSubscription(const TraCIServer::Subscription &s, tcpip::Storage &writeInto, std::string &errors)
The vehicle has departed (was inserted into the network)
Definition: MSNet.h:541
bool myDoingSimStep
Whether a step is currently done.
Definition: TraCIServer.h:313
static MsgHandler * getWarningInstance()
Returns the instance to add warnings to.
Definition: MsgHandler.cpp:71
tcpip::Socket * mySocket
The socket on which server is listening on.
Definition: TraCIServer.h:300
#define CMD_SUBSCRIBE_VEHICLE_CONTEXT
#define CMD_SUBSCRIBE_LANE_VARIABLE
bool findObjectShape(int domain, const std::string &id, PositionVector &shape)
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:81
long long int SUMOTime
Definition: SUMOTime.h:43
bool contextVars
Whether the subscription is a context subscription (variable subscription otherwise) ...
Definition: TraCIServer.h:361
#define CMD_GET_TL_VARIABLE
void collectObjectsInRange(int domain, const PositionVector &shape, SUMOReal range, std::set< std::string > &into)
#define CMD_SUBSCRIBE_JUNCTION_CONTEXT
void removeVehicleStateListener(VehicleStateListener *listener)
Removes a vehicle states listener.
Definition: MSNet.cpp:764
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc3: Change Lane State)
#define CMD_GET_VEHICLE_VARIABLE
virtual ~TraCIServer()
Destructor.
#define CMD_SUBSCRIBE_SIM_CONTEXT
bool commandGetVersion()
Returns the TraCI-version.
#define CMD_SUBSCRIBE_VEHICLETYPE_CONTEXT
#define CMD_CLOSE
virtual std::vector< std::string > readStringList()
#define POSITION_2D
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc4: Change Vehicle State)
std::vector< std::vector< unsigned char > > parameters
The parameters for the subscribed variables.
Definition: TraCIServer.h:355
void setVTDControlled(MSVehicle *v, Position xyPos, MSLane *l, SUMOReal pos, SUMOReal posLat, SUMOReal angle, int edgeOffset, ConstMSEdgeVector route, SUMOTime t)
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc7: Change PoI State)
bool receiveExact(Storage &)
Receive a complete TraCI message from Socket::socket_.
Definition: socket.cpp:497
#define CMD_GET_INDUCTIONLOOP_VARIABLE
bool readTypeCheckingColor(tcpip::Storage &inputStorage, RGBColor &into)
Reads the value type and a color, verifying the type.
static NamedRTree * getTree()
Returns a tree filled with junction instances.
static NamedRTree * getTree()
Returns a tree filled with polygon instances.
static void fill(RTREE &into)
Fills the given RTree with lane instances.
Definition: MSLane.cpp:1266
SUMOReal ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:124
#define CMD_SUBSCRIBE_INDUCTIONLOOP_VARIABLE
virtual unsigned int position() const
#define TYPE_UBYTE
#define RTYPE_OK
SUMOTime beginTime
The begin time of the subscription.
Definition: TraCIServer.h:357
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa9: Get Junction Variable)
#define CMD_GET_PERSON_VARIABLE
virtual double readDouble()
tcpip::Storage myOutputStorage
The storage to writeto.
Definition: TraCIServer.h:309
#define TYPE_POLYGON
void accept()
Wait for a incoming connection to port_.
Definition: socket.cpp:231
SUMOReal xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:112
StorageType::size_type size() const
Definition: storage.h:115
#define TRACI_VERSION
static bool getPosition(const std::string &id, Position &p)
Returns the named vehicle&#39;s position.
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xab: Get Simulation Variable)
bool readTypeCheckingInt(tcpip::Storage &inputStorage, int &into)
Reads the value type and an int, verifying the type.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:159
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc6: Change Route State)
SUMOTime DELTA_T
Definition: SUMOTime.cpp:39
bool readTypeCheckingString(tcpip::Storage &inputStorage, std::string &into)
Reads the value type and a string, verifying the type.
#define TYPE_COLOR
#define TYPE_STRINGLIST
bool readTypeCheckingDouble(tcpip::Storage &inputStorage, double &into)
Reads the value type and a double, verifying the type.
virtual bool valid_pos()
#define CMD_SUBSCRIBE_POLYGON_CONTEXT
tcpip::Storage myInputStorage
The storage to read from.
Definition: TraCIServer.h:306
#define CMD_GET_POLYGON_VARIABLE
virtual void writePacket(unsigned char *packet, int length)
#define CMD_SUBSCRIBE_JUNCTION_VARIABLE
Representation of a subscription.
Definition: TraCIServer.h:330
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:78
#define CMD_SUBSCRIBE_ROUTE_CONTEXT
bool readTypeCheckingPolygon(tcpip::Storage &inputStorage, PositionVector &into)
Reads the value type and a polygon, verifying the type.
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xca: Change Edge State)
virtual void writeUnsignedByte(int)
#define CMD_SET_EDGE_VARIABLE
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:254
bool writeErrorStatusCmd(int commandId, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage with status = RTYPE_ERR.
#define CMD_SUBSCRIBE_EDGE_VARIABLE
virtual unsigned char readChar()
SUMOReal xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:118
void addVehicleStateListener(VehicleStateListener *listener)
Adds a vehicle states listener.
Definition: MSNet.cpp:756
#define CMD_GET_ROUTE_VARIABLE
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
#define CMD_SUBSCRIBE_INDUCTIONLOOP_CONTEXT
virtual void writeInt(int)
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:69
#define TYPE_STRING
virtual int readUnsignedByte()
virtual void writeChar(unsigned char)
#define CMD_SUBSCRIBE_POI_VARIABLE
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa4: Get Vehicle Variable)
static bool getPosition(const std::string &id, Position &p)
Returns the named inductive loop&#39;s position.
static bool getPosition(const std::string &id, Position &p)
Returns the named persons&#39;s position.
static bool myDoCloseConnection
Whether the connection was set to be to close.
Definition: TraCIServer.h:297
void postProcessVTD()
The vehicles starts to stop.
Definition: MSNet.h:555
std::map< int, CmdExecutor > myExecutors
Map of commandIds -> their executors; applicable if the executor applies to the method footprint...
Definition: TraCIServer.h:319
#define CMD_SET_TL_VARIABLE
void set(SUMOReal xmin, SUMOReal ymin, SUMOReal xmax, SUMOReal ymax)
Sets the boundary to the given values.
Definition: Boundary.cpp:241
void vehicleStateChanged(const SUMOVehicle *const vehicle, MSNet::VehicleState to)
Called if a vehicle changes its state.
bool readTypeCheckingBoundary(tcpip::Storage &inputStorage, Boundary &into)
Reads the value type and a 2D bounding box, verifying the type.
static NamedRTree * getTree()
Returns a tree filled with PoI instances.
#define CMD_SUBSCRIBE_LANE_CONTEXT
#define CMD_SUBSCRIBE_SIM_VARIABLE
void removeSubscription(int commandId, const std::string &identity, int domain)
#define CMD_GET_VEHICLETYPE_VARIABLE
static void close()
request termination of connection
bool addObjectVariableSubscription(const int commandId, const bool hasContext)
#define CMD_SET_ROUTE_VARIABLE
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xcb: Set Simulation Variable)
#define CMD_GETVERSION
#define CMD_GET_AREAL_DETECTOR_VARIABLE
#define CMD_SUBSCRIBE_GUI_CONTEXT
Allows to store the object; used as context while traveling the rtree in TraCI.
The vehicle got a new route.
Definition: MSNet.h:549
The vehicle arrived at his destination (is deleted)
Definition: MSNet.h:547
StorageType::const_iterator end() const
Definition: storage.h:118
The vehicles starts to park.
Definition: MSNet.h:551
int commandId
commandIdArg The command id of the subscription
Definition: TraCIServer.h:349
std::vector< Subscription > mySubscriptions
The list of known, still valid subscriptions.
Definition: TraCIServer.h:370
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xce: Change Person State)
Representation of a vehicle.
Definition: SUMOVehicle.h:66
SUMOReal range
The range of the context.
Definition: TraCIServer.h:365
virtual int readInt()
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
std::string id
The id of the object that is subscribed.
Definition: TraCIServer.h:351
#define CMD_GET_POI_VARIABLE
void set(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
assigns new values
Definition: RGBColor.cpp:87
A list of positions.
std::vector< int > variables
The subscribed variables.
Definition: TraCIServer.h:353
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:307
#define CMD_SET_VEHICLETYPE_VARIABLE
#define CMD_SUBSCRIBE_MULTI_ENTRY_EXIT_DETECTOR_VARIABLE
#define TYPE_BOUNDINGBOX
bool readTypeCheckingStringList(tcpip::Storage &inputStorage, std::vector< std::string > &into)
Reads the value type and a string list, verifying the type.
#define CMD_SUBSCRIBE_GUI_VARIABLE
#define CMD_GET_LANE_VARIABLE
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa5: Get Vehicle Type Variable)
#define CMD_SET_VEHICLE_VARIABLE
SUMOTime string2time(const std::string &r)
Definition: SUMOTime.cpp:46
void postProcessSimulationStep2()
Handles subscriptions to send after a simstep2 command.
The vehicle started to teleport.
Definition: MSNet.h:543
#define CMD_GET_SIM_VARIABLE
virtual std::string readString()
#define CMD_GET_EDGE_VARIABLE
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:69
#define CMD_SET_POI_VARIABLE
#define CMD_SUBSCRIBE_POLYGON_VARIABLE
static TraCIServer * myInstance
Singleton instance of the server.
Definition: TraCIServer.h:294
static bool getPosition(const std::string &id, Position &p)
Returns the named PoI&#39;s position.
TraCIServer(const SUMOTime begin, const int port=0)
Constructor.
#define CMD_SUBSCRIBE_TL_CONTEXT
The vehicle ends to park.
Definition: MSNet.h:553
#define CMD_SUBSCRIBE_EDGE_CONTEXT
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa0: Get Induction Loop Variable)
#define CMD_GET_JUNCTION_VARIABLE
#define CMD_SUBSCRIBE_PERSON_VARIABLE
bool readTypeCheckingUnsignedByte(tcpip::Storage &inputStorage, int &into)
Reads the value type and an unsigned byte, verifying the type.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:55
TraCI server used to control sumo by a remote TraCI client.
Definition: TraCIServer.h:73
virtual void writeStorage(tcpip::Storage &store)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xae: Get Person Variable)
#define VAR_LEADER
#define CMD_SET_SIM_VARIABLE
void setVTDControlled(Position xyPos, MSLane *l, SUMOReal pos, SUMOReal posLat, SUMOReal angle, int edgeOffset, const ConstMSEdgeVector &route, SUMOTime t)
Definition: MSVehicle.cpp:435
#define CMD_SUBSCRIBE_AREAL_DETECTOR_VARIABLE
#define CMD_SUBSCRIBE_AREAL_DETECTOR_CONTEXT
#define CMD_SUBSCRIBE_VEHICLETYPE_VARIABLE
void writeResponseWithLength(tcpip::Storage &outputStorage, tcpip::Storage &tempMsg)
#define VERSION_STRING
Definition: config.h:225
VehicleState
Definition of a vehicle state.
Definition: MSNet.h:537
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa7: Get PoI Variable)
const bool myAmEmbedded
Whether the server runs in embedded mode.
Definition: TraCIServer.h:316
bool readTypeCheckingPosition2D(tcpip::Storage &inputStorage, Position &into)
Reads the value type and a 2D position, verifying the type.
The vehicle was built, but has not yet departed.
Definition: MSNet.h:539
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:206
static void processCommandsUntilSimStep(SUMOTime step)
process all commands until a simulation step is wanted
LANE_RTREE_QUAL * myLaneTree
A storage of lanes.
Definition: TraCIServer.h:379
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc5: Change Vehicle Type State)
Allows to store the object; used as context while traveling the rtree in TraCI.
Definition: Named.h:100
#define CMD_SET_POLYGON_VARIABLE
static void openSocket(const std::map< int, CmdExecutor > &execs)
Initialises the server.
Boundary & grow(SUMOReal by)
extends the boundary by the given amount
Definition: Boundary.cpp:201
static bool getShape(const std::string &id, PositionVector &shape)
Returns the named edge&#39;s shape.
virtual void writeString(const std::string &s)
#define RTYPE_NOTIMPLEMENTED
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:3448
#define CMD_GET_MULTI_ENTRY_EXIT_DETECTOR_VARIABLE
virtual const char * what() const
Definition: socket.h:70
#define TYPE_DOUBLE
std::string toHex(const T i, std::streamsize numDigits=0)
Definition: ToString.h:65
static bool getPosition(const std::string &id, Position &p)
Returns the named junction&#39;s position.
#define CMD_SUBSCRIBE_VEHICLE_VARIABLE
#define CMD_SUBSCRIBE_PERSON_CONTEXT
void sendExact(const Storage &)
Definition: socket.cpp:398
#define TYPE_BYTE
#define CMD_SET_LANE_VARIABLE
void inform(std::string msg, bool addType=true)
adds a new error to the list
Definition: MsgHandler.cpp:89
void set(SUMOReal x, SUMOReal y)
Definition: Position.h:78
SUMOTime myTargetTime
The time step to reach until processing the next commands.
Definition: TraCIServer.h:303
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa6: Get Route Variable)
static NamedRTree * getTree()
Returns a tree filled with inductive loop instances.
The vehicle ends to stop.
Definition: MSNet.h:557
#define LANE_RTREE_QUAL
std::map< int, NamedRTree * > myObjects
A storage of objects.
Definition: TraCIServer.h:376
StorageType::const_iterator begin() const
Definition: storage.h:117
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
std::map< std::string, MSVehicle * > myVTDControlledVehicles
Definition: TraCIServer.h:324
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa8: Get Polygon Variable)
int dispatchCommand()
#define CMD_SUBSCRIBE_MULTI_ENTRY_EXIT_DETECTOR_CONTEXT
void visit(const TraCIServerAPI_Lane::StoringVisitor &cont) const
Callback for visiting the lane when traversing an RTree.
Definition: MSLane.h:955
#define CMD_SUBSCRIBE_TL_VARIABLE
#define SUMOReal
Definition: config.h:213
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc2: Change Traffic Lights State)
void writeStatusCmd(int commandId, int status, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage.
SUMOReal ymax() const
Returns maximum y-coordinate.
Definition: Boundary.cpp:130
static std::string getFilePath(const std::string &path)
Removes the file information from the given path.
Definition: FileHelpers.cpp:76
#define CMD_SET_PERSON_VARIABLE
void simulationStep()
Performs a single simulation step.
Definition: MSNet.cpp:424
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa1: Get MeMeDetector Variable)
int contextDomain
The domain ID of the context.
Definition: TraCIServer.h:363
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:201
#define RTYPE_ERR
void initialiseSubscription(const Subscription &s)
#define TYPE_INTEGER
#define CMD_SIMSTEP2
#define ID_LIST
#define CMD_SUBSCRIBE_POI_CONTEXT
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xaa: Get Edge Variable)
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
Representation of a lane in the micro simulation.
Definition: MSLane.h:79
static bool wasClosed()
check whether close was requested
std::map< MSNet::VehicleState, std::vector< std::string > > myVehicleStateChanges
Changes in the states of simulated vehicles.
Definition: TraCIServer.h:373
The vehicle ended being teleported.
Definition: MSNet.h:545
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
virtual int readByte()
static bool getShape(const std::string &id, PositionVector &shape)
Returns the named polygons&#39;s shape.
bool readTypeCheckingByte(tcpip::Storage &inputStorage, int &into)
Reads the value type and a byte, verifying the type.
void close()
Definition: socket.cpp:349
SUMOTime endTime
The end time of the subscription.
Definition: TraCIServer.h:359
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa2: Get Traffic Lights Variable)
#define CMD_SUBSCRIBE_ROUTE_VARIABLE
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc8: Change Polygon State)
static bool getShape(const std::string &id, PositionVector &shape)
Returns the named lane&#39;s shape.
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa1: Get AreaDetector Variable)
const std::string & getID() const
Returns the name of the vehicle.
std::map< int, int > myParameterSizes
Map of variable ids to the size of the parameter in bytes.
Definition: TraCIServer.h:322