ROS tools to work with OSM data.
This is a ROS package that parses a .gpx file with GPS coordinats into a python class, which is later serialized and saved as a .mapdata file.
The class uses OSM as a source of data and parses it into a few cathegories:
- barriers - obstacles that we assume to be untraversable
- footways - paths designed for humans
- roads - areas designed for vehicles
We also provide a ROS node that uses the parsed map data and publishes a point cloud of footways. This may be used as one of the inputs for path-planning nodes.
There are two .gpx files in the ./data/
directory that can be used to test the package.
The package was developed and tested on Ubuntu 20.04 with ROS Noetic. However, it should be fully compatible with ROS Melodic.
The script create_mapdata
is used to create a .mapdata file from a .gpx file or to parse a .mapdata file which was created earlier.
There are two flags that can be used:
-d
- this signals that no prior .mapdata file exists and the script should parse a .gpx file and download data from OSM-f
- this flags allows the user to either specify a .gpx file to parse or a .mapdata file to read from, depending on the-d
flag, the filename should be a second argument after the flag
In both cases the script will create a .mapdata file in the ./data/
directory and taking the .gpx file there as well. The name of the .mapdata file will be the same as the .gpx file.
The script can be run either with the rosrun
command or by running it as an executable.
Using rosrun
and creating a .mapdata file from a .gpx file:
rosrun map_data create_mapdata -d -f coords.gpx
This will create a coords.mapdata
file in the ./data/
directory, downloading and parsing data from OSM.
Running as an executable and parsing a .mapdata file:
./scripts/create_mapdata -f coords.mapdata
This will load the coords.mapdata
file from the ./data/
directory and parse it, saving it back to the same file.
The script visualize_mapdata
is used to visualize the parsed data from a .mapdata file. It will show two images, first one with all parsed data (barriers, footways and roads), while the second one will only containt the footways. There are multiple flags that can be used:
-f
- this flag is used to specify the .mapdata file to read from, it should be followed by the filename, and the file should be in the./data/
directory-sm
- this flag is used to specify if the first image should be saved, it may be followed by a-mf
flag and a filename to save the image to, if the-mf
flag is not used the image will be saved asmap.png
-sb
- this flag is used to specify if the background should be saved, it may be followed by a-bf
flag and a filename to save the image to, if the-bf
flag is not used the image will be saved asbgd_map.png
All saved images will be located in the ./data/
directory.
The script can be run either with the rosrun
command or by running it as an executable.
Using rosrun
and visualizing the parsed data:
rosrun map_data visualize_mapdata -f coords.mapdata
Running as an executable and visualizing the parsed data and saving the images:
./scripts/visualize_mapdata -f coords.mapdata -sm -sb
The script osm_cloud
is used to publish a point cloud of footways. The point cloud is published as a sensor_msgs/PointCloud2
message on the /osm_cloud
topic. The point cloud is published on the grid
topic.
The script takes several parameters from the ROS parameter server:
~utm_frame
- the UTM frame of the map data, default isutm
~local_frame
- the local frame of the robot, default ismap
~utm_to_local
- the transformation from UTM to local frame, if set as an empty list the script will lookup for the transformation, default isNone
~mapdata_file
- absolute path for the .mapdata file to read from, default isNone
~gpx_file
- absolute path for the .gpx file to read from, the script will create and parse mapdata, if the .mapdata file is not provided, default isNone
~save_mapdata
- if set totrue
the script will save the parsed mapdata from the .gpx file, if the .mapdata file is not provided, default isfalse
~max_path_dist
- the maximum distance a point in the grid can be from a footway, default is1.0
~neighbor_cost
- in what way to calculate the cost - linear or quadratic or zero, default islinear
~grid_res
- the resolution of the grid, default is0.25
~grid_max
- the maximal value of the grid, default is[250, 250]
~grid_min
- the minimal value of the grid, default is[-250, -250]
The script can be run either with the rosrun
command or by running it as an executable. However we would recommend launching it with a provided launch file. The launch file will set the parameters for the script and launch the node. With the launch file you can also change the topic on which the point cloud is published. The launch file is located in the ./launch/
directory. The launch file has three arguments:
mapdata_file
- the absolute path for the .mapdata file to read fromgpx_file
- the absolute path for the .gpx file to read fromgrid_topic
- the topic on which the point cloud is published
Using rosrun
and publishing a point cloud of footways:
rosrun map_data osm_cloud
Using a launch file and publishing a point cloud of footways:
roslaunch map_data osm_cloud.launch mapdata_file:=/path/to/coords.mapdata grid_topic:=/osm_cloud
You can import the python classes from the map_data
package. The classes are located in the ./src/map_data/
directory.
To import the map_data
package you need to have it in your package.xml
and CMakeLists.txt
files (when working in ROS) or in your PYTHONPATH
(when working in a python environment).
The package contains the following files:
background_map.py
- file containing the functions to create a background map for the visualizationmap_data.py
- contains the main classMapData
that parses the .gpx file and creates a .mapdata filepoints_to_graph_points.py
- file containing the functions to convert points to lines of equidistant pointsvis_utils.py
- file that contains functions to visualize the parsed dataway.py
- file containing theWay
class that codes our representation of a way from OSM
To import the MapData
class you can use the following code:
from map_data.map_data import MapData
To plot the parsed data you can use the following code:
import pickle
from map_data.vis_utils import plot_map
file_name = "coords.mapdata"
with open(file_name, "rb") as fh:
map_data = pickle.load(fh)
plot_map(map_data)