文章目录

前言一、依赖库安装1、pygame安装2、numpy安装

二、Pygame渲染Carla Camera画面1、连接Carla并初始化TrafficManager2、生成自动驾驶车辆并设置交通行为3、创建初始化pygame surface对象的函数4、创建pygame处理Carla图像的回调函数5、创建pygame键盘控制车辆运动的函数6、创建相对于主车的Camera sensor7、创建Camera图像转pygame图像的回调函数8、运动控制初始化及画面渲染初始化9、更新pygame画面及处理车辆控制的键盘事件10、退出pygame结束仿真

三、运行Carla和pygame1、打开Carla客户端2、运行完整代码3、运行效果展示

提示:以下是本篇文章正文内容,下面案例可供参考

前言

pygame提供了一种渲染实时视觉输出的方法,显示camera sensor的输出。我们也通过视频注入的方法将视频数据注入到控制器内部,提供视觉感知的场景,模拟真实场景进行仿真。

一、依赖库安装

1、pygame安装

- sudo apt-get install python3-pip

- sudo pip3 install pygame

2、numpy安装

- sudo pip3 install numpy

二、Pygame渲染Carla Camera画面

1、连接Carla并初始化TrafficManager

import carla

import random

import pygame

import numpy as np

#连接Carla客户端

client = carla.Client('localhost', 2000)

world = client.get_world()

# 设置Carla的仿真方式为同步模式

settings = world.get_settings()

settings.synchronous_mode = True # 开启同步模式

settings.fixed_delta_seconds = 0.05 #设置仿真的更新周期

world.apply_settings(settings) #应用设置

# 设置TrafficManager为同步模式,注意使用TraffiManager一定要设置Carla为同步模式

traffic_manager = client.get_trafficmanager()

traffic_manager.set_synchronous_mode(True) #应用同步模式

# 控制随机数生成器的输出,使得在相同种子下生成的随机数序列可重复

traffic_manager.set_random_device_seed(0)

random.seed(0)

2、生成自动驾驶车辆并设置交通行为

# 随机获得Carla地图上的一个坐标点

spawn_point = random.choice(world.get_map().get_spawn_points())

# 生成车辆并设置自动驾驶

vehicle_bp = random.choice(world.get_blueprint_library().filter('*vehicle*')) #随机选择车辆蓝图

ego_vehicle = world.spawn_actor(vehicle_bp, spawn_point) #在坐标点生成车辆

ego_vehicle.set_autopilot(True) #设置自动驾驶模式

#设置100%忽略交通灯

traffic_manager.ignore_lights_percentage(ego_vehicle, 100)

3、创建初始化pygame surface对象的函数

通过这段代码,我们可以得知RenderObject类的作用是创建一个具有指定宽度和高度的随机图像的渲染对象。这个对象可以在pygame中用于显示或其他图形操作。

# Render object to keep and pass the PyGame surface

class RenderObject(object):

def __init__(self, width, height):

"""

使用numpy生成一个随机的图像矩阵,大小为(height, width, 3)

3表示RGB三个颜色通道

"""

init_image = np.random.randint(0,255,(height,width,3),dtype='uint8')

"""

将图像矩阵转换为pygame的Surface对象

注意swapaxes函数的作用是交换矩阵的轴,将宽度和高度的顺序交换

这是因为pygame中Surface对象的宽度在前,高度在后

"""

self.surface = pygame.surfarray.make_surface(init_image.swapaxes(0,1))

4、创建pygame处理Carla图像的回调函数

这段代码的目的是将一个包含 RGBA 通道的图像数据转换为 RGB 格式的 pygame 可以使用的 Surface 对象,并将其赋值给 obj.surface。这个函数可能是用于在 pygame 中处理图像数据的回调函数或处理函数。

def pygame_callback(data, obj):

# 将data.raw_data复制并重新形状为 (data.height, data.width, 4) 的图像矩阵

img = np.reshape(np.copy(data.raw_data), (data.height, data.width, 4))

# 从图像矩阵中移除alpha通道,只保留RGB三个颜色通道

img = img[:,:,:3]

# 反转颜色通道的顺序,由BGR转为RGB

img = img[:, :, ::-1]

# 将图像矩阵转换为pygame的Surface对象,并交换宽度和高度的顺序

obj.surface = pygame.surfarray.make_surface(img.swapaxes(0,1))

