Urban Backend API reference

This reference discusses the APIs the urban backend provides, and offers some examples to help user understand how to use these APIs.


Intersection

The Intersection class defines a normal intersection as is discussed in urban_backend_introduction. The Intersection class provides methods for users to add vehicles and customize traffic light. Therefore, users will having most of their time play with the Intersection class when trying to create urban simulation scenarios.

Instance Variables

  • world_pos(tuple, (float,float))
    The (x,y) location of the center of this Intersection in terms of the carla world coordinate. As is discussed in the urban_backend_introduction, the world pos is derived by taking average of the location of the 4 traffic lights inside the intersection.

  • distance(float)
    The side length of the intersection, as is discussed in urban_backend_introduction. The unit for distance is meter.

  • yaw(float)
    The angle for indicating the direction the ego vehicle will go through the intersection,as is discussed in urban_backend_introduction. yaw is in the range [0,360), with degree as its unit.

  • start_sim_distance(float)
    Variable to determine the start simulation condition of an Intersection (i.e. the blue region shown in the gif in Normal Intersection introduction)

  • navigation_speed(float)
    The max speed for the vehicle to navigate in the this section.

Method

  • add_vehicle(self, gap = 10.0, model_name = "vehicle.tesla.model3", choice = "subject", command = "straight", stop_choice = "normal", penetrate_distance = None,obey_traffic_lights = True, run = True, safety_distance = 15.0, vehicle_color = None)
    Add a vehicle to a chosen lane, as is discussed in the lane section and the vehicle section

    • Parameters

      • gap : float,optional
        the distance between a vehicle and its previous one. Default is 10 meter
      • model_name : string, optional
        vehicle model type. The default is "vehicle.tesla.model3".

      • choice : string, optional
        the lane this vehicle will be added, valid values: "subject", "left", "right", "ahead". The default is "subject".
        Note: 1. use " instead of ', 'subject' is invalid. This rule applies to all the string variables. 2. "ahead" is essentially the opposite direction as discussed in the lane section

      • command : string, optional
        the turning command, valid values: "straight", "right", "left"

      • stop_choice : string, optional
        how will the vehicle stop when at yellow or red light. valid values: "normal", "abrupt", "penetrate"

      • penetrate_distance : float, unit: meter
        to what extent the vehicle will penetrate the traffic lane. This parameter will only be use when stop_choice is "penetrate"

      • obey_traffic_light : bool, optional
        whether the vehicle will obey traffic light. Default is True

      • run : bool, optional
        whether the vehicle is running. Default is True

      • safety_distance : float, optional
        smallest distance between this vehicle and vehicle ahead. Default is 15 meters.

      • vehicle_color : string, optional
        custom string representation of the RGB color of the vehicle. The string should be in the format 'R,G,B', where R,G,B are integer values. For example, blue is represented as (R,G,B) = (47, 210, 231), then the input string should be '47,210,231'. The default is None, meaning using the default color for the vehicle.

    • Return

      • uniquename : the uniquename of the vehicle
        Note: uniquename is used to reference a vehicle in the backend and cannot change once being assigned. If user want to give the vehicle their own name, remember to store the uniquename.
  • remove_vehicle(self,uniquename)
    remove a specific vehicle from the intersection

    • Parameters
      • uniquename : string. The uniquename of the vehicle.
  • _shift_vehicles(self, length, choice = "subject", index = 0)
    shift the location of a list of vehicles

    • Parameters

      • length : float.
        the length we want to shift all the vehicles

      • choice : string, optional
        the lane this vehicle will be added, valid values: "subject", "left", "right", "ahead". The default is "subject".
        Note : "ahead" is the opposite direction

      • index : int, optional.
        the index of the vehicle that shifting. The default is 0.

  • edit_vehicle_settings(self, uniquename, choice, gap = 10.0,model_name = "vehicle.tesla.model3", command = "straight", stop_choice = "normal", penetrate_distance = None,obey_traffic_lights = True, run = True, safety_distance = 15.0, vehicle_color = None)
    Edit settings of an other type vehicle with the vehicle's uniquename and the lane choice.

    Note: This function will modify the vehicle's uniquename if editing is successful, or return None if failed. Please remember to store the new uniquename

    • Parameters

      • uniquename : the uniquename of the vehicle
      • choice : string
        the lane this vehicle will be added, valid values: "subject", "left", "right", "ahead". Note: 1. use " instead of ', 'subject' is invalid. This rule applies to all the string variables. 2. "ahead" is essentially the opposite direction as discussed in the lane section

      • gap : float,optional
        the distance between a vehicle and its previous one. Default is 10 meter

      • model_name : string, optional
        vehicle model type. The default is "vehicle.tesla.model3".

      • command : string, optional
        the turning command, valid values: "straight", "right", "left"

      • stop_choice : string, optional
        how will the vehicle stop when at yellow or red light. valid values: "normal", "abrupt", "penetrate"

      • penetrate_distance : float, unit: meter
        to what extent the vehicle will penetrate the traffic lane. This parameter will only be use when stop_choice is "penetrate"

      • obey_traffic_light : bool, optional
        whether the vehicle will obey traffic light. Default is True

      • run : bool, optional
        whether the vehicle is running. Default is True

      • safety_distance : float, optional
        smallest distance between this vehicle and vehicle ahead. Default is 15 meters.

      • vehicle_color : string, optional
        custom string representation of the RGB color of the vehicle. The string should be in the format 'R,G,B', where R,G,B are integer values. For example, blue is represented as (R,G,B) = (47, 210, 231), then the input string should be '47,210,231'. The default is None, meaning using the default color for the vehicle.

    • Return

      • new_uniquename : the new of the vehicle
        Note: this method will call the add_vehicle method for intersection and generate a new uniquename. Please remember to store the new uniquename
  • edit_traffic_light(self,light, red_start = 0.0,red_end = 10.0,yellow_start = 10.0,yellow_end = 15.0,green_start = 15.0,green_end = 25.0)
    edit the start and end time for traffic colors the traffic color timeline will not loop i.e. after it reaches the end of timeline, the traffic state will be frozen at that state

    Requirements: there exists and only exists one start time at 0 otherwise, a red color will be used as placeholder until the first start time

    • Parameters

      • light : string, optional
        light choice, valid values: "subject", "left", "right", "ahead".
        Note : "ahead" is the opposite direction

      • *_start : float.
        start time of a specific color

      • *_end : float.
        end time of a specific coloring.
  • export_settings(self)
    export all settings for a specific intersection, as discussed in export section Click to view a demo of exported settings

    • Returns
      • intersection_settings : ConfigObj
        settings of the intersection
  • import_settings(self, intersection_settings)
    export all settings for a specific intersection, as discussed in export section Click to view a demo of exported settings

    • Parameters

      • intersection_settings : ConfigObj
        the intersection settings we want to import
    • Returns

      • new_intersection_setting : ConfigObj
        settings of the intersection this will be generated by call export_settings after finishing import output these settings are for the purpose of creating the front-end gui
  • get_vehicle_bounding_box(self, uniquename)
    get the bounding box of the vehicle specified by the uniquename

    • Parameters

      • uniquename : string the uniquename of the vehicle
    • Returns

      • new_bb : carla.Vector3D the bounding box of the vehicle. new_bb.x is the length, new_bb.y is the width, new_bb.z is the height
  • get_vehicle_settings(self, uniquename)
    Get the settings entered for a specific vehicle in this intersection based on uniquename

    • Parameters

      • uniquename : string the uniquename of the vehicle
    • Returns

      • vehicle_settings : ConfigObj
        the settings of the vehicle that have been entered

    Note: to get the settings of the vehicle, following keyword are valid:

    • "gap"
    • "model"
    • 'choice'
    • 'command'
    • 'stop_choice'
    • 'penetrate_distance'
    • 'obey_traffic_lights'
    • 'safety_distance'
    • 'vehicle_color'

    Only those settings user entered are shown here. Internel settings are hidden from users. Follow the code recipe below to get setting:

    vehicle_settings_entered = intersection.get_vehicle_settings(uniquename)
    model = vehicle_settings_entered["model"]
    

