Skip to content

The Autoware Map Loader

Between your Lanelet2 file and the autonomy stack sits a piece of software that does not negotiate: the map loader. It reads the OSM XML, projects every coordinate into the robot’s local frame, and publishes a binary map the rest of the stack consumes. If it does not get what it expects, the map never reaches the robot.

13 min read

You have a Lanelet2 file. It is correct, validated, and stored on disk. That file is not yet a map the robot can use. Between the .osm file and the autonomy stack sits a piece of software that does not negotiate: the Autoware map loader. It reads the OSM XML, projects every coordinate into the robot’s local frame, and publishes a binary message that the rest of the stack consumes. If the loader does not get what it expects, the map never reaches the robot. Or worse, it reaches the robot incomplete, and the driving errors surface later, in a different module, with a different error message, where nobody thinks to check the loader.

This chapter opens the loader and watches what it does.

The map package

Before the loader runs, your map must be laid out the way Autoware expects. The loader does not search. It reads from the path you give it and assumes the files it finds there are complete and correctly projected.

A minimal Autoware map package contains two files:

harbor_yard/
├── lanelet2_map.osm
└── pointcloud_map.pcd

The Lanelet2 map and the pointcloud map share a directory because they share a coordinate frame. The loader does not enforce this. It is a convention, and violating it means you must manage two separate projector info configurations that must agree. Nobody does this twice.

For larger sites, the pointcloud map is split into tiles and the directory gains a metadata file:

harbor_yard/
├── lanelet2_map.osm
├── pointcloud_map/
│   ├── A.pcd
│   ├── B.pcd
│   ├── C.pcd
│   └── ...
├── map_projector_info.yaml
└── pointcloud_map_metadata.yaml

When the Lanelet2 map is also split for differential loading, it mirrors the same grid:

harbor_yard/
├── pointcloud_map/
│   ├── A.pcd
│   ├── B.pcd
│   └── ...
├── lanelet2_map/
│   ├── A.osm
│   ├── B.osm
│   ├── C.osm
│   └── ...
├── map_projector_info.yaml
├── lanelet2_map_metadata.yaml
└── pointcloud_map_metadata.yaml

For Harbor Yard, a single .osm file and a single .pcd file are sufficient. The site is small enough that differential loading buys nothing. The rest of this chapter assumes the single-file layout, but everything it says about parsing, projection, and extraction applies identically to the tiled case.

Invoking the loader

The loader is a ROS 2 node in the autoware_map_loader package. To load a single Lanelet2 map:

ros2 run autoware_map_loader lanelet2_map_loader \
  --ros-args -p lanelet2_map_path:=path/to/harbor_yard/lanelet2_map.osm

That is the entire invocation. The loader reads the file, waits for projection info, and publishes. If it does not publish, one of three things is missing: the file path is wrong, the projection info has not arrived, or the file contains something the parser cannot recover from. The next three sections cover each case.

What the loader does with your file

The loader’s pipeline has four stages, and it runs them in order.

1. Parse the OSM XML

The loader opens the .osm file and hands it to the Lanelet2 library’s parser. Lanelet2 maps are stored as OSM XML, the same format OpenStreetMap uses. The parser reads every <node>, <way>, and <relation> element and builds the internal Lanelet2 data structures: points, linestrings, lanelets, areas, and regulatory elements.

The parser is lenient. It parses what it understands and skips what it does not. A <tag> with an unrecognized key is ignored. A <relation> that references a missing <way> produces an orphaned regulatory element. The parser does not validate. It extracts.

2. Apply the projection

Every point in the Lanelet2 file is stored with geographic coordinates: latitude, longitude, and altitude. Autoware does not operate in lat/lon. It operates in a local Cartesian frame where X points east, Y points north, and Z points up.

The loader does not compute the projection itself. It subscribes to ~input/map_projector_info, a topic published by map_projection_loader, a separate node that must run before the map loader starts. The projector info carries the projection type (typically MGRS or a local transverse Mercator) and the parameters that define the transformation. The loader takes those parameters and applies them to every point in the map.

