首页/文章/ 详情

仿真测试入门参考(20):CARLA的传感器

1年前浏览6179

 经常有朋友问如何学习仿真测试,于是想着把自己的一些经验和理解分享出来,希望能有所帮助。不过视野和技术有限,所说不一定对,供大家批评和参考。这是第20篇,CARLA的传感器。

自动驾驶算法通过各种传感器获取周围环境状态,从而进行正确决策控制;传感器的仿真也是自动驾驶仿真的重要内容。本节介绍CARLA中传感器模型的种类,并以摄像头和物体传感器为例说明传感器模型的用法。

01

CARLA中的传感器种类


 


根据信息更新条件的不同可以将CARLA中的传感器分为周期型和事件型两个大的类别,简述如下:

(1)周期型传感器

根据设定的周期更新数据,包括的类型如下表:

(2)事件型传感器

相关事件发生时更新数据,包括的类型如下表:

02

Pygame的简介


 


Pygame 是基于 SDL库开发的游戏软件库,主要用于2D游戏开发,不仅可以进行渲染显示,还可以采集键盘事件并进行响应,在CARLA的很多官方示例中使用其进行显示和交互操作,如前面已经使用过的manual_control.py。后面传感器的实例中也使用Pygame进行摄像头信息的显示,所以我们在这里先对Pygame的使用方法进行一下简单说明。


Pygame的最小开发框架如下:






















import pygame
# pygame初始化pygame.init()screen = pygame.display.set_mode((1280720))
running = Truewhile running:    # 处理事件    for event in pygame.event.get():        if event.type == pygame.QUIT:        running = False
   ## 更新待显示对象    # 采用紫色填充屏幕    screen.fill("purple")
   ## 完成待显示对象更新    # 将当前对象显示到屏幕上    pygame.display.flip()pygame.quit()
Pygame的使用分为五步:
(1)导入pygame库,并进行初始化,如代码第1~5行所示,这里将显示窗口设置为1280x720大小。
(2)获取事件并进行响应,事件主要是指各种键盘按键和显示窗口操作,如代码第10~12行,获取对窗口关闭按钮X的点击,并将running设置为False,这将使运行循环退出。
(3)更新待显示对象,如代码第14~18行,将全部屏幕填充为紫色;
(4)显示对象,如代码第20行;
(5)运行循环结束后,退出pygame,如代码第21行。

03

传感器的添加和使用


 


传感器的添加包含四个步骤:获取蓝图,配置传感器参数,将传感器绑定至车辆,定义并配置监听方法。下面以常规摄像头RGB camera和障碍物传感器Obstacle detector为例说明传感器模型的用法。

代码第57~83行添加了ego车和50辆障碍车并为其配置了自动驾驶,这部分内容在上一节出现过,不在赘述。由于本实例中要添加传感器,为实现传感器的消息稳定和同步,将仿真设置为了同步定步长模式,于是也将Traffic Manager设置为了同步模式(代码第46~55行)。

由于对仿真世界的触发和其他处理会在每次循环中会占用一定的时间,而且该时间可能每次循环会有细微的差别,为保证运行周期的稳定,采用预设步长减去实际运行时间的结果作为每次循环的实际等待时间,如代码第143~146行。

代码第85~116行为ego车配置了常规摄像头RGB camera和障碍物传感器Obstacle detector。传感器的配置分为四步:

(1)获取蓝图

每种传感器都有专门的id,可以通过BlueprintLibrary的find方法获取相应id的传感器,如代码第88和104行所示分别获取了常规摄像头RGB camera和障碍物传感器Obstacle detector。

(2)配置传感器参数

不同传感器类型的参数各有不同,为实现满意的仿真效果,需要根据模拟的真实传感器的特性和测试需求,设置相应参数,并根据仿真效果,对参数进行调整。

本实例中所使用参数的含义如下表所示:

下面对障碍物传感器的探测原理进行简要说明,方便对其参数的理解。可以将障碍物探测传感器理解为一台安装在车辆上的大炮,其安装位置和方向由其绑定至车辆的位姿transform确定,该大炮每隔sensor_tick时间向前发射一枚半径为hit_radius的球形炮弹,炮弹的最远飞行distance距离,被炮弹击中的物体即为探测到的物体。所以建议将hit_radius设置为较小值(如0.5),以避免探测到多余的物体。

(3)绑定至车辆

通过world.try_spawn_actor的attach_to参数设置传感器安装的车辆,通过transform参数设置相对于车辆几何中心的安装位置,如代码第94~96和110~112所示。

(4)定义并配置监听方法

通过传感器的listen方法配置监听方法,该方法为回调callback的形式,当传感器收到信息后,调用该方法并将传感器信息传入。由该方法对传感器信息进行处理,如代码第100和116行所示。

代码第7~20和22~31行分别是常规摄像头RGB camera和障碍物传感器Obstacle detector的监听方法。对于摄像头,将其图像显示在了pygame的窗口上,方便运行时查看;对于障碍物传感器,对其探测到的障碍物信息进行了打印。

完整代码如下:


























































































































































