Generate maps with OpenStreetMap

OpenStreetMap is an open license map of the world developed by contributors. Sections of these map can be exported to a .osm file, the OpenSreetMap format, which is essentially an XML. CARLA can convert this file to OpenDRIVE format and ingest it as any other OpenDRIVE map using the OpenDRIVE Standalone Mode. The process is quite straightforward.


1- Obtain a map with OpenStreetMap

The first thing to do is use OpenStreetMap to generate the file containing the map information.

1.1. Go to openstreetmap.org. If the map is not properly visualized, try changing the layer in the righ pannel.

1.2 Search for a desired location and zoom in to a specific area. openstreetmap_view

Warning

Due to the Unreal Engine limitations, CARLA can ingest maps of a limited size (large cities like Paris push the limits of the engine). Additionally, the bigger the map, the longer the conversion to OpenDRIVE will take.

1.3.Click on Export in the upper left side of the window. The Export pannel will open.

1.4. Click on Manually select a different area in the Export pannel.

1.5. Select a custom area by dragging the corners of the square area in the viewport.

1.6. Click the Export button in the Export pannel, and save the map information of the selected area as a .osm file.

openstreetmap_area


2- Convert to OpenDRIVE format

CARLA can read a the content in the .osm file generated with OpenStreetMap, and convert it to OpenDRIVE format so that it can be ingested as a CARLA map. This can be done using the following classes in the PythonAPI.

  • carla.Osm2Odr – The class that does the conversion. It takes the content of the .osm parsed as strind, and returns a string containing the resulting .xodr.
    • osm_file — The content of the initial .osm file parsed as string.
    • settings — A carla.Osm2OdrSettings object containing the settings to parameterize the conversion.
  • carla.Osm2OdrSettings – Helper class that contains different parameters used during the conversion.
    • use_offsets (default False) — Determines whereas the map should be generated with an offset, thus moving the origin from the center according to that offset.
    • offset_x (default 0.0) — Offset in the X axis.
    • offset_y (default 0.0) — Offset in the Y axis.
    • default_lane_width (default 4.0) — Determines the width that lanes should have in the resulting XODR file.
    • elevation_layer_height (default 0.0) — Determines the height separating elements in different layers, used for overlapping elements. Read more on layers.

The input and output of the conversion are not the .osm and .xodr files itself, but their content. For said reason, the code should be similar to the following.

# Read the .osm data
f = open("path/to/osm/file", 'r')
osm_data = f.read()
f.close()

# Define the desired settings. In this case, default values.
settings = carla.Osm2OdrSettings()
# Convert to .xodr
xodr_data = carla.Osm2Odr.convert(osm_data, settings)

# save opendrive file
f = open("path/to/output/file", 'w')
f.write(xodr_data)
f.close()

The resulting file contains the road information in OpenDRIVE format.


3- Import into CARLA

Finally, the OpenDRIVE file can be easily ingested in CARLA using the OpenDRIVE Standalone Mode.

a) Using your own script — Call for client.generate_opendrive_world() through the API. This will generate the new map, and block the simulation until it is ready.
Use the carla.OpendriveGenerationParameters class to set the parameterization of the mesh generation.

vertex_distance = 2.0  # in meters
max_road_length = 500.0 # in meters
wall_height = 0.0      # in meters
extra_width = 0.6      # in meters
world = client.generate_opendrive_world(
    xodr_xml, carla.OpendriveGenerationParameters(
        vertex_distance=vertex_distance,
        max_road_length=max_road_length,
        wall_height=wall_height,
        additional_width=extra_width,
        smooth_junctions=True,
        enable_mesh_visibility=True))

Note

wall_height = 0.0 is strongly recommended. OpenStreetMap defines lanes in opposing directions as different roads. If walls are generated, this result in wall overlapping and undesired collisions.

b) Using config.py — The script can load an OpenStreetMap file directly into CARLA using a new argument.

python3 config.py --osm-file=/path/to/OSM/file

Important

client.generate_opendrive_world() requires the content of the OpenDRIVE file parsed as string, and allows parameterization. On the contrary, config.py script needs the path to the .xodr file and always uses default parameters.

Either way, the map should be ingested automatically in CARLA and the result should be similar to this. opendrive_meshissue

Outcome of the CARLA map generation using OpenStreetMap.

Warning

The roads generated end abruptly in the borders of the map. This will cause the TM to crash when vehicles are not able to find the next waypoint. To avoid this, the OSM mode is set to True by default (set_osm_mode()). This will show a warning, and destroy vehicles when necessary.


That is all there is to know about how to use OpenStreetMap to generate CARLA maps.

For issues and doubts related with this topic can be posted in the CARLA forum.