$npx -y skills add matlab/matlab-agentic-toolkit --skill roadrunner-convert-lanelet2-to-rrhdConvert Lanelet2 maps (.osm) to RoadRunner HD Map (.rrhd) format using MATLAB. Use when converting Lanelet2 maps into RoadRunner Scene Builder, building driving scenes from open-source map data, or transforming road network definitions for simulation.
| 1 | # Lanelet2 to RRHD Converter |
| 2 | |
| 3 | Converts Lanelet2 `.osm` files to RoadRunner HD Map `.rrhd` format. |
| 4 | |
| 5 | ## When to Use |
| 6 | |
| 7 | - Converting a Lanelet2 `.osm` file to RoadRunner HD Map `.rrhd` format |
| 8 | - Importing Lanelet2 maps into RoadRunner via MATLAB |
| 9 | - Building RRHD from `.osm` sources that contain `type=lanelet` relations |
| 10 | - Need full pipeline: parse, geometry, topology, semantics, junctions, barriers, signs, markings |
| 11 | |
| 12 | ## When NOT to Use |
| 13 | |
| 14 | - Input is a standard OpenStreetMap file (highway=* ways without `type=lanelet` relations) |
| 15 | - Input is OpenDRIVE `.xodr` — import directly via `roadrunner-import-scene` |
| 16 | - Building RRHD from scratch without a source file — use `roadrunner-rrhd-authoring` |
| 17 | - Only need asset path lookups — use `roadrunner-asset-mapping` |
| 18 | |
| 19 | ## Key Rules |
| 20 | |
| 21 | - **Always write to .m files.** Never put multi-line MATLAB code directly in `evaluate_matlab_code`. Write to a `.m` file, run with `run_matlab_file`, edit on error. |
| 22 | - **ALL pipeline steps are mandatory.** Do NOT stop after writing lanes/boundaries — junctions, curve markings, barriers, signs, and speed limits must all be built. |
| 23 | - **Boundary geometry is IMMUTABLE.** Never flip, resample, project, or modify boundary points. |
| 24 | - **One boundary object per way.** Deduplicate via `wayToBndID` map. |
| 25 | - **Detect alignment for EVERY lane.** Never hardcode `"Forward"` for all boundaries. |
| 26 | - **Center line density: 1 point per meter minimum.** Use `max(10, round(avgLen), nLeft, nRight)`. |
| 27 | - **Run enforcement gate before `write()`.** Alignment, spatial, extension, and completeness checks are mandatory. |
| 28 | - **No nested function definitions.** Code runs in script context — all logic inline or anonymous functions. |
| 29 | |
| 30 | ## Behavior |
| 31 | |
| 32 | Generate MATLAB code that performs the conversion pipeline described below. Run it via `mcp__matlab__evaluate_matlab_code`. No pre-built scripts or `addpath` calls are needed — Claude generates all code at runtime from these instructions. |
| 33 | |
| 34 | **MANDATORY: ALL steps must be executed.** Do NOT stop after writing lanes/boundaries. The pipeline is incomplete without: junctions, curve markings (stop lines + crosswalks), barriers, signs, and speed limits. Every element found in the OSM MUST appear in the output RRHD. |
| 35 | |
| 36 | **MANDATORY: Steps 3b and 3c (discovery) must execute IN THE SAME code block as Step 3a.** These are not optional post-processing — they are part of parsing. The discovery loop code is inlined below in Step 3. If you skip 3b/3c, the completeness gate in Step 9 will fail with assertion errors. |
| 37 | |
| 38 | **Scope:** This skill supports **Lanelet2 OSM only**. If the input is a standard OpenStreetMap file (highway=* ways without `type=lanelet` relations), do NOT attempt conversion. Instead inform the user: "This file appears to be a standard OpenStreetMap road network, not a Lanelet2 map. This skill only supports Lanelet2 OSM → RRHD conversion." |
| 39 | |
| 40 | **Companion skills (invoke automatically during conversion):** |
| 41 | |
| 42 | | Skill | When to invoke | Purpose | |
| 43 | |-------|----------------|---------| |
| 44 | | `roadrunner-rrhd-authoring` | Step 9 (Build RRHD Objects) | Provides `roadrunner.hdmap.*` class/property reference and construction patterns | |
| 45 | | `roadrunner-asset-mapping` | Step 8 (Extract Semantics) | Resolves marking subtypes, sign codes, and barrier types to RoadRunner asset paths | |
| 46 | |
| 47 | These skills are loaded on demand — read their references when generating RRHD construction code or resolving asset paths. This skill provides the Lanelet2-specific parsing and bridging logic. |
| 48 | |
| 49 | ## Coordinate System |
| 50 | |
| 51 | Lanelet2 OSM nodes may use either: |
| 52 | - **`local_x`/`local_y` tags** — already in local meters, use directly as geometry X/Y |
| 53 | - **`lat`/`lon` attributes only** — geographic coordinates that MUST be projected to local meters |
| 54 | |
| 55 | ### Step 1: Check for `map_projector_info.yaml` |
| 56 | |
| 57 | Lanelet2 datasets typically include a `map_projector_info.yaml` file in the same directory as the `.osm` file. This file specifies the projection and map origin: |
| 58 | |
| 59 | ```yaml |
| 60 | ProjectorType: TransverseMercator |
| 61 | VerticalDatum: WGS84 |
| 62 | MapOrigin: |
| 63 | Latitude: 42.300945 |
| 64 | Longitude: -83.698205 |
| 65 | Altitude: 0 |
| 66 | ``` |
| 67 | |
| 68 | **Always look for this file first.** Parse it to get `ProjectorType` and `MapOrigin`: |
| 69 | |
| 70 | ```matlab |
| 71 | projFile = fullfile(fileparts(osmFile), "map_projector_info.yaml"); |
| 72 | if isfile(projFile) |
| 73 | txt = fileread(projFile); |
| 74 | latMatch = regexp(txt, 'Latitude:\s*([-\d.]+)', 'tokens'); |
| 75 | lonMatch = regexp(txt, 'Longitude:\s*([-\d.]+)', 'tokens'); |
| 76 | if ~isempty(latMatch) && ~isempty(lonMatch) |
| 77 | originLat = str2double(latMatch{1}{1}); |
| 78 | originLon = str2double(lonMatch{1}{1}); |
| 79 | end |
| 80 | end |
| 81 | ``` |
| 82 | |
| 83 | If `MapOrigin` is `[0, 0]`, the origin |