Skip to content

Foretellix Driver examples

Example: shift behavior

OSC2 code: shift behavior
import "$FTX/env/basic/exe_platforms/model_ssp/config/model_sumo_config.osc"

extend test_config:
    set map = "$FTX_PACKAGES/maps/M77_FTX_highway_straight_long_road.xodr"
    # avoiding implicit moves to make sure that in specified time to trigger the shift command, 
    # the main scenario will be already active.
    set implicits_kind = none

scenario sut.shift_example:
    do serial:
        # creating a simple scenario with constant speed on a straight road.
        sut.car.drive(duration : 10second) with:
            speed(speed: 10mps)
            # unless specified as "best_effort" once the shift cause a lane change the scenario will fail. 
            lane(1, run_mode: best_effort)

extend top.main:
    do sut.shift_example()

extend sut.shift_example:
    # adding an event to trigger the shift, in this case a specific time event: time == 1 second.
    on @top.clk if (top.time == 1s):
        # creating a new shift command:
        #     shift lateral position by: 3.5 meters to the right (approx. 1 lane)
        #     shift type: additve - meaning the shift value will be ADDED to the actor's current lateral position
        #                           (for absolute type, the shifted value will REPLACE the current position).
        #     ramp up duration: 5 seconds - the time requested for the shift to be implemented fully.
        #                                   (if the input duration is too short, the shift will perform as soon as 
        #                                   possible within its physical boundaries and capabilities).
        call sut.car.set_bm_shift_lateral_position(shift: -3.5m, shift_type: additive, ramp_up_duration: 5s)

Example: LSS-ELK

OSC2 code: test LSS-ELK function
import "$FTX/env/basic/adas_hlm_imps/LSS/lss_hlm_imp.osc"

extend test_config:
    set map = "$FTX/qa/odr_maps/straight_long_road.xodr"
    set implicits_kind = none
    set test_drain_time = 0second

extend sut_vehicle:
    # Disabling the steering once ELK engages.
    # Preventing the ftx_driver from trying to make the lane change at the second time.
    def post_plan() is also:
        ftx_driver.adas_override_behavior.adas_steering_override_reaction.steering_control = disable
        hlm_driver.lss_behavior.lss_behavior_params.engaged_duration = 8second

scenario sut.lss_hlm_elk_with_obstacle:
    LSS_speed: speed with:
        keep(it==15mps)

    car1: vehicle

    do serial():

        sut.car.request_LSS_mode(state: active, use_elk: true)

        sut.car.turn_signal(turn_signal_state: right_on)

        parallel(overlap:equal):
            car1.drive(duration: 7second) with:
                position(distance: 100m, at: start)
                speed(speed: LSS_speed, at: start)
                speed(speed: LSS_speed, at: end)
                lane(2)

            lane_change_attempt: sut.car.drive() with:
                position(0meter, ahead_of: car1, at: start)
                speed(speed: 0mps, faster_than: car1, at: start)
                speed(speed: LSS_speed, at: end)
                lane(1, at: start)
                lane(3, at: end, run_mode: best_effort)
                avoid_collisions(false)

Example: LSS-LKA

OSC2 code: test LSS-LKA function
import "$FTX/env/basic/adas_hlm_imps/LSS/lss_hlm_imp.osc"

extend test_config:
    set map = "$FTX/qa/odr_maps/M85_FTX_highway_figure8_R200m.xodr"
    set test_drain_time = 0second

scenario sut.lss_hlm_without_turn_signal:

    start_point: odr_road with:
        keep(start_point.odr_id == 2 and start_point.sub_id == -1)

    LSS_speed: speed with:
        keep(it in [50..60]kph)

    do serial():

        pre_lss_request: sut.car.drive(duration: [1..2]second) with:
            s1: speed(speed: LSS_speed)
            override(s1, run_mode: best_effort)
            along(start_point, at: start, start_offset: 15m)
            lane(2)

        sut.car.request_LSS_mode(state: active)

        pre_lss_drive: sut.car.drive(duration: [1..2]second) with:
            s2: speed(speed:  LSS_speed)
            override(s2, run_mode: best_effort)

        lss_drive: sut.car.drive(duration: [5..15]second) with:
            driver_controls(steering: disabled)
            s3: speed(speed:  LSS_speed)
            override(s3, run_mode: best_effort)

Example: turn signal

OSC2 code: demonstrates turn signal activation by the FTX Driver
import "$FTX/env/basic/exe_platforms/model_ssp/config/model_sumo_config.osc"
import "$FTX/env/basic/msp/open_drive.osc"


