Skip to content

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_index
    A 1-based index starting from the lane closest to the road center. This is the default indexing used by the modifier vehicle.lane().

  • merging_lane
    The 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

OSC2 code: route elements 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

OSC2 code: route elements 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.