Init Intersection

Init intersection is designed for adding the full path vehicles in its subject lane, as discussed in Init Intersection

Init intersection class is inherited from the Intersection class, only new methods or overriden methods in Init Intersection will be shown below.

Instance Variables

  • ego_vehicle (ConfigObj)
    The configuration file for the ego vehicle

  • lead_vehicle (ConfigObj)
    The configuration file for the lead vehicle. If no lead vehicle available, value set to be None

  • follow_vehicle (ConfigObj)
    The configuration file for the follow vehicle. If no follow vehicle available, value set to be None

  • waypoint_list (list of carla.Waypoints)
    The list of waypoints used to form full navigation path.

  • subject_traffic_light_list (list of carla.TrafficLight)
    The list of traffic lights along the full navigation path.

  • navigation_speed(float)
    The max speed for the vehicle to navigate in the this section. This speed is also applied to the full path vehicles (i.e. ego, lead and follow vehicle, all are added in the init intersection)

Methods

  • add_ego_vehicle(self, gap = 10.0,model_name = "vehicle.tesla.model3", stop_choice = "abrupt", penetrate_distance = None, obey_traffic_lights = True, run = True, safety_distance = 0.0, vehicle_color = None)
    add the ego vehicle to the intersection

    • Parameters

      • gap : float,optional
        the distance between a vehicle and its previous one. Default is 10 meter
      • model_name : string, optional
        vehicle model type. The default is "vehicle.tesla.model3".

      • stop_choice : string, optional
        how will the vehicle stop when at yellow or red light. valid values: "normal", "abrupt", "penetrate" Default: "abrupt"

      • penetrate_distance : float, unit: meter
        to what extent the vehicle will penetrate the traffic lane. This parameter will only be use when stop_choice is "penetrate"

      • obey_traffic_light : bool, optional
        whether the vehicle will obey traffic light. Default is True

      • run : bool, optional
        whether the vehicle is running. Default is True

      • safety_distance : float, optional
        smallest distance between this vehicle and vehicle ahead. Default is 0.0 meters, means ego vehicle is highly likely to collide into other vehicles.

      • vehicle_color : string, optional
        custom string representation of the RGB color of the vehicle. The string should be in the format 'R,G,B', where R,G,B are integer values. For example, blue is represented as (R,G,B) = (47, 210, 231), then the input string should be '47,210,231'. The default is None, meaning using the default color for the vehicle.

    • Return

      • uniquename : the uniquename of the ego vehicle
  • add_lead_vehicle(self, lead_distance, gap = 10.0,model_name = "vehicle.tesla.model3", stop_choice = "abrupt", penetrate_distance = None, obey_traffic_lights = True, run = True, safety_distance = 15.0, vehicle_color = None)
    add the ego vehicle to the intersection

    • Parameters

      • lead_distance : float, the desired distance between lead vehicle and ego vehicle.

        Note: the lead distance is actually not put into use, enter whatever value you want at this point

      • gap : float,optional
        the distance between a vehicle and its previous one. Default is 10 meter

      • model_name : string, optional
        vehicle model type. The default is "vehicle.tesla.model3".

      • stop_choice : string, optional
        how will the vehicle stop when at yellow or red light. valid values: "normal", "abrupt", "penetrate" Default: "abrupt"

      • penetrate_distance : float, unit: meter
        to what extent the vehicle will penetrate the traffic lane. This parameter will only be use when stop_choice is "penetrate"

      • obey_traffic_light : bool, optional
        whether the vehicle will obey traffic light. Default is True

      • run : bool, optional
        whether the vehicle is running. Default is True

      • safety_distance : float, optional
        smallest distance between this vehicle and vehicle ahead. Default is 15.0 meters.

      • vehicle_color : string, optional
        custom string representation of the RGB color of the vehicle. The string should be in the format 'R,G,B', where R,G,B are integer values. For example, blue is represented as (R,G,B) = (47, 210, 231), then the input string should be '47,210,231'. The default is None, meaning using the default color for the vehicle.

    • Return

      • uniquename : the uniquename of the lead vehicle
  • add_follow_vehicle(self, follow_distance, gap = 10.0,model_name = "vehicle.tesla.model3", stop_choice = "abrupt", penetrate_distance = None, obey_traffic_lights = True, run = True, safety_distance = 15.0, vehicle_color = None)
    add the ego vehicle to the intersection

    • Parameters

      • follow_distance : float, the desired distance between follow vehicle and ego vehicle.

        Note: the follow distance is actually not put into use, enter whatever value you want at this point

      • gap : float,optional
        the distance between a vehicle and its previous one. Default is 10 meter

      • model_name : string, optional
        vehicle model type. The default is "vehicle.tesla.model3".

      • stop_choice : string, optional
        how will the vehicle stop when at yellow or red light. valid values: "normal", "abrupt", "penetrate" Default: "abrupt"

      • penetrate_distance : float, unit: meter
        to what extent the vehicle will penetrate the traffic lane. This parameter will only be use when stop_choice is "penetrate"

      • obey_traffic_light : bool, optional
        whether the vehicle will obey traffic light. Default is True

      • run : bool, optional
        whether the vehicle is running. Default is True

      • safety_distance : float, optional
        smallest distance between this vehicle and vehicle ahead. Default is 15.0 meters.

      • vehicle_color : string, optional
        custom string representation of the RGB color of the vehicle. The string should be in the format 'R,G,B', where R,G,B are integer values. For example, blue is represented as (R,G,B) = (47, 210, 231), then the input string should be '47,210,231'. The default is None, meaning using the default color for the vehicle.

    • Return

      • uniquename : the uniquename of the follow vehicle
  • export_settings(self)
    export all settings for the initial intersection, as discussed in export section Click to view a demo of exported settings

    Note: this method overrides the original export_settings in Intersection class by avoid exporting the settings of the vehicles in the subject lane of the init intersection

    • Returns
      • intersection_settings : ConfigObj
        settings of the intersection
  • import_settings(self, intersection_settings)
    export all settings for the init intersection, as discussed in export section Click to view a demo of exported settings

    Note: this method overrides the original import_settings in Intersection class by avoid importing the settings of the vehicles in the subject lane of the init intersection

    • Parameters

      • intersection_settings : ConfigObj
        the intersection settings we want to import
    • Returns

      • new_intersection_setting : ConfigObj
        settings of the intersection this will be generated by call export_settings after finishing import output these settings are for the purpose of creating the front-end gui