If the projector info has not arrived when the loader starts, the loader waits. If it never arrives, the loader fails with a timeout. If it arrives with the wrong projection, the map loads in the wrong place. A hundred-meter offset, a rotation, a slight tilt: these are all projection errors, and they all happen here, before the robot has taken a single measurement.

The projection is the most consequential step in the entire loading pipeline. Every centimeter of accuracy you achieved during capture and alignment passes through this single transformation. If the projection parameters do not match the projection the survey data was collected in, your map will be internally consistent and globally wrong.

3. Resample the centerlines

The parser extracts each lanelet’s centerline as a continuous sequence of points. The planner does not want a continuous centerline with arbitrary vertex density. It wants waypoints: a sequence of discrete poses the vehicle will visit in order.

The use_waypoints parameter controls how the loader handles this. When set to true (the default), the loader takes each lanelet’s centerline tag and overwrites it with the waypoints tag, if one exists. When set to false, the centerline is passed through as-is.

The center_line_resolution parameter (default 5.0 meters) controls how densely the loader resamples the centerline. If your lanelet is shorter than the resolution, the resampled centerline collapses to a single point. The planner needs at least two points to define a direction of travel. For Harbor Yard, where the dock approach lanelet is about 4 meters, the resolution must be set lower or the centerline must carry explicit waypoints.

4. Publish

The loader publishes the parsed, projected, and resampled map as an autoware_map_msgs/LaneletMapBin message on ~output/lanelet2_map. Every downstream module that needs the map subscribes to this topic or consumes the data indirectly through other nodes that do.

The full set of parameters the loader accepts:

Parameter Type Default What it does
lanelet2_map_path string (required) Path to the .osm file or directory of split files
center_line_resolution float 5.0 Spacing in meters between resampled centerline points
use_waypoints boolean true Use the waypoints tag as the lanelet centerline
allow_unsupported_version boolean true Load maps with unrecognized format_version tags
enable_differential_map_loading boolean false Enable tiled loading for large maps
lanelet2_map_metadata_path string (none) Path to metadata YAML for differential loading

What the loader extracts

When the parser finishes, five categories of data survive into the published message.

Points and linestrings. Every geometric element is built from points: atomic (X, Y, Z) coordinates with optional IDs. Linestrings are ordered sequences of points that define boundaries, centerlines, stop lines, and curb lines. The loader extracts all of them. A linestring with a single point is valid XML and a useless map element. The loader will not flag it.

Lanelets. The core element. Each lanelet carries a left boundary, a right boundary, a centerline (or waypoints), a direction of travel, and a speed limit. The loader extracts all of them, and the planner reads all of them. A lanelet with no speed limit gets the default speed limit, which is zero in some Autoware configurations. The vehicle will not move.

Areas. Open spaces: parking zones, loading bays, pedestrian plazas. Areas carry a subtype and a list of regulatory elements. Downstream modules treat areas with lighter assumptions than lanelets. An area is “this region exists.” It is not “this region is drivable in this direction at this speed.” The planner will enter an area if it must, but it will not plan a trajectory through one the way it plans through a lane.

Regulatory elements. Stop lines, speed limits, detection areas, and traffic signs. Each regElem carries a list of parameters (the refline for a stop line, the velocity for a speed limit, the polygon for a detection area) and a list of lanelets or areas it applies to. If a parameter references a linestring or area ID that does not exist in the map, the regElem is orphaned. The loader does not warn you about orphans.

Topic / Service Direction Type Purpose
~input/map_projector_info subscribe MapProjectorInfo Projection parameters from map_projection_loader
~output/lanelet2_map publish LaneletMapBin Binary Lanelet2 map consumed by the rest of the stack
~output/lanelet_map_meta_data publish LaneletMapMetaData Tile metadata (differential loading only)
~service/get_differential_lanelet_map service GetSelectedLanelet2Map Request a specific tile (differential loading only)

Differential loading for large sites

For a site the size of Harbor Yard, the loader reads the entire map once at startup and publishes it. Every downstream module receives the complete dataset. This works until it does not.

For large sites, a single .osm file becomes expensive. The planning stack spends time processing geometry the vehicle will never reach in a single run. The lanelet topology graph grows large enough that route search takes measurable time. The fix is differential loading: splitting the map into tiles and loading only the tiles the vehicle currently needs.