extend test_config:
    set map = "$FTX_PACKAGES/maps/Town04.xodr"
    set test_drain_time=0second
    set implicits_kind=none #ensure cars start at non-0 speed

extend top.main:
    do sut.vehicle_turns_at_junction()

extend ftx_driver:
    def post_plan() is also:
        executor_manager_params.turn_signals_controller_params.post_maneuver_signal_duration = 0s

scenario sut.vehicle_turns_at_junction:
    SUT_LON_SPEED: speed with:
        keep(it == 10mps)

    SUT_START_OFFSET: length with:
        keep(it == 35meter)

    start_sut_road_odr: odr_road
    end_sut_road_odr: odr_road

    #start position of SUT
    keep(start_sut_road_odr.odr_id == 30 and start_sut_road_odr.sub_id == -1)
    # end position of SUT
    keep(end_sut_road_odr.odr_id == 0)

    do vehicle_turns_at_junction: serial():
        sut_drive: serial():
            sut.car.drive() with:
                speed(SUT_LON_SPEED, at: start, run_mode: best_effort)
                speed(SUT_LON_SPEED, at: end, run_mode: best_effort)
                along(start_sut_road_odr, at: start, start_offset: start_sut_road_odr.length - SUT_START_OFFSET)
                along(end_sut_road_odr, at: end)

Example: Call update_config to update the behavior_param value for the junction behavior

OSC2 code: Call update_config to update the behavior_param value for the junction behavior
import "$FTX/env/basic/exe_platforms/model_ssp/config/model_sumo_config.osc"
# This scenario uses the update_config function to update the config param of junction behavior
extend test_config:
    set map = "$FTX_PACKAGES/maps/M38_FTX_urban_junctions_with_sgns.xodr"
    set implicits_kind = none

extend ftx_driver:
    # enable of the junction behavior is set to true
    keep(junction_behavior.enable == true)

scenario sut.example:
    start_sut_road_odr: odr_road
    keep(start_sut_road_odr.odr_id == 11)

    do serial:
        sut.car.drive(duration : 10second) with:
            along(start_sut_road_odr, at: start, start_offset: 4m)
            speed(4mps, at: start, run_mode: best_effort)

extend top.main:
    do sut.example()

extend sut.example:
    # adding an event to trigger disable of the junction_behavior
    on @top.clk if (top.time == 1s):
        # set enable param to false
        sut.car.ftx_driver.junction_behavior.enable = false
        #call to update_config function to update the config param of junction behavior
        call sut.car.ftx_driver.junction_behavior.update_config()

Example: The red_flashing traffic light state

OSC2 code: The red_flashing traffic light state
# Copyright (c) 2023 Foretellix Ltd. All Rights Reserved.
import "$FTX/env/basic/exe_platforms/model_ssp/config/model_sumo_config.osc"
import "$FTX/env/basic/msp/open_drive.osc"

extend test_config:
    set map = "$FTX_PACKAGES/maps/M510_FTX_TrafficSignals_Simple.xodr"
    set implicits_kind = none

extend ftx_driver:
    keep(junction_behavior.enable == true)

# The scenario sut_drives_over_junction is defined as sut drives over junction with road following and traffic light
scenario sut_drives_over_junction:
    p: roads_follow_in_junction_with_tl
    start_sut_road_odr: odr_road

    SUT_START_POSITION: length with:
        keep(default it == 10meter)

    SUT_LON_SPEED: speed with:
        keep(default it == 5mps)

    do serial():
        at_junction: sut.car.drive() with:
            along(p.in_road, at: start)
            along(start_sut_road_odr, at: start, start_offset: start_sut_road_odr.length - SUT_START_POSITION)
            speed(SUT_LON_SPEED, run_mode: best_effort)

# The scenario junction_traffic_light is defined road with traffic light on internal_road and the traffic light state is updated to stop_constant(red_flashing)
scenario junction_traffic_light:
    tl: traffic_light
    p: roads_follow_in_junction_with_tl

    event tl_event
    on @tl_event: 
        # Update the traffic light state to stop_constant(red_flashing)
        var res_sut := map.update_internal_road_tl_state(p.internal_road, stop_constant)

    do serial(duration:10s):
        emit tl_event
        wait elapsed(10s)

extend top.main:
    p: roads_follow_in_junction_with_tl
    do parallel():
        sut_drives_over_junction(p: p)
        junction_traffic_light(p: p)

