Eclipse SUMO - Simulation of Urban MObility
TraCIServer.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2007-2020 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
28 // TraCI server used to control sumo by a remote TraCI client (e.g., ns2)
29 /****************************************************************************/
30 #include <config.h>
31 
32 #ifdef HAVE_VERSION_H
33 #include <version.h>
34 #endif
35 
36 #include <string>
37 #include <cmath>
38 #include <map>
39 #include <iostream>
40 #include <algorithm>
41 #include <foreign/tcpip/socket.h>
42 #include <foreign/tcpip/storage.h>
43 #include <utils/common/SUMOTime.h>
51 #include <utils/xml/XMLSubSys.h>
52 #include <microsim/MSNet.h>
53 #include <microsim/MSVehicle.h>
54 #include <microsim/MSEdge.h>
57 #include <microsim/MSJunction.h>
58 #include <microsim/MSEdgeControl.h>
59 #include <microsim/MSLane.h>
60 #include <microsim/MSGlobals.h>
62 #include <libsumo/Simulation.h>
63 #include <libsumo/Subscription.h>
64 #include <libsumo/TraCIConstants.h>
65 #include "TraCIServer.h"
68 #include "TraCIServerAPI_Lane.h"
72 #include "TraCIServerAPI_Vehicle.h"
74 #include "TraCIServerAPI_Route.h"
75 #include "TraCIServerAPI_POI.h"
76 #include "TraCIServerAPI_Polygon.h"
77 #include "TraCIServerAPI_Edge.h"
79 #include "TraCIServerAPI_Person.h"
81 #include "TraCIServerAPI_BusStop.h"
89 
90 
91 // ===========================================================================
92 // debug constants
93 // ===========================================================================
94 //#define DEBUG_MULTI_CLIENTS
95 //#define DEBUG_SUBSCRIPTIONS
96 //#define DEBUG_SUBSCRIPTION_FILTERS
97 //#define DEBUG_RAW_INPUT
98 
99 
100 // ===========================================================================
101 // static member definitions
102 // ===========================================================================
105 
106 
107 // ===========================================================================
108 // method definitions
109 // ===========================================================================
110 void
111 TraCIServer::initWrapper(const int domainID, const int variable, const std::string& objID) {
116 }
117 
118 
119 bool
120 TraCIServer::wrapDouble(const std::string& /* objID */, const int /* variable */, const double value) {
123  return true;
124 }
125 
126 
127 bool
128 TraCIServer::wrapInt(const std::string& /* objID */, const int /* variable */, const int value) {
130  myWrapperStorage.writeInt(value);
131  return true;
132 }
133 
134 
135 bool
136 TraCIServer::wrapString(const std::string& /* objID */, const int /* variable */, const std::string& value) {
139  return true;
140 }
141 
142 
143 bool
144 TraCIServer::wrapStringList(const std::string& /* objID */, const int /* variable */, const std::vector<std::string>& value) {
147  return true;
148 }
149 
150 
151 bool
152 TraCIServer::wrapPosition(const std::string& /* objID */, const int variable, const libsumo::TraCIPosition& value) {
153  const bool includeZ = variable == libsumo::VAR_POSITION3D;
157  if (includeZ) {
159  }
160  return true;
161 }
162 
163 
164 bool
165 TraCIServer::wrapColor(const std::string& /* objID */, const int /* variable */, const libsumo::TraCIColor& value) {
171  return true;
172 }
173 
174 
175 bool
176 TraCIServer::wrapRoadPosition(const std::string& /* objID */, const int /* variable */, const libsumo::TraCIRoadPosition& /* value */) {
177  // this is currently only a placeholder to allow vehicle.subscribeLeader to work with libsumo
178  return false;
179 }
180 
181 
184  return myWrapperStorage;
185 }
186 
187 
188 
189 TraCIServer::TraCIServer(const SUMOTime begin, const int port, const int numClients)
190  : myTargetTime(begin), myLastContextSubscription(nullptr) {
191 #ifdef DEBUG_MULTI_CLIENTS
192  std::cout << "Creating new TraCIServer for " << numClients << " clients on port " << port << "." << std::endl;
193 #endif
194  myVehicleStateChanges[MSNet::VEHICLE_STATE_BUILT] = std::vector<std::string>();
195  myVehicleStateChanges[MSNet::VEHICLE_STATE_DEPARTED] = std::vector<std::string>();
197  myVehicleStateChanges[MSNet::VEHICLE_STATE_ENDING_TELEPORT] = std::vector<std::string>();
198  myVehicleStateChanges[MSNet::VEHICLE_STATE_ARRIVED] = std::vector<std::string>();
199  myVehicleStateChanges[MSNet::VEHICLE_STATE_NEWROUTE] = std::vector<std::string>();
200  myVehicleStateChanges[MSNet::VEHICLE_STATE_STARTING_PARKING] = std::vector<std::string>();
201  myVehicleStateChanges[MSNet::VEHICLE_STATE_MANEUVERING] = std::vector<std::string>();
202  myVehicleStateChanges[MSNet::VEHICLE_STATE_ENDING_PARKING] = std::vector<std::string>();
203  myVehicleStateChanges[MSNet::VEHICLE_STATE_STARTING_STOP] = std::vector<std::string>();
204  myVehicleStateChanges[MSNet::VEHICLE_STATE_ENDING_STOP] = std::vector<std::string>();
205  myVehicleStateChanges[MSNet::VEHICLE_STATE_COLLISION] = std::vector<std::string>();
206  myVehicleStateChanges[MSNet::VEHICLE_STATE_EMERGENCYSTOP] = std::vector<std::string>();
207 
211 
248  //myExecutors[libsumo::CMD_SET_MEANDATA_VARIABLE] = &TraCIServerAPI_MeanData::processSet;
251 
253 
254  myDoCloseConnection = false;
255 
256  // display warning if internal lanes are not used
258  WRITE_WARNING("Starting TraCI without using internal lanes!");
259  MsgHandler::getWarningInstance()->inform("Vehicles will jump over junctions.", false);
260  MsgHandler::getWarningInstance()->inform("Use without option --no-internal-links to avoid unexpected behavior", false);
261  }
262 
263  try {
264  WRITE_MESSAGE("***Starting server on port " + toString(port) + " ***");
265  tcpip::Socket serverSocket(port);
266  if (numClients > 1) {
267  WRITE_MESSAGE(" waiting for " + toString(numClients) + " clients...");
268  }
269  while ((int)mySockets.size() < numClients) {
270  int index = (int)mySockets.size() + libsumo::MAX_ORDER + 1;
271  mySockets[index] = new SocketInfo(serverSocket.accept(true), begin);
272  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_BUILT] = std::vector<std::string>();
273  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_DEPARTED] = std::vector<std::string>();
274  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_STARTING_TELEPORT] = std::vector<std::string>();
275  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_ENDING_TELEPORT] = std::vector<std::string>();
276  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_ARRIVED] = std::vector<std::string>();
277  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_NEWROUTE] = std::vector<std::string>();
278  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_STARTING_PARKING] = std::vector<std::string>();
279  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_MANEUVERING] = std::vector<std::string>();
280  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_ENDING_PARKING] = std::vector<std::string>();
281  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_STARTING_STOP] = std::vector<std::string>();
282  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_ENDING_STOP] = std::vector<std::string>();
283  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_COLLISION] = std::vector<std::string>();
284  mySockets[index]->vehicleStateChanges[MSNet::VEHICLE_STATE_EMERGENCYSTOP] = std::vector<std::string>();
285  if (numClients > 1) {
286  WRITE_MESSAGE(" client connected");
287  }
288  }
289  // When got here, all clients have connected
290  if (numClients > 1) {
292  }
293  // set myCurrentSocket != mySockets.end() to indicate that this is the first step in processCommandsUntilSimStep()
294  myCurrentSocket = mySockets.begin();
295  } catch (tcpip::SocketException& e) {
296  throw ProcessError(e.what());
297  }
298 }
299 
300 
302  for (myCurrentSocket = mySockets.begin(); myCurrentSocket != mySockets.end(); ++myCurrentSocket) {
303  delete myCurrentSocket->second;
304  }
305  cleanup();
306 }
307 
308 
309 // ---------- Initialisation and Shutdown
310 void
311 TraCIServer::openSocket(const std::map<int, CmdExecutor>& execs) {
312  if (myInstance == nullptr && !myDoCloseConnection && (OptionsCont::getOptions().getInt("remote-port") != 0)) {
313  myInstance = new TraCIServer(string2time(OptionsCont::getOptions().getString("begin")),
314  OptionsCont::getOptions().getInt("remote-port"),
315  OptionsCont::getOptions().getInt("num-clients"));
316  for (std::map<int, CmdExecutor>::const_iterator i = execs.begin(); i != execs.end(); ++i) {
317  myInstance->myExecutors[i->first] = i->second;
318  }
319  }
320  if (myInstance != nullptr) {
321  // maybe net was deleted and built again
324  }
325 }
326 
327 
328 void
330  if (myInstance == nullptr) {
331  return;
332  }
333  delete myInstance;
334  myInstance = nullptr;
335  myDoCloseConnection = true;
336 }
337 
338 
339 bool
341  return myDoCloseConnection;
342 }
343 
344 
345 // ---------- Initialisation and Shutdown
346 
347 
348 void
349 TraCIServer::vehicleStateChanged(const SUMOVehicle* const vehicle, MSNet::VehicleState to, const std::string& /*info*/) {
350  if (!myDoCloseConnection) {
351  myVehicleStateChanges[to].push_back(vehicle->getID());
352  for (std::map<int, SocketInfo*>::iterator i = mySockets.begin(); i != mySockets.end(); ++i) {
353  i->second->vehicleStateChanges[to].push_back(vehicle->getID());
354  }
355  }
356 }
357 
358 
359 void
361 #ifdef DEBUG_MULTI_CLIENTS
362  std::cout << "Checking client order requests." << std::endl;
363 #endif
364  // check for SET_ORDER commands queued by connected clients
365  // In multiclient cas it is mandatory that SET_ORDER is sent as the first command (or directly after GET_VERSION)
366  myCurrentSocket = mySockets.begin();
367  while (myCurrentSocket != mySockets.end()) {
368 #ifdef DEBUG_MULTI_CLIENTS
369  std::cout << " Socket " << myCurrentSocket->second->socket << ":" << std::endl;
370 #endif
371 // bool clientUnordered = true;
372 #ifdef _MSC_VER
373 #pragma warning(push)
374 #pragma warning(disable: 4127) // do not warn about constant conditional expression
375 #endif
376  while (true) {
377 #ifdef _MSC_VER
378 #pragma warning(pop)
379 #endif
381  myCurrentSocket->second->socket->receiveExact(myInputStorage);
382  int commandStart, commandLength;
383  int commandId = readCommandID(commandStart, commandLength);
384 #ifdef DEBUG_MULTI_CLIENTS
385  std::cout << " received command " << commandId << std::endl;
386 #endif
387  // Whether the received command is a permitted command for the initialization phase.
388  // Currently, getVersion and setOrder are permitted.
389  bool initCommand = commandId == libsumo::CMD_SETORDER || commandId == libsumo::CMD_GETVERSION;
390  if (initCommand) {
391 #ifdef DEBUG_MULTI_CLIENTS
392  std::cout << " Init command. Sending response." << std::endl;
393 #endif
394  // reset input storage to initial state before reading the commandId
395  // (ugly, but we can't just reset the store's iter_ from here)
396  // Giving the commandId to dispatch command didn't work either
397  tcpip::Storage tmp;
400  // we don't know whether the command was set with extended
401  // length syntax or not so we hardcode the length here (#5037)
405 
406  // Handle initialization command completely
407  dispatchCommand();
408  myCurrentSocket->second->socket->sendExact(myOutputStorage);
410  } else {
411 #ifdef DEBUG_MULTI_CLIENTS
412  std::cout << " Client " << myCurrentSocket->second->socket << " did not set order initially." << std::endl;
413 #endif
414  throw ProcessError("Execution order (libsumo::CMD_SETORDER) was not set for all TraCI clients in pre-execution phase.");
415  }
416  if (commandId == libsumo::CMD_SETORDER) {
417  // This is what we have waited for.
418  break;
419  }
420  }
421  ++myCurrentSocket;
422  }
423 }
424 
425 
426 void
428  // Process reordering requests
429  if (mySocketReorderRequests.size() > 0) {
430  // process reordering requests
431  std::map<int, SocketInfo*>::const_iterator i = mySocketReorderRequests.begin();
432  std::map<int, SocketInfo*>::iterator j;
433 #ifdef DEBUG_MULTI_CLIENTS
434  std::cout << SIMTIME << " Current socket ordering:\n";
435  for (j = mySockets.begin(); j != mySockets.end(); ++j) {
436  std::cout << " " << j->first << ": " << j->second->socket << "\n";
437  }
438  std::cout << "Reordering requests:\n";
439  for (i = mySocketReorderRequests.begin(); i != mySocketReorderRequests.end(); ++i) {
440  std::cout << " Socket " << i->second->socket << " -> " << i->first << "\n";
441  }
442  i = mySocketReorderRequests.begin();
443 #endif
444  while (i != mySocketReorderRequests.end()) {
445  j = mySockets.begin();
446  while (j != mySockets.end()) {
447  if (j->second->socket == i->second->socket) {
448  break;
449  } else {
450  j++;
451  }
452  }
453  assert(j != mySockets.end());
454  mySockets.erase(j);
455  mySockets[i->first] = i->second;
456  ++i;
457  }
458  mySocketReorderRequests.clear();
459 #ifdef DEBUG_MULTI_CLIENTS
460  std::cout << "New socket ordering:\n";
461  for (j = mySockets.begin(); j != mySockets.end(); ++j) {
462  std::cout << " " << j->first << ": " << j->second->socket << "\n";
463  }
464  std::cout << std::endl;
465 #endif
466  }
467 }
468 
469 
470 SUMOTime
472 #ifdef DEBUG_MULTI_CLIENTS
473  std::cout << "\n Determining new target time..." << std::endl;
474  if (mySockets.size() == 0) {
475  std::cout << " All clients have disconnected." << std::endl;
476  }
477 #endif
478  std::map<int, SocketInfo*>::const_iterator i;
479  SUMOTime targetTime = std::numeric_limits<SUMOTime>::max();
480  for (i = mySockets.begin(); i != mySockets.end(); ++i) {
481 #ifdef DEBUG_MULTI_CLIENTS
482  std::cout << " target time for client " << i->second->socket << ": " << i->second->targetTime << "\n";
483 #endif
484  targetTime = MIN2(targetTime, i->second->targetTime);
485  }
486 #ifdef DEBUG_MULTI_CLIENTS
487  std::cout << std::endl;
488 #endif
489  return targetTime;
490 }
491 
492 
493 // send out subscription results to clients which will act in this step (i.e. with client target time <= myTargetTime)
494 void
496 #ifdef DEBUG_MULTI_CLIENTS
497  std::cout << "\n Sending subscription results to clients:\n";
498 #endif
499  std::map<int, SocketInfo*>::const_iterator i = mySockets.begin();
500  while (i != mySockets.end()) {
501  if (i->second->targetTime <= MSNet::getInstance()->getCurrentTimeStep()) {
502  // this client will become active before the next SUMO step. Provide subscription results.
503  i->second->socket->sendExact(myOutputStorage);
504 #ifdef DEBUG_MULTI_CLIENTS
505  std::cout << i->second->socket << "\n";
506 #endif
507  }
508  ++i;
509  }
510 #ifdef DEBUG_MULTI_CLIENTS
511  std::cout << std::endl;
512 #endif
513 }
514 
515 
516 void
518 #ifdef DEBUG_MULTI_CLIENTS
519  std::cout << SIMTIME << " processCommandsUntilSimStep(step = " << step << "):\n" << std::endl;
520 #endif
521  try {
522  const bool firstStep = myCurrentSocket != mySockets.end();
523  // update client order if requested
525  if (!firstStep) {
526  // This is the entry point after performing a SUMO step (block is skipped before first SUMO step since then no simulation results have to be sent)
527  // update subscription results
529  // Send out subscription results to clients which will act in this SUMO step (i.e. with client target time <= current sumo timestep end)
530  sendOutputToAll();
532  }
533 
534  // determine minimal next target time among clients
536 
537  if (step < myTargetTime) {
538 #ifdef DEBUG_MULTI_CLIENTS
539  if (step < myTargetTime) {
540  std::cout << " next target time is larger than next SUMO simstep (" << step << "). Returning from processCommandsUntilSimStep()." << std::endl;
541  }
542 #endif
543  return;
544  }
545 
546  // Simulation should run until
547  // 1. end time reached or
548  // 2. got libsumo::CMD_CLOSE or
549  // 3. got libsumo::CMD_LOAD or
550  // 4. Client closes socket connection
551  while (!myDoCloseConnection && myTargetTime <= (MSNet::getInstance()->getCurrentTimeStep())) {
552 #ifdef DEBUG_MULTI_CLIENTS
553  std::cout << " Next target time: " << myTargetTime << std::endl;
554 #endif
555  // Iterate over clients and process communication for the ones with target time == myTargetTime
556  myCurrentSocket = mySockets.begin();
557  while (myCurrentSocket != mySockets.end()) {
558 #ifdef DEBUG_MULTI_CLIENTS
559  std::cout << " current socket: " << myCurrentSocket->second->socket
560  << " with target time " << myCurrentSocket->second->targetTime
561  << std::endl;
562 #endif
563 
564  if (myCurrentSocket->second->targetTime > myTargetTime) {
565  // this client must wait
566 #ifdef DEBUG_MULTI_CLIENTS
567  std::cout << " skipping client " << myCurrentSocket->second->socket
568  << " with target time " << myCurrentSocket->second->targetTime << std::endl;
569 #endif
570  myCurrentSocket++;
571  continue;
572  }
573  bool done = false;
574  bool closed = false;
575  bool load = false;
576  while (!done && !closed && !load) {
577  if (!myInputStorage.valid_pos()) {
578  // have read request completely, send response if adequate
579  if (myOutputStorage.size() > 0) {
580 #ifdef DEBUG_MULTI_CLIENTS
581  std::cout << " sending response..." << std::endl;
582 #endif
583  // send response to previous query
584  myCurrentSocket->second->socket->sendExact(myOutputStorage);
586  } else {
587 #ifdef DEBUG_MULTI_CLIENTS
588  std::cout << " No input and no output stored (This is the next client)." << std::endl;
589 #endif
590  }
591 #ifdef DEBUG_MULTI_CLIENTS
592  std::cout << " resetting input storage and reading next command..." << std::endl;
593 #endif
594  // Read next request
596  myCurrentSocket->second->socket->receiveExact(myInputStorage);
597  }
598 
600  // dispatch command
601  const int cmd = dispatchCommand();
602 #ifdef DEBUG_MULTI_CLIENTS
603  std::cout << " Received command " << cmd << std::endl;
604 #endif
605  if (cmd == libsumo::CMD_SIMSTEP) {
606 #ifdef DEBUG_MULTI_CLIENTS
607  std::cout << " Received command SIM_STEP, end turn for client " << myCurrentSocket->second->socket << std::endl;
608 #endif
609  done = true;
610  } else if (cmd == libsumo::CMD_LOAD) {
611 #ifdef DEBUG_MULTI_CLIENTS
612  std::cout << " Received command LOAD." << std::endl;
613 #endif
614  load = true;
615  } else if (cmd == libsumo::CMD_CLOSE) {
616 #ifdef DEBUG_MULTI_CLIENTS
617  std::cout << " Received command CLOSE." << std::endl;
618 #endif
619  closed = true;
620  }
621  }
622  }
623  if (done) {
624  // Clear vehicleStateChanges for this client -> For subsequent TraCI stepping
625  // that is performed within this SUMO step, no updates on vehicle states
626  // belonging to the last SUMO simulation step will be received by this client.
627  for (std::map<MSNet::VehicleState, std::vector<std::string> >::iterator i = myCurrentSocket->second->vehicleStateChanges.begin(); i != myCurrentSocket->second->vehicleStateChanges.end(); ++i) {
628  (*i).second.clear();
629  }
630  myCurrentSocket++;
631  } else if (load) {
632  myCurrentSocket = mySockets.end();
633  } else {
634  assert(closed);
635  // remove current socket and increment to next socket in ordering
637  }
638  }
639  if (!myLoadArgs.empty()) {
640 #ifdef DEBUG_MULTI_CLIENTS
641  std::cout << " Breaking loop to load new simulation." << std::endl;
642 #endif
643  break;
644  } else if (myDoCloseConnection) {
645 #ifdef DEBUG_MULTI_CLIENTS
646  std::cout << " Breaking loop because last client closed connection." << std::endl;
647 #endif
648  break;
649  }
650  SUMOTime nextT = nextTargetTime();
651  // minimal target time among clients should have been increased during the last loop through mySockets
652  // XXX: The assert below is disabled since many tests do sth. like simulationStep(step). Such that for a first call step=0,
653  // leading to targetTime==1000 (increased by DELTA_T in dispatchCommand()),
654  // the next call is then usually simulationStep(step=1000) leading to no further increase
655  // and thus a failing assertion here.
656  //assert(myTargetTime < nextT || myDoCloseConnection);
657  myTargetTime = nextT;
658  }
659  // All clients are done with the current time step
660  // Reset myVehicleStateChanges
661  for (std::map<MSNet::VehicleState, std::vector<std::string> >::iterator i = myVehicleStateChanges.begin(); i != myVehicleStateChanges.end(); ++i) {
662  (*i).second.clear();
663  }
664  } catch (std::invalid_argument& e) {
665  throw ProcessError(e.what());
666  } catch (libsumo::TraCIException& e) {
667  throw ProcessError(e.what());
668  } catch (tcpip::SocketException& e) {
669  throw ProcessError(e.what());
670  }
671 }
672 
673 
674 void
676  mySubscriptions.clear();
677  myTargetTime = string2time(OptionsCont::getOptions().getString("begin"));
678  for (myCurrentSocket = mySockets.begin(); myCurrentSocket != mySockets.end(); ++myCurrentSocket) {
679  myCurrentSocket->second->targetTime = myTargetTime;
680  }
684  std::map<MSNet::VehicleState, std::vector<std::string> >::iterator i;
685  for (i = myVehicleStateChanges.begin(); i != myVehicleStateChanges.end(); i++) {
686  i->second.clear();
687  }
688  myCurrentSocket = mySockets.begin();
689 }
690 
691 
692 std::map<int, TraCIServer::SocketInfo*>::iterator
694 #ifdef DEBUG_MULTI_CLIENTS
695  std::cout << " Removing socket " << myCurrentSocket->second->socket
696  << " (order " << myCurrentSocket->first << ")" << std::endl;
697 #endif
698 
699  if (mySockets.size() == 1) {
700  // Last client has disconnected
701  delete myCurrentSocket->second->socket;
702  mySockets.clear();
703  myCurrentSocket = mySockets.end();
704  return myCurrentSocket;
705  }
706 
707  const int currOrder = myCurrentSocket->first;
708  delete myCurrentSocket->second->socket;
709  myCurrentSocket++;
710  if (myCurrentSocket != mySockets.end()) {
711  const int nextOrder = myCurrentSocket->first;
712  mySockets.erase(currOrder);
713  myCurrentSocket = mySockets.find(nextOrder);
714  } else {
715  mySockets.erase(currOrder);
716  myCurrentSocket = mySockets.end();
717  }
718  return myCurrentSocket;
719 }
720 
721 
722 int
723 TraCIServer::readCommandID(int& commandStart, int& commandLength) {
724  commandStart = myInputStorage.position();
725  commandLength = myInputStorage.readUnsignedByte();
726  if (commandLength == 0) {
727  commandLength = myInputStorage.readInt();
728  }
729 #ifdef DEBUG_RAW_INPUT
730  std::cout << " commandStart=" << commandStart << " commandLength=" << commandLength << " pos=" << myInputStorage.position() << " raw=";
731  for (auto it = myInputStorage.begin(); it != myInputStorage.end(); ++it) {
732  std::cout << (int)*it << " ";
733  }
734  std::cout << "\n";
735 #endif
737 }
738 
739 
740 int
742  int commandStart, commandLength;
743  int commandId = readCommandID(commandStart, commandLength);
744 #ifdef DEBUG_MULTI_CLIENTS
745  std::cout << " dispatchCommand() called for client " << myCurrentSocket->second->socket
746  << ", commandId = " << commandId << std::endl;
747 #endif
748  bool success = false;
749  // dispatch commands
750  if (myExecutors.find(commandId) != myExecutors.end()) {
751  success = myExecutors[commandId](*this, myInputStorage, myOutputStorage);
752  } else {
753  switch (commandId) {
755  success = commandGetVersion();
756  break;
757  case libsumo::CMD_LOAD: {
758  std::vector<std::string> args;
760  return writeErrorStatusCmd(libsumo::CMD_LOAD, "A load command needs a list of string arguments.", myOutputStorage);
761  }
762 #ifdef DEBUG_MULTI_CLIENTS
763  std::cout << " commandId == libsumo::CMD_LOAD"
764  << ", args = " << toString(args) << std::endl;
765 #endif
766  try {
767  myLoadArgs = args;
768  success = true;
770  // XXX: This only cares for the client that issued the load command.
771  // Multiclient-load functionality is still to be implemented. Refs #3146.
772  myCurrentSocket->second->socket->sendExact(myOutputStorage);
774  } catch (libsumo::TraCIException& e) {
776  }
777  break;
778  }
779  case libsumo::CMD_SIMSTEP: {
780  const double nextT = myInputStorage.readDouble();
781  if (nextT == 0.) {
782  myCurrentSocket->second->targetTime += DELTA_T;
783  } else {
784  myCurrentSocket->second->targetTime = TIME2STEPS(nextT);
785  }
786 #ifdef DEBUG_MULTI_CLIENTS
787  std::cout << " commandId == libsumo::CMD_SIMSTEP"
788  << ", next target time for client is " << myCurrentSocket->second->targetTime << std::endl;
789 #endif
790  if (myCurrentSocket->second->targetTime <= MSNet::getInstance()->getCurrentTimeStep()) {
791  // This is not the last TraCI simstep in the current SUMO simstep -> send single simstep response.
792  // @note: In the other case the simstep results are sent to all after the SUMO step was performed, see entry point for processCommandsUntilSimStep()
794  }
795  return commandId;
796  }
797  case libsumo::CMD_CLOSE:
799  myCurrentSocket->second->socket->sendExact(myOutputStorage);
801  if (mySockets.size() == 1) {
802  // Last client has closed connection
803  myDoCloseConnection = true;
804  }
805  success = true;
806  break;
807  case libsumo::CMD_SETORDER: {
808  const int order = myInputStorage.readInt();
809 #ifdef DEBUG_MULTI_CLIENTS
810  std::cout << " commandId == libsumo::CMD_SETORDER"
811  << ", order index is " << order << std::endl;
812 #endif
813  if (order > libsumo::MAX_ORDER) {
814  return writeErrorStatusCmd(libsumo::CMD_SETORDER, "A set order command needs an int argument below " + toString(libsumo::MAX_ORDER) + ".", myOutputStorage);
815  }
816  if (mySockets.count(order) > 0 || mySocketReorderRequests.count(order) > 0) {
817  return writeErrorStatusCmd(libsumo::CMD_SETORDER, "Order '" + toString(order) + "' is already taken.", myOutputStorage);
818  }
819  // memorize reorder request (will only take effect in the next step)
820  mySocketReorderRequests[order] = myCurrentSocket->second;
821  success = true;
823  break;
824  }
840  success = addObjectVariableSubscription(commandId, false);
841  break;
857  success = addObjectVariableSubscription(commandId, true);
858  break;
860  success = addSubscriptionFilter();
861  break;
862  default:
863  if (commandId == libsumo::CMD_GET_GUI_VARIABLE || commandId == libsumo::CMD_SET_GUI_VARIABLE) {
864  writeStatusCmd(commandId, libsumo::RTYPE_NOTIMPLEMENTED, "GUI is not running, command not implemented in command line sumo");
865  } else {
866  writeStatusCmd(commandId, libsumo::RTYPE_NOTIMPLEMENTED, "Command not implemented in sumo");
867  }
868  }
869  }
870  if (!success) {
871  while (myInputStorage.valid_pos() && (int)myInputStorage.position() < commandStart + commandLength) {
873  }
874  }
875  if ((int)myInputStorage.position() != commandStart + commandLength) {
876  std::ostringstream msg;
877  msg << "Wrong position in requestMessage after dispatching command " << commandId << ".";
878  msg << " Expected command length was " << commandLength;
879  msg << " but " << myInputStorage.position() - commandStart << " Bytes were read.";
880  writeStatusCmd(commandId, libsumo::RTYPE_ERR, msg.str());
881  myDoCloseConnection = true;
882  }
883  return commandId;
884 }
885 
886 
887 // ---------- Server-internal command handling
888 bool
890  // Prepare response
891  tcpip::Storage answerTmp;
892  answerTmp.writeInt(libsumo::TRACI_VERSION);
893  answerTmp.writeString("SUMO " VERSION_STRING);
894  // When we get here, the response is stored in answerTmp -> put into myOutputStorage
896  // command length
897  myOutputStorage.writeUnsignedByte(1 + 1 + static_cast<int>(answerTmp.size()));
898  // command type
900  // and the parameter dependant part
901  myOutputStorage.writeStorage(answerTmp);
902  return true;
903 }
904 
905 
906 void
909 #ifdef DEBUG_MULTI_CLIENTS
910  std::cout << " postProcessSimulationStep() at time " << t << std::endl;
911 #endif
913  int noActive = 0;
914  for (std::vector<libsumo::Subscription>::iterator i = mySubscriptions.begin(); i != mySubscriptions.end();) {
915  const libsumo::Subscription& s = *i;
919  if ((s.endTime < t) || isArrivedVehicle || isArrivedPerson) {
920  i = mySubscriptions.erase(i);
921  continue;
922  }
923  ++i;
924  if (s.beginTime > t) {
925  continue;
926  }
927  ++noActive;
928  }
930 #ifdef DEBUG_SUBSCRIPTIONS
931  std::cout << " Initial size of mySubscriptionCache is " << mySubscriptionCache.size()
932  << "\n Nr. of active subscriptions = " << noActive << std::endl;
933 #endif
934  mySubscriptionCache.writeInt(noActive);
935 #ifdef DEBUG_SUBSCRIPTIONS
936  std::cout << " Size after writing an int is " << mySubscriptionCache.size() << std::endl;
937 #endif
938  for (std::vector<libsumo::Subscription>::iterator i = mySubscriptions.begin(); i != mySubscriptions.end();) {
939  const libsumo::Subscription& s = *i;
940  if (s.beginTime > t) {
941  ++i;
942  continue;
943  }
944  tcpip::Storage into;
945  std::string errors;
946  bool ok = processSingleSubscription(s, into, errors);
947 #ifdef DEBUG_SUBSCRIPTIONS
948  std::cout << " Size of into-store for subscription " << s.id
949  << ": " << into.size() << std::endl;
950 #endif
952  if (ok) {
953  ++i;
954  } else {
955  i = mySubscriptions.erase(i);
956  }
957  }
959 #ifdef DEBUG_SUBSCRIPTIONS
960  std::cout << " Size after writing subscriptions is " << mySubscriptionCache.size() << std::endl;
961 #endif
962 }
963 
964 
965 void
967 #ifdef DEBUG_MULTI_CLIENTS
968  std::cout << " Sending cached simstep response to current client " << myCurrentSocket->second->socket
969  << " (-> intermediate TraCI step)."
970  << "\n Size of mySubscriptionCache is " << mySubscriptionCache.size()
971  << std::endl;
972 #endif
974 
975 // NOTE: the commented code would send an empty response
976 // myOutputStorage.writeInt(0);
977 // myCurrentSocket->second->socket->sendExact(myOutputStorage);
978 // myOutputStorage.reset();
980  // send results to active client
981  myCurrentSocket->second->socket->sendExact(myOutputStorage);
983 }
984 
985 
986 void
987 TraCIServer::writeStatusCmd(int commandId, int status, const std::string& description) {
988  writeStatusCmd(commandId, status, description, myOutputStorage);
989 }
990 
991 
992 void
993 TraCIServer::writeStatusCmd(int commandId, int status, const std::string& description, tcpip::Storage& outputStorage) {
994  if (status == libsumo::RTYPE_ERR) {
995  WRITE_ERROR("Answered with error to command " + toHex(commandId, 2) + ": " + description);
996  } else if (status == libsumo::RTYPE_NOTIMPLEMENTED) {
997  WRITE_ERROR("Requested command not implemented (" + toHex(commandId, 2) + "): " + description);
998  }
999  outputStorage.writeUnsignedByte(1 + 1 + 1 + 4 + static_cast<int>(description.length())); // command length
1000  outputStorage.writeUnsignedByte(commandId); // command type
1001  outputStorage.writeUnsignedByte(status); // status
1002  outputStorage.writeString(description); // description
1003 }
1004 
1005 
1006 bool
1007 TraCIServer::writeErrorStatusCmd(int commandId, const std::string& description, tcpip::Storage& outputStorage) {
1008  writeStatusCmd(commandId, libsumo::RTYPE_ERR, description, outputStorage);
1009  return false;
1010 }
1011 
1012 
1013 void
1015  tcpip::Storage writeInto;
1016  std::string errors;
1017  libsumo::Subscription* modifiedSubscription = nullptr;
1018  if (processSingleSubscription(s, writeInto, errors)) {
1020  writeStatusCmd(s.commandId, libsumo::RTYPE_ERR, "Subscription has ended.");
1021  } else {
1022  if (libsumo::Helper::needNewSubscription(s, mySubscriptions, modifiedSubscription)) {
1023  // Add new subscription to subscription cache (note: seems a bit inefficient)
1025  // copy new subscription into cache
1026  int noActive = 1 + (mySubscriptionCache.size() > 0 ? mySubscriptionCache.readInt() : 0);
1027  tcpip::Storage tmp;
1028  tmp.writeInt(noActive);
1029  while (mySubscriptionCache.valid_pos()) {
1031  }
1032  tmp.writeStorage(writeInto);
1035  }
1036  }
1038  }
1039  if (modifiedSubscription != nullptr && (
1040  modifiedSubscription->isVehicleToVehicleContextSubscription()
1041  || modifiedSubscription->isVehicleToPersonContextSubscription())) {
1042  // Set last modified vehicle context subscription active for filter modifications
1043  myLastContextSubscription = modifiedSubscription;
1044  } else {
1045  // adding other subscriptions deactivates the activation for filter addition
1046  myLastContextSubscription = nullptr;
1047  }
1048  } else {
1049  writeStatusCmd(s.commandId, libsumo::RTYPE_ERR, "Could not add subscription. " + errors);
1050  }
1051  myOutputStorage.writeStorage(writeInto);
1052 }
1053 
1054 
1055 void
1056 TraCIServer::removeSubscription(int commandId, const std::string& id, int domain) {
1057  bool found = false;
1058  std::vector<libsumo::Subscription>::iterator j;
1059  for (j = mySubscriptions.begin(); j != mySubscriptions.end();) {
1060  if (j->id == id && j->commandId == commandId && j->contextDomain == domain) {
1061  j = mySubscriptions.erase(j);
1062  if (j != mySubscriptions.end() && myLastContextSubscription == &(*j)) {
1063  // Remove also reference for filter additions
1064  myLastContextSubscription = nullptr;
1065  }
1066  found = true;
1067  continue;
1068  }
1069  ++j;
1070  }
1071  // try unsubscribe
1072  if (found) {
1073  writeStatusCmd(commandId, libsumo::RTYPE_OK, "");
1074  } else {
1075  writeStatusCmd(commandId, libsumo::RTYPE_ERR, "The subscription to remove was not found.");
1076  }
1077 }
1078 
1079 
1080 bool
1082  std::string& errors) {
1083  bool ok = true;
1084  tcpip::Storage outputStorage;
1085  const int getCommandId = s.contextDomain > 0 ? s.contextDomain : s.commandId - 0x30;
1086  std::set<std::string> objIDs;
1087  if (s.contextDomain > 0) {
1089  PositionVector shape;
1092  }
1094  } else {
1095  objIDs.insert(s.id);
1096  }
1097  const int numVars = s.contextDomain > 0 && s.variables.size() == 1 && s.variables[0] == libsumo::TRACI_ID_LIST ? 0 : (int)s.variables.size();
1098  int skipped = 0;
1099  for (std::set<std::string>::iterator j = objIDs.begin(); j != objIDs.end(); ++j) {
1100  if (s.contextDomain > 0) {
1101  //if (centralObject(s, *j)) {
1102  // skipped++;
1103  // continue;
1104  //}
1105  outputStorage.writeString(*j);
1106  }
1107  if (numVars > 0) {
1108  std::vector<std::vector<unsigned char> >::const_iterator k = s.parameters.begin();
1109  for (std::vector<int>::const_iterator i = s.variables.begin(); i != s.variables.end(); ++i, ++k) {
1110  tcpip::Storage message;
1111  message.writeUnsignedByte(*i);
1112  message.writeString(*j);
1113  message.writePacket(*k);
1114  tcpip::Storage tmpOutput;
1115  if (myExecutors.find(getCommandId) != myExecutors.end()) {
1116  ok &= myExecutors[getCommandId](*this, message, tmpOutput);
1117  } else {
1118  writeStatusCmd(s.commandId, libsumo::RTYPE_NOTIMPLEMENTED, "Unsupported command specified", tmpOutput);
1119  ok = false;
1120  }
1121  // copy response part
1122  if (ok) {
1123  int length = tmpOutput.readUnsignedByte();
1124  while (--length > 0) {
1125  tmpOutput.readUnsignedByte();
1126  }
1127  int lengthLength = 1;
1128  length = tmpOutput.readUnsignedByte();
1129  if (length == 0) {
1130  lengthLength = 5;
1131  length = tmpOutput.readInt();
1132  }
1133  //read responseType
1134  tmpOutput.readUnsignedByte();
1135  int variable = tmpOutput.readUnsignedByte();
1136  std::string id = tmpOutput.readString();
1137  outputStorage.writeUnsignedByte(variable);
1138  outputStorage.writeUnsignedByte(libsumo::RTYPE_OK);
1139  length -= (lengthLength + 1 + 4 + (int)id.length());
1140  while (--length > 0) {
1141  outputStorage.writeUnsignedByte(tmpOutput.readUnsignedByte());
1142  }
1143  } else {
1144  //read length
1145  tmpOutput.readUnsignedByte();
1146  //read cmd
1147  tmpOutput.readUnsignedByte();
1148  //read status
1149  tmpOutput.readUnsignedByte();
1150  std::string msg = tmpOutput.readString();
1151  outputStorage.writeUnsignedByte(*i);
1152  outputStorage.writeUnsignedByte(libsumo::RTYPE_ERR);
1153  outputStorage.writeUnsignedByte(libsumo::TYPE_STRING);
1154  outputStorage.writeString(msg);
1155  errors = errors + msg;
1156  }
1157  }
1158  }
1159  }
1160  int length = (1 + 4) + 1 + (4 + (int)(s.id.length())) + 1 + (int)outputStorage.size();
1161  if (s.contextDomain > 0) {
1162  length += 4;
1163  }
1164  writeInto.writeUnsignedByte(0); // command length -> extended
1165  writeInto.writeInt(length);
1166  writeInto.writeUnsignedByte(s.commandId + 0x10);
1167  writeInto.writeString(s.id);
1168  if (s.contextDomain > 0) {
1169  writeInto.writeUnsignedByte(s.contextDomain);
1170  }
1171  writeInto.writeUnsignedByte(numVars);
1172  if (s.contextDomain > 0) {
1173  writeInto.writeInt((int)objIDs.size() - skipped);
1174  }
1175  if (s.contextDomain == 0 || objIDs.size() != 0) {
1176  writeInto.writeStorage(outputStorage);
1177  }
1178  return ok;
1179 }
1180 
1181 
1182 bool
1183 TraCIServer::addObjectVariableSubscription(const int commandId, const bool hasContext) {
1184  const double beginTime = myInputStorage.readDouble();
1185  const double endTime = myInputStorage.readDouble();
1186  const SUMOTime begin = beginTime == libsumo::INVALID_DOUBLE_VALUE ? 0 : TIME2STEPS(beginTime);
1187  const SUMOTime end = endTime == libsumo::INVALID_DOUBLE_VALUE || endTime > STEPS2TIME(SUMOTime_MAX) ? SUMOTime_MAX : TIME2STEPS(endTime);
1188  const std::string id = myInputStorage.readString();
1189  const int domain = hasContext ? myInputStorage.readUnsignedByte() : 0;
1190  const double range = hasContext ? myInputStorage.readDouble() : 0.;
1191  const int num = myInputStorage.readUnsignedByte();
1192  std::vector<int> variables;
1193  std::vector<std::vector<unsigned char> > parameters;
1194  for (int i = 0; i < num; ++i) {
1195  const int varID = myInputStorage.readUnsignedByte();
1196  variables.push_back(varID);
1197  parameters.push_back(std::vector<unsigned char>());
1198  for (int j = 0; j < myParameterSizes[varID]; j++) {
1199  parameters.back().push_back(myInputStorage.readChar());
1200  }
1201  if (varID == libsumo::VAR_PARAMETER_WITH_KEY) {
1202  parameters.back().push_back(myInputStorage.readChar());
1203  // the byte order of the int is unknown here, so we create a temp. storage
1204  int length = myInputStorage.readInt();
1205  tcpip::Storage tmp;
1206  tmp.writeInt(length);
1207  for (int j = 0; j < 4; j++) { // write int (length of string) char by char
1208  parameters.back().push_back(tmp.readChar());
1209  }
1210  for (int j = 0; j < length; j++) { // write string char by char
1211  parameters.back().push_back(myInputStorage.readChar());
1212  }
1213  }
1214  }
1215  // check subscribe/unsubscribe
1216  if (variables.empty()) {
1217  removeSubscription(commandId, id, domain);
1218  return true;
1219  }
1220  // process subscription
1221  libsumo::Subscription s(commandId, id, variables, parameters, begin, end, domain, range);
1223  return true;
1224 }
1225 
1226 
1227 
1228 bool
1230  bool success = true;
1231  if (myLastContextSubscription == nullptr) {
1232  WRITE_WARNING("addSubscriptionFilter: No previous vehicle context subscription exists to apply the context filter.");
1233  return true;
1234  }
1235  // Read filter type
1236  int filterType = myInputStorage.readUnsignedByte();
1237 
1238  // dispatch according to filter type
1239  switch (filterType) {
1241  // Remove all filters
1242  removeFilters();
1243  break;
1245  // Read relative lanes to consider for context filter
1246  int nrLanes = (int)myInputStorage.readByte();
1247  std::vector<int> lanes;
1248  for (int i = 0; i < nrLanes; ++i) {
1249  lanes.push_back((int) myInputStorage.readByte());
1250  }
1252  }
1253  break;
1255  // Add no-opposite filter
1257  break;
1259  myInputStorage.readByte(); // read type double
1260  double dist = myInputStorage.readDouble();
1262  }
1263  break;
1265  myInputStorage.readByte(); // read type double
1266  double dist = myInputStorage.readDouble();
1268  }
1269  break;
1271  // Read relative lanes to consider for context filter
1273  }
1274  break;
1277  break;
1279  myInputStorage.readByte(); // read type stringlist
1281  addSubscriptionFilterVClass(vClasses);
1282  }
1283  break;
1285  myInputStorage.readByte(); // read type stringlist
1286  std::vector<std::string> vTypesVector = myInputStorage.readStringList();
1287  std::set<std::string> vTypesSet;
1288  vTypesSet.insert(vTypesVector.begin(), vTypesVector.end());
1289  addSubscriptionFilterVType(vTypesSet);
1290  }
1291  break;
1293  myInputStorage.readByte(); // read type double
1294  double angle = myInputStorage.readDouble();
1296  }
1297  break;
1299  myInputStorage.readByte(); // read type double
1300  double dist = myInputStorage.readDouble();
1302  }
1303  break;
1304  default:
1305  writeStatusCmd(filterType, libsumo::RTYPE_NOTIMPLEMENTED, "'" + toString(filterType) + "' is no valid filter type code.");
1306  success = false;
1307  }
1308 
1309  if (success) {
1310  // acknowledge filter addition
1312  }
1313 
1314  return success;
1315 }
1316 
1317 
1318 void
1320 #ifdef DEBUG_SUBSCRIPTION_FILTERS
1321  std::cout << "Removing filters" << std::endl;
1322 #endif
1324 }
1325 
1326 void
1328 #ifdef DEBUG_SUBSCRIPTION_FILTERS
1329  std::cout << "Adding lane filter (lanes=" << toString(lanes) << ")" << std::endl;
1330 #endif
1333 }
1334 
1335 void
1337 #ifdef DEBUG_SUBSCRIPTION_FILTERS
1338  std::cout << "Adding no opposite filter" << std::endl;
1339 #endif
1341 }
1342 
1343 void
1345 #ifdef DEBUG_SUBSCRIPTION_FILTERS
1346  std::cout << "Adding downstream dist filter (dist=" << toString(dist) << ")" << std::endl;
1347 #endif
1350 }
1351 
1352 void
1354 #ifdef DEBUG_SUBSCRIPTION_FILTERS
1355  std::cout << "Adding upstream dist filter (dist=" << toString(dist) << ")" << std::endl;
1356 #endif
1359 }
1360 
1361 void
1363 #ifdef DEBUG_SUBSCRIPTION_FILTERS
1364  std::cout << "Adding Lead/Follow-maneuver filter" << std::endl;
1365 #endif
1367 }
1368 
1369 void
1371 #ifdef DEBUG_SUBSCRIPTION_FILTERS
1372  std::cout << "Adding turn-maneuver filter" << std::endl;
1373 #endif
1375 }
1376 
1377 void
1379 #ifdef DEBUG_SUBSCRIPTION_FILTERS
1380  std::cout << "Adding vClass filter (vClasses=" << toString(vClasses) << ")" << std::endl;
1381 #endif
1384 }
1385 
1386 void
1387 TraCIServer::addSubscriptionFilterVType(std::set<std::string> vTypes) {
1388 #ifdef DEBUG_SUBSCRIPTION_FILTERS
1389  std::cout << "Adding vType filter (vTypes=" << toString(vTypes) << ")" << std::endl;
1390 #endif
1393 }
1394 
1395 void
1397 #ifdef DEBUG_SUBSCRIPTION_FILTERS
1398  std::cout << "Adding FieldOfVision filter (openingAngle=" << toString(openingAngle) << ")" << std::endl;
1399 #endif
1402 }
1403 
1404 void
1406 #ifdef DEBUG_SUBSCRIPTION_FILTERS
1407  std::cout << "Adding lateral dist filter (dist=" << toString(dist) << ")" << std::endl;
1408 #endif
1411 }
1412 
1413 void
1415  if (tempMsg.size() < 254) {
1416  outputStorage.writeUnsignedByte(1 + (int)tempMsg.size()); // command length -> short
1417  } else {
1418  outputStorage.writeUnsignedByte(0); // command length -> extended
1419  outputStorage.writeInt(1 + 4 + (int)tempMsg.size());
1420  }
1421  outputStorage.writeStorage(tempMsg);
1422 }
1423 
1424 
1425 void
1428  if (shape.size() < 256) {
1429  outputStorage.writeUnsignedByte((int)shape.size());
1430  } else {
1431  outputStorage.writeUnsignedByte(0);
1432  outputStorage.writeInt((int)shape.size());
1433  }
1434  for (const libsumo::TraCIPosition& pos : shape) {
1435  outputStorage.writeDouble(pos.x);
1436  outputStorage.writeDouble(pos.y);
1437  }
1438 }
1439 
1440 
1441 bool
1443  if (inputStorage.readUnsignedByte() != libsumo::TYPE_INTEGER) {
1444  return false;
1445  }
1446  into = inputStorage.readInt();
1447  return true;
1448 }
1449 
1450 
1451 bool
1453  if (inputStorage.readUnsignedByte() != libsumo::TYPE_DOUBLE) {
1454  return false;
1455  }
1456  into = inputStorage.readDouble();
1457  return true;
1458 }
1459 
1460 
1461 bool
1462 TraCIServer::readTypeCheckingString(tcpip::Storage& inputStorage, std::string& into) {
1463  if (inputStorage.readUnsignedByte() != libsumo::TYPE_STRING) {
1464  return false;
1465  }
1466  into = inputStorage.readString();
1467  return true;
1468 }
1469 
1470 
1471 bool
1472 TraCIServer::readTypeCheckingStringList(tcpip::Storage& inputStorage, std::vector<std::string>& into) {
1473  if (inputStorage.readUnsignedByte() != libsumo::TYPE_STRINGLIST) {
1474  return false;
1475  }
1476  into = inputStorage.readStringList();
1477  return true;
1478 }
1479 
1480 
1481 bool
1482 TraCIServer::readTypeCheckingDoubleList(tcpip::Storage& inputStorage, std::vector<double>& into) {
1483  if (inputStorage.readUnsignedByte() != libsumo::TYPE_DOUBLELIST) {
1484  return false;
1485  }
1486  into = inputStorage.readDoubleList();
1487  return true;
1488 }
1489 
1490 
1491 bool
1493  if (inputStorage.readUnsignedByte() != libsumo::TYPE_COLOR) {
1494  return false;
1495  }
1496  into.r = static_cast<unsigned char>(inputStorage.readUnsignedByte());
1497  into.g = static_cast<unsigned char>(inputStorage.readUnsignedByte());
1498  into.b = static_cast<unsigned char>(inputStorage.readUnsignedByte());
1499  into.a = static_cast<unsigned char>(inputStorage.readUnsignedByte());
1500  return true;
1501 }
1502 
1503 
1504 bool
1506  if (inputStorage.readUnsignedByte() != libsumo::POSITION_2D) {
1507  return false;
1508  }
1509  into.x = inputStorage.readDouble();
1510  into.y = inputStorage.readDouble();
1511  into.z = 0;
1512  return true;
1513 }
1514 
1515 
1516 bool
1518  if (inputStorage.readByte() != libsumo::TYPE_BYTE) {
1519  return false;
1520  }
1521  into = inputStorage.readByte();
1522  return true;
1523 }
1524 
1525 
1526 bool
1528  if (inputStorage.readUnsignedByte() != libsumo::TYPE_UBYTE) {
1529  return false;
1530  }
1531  into = inputStorage.readUnsignedByte();
1532  return true;
1533 }
1534 
1535 
1536 bool
1538  if (inputStorage.readUnsignedByte() != libsumo::TYPE_POLYGON) {
1539  return false;
1540  }
1541  into.clear();
1542  int size = inputStorage.readUnsignedByte();
1543  if (size == 0) {
1544  size = inputStorage.readInt();
1545  }
1546  PositionVector shape;
1547  for (int i = 0; i < size; ++i) {
1548  double x = inputStorage.readDouble();
1549  double y = inputStorage.readDouble();
1550  if (std::isnan(x) || std::isnan(y)) {
1551  throw libsumo::TraCIException("NaN-Value in shape.");
1552  }
1553  into.push_back(Position(x, y));
1554  }
1555  return true;
1556 }
1557 
1558 
1559 void
1561  myTargetTime = targetTime;
1562  for (auto& s : mySockets) {
1563  s.second->targetTime = targetTime;
1564  for (auto& stateChange : s.second->vehicleStateChanges) {
1565  stateChange.second.clear();
1566  }
1567  }
1568 }
1569 
1570 
1571 bool
1572 TraCIServer::centralObject(const libsumo::Subscription& s, const std::string& objID) {
1573  return (s.id == objID && s.commandId + 32 == s.contextDomain);
1574 }
1575 
1576 
1577 /****************************************************************************/
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:278
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:284
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:276
SUMOTime DELTA_T
Definition: SUMOTime.cpp:37
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition: SUMOTime.cpp:45
#define STEPS2TIME(x)
Definition: SUMOTime.h:53
#define SUMOTime_MAX
Definition: SUMOTime.h:32
#define SIMTIME
Definition: SUMOTime.h:60
#define TIME2STEPS(x)
Definition: SUMOTime.h:55
long long int SUMOTime
Definition: SUMOTime.h:31
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
T MIN2(T a, T b)
Definition: StdDefs.h:73
std::string toHex(const T i, std::streamsize numDigits=0)
Definition: ToString.h:54
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:44
static bool gUseMesoSim
Definition: MSGlobals.h:88
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:66
VehicleState
Definition of a vehicle state.
Definition: MSNet.h:587
@ VEHICLE_STATE_NEWROUTE
The vehicle got a new route.
Definition: MSNet.h:599
@ VEHICLE_STATE_ENDING_TELEPORT
The vehicle ended being teleported.
Definition: MSNet.h:595
@ VEHICLE_STATE_DEPARTED
The vehicle has departed (was inserted into the network)
Definition: MSNet.h:591
@ VEHICLE_STATE_STARTING_PARKING
The vehicles starts to park.
Definition: MSNet.h:601
@ VEHICLE_STATE_MANEUVERING
Vehicle maneuvering either entering or exiting a parking space.
Definition: MSNet.h:613
@ VEHICLE_STATE_ENDING_STOP
The vehicle ends to stop.
Definition: MSNet.h:607
@ VEHICLE_STATE_ARRIVED
The vehicle arrived at his destination (is deleted)
Definition: MSNet.h:597
@ VEHICLE_STATE_COLLISION
The vehicle is involved in a collision.
Definition: MSNet.h:609
@ VEHICLE_STATE_EMERGENCYSTOP
The vehicle had to brake harder than permitted.
Definition: MSNet.h:611
@ VEHICLE_STATE_STARTING_TELEPORT
The vehicle started to teleport.
Definition: MSNet.h:593
@ VEHICLE_STATE_STARTING_STOP
The vehicles starts to stop.
Definition: MSNet.h:605
@ VEHICLE_STATE_ENDING_PARKING
The vehicle ends to park.
Definition: MSNet.h:603
@ VEHICLE_STATE_BUILT
The vehicle was built, but has not yet departed.
Definition: MSNet.h:589
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:171
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:313
void addVehicleStateListener(VehicleStateListener *listener)
Adds a vehicle states listener.
Definition: MSNet.cpp:1054
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:986
MSTransportable * get(const std::string &id) const
Returns the named transportable, if existing.
virtual void inform(std::string msg, bool addType=true)
adds a new error to the list
Definition: MsgHandler.cpp:117
static MsgHandler * getWarningInstance()
Returns the instance to add warnings to.
Definition: MsgHandler.cpp:67
const std::string & getID() const
Returns the id.
Definition: Named.h:73
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:36
A list of positions.
Representation of a vehicle.
Definition: SUMOVehicle.h:58
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc6: Change BusStop State)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa6: Get BusStop Variable)
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc6: Change Calibrator State)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa6: Get Calibrator Variable)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa6: Get ChargingStation Variable)
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc6: Change ChargingStation State)
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xca: Change Edge State)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xaa: Get Edge Variable)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa0: Get Induction Loop Variable)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa9: Get Junction Variable)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa1: Get AreaDetector Variable)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa3: Get Lane Variable)
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc3: Change Lane State)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa6: Get MeanData Variable)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa1: Get MeMeDetector Variable)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa6: Get OverheadWire Variable)
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc6: Change OverheadWire State)
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc7: Change PoI State)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa7: Get PoI Variable)
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc6: Change ParkingArea State)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa6: Get ParkingArea Variable)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xae: Get Person Variable)
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xce: Change Person State)
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc8: Change Polygon State)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa8: Get Polygon Variable)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa6: Get Rerouter Variable)
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc6: Change Rerouter State)
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc6: Change Route State)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa6: Get Route Variable)
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc6: Change RouteProbe State)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa6: Get RouteProbe Variable)
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xcb: Set Simulation Variable)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xab: Get Simulation Variable)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa2: Get Traffic Lights Variable)
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc2: Change Traffic Lights State)
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc6: Change VariableSpeedSign State)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa6: Get VariableSpeedSign Variable)
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc4: Change Vehicle State)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa4: Get Vehicle Variable)
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc5: Change Vehicle Type State)
static bool processGet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a get value command (Command 0xa5: Get Vehicle Type Variable)
TraCI server used to control sumo by a remote TraCI client.
Definition: TraCIServer.h:59
void addSubscriptionFilterDownstreamDistance(double dist)
static bool myDoCloseConnection
Whether the connection was set to be to close.
Definition: TraCIServer.h:343
std::map< int, int > myParameterSizes
Map of variable ids to the size of the parameter in bytes.
Definition: TraCIServer.h:374
tcpip::Storage myWrapperStorage
A temporary storage to let the wrapper write to.
Definition: TraCIServer.h:365
std::map< int, SocketInfo * > mySockets
The socket connections to the clients the first component (index) determines the client's order (lowe...
Definition: TraCIServer.h:347
void addSubscriptionFilterLateralDistance(double dist)
Filter only vehicles within the given lateral distance.
void writeStatusCmd(int commandId, int status, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage.
static bool wasClosed()
check whether close was requested
bool centralObject(const libsumo::Subscription &s, const std::string &objID)
check whether a found objID refers to the central object of a context subscription
std::map< int, SocketInfo * >::iterator myCurrentSocket
The currently active client socket.
Definition: TraCIServer.h:353
void addSubscriptionFilterVType(std::set< std::string > vTypes)
bool readTypeCheckingString(tcpip::Storage &inputStorage, std::string &into)
Reads the value type and a string, verifying the type.
bool wrapInt(const std::string &objID, const int variable, const int value)
bool readTypeCheckingByte(tcpip::Storage &inputStorage, int &into)
Reads the value type and a byte, verifying the type.
std::map< int, SocketInfo * >::iterator removeCurrentSocket()
removes myCurrentSocket from mySockets and returns an iterator pointing to the next member according ...
tcpip::Storage myOutputStorage
The storage to write to.
Definition: TraCIServer.h:362
bool addObjectVariableSubscription(const int commandId, const bool hasContext)
void addSubscriptionFilterUpstreamDistance(double dist)
void stateLoaded(SUMOTime targetTime)
updates myTargetTime and resets vehicle state changes after loading a simulation state
void addSubscriptionFilterLeadFollow()
void addSubscriptionFilterNoOpposite()
tcpip::Storage & getWrapperStorage()
SUMOTime nextTargetTime() const
get the minimal next target time among all clients
void removeSubscription(int commandId, const std::string &identity, int domain)
bool wrapDouble(const std::string &objID, const int variable, const double value)
tcpip::Storage mySubscriptionCache
The last timestep's subscription results.
Definition: TraCIServer.h:368
bool readTypeCheckingUnsignedByte(tcpip::Storage &inputStorage, int &into)
Reads the value type and an unsigned byte, verifying the type.
bool wrapColor(const std::string &objID, const int variable, const libsumo::TraCIColor &value)
bool wrapString(const std::string &objID, const int variable, const std::string &value)
int dispatchCommand()
Handles command, writes response to myOutputStorage.
void initWrapper(const int domainID, const int variable, const std::string &objID)
bool writeErrorStatusCmd(int commandId, const std::string &description, tcpip::Storage &outputStorage)
Writes a status command to the given storage with status = RTYPE_ERR.
void checkClientOrdering()
Called once after connection of all clients for executing SET_ORDER (and possibly prior GET_VERSION) ...
bool readTypeCheckingPosition2D(tcpip::Storage &inputStorage, libsumo::TraCIPosition &into)
Reads the value type and a 2D position, verifying the type.
void processReorderingRequests()
checks for and processes reordering requests (relevant for multiple clients)
void sendOutputToAll() const
send out subscription results (actually just the content of myOutputStorage) to clients which will ac...
void cleanup()
clean up subscriptions
static void close()
request termination of connection
void processCommandsUntilSimStep(SUMOTime step)
process all commands until the next SUMO simulation step. It is guaranteed that t->getTargetTime() >=...
void postProcessSimulationStep()
Handles subscriptions to send after a simstep2 command.
bool readTypeCheckingInt(tcpip::Storage &inputStorage, int &into)
Reads the value type and an int, verifying the type.
bool commandGetVersion()
Returns the TraCI-version.
bool wrapPosition(const std::string &objID, const int variable, const libsumo::TraCIPosition &value)
static void openSocket(const std::map< int, CmdExecutor > &execs)
Initialises the server.
std::vector< std::string > myLoadArgs
Definition: TraCIServer.h:376
void removeFilters()
void addSubscriptionFilterLanes(std::vector< int > lanes)
bool readTypeCheckingDoubleList(tcpip::Storage &inputStorage, std::vector< double > &into)
Reads the value type and a double list, verifying the type.
bool readTypeCheckingStringList(tcpip::Storage &inputStorage, std::vector< std::string > &into)
Reads the value type and a string list, verifying the type.
SUMOTime myTargetTime
The time step to reach until processing the next commands.
Definition: TraCIServer.h:356
virtual ~TraCIServer()
Destructor.
bool readTypeCheckingDouble(tcpip::Storage &inputStorage, double &into)
Reads the value type and a double, verifying the type.
void writePositionVector(tcpip::Storage &outputStorage, const libsumo::TraCIPositionVector &shape)
void addSubscriptionFilterTurn()
std::map< MSNet::VehicleState, std::vector< std::string > > myVehicleStateChanges
Changes in the states of simulated vehicles.
Definition: TraCIServer.h:391
int readCommandID(int &commandStart, int &commandLength)
Reads the next command ID from the input storage.
void sendSingleSimStepResponse()
sends an empty response to a simstep command to the current client. (This applies to a situation wher...
std::map< int, CmdExecutor > myExecutors
Map of commandIds -> their executors; applicable if the executor applies to the method footprint.
Definition: TraCIServer.h:371
std::vector< libsumo::Subscription > mySubscriptions
The list of known, still valid subscriptions.
Definition: TraCIServer.h:379
void vehicleStateChanged(const SUMOVehicle *const vehicle, MSNet::VehicleState to, const std::string &info="")
Called if a vehicle changes its state.
void writeResponseWithLength(tcpip::Storage &outputStorage, tcpip::Storage &tempMsg)
TraCIServer(const SUMOTime begin, const int port, const int numClients)
Constructor.
tcpip::Storage myInputStorage
The storage to read from.
Definition: TraCIServer.h:359
libsumo::Subscription * myLastContextSubscription
The last modified context subscription (the one to add a filter to, see @addSubscriptionFilter(),...
Definition: TraCIServer.h:382
bool wrapRoadPosition(const std::string &objID, const int variable, const libsumo::TraCIRoadPosition &value)
void addSubscriptionFilterVClass(SVCPermissions vClasses)
static TraCIServer * myInstance
Singleton instance of the server.
Definition: TraCIServer.h:340
std::map< int, SocketInfo * > mySocketReorderRequests
This stores the setOrder(int) requests of the clients.
Definition: TraCIServer.h:350
bool addSubscriptionFilter()
bool processSingleSubscription(const libsumo::Subscription &s, tcpip::Storage &writeInto, std::string &errors)
void initialiseSubscription(libsumo::Subscription &s)
bool readTypeCheckingPolygon(tcpip::Storage &inputStorage, PositionVector &into)
Reads the value type and a polygon, verifying the type.
void addSubscriptionFilterFieldOfVision(double openingAngle)
Filter only vehicles within field of vision.
bool wrapStringList(const std::string &objID, const int variable, const std::vector< std::string > &value)
bool readTypeCheckingColor(tcpip::Storage &inputStorage, libsumo::TraCIColor &into)
Reads the value type and a color, verifying the type.
static void findObjectShape(int domain, const std::string &id, PositionVector &shape)
Definition: Helper.cpp:560
static void applySubscriptionFilters(const Subscription &s, std::set< std::string > &objIDs)
Filter the given ID-Set (which was obtained from an R-Tree search) according to the filters set by th...
Definition: Helper.cpp:641
static void collectObjectIDsInRange(int domain, const PositionVector &shape, double range, std::set< std::string > &into)
Definition: Helper.cpp:593
static bool needNewSubscription(libsumo::Subscription &s, std::vector< Subscription > &subscriptions, libsumo::Subscription *&modifiedSubscription)
Definition: Helper.cpp:213
Representation of a subscription.
Definition: Subscription.h:67
double filterUpstreamDist
Upstream distance specified by the upstream distance filter.
Definition: Subscription.h:133
int commandId
commandIdArg The command id of the subscription
Definition: Subscription.h:110
std::set< std::string > filterVTypes
vTypes specified by the vTypes filter
Definition: Subscription.h:135
double filterFieldOfVisionOpeningAngle
Opening angle (in deg) specified by the field of vision filter.
Definition: Subscription.h:139
std::vector< int > filterLanes
lanes specified by the lanes filter
Definition: Subscription.h:129
std::string id
The id of the object that is subscribed.
Definition: Subscription.h:112
int filterVClasses
vClasses specified by the vClasses filter,
Definition: Subscription.h:137
SUMOTime endTime
The end time of the subscription.
Definition: Subscription.h:120
int contextDomain
The domain ID of the context.
Definition: Subscription.h:122
bool isVehicleToVehicleContextSubscription() const
Definition: Subscription.h:101
SUMOTime beginTime
The begin time of the subscription.
Definition: Subscription.h:118
std::vector< int > variables
The subscribed variables.
Definition: Subscription.h:114
bool isVehicleToPersonContextSubscription() const
Definition: Subscription.h:105
double filterDownstreamDist
Downstream distance specified by the downstream distance filter.
Definition: Subscription.h:131
double filterLateralDist
Lateral distance specified by the lateral distance filter.
Definition: Subscription.h:141
std::vector< std::vector< unsigned char > > parameters
The parameters for the subscribed variables.
Definition: Subscription.h:116
int activeFilters
Active filters for the subscription (bitset,.
Definition: Subscription.h:127
double range
The range of the context.
Definition: Subscription.h:124
Socket * accept(const bool create=false)
Wait for a incoming connection to port_.
Definition: socket.cpp:260
virtual void writePacket(unsigned char *packet, int length)
Definition: storage.cpp:367
StorageType::const_iterator begin() const
Definition: storage.h:120
virtual unsigned char readChar()
Definition: storage.cpp:97
virtual std::string readString()
Definition: storage.cpp:175
virtual void writeString(const std::string &s)
Definition: storage.cpp:192
virtual unsigned int position() const
Definition: storage.cpp:76
virtual void writeInt(int)
Definition: storage.cpp:316
StorageType::const_iterator end() const
Definition: storage.h:121
virtual void writeDouble(double)
Definition: storage.cpp:349
virtual int readUnsignedByte()
Definition: storage.cpp:150
virtual void writeStringList(const std::vector< std::string > &s)
Definition: storage.cpp:242
void reset()
Definition: storage.cpp:85
virtual void writeUnsignedByte(int)
Definition: storage.cpp:160
StorageType::size_type size() const
Definition: storage.h:118
virtual bool valid_pos()
Definition: storage.cpp:69
virtual void writeByte(int)
Definition: storage.cpp:135
virtual void writeStorage(tcpip::Storage &store)
Definition: storage.cpp:383
virtual int readByte()
Definition: storage.cpp:123
virtual std::vector< std::string > readStringList()
Definition: storage.cpp:206
virtual double readDouble()
Definition: storage.cpp:357
virtual int readInt()
Definition: storage.cpp:306
virtual std::vector< double > readDoubleList()
Definition: storage.cpp:224
TRACI_CONST double INVALID_DOUBLE_VALUE
TRACI_CONST int TYPE_COLOR
TRACI_CONST int CMD_SUBSCRIBE_SIM_VARIABLE
TRACI_CONST int FILTER_TYPE_DOWNSTREAM_DIST
TRACI_CONST int CMD_LOAD
TRACI_CONST int POSITION_3D
TRACI_CONST int CMD_GET_CHARGINGSTATION_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_EDGE_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_VEHICLETYPE_VARIABLE
TRACI_CONST int RTYPE_NOTIMPLEMENTED
TRACI_CONST int CMD_SUBSCRIBE_LANE_CONTEXT
TRACI_CONST int FILTER_TYPE_NOOPPOSITE
TRACI_CONST int CMD_SET_OVERHEADWIRE_VARIABLE
TRACI_CONST int TRACI_ID_LIST
TRACI_CONST int CMD_GET_PARKINGAREA_VARIABLE
TRACI_CONST int CMD_GET_POI_VARIABLE
TRACI_CONST int CMD_GET_TL_VARIABLE
TRACI_CONST int CMD_SET_EDGE_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_JUNCTION_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_VEHICLE_CONTEXT
TRACI_CONST int CMD_GET_REROUTER_VARIABLE
TRACI_CONST int CMD_GET_VEHICLE_VARIABLE
TRACI_CONST int CMD_SET_CALIBRATOR_VARIABLE
TRACI_CONST int CMD_GET_EDGE_VARIABLE
TRACI_CONST int CMD_GET_CALIBRATOR_VARIABLE
TRACI_CONST int MAX_ORDER
TRACI_CONST int CMD_SUBSCRIBE_TL_CONTEXT
TRACI_CONST int FILTER_TYPE_FIELD_OF_VISION
TRACI_CONST int CMD_SET_REROUTER_VARIABLE
std::vector< TraCIPosition > TraCIPositionVector
Definition: TraCIDefs.h:196
TRACI_CONST int CMD_GET_PERSON_VARIABLE
TRACI_CONST int CMD_SET_VARIABLESPEEDSIGN_VARIABLE
TRACI_CONST int TYPE_UBYTE
TRACI_CONST int CMD_SUBSCRIBE_GUI_VARIABLE
TRACI_CONST int CMD_SET_POI_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_ROUTE_CONTEXT
TRACI_CONST int CMD_GET_ROUTEPROBE_VARIABLE
TRACI_CONST int CMD_GET_LANEAREA_VARIABLE
TRACI_CONST int CMD_SET_POLYGON_VARIABLE
TRACI_CONST int POSITION_2D
TRACI_CONST int CMD_GET_BUSSTOP_VARIABLE
TRACI_CONST int VAR_LEADER
TRACI_CONST int CMD_CLOSE
TRACI_CONST int TYPE_POLYGON
TRACI_CONST int CMD_GET_ROUTE_VARIABLE
TRACI_CONST int CMD_SET_ROUTE_VARIABLE
TRACI_CONST int CMD_SETORDER
TRACI_CONST int FILTER_TYPE_VTYPE
TRACI_CONST int TYPE_STRINGLIST
TRACI_CONST int CMD_SET_SIM_VARIABLE
TRACI_CONST int TYPE_INTEGER
TRACI_CONST int CMD_ADD_SUBSCRIPTION_FILTER
TRACI_CONST int CMD_GET_MEANDATA_VARIABLE
TRACI_CONST int CMD_GET_JUNCTION_VARIABLE
TRACI_CONST int CMD_SET_VEHICLE_VARIABLE
TRACI_CONST int CMD_SET_GUI_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_ROUTE_VARIABLE
TRACI_CONST int TRACI_VERSION
TRACI_CONST int CMD_GET_VARIABLESPEEDSIGN_VARIABLE
TRACI_CONST int CMD_SET_VEHICLETYPE_VARIABLE
TRACI_CONST int CMD_SET_PERSON_VARIABLE
TRACI_CONST int CMD_GET_SIM_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_POLYGON_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_PERSON_CONTEXT
TRACI_CONST int CMD_GET_VEHICLETYPE_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_POLYGON_CONTEXT
TRACI_CONST int CMD_SET_CHARGINGSTATION_VARIABLE
TRACI_CONST int CMD_SET_LANE_VARIABLE
TRACI_CONST int FILTER_TYPE_LEAD_FOLLOW
TRACI_CONST int CMD_SUBSCRIBE_GUI_CONTEXT
TRACI_CONST int CMD_SET_PARKINGAREA_VARIABLE
TRACI_CONST int CMD_GET_LANE_VARIABLE
TRACI_CONST int VAR_POSITION3D
TRACI_CONST int CMD_GET_GUI_VARIABLE
TRACI_CONST int VAR_PARAMETER_WITH_KEY
TRACI_CONST int FILTER_TYPE_UPSTREAM_DIST
TRACI_CONST int TYPE_DOUBLELIST
TRACI_CONST int CMD_GET_POLYGON_VARIABLE
TRACI_CONST int FILTER_TYPE_TURN
TRACI_CONST int CMD_SUBSCRIBE_MULTIENTRYEXIT_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_VEHICLE_VARIABLE
TRACI_CONST int CMD_GET_MULTIENTRYEXIT_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_INDUCTIONLOOP_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_POI_VARIABLE
TRACI_CONST int TYPE_DOUBLE
@ SUBS_FILTER_LEAD_FOLLOW
Definition: Subscription.h:46
@ SUBS_FILTER_UPSTREAM_DIST
Definition: Subscription.h:44
@ SUBS_FILTER_VTYPE
Definition: Subscription.h:52
@ SUBS_FILTER_NO_RTREE
Definition: Subscription.h:59
@ SUBS_FILTER_LANES
Definition: Subscription.h:38
@ SUBS_FILTER_NOOPPOSITE
Definition: Subscription.h:40
@ SUBS_FILTER_DOWNSTREAM_DIST
Definition: Subscription.h:42
@ SUBS_FILTER_LATERAL_DIST
Definition: Subscription.h:57
@ SUBS_FILTER_TURN
Definition: Subscription.h:48
@ SUBS_FILTER_VCLASS
Definition: Subscription.h:50
@ SUBS_FILTER_NONE
Definition: Subscription.h:36
@ SUBS_FILTER_FIELD_OF_VISION
Definition: Subscription.h:55
TRACI_CONST int CMD_SUBSCRIBE_LANEAREA_VARIABLE
TRACI_CONST int TYPE_BYTE
TRACI_CONST int CMD_SUBSCRIBE_POI_CONTEXT
TRACI_CONST int CMD_SET_TL_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_INDUCTIONLOOP_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_SIM_CONTEXT
TRACI_CONST int FILTER_TYPE_VCLASS
TRACI_CONST int CMD_SUBSCRIBE_MULTIENTRYEXIT_VARIABLE
TRACI_CONST int CMD_GETVERSION
TRACI_CONST int RTYPE_ERR
TRACI_CONST int CMD_SIMSTEP
TRACI_CONST int FILTER_TYPE_NONE
TRACI_CONST int CMD_SUBSCRIBE_VEHICLETYPE_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_LANE_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_PERSON_VARIABLE
TRACI_CONST int RTYPE_OK
TRACI_CONST int CMD_GET_INDUCTIONLOOP_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_TL_VARIABLE
TRACI_CONST int CMD_GET_OVERHEADWIRE_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_LANEAREA_CONTEXT
TRACI_CONST int FILTER_TYPE_LANES
TRACI_CONST int CMD_SUBSCRIBE_JUNCTION_CONTEXT
TRACI_CONST int CMD_SET_ROUTEPROBE_VARIABLE
TRACI_CONST int CMD_SET_BUSSTOP_VARIABLE
TRACI_CONST int FILTER_TYPE_LATERAL_DIST
TRACI_CONST int CMD_SUBSCRIBE_EDGE_VARIABLE
TRACI_CONST int TYPE_STRING
A 3D-position.
Definition: TraCIDefs.h:141
An edgeId, position and laneIndex.
Definition: TraCIDefs.h:153