LCOV - code coverage report
Current view: top level - src/traci_testclient - TraCITestClient.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 677 725 93.4 %
Date: 2024-05-08 15:29:52 Functions: 17 17 100.0 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2008-2024 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             : /****************************************************************************/
      14             : /// @file    TraCITestClient.cpp
      15             : /// @author  Friedemann Wesner
      16             : /// @author  Daniel Krajzewicz
      17             : /// @author  Laura Bieker
      18             : /// @author  Axel Wegener
      19             : /// @author  Michael Behrisch
      20             : /// @author  Jakob Erdmann
      21             : /// @date    2008/04/07
      22             : ///
      23             : // A test execution class
      24             : /****************************************************************************/
      25             : /* =========================================================================
      26             :  * included modules
      27             :  * ======================================================================= */
      28             : #ifdef _MSC_VER
      29             : #define _CRT_SECURE_NO_WARNINGS
      30             : // Avoid some noisy warnings with Visual Studio
      31             : #pragma warning(disable:4820 4514 5045 4710)
      32             : #endif
      33             : #include <vector>
      34             : #include <iostream>
      35             : #include <iomanip>
      36             : #include <fstream>
      37             : #include <sstream>
      38             : #include <ctime>
      39             : #include <cstdlib>
      40             : 
      41             : #define BUILD_TCPIP
      42             : #include <foreign/tcpip/storage.h>
      43             : #include <foreign/tcpip/socket.h>
      44             : 
      45             : #include <libsumo/TraCIConstants.h>
      46             : #include <libsumo/TraCIDefs.h>
      47             : #include "TraCITestClient.h"
      48             : 
      49             : 
      50             : // ===========================================================================
      51             : // method definitions
      52             : // ===========================================================================
      53        1184 : TraCITestClient::TraCITestClient(std::string outputFileName)
      54        3552 :     : outputFileName(outputFileName), answerLog("") {
      55             :     answerLog.setf(std::ios::fixed, std::ios::floatfield);  // use decimal format
      56             :     answerLog.setf(std::ios::showpoint); // print decimal point
      57        1184 :     answerLog << std::setprecision(2);
      58        1184 : }
      59             : 
      60             : 
      61        1184 : TraCITestClient::~TraCITestClient() {
      62        1184 :     writeResult();
      63        2368 : }
      64             : 
      65             : 
      66             : int
      67        1184 : TraCITestClient::run(std::string fileName, int port, std::string host) {
      68        1184 :     std::ifstream defFile;
      69             :     std::string fileContentStr;
      70        1184 :     std::stringstream fileContent;
      71             :     std::string lineCommand;
      72        1184 :     std::stringstream msg;
      73        1184 :     int repNo = 1;
      74             :     bool commentRead = false;
      75             : 
      76             :     // try to connect
      77             :     try {
      78        1184 :         TraCIAPI::connect(host, port);
      79         592 :     } catch (tcpip::SocketException& e) {
      80         592 :         msg << "#Error while connecting: " << e.what();
      81         592 :         errorMsg(msg);
      82             :         return 2;
      83         592 :     }
      84             : 
      85             :     // read definition file and trigger commands according to it
      86         592 :     defFile.open(fileName.c_str());
      87         592 :     if (!defFile) {
      88             :         msg << "Can not open definition file " << fileName << std::endl;
      89           0 :         errorMsg(msg);
      90             :         return 1;
      91             :     }
      92             :     defFile.unsetf(std::ios::dec);
      93             : 
      94        4219 :     while (defFile >> lineCommand) {
      95        3628 :         repNo = 1;
      96        3628 :         if (lineCommand.compare("%") == 0) {
      97             :             // a comment was read
      98          38 :             commentRead = !commentRead;
      99          38 :             continue;
     100             :         }
     101        3590 :         if (commentRead) {
     102             :             // wait until end of comment is reached
     103         440 :             continue;
     104             :         }
     105        3150 :         if (lineCommand.compare("repeat") == 0) {
     106         186 :             defFile >> repNo;
     107         186 :             defFile >> lineCommand;
     108             :         }
     109        3150 :         if (lineCommand.compare("simstep2") == 0) {
     110             :             // read parameter for command simulation step and trigger command
     111             :             double time;
     112             :             defFile >> time;
     113        6552 :             for (int i = 0; i < repNo; i++) {
     114        5010 :                 commandSimulationStep(time);
     115             :             }
     116        1607 :         } else if (lineCommand.compare("getvariable") == 0) {
     117             :             // trigger command GetXXXVariable
     118             :             int domID, varID;
     119             :             std::string objID;
     120        1233 :             defFile >> domID >> varID >> objID;
     121        1233 :             commandGetVariable(domID, varID, objID);
     122         374 :         } else if (lineCommand.compare("getvariable_plus") == 0) {
     123             :             // trigger command GetXXXVariable with one parameter
     124             :             int domID, varID;
     125             :             std::string objID;
     126          82 :             defFile >> domID >> varID >> objID;
     127          82 :             tcpip::Storage tmp;
     128          82 :             setValueTypeDependant(tmp, defFile, msg);
     129             :             std::string msgS = msg.str();
     130          82 :             if (msgS != "") {
     131           0 :                 errorMsg(msg);
     132             :             }
     133          82 :             commandGetVariable(domID, varID, objID, &tmp);
     134         374 :         } else if (lineCommand.compare("subscribevariable") == 0) {
     135             :             // trigger command SubscribeXXXVariable
     136             :             int domID, varNo;
     137             :             double beginTime, endTime;
     138             :             std::string objID;
     139          22 :             defFile >> domID >> objID >> beginTime >> endTime >> varNo;
     140          11 :             commandSubscribeObjectVariable(domID, objID, beginTime, endTime, varNo, defFile);
     141         281 :         }  else if (lineCommand.compare("subscribecontext") == 0) {
     142             :             // trigger command SubscribeXXXVariable
     143             :             int domID, varNo, domain;
     144             :             double range;
     145             :             double beginTime, endTime;
     146             :             std::string objID;
     147           9 :             defFile >> domID >> objID >> beginTime >> endTime >> domain >> range >> varNo;
     148           3 :             commandSubscribeContextVariable(domID, objID, beginTime, endTime, domain, range, varNo, defFile);
     149         278 :         }  else if (lineCommand.compare("setvalue") == 0) {
     150             :             // trigger command SetXXXValue
     151             :             int domID, varID;
     152             :             std::string objID;
     153         276 :             defFile >> domID >> varID >> objID;
     154         276 :             commandSetValue(domID, varID, objID, defFile);
     155           2 :         } else if (lineCommand.compare("testAPI") == 0) {
     156             :             // call all native API methods
     157           1 :             testAPI();
     158           1 :         } else if (lineCommand.compare("setorder") == 0) {
     159             :             // call setOrder
     160             :             int order;
     161           1 :             defFile >> order;
     162           1 :             commandSetOrder(order);
     163             :         } else {
     164           0 :             msg << "Error in definition file: " << lineCommand << " is not a valid command";
     165           0 :             errorMsg(msg);
     166           0 :             commandClose();
     167           0 :             closeSocket();
     168             :             return 1;
     169             :         }
     170             :     }
     171         591 :     defFile.close();
     172         591 :     commandClose();
     173         591 :     closeSocket();
     174             :     return 0;
     175        3552 : }
     176             : 
     177             : 
     178             : // ---------- Commands handling
     179             : void
     180        5010 : TraCITestClient::commandSimulationStep(double time) {
     181             :     try {
     182        5010 :         send_commandSimulationStep(time);
     183        5010 :         answerLog << std::endl << "-> Command sent: <SimulationStep>:" << std::endl;
     184        5010 :         tcpip::Storage inMsg;
     185             :         std::string acknowledgement;
     186        5010 :         check_resultState(inMsg, libsumo::CMD_SIMSTEP, false, &acknowledgement);
     187             :         answerLog << acknowledgement << std::endl;
     188        5009 :         validateSimulationStep2(inMsg);
     189        5011 :     } catch (libsumo::TraCIException& e) {
     190           0 :         answerLog << e.what() << std::endl;
     191           0 :     }
     192        5009 : }
     193             : 
     194             : 
     195             : void
     196         591 : TraCITestClient::commandClose() {
     197             :     try {
     198         591 :         send_commandClose();
     199         591 :         answerLog << std::endl << "-> Command sent: <Close>:" << std::endl;
     200         591 :         tcpip::Storage inMsg;
     201             :         std::string acknowledgement;
     202         591 :         check_resultState(inMsg, libsumo::CMD_CLOSE, false, &acknowledgement);
     203             :         answerLog << acknowledgement << std::endl;
     204         591 :     } catch (libsumo::TraCIException& e) {
     205           0 :         answerLog << e.what() << std::endl;
     206           0 :     }
     207         591 : }
     208             : 
     209             : 
     210             : void
     211           1 : TraCITestClient::commandSetOrder(int order) {
     212             :     try {
     213           1 :         send_commandSetOrder(order);
     214           1 :         answerLog << std::endl << "-> Command sent: <SetOrder>:" << std::endl;
     215           1 :         tcpip::Storage inMsg;
     216             :         std::string acknowledgement;
     217           1 :         check_resultState(inMsg, libsumo::CMD_SETORDER, false, &acknowledgement);
     218             :         answerLog << acknowledgement << std::endl;
     219           1 :     } catch (libsumo::TraCIException& e) {
     220           0 :         answerLog << e.what() << std::endl;
     221           0 :     }
     222           1 : }
     223             : 
     224             : 
     225             : void
     226        1315 : TraCITestClient::commandGetVariable(int domID, int varID, const std::string& objID, tcpip::Storage* addData) {
     227        1315 :     tcpip::Storage inMsg;
     228             :     try {
     229        1315 :         createCommand(domID, varID, objID, addData);
     230        1315 :         mySocket->sendExact(myOutput);
     231        1315 :         answerLog << std::endl << "-> Command sent: <GetVariable>:" << std::endl
     232        1315 :                   << "  domID=" << domID << " varID=" << varID
     233        1315 :                   << " objID=" << objID << std::endl;
     234             :         std::string acknowledgement;
     235        1315 :         check_resultState(inMsg, domID, false, &acknowledgement);
     236             :         answerLog << acknowledgement << std::endl;
     237          79 :     } catch (libsumo::TraCIException& e) {
     238          79 :         answerLog << e.what() << std::endl;
     239             :         return;
     240          79 :     }
     241        1236 :     check_commandGetResult(inMsg, domID, -1, false);
     242             :     // report result state
     243             :     try {
     244        1236 :         int variableID = inMsg.readUnsignedByte();
     245        1236 :         std::string objectID = inMsg.readString();
     246        2472 :         answerLog <<  "  CommandID=" << (domID + 0x10) << "  VariableID=" << variableID << "  ObjectID=" << objectID;
     247        1236 :         int valueDataType = inMsg.readUnsignedByte();
     248        1236 :         answerLog << " valueDataType=" << valueDataType;
     249        1236 :         readAndReportTypeDependent(inMsg, valueDataType);
     250           0 :     } catch (libsumo::TraCIException& e) {
     251           0 :         std::stringstream msg;
     252           0 :         msg << "Error while receiving command: " << e.what();
     253           0 :         errorMsg(msg);
     254             :         return;
     255           0 :     }
     256        1315 : }
     257             : 
     258             : 
     259             : void
     260         276 : TraCITestClient::commandSetValue(int domID, int varID, const std::string& objID, std::ifstream& defFile) {
     261         276 :     std::stringstream msg;
     262         276 :     tcpip::Storage inMsg, tmp;
     263         276 :     setValueTypeDependant(tmp, defFile, msg);
     264             :     std::string msgS = msg.str();
     265         276 :     if (msgS != "") {
     266           0 :         errorMsg(msg);
     267             :     }
     268         276 :     createCommand(domID, varID, objID, &tmp);
     269         276 :     mySocket->sendExact(myOutput);
     270         276 :     answerLog << std::endl << "-> Command sent: <SetValue>:" << std::endl
     271         276 :               << "  domID=" << domID << " varID=" << varID
     272         276 :               << " objID=" << objID << std::endl;
     273             :     try {
     274             :         std::string acknowledgement;
     275         276 :         check_resultState(inMsg, domID, false, &acknowledgement);
     276             :         answerLog << acknowledgement << std::endl;
     277          69 :     } catch (libsumo::TraCIException& e) {
     278          69 :         answerLog << e.what() << std::endl;
     279          69 :     }
     280         276 : }
     281             : 
     282             : 
     283             : void
     284          11 : TraCITestClient::commandSubscribeObjectVariable(int domID, const std::string& objID, double beginTime, double endTime, int varNo, std::ifstream& defFile) {
     285             :     std::vector<int> vars;
     286          24 :     for (int i = 0; i < varNo; ++i) {
     287             :         int var;
     288          13 :         defFile >> var;
     289             :         // variable id
     290          13 :         vars.push_back(var);
     291             :     }
     292          11 :     send_commandSubscribeObjectVariable(domID, objID, beginTime, endTime, vars);
     293          11 :     answerLog << std::endl << "-> Command sent: <SubscribeVariable>:" << std::endl
     294          22 :               << "  domID=" << domID << " objID=" << objID << " with " << varNo << " variables" << std::endl;
     295          11 :     tcpip::Storage inMsg;
     296             :     try {
     297             :         std::string acknowledgement;
     298          11 :         check_resultState(inMsg, domID, false, &acknowledgement);
     299             :         answerLog << acknowledgement << std::endl;
     300           7 :         validateSubscription(inMsg);
     301           4 :     } catch (libsumo::TraCIException& e) {
     302           4 :         answerLog << e.what() << std::endl;
     303           4 :     }
     304          22 : }
     305             : 
     306             : 
     307             : void
     308           3 : TraCITestClient::commandSubscribeContextVariable(int domID, const std::string& objID, double beginTime, double endTime,
     309             :         int domain, double range, int varNo, std::ifstream& defFile) {
     310             :     std::vector<int> vars;
     311           9 :     for (int i = 0; i < varNo; ++i) {
     312             :         int var;
     313           6 :         defFile >> var;
     314             :         // variable id
     315           6 :         vars.push_back(var);
     316             :     }
     317           3 :     send_commandSubscribeObjectContext(domID, objID, beginTime, endTime, domain, range, vars);
     318           3 :     answerLog << std::endl << "-> Command sent: <SubscribeContext>:" << std::endl
     319           6 :               << "  domID=" << domID << " objID=" << objID << " domain=" << domain << " range=" << range
     320           3 :               << " with " << varNo << " variables" << std::endl;
     321           3 :     tcpip::Storage inMsg;
     322             :     try {
     323             :         std::string acknowledgement;
     324           3 :         check_resultState(inMsg, domID, false, &acknowledgement);
     325             :         answerLog << acknowledgement << std::endl;
     326           3 :         validateSubscription(inMsg);
     327           0 :     } catch (libsumo::TraCIException& e) {
     328           0 :         answerLog << e.what() << std::endl;
     329           0 :     }
     330           6 : }
     331             : 
     332             : 
     333             : // ---------- Report helper
     334             : void
     335        1184 : TraCITestClient::writeResult() {
     336             :     time_t seconds;
     337             :     tm* locTime;
     338        1184 :     std::ofstream outFile(outputFileName.c_str());
     339        1184 :     if (!outFile) {
     340             :         std::cerr << "Unable to write result file" << std::endl;
     341             :     }
     342        1184 :     time(&seconds);
     343        1184 :     locTime = localtime(&seconds);
     344        1184 :     outFile << "TraCITestClient output file. Date: " << asctime(locTime) << std::endl;
     345        1184 :     outFile << answerLog.str();
     346        1184 :     outFile.close();
     347        1184 : }
     348             : 
     349             : 
     350             : void
     351         592 : TraCITestClient::errorMsg(std::stringstream& msg) {
     352         592 :     std::cerr << msg.str() << std::endl;
     353         592 :     answerLog << "----" << std::endl << msg.str() << std::endl;
     354         592 : }
     355             : 
     356             : 
     357             : 
     358             : 
     359             : 
     360             : 
     361             : bool
     362        5009 : TraCITestClient::validateSimulationStep2(tcpip::Storage& inMsg) {
     363             :     try {
     364        5009 :         int noSubscriptions = inMsg.readInt();
     365        5302 :         for (int s = 0; s < noSubscriptions; ++s) {
     366         293 :             if (!validateSubscription(inMsg)) {
     367             :                 return false;
     368             :             }
     369             :         }
     370           0 :     } catch (std::invalid_argument& e) {
     371           0 :         answerLog << "#Error while reading message:" << e.what() << std::endl;
     372             :         return false;
     373           0 :     }
     374             :     return true;
     375             : }
     376             : 
     377             : 
     378             : bool
     379         303 : TraCITestClient::validateSubscription(tcpip::Storage& inMsg) {
     380             :     try {
     381         303 :         int length = inMsg.readUnsignedByte();
     382         303 :         if (length == 0) {
     383         303 :             length = inMsg.readInt();
     384             :         }
     385         303 :         int cmdId = inMsg.readUnsignedByte();
     386         303 :         if (cmdId >= libsumo::RESPONSE_SUBSCRIBE_INDUCTIONLOOP_VARIABLE && cmdId <= libsumo::RESPONSE_SUBSCRIBE_GUI_VARIABLE) {
     387         189 :             answerLog << "  CommandID=" << cmdId;
     388         189 :             answerLog << "  ObjectID=" << inMsg.readString();
     389         189 :             int varNo = inMsg.readUnsignedByte();
     390         189 :             answerLog << "  #variables=" << varNo << std::endl;
     391         601 :             for (int i = 0; i < varNo; ++i) {
     392         412 :                 answerLog << "      VariableID=" << inMsg.readUnsignedByte();
     393         412 :                 bool ok = inMsg.readUnsignedByte() == libsumo::RTYPE_OK;
     394         412 :                 answerLog << "      ok=" << ok;
     395         412 :                 int valueDataType = inMsg.readUnsignedByte();
     396         412 :                 answerLog << " valueDataType=" << valueDataType;
     397         412 :                 readAndReportTypeDependent(inMsg, valueDataType);
     398             :             }
     399         114 :         } else if (cmdId >= libsumo::RESPONSE_SUBSCRIBE_INDUCTIONLOOP_CONTEXT && cmdId <= libsumo::RESPONSE_SUBSCRIBE_GUI_CONTEXT) {
     400         114 :             answerLog << "  CommandID=" << cmdId;
     401         228 :             answerLog << "  ObjectID=" << inMsg.readString();
     402         114 :             answerLog << "  Domain=" << inMsg.readUnsignedByte();
     403         114 :             int varNo = inMsg.readUnsignedByte();
     404         114 :             answerLog << "  #variables=" << varNo << std::endl;
     405         114 :             int objNo = inMsg.readInt();
     406         114 :             answerLog << "  #objects=" << objNo << std::endl;
     407         457 :             for (int j = 0; j < objNo; ++j) {
     408         343 :                 answerLog << "   ObjectID=" << inMsg.readString() << std::endl;
     409        1029 :                 for (int i = 0; i < varNo; ++i) {
     410         686 :                     answerLog << "      VariableID=" << inMsg.readUnsignedByte();
     411         686 :                     bool ok = inMsg.readUnsignedByte() == libsumo::RTYPE_OK;
     412         686 :                     answerLog << "      ok=" << ok;
     413         686 :                     int valueDataType = inMsg.readUnsignedByte();
     414         686 :                     answerLog << " valueDataType=" << valueDataType;
     415         686 :                     readAndReportTypeDependent(inMsg, valueDataType);
     416             :                 }
     417             :             }
     418             :         } else {
     419           0 :             answerLog << "#Error: received response with command id: " << cmdId << " but expected a subscription response (0xe0-0xef / 0x90-0x9f)" << std::endl;
     420             :             return false;
     421             :         }
     422           0 :     } catch (std::invalid_argument& e) {
     423           0 :         answerLog << "#Error while reading message:" << e.what() << std::endl;
     424             :         return false;
     425           0 :     }
     426             :     return true;
     427             : }
     428             : 
     429             : 
     430             : 
     431             : 
     432             : 
     433             : 
     434             : 
     435             : // ---------- Conversion helper
     436             : int
     437        1066 : TraCITestClient::setValueTypeDependant(tcpip::Storage& into, std::ifstream& defFile, std::stringstream& msg) {
     438             :     std::string dataTypeS;
     439        1066 :     defFile >> dataTypeS;
     440        1066 :     if (dataTypeS == "<airDist>") {
     441           6 :         into.writeUnsignedByte(libsumo::REQUEST_AIRDIST);
     442             :         return 1;
     443        1060 :     } else if (dataTypeS == "<drivingDist>") {
     444           8 :         into.writeUnsignedByte(libsumo::REQUEST_DRIVINGDIST);
     445             :         return 1;
     446        1052 :     } else if (dataTypeS == "<objSubscription>") {
     447             :         int beginTime, endTime, numVars;
     448           0 :         defFile >> beginTime >> endTime >> numVars;
     449           0 :         into.writeInt(beginTime);
     450           0 :         into.writeInt(endTime);
     451           0 :         into.writeInt(numVars);
     452           0 :         for (int i = 0; i < numVars; ++i) {
     453             :             int var;
     454           0 :             defFile >> var;
     455           0 :             into.writeUnsignedByte(var);
     456             :         }
     457           0 :         return 4 + 4 + 4 + numVars;
     458             :     }
     459             :     int valI;
     460             :     double valF;
     461        1052 :     if (dataTypeS == "<int>") {
     462         105 :         defFile >> valI;
     463         105 :         into.writeUnsignedByte(libsumo::TYPE_INTEGER);
     464         105 :         into.writeInt(valI);
     465             :         return 4 + 1;
     466         947 :     } else if (dataTypeS == "<byte>") {
     467          55 :         defFile >> valI;
     468          55 :         into.writeUnsignedByte(libsumo::TYPE_BYTE);
     469          55 :         into.writeByte(valI);
     470             :         return 1 + 1;
     471         892 :     }  else if (dataTypeS == "<ubyte>") {
     472          22 :         defFile >> valI;
     473          22 :         into.writeUnsignedByte(libsumo::TYPE_UBYTE);
     474          22 :         into.writeUnsignedByte(valI);
     475             :         return 1 + 1;
     476         870 :     } else if (dataTypeS == "<double>") {
     477             :         defFile >> valF;
     478         374 :         into.writeUnsignedByte(libsumo::TYPE_DOUBLE);
     479         374 :         into.writeDouble(valF);
     480             :         return 8 + 1;
     481         496 :     } else if (dataTypeS == "<string>") {
     482             :         std::string valueS;
     483         189 :         defFile >> valueS;
     484         189 :         if (valueS == "\"\"") {
     485             :             valueS = "";
     486             :         }
     487         189 :         into.writeUnsignedByte(libsumo::TYPE_STRING);
     488         189 :         into.writeString(valueS);
     489         189 :         return 4 + 1 + (int) valueS.length();
     490         307 :     } else if (dataTypeS == "<string*>") {
     491             :         std::vector<std::string> slValue;
     492          12 :         defFile >> valI;
     493             :         int length = 1 + 4;
     494          36 :         for (int i = 0; i < valI; ++i) {
     495             :             std::string tmp;
     496          24 :             defFile >> tmp;
     497          24 :             slValue.push_back(tmp);
     498          24 :             length += 4 + int(tmp.length());
     499             :         }
     500          12 :         into.writeUnsignedByte(libsumo::TYPE_STRINGLIST);
     501          12 :         into.writeStringList(slValue);
     502             :         return length;
     503         307 :     } else if (dataTypeS == "<compound>") {
     504         238 :         defFile >> valI;
     505         238 :         into.writeUnsignedByte(libsumo::TYPE_COMPOUND);
     506         238 :         into.writeInt(valI);
     507             :         int length = 1 + 4;
     508         946 :         for (int i = 0; i < valI; ++i) {
     509         708 :             length += setValueTypeDependant(into, defFile, msg);
     510             :         }
     511         238 :         return length;
     512          57 :     } else if (dataTypeS == "<color>") {
     513           7 :         defFile >> valI;
     514           7 :         into.writeUnsignedByte(libsumo::TYPE_COLOR);
     515           7 :         into.writeUnsignedByte(valI);
     516          28 :         for (int i = 0; i < 3; ++i) {
     517          21 :             defFile >> valI;
     518          21 :             into.writeUnsignedByte(valI);
     519             :         }
     520             :         return 1 + 4;
     521          50 :     } else if (dataTypeS == "<position2D>") {
     522             :         defFile >> valF;
     523           8 :         into.writeUnsignedByte(libsumo::POSITION_2D);
     524           8 :         into.writeDouble(valF);
     525             :         defFile >> valF;
     526           8 :         into.writeDouble(valF);
     527             :         return 1 + 8 + 8;
     528          42 :     } else if (dataTypeS == "<position3D>") {
     529             :         defFile >> valF;
     530          17 :         into.writeUnsignedByte(libsumo::POSITION_3D);
     531          17 :         into.writeDouble(valF);
     532             :         defFile >> valF;
     533          17 :         into.writeDouble(valF);
     534             :         defFile >> valF;
     535          17 :         into.writeDouble(valF);
     536             :         return 1 + 8 + 8 + 8;
     537          25 :     } else if (dataTypeS == "<positionRoadmap>") {
     538             :         std::string valueS;
     539          22 :         defFile >> valueS;
     540          22 :         into.writeUnsignedByte(libsumo::POSITION_ROADMAP);
     541          22 :         into.writeString(valueS);
     542          22 :         int length = 1 + 8 + (int) valueS.length();
     543             :         defFile >> valF;
     544          22 :         into.writeDouble(valF);
     545          22 :         defFile >> valI;
     546          22 :         into.writeUnsignedByte(valI);
     547          22 :         return length + 4 + 1;
     548           3 :     } else if (dataTypeS == "<shape>") {
     549           3 :         defFile >> valI;
     550           3 :         into.writeUnsignedByte(libsumo::TYPE_POLYGON);
     551           3 :         into.writeUnsignedByte(valI);
     552             :         int length = 1 + 1;
     553          12 :         for (int i = 0; i < valI; ++i) {
     554             :             double x, y;
     555             :             defFile >> x >> y;
     556           9 :             into.writeDouble(x);
     557           9 :             into.writeDouble(y);
     558           9 :             length += 8 + 8;
     559             :         }
     560           3 :         return length;
     561             :     }
     562           0 :     msg << "## Unknown data type: " << dataTypeS;
     563             :     return 0;
     564             : }
     565             : 
     566             : 
     567             : void
     568        2587 : TraCITestClient::readAndReportTypeDependent(tcpip::Storage& inMsg, int valueDataType) {
     569             :     if (valueDataType == libsumo::TYPE_UBYTE) {
     570          18 :         int ubyte = inMsg.readUnsignedByte();
     571          18 :         answerLog << " Unsigned Byte Value: " << ubyte << std::endl;
     572             :     } else if (valueDataType == libsumo::TYPE_BYTE) {
     573           0 :         int byte = inMsg.readByte();
     574           0 :         answerLog << " Byte value: " << byte << std::endl;
     575             :     } else if (valueDataType == libsumo::TYPE_INTEGER) {
     576         259 :         int integer = inMsg.readInt();
     577         259 :         answerLog << " Int value: " << integer << std::endl;
     578             :     } else if (valueDataType == libsumo::TYPE_DOUBLE) {
     579        1468 :         double doublev = inMsg.readDouble();
     580        1468 :         answerLog << " Double value: " << doublev << std::endl;
     581             :     } else if (valueDataType == libsumo::TYPE_POLYGON) {
     582          10 :         int size = inMsg.readUnsignedByte();
     583          10 :         if (size == 0) {
     584           0 :             size = inMsg.readInt();
     585             :         }
     586          10 :         answerLog << " PolygonValue: ";
     587         155 :         for (int i = 0; i < size; i++) {
     588         145 :             double x = inMsg.readDouble();
     589         145 :             double y = inMsg.readDouble();
     590         145 :             answerLog << "(" << x << "," << y << ") ";
     591             :         }
     592             :         answerLog << std::endl;
     593             :     } else if (valueDataType == libsumo::POSITION_3D) {
     594           7 :         double x = inMsg.readDouble();
     595           7 :         double y = inMsg.readDouble();
     596           7 :         double z = inMsg.readDouble();
     597           7 :         answerLog << " Position3DValue: " << std::endl;
     598             :         answerLog << " x: " << x << " y: " << y
     599             :                   << " z: " << z << std::endl;
     600             :     } else if (valueDataType == libsumo::POSITION_ROADMAP) {
     601          11 :         std::string roadId = inMsg.readString();
     602          11 :         double pos = inMsg.readDouble();
     603          11 :         int laneId = inMsg.readUnsignedByte();
     604             :         answerLog << " RoadMapPositionValue: roadId=" << roadId
     605          11 :                   << " pos=" << pos
     606          11 :                   << " laneId=" << laneId << std::endl;
     607             :     } else if (valueDataType == libsumo::TYPE_STRING) {
     608         263 :         std::string s = inMsg.readString();
     609         263 :         answerLog << " string value: " << s << std::endl;
     610             :     } else if (valueDataType == libsumo::TYPE_STRINGLIST) {
     611         327 :         std::vector<std::string> s = inMsg.readStringList();
     612         327 :         answerLog << " string list value: [ " << std::endl;
     613         990 :         for (std::vector<std::string>::iterator i = s.begin(); i != s.end(); ++i) {
     614         663 :             if (i != s.begin()) {
     615         463 :                 answerLog << ", ";
     616             :             }
     617        1326 :             answerLog << '"' << *i << '"';
     618             :         }
     619             :         answerLog << " ]" << std::endl;
     620         327 :     } else if (valueDataType == libsumo::TYPE_COMPOUND) {
     621          47 :         int no = inMsg.readInt();
     622          47 :         answerLog << " compound value with " << no << " members: [ " << std::endl;
     623         300 :         for (int i = 0; i < no; ++i) {
     624         253 :             int currentValueDataType = inMsg.readUnsignedByte();
     625         253 :             answerLog << " valueDataType=" << currentValueDataType;
     626         253 :             readAndReportTypeDependent(inMsg, currentValueDataType);
     627             :         }
     628             :         answerLog << " ]" << std::endl;
     629             :     } else if (valueDataType == libsumo::POSITION_2D) {
     630         157 :         double xv = inMsg.readDouble();
     631         157 :         double yv = inMsg.readDouble();
     632         157 :         answerLog << " position value: (" << xv << "," << yv << ")" << std::endl;
     633             :     } else if (valueDataType == libsumo::TYPE_COLOR) {
     634          20 :         int r = inMsg.readUnsignedByte();
     635          20 :         int g = inMsg.readUnsignedByte();
     636          20 :         int b = inMsg.readUnsignedByte();
     637          20 :         int a = inMsg.readUnsignedByte();
     638          80 :         answerLog << " color value: (" << r << "," << g << "," << b << "," << a << ")" << std::endl;
     639             :     } else {
     640           0 :         answerLog << "#Error: unknown valueDataType!" << std::endl;
     641             :     }
     642        2587 : }
     643             : 
     644             : 
     645             : void
     646           1 : TraCITestClient::testAPI() {
     647           1 :     answerLog << "testAPI:\n";
     648           1 :     const auto& version = getVersion();
     649           2 :     answerLog << "  getVersion: " << version.first << ", " << version.second << "\n";
     650           1 :     answerLog << "  setOrder:\n";
     651           1 :     setOrder(0);
     652             :     // edge
     653           1 :     answerLog << "  edge:\n";
     654           3 :     answerLog << "    getIDList: " << joinToString(edge.getIDList(), " ") << "\n";
     655           1 :     answerLog << "    getIDCount: " << edge.getIDCount() << "\n";
     656           1 :     const std::string edgeID = "e_m0";
     657           1 :     edge.adaptTraveltime(edgeID, 42, 0, 10);
     658           1 :     edge.setEffort(edgeID, 420, 0, 10);
     659           2 :     answerLog << "    currentTraveltime: " << edge.getTraveltime(edgeID) << "\n";
     660           2 :     answerLog << "    adaptedTravelTime: " << edge.getAdaptedTraveltime(edgeID, 0) << "\n";
     661           2 :     answerLog << "    effort: " << edge.getEffort(edgeID, 0) << "\n";
     662           1 :     answerLog << "    laneNumber: " << edge.getLaneNumber(edgeID) << "\n";
     663           2 :     answerLog << "    streetName: " << edge.getStreetName(edgeID) << "\n";
     664           1 :     edge.setMaxSpeed(edgeID, 42);
     665           2 :     answerLog << "    maxSpeed: " << lane.getMaxSpeed(edgeID + "_0") << "\n";
     666             : 
     667             :     // lane
     668           1 :     answerLog << "  lane:\n";
     669           3 :     answerLog << "    getIDList: " << joinToString(lane.getIDList(), " ") << "\n";
     670           1 :     answerLog << "    getIDCount: " << lane.getIDCount() << "\n";
     671           1 :     const std::string laneID = "e_m6_0";
     672           1 :     answerLog << "    getLinkNumber: " << lane.getLinkNumber(laneID) << "\n";
     673           1 :     std::vector<libsumo::TraCIConnection> connections = lane.getLinks(laneID);
     674           1 :     answerLog << "    getLinks:\n";
     675           5 :     for (int i = 0; i < (int)connections.size(); ++i) {
     676           4 :         const libsumo::TraCIConnection& c = connections[i];
     677             :         answerLog << "    approachedLane=" << c.approachedLane
     678           4 :                   << " hasPrio=" << c.hasPrio
     679           4 :                   << " isOpen=" << c.isOpen
     680           4 :                   << " hasFoe=" << c.hasFoe
     681             :                   << " approachedInternal=" << c.approachedInternal
     682             :                   << " state=" << c.state
     683             :                   << " direction=" << c.direction
     684           4 :                   << " length=" << c.length
     685           4 :                   << "\n";
     686             :     }
     687           3 :     answerLog << "    getFoes: " << joinToString(lane.getFoes("e_vu0_0", "e_m4_0"), " ") << "\n";
     688             :     try {
     689           1 :         answerLog << "    getFoes (invalid): ";
     690           3 :         answerLog << joinToString(lane.getFoes("e_vu0_0", "e_m4_1"), " ") << "\n";
     691           1 :     } catch (libsumo::TraCIException& e) {
     692           1 :         answerLog << "    caught TraCIException(" << e.what() << ")\n";
     693           1 :     }
     694           3 :     answerLog << "    getInternalFoes: " << joinToString(lane.getInternalFoes(":n_m4_2_0"), " ") << "\n";
     695             :     try {
     696           1 :         answerLog << "    getInternalFoes (invalid): ";
     697           2 :         answerLog << joinToString(lane.getInternalFoes("dummy"), " ") << "\n";
     698           1 :     } catch (libsumo::TraCIException& e) {
     699           1 :         answerLog << "    caught TraCIException(" << e.what() << ")\n";
     700           1 :     }
     701           1 :     lane.setMaxSpeed(laneID, 42);
     702           2 :     answerLog << "    maxSpeed: " << lane.getMaxSpeed(laneID) << "\n";
     703             :     // poi
     704           1 :     answerLog << "  POI:\n";
     705           3 :     answerLog << "    getIDList: " << joinToString(poi.getIDList(), " ") << "\n";
     706           1 :     answerLog << "    getIDCount: " << poi.getIDCount() << "\n";
     707           3 :     answerLog << "    getPosition: " << poi.getPosition("poi0").getString() << "\n";
     708           3 :     answerLog << "    getColor: " << poi.getColor("poi0").getString() << "\n";
     709             : 
     710             :     // poly
     711           1 :     answerLog << "  polygon:\n";
     712           3 :     answerLog << "    getIDList: " << joinToString(polygon.getIDList(), " ") << "\n";
     713           1 :     answerLog << "    getIDCount: " << polygon.getIDCount() << "\n";
     714           1 :     libsumo::TraCIPositionVector shape = polygon.getShape("poly0");
     715           2 :     polygon.setLineWidth("poly0", 0.6);
     716           3 :     answerLog << "    getLineWidth: " << polygon.getLineWidth("poly0") << "\n";
     717           3 :     answerLog << "    getShape: " << shape.getString() << "\n";
     718           3 :     answerLog << "    getColor: " << polygon.getColor("poly0").getString() << "\n";
     719           1 :     shape.value[0].x = 42;
     720           2 :     polygon.setShape("poly0", shape);
     721           3 :     answerLog << "    getShape after modification: " << polygon.getShape("poly0").getString() << "\n";
     722             : 
     723             :     // junction
     724           1 :     answerLog << "  junction:\n";
     725           3 :     answerLog << "    getIDList: " << joinToString(junction.getIDList(), " ") << "\n";
     726           1 :     answerLog << "    getIDCount: " << junction.getIDCount() << "\n";
     727           3 :     answerLog << "    getShape: " << junction.getShape("n_m4").getString() << "\n";
     728             : 
     729             :     // route
     730           1 :     answerLog << "  route:\n";
     731           1 :     answerLog << "    add:\n";
     732             :     std::vector<std::string> edges;
     733           1 :     edges.push_back("e_u1");
     734           1 :     edges.push_back("e_u0");
     735           2 :     route.add("e_u1", edges);
     736             :     edges.clear();
     737           1 :     edges.push_back("e_m4");
     738           2 :     route.add("e_m4", edges);
     739           3 :     answerLog << "    getIDList: " << joinToString(route.getIDList(), " ") << "\n";
     740             : 
     741             :     // vehicletype
     742           1 :     answerLog << "  vehicleType:\n";
     743           3 :     answerLog << "    getIDList: " << joinToString(vehicletype.getIDList(), " ") << "\n";
     744           2 :     vehicletype.setEmergencyDecel("t1", 9.9);
     745           2 :     answerLog << "    getEmergencyDecel: " << vehicletype.getEmergencyDecel("t1") << "\n";
     746           2 :     vehicletype.setApparentDecel("t1", 99.9);
     747           2 :     answerLog << "    getApparentDecel: " << vehicletype.getApparentDecel("t1") << "\n";
     748           2 :     vehicletype.setWidth("t1", 1.9);
     749           2 :     answerLog << "    getWidth: " << vehicletype.getWidth("t1") << "\n";
     750           2 :     vehicletype.setHeight("t1", 1.8);
     751           2 :     answerLog << "    getHeight: " << vehicletype.getHeight("t1") << "\n";
     752           2 :     vehicletype.setMinGapLat("t1", 1.5);
     753           2 :     answerLog << "    setMinGapLat: " << vehicletype.getMinGapLat("t1") << "\n";
     754           2 :     vehicletype.setMaxSpeedLat("t1", 1.2);
     755           2 :     answerLog << "    setMaxSpeedLat: " << vehicletype.getMaxSpeedLat("t1") << "\n";
     756           2 :     vehicletype.setLateralAlignment("t1", "compact");
     757           3 :     answerLog << "    getLateralAlignment: " << vehicletype.getLateralAlignment("t1") << "\n";
     758           1 :     answerLog << "    getPersonCapacity: " << vehicletype.getPersonCapacity("t1") << "\n";
     759           1 :     answerLog << "    copy type 't1' to 't1_copy' and set accel to 100.\n";
     760           2 :     vehicletype.copy("t1", "t1_copy");
     761           3 :     answerLog << "    getIDList: " << joinToString(vehicletype.getIDList(), " ") << "\n";
     762           2 :     vehicletype.setAccel("t1_copy", 100.);
     763           3 :     answerLog << "    getAccel('t1'): " << vehicletype.getAccel("t1") << "\n";
     764           2 :     answerLog << "    getAccel('t1_copy'): " << vehicletype.getAccel("t1_copy") << "\n";
     765             : 
     766             :     // vehicle
     767           1 :     answerLog << "  vehicle:\n";
     768           2 :     vehicle.setLine("0", "S42");
     769             :     std::vector<std::string> via;
     770           1 :     via.push_back("e_shape1");
     771           1 :     vehicle.setVia("0", via);
     772           2 :     vehicle.setType("0", "t1_copy");
     773           3 :     answerLog << "    getTypeID: " << vehicle.getTypeID("0") << "\n";
     774           3 :     answerLog << "    getRoadID: " << vehicle.getRoadID("0") << "\n";
     775           3 :     answerLog << "    getRouteID: " << vehicle.getRouteID("0") << "\n";
     776           3 :     answerLog << "    getLaneID: " << vehicle.getLaneID("0") << "\n";
     777           3 :     answerLog << "    getLanePosition: " << vehicle.getLanePosition("0") << "\n";
     778           3 :     answerLog << "    getLateralLanePosition: " << vehicle.getLateralLanePosition("0") << "\n";
     779           3 :     answerLog << "    getSpeed: " << vehicle.getSpeed("0") << "\n";
     780           3 :     answerLog << "    getLateralSpeed: " << vehicle.getLateralSpeed("0") << "\n";
     781           3 :     answerLog << "    getAcceleration: " << vehicle.getAcceleration("0") << "\n";
     782             : 
     783           3 :     answerLog << "    getFollowSpeed: " << vehicle.getFollowSpeed("0", 10, 20, 9, 4.5) << "\n";
     784           3 :     answerLog << "    getSecureGap: " << vehicle.getSecureGap("0", 10, 9, 4.5) << "\n";
     785           3 :     answerLog << "    getStopSpeed: " << vehicle.getStopSpeed("0", 10, 20) << "\n";
     786             : 
     787           2 :     answerLog << "    getSpeedMode: " << vehicle.getSpeedMode("0") << "\n";
     788           3 :     answerLog << "    getSlope: " << vehicle.getSlope("0") << "\n";
     789           3 :     answerLog << "    getLine: " << vehicle.getLine("0") << "\n";
     790           3 :     answerLog << "    getVia: " << joinToString(vehicle.getVia("0"), ",") << "\n";
     791           1 :     answerLog << "    getPersonCapacity: " << vehicle.getPersonCapacity("0") << "\n";
     792           2 :     vehicle.setMaxSpeed("0", 30);
     793           3 :     answerLog << "    getMaxSpeed: " << vehicle.getMaxSpeed("0") << "\n";
     794           2 :     answerLog << "    isRouteValid: " << vehicle.isRouteValid("0") << "\n";
     795           2 :     answerLog << "    getStopState: " << vehicle.getStopState("0") << "\n";
     796           2 :     answerLog << "    getStopDelay: " << vehicle.getStopDelay("0") << "\n";
     797           2 :     vehicle.setParameter("0", "meaningOfLife", "42");
     798           3 :     answerLog << "    param: " << vehicle.getParameter("0", "meaningOfLife") << "\n";
     799           2 :     std::pair<std::string, std::string> paramTuple = vehicle.getParameterWithKey("0", "meaningOfLife");
     800           1 :     answerLog << "    parameterWithKey: (" << paramTuple.first << ", " << paramTuple.second << ")\n";
     801             :     libsumo::TraCIColor col1;
     802           1 :     col1.r = 255;
     803           1 :     col1.g = 255;
     804             :     col1.b = 0;
     805           1 :     col1.a = 128;
     806           1 :     vehicle.setColor("0", col1);
     807           2 :     libsumo::TraCIColor col2 = vehicle.getColor("0");
     808           4 :     answerLog << "    getColor:  r=" << (int)col2.r << " g=" << (int)col2.g << " b=" << (int)col2.b << " a=" << (int)col2.a << "\n";
     809           2 :     int signals = vehicle.getSignals("0");
     810           1 :     answerLog << "    getSignals: " << signals << "\n";
     811           1 :     vehicle.setSignals("0", signals ^ TraCIAPI::VehicleScope::SIGNAL_FOGLIGHT);
     812           2 :     vehicle.setRoutingMode("0", libsumo::ROUTING_MODE_AGGREGATED);
     813           1 :     answerLog << "    getRoutingMode: " << vehicle.getRoutingMode("0") << "\n";
     814           1 :     answerLog << "    getNextTLS:\n";
     815           1 :     std::vector<libsumo::TraCINextTLSData> result = vehicle.getNextTLS("0");
     816           2 :     for (int i = 0; i < (int)result.size(); ++i) {
     817           1 :         const libsumo::TraCINextTLSData& d = result[i];
     818           3 :         answerLog << "      tls=" << d.id << " tlIndex=" << d.tlIndex << " dist=" << d.dist << " state=" << d.state << "\n";
     819             :     }
     820           1 :     answerLog << "    moveToXY, simStep:\n";
     821           2 :     vehicle.moveToXY("0", "dummy", 0, 2231.61, 498.29, 90, 1);
     822           1 :     simulationStep();
     823             :     // simulationStep(1);
     824           3 :     answerLog << "    getRoadID: " << vehicle.getRoadID("0") << "\n";
     825           3 :     answerLog << "    getLaneID: " << vehicle.getLaneID("0") << "\n";
     826           2 :     vehicle.changeTarget("0", "e_o0");
     827           2 :     std::vector<std::string> edges2 = vehicle.getRoute("0");
     828           3 :     answerLog << "    edges: " << joinToString(edges2, " ") << "\n";
     829           2 :     vehicle.setRouteID("0", "e_m4");
     830           3 :     answerLog << "    edges: " << joinToString(vehicle.getRoute("0"), " ") << "\n";
     831           2 :     vehicle.setRoute("0", edges2);
     832           3 :     answerLog << "    edges: " << joinToString(vehicle.getRoute("0"), " ") << "\n";
     833           1 :     answerLog << "    add:\n";
     834           2 :     vehicle.add("1", "e_u1");
     835           2 :     vehicle.add("2", "e_u1");
     836           2 :     vehicle.moveTo("2", "e_u0_0", 5);
     837           1 :     simulationStep();
     838           3 :     answerLog << "    getIDList: " << joinToString(vehicle.getIDList(), " ") << "\n";
     839           3 :     answerLog << "    getWaitingTime: " << vehicle.getWaitingTime("0") << "\n";
     840           2 :     answerLog << "    getAccumulatedWaitingTime: " << vehicle.getAccumulatedWaitingTime("0") << "\n";
     841           2 :     vehicle.setShapeClass("0", "bicycle");
     842           3 :     answerLog << "    getShapeClass: " << vehicle.getShapeClass("0") << "\n";
     843           2 :     std::pair<std::string, double> leader = vehicle.getLeader("1", 1000);
     844           1 :     answerLog << "    getLeader: " << leader.first << ", " << leader.second << "\n";
     845           2 :     std::pair<std::string, double> follower = vehicle.getFollower("1", 1000);
     846           1 :     answerLog << "    getFollower: " << follower.first << ", " << follower.second << "\n";
     847           1 :     std::pair<int, int> state = vehicle.getLaneChangeState("1", 1);
     848           2 :     answerLog << "    getLaneChangeState (left): " << state.first << ", " << state.second << "\n";
     849           1 :     state = vehicle.getLaneChangeState("1", -1);
     850           2 :     answerLog << "    getLaneChangeState (right): " << state.first << ", " << state.second << "\n";
     851           1 :     vehicle.rerouteTraveltime("0");
     852           1 :     vehicle.setSpeedFactor("0", 0.8);
     853           2 :     vehicle.setSpeedMode("0", 0);
     854           1 :     answerLog << "    getSpeedMode after change: " << vehicle.getSpeedMode("0") << "\n";
     855           2 :     vehicle.setLaneChangeMode("0", 0);
     856           1 :     answerLog << "    getLaneChangeMode after change: " << vehicle.getLaneChangeMode("0") << "\n";
     857           1 :     answerLog << "    remove:\n";
     858           2 :     vehicle.remove("0");
     859           1 :     answerLog << "    getIDCount: " << vehicle.getIDCount() << "\n";
     860             : 
     861             :     // inductionLoop
     862           1 :     answerLog << "  inductionloop:\n";
     863           3 :     answerLog << "    getIDList: " << joinToString(inductionloop.getIDList(), " ") << "\n";
     864           1 :     answerLog << "    getVehicleData:\n";
     865           1 :     std::vector<libsumo::TraCIVehicleData> result2 = inductionloop.getVehicleData("det1");
     866           1 :     for (int i = 0; i < (int)result2.size(); ++i) {
     867           0 :         const libsumo::TraCIVehicleData& vd = result2[i];
     868           0 :         answerLog << "      veh=" << vd.id << " length=" << vd.length << " entered=" << vd.entryTime << " left=" << vd.leaveTime << " type=" << vd.typeID << "\n";
     869             :     }
     870             : 
     871             :     // multi-entry/-exit detector
     872             :     // answerLog << "  multi-entry/-exit detector:\n";
     873             :     // answerLog << "    getLastStepVehicleIDs: " << joinToString(multientryexit.getLastStepVehicleIDs("det2"), " ") << "\n";
     874             :     // answerLog << "    getEntryLanes: " << joinToString(multientryexit.getEntryLanes("det2"), " ") << "\n";
     875             :     // answerLog << "    getExitLanes: " << joinToString(multientryexit.getExitLanes("det2"), " ") << "\n";
     876             :     // answerLog << "    getEntryPositions: " << joinToString(multientryexit.getEntryPositions("det2"), " ") << "\n";
     877             :     // answerLog << "    getExitPositions: " << joinToString(multientryexit.getExitPositions("det2"), " ") << "\n";
     878             : 
     879             :     // simulation
     880           1 :     answerLog << "  simulation:\n";
     881           3 :     answerLog << "    getOption: " << simulation.getOption("net-file") << "\n";
     882           3 :     answerLog << "    convert2D: " << simulation.convert2D("e_m5", 0).getString() << "\n";
     883           3 :     answerLog << "    convert2DGeo: " << simulation.convert2D("e_m5", 0, 0, true).getString() << "\n";
     884           3 :     answerLog << "    convert3D: " << simulation.convert3D("e_m5", 0).getString() << "\n";
     885           3 :     answerLog << "    convert3DGeo: " << simulation.convert3D("e_m5", 0, 0, true).getString() << "\n";
     886           3 :     answerLog << "    convertRoad: " << simulation.convertRoad(2500, 500).getString() << "\n";
     887           3 :     answerLog << "    convertRoadBus: " << simulation.convertRoad(2500, 500, false, "bus").getString() << "\n";
     888           3 :     answerLog << "    convertGeo: " << simulation.convertGeo(2500, 500).getString() << "\n";
     889           3 :     answerLog << "    convertCartesian: " << simulation.convertGeo(12, 52, true).getString() << "\n";
     890           2 :     answerLog << "    getDistance2D_air: " << simulation.getDistance2D(2500, 500, 2000, 500, false, false) << "\n";
     891           2 :     answerLog << "    getDistance2D_driving: " << simulation.getDistance2D(2500, 500, 2000, 500, false, true) << "\n";
     892           3 :     answerLog << "    getDistanceRoad_air: " << simulation.getDistanceRoad("e_m5", 0, "e_m4", 0, false) << "\n";
     893           3 :     answerLog << "    getDistanceRoad_driving: " << simulation.getDistanceRoad("e_m5", 0, "e_m4", 0, true) << "\n";
     894           1 :     answerLog << "    getCurrentTime: " << simulation.getCurrentTime() << "\n";
     895           2 :     answerLog << "    getDeltaT: " << simulation.getDeltaT() << "\n";
     896           4 :     answerLog << "    parkingArea param: " << simulation.getParameter("park1", "parkingArea.capacity") << "\n";
     897           2 :     answerLog << "    busStopWaiting: " << simulation.getBusStopWaiting("bs1") << "\n";
     898           3 :     answerLog << "    busStopWaitingIDs: " << joinToString(simulation.getBusStopWaitingIDList("bs1"), " ") << "\n";
     899           1 :     simulation.writeMessage("custom message test");
     900           1 :     answerLog << "    subscribe to road and pos of vehicle '1':\n";
     901           3 :     answerLog << "    findRoute: " << joinToString(simulation.findRoute("e_m5", "e_m4").edges, " ") << "\n";
     902             :     std::vector<int> vars;
     903           1 :     vars.push_back(libsumo::VAR_ROAD_ID);
     904           1 :     vars.push_back(libsumo::VAR_LANEPOSITION);
     905           1 :     vehicle.subscribe("1", vars, 0, 100);
     906           1 :     simulationStep();
     907           1 :     answerLog << "    subscription results:\n";
     908           2 :     libsumo::TraCIResults result3 = vehicle.getSubscriptionResults("1");
     909           4 :     answerLog << "      roadID=" << result3[libsumo::VAR_ROAD_ID]->getString() << " pos=" << result3[libsumo::VAR_LANEPOSITION]->getString() << "\n";
     910             : 
     911           1 :     answerLog << "    subscribe to vehicles around edge 'e_u1':\n";
     912             :     std::vector<int> vars2;
     913           1 :     vars2.push_back(libsumo::VAR_LANEPOSITION);
     914           1 :     edge.subscribeContext("e_u1", libsumo::CMD_GET_VEHICLE_VARIABLE, 100, vars2, 0, 100);
     915           1 :     simulationStep();
     916           1 :     answerLog << "    context subscription results:\n";
     917           2 :     libsumo::SubscriptionResults result4 = edge.getContextSubscriptionResults("e_u1");
     918           3 :     for (libsumo::SubscriptionResults::iterator it = result4.begin(); it != result4.end(); ++it) {
     919           6 :         answerLog << "      vehicle=" << it->first << " pos=" << it->second[libsumo::VAR_LANEPOSITION]->getString() << "\n";
     920             :     }
     921             : 
     922           1 :     answerLog << "    subscribe to vehicles around vehicle '1':\n";
     923             :     std::vector<int> vars3;
     924           1 :     vars3.push_back(libsumo::VAR_SPEED);
     925           1 :     vehicle.subscribeContext("1", libsumo::CMD_GET_VEHICLE_VARIABLE, 1000, vars3, 0, 100);
     926           1 :     vehicle.addSubscriptionFilterLanes(std::vector<int>({0, 1, 2}));
     927           1 :     vehicle.addSubscriptionFilterNoOpposite();
     928           1 :     vehicle.addSubscriptionFilterDownstreamDistance(1000);
     929           1 :     vehicle.addSubscriptionFilterUpstreamDistance(1000);
     930           1 :     vehicle.addSubscriptionFilterCFManeuver();
     931           1 :     vehicle.addSubscriptionFilterLeadFollow(std::vector<int>({0, 1, 2}));
     932           1 :     vehicle.addSubscriptionFilterTurn();
     933           2 :     vehicle.addSubscriptionFilterVClass(std::vector<std::string>({"passenger"}));
     934           2 :     vehicle.addSubscriptionFilterVType(std::vector<std::string>({"DEFAULT_VEHTYPE"}));
     935           1 :     vehicle.addSubscriptionFilterLCManeuver(1);
     936             : 
     937           1 :     vehicle.subscribeContext("3", libsumo::CMD_GET_VEHICLE_VARIABLE, 200, vars3, 0, 100);
     938           1 :     vehicle.addSubscriptionFilterFieldOfVision(90);
     939             : 
     940           1 :     vehicle.subscribeContext("4", libsumo::CMD_GET_VEHICLE_VARIABLE, 200, vars3, 0, 100);
     941           1 :     vehicle.addSubscriptionFilterLateralDistance(50);
     942             :     //
     943             : 
     944           1 :     simulationStep();
     945           1 :     answerLog << "    context subscription results:\n";
     946           2 :     libsumo::SubscriptionResults result5 = vehicle.getContextSubscriptionResults("1");
     947           3 :     for (auto item : result5) {
     948           2 :         answerLog << "      vehicle=" << item.first << "\n";
     949           2 :     }
     950             : 
     951             :     // person
     952           1 :     answerLog << "  person:\n";
     953           1 :     person.setWidth("p0", 1);
     954           1 :     person.setMinGap("p0", 2);
     955           1 :     person.setLength("p0", 3);
     956           1 :     person.setHeight("p0", 4);
     957           1 :     person.setColor("p0", col1);
     958           2 :     person.setType("p0", "stilts");
     959           3 :     answerLog << "    getIDList: " << joinToString(person.getIDList(), " ") << "\n";
     960           3 :     answerLog << "    getRoadID: " << person.getRoadID("p0") << "\n";
     961           3 :     answerLog << "    getLaneID: " << person.getLaneID("p0") << "\n";
     962           3 :     answerLog << "    getTypeID: " << person.getTypeID("p0") << "\n";
     963           3 :     answerLog << "    getWaitingTime: " << person.getWaitingTime("p0") << "\n";
     964           3 :     answerLog << "    getNextEdge: " << person.getNextEdge("p0") << "\n";
     965           2 :     answerLog << "    getStage: " << person.getStage("p0").description << "\n";
     966           2 :     answerLog << "    getRemainingStages: " << person.getRemainingStages("p0") << "\n";
     967           3 :     answerLog << "    getVehicle: " << person.getVehicle("p0") << "\n";
     968           3 :     answerLog << "    getEdges: " << joinToString(person.getEdges("p0"), " ") << "\n";
     969           3 :     answerLog << "    getPosition: " << person.getPosition("p0").getString() << "\n";
     970           3 :     answerLog << "    getPosition3D: " << person.getPosition3D("p0").getString() << "\n";
     971           3 :     answerLog << "    getAngle: " << person.getAngle("p0") << "\n";
     972           3 :     answerLog << "    getSlope: " << person.getSlope("p0") << "\n";
     973           3 :     answerLog << "    getLanePosition: " << person.getLanePosition("p0") << "\n";
     974           3 :     answerLog << "    getLength: " << person.getLength("p0") << "\n";
     975           3 :     answerLog << "    getColor: " << person.getColor("p0").getString() << "\n";
     976           2 :     person.setParameter("p0", "foo", "bar");
     977           3 :     answerLog << "    param: " << person.getParameter("p0", "foo") << "\n";
     978           1 :     person.setSpeed("p0", 3);
     979           1 :     simulationStep();
     980           2 :     answerLog << "    getSpeed: " << person.getSpeed("p0") << "\n";
     981           2 :     person.add("p1", "e_u1", 10);
     982             :     std::vector<std::string> walkEdges;
     983           1 :     walkEdges.push_back("e_u1");
     984           1 :     walkEdges.push_back("e_shape1");
     985           2 :     person.appendWalkingStage("p1", walkEdges, -20);
     986           2 :     person.appendWaitingStage("p1", 5);
     987           2 :     person.appendDrivingStage("p1", "e_vu2", "BusLine42");
     988           2 :     libsumo::TraCIStage stage(libsumo::STAGE_WALKING);
     989           1 :     stage.edges.push_back("e_vu2");
     990           1 :     stage.edges.push_back("e_vo2");
     991           1 :     stage.arrivalPos = -10;
     992           1 :     person.appendStage("p1", stage);
     993           1 :     simulationStep();
     994             :     // expect 5 stages due to the initial waiting-for-departure stage
     995           1 :     answerLog << "    getRemainingStages: " << person.getRemainingStages("p1") << "\n";
     996           2 :     person.removeStage("p1", 3);
     997           1 :     answerLog << "    getRemainingStages: " << person.getRemainingStages("p1") << "\n";
     998           2 :     person.removeStages("p1");
     999           2 :     answerLog << "    getRemainingStages: " << person.getRemainingStages("p1") << "\n";
    1000           2 :     answerLog << "    getStage: " << person.getStage("p1").description << "\n";
    1001           1 :     walkEdges.push_back("e_m5");
    1002           2 :     person.appendWalkingStage("p1", walkEdges, -20);
    1003           1 :     simulationStep();
    1004           3 :     answerLog << "    getEdges before rerouting: " << joinToString(person.getEdges("p1"), " ") << "\n";
    1005           2 :     person.rerouteTraveltime("p1");
    1006           3 :     answerLog << "    getEdges after rerouting: " << joinToString(person.getEdges("p1"), " ") << "\n";
    1007             : 
    1008             :     // trafficlights
    1009           1 :     answerLog << "  trafficlights:\n";
    1010           1 :     trafficlights.setPhase("n_m4", 0);
    1011           2 :     trafficlights.setPhaseName("n_m4", "nameSetByTraCI");
    1012           3 :     answerLog << "    getIDList: " << joinToString(trafficlights.getIDList(), " ") << "\n";
    1013           1 :     answerLog << "    getIDCount: " << trafficlights.getIDCount() << "\n";
    1014           3 :     answerLog << "    state: " << trafficlights.getRedYellowGreenState("n_m4") << "\n";
    1015           3 :     answerLog << "    program: " << trafficlights.getProgram("n_m4") << "\n";
    1016           2 :     answerLog << "    phase: " << trafficlights.getPhase("n_m4") << "\n";
    1017           3 :     answerLog << "    phaseName: " << trafficlights.getPhaseName("n_m4") << "\n";
    1018           3 :     answerLog << "    phaseDuration: " << trafficlights.getPhaseDuration("n_m4") << "\n";
    1019           3 :     answerLog << "    nextSwitch: " << trafficlights.getNextSwitch("n_m4") << "\n";
    1020           3 :     answerLog << "    controlledLanes: " << joinToString(trafficlights.getControlledLanes("n_m4"), " ") << "\n";
    1021           1 :     std::vector<std::vector<libsumo::TraCILink> > links = trafficlights.getControlledLinks("n_m4");
    1022           1 :     answerLog << "    controlledLinks:\n";
    1023           8 :     for (int i = 0; i < (int)links.size(); ++i) {
    1024          14 :         for (int j = 0; j < (int)links[i].size(); ++j) {
    1025          28 :             answerLog << "      index=" << i << " link=" << j << " fromLane=" << links[i][j].fromLane << " viaLane=" << links[i][j].viaLane << " toLane=" << links[i][j].toLane << "\n";
    1026             :         }
    1027             :     }
    1028           2 :     libsumo::TraCILogic logic("custom", 0, 3);
    1029           1 :     logic.phases.push_back(std::make_shared<libsumo::TraCIPhase>(5, "rrrrrrr", 5, 5));
    1030           1 :     logic.phases.push_back(std::make_shared<libsumo::TraCIPhase>(10, "ggggggg", 5, 15));
    1031           1 :     logic.phases.push_back(std::make_shared<libsumo::TraCIPhase>(3, "GGGGGGG", 3, 3));
    1032           1 :     logic.phases.push_back(std::make_shared<libsumo::TraCIPhase>(3, "yyyyyyy", 3, 3));
    1033           1 :     trafficlights.setProgramLogic("n_m4", logic);
    1034             : 
    1035           1 :     std::vector<libsumo::TraCILogic> logics = trafficlights.getAllProgramLogics("n_m4");
    1036           1 :     answerLog << "    completeDefinition:\n";
    1037           3 :     for (int i = 0; i < (int)logics.size(); ++i) {
    1038           6 :         answerLog << "      subID=" << logics[i].programID << " type=" << logics[i].type << " phase=" << logics[i].currentPhaseIndex << "\n";
    1039           4 :         answerLog << "      params=" << joinToString(logics[i].subParameter) << "\n";
    1040          12 :         for (int j = 0; j < (int)logics[i].phases.size(); ++j) {
    1041          10 :             answerLog << "         phase=" << logics[i].phases[j]->state
    1042          10 :                       << " dur=" << logics[i].phases[j]->duration
    1043          10 :                       << " minDur=" << logics[i].phases[j]->minDur
    1044          10 :                       << " maxDur=" << logics[i].phases[j]->maxDur
    1045          10 :                       << "\n";
    1046             :         }
    1047             :     }
    1048           1 :     simulationStep();
    1049           3 :     answerLog << "    state=" << trafficlights.getRedYellowGreenState("n_m4") << "\n";
    1050           2 :     trafficlights.setRedYellowGreenState("n_m4", "gGyruoO");
    1051           3 :     answerLog << "    stateSet=" << trafficlights.getRedYellowGreenState("n_m4") << "\n";
    1052           3 :     answerLog << "    program: " << trafficlights.getProgram("n_m4") << "\n";
    1053             : 
    1054           1 :     answerLog << "  gui:\n";
    1055             :     try {
    1056           1 :         answerLog << "    setScheme: \n";
    1057           2 :         gui.setSchema("View #0", "real world");
    1058           0 :         answerLog << "    getScheme: " << gui.getSchema("View #0") << "\n";
    1059           0 :         gui.setZoom("View #0", 50);
    1060           0 :         answerLog << "    getZoom: " << gui.getZoom() << "\n";
    1061           0 :         answerLog << "    take screenshot: \n";
    1062           0 :         gui.screenshot("View #0", "image.png", 500, 500);
    1063           1 :     } catch (libsumo::TraCIException&) {
    1064           1 :         answerLog << "    no support for gui commands\n";
    1065           1 :     }
    1066             : 
    1067           1 :     answerLog << "  load:\n";
    1068             :     std::vector<std::string> args;
    1069           1 :     args.push_back("-n");
    1070           1 :     args.push_back("net.net.xml");
    1071           1 :     args.push_back("-r");
    1072           1 :     args.push_back("input_routes.rou.xml");
    1073           1 :     args.push_back("-a");
    1074           1 :     args.push_back("input_additional.add.xml");
    1075           1 :     args.push_back("--no-step-log");
    1076           1 :     load(args);
    1077           1 :     simulationStep();
    1078           1 :     answerLog << "    getCurrentTime: " << simulation.getCurrentTime() << "\n";
    1079           1 :     vehicle.subscribe("0", vars, 0, 100);
    1080           1 :     edge.subscribeContext("e_u1", libsumo::CMD_GET_VEHICLE_VARIABLE, 100, vars2, 0, 100);
    1081           5 : }

Generated by: LCOV version 1.14