grass
grass copied to clipboard
[Feat] New walking speed algorithm for r.walk
R.walk uses Langmuir's walking speed algorithm to calculate walking speeds. Langmuir's algorithm is essentially a souped-up version of Naismith's rule, an approximate heuristic developed in the late 19th century. Recent empirical work has returned more accurate walking speed algorithms based on actual data collected under experimental conditions.
This newer work tends to return significantly different speed values from Langmuir's algorithm, and to a lesser extent the popular Tobler's algorithm, particularly at moderate slopes. This would naturally lead to significantly different costs being generated by r.walk, particularly in areas where walking is a primary modality. See Figures 4 - 10 in the below linked article for a graphical illustration of this.
I would like to suggest that the GRASS team incorporate one of the newer, empirical walking speed algorithms as r.walk's default. I am most familiar with that developed by Irmischer and Clarke (2018, https://www.tandfonline.com/doi/abs/10.1080/15230406.2017.1292150) and would advocate for it.
I am open to other possibilities, though I'm only aware of similarly empirical work from Marquéz-Pérez (2017, https://www.tandfonline.com/doi/full/10.1080/00167223.2017.1316212?src=recsys). Pingel (2013, https://www.tandfonline.com/doi/abs/10.1559/152304010791232163?src=recsys) also convincingly argues that humans perceive slopes to be more costly than they are and route accordingly -- but I'm not sure how to integrate that in with the above algorithms.
Would you be willing to create a PR to change the default values and perhaps update the documentation? Or are you referring to a change in the algorithm itself?
Hi @petrasovaa -- I'm referring to a change in the algorithm itself.
This feature request came out of some discussions with @mlennert who said this should be doable and requested I open an issue here.
As the link to the Irmischer and Clark article points to a closed-access version, here's a link to a pre-publish, proof version: https://escholarship.org/content/qt9m37m9hw/qt9m37m9hw.pdf?t=p430ey.
The main elements are these formulas:
with 2 + 3 being for on-road, and 4+5 for off-road, with 3 + 5 for females. It might be enough to implement 2 + 4 as alternative formulas of the effect of slope on speed and then add a general speed modulation parameter which could be set to whatever value to multiply the speed by.
One issue with this is obviously that we cannot implement every formula that someone finds empirically based on some sample of people. However, I would imagine that most would find results that generally fit this curve with slight changes in the coefficients. So maybe it might be possible to implement a generic Gaussian formula with the coefficients as parameters to the module.
@metzm: You're the last one to work intensively on this module, what do you think ?
IIUC, in order to implement the proposed alternative algorithm, 'all' that needs to be done is to replace the 'fcost_dtm + (DIAG_fac * a)' part of the cost calculations in the respective calls such as
pres_cell->min_cost + fcost_dtm + (DIAG_fac * a) +
lambda * fcost_cost * DIAG_fac;
with the Gaussian formula rewritten as cost, not speed, to give something like this:
pres_cell->min_cost + Gaussian cost +
lambda * fcost_cost * DIAG_fac;
where Gaussian cost uses the direction dependant slope check_dtm calculated earlier such as:
check_dtm = (NW_dtm - my_dtm) / DIAG_fac;
Thanks for digging up an open access version @mlennert. I like the proposed adoption of 2 + 4 with a general speed modulation parameter: this opens the door for modulation based not just on sex, but on age, disability status, encumbrance, or whatever other influence needs to be modeled.
Agreed that we cannot implement just any formula and that a generic Gaussian formula helps us manage this. Happy to help on this further if need be, let me know.
Thinking about this a bit more, maybe the best option would be to first implement this in a separate (add-on) module r.walk.gaussian. r.walk already has a long list of parameters linked to the current formula and if we add parameters for a generic gaussian formula this might lead to parameter inflation.
Thinking about this a bit more, maybe the best option would be to first implement this in a separate (add-on) module r.walk.gaussian. r.walk already has a long list of parameters linked to the current formula and if we add parameters for a generic gaussian formula this might lead to parameter inflation.
Worse than parameter inflation is module inflation. We already have several modules that rise questions how they differ, why there is duplication of functionality etc.
On 17/01/22 19:27, Māris Nartišs wrote:
Thinking about this a bit more, maybe the best option would be to first implement this in a separate (add-on) module r.walk.gaussian. r.walk already has a long list of parameters linked to the current formula and if we add parameters for a generic gaussian formula this might lead to parameter inflation.
Worse than parameter inflation is module inflation. We already have several modules that rise questions how they differ, why there is duplication of functionality etc.
I hear you. When I find the time, I'll prepare a PR for all in one module and we can decide based on that.
Worse than parameter inflation is module inflation. We already have several modules that rise questions how they differ, why there is duplication of functionality etc.
Maybe the important point is the name which needs to make the distinction clear. r.walk, r.walk.gaussian, r.walk.langmuir? Notably, QGIS tends to split modules with a lot of parameters into more pseudo-modules - GRASS plugin has/had r.slope, r.aspect, and 4 g.region modules. I would say that this often makes sense. We have r.grow.distance and then more specialized r.grow. Maybe, we should be using it all. I'm for adding it to r.walk and then creating one or two additional wrapper modules if needed.
According to @mlennert, the changes required to implement formulas 2 + 4 are not too invasive. Therefore I would opt to add them to r.walk
and not to create a new module. The reason is to avoid code duplication.
I am also not happy with yet more parameters to the module. It is a compromise between code duplication, keeping the code base simple and keeping the user interface simple. In this case I prefer to avoid code duplication. It is already complicated enough to keep r.cost
and r.walk
in sync.