5、创建pygame键盘控制车辆运动的函数

这段代码的目的是为了通过结合pygame与键盘来控制车辆运动。键盘事件

回车键:关闭自动驾驶行为 上键:前进 下键:后退 左键:往左 右键:往右

class ControlObject(object):

def __init__(self, veh):

# 车辆的初始控制状态

self._vehicle = veh

self._steer = 0

self._throttle = False

self._brake = False

self._steer = None

self._steer_cache = 0

#获得carla控制

self._control = carla.VehicleControl()

#检查pygame按下的键盘事件

def parse_control(self, event):

if event.type == pygame.KEYDOWN:

if event.key == pygame.K_RETURN:

self._vehicle.set_autopilot(False)

if event.key == pygame.K_UP:

self._throttle = True

if event.key == pygame.K_DOWN:

self._brake = True

if event.key == pygame.K_RIGHT:

self._steer = 1

if event.key == pygame.K_LEFT:

self._steer = -1

if event.type == pygame.KEYUP:

if event.key == pygame.K_UP:

self._throttle = False

if event.key == pygame.K_DOWN:

self._brake = False

self._control.reverse = False

if event.key == pygame.K_RIGHT:

self._steer = None

if event.key == pygame.K_LEFT:

self._steer = None

# 设置简单的动力控制函数

def process_control(self):

#上键:踩下油门踏板时,松开刹车踏板,油门最大的开度为0.5,可以自行设置。

if self._throttle:

self._control.throttle = min(self._control.throttle + 0.01, 0.5)

self._control.gear = 1

self._control.brake = False

elif not self._brake:

self._control.throttle = 0.0

if self._brake:

# 下键后退:当车速小于0.01且不是倒档,设置倒档,并设置最大油门开度为0.5。

if self._vehicle.get_velocity().length() < 0.01 and not self._control.reverse:

self._control.brake = 0.0

self._control.gear = 1

self._control.reverse = True

self._control.throttle = min(self._control.throttle + 0.1, 0.5)

#下键后退:如果为倒档,则控制油门最大开度为0.5。

elif self._control.reverse:

self._control.throttle = min(self._control.throttle + 0.1, 0.5)

#下键减速:设置减速踏板的最大开度为1。

else:

self._control.throttle = 0.0

self._control.brake = min(self._control.brake + 0.3, 1)

else:

self._control.brake = 0.0

#简单的左右方向控制

if self._steer is not None:

if self._steer == 1:

self._steer_cache += 0.03

if self._steer == -1:

self._steer_cache -= 0.03

min(0.7, max(-0.7, self._steer_cache))

self._control.steer = round(self._steer_cache,1)

else:

if self._steer_cache > 0.0:

self._steer_cache *= 0.2

if self._steer_cache < 0.0:

self._steer_cache *= 0.2

if 0.01 > self._steer_cache > -0.01:

self._steer_cache = 0.0

self._control.steer = round(self._steer_cache,1)

# 应用控制参数控制ego_vehicle

self._vehicle.apply_control(self._control)

6、创建相对于主车的Camera sensor

相对于ego_vehicle生成camera sensor

# 设置camera的初始坐标系

camera_init_trans = carla.Transform(carla.Location(x=-5, z=3), carla.Rotation(pitch=-20))

#获取camera sensor蓝图

camera_bp = world.get_blueprint_library().find('sensor.camera.rgb')

#相对于ego_vehicle生成camera sensor

camera = world.spawn_actor(camera_bp, camera_init_trans, attach_to=ego_vehicle)

7、创建Camera图像转pygame图像的回调函数

通过这段代码,我们可以推断出该代码片段的目的是启动摄像头,并在每次摄像头有新图像时,调用 pygame_callback 函数对图像进行处理,并将结果更新到 renderObject 对象的 surface 属性中。这样可以实现实时更新渲染对象的显示。请确保在此之前已经定义了 pygame_callback 函数和 renderObject 对象。

"""

在这里,camera 是一个摄像头对象,其具有 listen 方法。listen 方法接受一个回调函数作为参数,并在每次摄像头有新图像时调用该回调函数。

在这个例子中,使用了一个匿名函数作为回调函数:lambda image: pygame_callback(image, renderObject)。这个回调函数接受一个 image 参数,然后调用 pygame_callback 函数,传递该图像和一个名为 renderObject 的对象作为参数。

"""