Function for start simulation

To create and start a simulation, three more functions are involved.

get_traffic_lights

  • get_traffic_lights(actor_list)

    get all traffic lights inside the simulation environment

    • Parameters

      • actor_list : list
        list of actors in carla simulation environment
    • Returns

      • traffic_light_list : list carla.TrafficLight
        all traffic lights inside the carla world, used to assign traffic light to intersections.

create_intersections

  • create_intersections(env, number_of_intersections, traffic_light_list, navigation_speed)

    create the intersections that form the base of an urban simulation scenario

    • Parameters

      • env : CARLA_ENV
        self-written simulation help class.

      • number_of_intersections : int
        number of intersection. Maximum number is 4

      • traffic_light_list : list carla.TrafficLight
        all traffic lights inside the carla world, used to assign traffic light to intersections.

      • navigation_speed : float
        the maximum speed vehicles in the urban environment can achieve. This value is applied to all vehicles in the urban environment

    • Returns

      • Intersections : list of intersections, [Init_Intersection,Intersection,Intersection,...,Intersection]

IntersectionBackend

  • IntersectionBackend(env, intersection_list, allow_collision = True, spectator_mode = None, enable_human_control = False)

    function for having the simulation run

    • Parameters

      • env : CARLA_ENV self-written simulation help class.

      • intersection_list : list of intersections, [Init_Intersection,Intersection,Intersection,...,Intersection]

      • allow_collision : bool, optional
        whether collision is allowed in during simulation. The default value is True. This method is not stable. There's no guarantee that vehicle will not collide if this value is set to be False

      • spectator_mode : string the spectator mode, valid value is "first_person" or "left" or "human_driving". The default is None. spectator will be fixed at 10 meters after the last full-path vehicle is "first_person" is chosen; spectator will be looking at the ego vehicle from the left if "left" is chosen. If "human_driving" is chosen, the spectator will be set at the position of the human driver.

      • enable_human_control : bool, optional
        Parameter indicating whether ego vehicle is controlled by human driver. The default value is False. If value is True, then human will be responsible for controlling the vehicle. Note: 1. if value is True, human command is needed. See the human-ego tutorial for more detail. 2. if value is True, the spectator mode will be automatically set to "human_driving" no matter what value is entered


