文章目录
- 前言
- 一、Carla多视图切换效果
- 二、Camera安装坐标系
- 1、Carla.Location
- 2、Carla.Rotation
- 三、接口及代码详解
- 1、接口介绍
- 2、生成上帝视图代码
- 3、生成Camera视图代码
- 四、完整代码
前言
1、Carla提供了大量的Python API接口,用户可以通过查找文档实现各类功能,本文介绍该如何通过Tab按键实现多视图切换的功能,视图切换方便我们调试功能以及摄像头画面注入;
2、一般的画面我们可以通过生成Camera,然后将Camera画面设置为当前视图;但是上帝视图我通过设置Camera来实现,但我发现画面会出现严重抖动,后面改成直接生成相对自车的视图就好了;
提示:以下是本篇文章正文内容,下面案例可供参考
一、Carla多视图切换效果
上帝视图:
后往前视图:
前视图:
后视图:
左视图:
右视图:
二、Camera安装坐标系
坐标原点是BoudingBox中心点
1、Carla.Location
2、Carla.Rotation
注意:生成摄像头的时候有三种附加方式,Rigid、SpringArm、SpringArmGhost,这里先引入这个坐标系,后面会具体讲到哪里会用到;
1、Rigid:生成摄像头的时候选择Rigid模式,视觉效果不好,画面会抖动,它附加在目标上的坐标系如下;
2、SpringArmGhost:叫做幽灵弹簧臂,不仅会跟随目标物跳过障碍物遮挡,还会自动调整运动的画面,使得画面变得平滑,UE4官方给出的SpringArmGhost效果如下图:
但是SpringArmGhost模式下的Roll有点奇怪,我调参的时候发现当Z轴值不为0时,0°的时候视角有点朝上,具体什么原因我也没搞懂,官方好像也不太清楚是什么原因,可能UE官方才知道什么原因,有懂的小伙伴可以分享下。
三、接口及代码详解
1、接口介绍
1)get_spectator是获得观察者,我们可以通过设置观察者的坐标系来获取视图;
2)获取坐标系信息,我们可以获取Camera坐标系,也可以获取车辆的坐标系;
3)set_transform设置观察者坐标系;
4)Carla坐标系,参考第二大点,Camera安装参照坐标系;
5)生成actor,可以用来生成车辆、Camera等,attahment设置附加的类型,上面有讲到他的种类
···
2、生成上帝视图代码
1)生成上帝视图不能使用Camera画面作为当前观察视图(会出现抖动的情况),而是通过直接设置相对于自车的观察视图,由于车的位置时刻在变因此更新每一帧的坐标:
import carla
#获得当前车辆的坐标系
Vehicle_transform = vehicle.get_transform()
#更新观察坐标系,在车辆坐标的基础上修改坐标
spectator_tranform = carla.Transform(Vehicle_transform .location + carla.Location(z=50),
carla.Rotation(pitch=-90))
#设置观察坐标系
world.get_spectator().set_transform(spectator_tranform )
3、生成Camera视图代码
import carla
#查找Camera蓝图
camera_bp = world.get_blueprint_library().find('sensor.camera.rgb')
#设置生成Camera的附加类型为SpringArmGhost
Atment_SpringArmGhost = carla.libcarla.AttachmentType.SpringArmGhost
#设置Camera的安装坐标系
Camera_transform = carla.Transform(carla.Location(x=-8, y=0, z=5),
carla.Rotation(pitch=15, yaw=0, roll=0))
#生成Camera
camera = world.spawn_actor(camera_bp, Camera_transform,attach_to=vehicle,
attachment_type=Atment_SpringArmGhost )
#设置观察者视图
world.get_spectator().set_transform(camera.get_transform())
四、完整代码
import carla
import random
import time
import threading
import keyboard
threads = []
def updateSpectator(vehicle,world):
spectator_obj_list =[]
#获得车辆的中心点,并将点定位到右上角,便于运算
bound_x = 0.5 + vehicle.bounding_box.extent.x
bound_y = 0.5 + vehicle.bounding_box.extent.y
bound_z = 0.5 + vehicle.bounding_box.extent.z
#查找相机蓝图
camera_bp = world.get_blueprint_library().find('sensor.camera.rgb')
#设置Camera的附加类型Camera跟随车辆(幽灵模式);
Atment_SpringArmGhost = carla.libcarla.AttachmentType.SpringArmGhost
Atment_Rigid = carla.libcarla.AttachmentType.Rigid
#设置相对车辆的安装位置,配置上帝视图(Camera无法实现上帝视图,画面会抖动)
Vehicle_transform_list = [
(carla.Location(z=50),carla.Rotation(pitch=-90))
]
#设置camera的安装位置,配置后往前视图以及前后左右视图
Camera_transform_list = [
(carla.Transform(carla.Location(x=-8, y=0, z=5),
carla.Rotation(pitch=15, yaw=0, roll=0)),Atment_SpringArmGhost),
(carla.Transform(carla.Location(x=bound_x, y=0, z=bound_z),
carla.Rotation(pitch=-15, yaw=180, roll=0)),Atment_SpringArmGhost),
(carla.Transform(carla.Location(x=-bound_x, y=0, z=bound_z),
carla.Rotation(pitch=-15, yaw=-180, roll=0)),Atment_SpringArmGhost),
(carla.Transform(carla.Location(x=bound_x-0.5, y=-bound_y, z=bound_z),
carla.Rotation(pitch=-15, yaw=120, roll=20)),Atment_SpringArmGhost),
(carla.Transform(carla.Location(x=bound_x-0.5, y=bound_y, z=bound_z),
carla.Rotation(pitch=-15, yaw=-120, roll=-20)),Atment_SpringArmGhost)
]
#拼接两个transform_list
spectator_transform_list = Vehicle_transform_list + Camera_transform_list
#上帝视图坐标系以及所有camera对象填入spectator_obj_list;
for spectator_transform_index in spectator_transform_list:
#spectator_transform_list第0个元素为上帝视图坐标系
if spectator_transform_list.index(spectator_transform_index) ==0:
spectator_obj_list.append(spectator_transform_index)
#spectator_transform_list其余元素为Camera安装参数,下面生成Camera对象
else:
camera = world.spawn_actor(camera_bp, spectator_transform_index[0],
attach_to=vehicle,attachment_type=spectator_transform_index[1])
spectator_obj_list.append(camera)
#设置Vehicle_transform_list[0]为初始视图(上帝视图);
spectator_obj = Vehicle_transform_list[0]
# 每一帧都需要更新视图,因为坐标时刻在变化;
while True:
#按Tab键切换
if keyboard.is_pressed("tab"):
#上一个spectator的索引号;
last_spectator_obj_index = spectator_obj_list.index(spectator_obj)
#计算下一个spectator的索引,如果列表索引超限则重新拿第0个spectator;
spectator_obj_index = last_spectator_obj_index +1 if len(spectator_obj_list) - last_spectator_obj_index -1 > 0 else 0
spectator_obj = spectator_obj_list[spectator_obj_index]
time.sleep(0.2)
#更新视图
if spectator_obj_list.index(spectator_obj) == 0:
#设置上帝视图
Vehicle_transform = carla.Transform(vehicle.get_transform().location + spectator_obj_list[0][0],
spectator_obj_list[0][1])
world.get_spectator().set_transform(Vehicle_transform)
else:
#设置其他Camera视图
world.get_spectator().set_transform(spectator_obj.get_transform())
def autopilot(vehicle):
#自动领航
vehicle.set_autopilot()
try:
# 连接至服务器
client = carla.Client('localhost', 2000)
client.set_timeout(10)
# 获取世界对象
world = client.get_world()
# 获取车辆原型
car_blueprnt = world.get_blueprint_library().filter('vehicle.tesla.*')[0]
car_blueprnt.set_attribute('role_name', 'ego_vehicle')
# 在随机位置生成车辆
spawn_point = random.choice(world.get_map().get_spawn_points())
vehicle = world.spawn_actor(car_blueprnt, spawn_point)
# 创建自动运行车辆的线程
Thread_autopilot = threading.Thread(target=autopilot(vehicle))
# 创建切换视图的线程
Thread_updateSpectator = threading.Thread(target=updateSpectator(vehicle,world))
#添加线程
threads.append(Thread_autopilot)
threads.append(Thread_updateSpectator)
for thread in threads:
thread.start()
finally:
# 销毁车辆
vehicle.destroy()