camera.listen(lambda image: pygame_callback(image, renderObject))

8、运动控制初始化及画面渲染初始化

# 设置画面的长宽

image_w = 800

image_h = 600

# 实例渲染对象以及车辆控制

renderObject = RenderObject(image_w, image_h)

controlObject = ControlObject(ego_vehicle)

# 初始化pygame

pygame.init()

"""

在这里,pygame.display.set_mode 是 Pygame 中用于创建窗口的函数。它接受一个表示窗口宽度和高度的元组 (image_w, image_h) 作为第一个参数。

第二个参数 pygame.HWSURFACE | pygame.DOUBLEBUF 是一个位掩码,用于指定窗口的模式选项。pygame.HWSURFACE 表示使用硬件加速的表面,pygame.DOUBLEBUF 表示使用双缓冲。

使用硬件加速的表面 (pygame.HWSURFACE) 可以利用计算机的图形硬件来加速渲染,从而提高性能。双缓冲 (pygame.DOUBLEBUF) 可以消除渲染过程中的闪烁问题,提供更平滑的显示效果。

"""

gameDisplay = pygame.display.set_mode((image_w,image_h), pygame.HWSURFACE | pygame.DOUBLEBUF)

# 通过将黑色作为参数传递给 fill() 方法,可以将窗口的背景色设置为黑色。

gameDisplay.fill((0,0,0))

#blit() 方法用于将一个图像绘制到另一个图像上,或者绘制到游戏显示窗口上。第一个参数 renderObject.surface 是要绘制的图像,第二个参数 (0, 0) 是绘制的位置,表示图像在游戏显示窗口上的左上角的坐标。

gameDisplay.blit(renderObject.surface, (0,0))

#刷新pygame窗口画面

pygame.display.flip()

9、更新pygame画面及处理车辆控制的键盘事件

# Game loop

crashed = False

while not crashed:

# 等待同步

world.tick()

# 按帧更新渲染的Camera画面

gameDisplay.blit(renderObject.surface, (0,0))

pygame.display.flip()

# 处理车辆控制请求

controlObject.process_control()

# 获取pygame事件

for event in pygame.event.get():

# If the window is closed, break the while loop

if event.type == pygame.QUIT:

crashed = True

# 获得pygame控制车辆键盘事件

controlObject.parse_control(event)

10、退出pygame结束仿真

# Stop camera and quit PyGame after exiting game loop

ego_vehicle.destory()

camera.stop()

pygame.quit()

三、运行Carla和pygame

1、打开Carla客户端

运行carla客户端并设置低帧率模式./CarlaUE4.sh -prefernvidia -quality-level=Low -benchmark -fps=15

2、运行完整代码

我是用vs code直接运行的,没有vs code可以直接python3 来运行,把代码复制进空的py文件,然后运行。

import carla

import random

import pygame

import numpy as np

# 连接到客户端并检索世界对象

client = carla.Client('localhost', 2000)

world = client.get_world()

# 在同步模式下设置模拟器

settings = world.get_settings()

settings.synchronous_mode = True # Enables synchronous mode

settings.fixed_delta_seconds = 0.05

world.apply_settings(settings)

# 以同步模式设置TM

traffic_manager = client.get_trafficmanager()

traffic_manager.set_synchronous_mode(True)

# 设置种子,以便必要时行为可以重复

traffic_manager.set_random_device_seed(0)

random.seed(0)

# 获取地图的刷出点

spawn_point = random.choice(world.get_map().get_spawn_points())

# 生成车辆并设置自动驾驶

vehicle_bp = random.choice(world.get_blueprint_library().filter('*vehicle*'))

ego_vehicle = world.spawn_actor(vehicle_bp, spawn_point)

ego_vehicle.set_autopilot(True)

traffic_manager.ignore_lights_percentage(ego_vehicle, 100)

# 渲染对象来保持和传递PyGame表面

class RenderObject(object):

def __init__(self, width, height):

init_image = np.random.randint(0,255,(height,width,3),dtype='uint8')

self.surface = pygame.surfarray.make_surface(init_image.swapaxes(0,1))

# 相机传感器回调,将相机的原始数据重塑为2D RGB,并应用于PyGame表面

def pygame_callback(data, obj):

img = np.reshape(np.copy(data.raw_data), (data.height, data.width, 4))

img = img[:,:,:3]

img = img[:, :, ::-1]

