SkillAgentSearch skills...

roadrunner-convert-lanelet2-to-rrhd

Convert Lanelet2 maps (.osm) to RoadRunner HD Map (.rrhd) format using MATLAB

Install / Use

npx skills add matlab/matlab-agentic-toolkit --skill roadrunner-convert-lanelet2-to-rrhd

Installs into whichever agent you are using.

About this skill
📄

SKILL.md

Installable skill definition

Quality Score

90/100

Supported Platforms

Universal

Tags

Our assessment of roadrunner-convert-lanelet2-to-rrhd

roadrunner-convert-lanelet2-to-rrhd scores 90/100 on our quality scale, 1529th of 4,582 Development & Engineering skills we index (top 34%).

Its SKILL.md is 27 KB long, well organised into 32 sections with 8 code examples: a thorough specification that gives an agent plenty to work with.

With 1,098 GitHub stars, it is one of the more widely adopted skills in the catalogue.

Substance
30/30
Structure
20/20
Description
12/15
Adoption
13/20
Freshness
15/15

Maintenance, license and trust

  • The repository was last updated 21 days ago, so roadrunner-convert-lanelet2-to-rrhd is actively maintained.
  • No license is declared. By default that means all rights are reserved: you can read it, but reusing or redistributing it is not clearly permitted. Ask the author before building on it commercially.
  • Its trust signals score 88/100, with 1 caution from licensing, adoption, age or documentation. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.

roadrunner-convert-lanelet2-to-rrhd compared with similar skills

All 4 of these similar skills score higher than roadrunner-convert-lanelet2-to-rrhd; compare them before choosing.

SkillScoreStarsUpdatedFormat
roadrunner-convert-lanelet2-to-rrhd (this skill)by matlab901.1k21d agoSKILL.md
ai-job-searchby MadsLorentzen10045.1k1d agoCLAUDE.md
claude-howtoby luongnv8910041.8k6d agoCLAUDE.md
algorithmic-artby anthropics100177.9k14d agoSKILL.md
pptxby anthropics100177.9k14d agoSKILL.md

Frequently asked questions

How do I install roadrunner-convert-lanelet2-to-rrhd?
Run npx skills add matlab/matlab-agentic-toolkit --skill roadrunner-convert-lanelet2-to-rrhd. The install tabs above show the steps for each supported agent.
Which AI agents does roadrunner-convert-lanelet2-to-rrhd work with?
It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
Is roadrunner-convert-lanelet2-to-rrhd safe to use?
It declares no license and scores 88/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
Is roadrunner-convert-lanelet2-to-rrhd still maintained?
The repository was last updated 21 days ago, so roadrunner-convert-lanelet2-to-rrhd is actively maintained.

name: roadrunner-convert-lanelet2-to-rrhd description: > Convert 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. license: https://www.mathworks.com/content/dam/mathworks/license/pmrl/license.md metadata: author: MathWorks version: "1.1"

Lanelet2 to RRHD Converter

Converts Lanelet2 .osm files to RoadRunner HD Map .rrhd format.

When to Use

  • Converting a Lanelet2 .osm file to RoadRunner HD Map .rrhd format
  • Importing Lanelet2 maps into RoadRunner via MATLAB
  • Building RRHD from .osm sources that contain type=lanelet relations
  • Need full pipeline: parse, geometry, topology, semantics, junctions, barriers, signs, markings

When NOT to Use

  • Input is a standard OpenStreetMap file (highway=* ways without type=lanelet relations)
  • Input is OpenDRIVE .xodr — import directly via roadrunner-import-scene
  • Building RRHD from scratch without a source file — use roadrunner-rrhd-authoring
  • Only need asset path lookups — use roadrunner-asset-mapping

Key Rules

  • Always write to .m files when executing code. Never put multi-line MATLAB code directly in evaluate_matlab_code. Write to a .m file, run with run_matlab_file, edit on error. Exception: if the user asks to "show the pattern" or says "do not execute", show code inline without writing files.
  • ALL pipeline steps are mandatory. Do NOT stop after writing lanes/boundaries — junctions, curve markings, barriers, signs, and speed limits must all be built.
  • Boundary geometry is IMMUTABLE. Never flip, resample, project, or modify boundary points.
  • One boundary object per way. Deduplicate via wayToBndID map.
  • Detect alignment for EVERY lane. Never hardcode "Forward" for all boundaries.
  • Center line density: 1 point per meter minimum. Use max(10, round(avgLen), nLeft, nRight).
  • Run enforcement gate before write(). Alignment, spatial, extension, and completeness checks are mandatory.
  • No nested function definitions. Code runs in script context — all logic inline or anonymous functions.

