Crosswalk elements
road_on_crosswalk
The road_on_crosswalk route element represents a driving route across a crosswalk. Crosswalks are provided to Foretify from the source map by the MSP as quadrilaterals.
They have a crosswalk_mark_type attribute that can be one of the following:
- solid
- transverse
- ladder
- diagonal_ladder
- bars
- spaced_bars
- bar_pairs
- none
- other
The also have a crosswalk_mark_color attribute that can be:
- white
- yellow
- green
- rainbow
- none
- other
The number of road_on_crosswalk occurrences corresponding to a single crosswalk can vary as follows:
- One occurrence per crosswalk if it is on a one-way road.
- Two occurrences per crosswalk if it is on a two-way road.
Two occurrences per crosswalk - More than two occurrences per crosswalk if it is part of a junction.
Six occurrences per crosswalk {straight, left, right} * {entering-junction, exiting-junction}
In a junction, a road_on_crosswalk occurrence can be reached either when entering or exiting the junction. The road_on_crosswalk_type enum classifies these occurrences based on their relationship to the road:
on_one_way- represents a singleroad_on_crosswalkoccurrence for a given crosswalk on a one-way road.on_two_way- indicates one of tworoad_on_crosswalkoccurrences for a given crosswalk on a two-way road.junction_entry- indicates that theroad_on_crosswalkis in an entry to a junction.junction_exit- indicates that theroad_on_crosswalkis in an exit from a junction.
OSC definition of road_on_crosswalk
# A crosswalk may be over a one-way-road, over a two-way-road or over multiple internal-roads
# at a junction. When inside a junction a vehicle may arrive at the crosswalk on its way
# into the junction or on its way out of the junction.
#
enum road_on_crosswalk_type: [other, on_one_way, on_two_way, junction_entry, junction_exit]
enum crosswalk_mark_type: [solid, transverse, ladder, diagonal_ladder, bars, spaced_bars, bar_pairs, none, other]
enum crosswalk_mark_color: [white, yellow, green, rainbow, none, other]
# road_on_crosswalk route element is a drive_route over a crosswalk.
# Start offset and end offset are the polygon borders of the crosswalk
#
struct road_on_crosswalk inherits road_element:
# ID (internal) of the crosswalk crossed by this element.
#
crosswalk_id: uint
# type of crosswalk crossed by this element
#
kind: road_on_crosswalk_type
# road marking type and color
#
mark_type: crosswalk_mark_type
mark_color: crosswalk_mark_color
road_to_crosswalk
The road_to_crosswalk route element represents a route that begins at the start of the overlapping or preceding one_way_road and ends precisely at the start of a road_on_crosswalk.
An exceptional case occurs when a crosswalk is located immediately after a junction, and the start of the nearest one_way_road is less than config.map.road_to_crosswalk_min_length (default of 10 meters) behind it. In this situation, the route is extended back to include the start of the one_way_road before the junction, resulting in multiple road_to_crosswalk occurrences for a single road_on_crosswalk.
In the exceptional case illustrated below, the road_on_crosswalk outlined in red is positioned just after exiting the junction, leading to three road_to_crosswalk occurrences connecting to it, one from each internal_road leading to it.
General case of road_to_crosswalk
In this image, road_on_crosswalk occurrences are highlighted in purple, and road_to_crosswalk occurrences are highlighted in green.
The road_to_crosswalk starts at the beginning of a one_way_road, leading to a road_on_crosswalk on the one_way_road.
There are two road_on_crosswalk occurences for a single crosswalk that covers two internal_roads. The two corresponding road_to_crosswalk occurences start at the beginning of the the previous one_way_road and overlap.
OSC definition of road_to_crosswalk
# road_to_crosswalk - a piece of road before a road_on_crosswalk. The element ends at the beginning of the
# road_on_crosswalk. It starts at the beginning of the containing or preceding one_way_road.
#
struct road_to_crosswalk inherits road_element:
road_on_crosswalk_id: uint
road_on_crosswalk: road_on_crosswalk with:
keep(it.id == self.road_on_crosswalk_id)
one_way_road_id: int
one_way_road: one_way_road with:
keep((self.one_way_road_id == -1 and it == null) or (self.one_way_road_id >=0 and it.id == self.one_way_road_id))
road_from_crosswalk
The road_from_crosswalk route element represents a route that starts precisely at the end of a road_on_crosswalk and ends at the end of the overlapping or following one_way_road.
The following image illustrates examples of road_from_crosswalk elements that follow road_on_crosswalk placements in different locations: at a junction entry, a junction exit and in the middle of a road (not in a junction).
When a crosswalk is located "very close" to a junction entry, but not classified as a junction_entry we may still want to mark road_from_crosswalk elements along the possible junction routes that follow it. In this context, "very close" is defined by the configuration variable config.map.road_to_crosswalk_min_length which specifies a threshold distance. If the forward distance from the crosswalk to the junction is less than this threshold, the system generates road_from_crosswalk elements for all junction routes, just as it would be for a road_on_crosswalk of kind junction_entry.
This case is illustrated in the following image where three road_from_crosswalk elements (highlighted in purple) follow a single road_on_crosswalk element (outlined in red), due to its close proximity to the junction.
OSC definition of road_from_crosswalk
# road_from_crosswalk - a piece of road after a road_on_crosswalk. The element starts at the end of the
# road_on_crosswalk. It ends at the end of the containing or following one_way_road.
#
struct road_from_crosswalk inherits road_element:
road_on_crosswalk_id: uint
road_on_crosswalk: road_on_crosswalk with:
keep(it.id == self.road_on_crosswalk_id)
one_way_road_id: int
one_way_road: one_way_road with:
keep((self.one_way_road_id == -1 and it == null) or (self.one_way_road_id >=0 and it.id == self.one_way_road_id))
get_roadside_position_by_crosswalk modifier
The purpose of the get_roadside_position_by_crosswalk modifier is to provide the start or end positions for a pedestrian crossing a specified road_on_crosswalk element, which is typically along the path of the Ego.
Modifier get_roadside_position_by_crosswalk has a single output parameter, position, which is an msp_position specifying a position by a crosswalk.
The input parameters of get_roadside_position_by_crosswalk are as follows.
| Parameter | Description |
|---|---|
road_on_crosswalk |
The specific road_on_crosswalk element for which you want to determine the position. |
side |
Indicates which side of the road_on_crosswalk (left or right relative to the driving direction) you want to get the position for. |
lon_offset |
A longitudinal offset specified in road coordinates from the start of the road_on_crosswalk element. |
path_fraction |
An alternative to lon_offset, this parameter specifies the longitudinal offset as a percentage of the length of the road_on_crosswalk element. The value is an integer in the range [0..100]. |
lat_offset |
A lateral offset relative to the outermost edge of the driving lane, such as the boundary between the driving lanes and the curb. Following the Foretify convention, lat_offset is directional according to the right-hand rule: positive values indicate a leftward direction, and negative values indicate a rightward direction, based on the orientation of the road_on_crosswalk parameter. |
OSC definition of get_roadside_position_by_crosswalk
# Get a position on the road-side (e.g., curb or shoulder) along some crosswalk
#
modifier top.get_roadside_position_by_crosswalk:
# Output properties
# The resulting position generated from defined input properties
#
position: msp_position with:
properties(it, required: true)
# Input properties
# Input 'road_on_crosswalk', used for defining the reference route
#
road_on_crosswalk: road_on_crosswalk with:
properties(it, required: true)
# 'side', on which side of the road is the requested position
#
side: av_side with:
properties(it, required: true)
# Sets a longitudinal offset from the start of the crosswalk.
# Offset must be positive and less than or equal to road_on_crosswalk.length.
#
lon_offset: length with:
properties(it, exclusive_sets: ["lon_pos"])
keep(lon_offset >= 0m and lon_offset <= road_on_crosswalk.length)
# Sets a longitudinal reference by defining a fraction of the total crosswalk length.
# Value must be in [0..100], otherwise 'lon_offset' parameter is used.
#
path_fraction: int with:
properties(it, exclusive_sets: ["lon_pos"])
keep(default path_fraction == -1)
# Lateral offset from the edge of the crosswalk
#
lat_offset: length with:
properties(it)
keep(default it == 0m)
Example using get_roadside_position_by_crosswalk modifier
In this scenario, the SUT’s route crosses a crosswalk while exiting a junction in a left turn. A pedestrian is crossing in parallel with the SUT drive. A possible result is illustrated in the following image. The SUT and its planned path are green, the pedestrian is highlighted yellow, and the road_on_crosswalk occurrences are marked in purple.
Example scenario using get_roadside_position_by_crosswalk modifier
import "$FTX/env/basic/exe_platforms/model_ssp/config/model_dummy_config.osc"
import "$FTX/env/basic/msp/open_drive.osc"
extend test_config:
set map = "$FTX/packages/maps/M499_FTX_suburban.xodr"
scenario sut.turn_left_to_crosswalk_with_pedestrian_from_left:
p: person
start_pos: msp_position
mid_pos: msp_position
end_pos: msp_position
# road_on_crosswalk - a road route congruent with a crosswalk arrived at when departing a junction.
#
road_on_crosswalk: road_on_crosswalk with:
keep(it.kind == junction_exit)
# road_to_crosswalk - a road route reaching 'road_on_crosswalk'.
#
road_to_crosswalk: road_to_crosswalk with:
keep(it.road_on_crosswalk == self.road_on_crosswalk)
# left_turn - a left-turn internal_road.
#
left_turn: internal_road with:
keep(it.direction in [slight_left, left, sharp_left])
road_from_crosswalk: road_from_crosswalk with:
keep(it.road_on_crosswalk == self.road_on_crosswalk)
position_along_road(end_pos,
road_from_crosswalk,
lon_offset: 20m,
outermost_lane: true,
lat_offset: -1m,
lat_reference: right)
# set 'start_pos' on the left side of the crosswalk, 1 meter away from the road's edge
# (could be on sidewalk or on shoulder or in a position that is not on the road-network).
#
get_roadside_position_by_crosswalk(start_pos, road_on_crosswalk, left, lon_offset: 1m, lat_offset: 1m)
# set 'mid_pos' on the right side of the crosswalk, 1 meter away from the road's edge
# (could be on sidewalk or on shoulder or in a position that is not on the road-network).
#
get_roadside_position_by_crosswalk(mid_pos, road_on_crosswalk, right, lon_offset: 2m, lat_offset: -1m)
do parallel(overlap: start):
serial:
m1: p.move(mid_pos, start_position: start_pos, duration: 10s)
m2: p.move(end_pos, duration: 10s)
serial:
a: sut.car.drive(duration: 10s) with:
a1: along(road_to_crosswalk, at: start)
a2: along(left_turn, at: end, run_mode: best_effort)
b: sut.car.drive(duration: 10s) with:
b1: along(road_on_crosswalk, at: start, run_mode: best_effort)
b2: along(road_from_crosswalk, at: end, run_mode: best_effort)
b3: speed(20kph, at: end, run_mode: best_effort)
extend top.main:
do sut.turn_left_to_crosswalk_with_pedestrian_from_left()