第二、参与者和蓝图

Carla 中的参与者是在模拟中执行动作的元素,他们可以影响其他参与者。Carla 的参与者包括车辆和行人,也包括传感器、交通标志、红绿灯和观看者。对如何操作它们有充分的了解是至关重要的。

本节将介绍生成、销毁、类型以及如何管理它们。然而,可能性几乎是无穷无尽的。实验、查看本文档中的 教程,并在 Carla 论坛 中分享疑虑和想法。


蓝图

这些布局允许用户将新的参与者平滑地结合到模拟中。它们已经是带有动画和一系列属性的模型。其中一些是可修改的,而另一些则不是。这些属性包括车辆颜色、激光雷达传感器中的通道数量、行人的速度等等。

蓝图库 列出了可用的蓝图及其属性。车辆和行人蓝图具有一个生成属性,用于指示它们是新的(第 2 代)资产还是旧的(第 1 代)资产。

管理蓝图库

carla.BlueprintLibrary 类包含一系列 carla.ActorBlueprint 元素。它是能够提供对它访问的世界对象。

blueprint_library = world.get_blueprint_library()

蓝图有一个 ID 来识别它们和由此产生的参与者。可以读取库来找到某个 ID,随机选择蓝图,或者使用 通配符模式 过滤结果。

# 找一个指定的蓝图
collision_sensor_bp = blueprint_library.find('sensor.other.collision')
# 随机选择一个车辆蓝图
vehicle_bp = random.choice(blueprint_library.filter('vehicle.*.*'))

除此之外,每个 carla.ActorBlueprint 能获取 get 和改变 set 一些列参与者属性 carla.ActorAttribute

is_bike = [vehicle.get_attribute('number_of_wheels') == 2]
if(is_bike)
    vehicle.set_attribute('color', '255,0,0')

笔记

某些属性无法修改。在蓝图库中查看。

属性有一个参与者属性类型 carla.ActorAttributeType 变量。它从枚举列表中声明其类型。此外,可修改的属性还附带一个 推荐值列表

for attr in blueprint:
    if attr.is_modifiable:
        blueprint.set_attribute(attr.id, random.choice(attr.recommended_values))

笔记

用户可以创建他们自己的车辆。查看 教程(资产) 以了解相关信息。贡献者可以 将他们的新内容添加到 Carla


参与者生命周期

重要

本节提到了关于参与者的不同方法。Python API 提供 commands ,以便在一个框架中应用一批最常见的命令。

生成

世界对象负责生成参与者并跟踪这些参与者。 生成只需要一张蓝图和一个 carla.Transform 说明参与者的位置和旋转。

世界有两个不同的方法生成参与者。

transform = Transform(Location(x=230, y=195, z=40), Rotation(yaw=180))
actor = world.spawn_actor(blueprint, transform)

重要

Carla 使用 虚幻引擎坐标系统 。记住: carla.Rotation 构造函数定义为“俯仰、偏航、翻滚” (pitch, yaw, roll),与虚幻编辑器的“翻滚、俯仰、偏航” (roll, pitch, yaw) 不同。

如果在指定位置发生冲突,将不会生成参与者。无论这种情况发生在静态对象还是其他参与者身上。可以尝试避免这些不希望的生成碰撞。

  • 对于车辆map.get_spawn_points() 返回推荐生成点的列表。
spawn_points = world.get_map().get_spawn_points()
  • 对于行人world.get_random_location()返回人行道上的随机点。同样的方法也用于为行人设置目标位置。
spawn_point = carla.Transform()
spawn_point.location = world.get_random_location_from_navigation()

一个参与者在生成时可以附加到另一个参与者上。参与者跟随他们所依附的父级。这对于传感器特别有用。该附件可以是刚性的(适合检索精确数据),也可以根据其父级的情况进行轻松移动。它由辅助类 carla.AttachmentType 定义。

下一个示例将相机刚性地连接到车辆上,因此它们的相对位置保持固定。

camera = world.spawn_actor(camera_bp, relative_transform, attach_to=my_vehicle, carla.AttachmentType.Rigid)

