$npx -y skills add matlab/matlab-agentic-toolkit --skill roadrunner-scenario-authoringProgrammatically author RoadRunner scenarios from MATLAB using roadrunnerAPI. Use when adding actors, creating routes, building scenario logic (phases, conditions, actions), placing vehicles/pedestrians, defining cut-in/crossing/ follow scenarios, or any programmatic scenario cre
| 1 | # RoadRunner Scenario Authoring |
| 2 | |
| 3 | Programmatically create RoadRunner scenarios from MATLAB: actors, routes, phase logic, and validation — all via `roadrunnerAPI`. |
| 4 | |
| 5 | ## When to Use |
| 6 | |
| 7 | - Adding actors (vehicles, pedestrians, objects) to a RoadRunner scenario |
| 8 | - Creating routes and waypoints for actors |
| 9 | - Building scenario logic: phases, conditions, actions |
| 10 | - Authoring common patterns: cut-in, pedestrian crossing, lead-follow, emergency brake |
| 11 | - Placing actors on roads using anchor-based or HD Map positioning |
| 12 | - Validating scenario structure before simulation |
| 13 | |
| 14 | ## When NOT to Use |
| 15 | |
| 16 | - Connecting to or launching RoadRunner → use `roadrunner-core` |
| 17 | - Building scenarios from recorded sensor data → use `matlab-scenario-builder` |
| 18 | - Authoring road geometry (lanes, junctions) → use `roadrunner-rrhd-authoring` |
| 19 | - Importing maps or scenes → use `roadrunner-import-scene` |
| 20 | - Simulating or exporting scenarios → use `roadrunner-scenario-simulating` |
| 21 | |
| 22 | ## Workflow |
| 23 | |
| 24 | ### 1. Ensure Session |
| 25 | |
| 26 | Verify `rrApp` exists. If not, ensure RoadRunner is connected first (e.g., via `roadrunner-core` or manually). |
| 27 | |
| 28 | ```matlab |
| 29 | if ~exist('rrApp', 'var') || ~isvalid(rrApp) |
| 30 | error("No active RoadRunner session. Use the roadrunner-core skill."); |
| 31 | end |
| 32 | ``` |
| 33 | |
| 34 | **Path setup:** Before calling helper functions, ensure the scripts directory is on the MATLAB path: |
| 35 | ```matlab |
| 36 | addpath('<path-to-skill>/scripts'); |
| 37 | ``` |
| 38 | |
| 39 | ### 2. Initialize Scenario |
| 40 | |
| 41 | ```matlab |
| 42 | openScene(rrApp, sceneName); |
| 43 | newScenario(rrApp); |
| 44 | rrApi = roadrunnerAPI(rrApp); |
| 45 | rrs = rrApi.Scenario; |
| 46 | phaseLogic = rrs.PhaseLogic; |
| 47 | rrprj = rrApi.Project; |
| 48 | ``` |
| 49 | |
| 50 | ### 3. Scene Awareness |
| 51 | |
| 52 | Before placing actors, survey the scene to find valid lane positions. Use the `helperSceneAwareness` script for automated analysis, or query manually via HD Map export: |
| 53 | |
| 54 | ```matlab |
| 55 | sceneInfo = helperSceneAwareness(rrApp, NumActors=2, ScenarioType="cut-in"); |
| 56 | ``` |
| 57 | |
| 58 | See `references/scene-awareness.md` for manual HD Map query patterns when the helper is unavailable. |
| 59 | |
| 60 | ### 4. Add Actors |
| 61 | |
| 62 | **Option A — Batch placement** (recommended for 2+ actors): |
| 63 | ```matlab |
| 64 | actorSpecs(1) = struct(Name="Ego", AssetPath="Vehicles/Sedan.fbx", ... |
| 65 | AssetType="VehicleAsset", LaneIndex=1, Fraction=0.1, Speed=15); |
| 66 | [actors, report] = helperPlaceActors(rrs, rrprj, phaseLogic, sceneInfo.HDMap, actorSpecs); |
| 67 | ego = actors{1}; % cell array — use curly braces |
| 68 | ``` |
| 69 | |
| 70 | **Option B — Manual placement:** |
| 71 | ```matlab |
| 72 | vehicleAsset = getAsset(rrprj, "Vehicles/Sedan.fbx", "VehicleAsset"); |
| 73 | actor = addActor(rrs, vehicleAsset, position); |
| 74 | actor.Name = "Ego"; |
| 75 | autoAnchor(actor.InitialPoint); % Snaps to nearest road |
| 76 | ``` |
| 77 | |
| 78 | **Post-placement check:** Verify `actor.InitialPoint.WorldPosition` is NOT `[0 0 0]`. |
| 79 | |
| 80 | See `references/asset-catalog.md` for available vehicle/character paths. |
| 81 | |
| 82 | ### 5. Position Actors (Anchoring) |
| 83 | |
| 84 | **Option A — Scene anchors available:** |
| 85 | ```matlab |
| 86 | anchors = getAnchors(rrApp); |
| 87 | % Use remapAnchor for cross-scene portability (not findSceneAnchor) |
| 88 | anchorPt = findSceneAnchor(rrs, anchors(1).Name); |
| 89 | anchorToPoint(actor.InitialPoint, anchorPt); |
| 90 | actor.InitialPoint.ForwardOffset = 20; |
| 91 | actor.InitialPoint.LaneOffset = 1; |
| 92 | ``` |
| 93 | |
| 94 | **Option B — No scene anchors (use autoAnchor):** |
| 95 | ```matlab |
| 96 | actor = addActor(rrs, asset, approximatePosition); |
| 97 | autoAnchor(actor.InitialPoint); % Must be within 5m of road |
| 98 | ``` |
| 99 | |
| 100 | **Option C — Relative to another actor:** |
| 101 | ```matlab |
| 102 | anchorToPoint(target.InitialPoint, ego.InitialPoint); |
| 103 | target.InitialPoint.ForwardOffset = 30; |
| 104 | target.InitialPoint.LaneOffset = 1; |
| 105 | ``` |
| 106 | |
| 107 | ### 6. Create Routes (When Needed) |
| 108 | |
| 109 | Routes put actors in **path-following mode**. Actors without routes drive in **lane-following mode** along their anchored lane. |
| 110 | |
| 111 | ```matlab |
| 112 | route = actor.InitialPoint.Route; |
| 113 | fwdPt = addPoint(route, actor.InitialPoint.WorldPosition + [20 0 0]); |
| 114 | autoAnchor(fwdPt); |
| 115 | % For vehicles: disable freeform so route follows road surface |
| 116 | % (Do NOT do this for pedestrians — they need freeform to cross roads) |
| 117 | for i = 1:numel(route.Segments) |
| 118 | route.Segments(i).Freeform = false; |
| 119 | end |
| 120 | ``` |
| 121 | |
| 122 | **When to add routes:** |
| 123 | - Character/pedestrian actors — ALWAYS required (validation fails without them) |
| 124 | - Vehicles that follow a specific path (e.g., ego driving straight) |
| 125 | - Vehicles that do NOT need `ChangeLaneAction` |
| 126 | |
| 127 | **When NOT to add routes:** |
| 128 | - Vehicles that need `ChangeLaneAction` — they MUST be in lane-following mode (no routes) |
| 129 | - Vehicles that need `ChangeLateralOffsetAction` — same requirement |
| 130 | |
| 131 | **Route point rules:** |
| 132 | - Alw |