import carlaimport numpy as npimport pygameimport randomimport time
def rgb_camera_callback(image, pygame_display):    '''RGB camera的监听方法    '''    # print(f"-- rgb camera callback time = {time.time()}")    #在pygame窗口显示    image.convert(carla.ColorConverter.Raw)    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))    pygame_display.blit(surface, (0, 0))    #保存至文件    # image.save_to_disk(f"image/{image.frame}_{image.timestamp}.png")
def obstacle_detector_callback(obs):    '''obstacle detector的监听方法    '''    # print(f"-- obstacle detector callback time = {time.time()}")    ego_tf = obs.actor.get_transform()    other_actor_id = obs.other_actor.id    other_actor_tf = obs.other_actor.get_transform()    print(f"ego transform = {ego_tf}")    print(f"other actor id = {other_actor_id}, transform = {other_actor_tf}")    print(f"distance = {obs.distance}")  def main():    #创建client,并获取world    client = carla.Client("localhost", 2000)    world = client.get_world()    original_settings = world.get_settings()    vehicles = []    sensors = []    try:        #初始化pygame        pygame.init()        pygame.font.init()        pygame_display = pygame.display.set_mode([800, 600], pygame.HWSURFACE | pygame.DOUBLEBUF)                #设置模式为:同步定步长,且步长为0.05s        time_step = 0.05        settings = world.get_settings()        settings.synchronous_mode = True        settings.fixed_delta_seconds = time_step        world.apply_settings(settings)                #设置traffic manager为同步模式        traffic_manager = client.get_trafficmanager()        traffic_manager.set_synchronous_mode(True)                #选择一些障碍车的车型        models = ['dodge', 'audi', 'model3', 'mini', 'mustang', 'lincoln', 'prius', 'nissan', 'crown', 'impala']        blueprints = []        for vehicle in world.get_blueprint_library().filter('*vehicle*'):            if any(model in vehicle.id for model in models):            blueprints.append(vehicle)                #设置生成障碍车的数量        spawn_points = world.get_map().get_spawn_points()        max_vehicles = 50        max_vehicles = min([max_vehicles, len(spawn_points)])                #生成障碍车并设置自动驾驶        for i, spawn_point in enumerate(random.sample(spawn_points, max_vehicles)):            vehicle = world.try_spawn_actor(random.choice(blueprints), spawn_point)            if vehicle is not None:                vehicles.append(vehicle)                vehicle.set_autopilot(True)                #生成ego车        ego_bp = world.get_blueprint_library().find('vehicle.tesla.model3')        ego_bp.set_attribute('role_name','ego')        ego_spawn_point = random.choice(spawn_points)        ego_vehicle = world.try_spawn_actor(ego_bp, ego_spawn_point)        if ego_vehicle is not None:            vehicles.append(ego_vehicle)            ego_vehicle.set_autopilot(True)                sensors = []        #为ego车配置RGB camera        #1.获取blueprint        rgb_camera_bp = world.get_blueprint_library().find('sensor.camera.rgb')        #2.配置参数        rgb_camera_bp.set_attribute('image_size_x', '800')        rgb_camera_bp.set_attribute('image_size_y', '600')        rgb_camera_bp.set_attribute('fov', '110')        rgb_camera_bp.set_attribute('sensor_tick', '0.1')        #3.绑定至车辆        rgb_camera_tf = carla.Transform(carla.Location(x=1.0, z=2.0), carla.Rotation(yaw=0.0))        rgb_camera = world.try_spawn_actor(rgb_camera_bp, rgb_camera_tf, attach_to=ego_vehicle)        if rgb_camera is not None:            sensors.append(rgb_camera)        #4.配置监听方法        rgb_camera.listen(lambda image: rgb_camera_callback(image, pygame_display))                #为ego车配置Obstacle detector        #1.获取blueprint        obstacle_detector_bp = world.get_blueprint_library().find('sensor.other.obstacle')        #2.配置参数        obstacle_detector_bp.set_attribute('distance', '100')        obstacle_detector_bp.set_attribute('hit_radius', '0.5')        obstacle_detector_bp.set_attribute('only_dynamics', 'True')        obstacle_detector_bp.set_attribute('sensor_tick', '0.0')        #3.绑定至车辆        obstacle_detector_tf = carla.Transform(carla.Location(x=1.0, z=2.0), carla.Rotation(yaw=0.0))        obstacle_detector = world.try_spawn_actor(obstacle_detector_bp, obstacle_detector_tf, attach_to=ego_vehicle)        if obstacle_detector is not None:            sensors.append(obstacle_detector)        #4.配置监听方法        obstacle_detector.listen(lambda obs: obstacle_detector_callback(obs))                #运行        running = True        while running:            start_time = time.time()            ##start of own scripts            ret = world.tick()            snap = world.get_snapshot()            frame = snap.timestamp.frame            print(f"---------- frame = {frame} ----------")                        #设置spectator跟随ego车            spectator = world.get_spectator()            ego_tf = ego_vehicle.get_transform()            spectator_tf = carla.Transform(ego_tf.location, ego_tf.rotation)            spectator_tf.location += ego_tf.get_forward_vector() * (-10)            spectator_tf.location += ego_tf.get_up_vector() * 3            spectator.set_transform(spectator_tf)                        #pygame            for event in pygame.event.get():                if event.type == pygame.QUIT:                running = False            pygame.display.flip()            ##end of own scripts                        end_time = time.time()            sleep_time = time_step - (end_time -  start_time)            if sleep_time > 0:                time.sleep(sleep_time)    finally:        pygame.quit()        world.apply_settings(original_settings)        for actor in vehicles + sensors:            actor.destroy()if __name__ == "__main__":    main()
                       

来源:孙工自动驾驶
自动驾驶游戏控制渲染
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2023-10-25
最近编辑:1年前
孙工自动驾驶
硕士 专注自动驾驶仿真测试
获赞 19粉丝 30文章 82课程 0
点赞
收藏
未登录
1条评论
学习使我快乐1.0
签名征集中
8月前
您好,请问Carla中如何将camera绑定至路口信号灯上呢?
回复
课程
培训
服务
行家
VIP会员 学习计划 福利任务
下载APP
联系我们
帮助与反馈