Hi Ruud, All,

Thanks for the help. Calling the get*() in each step works.


Just to wrap up: the getSubscriptionResults() gives results that can be iterated for libtraci::Vehicle.

It does not seem to provide any useable results for the libtraci::Simulation and libtraci::Edge though.


Kind regards,

Bart


On 05-12-2023 17:45, Ruud van Gaal wrote:
Hi Bart,

I haven't really used arrival/departure a lot, since I have mostly flow vehicles. But at the beginning I used code like this, notably *outside* of the subscription results:

/  int n=Simulation::getArrivedNumber();
    if(n>0) {
      pt_Log("Query vehicles: arrivedNumber=%d",n);

      auto id_list=Simulation::getArrivedIDList();
      for(auto id:id_list) {
        pt_Log("- %s",id.c_str());
      }
    }
/

Probably departure works exactly the same, but using getDepartedNumber() and getDepartedIDList(). This has to be called after every simulation step. To avoid missing vehicles that arrive or depart, do call Simulation::step(0) instead of taking multiple steps (Simulation::step(new_time)). The /getArrivedNumber() /call only reports vehicles from the last simulation step. Also, when overruling properties of vehicles, you need to make sure you do this on every simulation step, and not take large jumps.

As for keeping track of vehicle ID's, I keep a list of all vehicle ID's that I see in the subscription results. Then I remove and add vehicles as they disappear from the subscription results. This is slightly different from trying to keep a list of ALL vehicles in SUMO (which can be thousands); I only track the closest 50 or so within a radius. I guess for your case, keeping a local vehicle ID list and adding ID's as they are seen with 'getDepartedIDList()' and remove them when you see the ID in getArrivedIDList() is a nice way to keep an overview of all active vehicles within SUMO. There is a call to get them all, but the fewer calls to sumo-gui (over relatively slow TCP), the better.

Cheers,
Ruud