extend sut_drives_over_junction:
    keep(start_sut_road_odr.odr_id == 2 and start_sut_road_odr.sub_id == -1)

Example: Configure when vehicles are considered to arrive at a junction at the same time

OSC2 code: Configure when vehicles are considered to arrive at a junction at the same time
import "$FTX/env/basic/exe_platforms/model_ssp/config/model_sumo_config.osc"

# This scenario uses the same_time_arrival_resolution definition for Junction Behavior.
# Two vehicles are presented arriving at the same speed and starting their 
# drive at the same distance from a junction.
# Both vehicles will arrive at the junction at the same time and stop at the stop line. 

extend test_config:
    set map = "$FTX_PACKAGES/maps/M38_FTX_urban_junctions_with_sgns.xodr"
    set implicits_kind = none

extend top.main:
    start_sut_road_odr: odr_road
    keep(start_sut_road_odr.odr_id == 11)

    vehicle: vehicle
    start_npc_road_odr: odr_road
    keep(start_npc_road_odr.odr_id == 12)

    do parallel(duration:[15..25]s):
        serial:
            sut.car.drive() with:
                along(start_sut_road_odr, at: start, start_offset: 4m)
                speed(4mps, at: start, run_mode: best_effort)
        serial():
            vehicle.drive() with:
                along(start_npc_road_odr, at: start, start_offset: 4m)
                speed(4mps, at: start, run_mode: best_effort)

extend ftx_driver:
    keep(junction_behavior.enable == true)
    def post_plan() is also:
        # set same_time_arrival_resolution param of junction behavior to 1s default value is [0.5 .. 2]s
        junction_behavior.same_time_arrival_resolution = 1s

Example: Unknown traffic light states

OSC2 code: Unknown traffic light states
# Copyright (c) 2023 Foretellix Ltd. All Rights Reserved.
import "$FTX/env/basic/exe_platforms/model_ssp/config/model_sumo_config.osc"
import "$FTX/env/basic/msp/open_drive.osc"

extend test_config:
    set map = "$FTX_PACKAGES/maps/M510_FTX_TrafficSignals_Simple.xodr"
    set implicits_kind = none

extend ftx_driver:
    keep(junction_behavior.enable == true)

# The scenario sut_drives_over_junction is defined as sut drives over junction with road following and traffic light
scenario sut_drives_over_junction:
    p: roads_follow_in_junction_with_tl
    start_sut_road_odr: odr_road

    SUT_START_POSITION: length with:
        keep(default it == 10meter)

    SUT_LON_SPEED: speed with:
        keep(default it == 5mps)

    do serial():
        at_junction: sut.car.drive() with:
            along(p.in_road, at: start)
            along(start_sut_road_odr, at: start, start_offset: start_sut_road_odr.length - SUT_START_POSITION)
            speed(SUT_LON_SPEED, run_mode: best_effort)

# The scenario junction_traffic_light is defined road with traffic light on internal_road and the traffic light state is updated to unknown
scenario junction_traffic_light:
    tl: traffic_light
    p: roads_follow_in_junction_with_tl

    event tl_event
    on @tl_event: 
        # Update the traffic light state to unknown
        var res_sut := map.update_internal_road_tl_state(p.internal_road, unknown)

    do serial(duration:10s):
        emit tl_event
        wait elapsed(10s)

extend top.main:
    p: roads_follow_in_junction_with_tl
    do parallel():
        sut_drives_over_junction(p: p)
        junction_traffic_light(p: p)

extend sut_drives_over_junction:
    keep(start_sut_road_odr.odr_id == 2 and start_sut_road_odr.sub_id == -1)

Example: OC Trajectory

OSC2 code: OC Trajectory
import "$FTX/env/basic/exe_platforms/model_ssp/config/model_sumo_config.osc"
import "$FTX/env/basic/msp/open_drive.osc"

extend test_config:
    set test_drain_time = 0second
    set map = "$FTX_PACKAGES/maps/M494_FTX_straight_road_1040m_3x3.xodr"
    set implicits_kind = none



scenario sut.oc_example:
    oc_vehicle: vehicle
    keep(oc_vehicle.ftx_driver.trajectory_manager_params.oc_trajectory_generator_params.enable == true)
    d_behind: length with:
        keep(it == 100meter)
    d_oc_ahead_min: length with:
        keep(it == 10meter)
    d_oc_ahead_max: length with:
        keep(it == 20meter)

    do oc_example: serial():
            init_drive: parallel(overlap: equal):
                sut.car.drive() with:
                    avoid_collisions(false)
                oc_vehicle.drive() with:
                    avoid_collisions(false)
                    position(distance: d_behind, behind: sut.car, at: start)
                    position(distance: [d_oc_ahead_min..d_oc_ahead_max], ahead_of: sut.car, at: end)
                    speed(speed: [-5..5]kph, faster_than: sut.car, at: end)
                    lane(same_as: sut.car, at: end)
            with:
                duration([15..25]s, run_mode: best_effort)


