{% import "partials/icons.html" as ic %} {# Metadata-driven form controls. Every control is chosen from a FieldSpec's `kind`, never from the primitive's type, so registering a new action / condition / constraint in Python gives it a working inspector with no change to this file. #} {% macro control(spec, value, document, prefix='', draft=none, params={}) %} {%- set name = prefix ~ spec.name -%} {%- set current = spec.default if value is none else value -%} {% if spec.kind == 'bool' %} {% elif spec.kind == 'select' %} {% elif spec.kind == 'entity' %} {% elif spec.kind in ('lanelet', 'lanelet_list') %} {# The readout only. Its map lives in a modal that `partials/lanelet_search.html` renders outside this form -- the choice between a pinned lanelet and a constraint search is made of forms, and a form cannot nest. Anything rendering `fields()` renders `modals()` too. #} {{ lanelet_field(name, current, draft, many=(spec.kind == 'lanelet_list')) }} {% elif spec.kind == 'action' %} {# Actions are listed by track, because "which one is Cut in" is a question about whose track it sits on as much as about its title. #} {% elif spec.kind == 'signal_controller' %} {# The document already says which junctions it runs. Offering them beats a text box whose only feedback is a validation error after the fact. #} {%- set declared = document.map.traffic_signal_controllers -%} {%- set names = [] -%} {%- for controller in declared %}{% set _ = names.append(controller.name) %}{% endfor -%} {% elif spec.kind == 'signal_phase' %} {# Scoped to the controller the card names, because a phase only means anything inside one. The form re-renders on change, so choosing a controller refills this list. #} {%- set chosen = params.get('controller') -%} {%- set declared = document.map.traffic_signal_controllers -%} {%- set scoped = declared|selectattr('name', 'equalto', chosen)|list if chosen else declared -%} {%- set names = [] -%} {%- for controller in scoped %}{% for phase in controller.phases %}{% set _ = names.append(phase.name) %}{% endfor %}{% endfor -%} {% elif spec.kind in ('int_list', 'int_list_or_ref') %} {% elif spec.kind == 'trajectory' %} {# Rows of data rather than one value: a recording transcribes to hundreds of vertices, so they are edited as text, one per line, and the line above says what the text adds up to. #}
{{ trajectory_summary(current) }}
{% elif spec.kind == 'relative_lane_trajectory' %} {# The same text editing as a map-frame trajectory, with the columns of a lane-relative vertex. #}{{ relative_trajectory_summary(current) }}
{% elif spec.kind == 'route_trajectory' %} {# Vertices placed against the scenario's route: one per line, the kind first, then the kind's keys. #}{{ route_trajectory_summary(current) }}
{% elif spec.kind == 'record_list' %} {# One block of controls per record, in order. `__rows` says how many the form holds, and each row button is a submit whose name and value say what to do -- so adding, removing and reordering go through the inspector form's own post, with the rest of the form, and need no route of their own. `editor/forms.py` parses the names written here. #} {%- set rows = current or [] -%}The Lanelet2 map viewer could not be loaded, so there is nothing to pick from. Check that this scenario's Lanelet2 file path is right.
{{ spec.help }}
{% endif %}