On Tue, Dec 5, 2023 at 5:35 PM T Eenachtacht <[email protected]> wrote:

    HI Ruud,

    Yes i do subscribe during initialisation (before the first
    simulation step) for both VAR_DEPARTED_VEHICLES_IDS and
    VAR_ARRIVED_VEHICLES_IDS.

    Vehicle_ids seem to be generated by SUMO only during the
    simulation when a vehicle departs. So as soon as the above
    subscription gives a new vehicle id the vehicle subscription can
    be done.

    Both subscriptions work fine. I can also receive and process
    subscription results for a specific vehicle, when i subscribe with
    a hard coded vehicle id.

    The only thing i do not understand how to get the vehicle_id from
    the libtraci::Simulation subscription results. I expect some type
    of list or vector of vehicle ids in the subscription results, but
    '/r.second()->getString().c_str()/' does not yield any vehicleid,
    or anything readable anyway.

    Can you explain or give an example how to get every single vehicle
    id from the subscription results to VAR_DEPARTED_VEHICLES_IDS?

    Thanks a lot,

    Bart


    On 05-12-2023 17:09, Ruud van Gaal wrote:
    Hi Bart,

    Yes, all subscribe results are returned in one batch. But that is
    probably the better thing to do. Realise that all these calls are
    really TCP send & receive calls to 'sumo-gui' or 'sumo'. So if
    you would intend to call getSubscriptionResults() multiple times
    per simulation step (each with a different filter), you're
    probably reducing performance quite a bit.
    So it's better to cache the results and make multiple passes in
    your own code instead of calling expensive TraCI functions.

    So something like this would be much faster:

    /void ProcessSubResults()/
    /{/
    /  auto sub_results = Vehicle::getSubscriptionResults(name.c_str());
    /
    /ProcessArrivedVehicles(sub_results);/
    /ProcessDepartedVehicles(sub_results);/
    /}
    /
    /void ProcessArrivedVehicles(...) {...}/

    You probably have something like this at subscription init time
    already; do you request VAR_ARRIVED_VEHICLES_IDS when subscribing?

    /std::vector<int> vars;
      // Info we need from vehicles in vicinity
      vars.push_back(libsumo::VAR_SPEED);
      vars.push_back(libsumo::VAR_ANGLE);
      vars.push_back(libsumo::VAR_SLOPE);
      vars.push_back(libsumo::VAR_SIGNALS);
      vars.push_back(libsumo::VAR_POSITION3D);
      Vehicle::subscribeContext(veh_id,
    libsumo::CMD_GET_VEHICLE_VARIABLE, prefSubscribeDistance, vars);
    /

    So, get all sub results in one call (which is probably one TCP
    send and receive call in the background), then do processing on
    the batch of results in your own code (where it's now local in
    memory).

    Indeed, the variable id (int) is the first item of every pair.

    Cheers,
    Ruud

    On Tue, Dec 5, 2023 at 3:41 PM T Eenachtacht
    <[email protected]> wrote:

        Hi Ruud,


        Thank you very much for the snippets. Very useful for my next
        step to extract vehicle information.

        As the first step i would like to get a list of the vehicle
        ids that just departed from the simulation (or newly arrived)
        to manage my internal list of active vehicles. From your
        first example it seems the results cannot be filtered to only
        the VAR_ARRIVED_VEHICLES_IDS or
        VAR_DEPARTED_VEHICLES_IDSInstead all subscribed results are
        returned in the sub_results map. The first element of the map
        is the variable ID, correct? Then i would expect the second
        element is a list of vehicle ids:

        /auto sub_results =
        Vehicle::getSubscriptionResults(name.c_str());
            for (auto r : sub_results) {
                int var_id = r.first();
        /
        /    if (var_id == libsumo::VAR_ARRIVED_VEHICLES_IDS) {
        /
        /        char const* vehicle_ids =
        r.second()->getString().c_str();/
        /    }
        /
        /    }
        /

        However, the vehicle_ids string does seems to contain any
        vehicle ids, list or ...

        Is it possible to get just the list of vehicle ids in the C++
        lib (like in Python), and if so how, or do i need to
        determine that from the individual vehicles results like in
        your second example?


        Thanks,

        Bart


        On 05-12-2023 10:12, Ruud van Gaal wrote:
        Hi Bart,

        Here are some snippets. For getSubscriptionResults():

        /auto sub_results =
        Vehicle::getSubscriptionResults(name.c_str());
            for (auto r : sub_results) {
              pt_LogDbg("- Ego subscr result type 0x%x: '%s'",
        r.first, r.second->getString().c_str());
            }
        /

        I'm using a context subscription really (only report within
        a specific radius):

        /libsumo::SubscriptionResults subscriptionResults;
          if (prefLogSumoCalls)
            pt_Log("SUMO call:
        Vehicle::getContextSubscriptionResults(%s)", name.c_str());

          subscriptionResults =
        Vehicle::getContextSubscriptionResults(name.c_str());

          // Go through results (parse)
          std::string entity_id;
          for (auto e : subscriptionResults) {
            entity_id = e.first;
            //pt_LogDbg("- Ego ctx subscr result type '%s'",
        entity_id.c_str());

            auto res = e.second;
            for (auto r : res) {
              //pt_LogDbg("  - subscr result var 0x%x value '%s''",
        r.first, r.second->getString().c_str());
              switch (r.first) {
                case libsumo::VAR_ANGLE:
                  vehicle->angle = ParseDouble(r.second->getString());
                  break;
                case libsumo::VAR_POSITION3D:/
        /     // Convert string to Vector3-like struct
        ParsePosition(r.second->getString(), vehicle->position);
                  break;
                case libsumo::VAR_TYPE:
                  //pt_LogDbg("VAR_TYPE='%s'",
        r.second->getString().c_str());
                  vehicle->type_sumo = r.second->getString();/
        /    break;/
        /  //////////////// etc
                default:
                  pt_LogWarn("Var 0x%x is not parsed; fix the
        source", r.first);
                  break;
              }
            }
          }
        /

        Hope that helps,
        Ruud



        On Mon, Dec 4, 2023 at 11:35 PM T Eenachtacht via sumo-user
        <[email protected]> wrote:

            Dear All,


            Does anyone have experience, or can send a link to
            documentation, on how to process results from a
            subscription in C++ using libtraci? I need to convert
            the following from Python into C++. The subscription is
            for multiple types of variables. (not only
            VAR_ARRIVED_VEHICLES_IDS).

            In Python the implementation is rather straightforward
            with the documentation (e.g. in
            https://sumo.dlr.de/docs/TraCI/Interfacing_TraCI_from_Python.html).


                results = traci.simulation.getSubscriptionResults()

                forvehicle_id inresults[tc.VAR_ARRIVED_VEHICLES_IDS]:

                # process vehicle_id

            This can be converted to C++ like this:

            libsumo::TraCIResultsresults =
            libtraci::Simulation::getSubscriptionResults();

            //std::map<int, std::shared_ptr<libsumo::TraCIResult> >
            libsumo::TraCIResults

            for(autoentry : results) {

            inti = entry.first;

            shared_ptr<libsumo::TraCIResult> result = entry.second;

            How can the TraCIResults be filtered for '
            libsumo::VAR_ARRIVED_VEHICLES_ID' values, and

            how to get the id values from the result?

            Thanks for the help,

            Bart Netten

            _______________________________________________
            sumo-user mailing list
            [email protected]
            To unsubscribe from this list, visit
            https://www.eclipse.org/mailman/listinfo/sumo-user
_______________________________________________
sumo-user mailing list
[email protected]
To unsubscribe from this list, visit 
https://www.eclipse.org/mailman/listinfo/sumo-user

Reply via email to