[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [sumo-user] getSubscriptionResults in libtraci / C++
|
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
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
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_IDS Instead 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
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()
for vehicle_id in results[tc.VAR_ARRIVED_VEHICLES_IDS]:
# process vehicle_id
This can be converted to C++ like this:
libsumo::TraCIResults results = libtraci::Simulation::getSubscriptionResults();
//std::map<int, std::shared_ptr<libsumo::TraCIResult> > libsumo::TraCIResults
for (auto entry : results) {
int i = 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
sumo-user@xxxxxxxxxxx
To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/sumo-user