44Connection::Connection(
const std::string& host,
int port,
int numRetries,
const std::string& label, FILE*
const pipe) :
45 myLabel(label), myProcessPipe(pipe), myProcessReader(nullptr), mySocket(host, port) {
46 if (pipe !=
nullptr) {
49 for (
int i = 0; i <= numRetries; i++) {
55 if (i == numRetries) {
59 std::cout <<
"Could not connect to TraCI server at " << host <<
":" << port <<
" " << e.what() << std::endl;
60 std::cout <<
" Retrying in 1 second" << std::endl;
61 std::this_thread::sleep_for(std::chrono::seconds(1));
69 std::array<char, 256> buffer;
71 while (fgets(buffer.data(), (
int)buffer.size(),
myProcessPipe) !=
nullptr) {
72 std::stringstream result;
73 result << buffer.data();
75 while (std::getline(result, line)) {
76 if ((errout && (line.empty() || line[0] ==
' ')) || line.compare(0, 6,
"Error:") == 0 || line.compare(0, 8,
"Warning:") == 0) {
77 std::cerr << line << std::endl;
80 std::cout << line << std::endl;
91 std::unique_lock<std::mutex> lock{
myMutex };
100 std::string acknowledgement;
122 std::unique_lock<std::mutex> lock{
myMutex};
137 while (numSubs-- > 0) {
151 std::unique_lock<std::mutex> lock{
myMutex };
176 if (objID !=
nullptr) {
177 length += 4 + (int)objID->length();
180 if (add !=
nullptr) {
181 length += (int)add->
size();
192 if (objID !=
nullptr) {
197 if (add !=
nullptr) {
209 const bool isContext = domain != -1;
219 if (vars.size() == 1 && vars.front() == -1) {
237 for (
const int v : vars) {
239 const auto& paramEntry = params.find(v);
240 if (paramEntry != params.end()) {
249 std::unique_lock<std::mutex> lock{
myMutex };
280 }
catch (std::invalid_argument&) {
283 switch (resultType) {
289 if (acknowledgement !=
nullptr) {
290 (*acknowledgement) =
".. Command acknowledged (" +
toHex(command) +
"), [description: " + msg +
"]";
296 if (command != cmdId && !ignoreCommandId) {
299 if ((cmdStart + cmdLength) != (
int) inMsg.
position()) {
312 if (!ignoreCommandId && cmdId != (command + 0x10)) {
315 if (expectedType >= 0) {
320 if (valueDataType != expectedType) {
334 if (expectedType >= 0) {
343 std::unique_lock<std::mutex> lock{
myMutex };
353 while (variableCount > 0) {
362 into[objectID][variableID] = std::make_shared<libsumo::TraCIDouble>(inMsg.
readDouble());
365 into[objectID][variableID] = std::make_shared<libsumo::TraCIString>(inMsg.
readString());
368 auto p = std::make_shared<libsumo::TraCIPosition>();
371 into[objectID][variableID] = p;
375 auto p = std::make_shared<libsumo::TraCIPosition>();
379 into[objectID][variableID] = p;
383 auto c = std::make_shared<libsumo::TraCIColor>();
388 into[objectID][variableID] = c;
392 into[objectID][variableID] = std::make_shared<libsumo::TraCIInt>(inMsg.
readInt());
395 auto sl = std::make_shared<libsumo::TraCIStringList>();
397 for (
int i = 0; i < n; ++i) {
400 into[objectID][variableID] = sl;
410 auto r = std::make_shared<libsumo::TraCIRoadPosition>();
413 into[objectID][variableID] = r;
415 auto sl = std::make_shared<libsumo::TraCIStringList>();
416 sl->value.push_back(s);
418 into[objectID][variableID] = sl;
440 const std::string objectID = inMsg.
readString();
448 const std::string contextID = inMsg.
readString();
451 int numObjects = inMsg.
readInt();
455 while (numObjects-- > 0) {
456 const std::string& objectID = inMsg.
readString();
An error which is not recoverable.
static std::shared_ptr< tcpip::Storage > toStorage(const TraCIResult &v)
An error which allows to continue.
void simulationStep(double time)
Sends a SimulationStep command.
Connection(const std::string &host, int port, int numRetries, const std::string &label, FILE *const pipe)
Constructor, connects to the specified SUMO server.
void close()
ends the simulation and closes the connection
void createCommand(int cmdID, int varID, const std::string *const objID, tcpip::Storage *add=nullptr) const
Sends a GetVariable / SetVariable request if mySocket is connected. Otherwise writes to myOutput only...
int check_commandGetResult(tcpip::Storage &inMsg, int command, int expectedType=-1, bool ignoreCommandId=false) const
Validates the result state of a command.
void addFilter(int var, tcpip::Storage *add=nullptr)
void readVariableSubscription(int responseID, tcpip::Storage &inMsg)
tcpip::Socket mySocket
The socket.
std::map< int, libsumo::SubscriptionResults > mySubscriptionResults
void check_resultState(tcpip::Storage &inMsg, int command, bool ignoreCommandId=false, std::string *acknowledgement=0)
Validates the result state of a command.
tcpip::Storage myInput
The reusable input storage.
FILE *const myProcessPipe
void readVariables(tcpip::Storage &inMsg, const std::string &objectID, int variableCount, libsumo::SubscriptionResults &into)
std::map< int, libsumo::ContextSubscriptionResults > myContextSubscriptionResults
tcpip::Storage myOutput
The reusable output storage.
void setOrder(int order)
Sends a SetOrder command.
void subscribe(int domID, const std::string &objID, double beginTime, double endTime, int domain, double range, const std::vector< int > &vars, const libsumo::TraCIResults ¶ms)
Sends a SubscribeContext or a SubscribeVariable request.
static std::map< const std::string, Connection * > myConnections
const std::string myLabel
void readContextSubscription(int responseID, tcpip::Storage &inMsg)
tcpip::Storage & doCommand(int command, int var=-1, const std::string &id="", tcpip::Storage *add=nullptr, int expectedType=-1)
static Connection * myActive
static std::string toString(const T &t, std::streamsize accuracy=PRECISION)
std::thread * myProcessReader
std::string toHex(const T i, std::streamsize numDigits=2)
bool receiveExact(Storage &)
Receive a complete TraCI message from Socket::socket_.
void sendExact(const Storage &)
bool has_client_connection() const
void connect()
Connects to host_:port_.
virtual std::string readString()
virtual void writeString(const std::string &s)
virtual unsigned int position() const
virtual void writeInt(int)
virtual void writeDouble(double)
virtual int readUnsignedByte()
virtual void writeUnsignedByte(int)
StorageType::size_type size() const
virtual void writeStorage(tcpip::Storage &store)
virtual double readDouble()
TRACI_CONST int TYPE_COLOR
TRACI_CONST int LAST_STEP_VEHICLE_NUMBER
TRACI_CONST int POSITION_3D
TRACI_CONST int RTYPE_NOTIMPLEMENTED
TRACI_CONST int TRACI_ID_LIST
TRACI_CONST int VAR_ROAD_ID
TRACI_CONST int TYPE_COMPOUND
TRACI_CONST int RESPONSE_SUBSCRIBE_PARKINGAREA_VARIABLE
TRACI_CONST int RESPONSE_SUBSCRIBE_INDUCTIONLOOP_VARIABLE
TRACI_CONST int POSITION_2D
TRACI_CONST int RESPONSE_SUBSCRIBE_OVERHEADWIRE_VARIABLE
TRACI_CONST int CMD_CLOSE
TRACI_CONST int CMD_SETORDER
TRACI_CONST int TYPE_STRINGLIST
TRACI_CONST int TYPE_INTEGER
TRACI_CONST int RESPONSE_SUBSCRIBE_BUSSTOP_VARIABLE
TRACI_CONST int CMD_ADD_SUBSCRIPTION_FILTER
std::map< std::string, libsumo::TraCIResults > SubscriptionResults
{object->{variable->value}}
TRACI_CONST int VAR_LANEPOSITION
TRACI_CONST int CMD_SUBSCRIBE_VEHICLE_VARIABLE
TRACI_CONST int TYPE_DOUBLE
TRACI_CONST int CMD_SUBSCRIBE_LANEAREA_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_INDUCTIONLOOP_VARIABLE
TRACI_CONST int CMD_SUBSCRIBE_MULTIENTRYEXIT_VARIABLE
TRACI_CONST int RTYPE_ERR
TRACI_CONST int CMD_SIMSTEP
TRACI_CONST int CMD_SUBSCRIBE_LANE_VARIABLE
std::map< int, std::shared_ptr< libsumo::TraCIResult > > TraCIResults
{variable->value}
TRACI_CONST int CMD_SUBSCRIBE_EDGE_VARIABLE
TRACI_CONST int TYPE_STRING