Behavior

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.

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.

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.

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."

Companion skills (invoke automatically during conversion):

| Skill | When to invoke | Purpose | |-------|----------------|---------| | roadrunner-rrhd-authoring | Step 9 (Build RRHD Objects) | Provides roadrunner.hdmap.* class/property reference and construction patterns | | roadrunner-asset-mapping | Step 8 (Extract Semantics) | Resolves marking subtypes, sign codes, and barrier types to RoadRunner asset paths |

These skills are loaded on demand — read their references when generating RRHD construction code or resolving asset paths.

Skill boundary: This skill owns everything Lanelet2-specific (OSM parsing, node-ref topology, turn_direction clustering, opposing-boundary detection). For RRHD object construction patterns (alignment algorithm, center line synthesis, junction polygon, API reference), defer to roadrunner-rrhd-authoring.

Coordinate System

Lanelet2 OSM nodes may use either:

  • local_x/local_y tags — already in local meters, use directly as geometry X/Y
  • lat/lon attributes only — geographic coordinates that MUST be projected to local meters

Step 1: Check for map_projector_info.yaml

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:

ProjectorType: TransverseMercator
VerticalDatum: WGS84
MapOrigin:
  Latitude: 42.300945
  Longitude: -83.698205
  Altitude: 0

Always look for this file first. Parse it to get ProjectorType and MapOrigin:

projFile = fullfile(fileparts(osmFile), "map_projector_info.yaml");
if isfile(projFile)
    txt = fileread(projFile);
    latMatch = regexp(txt, 'Latitude:\s*([-\d.]+)', 'tokens');
    lonMatch = regexp(txt, 'Longitude:\s*([-\d.]+)', 'tokens');
    if ~isempty(latMatch) && ~isempty(lonMatch)
        originLat = str2double(latMatch{1}{1});
        originLon = str2double(lonMatch{1}{1});
    end
end

If MapOrigin is [0, 0], the origin is implicit — use the centroid of all nodes instead.

Step 2: Determine coordinate mode

  1. Nodes have local_x/local_y → use directly, set geoRef from map_projector_info.yaml MapOrigin (or from node lat/lon if yaml missing)
  2. Nodes have only lat/lon → project to local ENU meters using the origin from yaml (or node centroid as fallback)

Step 3: Project lat/lon to local meters (when needed)

% Origin from map_projector_info.yaml or centroid fallback
geoRef = [originLat, originLon];

% For each node, convert to local meters:
dLat = node.lat - originLat;
dLon = node.lon - originLon;
metersPerDegLat = 111132.92;
metersPerDegLon = 111132.92 * cosd(originLat);
x = dLon * metersPerDegLon;   % East
y = dLat * metersPerDegLat;   % North
z = node.ele;                  % Up (elevation)

Set rrMap.GeoReference = [originLat, originLon] so RoadRunner knows the map's geographic position.

IMPORTANT: This projection happens ONCE during node parsing. All downstream geometry (boundaries, center lines, barriers, signs) uses the projected local coordinates. The "boundary geometry is immutable" rule (below) refers to the projected coordinates — do not re-project or modify them after initial parsing.

Geometry Invariants (MUST enforce — violations produce broken RRHD)

These rules are NON-NEGOTIABLE. Every conversion MUST follow them:

  1. Boundary geometry is IMMUTABLE. Store way node coordinates (local or projected) exactly as computed during parsing. NEVER flip, resample, or modify boundary points after initial coordinate assignment. Shared boundaries between opposing lanes will corrupt if touched. Use Alignment="Backward" instead.

  2. One boundary object per way. Deduplicate via wayToBndID map. Multiple lanes reference the same boundary with different alignments.

  3. Alignment via left/right dot product + proximity test. Compute dp = dot(leftDir, rightDir) (normalized overall direction — this is correct for the threshold check). If dp >= -0.3: both boundaries are Forward. If dp < -0.3: boundaries are opposing — use proximity (d_ls_re = norm(leftStart - rightEnd) vs d_ls_rs = norm(leftStart - rightStart)) to determine which is Backward. If d_ls_re < d_ls_rs, right is Backward, left is Forward. (Note: the "NEVER use overall direction" warning in Step 9 applies to the multi-sample spatial verification step, not this dp threshold check.)

  4. Center line density: 1 point per meter minimum. Use nPts = max(10, round(avgBoundaryLength), nLeftPts, nRightPts). Too few points causes pchip interpolation deviation from true midpoint.

  5. Center line orthogonal endpoints only. Enforce perpendicular start/end on CENTER LINE via tangent blending. Do NOT project boundary endpoints.

