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-rrhdInstalls into whichever agent you are using.
SKILL.md
Installable skill definition
Quality Score
Category
Development & EngineeringSupported Platforms
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.
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.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| roadrunner-convert-lanelet2-to-rrhd (this skill)by matlab | 90 | 1.1k | 21d ago | SKILL.md |
| ai-job-searchby MadsLorentzen | 100 | 45.1k | 1d ago | CLAUDE.md |
| claude-howtoby luongnv89 | 100 | 41.8k | 6d ago | CLAUDE.md |
| algorithmic-artby anthropics | 100 | 177.9k | 14d ago | SKILL.md |
| pptxby anthropics | 100 | 177.9k | 14d ago | SKILL.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.
Skill content
View source on GitHubname: 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
.osmfile to RoadRunner HD Map.rrhdformat - Importing Lanelet2 maps into RoadRunner via MATLAB
- Building RRHD from
.osmsources that containtype=laneletrelations - 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=laneletrelations) - Input is OpenDRIVE
.xodr— import directly viaroadrunner-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.mfile, run withrun_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
wayToBndIDmap. - 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_ytags — already in local meters, use directly as geometry X/Ylat/lonattributes 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
- Nodes have
local_x/local_y→ use directly, setgeoReffrommap_projector_info.yamlMapOrigin (or from node lat/lon if yaml missing) - 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:
-
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. -
One boundary object per way. Deduplicate via
wayToBndIDmap. Multiple lanes reference the same boundary with different alignments. -
Alignment via left/right dot product + proximity test. Compute
dp = dot(leftDir, rightDir)(normalized overall direction — this is correct for the threshold check). Ifdp >= -0.3: both boundaries are Forward. Ifdp < -0.3: boundaries are opposing — use proximity (d_ls_re = norm(leftStart - rightEnd)vsd_ls_rs = norm(leftStart - rightStart)) to determine which is Backward. Ifd_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.) -
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. -
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 ... endblocks — these error with "Function definitions are not supported in this context" - Empty typed arrays — use
ClassName.emptynot[](e.g.,roadrunner.hdmap.AlignedReference.empty) - Name=Value constructors —
RelativeAssetPath,AlignedReferencerequire 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) = []. Usemap(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 useunique(stringArray)directly. For mixed cells:unique(string(cellArray)).containers.Mapvalues need explicit type cast — values retrieved fromcontainers.Mapmay lose their numeric type. Always cast before math:double(geoRef(1))before passing tocosd(),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
ai-job-search
45.1kThe job search that runs on your machine. AI job application framework built on Claude Code: evaluate postings, tailor CVs, write cover letters, prep interviews. Fork it and own it.
claude-howto
41.8kA visual, example-driven guide to Claude Code — from basic concepts to advanced agents, with copy-paste templates that bring immediate value.
algorithmic-art
177.9kCreating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems.
pptx
177.9kUse this skill any time a .pptx or .potx file is involved in any way — as input, output, or both. This includes: creating slide decks, pitch decks, or presentations; reading, parsing, or extracting text from any .pptx or .potx file (even if the extracted content will be used elsewhere, like in an em…
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
