自动驾驶仿真工程师,上班玩玩自制赛车游戏,是不是很香?此前的分享中,我们成功地在Carla的服务器端打开了一个界面,并根据实时更新观察者视角,获得了最初的仿真体验。但真实使用过程中,服务器端的界面我们是不会动的,而是重新生成一个或多个新的客户端界面。相当于服务器主机只有一个,但是有多个玩家客户端在操控,共同控制服务器里各自的车辆形式,进行交互。这种多个客户端一个服务器端的模式,正是Carla的底层架构模式。大家完全可以基于Carla开发出来一个多人赛车游戏。要创建客户端游戏界面,最好的python库就是pygame,本期,我们尝试来结合carla和pygame,创建客户端游戏界面。pygame中显示的界面内容,我们尝试从车辆上的摄像头传感器中获取。Python Pygame 是一款专门为开发和设计 2D 电子游戏而生的软件包,它支 Windows、Linux、Mac OS 等操作系统,具有良好的跨平台性。Pygame 由 Pete Shinners 于 2000 年开发而成,是一款免费、开源的的软件包,因此您可以放心地使用它来开发游戏,不用担心有任何费用产生。
Pygame 在 SDL(Simple DirectMedia Layer,使用 C语言编写的多媒体开发库) 的基础上开发而成,它提供了诸多操作模块,比如图像模块(image)、声音模块(mixer)、输入/输出(鼠标、键盘、显示屏)模块等。相比于开发 3D 游戏而言,Pygame 更擅长开发 2D 游戏,比如于飞机大战、贪吃蛇、扫雷等游戏。要使用pygame,命令行输入如下指令完成安装即可。
# -*- coding:utf-8 -*-
import pygame
import sys #sys是python的标准库,提供Python运行时环境变量的操控
pygame.init() # 内部各功能模块进行初始化创建及变量设置,默认调用
size = width, height = 800, 600 # 设置游戏窗口大小,分别是宽度和高度
screen = pygame.display.set_mode(size) # 初始化显示窗口
pygame.display.set_caption("我的小游戏程序") # 设置显示窗口的标题内容,是一个字符串类型
while True: # 无限循环,直到Python运行时退出结束
for event in pygame.event.get(): # 从Pygame的事件队列中取出事件,并从队列中删除该事件
if event.type == pygame.QUIT: # 获得事件类型,并逐类响应
sys.exit() # 用于退出结束游戏并退出
pygame.display.update() # 对显示窗口进行更新,默认窗口全部重绘
运行后会创建打开一个如下的窗口,只有点击关闭按钮,才会退出该程序。
再来看看下面的例子,我们对上述代码稍加改动,手动创建了一个50*50大小的Surface对象,将之添加到了显示窗口(100,100)位置处。# -*- coding:utf-8 -*-
import pygame
import sys #sys是python的标准库,提供Python运行时环境变量的操控
pygame.init() # 内部各功能模块进行初始化创建及变量设置,默认调用
size = width, height = 800, 600 # 设置游戏窗口大小,分别是宽度和高度
screen = pygame.display.set_mode(size) # 初始化显示窗口
pygame.display.set_caption("我的小游戏程序") # 设置显示窗口的标题内容,是一个字符串类型
# 创建一个 50*50 的图像, 并优化显示
face = pygame.Surface((50, 50), flags=pygame.HWSURFACE)
face.fill(color='white') #填充颜色
while True: # 无限循环,确保窗口一直显示
for event in pygame.event.get(): # 遍历所有用户操作事件
if event.type == pygame.QUIT: # 获得事件类型,判断是否为关闭窗口
sys.exit() # 用于结束程序的运行并退出
# 将绘制的图像添加到主屏幕上,(100,100)是位置坐标,显示屏的左上角为坐标系的(0,0)原点
screen.blit(face, (100, 100))
pygame.display.update() # 对显示窗口进行更新,默认窗口全部重绘
pygame.quit() # 退出pygame
现在,我们实现了自己创建一个图像并显示在了pygame的窗口中。那么carla服务器端的图像,又该怎么显示到pygame窗口中呢?
import pygame
import sys
import carla
import numpy as np
def sensor_image(image):
array = np.frombuffer(image.raw_data, dtype=np.dtype("uint8"))
array = np.reshape(array, (image.height, image.width, 4))
array = array[:, :, :3]
array = array[:, :, ::-1]
surface = pygame.surfarray.make_surface(array.swapaxes(0, 1))
my_display.blit(surface, (0, 0))
return surface
try:
pygame.init()
size = width, height = 800, 600
screen = pygame.display.set_mode(size)
pygame.display.set_caption("我的小游戏程序")
my_display = pygame.display.set_mode(size, pygame.HWSURFACE | pygame.DOUBLEBUF)
actor_list = []
client = carla.Client('localhost', 2000)
client.set_timeout(5.0)
world = client.get_world()
blueprint_library = world.get_blueprint_library()
bp = blueprint_library.filter('model3')[0]
print("the vehicle blueprint:", bp)
spawn_point = world.get_map().get_spawn_points()[0]
vehicle = world.spawn_actor(bp, spawn_point)
vehicle.set_autopilot(True)
actor_list.append(vehicle)
blueprint = blueprint_library.find('sensor.camera.rgb')
blueprint.set_attribute('image_size_x', str(width))
blueprint.set_attribute('image_size_y', str(height))
blueprint.set_attribute('fov', '110')
spawn_point = carla.Transform(carla.Location(x=-4, z=2))
sensor_camera = world.spawn_actor(blueprint, spawn_point, attach_to=vehicle)
actor_list.append(sensor_camera)
sensor_camera.listen(lambda img: sensor_image(img))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
pygame.display.update()
finally:
pygame.quit()
for actor in actor_list:
actor.destroy()
print("销毁:", actor)
如上内容,即如何获得Carla中的摄像头数据,并将之显示到pygame窗口中。效果如下:
上图中,大窗口为Carla的仿真世界,即服务器端。小窗口为pygame窗口,是我们创建的客户端界面。如果将客户端窗口运行多次,将会打开多个客户端窗口。再配合pygame获取键盘输入的功能,即能实现以键盘方式驱动车辆形式,实现多个玩家赛车的场景了。
自动驾驶仿真工程师,上班玩玩自制赛车游戏,是不是很香?本期分享到这里,诸位道友如有所得,欢迎关注-点赞-收藏-转发哦。