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(
28 ego_vehicle: str = "vehicle.lincoln.mkz_2020", 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
63@overload
64def get_actor_blueprints(pattern: str, generation: Literal[1, 2]) -> List[carla.ActorBlueprint]: ...
65
66
[docs]
67def get_actor_blueprints(
68 pattern: str, generation: Literal[1, 2, "all"]
69) -> Union[List["carla.ActorBlueprint"], carla.BlueprintLibrary]:
70 """
71 Returns a list of actor blueprints filtered by the given filter and generation.
72
73 Args:
74 world : The world to get the blueprints from.
75 filter : The filter to apply to the blueprints.
76 generation : The generation of the blueprints to return. Can be "all", "1", or "2".
77
78 Returns:
79 List of carla.ActorBlueprint: The list of actor blueprints that match the given filter and generation.
80 """
81 bps = get_blueprint_library().filter(pattern)
82
83 if isinstance(generation, str) and generation.lower() == "all":
84 return bps
85
86 # If the filter returns only one bp, we assume that this one needed
87 # and therefore, we ignore the generation
88 if len(bps) == 1:
89 return [bps[0]]
90
91 try:
92 int_generation = int(generation)
93 # Check if generation is in available generations
94 if int_generation in [1, 2]:
95 return [x for x in bps if int(x.get_attribute("generation")) == int_generation]
96 except Exception: # noqa: S110
97 pass
98 print(" Warning! Actor Generation is not valid. No actor will be spawned.")
99 return []