1# pyright: reportPrivateUsage=none
2from typing import List, Optional, Tuple, Union
3
4import carla
5from typing_extensions import Annotated, Literal, overload
6
7from launch_tools import CarlaDataProvider
8
9create_blueprint = CarlaDataProvider.create_blueprint
10
11
[docs]
12def get_blueprint_library(world: Optional["carla.World"] = None) -> carla.BlueprintLibrary:
13 """
14 Get the blueprint library of the given world.
15
16 .. deprecated::
17 Consider using :py:attr:`.CarlaDataProvider._blueprint_library`
18 or :py:meth:`.CarlaDataProvider.create_blueprint` instead.
19 """
20 if CarlaDataProvider._blueprint_library: # noqa: SLF001
21 return CarlaDataProvider._blueprint_library # noqa: SLF001
22 if world is None:
23 world = CarlaDataProvider.get_world()
24 return world.get_blueprint_library()
25
26
[docs]
27def get_contrasting_blueprints(ego_vehicle: str = "vehicle.lincoln.mkz_2020",
28 ego_color: str = "255,0,0") \
29 -> Tuple[Annotated[carla.ActorBlueprint, "ego"], Annotated[carla.ActorBlueprint, "NPC"]]:
30 """
31 Convenience function to acquire two different colored blueprints,
32 e.g. for the ego and all other NPC vehicles.
33
34 Parameters:
35 ego_vehicle : str, optional
36 The name of the ego vehicle, by default "vehicle.lincoln.mkz_2020"
37 ego_color : str, optional
38 The color of the ego vehicle in RGB format, by default "255,0,0"
39
40 Returns:
41 A tuple containing the ego vehicle blueprint and the NPC vehicle blueprint.
42 """
43 blueprint_library: carla.BlueprintLibrary = get_blueprint_library()
44 car_blueprint = blueprint_library.filter('vehicle')[0]
45
46 if car_blueprint.has_attribute('color'):
47 color = car_blueprint.get_attribute('color').recommended_values[-1]
48 car_blueprint.set_attribute('color', color)
49
50 ego_bp = blueprint_library.find(ego_vehicle)
51 if ego_bp.has_attribute('color'):
52 color = ego_bp.get_attribute('color').recommended_values[0]
53 ego_bp.set_attribute('color', ego_color)
54
55 ego_bp.set_attribute('role_name', 'hero')
56 return ego_bp, car_blueprint
57
58
59@overload
60def get_actor_blueprints(pattern: str, generation: Literal['all']) -> carla.BlueprintLibrary: ...
61
62@overload
63def get_actor_blueprints(pattern: str, generation: Literal[1, 2]) -> List[carla.ActorBlueprint]: ...
64
65
[docs]
66def get_actor_blueprints(pattern: str, generation: Literal[1, 2, 'all']) -> Union[List["carla.ActorBlueprint"], carla.BlueprintLibrary]:
67 """
68 Returns a list of actor blueprints filtered by the given filter and generation.
69
70 Args:
71 world : The world to get the blueprints from.
72 filter : The filter to apply to the blueprints.
73 generation : The generation of the blueprints to return. Can be "all", "1", or "2".
74
75 Returns:
76 List of carla.ActorBlueprint: The list of actor blueprints that match the given filter and generation.
77 """
78 bps = get_blueprint_library().filter(pattern)
79
80 if isinstance(generation, str) and generation.lower() == "all":
81 return bps
82
83 # If the filter returns only one bp, we assume that this one needed
84 # and therefore, we ignore the generation
85 if len(bps) == 1:
86 return [bps[0]]
87
88 try:
89 int_generation = int(generation)
90 # Check if generation is in available generations
91 if int_generation in [1, 2]:
92 return [x for x in bps if int(x.get_attribute('generation')) == int_generation]
93 except Exception: # noqa: S110
94 pass
95 print(" Warning! Actor Generation is not valid. No actor will be spawned.")
96 return []