6-演员和蓝图
演员不仅包括车辆和行人,还包括传感器、交通标志、交通信号灯和观众。充分了解如何对它们进行操作是至关重要的。
1 蓝图
这些布局允许用户顺利地将新的演员合并到模拟中。它们是已经制作好的带有动画和一系列属性的模型。其中一些是可以修改的,而另一些则不能。这些属性包括车辆颜色、激光雷达传感器的通道数量、行人的速度等等。
蓝图库中列出了可用的blueprint library及其属性。车辆和行人蓝图有一个生成属性,指示它们是新的(第2代)还是旧的(第1代)资源。
2 管理蓝图库
carla.BlueprintLibrary类包含一个 carla.ActorBlueprint列表,世界对象提供了对它的访问。
blueprint_library = world.get_blueprint_library()
蓝图有一个ID来识别它们和由此产生的演员。可以读取库以查找某个ID,随机选择蓝图,或使用通配符模式 wildcard pattern过滤结果。
# Find a specific blueprint.
collision_sensor_bp = blueprint_library.find('sensor.other.collision')
# Choose a vehicle blueprint at random.
vehicle_bp = random.choice(blueprint_library.filter('vehicle.*.*'))
除此之外,每个carla.ActorBlueprint有一系列carla.ActorAttribute,可以获取和设置的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))
用户可以创建自己的车辆,参见 Tutorials (assets) 文档。
2 演员生命周期
本节提到关于actor的不同方法。Python API提供的命令可以在一个框架内批量应用最常见的命令。
2.1 生成角色
世界对象负责生成角色并跟踪它们。生成演员只需要蓝图和 carla.Transform (表示角色的位置和旋转信息)。
世界有两种不同的方法来生成角色。
如果生成失败,Spawn_actor()将引发异常。
如果生成失败,try_spawn_actor()返回None。
transform = Transform(Location(x=230, y=195, z=40), Rotation(yaw=180))
actor = world.spawn_actor(blueprint, transform)
注意:CARLA使用虚幻引擎坐标系https://carla.readthedocs.io/en/latest/python_api/#carlarotation。carla旋转的构造函数定义为(俯仰pitch,偏航yaw,滚动roll),这与虚幻引擎编辑器(滚动roll,俯仰pitch,偏航yaw)不同。
如果在指定位置发生碰撞,则不会生成actor。无论这是发生在静态对象还是其他参与者身上。
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()
一个actor可以在生成时附加到另一个actor上。演员可以附加他们所依附的父母atctor上。这对传感器特别有用。附件可以是刚性的(适合检索精确的数据),也可以根据父actor附件轻松移动。它由助手类carla.AttachmentType定义。
下一个示例将摄像机固定在车辆上,因此它们的相对位置保持固定。
camera = world.spawn_actor(camera_bp, relative_transform, attach_to=my_vehicle, carla.AttachmentType.Rigid)
注意:当生成附加的actor时,所提供的转换必须相对于父actor。
生成后,world对象将actor添加到列表中。这可以很容易地搜索或迭代。
actor_list = world.get_actors()
# Find an actor by id.
actor = actor_list.find(id)
# Print the location of all the speed limit signs in the world.
for speed_sign in actor_list.filter('traffic.speed_limit.*'):
print(speed_sign.get_location())
2.2 处理
carla.Actor主要由get()和set()方法组成,用于管理map上的actor。
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()方法会累积明显的延迟。
2.3 销毁
当Python脚本结束时,actor不会被销毁。他们必须明确地被指定销毁。
destroyed_sucessfully = actor.destroy() # Returns True if successful
销毁actor会阻塞模拟器,直到该过程完成。
3 演员类型
传感器
传感器是产生数据流的角色。现在,让我们来看看一个常见的传感器生成方式。
本例生成一个相机传感器,将其连接到车辆上,并告诉相机将生成的图像保存到磁盘上。
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 expression描述的函数。
3.1 观察者(Spectator)
由虚幻引擎放置,以提供仿真视野。它可以用来移动模拟器窗口的视图。下面的示例将移动观察者actor,将视图指向所需的车辆。
spectator = world.get_spectator()
transform = vehicle.get_transform()
spectator.set_transform(carla.Transform(transform.location + carla.Location(z=50),
carla.Rotation(pitch=-90)))
3.2 交通标志和交通灯
到目前为止,在CARLA中只有停车、停车和交通灯被认为是演员。其余的Opendrive标志可以通过API访问,命名为carla.Landmark。他们的信息可以使用这些实例访问,但他们并不以参与者的身份存在于仿真中。
当仿真开始,停止,生成和红绿灯自动生成使用在Opendrive文件中的信息。这些都不能在蓝图库中找到,因此不能生成。
CARLA地图在OpenDRIVE文件中没有交通标志和灯光。这些是由开发人员手动放置的。
交通标志Traffic signs并没有在道路地图中定义,而是有一个 carla.BoundingBox来影响车辆。
#Get the traffic light affecting a vehicle
if vehicle_actor.is_at_traffic_light():
traffic_light = vehicle_actor.get_traffic_light()
交通信号灯Traffic lights 在交叉路口。他们有自己唯一的ID,同时也有一个连接的组ID。为了识别同一组中的交通灯,使用灯杆ID。
同一组中的交通灯遵循一个循环。第一个被设置为绿色,而其余的保持冻结在红色。活跃的那个会在绿色、黄色和红色中停留几秒钟,所以会有一段时间所有的灯都是红色的。然后,下一个红绿灯开始循环,前一个红绿灯和其他红绿灯一起被冻结。
可以使用API设置交通灯的状态。灯可能得状态用carla.TrafficLightState来描述。TrafficLightState是一系列枚举值。
#Change a red traffic light to green
if traffic_light.get_state() == carla.TrafficLightState.Red:
traffic_light.set_state(carla.TrafficLightState.Green)
traffic_light.set_set_green_time(4.0)
注意:只有当交通灯是红色的时候,车辆才会识别到交通灯。
3.3 车辆
carla.Vehicle是一种特殊类型的actor。它集成了特殊的内部组件来模拟车辆的轮式物理特性。这可以通过应用以下四种不同类型的控制来实现:
carla.VehicleControl诸如油门、转向、刹车等驾驶指令提供输入。
vehicle.apply_control(carla.VehicleControl(throttle=1.0, steer=-1.0))
carla.VehiclePhysicsControl定义了车辆的物理属性,并包含两个控制器:
carla.GearPhysicsControl控制车辆的档位。
carla.WheelPhysicsControl提供对每个车轮的特定控制。
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) # Location relative to the vehicle.
print(box.extent) # XYZ half-box extents in meters.
通过启用扫掠轮碰撞参数sweep wheel collision parameter,可以改善车轮的物理性能。默认的车轮物理为每个车轮使用从轴到地板的单射线投射,但启用扫掠车轮碰撞时,会检查车轮的整个体积是否发生碰撞。它可以按如下方式启用:
physics_control = vehicle.get_physics_control()
physics_control.use_sweep_wheel_collision = True
vehicle.apply_physics_control(physics_control)
自动驾驶模式将车辆订阅到交通管理器Traffic Manager,以模拟真实的城市条件。这个模块是硬编码的,不是基于机器学习。
vehicle.set_autopilot(True)
车辆灯必须由使用者打开和关闭。每辆车都有一组在carla.VehicleLightState中列出的灯。并不是所有的车辆都集成了车灯。目前集成灯的车辆如下:
自行车:所有的自行车都有前后位置灯。
摩托车:雅马哈和哈雷戴维森型号。
车型:奥迪TT、雪佛兰黑斑羚、两款道奇警车、道奇Charger、奥迪e-tron、林肯2017和2020、野马、特斯拉Model 3、特斯拉赛博卡车、大众T2和梅赛德斯c级。
车辆的车灯可以随时使用carla.Vehicle.get_light_state和carla.Vehicle.set_light_state进行检索和更新。它们使用二进制操作来进行光照设置。
# Turn on position lights
current_lights = carla.VehicleLightState.NONE
current_lights |= carla.VehicleLightState.Position
vehicle.set_light_state(current_lights)
3.3 行人
carla.Walker 的工作原理与车辆相似。对它们的控制由控制器提供。
carla.WalkerControl可以以一定的方向和速度移动行人,还允许它们跳跃。
carla.WalkerBoneControl提供对3D骨架的控制,具体可以参考该文档This tutorial。
步行者可以由AI进行控制。他们没有自动驾驶模式。carla.WalkerAIController在它所依附的actor周围移动。
walker_controller_bp = world.get_blueprint_library().find('controller.ai.walker')
world.SpawnActor(walker_controller_bp, carla.Transform(), parent_walker)
注意:AI控制器是无实体的,没有物理属性。它不会出现在场景中。同样,相对于其父节点的位置(0,0,0)也不会导致冲突。
每个AI控制器都需要初始化、目标和速度(可选)。停止控制器的工作原理相同。
ai_controller.start()
ai_controller.go_to_location(world.get_random_location_from_navigation())
ai_controller.set_max_speed(1 + random.random()) # Between 1 and 2 m/s (default is 1.4 m/s).
...
ai_controller.stop()
当行人到达目标位置时,他们会自动走到另一个随机点。如果目标点无法到达,行人将前往离当前位置最近的点。
carla.Client 使用批量生成行人,并使他们在随机点附近逗留。
注意:要销毁AI行人,请停止AI控制器并同时销毁actor和控制器。