重要

当生成附加的参与者时,提供的变换必须相对于父级参与者。

一旦生成,世界对象就会将参与者添加到列表中。这可以很容易地搜索或迭代。

actor_list = world.get_actors()
# 根据 id 找参与者
actor = actor_list.find(id)
# 打印世界上所有限速标志的位置。
for speed_sign in actor_list.filter('traffic.speed_limit.*'):
    print(speed_sign.get_location())

处理

carla.Actor 主要由 get()set() 方法组成,用于管理地图周围的参与者。

print(actor.get_acceleration())
print(actor.get_velocity())

location = actor.get_location()
location.z += 10.0
actor.set_location(location)

可以禁用参与者的物理特性以将其冻结在适当的位置。

actor.set_simulate_physics(False)

除此之外,参与者还有他们的蓝图提供的标签。这些对于语义分割传感器最有用。

笔记

大多数方法是异步向模拟器发送请求。模拟器每次更新解析它们的时间有限。使用 set() 方法淹没模拟器将积累明显的延迟。

销毁

当 Python 脚本完成时,不回销毁参与者。他们必须明确地销毁自己。

destroyed_sucessfully = actor.destroy() # 如果成功返回 True 

重要

销毁参与者会阻塞模拟器,直到该过程完成。


参与者类型

传感器

传感器是产生数据流的参与者。他们有自己的部分,第四部分. 传感器和数据。现在,我们只看一下常见的传感器生成周期。

此示例生成一个相机传感器,将其连接到车辆,并告诉相机将生成的图像保存到磁盘。

camera_bp = blueprint_library.find('sensor.camera.rgb')
camera = world.spawn_actor(camera_bp, relative_transform, attach_to=my_vehicle)
camera.listen(lambda image: image.save_to_disk('output/%06d.png' % image.frame))
  • 传感器也有蓝图。设置属性至关重要。
  • 大多数传感器将安装在车辆上以收集周围环境的信息。
  • 传感器 监听 数据。收到数据后,它们会调用用 Lambda 表达式 描述的函数(提供的链接中的 6.14)

观察者

由虚幻引擎放置以提供游戏内的视角。它可用于移动模拟器窗口的视角。以下示例将移动观众参与者,将视角指向所需的车辆。

spectator = world.get_spectator()
transform = vehicle.get_transform()
spectator.set_transform(carla.Transform(transform.location + carla.Location(z=50),
carla.Rotation(pitch=-90)))

交通标志和交通灯

到目前为止,Carela 中只有停靠点、让行路线和交通信号灯被视为参与者。其余的 OpenDRIVE 标志可通过 API 作为地标(carla.Landmark)进行访问。他们的信息可以使用这些实例访问,但他们在模拟中并不作为参与者存在。在接下来的 第 3 部分 地图和导航 中将更详细地解释地标。

当模拟开始、停止、让行和交通灯时,会使用 OpenDRIVE 文件中的信息自动生成。这些都无法在蓝图库中找到,因此无法生成。

笔记

OpenDRIVE 文件中的 Carela 地图没有交通标志或信号灯。这些是由开发人员手动放置的。

交通标志 未在路线图本身中定义,如下页所述。相反,他们有一个 carla.BoundingBox 来影响其中的车辆。

# 获得影响车辆的交通灯
if vehicle_actor.is_at_traffic_light():
    traffic_light = vehicle_actor.get_traffic_light()

路口设有交通灯。与任何参与者一样,他们有自己独特的 ID,但对于岔路口也有一个组(group) ID 。

同一组中的交通灯遵循一个循环。第一个设置为绿色,而其余的则保持红色。活跃的灯会持续几秒钟呈绿色、黄色和红色,因此有一段时间所有灯都是红色的。然后,下一个红绿灯开始循环,前一个红绿灯与其余红绿灯一起冻结。

可以使用 API 设置交通灯的状态。每个状态花费的秒数也是如此。可能的状态用 carla.TrafficLightState 描述为一系列枚举值。

# 交通灯从红变绿
if traffic_light.get_state() == carla.TrafficLightState.Red:
    traffic_light.set_state(carla.TrafficLightState.Green)
    traffic_light.set_set_green_time(4.0)

笔记

只有当信号灯为红色时,车辆才会意识到交通灯。

车辆

carla.Vehicle 是一种特殊类型的参与者。它采用了模拟轮式车辆物理特性的特殊内部组件。这是通过应用四种不同的控件来实现的:

vehicle.apply_control(carla.VehicleControl(throttle=1.0, steer=-1.0))
vehicle.apply_physics_control(carla.VehiclePhysicsControl(max_rpm = 5000.0, center_of_mass = carla.Vector3D(0.0, 0.0, 0.0), torque_curve=[[0,400],[5000,400]]))

车辆有一个 carla.BoundingBox 封装它们。该边界框允许将物理原理应用于车辆并检测碰撞。

box = vehicle.bounding_box
print(box.location)         # 相对车辆的位置
print(box.extent)           # XYZ half-box extents in meters.

通过启用 扫轮碰撞参数 可以改善车轮的物理特性。默认的轮子物理系统对每个轮子使用从轴到地板的单射线投射,但是当启用扫轮碰撞时,将检查轮子的整个体积是否发生碰撞。它可以这样启用:

physics_control = vehicle.get_physics_control()
physics_control.use_sweep_wheel_collision = True
vehicle.apply_physics_control(physics_control)

车辆还包括其独有的其他功能:

  • 自动驾驶模式 会将车辆订阅到 交通管理器 以模拟真实的城市状况。该模块是硬编码的,不是基于机器学习的。
vehicle.set_autopilot(True)
  • 车灯 必须由用户打开和关闭。每辆车都有一组在carla.VehicleLightState 中列出的灯。并非所有车辆都集成了车灯。截至撰写本文时,配备集成车灯的车辆如下:
    • 自行车: 所有自行车都有前后位置灯。
    • 摩托车: 雅马哈和哈雷戴维森型号。
    • 汽车: 奥迪 TT、雪佛兰 Impala、道奇警车、道奇 Charger、奥迪 e-tron、林肯 2017 年和 2020 年、野马、特斯拉 Model 3、特斯拉 Cybertruck、大众 T2 和梅赛德斯 C 级。

可以使用 carla.Vehicle.get_light_statecarla.Vehicle.set_light_state 方法随时检索和更新车辆的灯光。它们使用二进制运算来自定义灯光设置。

# 打开位置灯
current_lights = carla.VehicleLightState.NONE
current_lights |= carla.VehicleLightState.Position
vehicle.set_light_state(current_lights)

行人

carla.Walker 的工作方式与车辆类似。对它们的控制由控制器提供。

行人可以由人工智能控制。他们没有自动驾驶模式。carla.WalkerAIController 参与者在它所附加的参与者周围移动。

walker_controller_bp = world.get_blueprint_library().find('controller.ai.walker')
world.SpawnActor(walker_controller_bp, carla.Transform(), parent_walker)

笔记

人工智能控制器是无形的,没有物理特性。它不会出现在现场。此外,位置 (0,0,0) 相对于其父级的位置不会导致碰撞。

每个人工智能控制器都需要初始化、目标和可选的速度。停止控制器的工作方式相同。

ai_controller.start()
ai_controller.go_to_location(world.get_random_location_from_navigation())
ai_controller.set_max_speed(1 + random.random())  # 在 1 米每秒 到 2 米每秒之间(默认是 1.4 米每秒)
...
ai_controller.stop()

当行人到达目标位置时,他们会自动步行到另一个随机点。如果无法到达目标点,行人将前往距离当前位置最近的点。

carla.Client 中的一个片段使用批次生成大量行人并让它们四处游荡。

重要

要销毁人工智能行人,请停止人工智能控制器并销毁参与者和控制器。


关于 Carla 中的参与者,这就是一个总结。下一步将仔细研究 Carla 的地图、道路和交通。

继续阅读以了解更多信息,或访问论坛发布在阅读过程中想到的任何疑问或建议。