Store and read Intersection settings in file format

The backend provides method for storing/reading Intersection settings into/from file system. This is done by the following 2 helper function. Make sure you use these functions to deal with settings storage and reading.

write_intersection_settings

  • write_intersection_settings(name, settings)

    • Parameters

      • name : string
        Name of the intersection setting you want to store.

      • settings : ConfigObj
        the intersection settings exported by calling the export_settings() method of Init Intersection or Normal Intersection.

read_intersection_settings

  • read_intersection_settings(config_filename)

    • Parameters

      • config_filename : string
        Name of the intersection setting you want to read in.
    • Returns

      • intersection_settings : ConfigObj
        the valid intersection setting that can be imported by intersections

Demo code recipe

Here is an example of the whole work flow of creating an urban simulation. This example is also available at test_backend

# the following two lines are for front end user
import sys
sys.path.append("..")

import carla
import time

from backend.intersection_settings_helper import write_intersection_settings, read_intersection_settings

from backend.carla_env import CARLA_ENV # self-written class that provides help functions
from backend.multiple_vehicle_control import VehicleControl
from backend.initial_intersection import  create_intersections, get_ego_spectator, get_ego_left_spectator
from backend.full_path_vehicle import LeadVehicleControl, FollowVehicleControl

from backend.intersection_definition import get_traffic_lights
from backend.intersection_backend import IntersectionBackend

