Other road classifications
road_with_merging_lane
The road_with_merging_lane route element represents a sequence of two lane_section occurrences where the number of lanes decreases from the first section to the next. The route associated with this element corresponds to the first lane_section. It includes two members that specify the “merging-lane” - a lane that does not have a successor/next lane:
-
merging_lane_indexA 1-based index starting from the lane closest to the road center. This is the default indexing used by the modifier vehicle.lane(). -
merging_laneThe lane route element occurrence that corresponds to the merging lane.
In the image below, occurrences of road_with_merging_lane are highlighted in green.
OSC definition of road_with_merging_lane
# road_with_merging_lane - subsequent lane_sections with decreasing number of lanes
#
struct road_with_merging_lane inherits road_element:
# The first lane_section. In this section, there are driving lanes that do not have a successor
# lane in the next lane_section 'less_lanes_road'.
#
more_lanes_road: lane_section
more_lanes_road_id: uint
# The second lane_section, it has fewer lanes than 'more_lanes_road'
#
less_lanes_road: lane_section
less_lanes_road_id: uint
keep(more_lanes_road.id ==more_lanes_road_id )
keep(less_lanes_road.id ==less_lanes_road_id )
# Index of lane in 'more_lanes_road' that does not have a successor in 'less_lanes_road':
# value 1 represents the lane closest to the road center and 'more_lanes_road.lanes' represents
# the lane closest to curb. As such 'merging_lane_index' can be given to 'vehicle.lane()'
# modifier (leaving all its other arguments defaulted)
#
merging_lane_index: uint
# The 'lane' route element corresponding to the merging-lane
#
merging_lane_id: uint
merging_lane: lane with:
keep(it.id == merging_lane_id)
Example using road_with_merging_lane
In this example, the SUT and NPC drive along a route with a decreasing number of lanes. The SUT starts in the lane that merges or ends, and the NPC starts on the lane left of it. A possible result is illustrated in the following image. The SUT and its planned path are green, and the NPC vehicle and its planned path are blue.
Scenario using road_with_merging_lane
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/M56_FTX_highway_prague.xodr"
scenario sut.merging_lane_conflict:
npc: vehicle
# road_with_merging_lane - subsequent lane_section occurrences with decreasing number of lanes.
#
road_with_merging_lane: road_with_merging_lane
do parallel(overlap: equal, duration: [3..6]s):
serial:
sut.car.drive() with:
along(road_with_merging_lane.merging_lane, at: start)
along(road_with_merging_lane.less_lanes_road, at: end)
serial:
npc.drive() with:
along(road_with_merging_lane, at: start)
along(road_with_merging_lane.less_lanes_road, at: end)
lane(1, left_of: sut.car, at: start)
keep_lane()
extend top.main:
do sut.merging_lane_conflict()
road_with_facing_road
The road_with_facing_road element represents a pair of one_way_roads - 'main' and 'facing' - that enter a junction from opposite directions. Continuing straight from the 'facing' road (crossing the junction) leads to the one_way_road that travels in the opposite direction of the 'main' road. This element can be used to generate traffic arriving from the opposite side of a junction.
In the image below, road_with_facing_road occurrences are highlighted in purple. Each occurrence corresponds to one one_way_road.
For the road_with_facing_road occurrence outlined in blue:
- main is the one_way_road occurrence outlined in blue.
- facing the one_way_road occurrence outlined in red.
For the road_with_facing_road occurrence outlined in red:
- main is the one_way_road occurrence outlined in red.
- facing is the one_way_road occurrence outlined in blue.
OSC definition of road_with_facing_road
# road_with_facing_road - pairs two roads with opposite traffic directions from different sides of a junction.
# I.e., driving straight from 'facing' via junction 'facing.in_junction_id' leads to the opposite of 'main'
#
struct road_with_facing_road inherits road_element:
# a one_way_road
#
main: one_way_road
# driving straight from 'facing' via junction 'facing.in_junction_id' leads to the opposite of 'main'
#
facing: one_way_road
facing_id: int
main_id: int
keep(facing.id == facing_id)
keep (main.id == main_id)
Example using road_with_facing_road
SUT and NPC crossing the junction from opposite directions in the innermost lanes.
Example scenario using road_with_facing_road
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.facing_roads:
facing_roads: road_with_facing_road
sut_route: roads_follow_in_junction with:
keep(it.in_road == facing_roads.main and it.internal_road.direction == straight)
npc_route: roads_follow_in_junction with:
keep(it.in_road == facing_roads.facing and it.internal_road.direction == straight)
npc: vehicle
do parallel(overlap: equal):
serial:
sut.car.drive() with:
along(sut_route.in_road, end_offset: [10..20]m, at:start)
along(sut_route.out_road, at:end)
lane(innermost: true)
serial:
npc.drive() with:
along(npc_route.in_road, end_offset: [10..20]m, at:start)
along(npc_route.out_road, at:end)
lane(innermost: true)
extend top.main:
do sut.facing_roads()
road_with_opposite and road_with_opposite_side
The road_with_opposite_side route element represents a one-way route that has an opposing one-way route driving in the opposite direction from start to end. These routes consist of a list of msp_roads see MSP Implementation Guide.
This road element is defined exclusively on a one_way_road. It includes fields to specify the one_way_road it applies to, as well as the start and end offsets along that road.
The road_with_opposite element refers to a pair of road_with_opposite_side lanes that have opposite driving directions.
Classification of opposite routes depends on the designation of opposite msp_roads by the MSP, indicated by msp_road.opposite_road != null.
Recall that a route R is a list of connected msp_roads, along with start-offset, end-offset, and ranges of lanes on each msp_road (though those details can be omitted here). We can denote the i-th msp_road in R as by R[i], and R.size() as the total number of msp_roads in R.
Two routes, A and B, are considered opposite if:
- A.size() == B.size()
- A[i].
opposite_road== B[B.size()-1-i], for i in [0 .. A.size()-1] - The lateral distance between pairs of opposite msp_roads along the routes is at most
config.map.oncoming_threshold(20cm by default) along a portion of at least 1;config.map.oncoming_exceeded_samples_threshold(0.8 by default) of the msp_road’s length.
The road_with_opposite route element is a pair <main, opposite> of road_with_opposite_side elements that are opposite to each other. For every pair <R1, R2> of opposite road_with_opposite_side occurrences there are two road_with_opposite occurrences, one for ordered pair <R1, R2> and one for ordered pair <R2, R1>.
The route associated with a road_with_opposite occurrence corresponds to the route of road_with_opposite.main.
In the image below, road_with_opposite occurrences are highlighted in brown. The red and blue outlined occurrences are an example of two occurrences that contain the same pair of road_with_opposite_side occurrences in different order <red, blue> and <blue, red>.
OSC definition of road_with_opposite and road_with_opposite_side
# road_with_opposite_side - a longest piece of driving-route for which we can uniquely determine an opposite
# driving-route
#
struct road_with_opposite_side inherits road_element:
one_way_road_id: uint
one_way_road: one_way_road with:
keep(it.id == one_way_road_id)
one_way_road_start_offset: length
one_way_road_end_offset: length
# road_with_opposite - packs pairs of opposite 'road_with_opposite_side' elements. The route associated with this
# element is the same that of its 'main' member
#
struct road_with_opposite inherits road_element:
# main 'road_with_opposite_side'
#
main_id: uint
main: road_with_opposite_side with:
keep(it.id == self.main_id)
# opposite 'road_with_opposite_side'
opposite_id: uint
opposite: road_with_opposite_side with:
keep(it.id == self.opposite_id)
Example scenarios using road_with_opposite and road_with_opposite_side
These elements are used in the scenarios for the slope_section example and road_curvature example.