extend top.main:
    do a : sut.oc_example()

Example: Unprotected left turn on a traffic light junction

OSC2 code: Unprotected left turn on a traffic light junction
# Copyright (c) 2024 Foretellix Ltd. All Rights Reserved.
import "$FTX/env/basic/exe_platforms/model_ssp/config/model_sumo_config.osc"
import "$FTX/env/basic/msp/open_drive.osc"

import "$FTX/ext_modules/foretify_top/driver/behavior_layer/ftx_behaviors/junction/test/integration_tests/check_trafic_light_sequence/SUT_drive_through_traffic_light_junction_imp.osc"
import "$FTX/ext_modules/foretify_top/driver/behavior_layer/ftx_behaviors/junction/test/integration_tests/check_trafic_light_sequence/NPC_drive_through_traffic_light_junction_imp.osc"
import "$FTX/ext_modules/foretify_top/driver/behavior_layer/ftx_behaviors/junction/test/integration_tests/check_trafic_light_sequence/SUT_drive_through_traffic_light_junction_checks.osc"

# In this test, we create a situation where SUT arrives at a junction that tl is unprotected left.
# the SUT should stop at the tl (green light) and wait for the npc to pass. after that perform a left turn on green light.
# we check:
    #3# SUT_STOPPED_ON_JUNCTION_ENTRY - check that SUT stopped at the junction entry and distance to stop line is correct
    #5# SUT_CROSS_THE_STOP_LINE - check that SUT cross the stop line8
    #4# EXPECT_SUT_ENTERED_LAST -check that SUT move second at the junction entry

#               | NPC straight|   
#               | internal   |
#               |  road= 714|
#          _____|            |______
#                 
#                             
#        --------            ---------
#            ___              ___
#               | SUT left direction   
#               | internal   |
#               | road = 746 |

extend test_config:
    set map = "$FTX/ext_modules/foretify_top/driver/behavior_layer/ftx_behaviors/junction/test/integration_tests/check_trafic_light_sequence/M639_FTX_JunctionExamples.xodr"

extend top.main:
    p: roads_follow_in_junction_with_tl with:
        keep(it.internal_road.direction == left and it.internal_road.valid_tl_go and not it.internal_road.valid_tl_go_exclusive)
    p_npc: roads_follow_in_junction_with_tl with:
        keep(it.internal_road.direction == straight and it.internal_road.valid_tl_go_exclusive and not it.internal_road.valid_tl_go)

    roads_enter_junction_relation(in_road1: p.in_road, in_road2: p_npc.in_road, relative_direction: opposite)

    keep(p.internal_road.junction_id == p_npc.internal_road.junction_id)

    speed: speed with:
        keep(default it in [0..20]mps)

    do parallel(overlap: equal):
        sut_drives_over_junction(p: p, SUT_LON_SPEED: speed)
        npc_drives_through_taffic_light_junction(p: p_npc, NPC_LON_SPEED: speed)
    with: duration([15..20]s, run_mode: best_effort)

extend npc_drives_through_taffic_light_junction:
    keep(NPC_START_POSITION == 3meter)
    keep(NPC_LON_SPEED == 7mps)

    in npc_at_junction with:
        override(keep_lane, run_mode: disable) #keep_lane is not used in this test
        lane(2, from: curb, at: start, run_mode: best_effort)
        lane(2, from: curb, at: end, run_mode: best_effort)

extend sut_drives_over_junction:
    set SUT_STOPPED_ON_JUNCTION_ENTRY = true
    set SUT_CROSS_THE_STOP_LINE = true
    set EXPECT_SUT_ENTERED_LAST = true

    keep(SUT_START_POSITION == 15meter)
    keep(SUT_LON_SPEED == 7mps)

extend ftx_driver:
    keep(collision_avoidance_behavior.enabling_policy == always_disabled)

# Since collision avoidance constraints in generation prevent the generation of the needed scenario, we disable them; we do it this way and not by using the avoid_calising(false) modifier because of the generation issue.
extend internal_model_controls:
    set no_collision_disabled = true