def main():
    try:
        client = carla.Client("localhost",2000)
        client.set_timeout(10.0)
        world = client.load_world('Town05')

        # set the weather
        weather = carla.WeatherParameters(
            cloudiness=10.0,
            precipitation=0.0,
            sun_altitude_angle=90.0)
        world.set_weather(weather)

        # set the spectator position for demo purpose
        spectator = world.get_spectator()
        spectator.set_transform(carla.Transform(carla.Location(x=-190, y=1.29, z=75.0), carla.Rotation(pitch=-88.0, yaw= -1.85, roll=1.595))) # top view of intersection

        env = CARLA_ENV(world) 
        time.sleep(2) # sleep for 2 seconds, wait the initialization to finish



        # get traffic light list
        traffic_light_list = get_traffic_lights(world.get_actors())


        # get intersection list
        intersection_list = create_intersections(env, 4, traffic_light_list, navigation_speed = 10.0)

        # edit intersection
        # these should be done with the help of the front end gui
        init_intersection = intersection_list[0]
        normal_intersections = intersection_list[1:]
        init_intersection.add_ego_vehicle(safety_distance = 15.0, stop_choice = "abrupt", vehicle_color = '255,255,255')
        init_intersection.add_follow_vehicle(follow_distance = 20.0, stop_choice = "penetrate", penetrate_distance = 2.0)
        init_intersection.add_lead_vehicle(lead_distance = 20.0, stop_choice = "abrupt")
        init_intersection.add_vehicle(choice = "left", stop_choice = "abrupt", vehicle_color = '255,255,255')
        init_intersection.add_vehicle(choice = "right",command="left")

        # test edit settings
        name1 = init_intersection.add_vehicle(choice = "ahead",command="left")
        name2 = init_intersection.add_vehicle(choice = "ahead",command = "right")

        name1 = init_intersection.edit_vehicle_settings(name1, choice = "ahead", vehicle_color = '128,128,128')
        name2 = init_intersection.edit_vehicle_settings(name2, choice = "ahead", gap = 15.0, vehicle_color = '128,128,128')

        # get bounding box
        bb = init_intersection.get_vehicle_bounding_box(name1)
        print("bb.x = %f, bb.y = %f, bb.z = %f" % (bb.x, bb.y, bb.z))

        init_intersection.edit_traffic_light("subject")
        init_intersection.edit_traffic_light("left",red_start = 40.0,red_end = 60.0,yellow_start=30.0,yellow_end=40.0,green_start=0.0,green_end = 30.0)
        init_intersection.edit_traffic_light("right",red_start = 0.0,red_end = 10.0,yellow_start=10.0,yellow_end=20.0,green_start=20.0,green_end = 40.0)
        init_intersection.edit_traffic_light("ahead",red_start = 20.0,red_end = 40.0,yellow_start=10.0,yellow_end=20.0,green_start=0.0,green_end = 10.0)


        intersection_list[1].add_vehicle(choice = "ahead")
        intersection_list[1].add_vehicle(choice = "left",command="left")
        intersection_list[1].add_vehicle(choice = "right",command = "left")
        intersection_list[1].add_vehicle(choice = "right",command = "right")
        intersection_list[1]._shift_vehicles(-10, choice = "right",index = 0)
        #intersection_list[1].edit_traffic_light("left")

        intersection_list[2].add_vehicle(choice = "ahead")
        intersection_list[2].add_vehicle(choice = "left",command="left")
        intersection_list[2].add_vehicle(choice = "right",command = "left")
        intersection_list[2].add_vehicle(choice = "right",command = "right")
        #intersection_list[2].edit_traffic_light("right")

        intersection_list[3].add_vehicle(command = "left")
        intersection_list[3].add_vehicle()
        intersection_list[3].edit_traffic_light("ahead")

        # test import/export
        init_setting = init_intersection.export_settings()

        intersection_list[3].import_settings(init_setting)
        intersection_list[3].add_vehicle(command = "left")
        intersection_list[3].add_vehicle()
        third_setting = intersection_list[3].export_settings()

        write_intersection_settings("third_intersection_setting",third_setting)
        new_third_setting = read_intersection_settings('third_intersection_setting')

        intersection_list[2].import_settings(new_third_setting)




        IntersectionBackend(env,intersection_list)
    finally:
        time.sleep(10)
        env.destroy_actors()

if __name__ == '__main__':
    main()

Note:

Note: the first time you run the code, the following error may occur:

    RuntimeError: time-out of 10000ms while waiting for the simulator, make sure the simulator is ready and connected to localhost:2000

    UnboundLocalError: local variable 'env' referenced before assignment

This is because the carla client failed to connect to the carla server. Just run the code again and it should be fine.

author: shijiliu

date: 2020-07-19

email: shijiliu@umich.edu