The attached patch adds offline path computation capabilities to wavefront, i.e. allows one to calculate waypoints for a path without executing it and without affecting the path wavefront is currently following. Besides, it calculates the total path length both for offline computed paths and for the current path. (Both features were listed as TODOs in wavefront.cc for a long time already, and I needed them for optimal tour planning.)
The patch is based on work from a fellow student, Paul Neugebauer, who kindly permitted me to submit it.
To realize this, the planner interface is extended by a new request GET_OFFLINE_WAYPOINTS and a corresponding struct player_planner_offline_waypoints_req containing a start pose, goal pose, total path length, number of waypoints and the actual waypoints. The existing player_planner_waypoints_req is extended by a total path length field as well.
Wavefront, the only driver providing the planner interface, is extended as follows: The Wavefront class gets a new member offline_plan for calculating paths independent of the current plan. offline_plan is created as a copy of the current planner (to avoid the costly recomputation of the C-Space map) when a GET_OFFLINE_WAYPOINTS request comes in and it has not been created yet. When the map (and thus the normal planner) changes, offline_plan is deleted so it will be recreated as a new copy of the updated plan when needed. This way the new feature does not incur any overhead when it is not used, and the overhead of the second planner is kept to a minimum. Both for GET_OFFLINE_WAYPOINTS and GET_WAYPOINTS requests, wavefront calculates the total path length as the sum of euclidean distances between the waypoints on-the-fly while copying the waypoints to the response struct.
As a bonus, the patch removes the two TODOs from wavefront.cc :)
Alternatives: player_planner_waypoints_req already contains everything one needs as a response to a GET_OFFLINE_WAYPOINTS request, so it seems it would make sense to reuse it for that purpose. However, the way libplayerc is implemented, the response must use the same struct type as the request. One could change client_libs/libplayerc/client.c accordingly to allow different struct types for request and reply, or one could use the player_planner_waypoints_req to also convey the request (by setting start and goal as two waypoints in the struct), but I think the chosen solution is the lesser evil.
Shortcomings: wavefront has a force_map_refresh setting which fetches a new map and updates the planner whenever a new goal comes in. For offline path computation requests, the force_map_refresh setting is currently ignored. (The offline planner will be updated whenever the main planner got updated, but it never gets updated on its own.)
The patch is against Player-3.1.0-svn revision 8914.