LCOV - code coverage report
Current view: top level - src/traci_testclient - TraCITestClient.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 93.4 % 722 674
Test Date: 2024-11-21 15:56:26 Functions: 100.0 % 17 17

            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         1218 : TraCITestClient::TraCITestClient(std::string outputFileName)
      54         3654 :     : 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         1218 :     answerLog << std::setprecision(2);
      58         1218 : }
      59              : 
      60              : 
      61         1218 : TraCITestClient::~TraCITestClient() {
      62         1218 :     writeResult();
      63         1218 : }
      64              : 
      65              : 
      66              : int
      67         1218 : TraCITestClient::run(std::string fileName, int port, std::string host) {
      68         1218 :     std::ifstream defFile;
      69              :     std::string fileContentStr;
      70         1218 :     std::stringstream fileContent;
      71              :     std::string lineCommand;
      72         1218 :     std::stringstream msg;
      73         1218 :     int repNo = 1;
      74              :     bool commentRead = false;
      75              : 
      76              :     // try to connect
      77              :     try {
      78         1218 :         TraCIAPI::connect(host, port);
      79          609 :     } catch (tcpip::SocketException& e) {
      80          609 :         msg << "#Error while connecting: " << e.what();
      81          609 :         errorMsg(msg);
      82              :         return 2;
      83          609 :     }
      84              : 
      85              :     // read definition file and trigger commands according to it
      86          609 :     defFile.open(fileName.c_str());
      87          609 :     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         4303 :     while (defFile >> lineCommand) {
      95         3695 :         repNo = 1;
      96         3695 :         if (lineCommand.compare("%") == 0) {
      97              :             // a comment was read
      98           38 :             commentRead = !commentRead;
      99           38 :             continue;
     100              :         }
     101         3657 :         if (commentRead) {
     102              :             // wait until end of comment is reached
     103          440 :             continue;
     104              :         }
     105         3217 :         if (lineCommand.compare("repeat") == 0) {
     106          186 :             defFile >> repNo;
     107          186 :             defFile >> lineCommand;
     108              :         }
     109         3217 :         if (lineCommand.compare("simstep2") == 0) {
     110              :             // read parameter for command simulation step and trigger command
     111              :             double time;
     112              :             defFile >> time;
     113         6640 :             for (int i = 0; i < repNo; i++) {
     114         5054 :                 commandSimulationStep(time);
     115              :             }
     116         1630 :         } else if (lineCommand.compare("getvariable") == 0) {
     117              :             // trigger command GetXXXVariable
     118              :             int domID, varID;
     119              :             std::string objID;
     120         1247 :             defFile >> domID >> varID >> objID;
     121         1247 :             commandGetVariable(domID, varID, objID);
     122          383 :         } else if (lineCommand.compare("getvariable_plus") == 0) {
     123              :             // trigger command GetXXXVariable with one parameter
     124              :             int domID, varID;
     125              :             std::string objID;
     126           84 :             defFile >> domID >> varID >> objID;
     127           84 :             tcpip::Storage tmp;
     128           84 :             setValueTypeDependant(tmp, defFile, msg);
     129              :             std::string msgS = msg.str();
     130           84 :             if (msgS != "") {
     131            0 :                 errorMsg(msg);
     132              :             }
     133           84 :             commandGetVariable(domID, varID, objID, &tmp);
     134          383 :         } 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          288 :         }  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          285 :         }  else if (lineCommand.compare("setvalue") == 0) {
     150              :             // trigger command SetXXXValue
     151              :             int domID, varID;
     152              :             std::string objID;
     153          283 :             defFile >> domID >> varID >> objID;
     154          283 :             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          608 :     defFile.close();
     172          608 :     commandClose();
     173          608 :     closeSocket();
     174              :     return 0;
     175         3654 : }
     176              : 
     177              : 
     178              : // ---------- Commands handling
     179              : void
     180         5054 : TraCITestClient::commandSimulationStep(double time) {
     181              :     try {
     182         5054 :         send_commandSimulationStep(time);
     183         5054 :         answerLog << std::endl << "-> Command sent: <SimulationStep>:" << std::endl;
     184         5054 :         tcpip::Storage inMsg;
     185              :         std::string acknowledgement;
     186         5054 :         check_resultState(inMsg, libsumo::CMD_SIMSTEP, false, &acknowledgement);
     187              :         answerLog << acknowledgement << std::endl;
     188         5053 :         validateSimulationStep2(inMsg);
     189         5055 :     } catch (libsumo::TraCIException& e) {
     190            0 :         answerLog << e.what() << std::endl;
     191            0 :     }
     192         5053 : }
     193              : 
     194              : 
     195              : void
     196          608 : TraCITestClient::commandClose() {
     197              :     try {
     198          608 :         send_commandClose();
     199          608 :         answerLog << std::endl << "-> Command sent: <Close>:" << std::endl;
     200          608 :         tcpip::Storage inMsg;
     201              :         std::string acknowledgement;
     202          608 :         check_resultState(inMsg, libsumo::CMD_CLOSE, false, &acknowledgement);
     203              :         answerLog << acknowledgement << std::endl;
     204          608 :     } catch (libsumo::TraCIException& e) {
     205            0 :         answerLog << e.what() << std::endl;
     206            0 :     }
     207          608 : }
     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         1331 : TraCITestClient::commandGetVariable(int domID, int varID, const std::string& objID, tcpip::Storage* addData) {
     227         1331 :     tcpip::Storage inMsg;
     228              :     try {
     229         1331 :         createCommand(domID, varID, objID, addData);
     230         1331 :         mySocket->sendExact(myOutput);
     231         1331 :         answerLog << std::endl << "-> Command sent: <GetVariable>:" << std::endl
     232         1331 :                   << "  domID=" << domID << " varID=" << varID
     233         1331 :                   << " objID=" << objID << std::endl;
     234              :         std::string acknowledgement;
     235         1331 :         check_resultState(inMsg, domID, false, &acknowledgement);
     236              :         answerLog << acknowledgement << std::endl;
     237           81 :     } catch (libsumo::TraCIException& e) {
     238           81 :         answerLog << e.what() << std::endl;
     239              :         return;
     240           81 :     }
     241         1250 :     check_commandGetResult(inMsg, domID, -1, false);
     242              :     // report result state
     243              :     try {
     244         1250 :         int variableID = inMsg.readUnsignedByte();
     245         1250 :         std::string objectID = inMsg.readString();
     246         2500 :         answerLog <<  "  CommandID=" << (domID + 0x10) << "  VariableID=" << variableID << "  ObjectID=" << objectID;
     247         1250 :         int valueDataType = inMsg.readUnsignedByte();
     248         1250 :         answerLog << " valueDataType=" << valueDataType;
     249         1250 :         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         1331 : }
     257              : 
     258              : 
     259              : void
     260          283 : TraCITestClient::commandSetValue(int domID, int varID, const std::string& objID, std::ifstream& defFile) {
     261          283 :     std::stringstream msg;
     262          283 :     tcpip::Storage inMsg, tmp;
     263          283 :     setValueTypeDependant(tmp, defFile, msg);
     264              :     std::string msgS = msg.str();
     265          283 :     if (msgS != "") {
     266            0 :         errorMsg(msg);
     267              :     }
     268          283 :     createCommand(domID, varID, objID, &tmp);
     269          283 :     mySocket->sendExact(myOutput);
     270          283 :     answerLog << std::endl << "-> Command sent: <SetValue>:" << std::endl
     271          283 :               << "  domID=" << domID << " varID=" << varID
     272          283 :               << " objID=" << objID << std::endl;
     273              :     try {
     274              :         std::string acknowledgement;
     275          283 :         check_resultState(inMsg, domID, false, &acknowledgement);
     276              :         answerLog << acknowledgement << std::endl;
     277           73 :     } catch (libsumo::TraCIException& e) {
     278           73 :         answerLog << e.what() << std::endl;
     279           73 :     }
     280          283 : }
     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           11 : }
     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            3 : }
     331              : 
     332              : 
     333              : // ---------- Report helper
     334              : void
     335         1218 : TraCITestClient::writeResult() {
     336              :     time_t seconds;
     337              :     tm* locTime;
     338         1218 :     std::ofstream outFile(outputFileName.c_str());
     339         1218 :     if (!outFile) {
     340              :         std::cerr << "Unable to write result file" << std::endl;
     341              :     }
     342         1218 :     time(&seconds);
     343         1218 :     locTime = localtime(&seconds);
     344         1218 :     outFile << "TraCITestClient output file. Date: " << asctime(locTime) << std::endl;
     345         1218 :     outFile << answerLog.str();
     346         1218 :     outFile.close();
     347         1218 : }
     348              : 
     349              : 
     350              : void
     351          609 : TraCITestClient::errorMsg(std::stringstream& msg) {
     352          609 :     std::cerr << msg.str() << std::endl;
     353          609 :     answerLog << "----" << std::endl << msg.str() << std::endl;
     354          609 : }
     355              : 
     356              : 
     357              : 
     358              : 
     359              : 
     360              : 
     361              : bool
     362         5053 : TraCITestClient::validateSimulationStep2(tcpip::Storage& inMsg) {
     363              :     try {
     364         5053 :         int noSubscriptions = inMsg.readInt();
     365         5346 :         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              :                 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              :                     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         1077 : TraCITestClient::setValueTypeDependant(tcpip::Storage& into, std::ifstream& defFile, std::stringstream& msg) {
     438              :     std::string dataTypeS;
     439         1077 :     defFile >> dataTypeS;
     440         1077 :     if (dataTypeS == "<airDist>") {
     441            6 :         into.writeUnsignedByte(libsumo::REQUEST_AIRDIST);
     442              :         return 1;
     443         1071 :     } else if (dataTypeS == "<drivingDist>") {
     444            8 :         into.writeUnsignedByte(libsumo::REQUEST_DRIVINGDIST);
     445              :         return 1;
     446         1063 :     } 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         1063 :     if (dataTypeS == "<int>") {
     462          105 :         defFile >> valI;
     463          105 :         into.writeUnsignedByte(libsumo::TYPE_INTEGER);
     464          105 :         into.writeInt(valI);
     465              :         return 4 + 1;
     466          958 :     } 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          903 :     }  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          881 :     } else if (dataTypeS == "<double>") {
     477              :         defFile >> valF;
     478          378 :         into.writeUnsignedByte(libsumo::TYPE_DOUBLE);
     479          378 :         into.writeDouble(valF);
     480              :         return 8 + 1;
     481          503 :     } else if (dataTypeS == "<string>") {
     482              :         std::string valueS;
     483          193 :         defFile >> valueS;
     484          193 :         if (valueS == "\"\"") {
     485              :             valueS = "";
     486              :         }
     487          193 :         into.writeUnsignedByte(libsumo::TYPE_STRING);
     488          193 :         into.writeString(valueS);
     489          193 :         return 4 + 1 + (int) valueS.length();
     490          310 :     } 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          310 :     } else if (dataTypeS == "<compound>") {
     504          239 :         defFile >> valI;
     505          239 :         into.writeUnsignedByte(libsumo::TYPE_COMPOUND);
     506          239 :         into.writeInt(valI);
     507              :         int length = 1 + 4;
     508          949 :         for (int i = 0; i < valI; ++i) {
     509          710 :             length += setValueTypeDependant(into, defFile, msg);
     510              :         }
     511          239 :         return length;
     512           59 :     } else if (dataTypeS == "<color>") {
     513            9 :         defFile >> valI;
     514            9 :         into.writeUnsignedByte(libsumo::TYPE_COLOR);
     515            9 :         into.writeUnsignedByte(valI);
     516           36 :         for (int i = 0; i < 3; ++i) {
     517           27 :             defFile >> valI;
     518           27 :             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         2601 : 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          260 :         int integer = inMsg.readInt();
     577          260 :         answerLog << " Int value: " << integer << std::endl;
     578              :     } else if (valueDataType == libsumo::TYPE_DOUBLE) {
     579         1476 :         double doublev = inMsg.readDouble();
     580         1476 :         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:";
     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          267 :         std::string s = inMsg.readString();
     609          534 :         answerLog << " string value: " << (s.empty() ? "''" : s) << std::endl;
     610              :     } else if (valueDataType == libsumo::TYPE_STRINGLIST) {
     611          328 :         std::vector<std::string> s = inMsg.readStringList();
     612          328 :         answerLog << " string list value: [ ";
     613          991 :         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          328 :     } else if (valueDataType == libsumo::TYPE_COMPOUND) {
     621           47 :         int no = inMsg.readInt();
     622           47 :         answerLog << " compound value with " << no << " members: [";
     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         2601 : }
     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            4 :     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            4 :     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            2 :     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            2 :     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            2 :     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            4 :     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            3 :     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            2 :     answerLog << "    getLaneID: " << vehicle.getLaneID("0") << "\n";
     826            2 :     vehicle.changeTarget("0", "e_o0");
     827            2 :     std::vector<std::string> edges2 = vehicle.getRoute("0");
     828            2 :     answerLog << "    edges: " << joinToString(edges2, " ") << "\n";
     829            2 :     vehicle.setRouteID("0", "e_m4");
     830            4 :     answerLog << "    edges: " << joinToString(vehicle.getRoute("0"), " ") << "\n";
     831            2 :     vehicle.setRoute("0", edges2);
     832            4 :     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            2 :     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            2 :     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            3 :     answerLog << "    parkingArea param: " << simulation.getParameter("park1", "parkingArea.capacity") << "\n";
     897            2 :     answerLog << "    busStopWaiting: " << simulation.getBusStopWaiting("bs1") << "\n";
     898            4 :     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            4 :     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              :     }
     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            3 :     answerLog << "    getStage: " << person.getStage("p0").description << "\n";
     966            2 :     answerLog << "    getRemainingStages: " << person.getRemainingStages("p0") << "\n";
     967            3 :     answerLog << "    getVehicle: " << person.getVehicle("p0") << "\n";
     968            4 :     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            2 :     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            4 :     answerLog << "    getEdges before rerouting: " << joinToString(person.getEdges("p1"), " ") << "\n";
    1005            2 :     person.rerouteTraveltime("p1");
    1006            4 :     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            4 :     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            2 :     answerLog << "    state=" << trafficlights.getRedYellowGreenState("n_m4") << "\n";
    1050            2 :     trafficlights.setRedYellowGreenState("n_m4", "gGyruoO");
    1051            3 :     answerLog << "    stateSet=" << trafficlights.getRedYellowGreenState("n_m4") << "\n";
    1052            2 :     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           11 : }
        

Generated by: LCOV version 2.0-1