Driving skill : agents not moving ?

203 views
Skip to first unread message

Thomas Elskens

unread,
Mar 29, 2014, 1:31:56 PM3/29/14
to gama-p...@googlegroups.com
Hello,

In my simulation I've truck-agents which should deliver goods to retailers on a road-network. To achieve this, I've use the driving-skill, but the agents are not moving on the map when the simulation is launched. 
My code is as follows :

species truck skills: [driving]
{
gene route ; 
point boss ; 
int          charge ;
point destination ;
retailer       client ;
bool          finished <- false ;
action initialization(gene g, point loc_carrier)
{
write 'Initialisation of ' + self ;
route <- g ;
charge <- route.loadfactor ;
boss <- loc_carrier ;
location <- boss ;
destination <- next_destination() ; 
}
point next_destination
{
client <- route.pop_client() ;
if (client != nil)
{
return client.location ;
}
else
{
finished <- true ;
return boss ;
}
}
reflex truck_moving
{
do goto target: destination on: le_graphe speed: (100  °km / °h);
write 'Truck moving : ' + self + ' with speed : ' + speed;
if (finished and location = boss)
{
do die ;
}
else if (location = destination) 
{
ask client
{
ordering <- false ;
stock <- stock + quantity_to_deliver ;
myself.charge <- myself.charge - quantity_to_deliver ;
quantity_to_deliver <- 0 ;
}
destination <- next_destination();
}
}

Besides the fact that the trucks do not move, there are two other abnormalities :

  • In the console, the message "truck moving" appears, although this write-instruction comes after the goto statement. 
  • The effect is the same with or without speed specification. Moreover, the console always prints "speed : 1.0", regardless of the actual speed coded (I've tried from 50 up to 500  °km / °h). 

The entire code can be found in the attachment. 

Thanks a lot in advance !

Thomas Elskens

P.S.

In another post, I've read I should replace the driving_skill_plugin by a more recent version, but I've checked and the most recent is already present in my plugin map: simtools.gaml.extensions.traffic_1.0.0.201310060252.jar


PULSE.zip

Srirama Bhamidipati

unread,
Mar 30, 2014, 2:33:02 AM3/30/14
to
For live speed, I was once advised to use 

path_followed.shape.perimeter / step 

of course with step you have to be careful on units of speed in accordance with units of length

sriram

Thomas Elskens

unread,
Mar 31, 2014, 3:33:00 AM3/31/14
to gama-p...@googlegroups.com

When I try the statement :
path path_followed <- self goto [target::destination, on::le_graphe, return_path:: true, speed:: (path_followed.perimeter / step)];
the Gaml-interpretator notifies that the variable path_followed is not defined or accessible in this context. This seems not too surprising, as I'm using it (to determine the speed) even before it has been initialized ? Or am I missing something ? 

But asides the problem of finding an simulationrelevant value for speed, when I do not mention a value for it, the agents still do not move, even though this facet is, according to the manuel, optional ? 

Thomas

Thomas Elskens

unread,
Mar 31, 2014, 5:26:34 AM3/31/14
to gama-p...@googlegroups.com

By the way, I've just tested this a bit more thoroughly and contrary to what the manual states (data type "path" inherits from all operators and attributes of datatype "geometry"), GAMA accepts neither path_name.perimeter (intercepted by the interpretor) nor path_name.shape.perimeter (raises a nullpointerexception at runtime). 

The only way of accessing the perimeter-property, as shown in the tutorials, seems to be by looping over all segments of the path, unless I've missed one or another subtility ? 

Thomas

Srirama Bhamidipati

unread,
Mar 31, 2014, 6:08:56 AM3/31/14
to gama-p...@googlegroups.com
two things from my little knowledge of GAMA:

I think destination is a keyword and should not be used in the model.

And path should be in reflex of each agent.

Patrick Taillandier

unread,
Mar 31, 2014, 6:24:47 AM3/31/14
to gama-p...@googlegroups.com
Hi,

You are right, a path is not a geometry. I have corrected the doc. If you need to get the geometry of a path, you have to write : my_path.shape

Concerning your problem, I think it comes from the fact that your roads are not cut at their intersection: as they are not cut, GAMA will not built a node at the intersection of two roads. 

Cheers,

Patrick


--
You received this message because you are subscribed to the Google Groups "GAMA" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gama-platfor...@googlegroups.com.
To post to this group, send email to gama-p...@googlegroups.com.
Visit this group at http://groups.google.com/group/gama-platform.
For more options, visit https://groups.google.com/d/optout.

Thomas Elskens

unread,
Mar 31, 2014, 7:08:46 AM3/31/14
to gama-p...@googlegroups.com
Hello,

I'm not sure I quite rightly understand your answer. When I analyse my roadshapefile with QGIS 2.2 (tool "analyse intersections at lines"), this software finds more than 24.300 intersection points (cf. the result of this analysis in attachment). 

This isn't enough ? Or am I misunderstanding your point ? 

Thomas
Intersections.zip

Patrick Taillandier

unread,
Mar 31, 2014, 11:31:25 AM3/31/14
to gama-p...@googlegroups.com
Just after inspection of your model; there is a small error: you use the variable "destination" that is a built-in non writable variable, thus you cannot change its value. First thing to do, change the name of this variable.

Concerning the speed of the agent and the map of weight, you should use something like:

map<road,float> weights_map <- road as_map(each::(each.shape.perimeter * step / each.max_speed)) ;


do goto target: dest on: le_graphe; //speed = 1


At last, you road shape file seems weird, I computed on the graph built by GAMA the number of connected component and I got: 5472.... not a surprise to do not find a shortest path with this graph.

Cheers,

Patrick

Thomas Elskens

unread,
Mar 31, 2014, 3:20:22 PM3/31/14
to gama-p...@googlegroups.com
Hello,

Ok I'll check and simplify the shapefile : it's too big anyhow. Could you just tell me how to compute the number of connected components via GAMA ? Then I could compare with the number obtained via QGIS...

Thanks in advance,

Thomas

Patrick Taillandier

unread,
Mar 31, 2014, 8:33:58 PM3/31/14
to gama-p...@googlegroups.com
Hi,

Unfortunately, the operator (coming from the jgrapht lib) that allows to compute the connected components of a graph is not available in GAMA 1.6 but will in the forthcoming 1.6.1 version.

Cheers,

Patrick

Thomas Elskens

unread,
Apr 5, 2014, 11:49:38 AM4/5/14
to gama-p...@googlegroups.com
Hello,

I followed your advice and finally, the trucks are moving ! That's already much better and even though I did not simplify the graph yet, the trucks behave in a very plausible manner : for instance, when they have to cross the citycenter of Brussels, they very nicely take the ring, where the maximum_speed is much higher  than in the city center. 

Unfortunately, I've still trouble setting a realistic speed for the trucks with respect to the distances they have to go : I've defined step as 30 °minutes, so I would expect the trucks to be able to cross the entire environment (which is only Belgium) in 2 to 5 steps. Now, even when initializing the speed of the trucks at 120 °km / °h, the trucks are quite slow : they seem to need more than 10 steps. 

So my question is: how can I fasten things up without having to define irrealistic values in the model ?

Thanks so much for your help,

Thomas Elskens

Patrick Taillandier

unread,
Apr 5, 2014, 12:29:32 PM4/5/14
to gama-p...@googlegroups.com
Hi,

Just some questions to give me a better idea of your model:
 - did you define a specific speed limit per road?
 - do trucks have a constant speed? do they all drive at the same speed?
 - if they do not have a constant speed: 
      -  is their speed the speed limit of each road (or something like alpha * limit_speed_road with alpha a constant)? 
      -  something else?

Note that with GAMA 1.6.1, a new traffic skill will be available. This traffic skill allows realist simulations of traffic but is more adapted to 1 second/per step simulation : http://agents.fel.cvut.cz/att2014/att2014_paper_3.pdf


Cheers,

Patrick


--

Srirama Bhamidipati

unread,
Apr 5, 2014, 2:40:18 PM4/5/14
to gama-p...@googlegroups.com
You could also play around with edge weights when defining your graph. 

Thomas Elskens

unread,
Apr 6, 2014, 6:34:19 AM4/6/14
to gama-p...@googlegroups.com
Hello,

See below (answers in blue). 

Thanks,

Thomas Elskens


Le samedi 5 avril 2014 18:29:32 UTC+2, Patrick Taillandier a écrit :
Hi,

Just some questions to give me a better idea of your model:
 - did you define a specific speed limit per road?
Yes I did : Each road is initialized with one of the four following speeds : 50, 70, 90, 120 °km / °h. These speeds are then incorporated in the weights_map of the graph as follows :
set le_graphe      <- (as_edge_graph(list(road))) ;
map<road,float> weights_map <- road as_map(each::(each.shape.perimeter * step / each.max_speed)) ;
set le_graphe      <- le_graphe with_weights weights_map ; 
 - do trucks have a constant speed? do they all drive at the same speed?
They do : they are alle initialized with speed 120 °km / °h. Nothing in code alters this predefined speed. 
 - if they do not have a constant speed: 
      -  is their speed the speed limit of each road (or something like alpha * limit_speed_road with alpha a constant)? 
I did try something in that sense :  
do goto target: mytarget on: le_graphe speed: ((road overlapping self) max_of each.max_speed);
but that code gave me runtime errors ("the container is empty"). 
      -  something else?

Note that with GAMA 1.6.1, a new traffic skill will be available. This traffic skill allows realist simulations of traffic but is more adapted to 1 second/per step simulation : http://agents.fel.cvut.cz/att2014/att2014_paper_3.pdf

Sounds very promising. However, the simulation I have to code should eventually cover 1 to 3 months (to be performed in batch of course, not in GUI) to simulate order behaviour of retailers, so 1 second a step is a bit too microscopical...    

Thanks for your time,

Thomas Elskens

Patrick Taillandier

unread,
Apr 6, 2014, 8:33:25 AM4/6/14
to gama-p...@googlegroups.com
Hi,

In this case, the simplest in to integrate in the weights of the graph edges all the information concerning the max_speed on the road and the step.

For instance: 
if you have defined a step like this:

float step <- 30°mn;


You can initialize the road_graph like this: 

map weights <- road as_map (each::(each.shape.perimeter / (each.maxspeed °km/°h) /step));

road_graph <- as_edge_graph(road) with_weights weights;

Then, you can write for the trucks:

do goto target: target on: road_graph speed: 1.0;


In this case, the trucks will always respect the speed limit. 

See the attached model
Cheers,

Patrick
example moving.zip

Thomas Elskens

unread,
Apr 7, 2014, 8:23:01 AM4/7/14
to gama-p...@googlegroups.com

Okay, I slightly modified the proposed solution 
  • by adding "°minutes" in the initialization of the weights: 
map<road,float> weights <- road as_map (each::(each.shape.perimeter / (each.max_speed °km/°h) / (step °minutes)));
  • and by removing "speed=1.0" in the goto action of the trucks. 
And this way the trucks seem to adopt the expected behaviour (I should do some thorough tests of course, but at least the trucks arrive at destination, change destination, and "die" in the end, as they are supposed to do). Otherwise, they won't move. 

This is very nice and a real progress, but it leaves me with two questions :  
  1. I do not understand why it is necessary to add the units again : GAMA doesn't convert them to float-value while the variables they're used in, are initialised... ?
  2. According to the documentation, "In a localized graph, an edge has a weight by default (the distance between both vertices)". Should I understand that
    • this distance is the same as the perimeter of the shape of the road ? 
    • this distance is expressed in meters ? 
Anyhow, thanks a lot for your help ! The debugging can go on :)

Thomas Elskens 

Patrick Taillandier

unread,
Apr 7, 2014, 9:06:12 AM4/7/14
to gama-p...@googlegroups.com
  1. I do not understand why it is necessary to add the units again : GAMA doesn't convert them to float-value while the variables they're used in, are initialised... ?
In GAMA the default unit (if you do not precise an unit) is the meter for distance and second for the time. Thus, here I just tell GAMA that the maxspeed value are expressed in km/h (as I used OSM data where the max speed of roads are expressed in this unit) to let him make the conversion.
  1. According to the documentation, "In a localized graph, an edge has a weight by default (the distance between both vertices)". Should I understand that
    • this distance is the same as the perimeter of the shape of the road ? 
    • this distance is expressed in meters ? 
When you use the "ad_edge_graph" operator, by default the weight of each edge is the perimeter (in meter) of the shape of the road.

Thomas Elskens

unread,
Apr 13, 2014, 6:37:57 PM4/13/14
to gama-p...@googlegroups.com
Hello,

It's me, again :-( First the good news : I've filtered some bugs and I found better data for my shapefiles. The trucks adopt very reasonable behaviour now, and the performance of the model has become quite impressive (admittedly, the number of road segments has been reduced to less than 3000 agents). 

But there's is still a bit of a weird problem that remains : the trucks seem to "jump" between their departure-point (in the example csv-file, in Luxembourg) and their arrivalpoints (customers, always in the Brussels region). 

This "jumping" is not only graphical, but also confirmed by the data saved in a csv-file, as if it were possible to go from Luxembourg to Brussels in 30 minutes (value of a step). 

Once more, I think the weights of my graph still aren't calibrated correctly, but I don't know how to fix it. 

Last tries have been :
    1. map<road,float> weights_map <- road as_map(each::(each.shape.perimeter * step / each.max_speed)) ; 
      • Effect : trucks advance horribly slowly. 
    1. map<road,float> weights_map <- road as_map(each::(each.shape.perimeter / (each.max_speed °km / °h) / (step °minutes)));
      • Effect :  aforementioned "jumping" behaviour.
    2. map<road,float> weights_map <- road as_map(each::(each.shape.perimeter / each.max_speed / step ));
      • Effect : the same as 2
    I never touch the default value of speed (neither as a facet, nor in the goto-action), because when doing this, results become very bad. 

    Could there be other options than the weights or the speed ... ? 

    Thanks a lot,

    Thomas Elskens

    data.csv

    Srirama Bhamidipati

    unread,
    Apr 15, 2014, 4:21:32 AM4/15/14
    to
    1. If you say that the time taken by truck to reach destination is 1 step, that surely means that your weights are not being read or what is read by the interpreter is a zero value. 
    2. To make sense of weight: higher the each value ( in your case each.shape.perimeter * step / each.max_speed), slower they will move, and lower that value faster they move. in your case if vehicles are reaching in 1 step, the reason is as I indicate above.

    3. to get a right fix on weight, a simple logic will be = more speed causes less resistance. So the simplest you could try is to give each::(1.0/each.speed) 
    4. you could also use another simple logic = by using free flow travel time, more time is less speed. So you can try each::(each.free_flow_time) // where you calculate free_flow_time as perimeter_of_edge/speed_limit_of_edge)

    regards,
    Srirama

    Patrick Taillandier

    unread,
    Apr 15, 2014, 5:15:34 AM4/15/14
    to gama-p...@googlegroups.com
    Hi,

    The good weights, if you want to use the speed of the road is:
    map weights <- road as_map (each::(each.shape.perimeter / (each.maxspeed °km/°h) /step));

    In your case, a step is 30 minutes  (float step <- 30 °mn;), so it means that step = 1800
    now, if you use speed with unit in km/h (like me :) ), it means, for instance, that maxspeed = 50 km/h -> maxspeed  = 13.88889 

    thus, if your have a road of 50 km, with my formula, the weight will be: weight of this road: 50 000 / 13.8889 / 1800 = 2 
    If you keep the default value for the speed of your agent, it means its speed is 1.
    thus, in the first step, the agent is going to travel half of the road (25km, in 30 minutes) and during the second step, the second half.... so the agent is going to travel the 50km in 2 steps, so 1h.... so its speed is 50km/h :) .

    If it does not work with these values for the weights, it means that you have a problem with your model.

    Cheers,

    Patrick



    4. you could also use another simple logic = by using free flow travel time, more time is less speed. So you can try each::(each.free_flow_time) // where you calculate free_flow_time as perimeter/speed)

    regards,
    Srirama

    Srirama Bhamidipati

    unread,
    Apr 15, 2014, 5:38:16 AM4/15/14
    to gama-p...@googlegroups.com
    Yes, I thought as much so that the problem is units. To be on safe side, i would always have all the inputs in GAMA defaults, for example all values in m, sec, m/sec

    Thomas Elskens

    unread,
    Apr 15, 2014, 6:26:44 AM4/15/14
    to gama-p...@googlegroups.com

    Hello,

    Thank you both for explaining the exact meaning of the weights (and speed variable) : I think I see much clearer now in the logic of them. 

    I don't want to abuse of your time, but I would like to ask one more explanation about this matter, more in particular a little test I just performed:
    I used following weights :
    map<road,float> weights_map <- road as_map(each::(each.shape.perimeter * 1000) / each.max_speed / step );
    in order to obtain artificial high weights (in attachment) : there are now weights ranging from 5.7 up to 712,58, with a average value of 101,21
    I obtained the attachment by writing :
    loop p over: weights_map.pairs
    {
    float distance <- (p.key as road).shape.perimeter ;
    float speed <- (p.key as road).max_speed ;
    save [distance, speed, p.value] to: "graphweights.csv" type: "csv" ;

    The result is surprising : trucks (finally !) move correctly ? How can this be ?

    Thomas
    graphweights.csv

    Patrick Taillandier

    unread,
    Apr 15, 2014, 7:24:50 AM4/15/14
    to gama-p...@googlegroups.com
    Hi,

    It depends what you mean by "moving correctly". I mean, your hypothesis, is that your trucks move at a speed of max_speed / 1000.0 ... which is rather slow ;) . Even if you consider the traffic lights, traffic jams and so on, I think the real speed of a vehicle is closer to move  max_speed / 3 (in city center).

    if you consider that a simulation step is 30 minutes, moving "correctly" means travelling at least 10 km (except in city center where it can be less).

    By curiosity, can you send to me your model?

    Cheers,

    Patrick

    Thomas Elskens

    unread,
    Apr 15, 2014, 11:06:28 AM4/15/14
    to gama-p...@googlegroups.com

    Hello,

    Speed is between 30 to 50 °km / °h. The problem I see is that the weights (average of 100) attached to the roads should make it impossible for the trucks to move, but they don't use 100 steps to make a move... Or is there anything I did not get right in the explanation ... ?

    In attachment you can find the most recent version of the model. 

    Thomas Elskens
    PULSE.zip

    Patrick Taillandier

    unread,
    Apr 15, 2014, 1:50:55 PM4/15/14
    to gama-p...@googlegroups.com
    Hi,

    Ok, I think I see my error.... I work to much with traffic simulation with 1s simulation step :p .
    In the moving speed, the distance travelled by the agent is its speed multiplied by the step value, so you don't need to divide the weight of the roads by it.... 

    Thus, the weight map should be:
    map weights <- road as_map (each::(each.shape.perimeter / (each.maxspeed °km/°h) ));

    (in your case: map<road,float> weights_map <- road as_map(each::(each.shape.perimeter / each.max_speed ) );)

    Sorry ;) 

    Patrick

    Thomas Elskens

    unread,
    Apr 15, 2014, 2:18:51 PM4/15/14
    to gama-p...@googlegroups.com

    Thank you so very much, now it works very nicely, and moreover I even understand why (and how) it works !!!

    So when I divide the value of a weight by the value of my step (30 °minutes, i.e. 1800) i get the distance expressed in the number of cycles needed. 

    Once more, thank you very much for your time and patient explanations. I think some copy-paste of them would be a very good addendum to the manuel in order to explain in detail the relationships between the graphweights and the values for speed and step. The manuel, for the time being, is a bit laconic about this topic. 

    Thank you et merci beaucoup,

    Thomas
    Reply all
    Reply to author
    Forward
    0 new messages