LCOV - code coverage report
Current view: top level - src/traci-server/lib - TraCI_Person.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 169 223 75.8 %
Date: 2017-11-11 03:29:50 Functions: 29 34 85.3 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
       3             : // Copyright (C) 2017-2017 German Aerospace Center (DLR) and others.
       4             : /****************************************************************************/
       5             : //
       6             : //   This program and the accompanying materials
       7             : //   are made available under the terms of the Eclipse Public License v2.0
       8             : //   which accompanies this distribution, and is available at
       9             : //   http://www.eclipse.org/legal/epl-v20.html
      10             : //
      11             : /****************************************************************************/
      12             : /// @file    TraCI_Person.cpp
      13             : /// @author  Leonhard Luecken
      14             : /// @date    15.09.2017
      15             : /// @version $Id$
      16             : ///
      17             : // C++ TraCI client API implementation
      18             : /****************************************************************************/
      19             : 
      20             : 
      21             : // ===========================================================================
      22             : // included modules
      23             : // ===========================================================================
      24             : #ifdef _MSC_VER
      25             : #include <windows_config.h>
      26             : #else
      27             : #include <config.h>
      28             : #endif
      29             : 
      30             : #include <microsim/MSTransportableControl.h>
      31             : #include <microsim/MSVehicleControl.h>
      32             : #include <microsim/MSEdge.h>
      33             : #include <microsim/MSNet.h>
      34             : #include <microsim/pedestrians/MSPerson.h>
      35             : #include <utils/geom/GeomHelper.h>
      36             : #include <utils/common/StringTokenizer.h>
      37             : #include "TraCI_VehicleType.h"
      38             : #include "TraCI_Person.h"
      39             : 
      40             : 
      41             : // ===========================================================================
      42             : // member definitions
      43             : // ===========================================================================
      44             : 
      45             : std::vector<std::string>
      46       43281 : TraCI_Person::getIDList() {
      47       43281 :     MSTransportableControl& c = MSNet::getInstance()->getPersonControl();
      48       43281 :     std::vector<std::string> ids;
      49      122652 :     for (MSTransportableControl::constVehIt i = c.loadedBegin(); i != c.loadedEnd(); ++i) {
      50       79371 :         if (i->second->getCurrentStageType() != MSTransportable::WAITING_FOR_DEPART) {
      51       79371 :             ids.push_back(i->first);
      52             :         }
      53             :     }
      54       43281 :     return std::move(ids);
      55             : }
      56             : 
      57             : 
      58             : int
      59          11 : TraCI_Person::getIDCount() {
      60          11 :     return MSNet::getInstance()->getPersonControl().size();
      61             : }
      62             : 
      63             : 
      64             : TraCIPosition
      65      101533 : TraCI_Person::getPosition(const std::string& personID) {
      66      101533 :     MSTransportable* p = getPerson(personID);
      67             :     TraCIPosition pos;
      68      101533 :     pos.x = p->getPosition().x();
      69      101533 :     pos.y = p->getPosition().y();
      70      101533 :     pos.z = p->getPosition().z();
      71      101533 :     return pos;
      72             : }
      73             : 
      74             : 
      75             : double
      76           8 : TraCI_Person::getAngle(const std::string& personID){
      77           8 :     return GeomHelper::naviDegree(getPerson(personID)->getAngle());
      78             : }
      79             : 
      80             : 
      81             : double
      82          14 : TraCI_Person::getSpeed(const std::string& personID){
      83          14 :     return getPerson(personID)->getSpeed();
      84             : }
      85             : 
      86             : 
      87             : std::string
      88          24 : TraCI_Person::getRoadID(const std::string& personID){
      89          24 :     return getPerson(personID)->getEdge()->getID();
      90             : }
      91             : 
      92             : 
      93             : double
      94          11 : TraCI_Person::getLanePosition(const std::string& personID) {
      95          11 :     return getPerson(personID)->getEdgePos();
      96             : }
      97             : 
      98             : 
      99             : TraCIColor
     100           8 : TraCI_Person::getColor(const std::string& personID){
     101           8 :     const RGBColor& col = getPerson(personID)->getParameter().color;
     102             :     TraCIColor tcol;
     103           8 :     tcol.r = col.red();
     104           8 :     tcol.g = col.green();
     105           8 :     tcol.b = col.blue();
     106           8 :     tcol.a = col.alpha();
     107           8 :     return tcol;
     108             : }
     109             : 
     110             : 
     111             : std::string
     112          30 : TraCI_Person::getTypeID(const std::string& personID) {
     113          30 :     return getPerson(personID)->getVehicleType().getID();
     114             : }
     115             : 
     116             : 
     117             : double
     118        1778 : TraCI_Person::getWaitingTime(const std::string& personID) {
     119        1778 :     return getPerson(personID)->getWaitingSeconds();
     120             : }
     121             : 
     122             : 
     123             : std::string
     124         210 : TraCI_Person::getNextEdge(const std::string& personID) {
     125         210 :     return dynamic_cast<MSPerson*>(getPerson(personID))->getNextEdge();
     126             : }
     127             : 
     128             : 
     129             : std::vector<std::string>
     130          23 : TraCI_Person::getEdges(const std::string& personID, int nextStageIndex) {
     131          23 :     MSTransportable* p = getPerson(personID);
     132          23 :     if (nextStageIndex >= p->getNumRemainingStages()) {
     133           0 :         throw TraCIException("The stage index must be lower than the number of remaining stages.");
     134             :     }
     135          23 :     if (nextStageIndex < (p->getNumRemainingStages() - p->getNumStages())) {
     136           0 :         throw TraCIException("The negative stage index must refer to a valid previous stage.");
     137             :     }
     138          23 :     std::vector<std::string> edgeIDs;
     139         100 :     for(auto& e : p->getEdges(nextStageIndex)) {
     140          77 :         edgeIDs.push_back(e->getID());
     141          23 :     }
     142          23 :     return edgeIDs;
     143             : }
     144             : 
     145             : 
     146             : int
     147          14 : TraCI_Person::getStage(const std::string& personID, int nextStageIndex) {
     148          14 :     MSTransportable* p = getPerson(personID);
     149          14 :     if (nextStageIndex >= p->getNumRemainingStages()) {
     150           3 :         throw TraCIException("The stage index must be lower than the number of remaining stages.");
     151             :     }
     152          11 :     if (nextStageIndex < (p->getNumRemainingStages() - p->getNumStages())) {
     153           3 :         throw TraCIException("The negative stage index must refer to a valid previous stage.");
     154             :     }
     155           8 :     return p->getStageType(nextStageIndex);
     156             : }
     157             : 
     158             : 
     159             : int
     160          31 : TraCI_Person::getRemainingStages(const std::string& personID) {
     161          31 :     return getPerson(personID)->getNumRemainingStages();
     162             : }
     163             : 
     164             : 
     165             : std::string
     166           7 : TraCI_Person::getVehicle(const std::string& personID) {
     167           7 :     const SUMOVehicle* veh = getPerson(personID)->getVehicle();
     168           7 :     if (veh == nullptr) {
     169           7 :         return "";
     170             :     } else {
     171           0 :         return veh->getID();
     172             :     }
     173             : }
     174             : 
     175             : 
     176             : std::string
     177           6 : TraCI_Person::getParameter(const std::string& personID, const std::string& param) {
     178           6 :     return getPerson(personID)->getParameter().getParameter(param, "");
     179             : }
     180             : 
     181             : 
     182             : 
     183             : 
     184             : void
     185           4 : TraCI_Person::setSpeed(const std::string& personID, double speed) {
     186           4 :     getPerson(personID)->setSpeed(speed);
     187           4 : }
     188             : 
     189             : 
     190             : void
     191           4 : TraCI_Person::setType(const std::string& personID, const std::string& typeID) {
     192           4 :     MSVehicleType* vehicleType = MSNet::getInstance()->getVehicleControl().getVType(typeID);
     193           4 :     if (vehicleType == 0) {
     194           0 :         throw TraCIException("The vehicle type '" + typeID + "' is not known.");
     195             :     }
     196           4 :     getPerson(personID)->replaceVehicleType(vehicleType);
     197           4 : }
     198             : 
     199             : 
     200             : void
     201           7 : TraCI_Person::add(const std::string& personID, const std::string& edgeID, double pos, double departInSecs, const std::string typeID) {
     202             :     MSTransportable* p;
     203             :     try {
     204           7 :         p = getPerson(personID);
     205          14 :     } catch (TraCIException&) {
     206           7 :         p = nullptr;
     207             :     }
     208             : 
     209           7 :     if (p != nullptr) {
     210           0 :         throw TraCIException("The person " + personID + " to add already exists.");
     211             :     }
     212             : 
     213           7 :     SUMOTime depart = TIME2STEPS(departInSecs);
     214           7 :     SUMOVehicleParameter vehicleParams;
     215           7 :     vehicleParams.id = personID;
     216             : 
     217           7 :     MSVehicleType* vehicleType = MSNet::getInstance()->getVehicleControl().getVType(typeID);
     218           7 :     if (!vehicleType) {
     219           0 :         throw TraCIException("Invalid type '" + typeID + "' for person '" + personID + "'");
     220             :     }
     221             : 
     222           7 :     const MSEdge* edge = MSEdge::dictionary(edgeID);
     223           7 :     if (!edge) {
     224           0 :         throw TraCIException("Invalid edge '" + edgeID + "' for person: '" + personID + "'");
     225             :     }
     226             : 
     227           7 :     if (depart < 0) {
     228           7 :         const int proc = (int)-depart;
     229           7 :         if (proc >= static_cast<int>(DEPART_DEF_MAX)) {
     230           0 :             throw TraCIException("Invalid departure time.");
     231             :         }
     232           7 :         vehicleParams.departProcedure = (DepartDefinition)proc;
     233           7 :         vehicleParams.depart = MSNet::getInstance()->getCurrentTimeStep();
     234           0 :     } else if (depart < MSNet::getInstance()->getCurrentTimeStep()) {
     235           0 :         vehicleParams.depart = MSNet::getInstance()->getCurrentTimeStep();
     236           0 :         WRITE_WARNING("Departure time " + toString(departInSecs) + " for person '" + personID 
     237             :                 + "' is in the past; using current time " + time2string(vehicleParams.depart) + " instead.");
     238             :     } else {
     239           0 :         vehicleParams.depart = depart;
     240             :     }
     241             : 
     242           7 :     vehicleParams.departPosProcedure = DEPART_POS_GIVEN;
     243           7 :     if (fabs(pos) > edge->getLength()) {
     244           0 :         throw TraCIException("Invalid departure position.");
     245             :     }
     246           7 :     if (pos < 0) {
     247           6 :         pos += edge->getLength();
     248             :     }
     249           7 :     vehicleParams.departPos = pos;
     250             : 
     251           7 :     SUMOVehicleParameter* params = new SUMOVehicleParameter(vehicleParams);
     252           7 :     MSTransportable::MSTransportablePlan* plan = new MSTransportable::MSTransportablePlan();
     253           7 :     plan->push_back(new MSTransportable::Stage_Waiting(*edge, 0, depart, pos, "awaiting departure", true));
     254             : 
     255             :     try {
     256           7 :         MSTransportable* person = MSNet::getInstance()->getPersonControl().buildPerson(params, vehicleType, plan, false);
     257           7 :         MSNet::getInstance()->getPersonControl().add(person);
     258           0 :     } catch (ProcessError& e) {
     259           0 :         delete params;
     260           0 :         delete plan;
     261           0 :         throw TraCIException(e.what());
     262           7 :     }
     263           7 : }
     264             : 
     265             : 
     266             : void
     267           4 : TraCI_Person::appendDrivingStage(const std::string& personID, const std::string& toEdge, const std::string& lines, const std::string& stopID) {
     268           4 :     MSTransportable* p = getPerson(personID);
     269           4 :     const MSEdge* edge = MSEdge::dictionary(toEdge);
     270           4 :     if (!edge) {
     271           0 :         throw TraCIException("Invalid edge '" + toEdge + "' for person: '" + personID + "'");
     272             :     }
     273           4 :     if (lines.size() == 0) {
     274           0 :         return throw TraCIException("Empty lines parameter for person: '" + personID + "'");
     275             :     }
     276           4 :     MSStoppingPlace* bs = 0;
     277           4 :     if (stopID != "") {
     278           0 :         bs = MSNet::getInstance()->getBusStop(stopID);
     279           0 :         if (bs == 0) {
     280           0 :             throw TraCIException("Invalid stopping place id '" + stopID + "' for person: '" + personID + "'");
     281             :         }
     282             :     }
     283           4 :     p->appendStage(new MSPerson::MSPersonStage_Driving(*edge, bs, -NUMERICAL_EPS, StringTokenizer(lines).getVector()));
     284           4 : }
     285             : 
     286             : 
     287             : void
     288          10 : TraCI_Person::appendWaitingStage(const std::string& personID, double duration, const std::string& description, const std::string& stopID) {
     289          10 :     MSTransportable* p = getPerson(personID);
     290          10 :     if (duration < 0) {
     291           0 :         throw TraCIException("Duration for person: '" + personID + "' must not be negative");
     292             :     }
     293          10 :     MSStoppingPlace* bs = 0;
     294          10 :     if (stopID != "") {
     295           0 :         bs = MSNet::getInstance()->getBusStop(stopID);
     296           0 :         if (bs == 0) {
     297           0 :             throw TraCIException("Invalid stopping place id '" + stopID + "' for person: '" + personID + "'");
     298             :         }
     299             :     }
     300          10 :     p->appendStage(new MSTransportable::Stage_Waiting(*p->getArrivalEdge(), TIME2STEPS(duration), 0, p->getArrivalPos(), description, false));
     301          10 : }
     302             : 
     303             : 
     304             : void
     305          14 : TraCI_Person::appendWalkingStage(const std::string& personID, const std::vector<std::string>& edgeIDs, double arrivalPos, double duration, double speed, const std::string& stopID) {
     306          14 :     MSTransportable* p = getPerson(personID);
     307          14 :     ConstMSEdgeVector edges;
     308             :     try {
     309          14 :         MSEdge::parseEdgesList(edgeIDs, edges, "<unknown>");
     310           0 :     } catch (ProcessError& e) {
     311           0 :         throw TraCIException(e.what());
     312             :     }
     313          14 :     if (edges.empty()) {
     314           0 :         throw TraCIException("Empty edge list for walking stage of person '" + personID+ "'.");
     315             :     }
     316          14 :     if (fabs(arrivalPos) > edges.back()->getLength()) {
     317           0 :         throw TraCIException("Invalid arrivalPos for walking stage of person '" + personID  + "'.");
     318             :     }
     319          14 :     if (arrivalPos < 0) {
     320          11 :         arrivalPos += edges.back()->getLength();
     321             :     }
     322          14 :     if (speed < 0) {
     323          14 :         speed = p->getVehicleType().getMaxSpeed();
     324             :     }
     325          14 :     MSStoppingPlace* bs = 0;
     326          14 :     if (stopID != "") {
     327           0 :         bs = MSNet::getInstance()->getBusStop(stopID);
     328           0 :         if (bs == 0) {
     329           0 :             throw TraCIException("Invalid stopping place id '" + stopID + "' for person: '" + personID + "'");
     330             :         }
     331             :     }
     332          14 :     p->appendStage(new MSPerson::MSPersonStage_Walking(edges, bs, TIME2STEPS(duration), speed, p->getArrivalPos(), arrivalPos, 0));
     333          14 : }
     334             : 
     335             : 
     336             : void
     337          25 : TraCI_Person::removeStage(const std::string& personID, int nextStageIndex) {
     338          25 :     MSTransportable* p = getPerson(personID);
     339          25 :     if (nextStageIndex >= p->getNumRemainingStages()) {
     340           0 :         throw TraCIException("The stage index must be lower than the number of remaining stages.");
     341             :     }
     342          25 :     if (nextStageIndex < 0) {
     343           0 :         throw TraCIException("The stage index may not be negative.");
     344             :     }
     345          25 :     p->removeStage(nextStageIndex);
     346          25 : }
     347             : 
     348             : 
     349             : void
     350         598 : TraCI_Person::rerouteTraveltime(const std::string& personID) {
     351         598 :     MSTransportable* p = getPerson(personID);
     352         598 :     if (p->getNumRemainingStages() == 0 || p->getCurrentStageType() != MSTransportable::MOVING_WITHOUT_VEHICLE) {
     353           0 :         throw TraCIException("Person '" + personID + "' is not currenlty walking.");
     354             :     }
     355         598 :     const MSEdge* from = p->getEdge();
     356         598 :     double  departPos = p->getEdgePos();
     357         598 :     const MSEdge* to = p->getArrivalEdge();
     358         598 :     double  arrivalPos = p->getArrivalPos();
     359         598 :     double speed = p->getVehicleType().getMaxSpeed();
     360         598 :     ConstMSEdgeVector newEdges;
     361         598 :     MSNet::getInstance()->getPedestrianRouter().compute(from, to, departPos, arrivalPos, speed, 0, 0, newEdges);
     362         598 :     if (newEdges.empty()) {
     363           0 :         throw TraCIException("Could not find new route for person '" + personID + "'.");
     364             :     }
     365         608 :     ConstMSEdgeVector oldEdges = p->getEdges(0);
     366             :     assert(!oldEdges.empty());
     367         598 :     if (oldEdges.front()->getFunction() != EDGEFUNC_NORMAL) {
     368         588 :         oldEdges.erase(oldEdges.begin());
     369             :     }
     370         598 :     if (newEdges == oldEdges) {
     371        1186 :         return;
     372             :     }
     373          10 :     if (newEdges.front() != from) {
     374             :         // @note: maybe this should be done automatically by the router
     375           3 :         newEdges.insert(newEdges.begin(), from);
     376             :     }
     377             :     //std::cout << " from=" << from->getID() << " to=" << to->getID() << " newEdges=" << toString(newEdges) << "\n";
     378          10 :     MSPerson::MSPersonStage_Walking* newStage = new MSPerson::MSPersonStage_Walking(newEdges, 0, -1, speed, departPos, arrivalPos, 0);
     379          10 :     if (p->getNumRemainingStages() == 1) {
     380             :         // Do not remove the last stage (a waiting stage would be added otherwise)
     381          10 :         p->appendStage(newStage);
     382             :         //std::cout << "case a: remaining=" << p->getNumRemainingStages() << "\n";
     383          10 :         p->removeStage(0);
     384             :     } else {
     385           0 :         p->removeStage(0);
     386           0 :         p->appendStage(newStage);
     387             :         //std::cout << "case b: remaining=" << p->getNumRemainingStages() << "\n";
     388          10 :     }
     389             : }
     390             : 
     391             : 
     392             : /** untested setter functions which alter the person's vtype ***/
     393             : 
     394             : void
     395           3 : TraCI_Person::setParameter(const std::string& personID, const std::string& key, const std::string& value) {
     396           3 :     MSTransportable* p = getPerson(personID);
     397           3 :     ((SUMOVehicleParameter&) p->getParameter()).setParameter(key, value);
     398           3 : }
     399             : 
     400             : void
     401           0 : TraCI_Person::setLength(const std::string& personID, double length) {
     402           0 :     TraCI_VehicleType::getVType(getSingularVType(personID))->setLength(length);
     403           0 : }
     404             : 
     405             : void
     406           0 : TraCI_Person::setWidth(const std::string& personID, double width) {
     407           0 :     TraCI_VehicleType::getVType(getSingularVType(personID))->setWidth(width);
     408           0 : }
     409             : 
     410             : void
     411           0 : TraCI_Person::setHeight(const std::string& personID, double height) {
     412           0 :     TraCI_VehicleType::getVType(getSingularVType(personID))->setHeight(height);
     413           0 : }
     414             : 
     415             : void
     416           0 : TraCI_Person::setMinGap(const std::string& personID, double minGap) {
     417           0 :     TraCI_VehicleType::getVType(getSingularVType(personID))->setMinGap(minGap);
     418           0 : }
     419             : 
     420             : void
     421           0 : TraCI_Person::setColor(const std::string& personID, const TraCIColor& c) {
     422           0 :     TraCI_VehicleType::getVType(getSingularVType(personID))->setColor(RGBColor(c.r, c.g, c.b, c.a));
     423           0 : }
     424             : 
     425             : 
     426             : 
     427             : /******** private functions *************/
     428             : 
     429             : MSTransportable*
     430      104390 : TraCI_Person::getPerson(const std::string& personID) {
     431      104390 :     MSTransportableControl& c = MSNet::getInstance()->getPersonControl();
     432      104390 :     MSTransportable* p = c.get(personID);
     433      104390 :     if (p == 0) {
     434          12 :         throw TraCIException("Person '" + personID + "' is not known");
     435             :     }
     436      104378 :     return p;
     437             : }
     438             : 
     439             : std::string
     440          24 : TraCI_Person::getSingularVType(const std::string& personID) {
     441          24 :     return getPerson(personID)->getSingularType().getID();
     442       43554 : }
     443             : 
     444             : 
     445             : /****************************************************************************/

Generated by: LCOV version 1.12