当前位置: 首页 > 工具软件 > Blueprints > 使用案例 >

CARLA 笔记(05)— Actors and blueprints(创建和修改 Blueprint、生成 Spawning、使用 Handling、销毁 Destruction)

阎宝
2023-12-01

创立了世界之后,就要开始安放我们的主角 actor了。Actor 翻译为演员,在仿真世界里则代表可以移动的物体,包括交通标志、交通信号灯、视角、汽车,传感器(因为传感器要安在车身上)以及行人。

1. Blueprints

要创建 Actor,首先需要提供要创建的 Actor 的类型,不同的类型会有不同的属性,比如一台车,它可以是不同的型号,可以是不同的颜色, 外观不同,可以通过油门和方向盘来控制,而如果是一个传感器,它可能都没有这些任何一个属性,因此创建一个 Actor 需要知道这些信息,也就是类似于需要使用一个模板,这个东西在 Carla 中叫做蓝图,即 BlueprintsCarla 中已经内置了一个蓝图库,里边包含了许多不同的 Actors

这些布局允许用户将新的 Actor 顺利加入仿真。 它们是带有动画和一系列属性的已制作模型。 其中一些是可修改的,而另一些则不能。 这些属性包括车辆颜色、激光雷达传感器中的通道数量、步行者的速度等等。

carla.BlueprintLibrary类包含一个 carla.ActorBlueprint 元素列表。 world对象可以提供对它的访问。

# 拿到这个世界所有物体的蓝图
blueprint_library = world.get_blueprint_library()

blueprint 有一个 ID 来识别它们以及由此产生的 Actor。 可以读取该库以查找特定 ID、随机选择 blueprint 或使用通配符模式过滤结果。

# 从浩瀚如海的蓝图中找到奔驰的蓝图
ego_vehicle_bp = blueprint_library.find('vehicle.mercedes-benz.coupe')
# 给我们的车加上特定的颜色
ego_vehicle_bp.set_attribute('color', '0, 0, 0')


# 找到一个碰撞蓝图
collision_sensor_bp = blueprint_library.find('sensor.other.collision')
# Choose a vehicle blueprint at random. 
# 使用 `filter` 方法然后给定模糊匹配的方法获取到多个蓝图
vehicle_bp = random.choice(blueprint_library.filter('vehicle.*.*'))

find 里找到添加的东西,建议打开网页然后 CTRL+F ,然后搜索关键字,比如:

  1. 如果想添加的是传感器,那么一般以 sensor 开头,sensor.sensor_type (传感器.传感器类型) sensor.lidar.ray_cast 就是激光雷达,sensor.other.collision 就是碰撞检测的
  2. 如果是车呢,一般就是 vehicle 开头,vehicle.audi.a2 就是奥迪A2的车型

除此之外,每个 carla.ActorBlueprint 都有一系列 carla.ActorAttribute 可以 getset

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))

2. Actor life cycle

一个 Actor 可以被生成(Spawning),使用(Handling),以及销毁(Destruction)。

  • 生成:有了蓝图之后,意味着我们有了模板,然后就需要使用这个模板生成一个或者多个演员(Actor),这一过程叫做 Spawning ,因为 Actor 是在世界中存在的一个物体,因此在生成的时候,需要告诉环境它的出生点在哪里。
  • 使用:当 Actor 生成以后,就可以通过客户端来控制它的一些行为,比如可以让车子跑起来,并控制它的油门和转向。
  • 销毁:当我们不在需要一个 Actor 的时候可以选择销毁它,这样可以释放仿真环境的资源,让环境运行更顺畅。

2.1 Spawning

构建好蓝图以后,下一步便是选定它的出生点。不过上边提到,在生成 Actor 的时候,需要告诉世界它的出生点在哪里,出生点在 Carla 中抽象为 carla.Transform

world 对象负责生成 actors 并跟踪它们,生成 actors 只需要一个 blueprint 和一个 carla.Transform,说明 actor 的位置和旋转角。

world 有两种不同的方法来产生 Actors

  • spawn_actor() 如果生成失败会引发异常。
  • try_spawn_actor() 如果生成失败将返回 None

比如,我们可以用下边这段代码,指定将 Actor 生成到某一个地点。

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

CARLA uses the Unreal Engine coordinates system. Remember that carla.Rotation constructor is defined as (pitch, yaw, roll), that differs from Unreal Engine Editor (roll, pitch, yaw).

或者赋予随机的位置,不过这个位置必须是空的位置,因为物体在世界中是有体积的,所以有可能你指定的地点上已经有其他物体了,比如,该位置已经有台车子,或者该位置是一个建筑物,这种情况下,Actor 被生成的时候就会出现碰撞,为了避免这个问题,Carla 提供了一个接口可以获取到所有空的出生点,只要在这些空的出生点上生成 Actor 就不会出现碰撞的问题了。

如果在指定位置发生碰撞,actor 将不会生成。 无论这发生在静态对象还是其他 Actor身上。 可以尝试避免这些不希望的产碰撞产生。

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

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

将摄像头固定在车辆上,因此它们的相对位置保持固定。

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

注意:When spawning attached actors, the transform provided must be relative to the parent 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 Handling

Actor 被生成以后,生成方法会返回被生成的 Actor 对象,我们可以使用该对象控制 Actor 的行为。比如,我们可以随意挪动它的初始位置,定义它的动态参数等等,根据不同的 Actor 类型,可以控制的参数也不一样。

carla.Actor 主要由 get()set()方法组成,用于管理地图周围的 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)

除此之外,Actor 也有他们的 blueprint 蓝图提供的标签。 这些对语义分割传感器最有用。

大多数方法都以异步方式向仿真器发送请求。每次更新时,仿真器解析它们的时间有限。用 set() 方法充斥仿真器会积累大量的延迟。

2.3 Destruction

Python 脚本完成时,Actor 不会被自动销毁。 必须明确地摧毁自己。

destroyed = actor.destroy() # Returns True if successful

最后如果我们不需要生成的 actor 之后,我们可以用代码把原来生成的车辆关闭,语句如下:

finally:
	for actor in actor_list:
		actor.destroy()

销毁一个 actor 将阻塞仿真器,直到进程完成。

command 有一些最常见的 CARLA 方法的适配,也可以批量应用。例如,命令 SetAutopilot 等同于vehicle.set_autopilot() ,启用车辆的自动驾驶。也可以使用批量的 Client 方法。

# 如果你有多个 Actor 存在 list 里,可以一起销毁。
client.apply_batch([carla.command.DestroyActor(x) for x in actor_list])

当执行多个脚本文件的时候,服务器是不会自动清理掉上一个脚本生成的 actor 的,所以需要手动清除。

 类似资料: