132. Scenario Relevance KPI
KPI location: $FTX_PACKAGES/common/scenarios/scenario_relevance_kpi/
The Scenario Relevance KPI defines a dynamic region of interest (ROI) around the Ego and checks whether other actors (traffic vehicles, plain objects, and random vehicles) enter this ROI during a scenario.
The ROI is shaped:
- Longitudinally, using a time gap relative to the Ego
- Laterally, using a distance range from the Ego
132.1 Zones of interest
The ROI is divided into four primary zones around the Ego:
- Front-Left
- Front-Right
- Back-Left
- Back-Right
These zones allow for granular detection of spatial and temporal proximity.
132.2 Zone definitions
Each zone is defined using longitudinal time gap and lateral distance relative to the Ego.
132.3 Zone Definitions
Each zone is defined using a combination of longitudinal time gap and lateral distance relative to the Ego.
| Zone | Time Gap (s) | Longitudinal Reference | Lateral Range (m) | Lateral Reference |
|---|---|---|---|---|
| Front-Left | < 5 | Ego front center → actor back center | 0 to 5 | Ego center → actor center |
| Front-Right | < 5 | Ego front center → actor back center | 0 to -5 | Ego center → actor center |
| Back-Left | < 1 | Ego back center → actor front center | 0 to 5 | Ego center → actor center |
| Back-Right | < 1 | Ego back center → actor front center | 0 to -5 | Ego center → actor center |
132.4 Watchers
Watchers generate intervals when an actor enters one of the Ego’s defined ROI zones. Two watcher types are used:
- Vehicle zone watchers
- Plain object watchers
132.4.1 Vehicle Zone watchers
A watcher type ego_zone_limit_watcher_for_vehicle creates intervals when any vehicle enters one of the defined zones. Four watchers are instantiated:
ego_front_left_zone_limit_watcher_for_vehicleego_front_right_zone_limit_watcher_for_vehicleego_back_left_zone_limit_watcher_for_vehicleego_back_right_zone_limit_watcher_for_vehicle
Example visualization in the Foretify debugger (teal shows active intervals for NPC vehicles):
132.4.2 Plain object zone watchers
A similar watcher type ego_zone_limit_watcher_for_plain_object is used for plain objects, with the same four-zone instantiations.
Example visualization of plain object zone watchers in Foretify
132.5 Vehicle zone watchers
A watcher type ego_zone_limit_watcher_for_vehicle creates intervals when any vehicle enters one of the respective zone conditions, with the same four-zone instantiations.
Example visualization of vehicle zone watchers in Foretify
132.6 Watcher example
This example shows how a watcher is defined and instantiated to track vehicles entering ROI zones. A data struct vehicle_zone_watcher_data stores:
actor_idinterval_countvehicle_lon_time_gapvehicle_lat_offset
# Copyright (C) 2024 Foretellix Ltd (“Foretellix”)
# This source code file is licensed to you under Foretellix’ End User License
# Agreement, you may not use this file except in compliance with the License.
# You are not allowed to distribute it to any third party without Foretellix’
# written approval.
# If you choose to modify this code (in compliance with the license terms),
# you do it at your own risk, and Foretellix will no longer supply any
# support or maintenance services for this source code.
# See the License for the specific language governing permissions and
# limitations under the License.
#----- code snippet start -----#
struct vehicle_zone_watcher_data inherits any_watcher_data:
actor_id: int
interval_count : int = 0
vehicle_lon_time_gap: time
vehicle_lat_offset : length
record(actor_id, text: "Unique identification number of the actor")
record(interval_count, text: "The total interval count of the zone")
record(vehicle_lat_offset, unit : m,
text: "Lateral offset of the actor relative to Ego")
record(vehicle_lon_time_gap, unit: s,
text: "Londitudinal time-gap of the actor relative to Ego")
# The watcher creates intervals when any vehicle enters the respective zone conditions.
# A watcher type, ego_zone_limit_watcher_for_vehicle, is created and the watchers,
# ego_front_left_zone_limit_watcher_for_vehicle,
# ego_front_right_zone_limit_watcher_for_vehicle,
# ego_back_left_zone_limit_watcher_for_vehicle,
# and ego_back_right_zone_limit_watcher_for_vehicle,
# are instantiated from that watcher type
watcher modifier ego_zone_limit_watcher_for_vehicle(vehicle_zone_watcher_data):
any_actor : vehicle
vehicle_max_time_gap_threshold : time
vehicle_min_time_gap_threshold : time
vehicle_max_lat_threshold : length
vehicle_min_lat_threshold : length
ego_dist_ref: distance_reference
vehicle_dist_ref: distance_reference
var vehicle_lat_offset: length = 0m
var vehicle_lon: length = 0m
var vehicle_lon_time_gap: time
var i : int = 0
var actor_id: int =0
var interval_count: int = 0
var vehicle_present :int = 0
var start_time : time =0s
var end_time : time =0s
var move_duration: time= 0s
var previous_total_time: time =0s
var total_time: time =0s
on @top.w_clk:
# Lateral position
vehicle_lat_offset = sut.car.road_distance(\
any_actor, center, center, direction: lat, route_type: road)
# Longitudinal position
vehicle_lon = sut.car.road_distance(\
any_actor, ego_dist_ref,vehicle_dist_ref, direction: lon, route_type: road)
if (sut.car.state.speed != 0kph):
vehicle_lon_time_gap = vehicle_lon/sut.car.state.speed
# To emit start interval the vehicle_lat_offset should be
# lesser than vehicle_max_lat_threshold and
# greater than vehicle_min_lat_threshold parameter values.
# The vehicle_lon_time_gap should be lesser than
# vehicle_max_time_gap_threshold and greater than
# vehicle_min_time_gap_threshold
if (vehicle_lat_offset > vehicle_min_lat_threshold and
vehicle_lat_offset < vehicle_max_lat_threshold and
vehicle_lon_time_gap < vehicle_max_time_gap_threshold and
vehicle_lon_time_gap > vehicle_min_time_gap_threshold and
vehicle_present == 0 and data == null):
vehicle_present = 1
set actor_id = any_actor.uid
i = 0
interval_count = interval_count + 1
start_interval()
# Interval ends if the vehicle_max_time_gap_threshold
# and vehicle_min_time_gap_threshold exceeds
elif not(vehicle_lon_time_gap < vehicle_max_time_gap_threshold and
vehicle_lon_time_gap > vehicle_min_time_gap_threshold):
if (vehicle_present==1 and i == 0):
vehicle_present = 0
i= i+1
end_interval()
# Interval ends if the vehicle_max_lat_threshold
# and vehicle_min_lat_threshold exceeds
elif not(vehicle_lat_offset > vehicle_min_lat_threshold and
vehicle_lat_offset < vehicle_max_lat_threshold):
if (vehicle_present==1 and i == 0):
vehicle_present = 0
i= i+1
end_interval()
on @i_end:
if(data.end_time>data.start_time):
total_time = total_time + data.end_time - data.start_time
else :
total_time = total_time + top.time - data.start_time
on @i_clock:
data.actor_id = actor_id
data.interval_count = interval_count
data.vehicle_lon_time_gap = vehicle_lon_time_gap
data.vehicle_lat_offset = vehicle_lat_offset
global modifier npc_vehicle.ego_vehicle_zone_check:
vehicle_min_time_gap : time = 0s
vehicle_front_max_time_gap: time = 5s
vehicle_back_max_time_gap: time = -1s
vehicle_min_lat_offset : length = 0.01m
vehicle_max_lat_offset : length = 5m
watcher ego_front_left_zone_limit_watcher_for_vehicle is ego_zone_limit_watcher_for_vehicle(any_actor: actor,
vehicle_max_time_gap_threshold : vehicle_front_max_time_gap, vehicle_min_time_gap_threshold : vehicle_min_time_gap,
vehicle_max_lat_threshold : vehicle_max_lat_offset, vehicle_min_lat_threshold : vehicle_min_lat_offset,
ego_dist_ref: front_center, vehicle_dist_ref: back_center)
watcher ego_front_right_zone_limit_watcher_for_vehicle is ego_zone_limit_watcher_for_vehicle(any_actor: actor,
vehicle_max_time_gap_threshold : vehicle_front_max_time_gap, vehicle_min_time_gap_threshold : vehicle_min_time_gap,
vehicle_max_lat_threshold : -1 * vehicle_min_lat_offset, vehicle_min_lat_threshold : -1 * vehicle_max_lat_offset,
ego_dist_ref: front_center, vehicle_dist_ref: back_center)
watcher ego_back_left_zone_limit_watcher_for_vehicle is ego_zone_limit_watcher_for_vehicle(any_actor: actor,
vehicle_max_time_gap_threshold : vehicle_min_time_gap, vehicle_min_time_gap_threshold : vehicle_back_max_time_gap,
vehicle_max_lat_threshold : vehicle_max_lat_offset, vehicle_min_lat_threshold : vehicle_min_lat_offset,
ego_dist_ref: back_center, vehicle_dist_ref: front_center)
watcher ego_back_right_zone_limit_watcher_for_vehicle is ego_zone_limit_watcher_for_vehicle(any_actor: actor,
vehicle_max_time_gap_threshold : vehicle_min_time_gap, vehicle_min_time_gap_threshold : vehicle_back_max_time_gap,
vehicle_max_lat_threshold : -1 * vehicle_min_lat_offset, vehicle_min_lat_threshold : -1 * vehicle_max_lat_offset,
ego_dist_ref: back_center, vehicle_dist_ref: front_center)
#----- code snippet end -----#
132.7 KPI
The performance metrics and the data items captured during the test execution are as follows:
| Name/Item | Description | Range | Unit / Type |
|---|---|---|---|
actor_id |
The unique id of the actor hitting the zone of the Ego | int | |
interval_count |
The sum of the interval count of the actor hitting the zone of the Ego | int | |
vehicle_lat_offset |
The relative lateral offset of the vehicle hitting the zone of the Ego | m | |
vehicle_lon_time_gap |
The relative longitudinal time gap of the vehicle hitting the zone of the Ego | s | |
plain_object_lat_offset |
The relative lateral offset of the plain object hitting the zone of the Ego | m | |
plain_object_lon_time_gap |
The relative longitudinal time gap of the plain object hitting the zone of the Ego | s | |
total_left_zone_count |
The sum of the interval count of the actor hitting the front left zone and back left zone of the Ego | int | |
total_right_zone_count |
The sum of the interval count of the actor hitting the front right zone and back right zone of the Ego | int | |
total_front_zone_count |
The sum of the interval count of the actor hitting the front left zone and front right zone of the Ego | int | |
total_back_zone_count |
The sum of the interval count of the actor hitting the back left zone and back right zone of the Ego | int | |
total_zone_count |
The sum of the interval count of the actor hitting the front left zone, front right zone, back left zone, and back right zone of the Ego | int | |
front_left_zone_duration |
The interval duration of the actor hitting the front left zone of the Ego | second | |
front_right_zone_duration |
The interval duration of the actor hitting the front right zone of the Ego | second | |
back_left_zone_duration |
The interval duration of the actor hitting the back left zone of the Ego | second | |
back_right_zone_duration |
The interval duration of the actor hitting the back right zone of the Ego | second | |
total_left_zone_duration |
The sum of the interval duration of the actor hitting the front left zone and back left zone | second | |
total_right_zone_duration |
The sum of the interval duration of the actor hitting the front right zone and back right zone | second | |
total_front_zone_duration |
The sum of the interval duration of the actor hitting the front left zone and front right zone | second | |
total_back_zone_duration |
The sum of the interval duration of the actor hitting the back left zone and back right zone | second | |
total_zone_duration |
The sum of the interval duration of the actor hitting the front left zone, front right zone, back left zone, and back right zone | second | |
left_zone_percentage |
The percentage of time the actor occupies the front left zone and back left zone of the Ego | float | |
right_zone_percentage |
The percentage of time the actor occupies the front right zone and back right zone of the Ego | float | |
front_zone_percentage |
The percentage of time the actor occupies the front left zone and front right zone of the Ego | float | |
back_zone_percentage |
The percentage of time the actor occupies the back left zone and back right zone of the Ego | float |