MATLAB Script Constraints

Code runs in mcp__matlab__evaluate_matlab_code which is a script context (NOT a function file):

  • NO nested function definitions — all logic must be inline or use anonymous functions
  • NO function ... end blocks — these error with "Function definitions are not supported in this context"
  • Empty typed arrays — use ClassName.empty not [] (e.g., roadrunner.hdmap.AlignedReference.empty)
  • Name=Value constructors — RelativeAssetPath, AlignedReference require Name=Value syntax:
    % CORRECT:
    rap = roadrunner.hdmap.RelativeAssetPath(AssetPath="Assets/Markings/StopLine.rrlms");
    ar = roadrunner.hdmap.AlignedReference(Reference=ref, Alignment="Forward");
    
    % WRONG (will error with "A name is expected"):
    rap = roadrunner.hdmap.RelativeAssetPath("Assets/Markings/StopLine.rrlms");
    ar = roadrunner.hdmap.AlignedReference(bndID, "Forward");
    
  • containers.Map empty assignment — never do map(key) = []. Use map(key) = zeros(1,0) or only assign non-empty values
  • No chaining ()() — geomMap(key)(:,1) errors with "Using parentheses directly after parentheses is disallowed". Assign to a temp variable first:
    % WRONG: min(geomMap(k)(:,1))
    % CORRECT:
    pts = geomMap(k);
    minX = min(pts(:,1));
    
  • unique() on cell arrays — unique(cellArray) requires cellstr (cell of char vectors). For string arrays use unique(stringArray) directly. For mixed cells: unique(string(cellArray)).
  • containers.Map values need explicit type cast — values retrieved from containers.Map may lose their numeric type. Always cast before math: double(geoRef(1)) before passing to cosd(), sind(), etc.
  • Cell array struct field assignment — never do cellArray{end+1} = x; cellArray{end}.field = val; (errors with "dot indexing not supported for double"). Instead, build the struct first then append:
    % WRONG:
    stopLineWays{end+1} = w; stopLineWays{end}.wayID = wid;
    % CORRECT:
    w.wayID = wid; stopLineWays{end+1} = w;
    % OR: store IDs in a separate parallel cell array
    

Pipeline (execute in order)

Step 1: Parse OSM

See references/readOSM.md and scripts/parseOSM.m.

doc = xmlread(osmFile);
% Parse nodes: id, lat, lon, ele, local_x, local_y (from tags)
% Parse ways: id, nodeRefs[], tags (containers.Map)
% Parse relations: id, members[], tags (containers.Map)

Step 2: Validate Format

Check that at least one relation has type=lanelet. If none found, error with clear message identifying the file as non-Lanelet2.

hasLanelet = false;
relKeys = relations.keys;
for i = 1:numel(relKeys)
    rel = relations(relKeys{i});
    if rel.tags.isKey('type') && strcmp(rel.tags('type'), 'lanelet')
        hasLanelet = true; break;
    end
end
if ~hasLanelet
    error('UNSUPPORTED FORMAT: This converter supports Lanelet2 OSM files only.');
end

Step 3: Extract Lanelets + Discover ALL Non-Lane Elements

This step has THREE mandatory sub-steps. ALL must execute.

Step 3a: Extract Lanelets

Filter relations with type=lanelet. See references/extractLanelets.md.

% For each relation with type=lanelet:
%   leftWayID  = member with role="left"
%   rightWayID = member with role="right"
%   subtype, one_way, speed_limit, turn_direction from tags

Step 3b: Discover ALL Way Types (MANDATORY — run immediately after 3a)

See scripts/discoverWayTypes.m for the reference implementation.

DO NOT use a whitelist. Scan every way, categorize by type tag using strsplit(wType, '/') for compound types:

stopLineWays = {}; pedestrianMarkingWays

Truncated for display — read the full file on GitHub.

Related Skills

View on GitHub
GitHub Stars1.1k
CategoryDevelopment
Updated21d ago
Forks134

Languages

MATLAB

Trust signals

88/100

From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.

1 medium