The split must follow specific rules. Tiles must be divided by straight lines parallel to the X and Y axes of the projected coordinate frame. No diagonal cuts. No curved boundaries. Every tile must be the same size. Tiles must not overlap. And critically, all tiles must fall within the same MGRS grid zone. Mixing grid zones is unsupported. That constraint is the tiling-specific face of a rule Chapter 6 established for the map as a whole: one map, one projection, one zone. A zone boundary running through a site is not a tiling problem to engineer around. It is a decision about which frame the entire site lives in, and it is made long before the first tile is cut.

The recommended tile size is roughly 20 meters by 20 meters. Tiles larger than 100 meters on a side cause performance problems in the NDT scan matcher and the compare map segmentation module, the two nodes that consume pointcloud map tiles most aggressively.

The metadata file that tells the loader which tile covers which coordinate range looks like this:

x_resolution: 20.0
y_resolution: 20.0
A.osm: [1200, 2500]    # 1200 < x < 1220, 2500 < y < 2520
B.osm: [1220, 2500]    # 1220 < x < 1240, 2500 < y < 2520
C.osm: [1200, 2520]    # 1200 < x < 1220, 2520 < y < 2540
D.osm: [1240, 2520]    # 1240 < x < 1260, 2520 < y < 2540

Each entry maps a filename to its lower-left corner in projected coordinates. The resolution fields tell the loader the tile dimensions. The loader uses these to compute which tile covers the vehicle’s current position and publishes only that tile. As the vehicle moves, the loader swaps tiles. The split must be generated by lanelet2_map_tile_generator, an external tool that guarantees tile boundaries never bisect a lanelet. A hand-split map has no such guarantee.

What goes wrong

The loader has few failure modes, but each is expensive to debug because the error message does not name the map. Two of them stop the map from reaching the robot at all: launch failures. Two publish an incomplete map that surfaces later as a driving error: behavioral failures, the class Chapter 36 catalogs from the symptom side. This section covers all four from the loader’s end of the pipe.

Missing projection info. The loader waits for map_projector_info and receives nothing. It fails at startup with a timeout. The fix: check that map_projection_loader is running and publishing on the correct topic.

Version mismatch. Lanelet2 files carry a format_version tag. If the loader encounters a version it does not recognize, it prints a warning and continues when allow_unsupported_version is true. When it is false, the loader refuses to parse. The version field is easy to overlook because most editors do not surface it. A map saved by a newer editor version may carry a tag the installed loader does not recognize.

Orphaned references. The loader does not validate references. A stop line regElem pointing to a linestring ID that no longer exists will parse, load, and publish as an incomplete regulatory element. The logs show no error at load time. What the planner does with an incomplete regElem is a runtime question, and Chapter 36’s ghost stop is this exact defect seen from the road.

Centerline collapse. A lanelet shorter than the center_line_resolution value resamples to a single point. The planner needs at least two points. The vehicle stops at the lanelet entry with a “no valid path” error that names the planner, not the loader. Lower the resolution or add explicit waypoints.

Try this

[10 min] Run the map loader on Harbor Yard and inspect what it publishes.

  1. Launch the loader against your Harbor Yard map:
    ros2 run autoware_map_loader lanelet2_map_loader \
      --ros-args -p lanelet2_map_path:=path/to/harbor_yard/lanelet2_map.osm
  2. Once the loader publishes, echo the output topic:
    ros2 topic echo /output/lanelet2_map | head -n 50
  3. Count the lanelets in the published message. Does the count match the number of lanelets in your .osm file? If not, a lanelet failed to parse. Open the file and find the missing one. It has a structural error the loader could not recover from.
  4. Check the center_line_resolution against your shortest lanelet. If the dock approach lanelet is under 5 meters, lower the resolution and reload. The vehicle should now plan through it without stopping at the entry.

Found an error or have a suggestion?

Report an erratum or send feedback →

In this Part

Keep reading

Beyond the book

Build your own HD map.

Veer Studio is the spatial compiler this handbook teaches you to use. Download it and map a site, or tell us about your site and we will show you a validated map.

← Back to HD Map HandbookContinue to Where Am I? What’s Around Me? →