obj.surface = pygame.surfarray.make_surface(img.swapaxes(0,1))

# 控件对象来管理车辆控件

class ControlObject(object):

def __init__(self, veh):

# 控制参数来存储控制状态

self._vehicle = veh

self._steer = 0

self._throttle = False

self._brake = False

self._steer = None

self._steer_cache = 0

self._control = carla.VehicleControl()

# 检查PyGame窗口中的按键事件

# 定义控件状态

def parse_control(self, event):

if event.type == pygame.KEYDOWN:

if event.key == pygame.K_RETURN:

self._vehicle.set_autopilot(False)

if event.key == pygame.K_UP:

self._throttle = True

if event.key == pygame.K_DOWN:

self._brake = True

if event.key == pygame.K_RIGHT:

self._steer = 1

if event.key == pygame.K_LEFT:

self._steer = -1

if event.type == pygame.KEYUP:

if event.key == pygame.K_UP:

self._throttle = False

if event.key == pygame.K_DOWN:

self._brake = False

self._control.reverse = False

if event.key == pygame.K_RIGHT:

self._steer = None

if event.key == pygame.K_LEFT:

self._steer = None

# 处理当前控制状态,改变控制参数

def process_control(self):

if self._throttle:

self._control.throttle = min(self._control.throttle + 0.01, 0.5)

self._control.gear = 1

self._control.brake = False

elif not self._brake:

self._control.throttle = 0.0

if self._brake:

# 如果在汽车静止时按住向下箭头,则切换到倒车

if self._vehicle.get_velocity().length() < 0.01 and not self._control.reverse:

self._control.brake = 0.0

self._control.gear = 1

self._control.reverse = True

self._control.throttle = min(self._control.throttle + 0.1, 0.5)

elif self._control.reverse:

self._control.throttle = min(self._control.throttle + 0.1, 0.5)

else:

self._control.throttle = 0.0

self._control.brake = min(self._control.brake + 0.3, 1)

else:

self._control.brake = 0.0

if self._steer is not None:

if self._steer == 1:

self._steer_cache += 0.03

if self._steer == -1:

self._steer_cache -= 0.03

min(0.7, max(-0.7, self._steer_cache))

self._control.steer = round(self._steer_cache,1)

else:

if self._steer_cache > 0.0:

self._steer_cache *= 0.2

if self._steer_cache < 0.0:

self._steer_cache *= 0.2

if 0.01 > self._steer_cache > -0.01:

self._steer_cache = 0.0

self._control.steer = round(self._steer_cache,1)

# Ápply小车的控制参数

self._vehicle.apply_control(self._control)

# 初始化安装在车辆后面的摄像头

camera_init_trans = carla.Transform(carla.Location(x=-5, z=3), carla.Rotation(pitch=-20))

camera_bp = world.get_blueprint_library().find('sensor.camera.rgb')

camera = world.spawn_actor(camera_bp, camera_init_trans, attach_to=ego_vehicle)

# 用PyGame回调启动camera

camera.listen(lambda image: pygame_callback(image, renderObject))

# 设置渲染画面size

image_w = 800

image_h = 600

# 为渲染和车辆控制实例化对象

renderObject = RenderObject(image_w, image_h)

controlObject = ControlObject(ego_vehicle)

# 初始化显示

pygame.init()

gameDisplay = pygame.display.set_mode((image_w,image_h), pygame.HWSURFACE | pygame.DOUBLEBUF)

# 填充黑色背景

gameDisplay.fill((0,0,0))

gameDisplay.blit(renderObject.surface, (0,0))

pygame.display.flip()

# 循环执行

crashed = False

while not crashed:

# 等待同步

world.tick()

# 按帧更新渲染的Camera画面

gameDisplay.blit(renderObject.surface, (0,0))

pygame.display.flip()

# 处理车辆控制请求

controlObject.process_control()

# 获取pygame事件

for event in pygame.event.get():

# If the window is closed, break the while loop

if event.type == pygame.QUIT:

crashed = True

# 获得pygame控制车辆键盘事件

controlObject.parse_control(event)

# 结束

ego_vehicle.destory()

camera.stop()

pygame.quit()

3、运行效果展示

回车键:关闭自动驾驶 上键:前进 下键:后退 左键:往左 右键:往右注意需要关闭自动驾驶才能通过键盘去控制车辆上下左右运行。

相关链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: