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-2022 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>
51#include <utils/xml/XMLSubSys.h>
52#include <libsumo/Helper.h>
53#include <microsim/MSNet.h>
54#include <microsim/MSVehicle.h>
55#include <microsim/MSEdge.h>
58#include <microsim/MSJunction.h>
60#include <microsim/MSLane.h>
61#include <microsim/MSGlobals.h>
63#include <libsumo/Simulation.h>
66#include "TraCIServer.h"
69#include "TraCIServerAPI_Lane.h"
76#include "TraCIServerAPI_POI.h"
78#include "TraCIServerAPI_Edge.h"
90
91
92// ===========================================================================
93// debug constants
94// ===========================================================================
95//#define DEBUG_MULTI_CLIENTS
96//#define DEBUG_SUBSCRIPTIONS
97//#define DEBUG_SUBSCRIPTION_FILTERS
98//#define DEBUG_RAW_INPUT
99
100
101// ===========================================================================
102// static member definitions
103// ===========================================================================
106
107
108// ===========================================================================
109// method definitions
110// ===========================================================================
111void
112TraCIServer::initWrapper(const int domainID, const int variable, const std::string& objID) {
117}
118
119
120bool
121TraCIServer::wrapDouble(const std::string& /* objID */, const int /* variable */, const double value) {
124 return true;
125}
126
127
128bool
129TraCIServer::wrapInt(const std::string& /* objID */, const int /* variable */, const int value) {
132 return true;
133}
134
135
136bool
137TraCIServer::wrapString(const std::string& /* objID */, const int /* variable */, const std::string& value) {
140 return true;
141}
142
143
144bool
145TraCIServer::wrapStringList(const std::string& /* objID */, const int /* variable */, const std::vector<std::string>& value) {
148 return true;
149}
150
151
152bool
153TraCIServer::wrapDoubleList(const std::string& /* objID */, const int /* variable */, const std::vector<double>& value) {
156 return true;
157}
158
159
160bool
161TraCIServer::wrapPosition(const std::string& /* objID */, const int variable, const libsumo::TraCIPosition& value) {
162 const bool includeZ = variable == libsumo::VAR_POSITION3D;
166 if (includeZ) {
168 }
169 return true;
170}
171
172
173bool
174TraCIServer::wrapPositionVector(const std::string& /* objID */, const int /* variable */, const libsumo::TraCIPositionVector& shape) {
176 if (shape.value.size() < 256) {
177 myWrapperStorage.writeUnsignedByte((int)shape.value.size());
178 } else {
180 myWrapperStorage.writeInt((int)shape.value.size());
181 }
182 for (const libsumo::TraCIPosition& pos : shape.value) {
185 }
186 return true;
187}
188
189
190bool
191TraCIServer::wrapColor(const std::string& /* objID */, const int /* variable */, const libsumo::TraCIColor& value) {
197 return true;
198}
199
200
201bool
202TraCIServer::wrapStringDoublePair(const std::string& /* objID */, const int /* variable */, const std::pair<std::string, double>& value) {
206 myWrapperStorage.writeString(value.first);
208 myWrapperStorage.writeDouble(value.second);
209 return true;
210}
211
212
213bool
214TraCIServer::wrapStringPair(const std::string& /* objID */, const int /* variable */, const std::pair<std::string, std::string>& value) {
218 myWrapperStorage.writeString(value.first);
220 myWrapperStorage.writeString(value.second);
221 return true;
222}
223
224
227 return myWrapperStorage;
228}
229
230
231
232TraCIServer::TraCIServer(const SUMOTime begin, const int port, const int numClients)
233 : myTargetTime(begin), myLastContextSubscription(nullptr) {
234#ifdef DEBUG_MULTI_CLIENTS
235 std::cout << "Creating new TraCIServer for " << numClients << " clients on port " << port << "." << std::endl;
236#endif
237 myVehicleStateChanges[MSNet::VehicleState::BUILT] = std::vector<std::string>();
238 myVehicleStateChanges[MSNet::VehicleState::DEPARTED] = std::vector<std::string>();
241 myVehicleStateChanges[MSNet::VehicleState::ARRIVED] = std::vector<std::string>();
242 myVehicleStateChanges[MSNet::VehicleState::NEWROUTE] = std::vector<std::string>();
244 myVehicleStateChanges[MSNet::VehicleState::MANEUVERING] = std::vector<std::string>();
246 myVehicleStateChanges[MSNet::VehicleState::STARTING_STOP] = std::vector<std::string>();
247 myVehicleStateChanges[MSNet::VehicleState::ENDING_STOP] = std::vector<std::string>();
248 myVehicleStateChanges[MSNet::VehicleState::COLLISION] = std::vector<std::string>();
249 myVehicleStateChanges[MSNet::VehicleState::EMERGENCYSTOP] = std::vector<std::string>();
250
255
262
300 //myExecutors[libsumo::CMD_SET_MEANDATA_VARIABLE] = &TraCIServerAPI_MeanData::processSet;
303
306 myParameterized.insert(std::make_pair(0, libsumo::VAR_PARAMETER));
307 myParameterized.insert(std::make_pair(0, libsumo::VAR_PARAMETER_WITH_KEY));
308
309 myDoCloseConnection = false;
310
311 // display warning if internal lanes are not used
313 WRITE_WARNING(TL("Starting TraCI without using internal lanes!"));
314 MsgHandler::getWarningInstance()->inform("Vehicles will jump over junctions.", false);
315 MsgHandler::getWarningInstance()->inform("Use without option --no-internal-links to avoid unexpected behavior", false);
316 }
317
318 try {
319 WRITE_MESSAGE("***Starting server on port " + toString(port) + " ***");
320 tcpip::Socket serverSocket(port);
321 if (numClients > 1) {
322 WRITE_MESSAGE(" waiting for " + toString(numClients) + " clients...");
323 }
324 while ((int)mySockets.size() < numClients) {
325 int index = (int)mySockets.size() + libsumo::MAX_ORDER + 1;
326 mySockets[index] = new SocketInfo(serverSocket.accept(true), begin);
327 mySockets[index]->vehicleStateChanges[MSNet::VehicleState::BUILT] = std::vector<std::string>();
328 mySockets[index]->vehicleStateChanges[MSNet::VehicleState::DEPARTED] = std::vector<std::string>();
329 mySockets[index]->vehicleStateChanges[MSNet::VehicleState::STARTING_TELEPORT] = std::vector<std::string>();
330 mySockets[index]->vehicleStateChanges[MSNet::VehicleState::ENDING_TELEPORT] = std::vector<std::string>();
331 mySockets[index]->vehicleStateChanges[MSNet::VehicleState::ARRIVED] = std::vector<std::string>();
332 mySockets[index]->vehicleStateChanges[MSNet::VehicleState::NEWROUTE] = std::vector<std::string>();
333 mySockets[index]->vehicleStateChanges[MSNet::VehicleState::STARTING_PARKING] = std::vector<std::string>();
334 mySockets[index]->vehicleStateChanges[MSNet::VehicleState::MANEUVERING] = std::vector<std::string>();
335 mySockets[index]->vehicleStateChanges[MSNet::VehicleState::ENDING_PARKING] = std::vector<std::string>();
336 mySockets[index]->vehicleStateChanges[MSNet::VehicleState::STARTING_STOP] = std::vector<std::string>();
337 mySockets[index]->vehicleStateChanges[MSNet::VehicleState::ENDING_STOP] = std::vector<std::string>();
338 mySockets[index]->vehicleStateChanges[MSNet::VehicleState::COLLISION] = std::vector<std::string>();
339 mySockets[index]->vehicleStateChanges[MSNet::VehicleState::EMERGENCYSTOP] = std::vector<std::string>();
340
341 mySockets[index]->transportableStateChanges[MSNet::TransportableState::PERSON_DEPARTED] = std::vector<std::string>();
342 mySockets[index]->transportableStateChanges[MSNet::TransportableState::PERSON_ARRIVED] = std::vector<std::string>();
343 mySockets[index]->transportableStateChanges[MSNet::TransportableState::CONTAINER_DEPARTED] = std::vector<std::string>();
344 mySockets[index]->transportableStateChanges[MSNet::TransportableState::CONTAINER_ARRIVED] = std::vector<std::string>();
345 if (numClients > 1) {
346 WRITE_MESSAGE(TL(" client connected"));
347 }
348 }
349 // When got here, all clients have connected
350 if (numClients > 1) {
352 }
353 // set myCurrentSocket != mySockets.end() to indicate that this is the first step in processCommandsUntilSimStep()
354 myCurrentSocket = mySockets.begin();
355 } catch (tcpip::SocketException& e) {
356 throw ProcessError(e.what());
357 }
358}
359
360
362 for (const auto& socket : mySockets) {
363 delete socket.second;
364 }
365 // there is no point in calling cleanup() here, it does not free any pointers and will only modify members which get deleted anyway
366}
367
368
369// ---------- Initialisation and Shutdown
370void
371TraCIServer::openSocket(const std::map<int, CmdExecutor>& execs) {
372 if (myInstance == nullptr && !myDoCloseConnection && (OptionsCont::getOptions().getInt("remote-port") != 0)) {
373 myInstance = new TraCIServer(string2time(OptionsCont::getOptions().getString("begin")),
374 OptionsCont::getOptions().getInt("remote-port"),
375 OptionsCont::getOptions().getInt("num-clients"));
376 for (std::map<int, CmdExecutor>::const_iterator i = execs.begin(); i != execs.end(); ++i) {
377 myInstance->myExecutors[i->first] = i->second;
378 }
379 }
380 if (myInstance != nullptr) {
381 // maybe net was deleted and built again
385 }
386}
387
388
389void
391 if (myInstance == nullptr) {
392 return;
393 }
394 delete myInstance;
395 myInstance = nullptr;
396 myDoCloseConnection = true;
397}
398
399
400bool
402 return myDoCloseConnection;
403}
404
405
406// ---------- Initialisation and Shutdown
407
408
409void
410TraCIServer::vehicleStateChanged(const SUMOVehicle* const vehicle, MSNet::VehicleState to, const std::string& /*info*/) {
411 if (!myDoCloseConnection) {
412 myVehicleStateChanges[to].push_back(vehicle->getID());
413 for (std::map<int, SocketInfo*>::iterator i = mySockets.begin(); i != mySockets.end(); ++i) {
414 i->second->vehicleStateChanges[to].push_back(vehicle->getID());
415 }
416 }
417}
418
419
420void
421TraCIServer::transportableStateChanged(const MSTransportable* const transportable, MSNet::TransportableState to, const std::string& /*info*/) {
422 if (!myDoCloseConnection) {
423 myTransportableStateChanges[to].push_back(transportable->getID());
424 for (std::map<int, SocketInfo*>::iterator i = mySockets.begin(); i != mySockets.end(); ++i) {
425 i->second->transportableStateChanges[to].push_back(transportable->getID());
426 }
427 }
428}
429
430
431void
433#ifdef DEBUG_MULTI_CLIENTS
434 std::cout << "Checking client order requests." << std::endl;
435#endif
436 // check for SET_ORDER commands queued by connected clients
437 // In multiclient cas it is mandatory that SET_ORDER is sent as the first command (or directly after GET_VERSION)
438 myCurrentSocket = mySockets.begin();
439 while (myCurrentSocket != mySockets.end()) {
440#ifdef DEBUG_MULTI_CLIENTS
441 std::cout << " Socket " << myCurrentSocket->second->socket << ":" << std::endl;
442#endif
443// bool clientUnordered = true;
444#ifdef _MSC_VER
445#pragma warning(push)
446#pragma warning(disable: 4127) // do not warn about constant conditional expression
447#endif
448 while (true) {
449#ifdef _MSC_VER
450#pragma warning(pop)
451#endif
453 myCurrentSocket->second->socket->receiveExact(myInputStorage);
454 int commandStart, commandLength;
455 int commandId = readCommandID(commandStart, commandLength);
456#ifdef DEBUG_MULTI_CLIENTS
457 std::cout << " received command " << commandId << std::endl;
458#endif
459 // Whether the received command is a permitted command for the initialization phase.
460 // Currently, getVersion and setOrder are permitted.
461 bool initCommand = commandId == libsumo::CMD_SETORDER || commandId == libsumo::CMD_GETVERSION;
462 if (initCommand) {
463#ifdef DEBUG_MULTI_CLIENTS
464 std::cout << " Init command. Sending response." << std::endl;
465#endif
466 // reset input storage to initial state before reading the commandId
467 // (ugly, but we can't just reset the store's iter_ from here)
468 // Giving the commandId to dispatch command didn't work either
469 tcpip::Storage tmp;
472 // we don't know whether the command was set with extended
473 // length syntax or not so we hardcode the length here (#5037)
477
478 // Handle initialization command completely
480 myCurrentSocket->second->socket->sendExact(myOutputStorage);
482 } else {
483#ifdef DEBUG_MULTI_CLIENTS
484 std::cout << " Client " << myCurrentSocket->second->socket << " did not set order initially." << std::endl;
485#endif
486 throw ProcessError("Execution order (libsumo::CMD_SETORDER) was not set for all TraCI clients in pre-execution phase.");
487 }
488 if (commandId == libsumo::CMD_SETORDER) {
489 // This is what we have waited for.
490 break;
491 }
492 }
494 }
495}
496
497
498void
500 // Process reordering requests
501 if (mySocketReorderRequests.size() > 0) {
502 // process reordering requests
503 std::map<int, SocketInfo*>::const_iterator i = mySocketReorderRequests.begin();
504 std::map<int, SocketInfo*>::iterator j;
505#ifdef DEBUG_MULTI_CLIENTS
506 std::cout << SIMTIME << " Current socket ordering:\n";
507 for (j = mySockets.begin(); j != mySockets.end(); ++j) {
508 std::cout << " " << j->first << ": " << j->second->socket << "\n";
509 }
510 std::cout << "Reordering requests:\n";
511 for (i = mySocketReorderRequests.begin(); i != mySocketReorderRequests.end(); ++i) {
512 std::cout << " Socket " << i->second->socket << " -> " << i->first << "\n";
513 }
514 i = mySocketReorderRequests.begin();
515#endif
516 while (i != mySocketReorderRequests.end()) {
517 j = mySockets.begin();
518 while (j != mySockets.end()) {
519 if (j->second->socket == i->second->socket) {
520 break;
521 } else {
522 j++;
523 }
524 }
525 assert(j != mySockets.end());
526 mySockets.erase(j);
527 mySockets[i->first] = i->second;
528 ++i;
529 }
531#ifdef DEBUG_MULTI_CLIENTS
532 std::cout << "New socket ordering:\n";
533 for (j = mySockets.begin(); j != mySockets.end(); ++j) {
534 std::cout << " " << j->first << ": " << j->second->socket << "\n";
535 }
536 std::cout << std::endl;
537#endif
538 }
539}
540
541
544#ifdef DEBUG_MULTI_CLIENTS
545 std::cout << "\n Determining new target time..." << std::endl;
546 if (mySockets.size() == 0) {
547 std::cout << " All clients have disconnected." << std::endl;
548 }
549#endif
550 std::map<int, SocketInfo*>::const_iterator i;
551 SUMOTime targetTime = std::numeric_limits<SUMOTime>::max();
552 for (i = mySockets.begin(); i != mySockets.end(); ++i) {
553#ifdef DEBUG_MULTI_CLIENTS
554 std::cout << " target time for client " << i->second->socket << ": " << i->second->targetTime << "\n";
555#endif
556 targetTime = MIN2(targetTime, i->second->targetTime);
557 }
558#ifdef DEBUG_MULTI_CLIENTS
559 std::cout << std::endl;
560#endif
561 return targetTime;
562}
563
564
565// send out subscription results to clients which will act in this step (i.e. with client target time <= myTargetTime)
566void
568#ifdef DEBUG_MULTI_CLIENTS
569 std::cout << "\n Sending subscription results to clients:\n";
570#endif
571 std::map<int, SocketInfo*>::const_iterator i = mySockets.begin();
572 while (i != mySockets.end()) {
573 if (i->second->targetTime <= MSNet::getInstance()->getCurrentTimeStep()) {
574 // this client will become active before the next SUMO step. Provide subscription results.
575 i->second->socket->sendExact(myOutputStorage);
576#ifdef DEBUG_MULTI_CLIENTS
577 std::cout << i->second->socket << "\n";
578#endif
579 }
580 ++i;
581 }
582#ifdef DEBUG_MULTI_CLIENTS
583 std::cout << std::endl;
584#endif
585}
586
587
588void
590#ifdef DEBUG_MULTI_CLIENTS
591 std::cout << SIMTIME << " processCommandsUntilSimStep(step = " << step << "):\n" << std::endl;
592#endif
593 try {
594 const bool firstStep = myCurrentSocket != mySockets.end();
595 // update client order if requested
597 if (!firstStep) {
598 // 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)
599 // update subscription results
601 // Send out subscription results to clients which will act in this SUMO step (i.e. with client target time <= current sumo timestep end)
604 }
605
606 // determine minimal next target time among clients
608
609 if (step < myTargetTime) {
610#ifdef DEBUG_MULTI_CLIENTS
611 if (step < myTargetTime) {
612 std::cout << " next target time is larger than next SUMO simstep (" << step << "). Returning from processCommandsUntilSimStep()." << std::endl;
613 }
614#endif
615 return;
616 }
617
618 // Simulation should run until
619 // 1. end time reached or
620 // 2. got libsumo::CMD_CLOSE or
621 // 3. got libsumo::CMD_LOAD or
622 // 4. Client closes socket connection
623 while (!myDoCloseConnection && myTargetTime <= (MSNet::getInstance()->getCurrentTimeStep())) {
624#ifdef DEBUG_MULTI_CLIENTS
625 std::cout << " Next target time: " << myTargetTime << std::endl;
626#endif
627 // Iterate over clients and process communication for the ones with target time == myTargetTime
628 myCurrentSocket = mySockets.begin();
629 while (myCurrentSocket != mySockets.end()) {
630#ifdef DEBUG_MULTI_CLIENTS
631 std::cout << " current socket: " << myCurrentSocket->second->socket
632 << " with target time=" << myCurrentSocket->second->targetTime
633 << std::endl;
634#endif
635
636 if (myCurrentSocket->second->targetTime > myTargetTime) {
637 // this client must wait
638#ifdef DEBUG_MULTI_CLIENTS
639 std::cout << " skipping client " << myCurrentSocket->second->socket
640 << " with target time=" << myCurrentSocket->second->targetTime << std::endl;
641#endif
643 continue;
644 }
645 bool done = false;
646 bool closed = false;
647 bool load = false;
648 while (!done && !closed && !load) {
649 if (!myInputStorage.valid_pos()) {
650 // have read request completely, send response if adequate
651 if (myOutputStorage.size() > 0) {
652#ifdef DEBUG_MULTI_CLIENTS
653 std::cout << " sending response..." << std::endl;
654#endif
655 // send response to previous query
656 myCurrentSocket->second->socket->sendExact(myOutputStorage);
658 } else {
659#ifdef DEBUG_MULTI_CLIENTS
660 std::cout << " No input and no output stored (This is the next client)." << std::endl;
661#endif
662 }
663#ifdef DEBUG_MULTI_CLIENTS
664 std::cout << " resetting input storage and reading next command..." << std::endl;
665#endif
666 // Read next request
668 myCurrentSocket->second->socket->receiveExact(myInputStorage);
669 }
670
672 // dispatch command
673 const int cmd = dispatchCommand();
674#ifdef DEBUG_MULTI_CLIENTS
675 std::cout << " Received command " << cmd << std::endl;
676#endif
677 if (cmd == libsumo::CMD_SIMSTEP) {
678#ifdef DEBUG_MULTI_CLIENTS
679 std::cout << " Received command SIM_STEP, end turn for client " << myCurrentSocket->second->socket << std::endl;
680#endif
681 done = true;
682 } else if (cmd == libsumo::CMD_LOAD) {
683#ifdef DEBUG_MULTI_CLIENTS
684 std::cout << " Received command LOAD." << std::endl;
685#endif
686 load = true;
687 } else if (cmd == libsumo::CMD_CLOSE) {
688#ifdef DEBUG_MULTI_CLIENTS
689 std::cout << " Received command CLOSE." << std::endl;
690#endif
691 closed = true;
692 }
693 }
694 }
695 if (done) {
696 // Clear vehicleStateChanges and transportableStateChanges for this client
697 // -> For subsequent TraCI stepping
698 // that is performed within this SUMO step, no updates on vehicle states
699 // belonging to the last SUMO simulation step will be received by this client.
700 for (std::map<MSNet::VehicleState, std::vector<std::string> >::iterator i = myCurrentSocket->second->vehicleStateChanges.begin(); i != myCurrentSocket->second->vehicleStateChanges.end(); ++i) {
701 (*i).second.clear();
702 }
703 for (std::map<MSNet::TransportableState, std::vector<std::string> >::iterator i = myCurrentSocket->second->transportableStateChanges.begin(); i != myCurrentSocket->second->transportableStateChanges.end(); ++i) {
704 (*i).second.clear();
705 }
707 } else if (load) {
709 } else {
710 assert(closed);
711 // remove current socket and increment to next socket in ordering
713 }
714 }
715 if (!myLoadArgs.empty()) {
716#ifdef DEBUG_MULTI_CLIENTS
717 std::cout << " Breaking loop to load new simulation." << std::endl;
718#endif
719 break;
720 } else if (myDoCloseConnection) {
721#ifdef DEBUG_MULTI_CLIENTS
722 std::cout << " Breaking loop because last client closed connection." << std::endl;
723#endif
724 break;
725 }
726 SUMOTime nextT = nextTargetTime();
727 // minimal target time among clients should have been increased during the last loop through mySockets
728 // XXX: The assert below is disabled since many tests do sth. like simulationStep(step). Such that for a first call step=0,
729 // leading to targetTime==1000 (increased by DELTA_T in dispatchCommand()),
730 // the next call is then usually simulationStep(step=1000) leading to no further increase
731 // and thus a failing assertion here.
732 //assert(myTargetTime < nextT || myDoCloseConnection);
733 myTargetTime = nextT;
734 }
735 // All clients are done with the current time step
736 // Reset myVehicleStateChanges and myTransportableStateChanges
737 for (std::map<MSNet::VehicleState, std::vector<std::string> >::iterator i = myVehicleStateChanges.begin(); i != myVehicleStateChanges.end(); ++i) {
738 (*i).second.clear();
739 }
740 for (std::map<MSNet::TransportableState, std::vector<std::string> >::iterator i = myTransportableStateChanges.begin(); i != myTransportableStateChanges.end(); ++i) {
741 (*i).second.clear();
742 }
743 } catch (std::invalid_argument& e) {
744 throw ProcessError(e.what());
745 } catch (libsumo::TraCIException& e) {
746 throw ProcessError(e.what());
747 } catch (tcpip::SocketException& e) {
748 throw ProcessError(e.what());
749 }
750}
751
752
753void
755 mySubscriptions.clear();
756 myTargetTime = string2time(OptionsCont::getOptions().getString("begin"));
758 myCurrentSocket->second->targetTime = myTargetTime;
759 }
763 for (auto& i : myVehicleStateChanges) {
764 i.second.clear();
765 }
766 for (auto& i : myTransportableStateChanges) {
767 i.second.clear();
768 }
769 myCurrentSocket = mySockets.begin();
770}
771
772
773std::map<int, TraCIServer::SocketInfo*>::iterator
775#ifdef DEBUG_MULTI_CLIENTS
776 std::cout << " Removing socket " << myCurrentSocket->second->socket
777 << " (order " << myCurrentSocket->first << ")" << std::endl;
778#endif
779 delete myCurrentSocket->second;
781 return myCurrentSocket;
782}
783
784
785int
786TraCIServer::readCommandID(int& commandStart, int& commandLength) {
787 commandStart = myInputStorage.position();
788 commandLength = myInputStorage.readUnsignedByte();
789 if (commandLength == 0) {
790 commandLength = myInputStorage.readInt();
791 }
792#ifdef DEBUG_RAW_INPUT
793 std::cout << " commandStart=" << commandStart << " commandLength=" << commandLength << " pos=" << myInputStorage.position() << " raw=";
794 for (auto it = myInputStorage.begin(); it != myInputStorage.end(); ++it) {
795 std::cout << (int)*it << " ";
796 }
797 std::cout << "\n";
798#endif
800}
801
802
803int
805 int commandStart, commandLength;
806 int commandId = readCommandID(commandStart, commandLength);
807#ifdef DEBUG_MULTI_CLIENTS
808 std::cout << " dispatchCommand() called for client " << myCurrentSocket->second->socket
809 << ", commandId = " << commandId << std::endl;
810#endif
811 bool success = false;
812 // dispatch commands
813 if (myExecutors.find(commandId) != myExecutors.end()) {
814 success = myExecutors[commandId](*this, myInputStorage, myOutputStorage);
815 } else {
816 switch (commandId) {
818 success = commandGetVersion();
819 break;
820 case libsumo::CMD_LOAD: {
821 std::vector<std::string> args;
823 return writeErrorStatusCmd(libsumo::CMD_LOAD, "A load command needs a list of string arguments.", myOutputStorage);
824 }
825#ifdef DEBUG_MULTI_CLIENTS
826 std::cout << " commandId == libsumo::CMD_LOAD"
827 << ", args = " << toString(args) << std::endl;
828#endif
829 try {
830 myLoadArgs = args;
831 success = true;
833 // XXX: This only cares for the client that issued the load command.
834 // Multiclient-load functionality is still to be implemented. Refs #3146.
835 myCurrentSocket->second->socket->sendExact(myOutputStorage);
837 } catch (libsumo::TraCIException& e) {
839 }
840 break;
841 }
843 const double nextT = myInputStorage.readDouble();
844 if (nextT == 0.) {
845 myCurrentSocket->second->targetTime += DELTA_T;
846 } else {
847 myCurrentSocket->second->targetTime = TIME2STEPS(nextT);
848 }
849#ifdef DEBUG_MULTI_CLIENTS
850 std::cout << " commandId == libsumo::CMD_SIMSTEP"
851 << ", next target time for client is " << myCurrentSocket->second->targetTime << std::endl;
852#endif
853 if (myCurrentSocket->second->targetTime <= MSNet::getInstance()->getCurrentTimeStep()) {
854 // This is not the last TraCI simstep in the current SUMO simstep -> send single simstep response.
855 // @note: In the other case the simstep results are sent to all after the SUMO step was performed, see entry point for processCommandsUntilSimStep()
857 }
858 return commandId;
859 }
862 myCurrentSocket->second->socket->sendExact(myOutputStorage);
864 if (mySockets.size() == 1) {
865 // Last client has closed connection
866 myDoCloseConnection = true;
867 }
868 success = true;
869 break;
871 const int order = myInputStorage.readInt();
872#ifdef DEBUG_MULTI_CLIENTS
873 std::cout << " commandId == libsumo::CMD_SETORDER"
874 << ", order index is " << order << std::endl;
875#endif
876 if (order > libsumo::MAX_ORDER) {
877 return writeErrorStatusCmd(libsumo::CMD_SETORDER, "A set order command needs an int argument below " + toString(libsumo::MAX_ORDER) + ".", myOutputStorage);
878 }
879 if (mySockets.count(order) > 0 || mySocketReorderRequests.count(order) > 0) {
880 return writeErrorStatusCmd(libsumo::CMD_SETORDER, "Order '" + toString(order) + "' is already taken.", myOutputStorage);
881 }
882 // memorize reorder request (will only take effect in the next step)
884 success = true;
886 break;
887 }
912 success = addObjectVariableSubscription(commandId, false);
913 break;
938 success = addObjectVariableSubscription(commandId, true);
939 break;
941 success = addSubscriptionFilter();
942 break;
943 default:
944 if (commandId == libsumo::CMD_GET_GUI_VARIABLE || commandId == libsumo::CMD_SET_GUI_VARIABLE) {
945 writeStatusCmd(commandId, libsumo::RTYPE_NOTIMPLEMENTED, "GUI is not running, command not implemented in command line sumo");
946 } else {
947 writeStatusCmd(commandId, libsumo::RTYPE_NOTIMPLEMENTED, "Command not implemented in sumo");
948 }
949 }
950 }
951 if (!success) {
952 while (myInputStorage.valid_pos() && (int)myInputStorage.position() < commandStart + commandLength) {
954 }
955 }
956 if ((int)myInputStorage.position() != commandStart + commandLength) {
957 std::ostringstream msg;
958 msg << "Wrong position in requestMessage after dispatching command " << commandId << ".";
959 msg << " Expected command length was " << commandLength;
960 msg << " but " << myInputStorage.position() - commandStart << " Bytes were read.";
961 writeStatusCmd(commandId, libsumo::RTYPE_ERR, msg.str());
962 myDoCloseConnection = true;
963 }
964 return commandId;
965}
966
967
968// ---------- Server-internal command handling
969bool
971 // Prepare response
972 tcpip::Storage answerTmp;
974 answerTmp.writeString("SUMO " VERSION_STRING);
975 // When we get here, the response is stored in answerTmp -> put into myOutputStorage
977 // command length
978 myOutputStorage.writeUnsignedByte(1 + 1 + static_cast<int>(answerTmp.size()));
979 // command type
981 // and the parameter dependant part
982 myOutputStorage.writeStorage(answerTmp);
983 return true;
984}
985
986
987void
990#ifdef DEBUG_MULTI_CLIENTS
991 std::cout << " postProcessSimulationStep() at time=" << t << std::endl;
992#endif
994 int noActive = 0;
995 for (std::vector<libsumo::Subscription>::iterator i = mySubscriptions.begin(); i != mySubscriptions.end();) {
996 const libsumo::Subscription& s = *i;
999
1001 if ((s.endTime < t) || isArrivedVehicle || isArrivedPerson) {
1002 i = mySubscriptions.erase(i);
1003 continue;
1004 }
1005 ++i;
1006 if (s.beginTime > t) {
1007 continue;
1008 }
1009 ++noActive;
1010 }
1012#ifdef DEBUG_SUBSCRIPTIONS
1013 std::cout << " Initial size of mySubscriptionCache is " << mySubscriptionCache.size()
1014 << "\n Nr. of active subscriptions = " << noActive << std::endl;
1015#endif
1016 mySubscriptionCache.writeInt(noActive);
1017#ifdef DEBUG_SUBSCRIPTIONS
1018 std::cout << " Size after writing an int is " << mySubscriptionCache.size() << std::endl;
1019#endif
1020 for (std::vector<libsumo::Subscription>::iterator i = mySubscriptions.begin(); i != mySubscriptions.end();) {
1021 const libsumo::Subscription& s = *i;
1022 if (s.beginTime > t) {
1023 ++i;
1024 continue;
1025 }
1026 tcpip::Storage into;
1027 std::string errors;
1028 bool ok = processSingleSubscription(s, into, errors);
1029#ifdef DEBUG_SUBSCRIPTIONS
1030 std::cout << " Size of into-store for subscription " << s.id
1031 << ": " << into.size() << std::endl;
1032#endif
1034 if (ok) {
1035 ++i;
1036 } else {
1037 i = mySubscriptions.erase(i);
1038 }
1039 }
1041#ifdef DEBUG_SUBSCRIPTIONS
1042 std::cout << " Size after writing subscriptions is " << mySubscriptionCache.size() << std::endl;
1043#endif
1044}
1045
1046
1047void
1049#ifdef DEBUG_MULTI_CLIENTS
1050 std::cout << " Sending cached simstep response to current client " << myCurrentSocket->second->socket
1051 << " (-> intermediate TraCI step)."
1052 << "\n Size of mySubscriptionCache is " << mySubscriptionCache.size()
1053 << std::endl;
1054#endif
1056
1057// NOTE: the commented code would send an empty response
1058// myOutputStorage.writeInt(0);
1059// myCurrentSocket->second->socket->sendExact(myOutputStorage);
1060// myOutputStorage.reset();
1062 // send results to active client
1063 myCurrentSocket->second->socket->sendExact(myOutputStorage);
1065}
1066
1067
1068void
1069TraCIServer::writeStatusCmd(int commandId, int status, const std::string& description) {
1070 writeStatusCmd(commandId, status, description, myOutputStorage);
1071}
1072
1073
1074void
1075TraCIServer::writeStatusCmd(int commandId, int status, const std::string& description, tcpip::Storage& outputStorage) {
1076 if (status == libsumo::RTYPE_ERR) {
1077 WRITE_ERROR("Answered with error to command " + toHex(commandId, 2) + ": " + description);
1078 } else if (status == libsumo::RTYPE_NOTIMPLEMENTED) {
1079 WRITE_ERROR("Requested command not implemented (" + toHex(commandId, 2) + "): " + description);
1080 }
1081 outputStorage.writeUnsignedByte(1 + 1 + 1 + 4 + static_cast<int>(description.length())); // command length
1082 outputStorage.writeUnsignedByte(commandId); // command type
1083 outputStorage.writeUnsignedByte(status); // status
1084 outputStorage.writeString(description); // description
1085}
1086
1087
1088bool
1089TraCIServer::writeErrorStatusCmd(int commandId, const std::string& description, tcpip::Storage& outputStorage) {
1090 writeStatusCmd(commandId, libsumo::RTYPE_ERR, description, outputStorage);
1091 return false;
1092}
1093
1094
1095void
1097 tcpip::Storage writeInto;
1098 std::string errors;
1099 libsumo::Subscription* modifiedSubscription = nullptr;
1100 if (processSingleSubscription(s, writeInto, errors)) {
1102 writeStatusCmd(s.commandId, libsumo::RTYPE_ERR, "Subscription has ended.");
1103 } else {
1104 if (libsumo::Helper::needNewSubscription(s, mySubscriptions, modifiedSubscription)) {
1105 // Add new subscription to subscription cache (note: seems a bit inefficient)
1107 // copy new subscription into cache
1108 int noActive = 1 + (mySubscriptionCache.size() > 0 ? mySubscriptionCache.readInt() : 0);
1109 tcpip::Storage tmp;
1110 tmp.writeInt(noActive);
1111 while (mySubscriptionCache.valid_pos()) {
1113 }
1114 tmp.writeStorage(writeInto);
1117 }
1118 }
1120 }
1121 if (modifiedSubscription != nullptr && (
1122 modifiedSubscription->isVehicleToVehicleContextSubscription()
1123 || modifiedSubscription->isVehicleToPersonContextSubscription())) {
1124 // Set last modified vehicle context subscription active for filter modifications
1125 myLastContextSubscription = modifiedSubscription;
1126 } else {
1127 // adding other subscriptions deactivates the activation for filter addition
1128 myLastContextSubscription = nullptr;
1129 }
1130 } else {
1131 writeStatusCmd(s.commandId, libsumo::RTYPE_ERR, "Could not add subscription. " + errors);
1132 }
1133 myOutputStorage.writeStorage(writeInto);
1134}
1135
1136
1137void
1138TraCIServer::removeSubscription(int commandId, const std::string& id, int domain) {
1139 bool found = false;
1140 std::vector<libsumo::Subscription>::iterator j;
1141 for (j = mySubscriptions.begin(); j != mySubscriptions.end();) {
1142 if (j->id == id && j->commandId == commandId && j->contextDomain == domain) {
1143 j = mySubscriptions.erase(j);
1144 if (j != mySubscriptions.end() && myLastContextSubscription == &(*j)) {
1145 // Remove also reference for filter additions
1146 myLastContextSubscription = nullptr;
1147 }
1148 found = true;
1149 continue;
1150 }
1151 ++j;
1152 }
1153 // try unsubscribe
1154 if (found) {
1155 writeStatusCmd(commandId, libsumo::RTYPE_OK, "");
1156 } else {
1157 writeStatusCmd(commandId, libsumo::RTYPE_ERR, "The subscription to remove was not found.");
1158 }
1159}
1160
1161
1162bool
1164 std::string& errors) {
1165 bool ok = true;
1166 tcpip::Storage outputStorage;
1167 const int getCommandId = s.contextDomain > 0 ? s.contextDomain : s.commandId - 0x30;
1168 std::set<std::string> objIDs;
1169 if (s.contextDomain > 0) {
1171 PositionVector shape;
1174 }
1176 } else {
1177 objIDs.insert(s.id);
1178 }
1179 const int numVars = s.contextDomain > 0 && s.variables.size() == 1 && s.variables[0] == libsumo::TRACI_ID_LIST ? 0 : (int)s.variables.size();
1180 int skipped = 0;
1181 for (std::set<std::string>::iterator j = objIDs.begin(); j != objIDs.end(); ++j) {
1182 if (s.contextDomain > 0) {
1183 //if (centralObject(s, *j)) {
1184 // skipped++;
1185 // continue;
1186 //}
1187 outputStorage.writeString(*j);
1188 }
1189 if (numVars > 0) {
1190 std::vector<std::shared_ptr<tcpip::Storage> >::const_iterator k = s.parameters.begin();
1191 for (std::vector<int>::const_iterator i = s.variables.begin(); i != s.variables.end(); ++i, ++k) {
1192 tcpip::Storage message;
1193 message.writeUnsignedByte(*i);
1194 message.writeString(*j);
1195 // TODO check why writeStorage fails here (probably some kind of invalid iterator)
1196 for (const auto& v :** k) {
1197 message.writeChar(v);
1198 }
1199 tcpip::Storage tmpOutput;
1200 if (myExecutors.find(getCommandId) != myExecutors.end()) {
1201 ok &= myExecutors[getCommandId](*this, message, tmpOutput);
1202 } else {
1203 writeStatusCmd(s.commandId, libsumo::RTYPE_NOTIMPLEMENTED, "Unsupported command specified", tmpOutput);
1204 ok = false;
1205 }
1206 // copy response part
1207 if (ok) {
1208 int length = tmpOutput.readUnsignedByte();
1209 while (--length > 0) {
1210 tmpOutput.readUnsignedByte();
1211 }
1212 int lengthLength = 1;
1213 length = tmpOutput.readUnsignedByte();
1214 if (length == 0) {
1215 lengthLength = 5;
1216 length = tmpOutput.readInt();
1217 }
1218 //read responseType
1219 tmpOutput.readUnsignedByte();
1220 int variable = tmpOutput.readUnsignedByte();
1221 std::string id = tmpOutput.readString();
1222 outputStorage.writeUnsignedByte(variable);
1223 outputStorage.writeUnsignedByte(libsumo::RTYPE_OK);
1224 length -= (lengthLength + 1 + 4 + (int)id.length());
1225 while (--length > 0) {
1226 outputStorage.writeUnsignedByte(tmpOutput.readUnsignedByte());
1227 }
1228 } else {
1229 //read length
1230 tmpOutput.readUnsignedByte();
1231 //read cmd
1232 tmpOutput.readUnsignedByte();
1233 //read status
1234 tmpOutput.readUnsignedByte();
1235 std::string msg = tmpOutput.readString();
1236 outputStorage.writeUnsignedByte(*i);
1239 outputStorage.writeString(msg);
1240 errors = errors + msg;
1241 }
1242 }
1243 }
1244 }
1245 int length = (1 + 4) + 1 + (4 + (int)s.id.length()) + 1 + (int)outputStorage.size();
1246 if (s.contextDomain > 0) {
1247 length += 1 + 4; // context domain and number of objects
1248 }
1249 // we always write extended command length here for backward compatibility
1250 writeInto.writeUnsignedByte(0); // command length -> extended
1251 writeInto.writeInt(length);
1252 writeInto.writeUnsignedByte(s.commandId + 0x10);
1253 writeInto.writeString(s.id);
1254 if (s.contextDomain > 0) {
1255 writeInto.writeUnsignedByte(s.contextDomain);
1256 }
1257 writeInto.writeUnsignedByte(numVars);
1258 if (s.contextDomain > 0) {
1259 writeInto.writeInt((int)objIDs.size() - skipped);
1260 }
1261 if (s.contextDomain == 0 || objIDs.size() != 0) {
1262 writeInto.writeStorage(outputStorage);
1263 }
1264 return ok;
1265}
1266
1267
1268bool
1269TraCIServer::addObjectVariableSubscription(const int commandId, const bool hasContext) {
1270 const double beginTime = myInputStorage.readDouble();
1271 const double endTime = myInputStorage.readDouble();
1272 const SUMOTime begin = beginTime == libsumo::INVALID_DOUBLE_VALUE ? 0 : TIME2STEPS(beginTime);
1273 const SUMOTime end = endTime == libsumo::INVALID_DOUBLE_VALUE || endTime > STEPS2TIME(SUMOTime_MAX) ? SUMOTime_MAX : TIME2STEPS(endTime);
1274 const std::string id = myInputStorage.readString();
1275 const int domain = hasContext ? myInputStorage.readUnsignedByte() : 0;
1276 const double range = hasContext ? myInputStorage.readDouble() : 0.;
1277 const int num = myInputStorage.readUnsignedByte();
1278 std::vector<int> variables;
1279 std::vector<std::shared_ptr<tcpip::Storage> > parameters;
1280 for (int i = 0; i < num; ++i) {
1281 const int varID = myInputStorage.readUnsignedByte();
1282 variables.push_back(varID);
1283 parameters.push_back(std::make_shared<tcpip::Storage>());
1284 if ((myParameterized.count(std::make_pair(0, varID)) > 0) || (myParameterized.count(std::make_pair(commandId, varID)) > 0)) {
1285 const int parType = myInputStorage.readUnsignedByte();
1286 parameters.back()->writeUnsignedByte(parType);
1287 if (parType == libsumo::TYPE_DOUBLE) {
1288 parameters.back()->writeDouble(myInputStorage.readDouble());
1289 } else if (parType == libsumo::TYPE_STRING) {
1290 parameters.back()->writeString(myInputStorage.readString());
1291 } else {
1292 // Error!
1293 }
1294 }
1295 }
1296 // check subscribe/unsubscribe
1297 if (variables.empty()) {
1298 removeSubscription(commandId, id, domain);
1299 return true;
1300 }
1301 // process subscription
1302 libsumo::Subscription s(commandId, id, variables, parameters, begin, end, domain, range);
1304 return true;
1305}
1306
1307
1308
1309bool
1311 bool success = true;
1312 // Read filter type
1313 int filterType = myInputStorage.readUnsignedByte();
1314
1315 if (myLastContextSubscription == nullptr) {
1316 writeStatusCmd(filterType, libsumo::RTYPE_ERR, "No previous vehicle context subscription exists to apply filter type " + toHex(filterType, 2));
1317 return false;
1318 }
1319
1320 // dispatch according to filter type
1321 switch (filterType) {
1323 // Remove all filters
1324 removeFilters();
1325 break;
1327 // Read relative lanes to consider for context filter
1328 int nrLanes = (int)myInputStorage.readByte();
1329 std::vector<int> lanes;
1330 for (int i = 0; i < nrLanes; ++i) {
1331 lanes.push_back((int) myInputStorage.readByte());
1332 }
1334 }
1335 break;
1337 // Add no-opposite filter
1339 break;
1341 myInputStorage.readByte(); // read type double
1342 double dist = myInputStorage.readDouble();
1344 }
1345 break;
1347 myInputStorage.readByte(); // read type double
1348 double dist = myInputStorage.readDouble();
1350 }
1351 break;
1353 // Read relative lanes to consider for context filter
1355 }
1356 break;
1358 myInputStorage.readByte(); // read type double
1359 double dist = myInputStorage.readDouble();
1361 }
1362 break;
1364 myInputStorage.readByte(); // read type stringlist
1367 }
1368 break;
1370 myInputStorage.readByte(); // read type stringlist
1371 std::vector<std::string> vTypesVector = myInputStorage.readStringList();
1372 std::set<std::string> vTypesSet;
1373 vTypesSet.insert(vTypesVector.begin(), vTypesVector.end());
1374 addSubscriptionFilterVType(vTypesSet);
1375 }
1376 break;
1378 myInputStorage.readByte(); // read type double
1379 double angle = myInputStorage.readDouble();
1381 }
1382 break;
1384 myInputStorage.readByte(); // read type double
1385 double dist = myInputStorage.readDouble();
1387 }
1388 break;
1389 default:
1390 writeStatusCmd(filterType, libsumo::RTYPE_NOTIMPLEMENTED, "'" + toString(filterType) + "' is no valid filter type code.");
1391 success = false;
1392 }
1393
1394 if (success) {
1395 // acknowledge filter addition
1397 }
1398
1399 return success;
1400}
1401
1402
1403void
1405#ifdef DEBUG_SUBSCRIPTION_FILTERS
1406 std::cout << "Removing filters" << std::endl;
1407#endif
1409}
1410
1411void
1413#ifdef DEBUG_SUBSCRIPTION_FILTERS
1414 std::cout << "Adding lane filter (lanes=" << toString(lanes) << ")" << std::endl;
1415#endif
1418}
1419
1420void
1422#ifdef DEBUG_SUBSCRIPTION_FILTERS
1423 std::cout << "Adding no opposite filter" << std::endl;
1424#endif
1426}
1427
1428void
1430#ifdef DEBUG_SUBSCRIPTION_FILTERS
1431 std::cout << "Adding downstream dist filter (dist=" << toString(dist) << ")" << std::endl;
1432#endif
1435}
1436
1437void
1439#ifdef DEBUG_SUBSCRIPTION_FILTERS
1440 std::cout << "Adding upstream dist filter (dist=" << toString(dist) << ")" << std::endl;
1441#endif
1444}
1445
1446void
1448#ifdef DEBUG_SUBSCRIPTION_FILTERS
1449 std::cout << "Adding Lead/Follow-maneuver filter" << std::endl;
1450#endif
1452}
1453
1454void
1456#ifdef DEBUG_SUBSCRIPTION_FILTERS
1457 std::cout << "Adding turn-maneuver filter" << std::endl;
1458#endif
1461}
1462
1463void
1465#ifdef DEBUG_SUBSCRIPTION_FILTERS
1466 std::cout << "Adding vClass filter (vClasses=" << toString(vClasses) << ")" << std::endl;
1467#endif
1470}
1471
1472void
1473TraCIServer::addSubscriptionFilterVType(std::set<std::string> vTypes) {
1474#ifdef DEBUG_SUBSCRIPTION_FILTERS
1475 std::cout << "Adding vType filter (vTypes=" << toString(vTypes) << ")" << std::endl;
1476#endif
1479}
1480
1481void
1483#ifdef DEBUG_SUBSCRIPTION_FILTERS
1484 std::cout << "Adding FieldOfVision filter (openingAngle=" << toString(openingAngle) << ")" << std::endl;
1485#endif
1488}
1489
1490void
1492#ifdef DEBUG_SUBSCRIPTION_FILTERS
1493 std::cout << "Adding lateral dist filter (dist=" << toString(dist) << ")" << std::endl;
1494#endif
1497}
1498
1499void
1501 if (tempMsg.size() < 254) {
1502 outputStorage.writeUnsignedByte(1 + (int)tempMsg.size()); // command length -> short
1503 } else {
1504 outputStorage.writeUnsignedByte(0); // command length -> extended
1505 outputStorage.writeInt(1 + 4 + (int)tempMsg.size());
1506 }
1507 outputStorage.writeStorage(tempMsg);
1508}
1509
1510
1511void
1514 if (shape.value.size() < 256) {
1515 outputStorage.writeUnsignedByte((int)shape.value.size());
1516 } else {
1517 outputStorage.writeUnsignedByte(0);
1518 outputStorage.writeInt((int)shape.value.size());
1519 }
1520 for (const libsumo::TraCIPosition& pos : shape.value) {
1521 outputStorage.writeDouble(pos.x);
1522 outputStorage.writeDouble(pos.y);
1523 }
1524}
1525
1526
1527bool
1529 if (inputStorage.readUnsignedByte() != libsumo::TYPE_INTEGER) {
1530 return false;
1531 }
1532 into = inputStorage.readInt();
1533 return true;
1534}
1535
1536
1537bool
1539 if (inputStorage.readUnsignedByte() != libsumo::TYPE_DOUBLE) {
1540 return false;
1541 }
1542 into = inputStorage.readDouble();
1543 return true;
1544}
1545
1546
1547bool
1548TraCIServer::readTypeCheckingString(tcpip::Storage& inputStorage, std::string& into) {
1549 if (inputStorage.readUnsignedByte() != libsumo::TYPE_STRING) {
1550 return false;
1551 }
1552 into = inputStorage.readString();
1553 return true;
1554}
1555
1556
1557bool
1558TraCIServer::readTypeCheckingStringList(tcpip::Storage& inputStorage, std::vector<std::string>& into) {
1559 if (inputStorage.readUnsignedByte() != libsumo::TYPE_STRINGLIST) {
1560 return false;
1561 }
1562 into = inputStorage.readStringList();
1563 return true;
1564}
1565
1566
1567bool
1568TraCIServer::readTypeCheckingDoubleList(tcpip::Storage& inputStorage, std::vector<double>& into) {
1569 if (inputStorage.readUnsignedByte() != libsumo::TYPE_DOUBLELIST) {
1570 return false;
1571 }
1572 into = inputStorage.readDoubleList();
1573 return true;
1574}
1575
1576
1577bool
1579 if (inputStorage.readUnsignedByte() != libsumo::TYPE_COLOR) {
1580 return false;
1581 }
1582 into.r = static_cast<unsigned char>(inputStorage.readUnsignedByte());
1583 into.g = static_cast<unsigned char>(inputStorage.readUnsignedByte());
1584 into.b = static_cast<unsigned char>(inputStorage.readUnsignedByte());
1585 into.a = static_cast<unsigned char>(inputStorage.readUnsignedByte());
1586 return true;
1587}
1588
1589
1590bool
1592 if (inputStorage.readUnsignedByte() != libsumo::POSITION_2D) {
1593 return false;
1594 }
1595 into.x = inputStorage.readDouble();
1596 into.y = inputStorage.readDouble();
1597 into.z = 0;
1598 return true;
1599}
1600
1601
1602bool
1604 if (inputStorage.readByte() != libsumo::TYPE_BYTE) {
1605 return false;
1606 }
1607 into = inputStorage.readByte();
1608 return true;
1609}
1610
1611
1612bool
1614 if (inputStorage.readUnsignedByte() != libsumo::TYPE_UBYTE) {
1615 return false;
1616 }
1617 into = inputStorage.readUnsignedByte();
1618 return true;
1619}
1620
1621
1622bool
1624 if (inputStorage.readUnsignedByte() != libsumo::TYPE_POLYGON) {
1625 return false;
1626 }
1627 into.clear();
1628 int size = inputStorage.readUnsignedByte();
1629 if (size == 0) {
1630 size = inputStorage.readInt();
1631 }
1632 PositionVector shape;
1633 for (int i = 0; i < size; ++i) {
1634 double x = inputStorage.readDouble();
1635 double y = inputStorage.readDouble();
1636 if (std::isnan(x) || std::isnan(y)) {
1637 throw libsumo::TraCIException("NaN-Value in shape.");
1638 }
1639 into.push_back(Position(x, y));
1640 }
1641 return true;
1642}
1643
1644
1645void
1647 myTargetTime = targetTime;
1648 for (auto& s : mySockets) {
1649 s.second->targetTime = targetTime;
1650 for (auto& stateChange : s.second->vehicleStateChanges) {
1651 stateChange.second.clear();
1652 }
1653 for (auto& stateChange : s.second->transportableStateChanges) {
1654 stateChange.second.clear();
1655 }
1656 }
1657 mySubscriptions.clear();
1659}
1660
1661
1662bool
1663TraCIServer::centralObject(const libsumo::Subscription& s, const std::string& objID) {
1664 return (s.id == objID && s.commandId + 32 == s.contextDomain);
1665}
1666
1667
1668/****************************************************************************/
long long int SUMOTime
Definition: GUI.h:36
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:267
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:274
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:265
#define TL(string)
Definition: MsgHandler.h:282
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:54
#define SUMOTime_MAX
Definition: SUMOTime.h:33
#define SIMTIME
Definition: SUMOTime.h:61
#define TIME2STEPS(x)
Definition: SUMOTime.h:56
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:71
std::string toHex(const T i, std::streamsize numDigits=0)
Definition: ToString.h:56
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
static bool gUseMesoSim
Definition: MSGlobals.h:103
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:78
VehicleState
Definition of a vehicle state.
Definition: MSNet.h:603
@ ENDING_PARKING
The vehicle ends to park.
@ STARTING_STOP
The vehicles starts to stop.
@ BUILT
The vehicle was built, but has not yet departed.
@ STARTING_PARKING
The vehicles starts to park.
@ NEWROUTE
The vehicle got a new route.
@ STARTING_TELEPORT
The vehicle started to teleport.
@ ENDING_STOP
The vehicle ends to stop.
@ ENDING_TELEPORT
The vehicle ended being teleported.
@ ARRIVED
The vehicle arrived at his destination (is deleted)
@ DEPARTED
The vehicle has departed (was inserted into the network)
@ COLLISION
The vehicle is involved in a collision.
@ EMERGENCYSTOP
The vehicle had to brake harder than permitted.
@ MANEUVERING
Vehicle maneuvering either entering or exiting a parking space.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:183
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:321
void addVehicleStateListener(VehicleStateListener *listener)
Adds a vehicle states listener.
Definition: MSNet.cpp:1164
void addTransportableStateListener(TransportableStateListener *listener)
Adds a transportable states listener.
Definition: MSNet.cpp:1192
TransportableState
Definition of a transportable state.
Definition: MSNet.h:680
@ CONTAINER_DEPARTED
The transportable container has departed (was inserted into the network)
@ PERSON_DEPARTED
The transportable person has departed (was inserted into the network)
@ PERSON_ARRIVED
The transportable person arrived at his destination (is deleted)
@ CONTAINER_ARRIVED
The transportable container arrived at his destination (is deleted)
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:1096
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:116
static MsgHandler * getWarningInstance()
Returns the instance to add warnings to.
Definition: MsgHandler.cpp:66
const std::string & getID() const
Returns the id.
Definition: Named.h:74
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:59
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
A list of positions.
Representation of a vehicle.
Definition: SUMOVehicle.h:60
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 processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc0: Set Induction Loop Variable)
static bool processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc9: Set Junction 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 processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xcd: Set 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 processSet(TraCIServer &server, tcpip::Storage &inputStorage, tcpip::Storage &outputStorage)
Processes a set value command (Command 0xc1: Set MeMeDetector 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:359
bool wrapStringDoublePair(const std::string &objID, const int variable, const std::pair< std::string, double > &value)
tcpip::Storage myWrapperStorage
A temporary storage to let the wrapper write to.
Definition: TraCIServer.h:381
std::map< int, SocketInfo * > mySockets
The socket connections to the clients the first component (index) determines the client's order (lowe...
Definition: TraCIServer.h:363
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
void addSubscriptionFilterTurn(double dist)
bool centralObject(const libsumo::Subscription &s, const std::string &objID)
check whether a found objID refers to the central object of a context subscription
bool wrapPositionVector(const std::string &objID, const int variable, const libsumo::TraCIPositionVector &value)
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:378
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
std::map< MSNet::TransportableState, std::vector< std::string > > myTransportableStateChanges
Changes in the states of simulated transportables.
Definition: TraCIServer.h:416
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:384
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.
bool wrapDoubleList(const std::string &objID, const int variable, const std::vector< double > &value)
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:392
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:372
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)
bool wrapStringPair(const std::string &objID, const int variable, const std::pair< std::string, std::string > &value)
std::map< MSNet::VehicleState, std::vector< std::string > > myVehicleStateChanges
Changes in the states of simulated vehicles.
Definition: TraCIServer.h:407
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:387
std::vector< libsumo::Subscription > mySubscriptions
The list of known, still valid subscriptions.
Definition: TraCIServer.h:395
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:375
libsumo::Subscription * myLastContextSubscription
The last modified context subscription (the one to add a filter to, see @addSubscriptionFilter(),...
Definition: TraCIServer.h:398
std::map< int, SocketInfo * >::iterator myCurrentSocket
The currently active client socket.
Definition: TraCIServer.h:369
void addSubscriptionFilterVClass(SVCPermissions vClasses)
static TraCIServer * myInstance
Singleton instance of the server.
Definition: TraCIServer.h:356
std::map< int, SocketInfo * > mySocketReorderRequests
This stores the setOrder(int) requests of the clients.
Definition: TraCIServer.h:366
bool addSubscriptionFilter()
std::set< std::pair< int, int > > myParameterized
Set of variables which have parameters.
Definition: TraCIServer.h:390
void transportableStateChanged(const MSTransportable *const transportable, MSNet::TransportableState to, const std::string &info="")
Called if a transportable changes its state.
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:731
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:881
static void collectObjectIDsInRange(int domain, const PositionVector &shape, double range, std::set< std::string > &into)
Definition: Helper.cpp:801
static bool needNewSubscription(libsumo::Subscription &s, std::vector< Subscription > &subscriptions, libsumo::Subscription *&modifiedSubscription)
Definition: Helper.cpp:175
Representation of a subscription.
Definition: Subscription.h:69
double filterUpstreamDist
Upstream distance specified by the upstream distance filter.
Definition: Subscription.h:136
int commandId
commandIdArg The command id of the subscription
Definition: Subscription.h:113
std::set< std::string > filterVTypes
vTypes specified by the vTypes filter
Definition: Subscription.h:140
double filterFieldOfVisionOpeningAngle
Opening angle (in deg) specified by the field of vision filter.
Definition: Subscription.h:144
std::vector< int > filterLanes
lanes specified by the lanes filter
Definition: Subscription.h:132
std::string id
The id of the object that is subscribed.
Definition: Subscription.h:115
int filterVClasses
vClasses specified by the vClasses filter,
Definition: Subscription.h:142
SUMOTime endTime
The end time of the subscription.
Definition: Subscription.h:123
int contextDomain
The domain ID of the context.
Definition: Subscription.h:125
double filterFoeDistToJunction
Foe distance to junction specified by the turn filter.
Definition: Subscription.h:138
bool isVehicleToVehicleContextSubscription() const
Definition: Subscription.h:104
SUMOTime beginTime
The begin time of the subscription.
Definition: Subscription.h:121
std::vector< int > variables
The subscribed variables.
Definition: Subscription.h:117
bool isVehicleToPersonContextSubscription() const
Definition: Subscription.h:108
double filterDownstreamDist
Downstream distance specified by the downstream distance filter.
Definition: Subscription.h:134
double filterLateralDist
Lateral distance specified by the lateral distance filter.
Definition: Subscription.h:146
int activeFilters
Active filters for the subscription (bitset,.
Definition: Subscription.h:130
double range
The range of the context.
Definition: Subscription.h:127
std::vector< std::shared_ptr< tcpip::Storage > > parameters
The parameters for the subscribed variables.
Definition: Subscription.h:119
An error which allows to continue.
Definition: TraCIDefs.h:138
Socket * accept(const bool create=false)
Wait for a incoming connection to port_.
Definition: socket.cpp:269
StorageType::const_iterator begin() const
Definition: storage.h:121
virtual unsigned char readChar()
Definition: storage.cpp:102
virtual std::string readString()
Definition: storage.cpp:180
virtual void writeString(const std::string &s)
Definition: storage.cpp:197
virtual unsigned int position() const
Definition: storage.cpp:76
virtual void writeInt(int)
Definition: storage.cpp:321
StorageType::const_iterator end() const
Definition: storage.h:122
virtual void writeDouble(double)
Definition: storage.cpp:354
virtual int readUnsignedByte()
Definition: storage.cpp:155
virtual void writeStringList(const std::vector< std::string > &s)
Definition: storage.cpp:247
virtual void writeChar(unsigned char)
Definition: storage.cpp:116
void reset()
Definition: storage.cpp:85
virtual void writeUnsignedByte(int)
Definition: storage.cpp:165
StorageType::size_type size() const
Definition: storage.h:119
virtual bool valid_pos()
Definition: storage.cpp:69
virtual void writeDoubleList(const std::vector< double > &s)
Definition: storage.cpp:262
virtual void writeByte(int)
Definition: storage.cpp:140
virtual void writeStorage(tcpip::Storage &store)
Definition: storage.cpp:388
virtual int readByte()
Definition: storage.cpp:128
virtual std::vector< std::string > readStringList()
Definition: storage.cpp:211
virtual double readDouble()
Definition: storage.cpp:362
virtual int readInt()
Definition: storage.cpp:311
virtual std::vector< double > readDoubleList()
Definition: storage.cpp:229
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 CMD_SET_JUNCTION_VARIABLE
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 CMD_SUBSCRIBE_BUSSTOP_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_PARKINGAREA_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 TYPE_COMPOUND
TRACI_CONST int CMD_SUBSCRIBE_ROUTEPROBE_VARIABLE
TRACI_CONST int CMD_SET_REROUTER_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_MEANDATA_CONTEXT
TRACI_CONST int CMD_GET_PERSON_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_REROUTER_CONTEXT
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_SUBSCRIBE_OVERHEADWIRE_VARIABLE
TRACI_CONST int CMD_SET_POLYGON_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_BUSSTOP_CONTEXT
TRACI_CONST int POSITION_2D
TRACI_CONST int CMD_GET_BUSSTOP_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_ROUTEPROBE_CONTEXT
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_SUBSCRIBE_OVERHEADWIRE_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_CALIBRATOR_CONTEXT
TRACI_CONST int VAR_PARAMETER
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_SET_MULTIENTRYEXIT_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_CHARGINGSTATION_CONTEXT
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 CMD_SET_LANEAREA_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 CMD_SUBSCRIBE_PARKINGAREA_CONTEXT
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_REROUTER_VARIABLE
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:48
@ SUBS_FILTER_UPSTREAM_DIST
Definition: Subscription.h:46
@ SUBS_FILTER_VTYPE
Definition: Subscription.h:54
@ SUBS_FILTER_NO_RTREE
Definition: Subscription.h:61
@ SUBS_FILTER_LANES
Definition: Subscription.h:40
@ SUBS_FILTER_NOOPPOSITE
Definition: Subscription.h:42
@ SUBS_FILTER_DOWNSTREAM_DIST
Definition: Subscription.h:44
@ SUBS_FILTER_LATERAL_DIST
Definition: Subscription.h:59
@ SUBS_FILTER_TURN
Definition: Subscription.h:50
@ SUBS_FILTER_VCLASS
Definition: Subscription.h:52
@ SUBS_FILTER_NONE
Definition: Subscription.h:38
@ SUBS_FILTER_FIELD_OF_VISION
Definition: Subscription.h:57
TRACI_CONST int CMD_SUBSCRIBE_LANEAREA_VARIABLE
TRACI_CONST int TYPE_BYTE
TRACI_CONST int CMD_SUBSCRIBE_POI_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_CALIBRATOR_VARIABLE
TRACI_CONST int CMD_SET_INDUCTIONLOOP_VARIABLE
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_SUBSCRIBE_CHARGINGSTATION_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 VAR_FOLLOWER
TRACI_CONST int CMD_SUBSCRIBE_LANEAREA_CONTEXT
TRACI_CONST int CMD_SUBSCRIBE_VARIABLESPEEDSIGN_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 CMD_SUBSCRIBE_MEANDATA_VARIABLE
TRACI_CONST int FILTER_TYPE_LATERAL_DIST
TRACI_CONST int CMD_SUBSCRIBE_EDGE_VARIABLE
TRACI_CONST int TYPE_STRING
TRACI_CONST int CMD_SUBSCRIBE_VARIABLESPEEDSIGN_VARIABLE
A 3D-position.
Definition: TraCIDefs.h:172
A list of positions.
Definition: TraCIDefs.h:215
std::vector< TraCIPosition > value
Definition: TraCIDefs.h:225