Advertisement

Carla自动驾驶仿真七:CARLA&SUMO真实世界交通流仿真

阅读量:

文章目录

  • 一、基于SUMO与CARLA的背景
  • 二、OpenSteerMap的应用
  • 三、从OSM转换为XODR的过程
  • 四、在CARLA中加载XODR的具体方法
  • 五、CARLA环境下进行工程修改的步骤
  • 六、开始联合仿真操作的流程
  • 七、仿真结束后的总结与分析

一、SUMO&CARLA背景

SUMO(城市交通移动性仿真)作为一个开放源代码的城市交通系统模拟工具,在城市规划与管理中具有广泛应用。而CARLA则是一个专门用于自动驾驶技术研究与开发的仿真实验平台。它涵盖了从物理环境到感知系统(如摄像头、雷达等)的全面模拟。

本文重点阐述了基于真实地理环境设置下的SUMO和CARLA软件平台进行交通流仿真的方法,并通过仿真实验验证了该系统能够实现高级别自动驾驶行为的仿真需求。同时,在复杂交通场景下,该仿真实验还证明了其在NOA等关键功能模块上的良好适用性

CARLA &SUMO加载交通流框架:

在这里插入图片描述

CARLA &SUMO联合仿真框架:

在这里插入图片描述

二、OpenSteerMap使用

1)OpenStreetMap简介

OpenStreetMap(OSM)是由不同参与者组成的开放社区致力于提供一张全球可用并不断更新的地图。该系统通过GPS设备获取定位信息、利用无人机拍摄遥感影像以及借助各类公共数据源或实地调查来收集地图数据。

2)OpenStreetMap官网:

https://www.openstreetmap.org(需要科学上网)

在这里插入图片描述

3)导出OSM地图

在这里插入图片描述
在这里插入图片描述

三、OSM TO XODR

1)OSM转XODR

必须将OSM文件转换为XODR格式,并将其导入到CARLA中使用。同时, CARLA能够直接导入未转换的OSM文件。然而, 为了后续应用Roadrunner对道路网络和建筑信息进行修改的需求, 我们必须将原始数据转化为XODR格式。

复制代码
    import io
    import carla
    import os
    import xml.etree.ElementTree as ET
    # 注意:这里只是目录路径,不包括 proj.db 文件本身,这个需要安装库pyproj,
    # 为了消除pj_obj_create: Cannot find proj.db错误,不消除也不影响。
    os.environ['PROJ_LIB'] = 'D:\Python\Lib\site-packages\pyproj\proj_dir\share\proj'
    
    #osm文件路径
    osm_path = r'C:\Users\Desktop\map2.osm'
    
    # Read the .osm data
    f = io.open(osm_path, mode="r", encoding="utf-8")
    osm_data = f.read()
    f.close()
    
    # Define the desired settings. In this case, default values.
    settings = carla.Osm2OdrSettings()
    # Set OSM road types to export to OpenDRIVE
    settings.set_osm_way_types(["motorway", "motorway_link", "trunk", "trunk_link", "primary", "primary_link", "secondary", "secondary_link", "tertiary", "tertiary_link", "unclassified", "residential"])
    settings.use_offsets =False
    settings.center_map =False
    # Convert to .xodr
    xodr_data = carla.Osm2Odr.convert(osm_data, settings)
    
    # 解析 XML 数据
    root = ET.fromstring(xodr_data)
    
    roads = root.findall('.//road')
    #修改道路的中文名称,这会影响CARLA加载地图
    for index,road in enumerate(roads):
    road_name = road.attrib.get('name')
    for char in road_name:
        #如果道路的名称存在中文字符,则修改道路名称
        if '\u4e00' <= char <= '\u9fa5':
            road_name = ''.join(['road',str(index)])
            road.set('name',road_name)
    
    # 查找 <header> 标签
    header = root.find('.//header')
    
    # 修改原点信息,原点太远地图也无法顺利加载
    if header is not None:
    # 提取地图区域,以south和west作为地图区域的原点
    north = float(header.attrib.get('north'))
    south = float(header.attrib.get('south'))
    east = float(header.attrib.get('east'))
    west = float(header.attrib.get('west'))
    # 新原点计算
    x_orig = abs(round(east - west,6))
    y_orig = abs(round(north - south))
    header.set('north', str(y_orig))
    header.set('south', '0')
    header.set('east', str(x_orig))
    header.set('west','0')
    
    # 根据新生成的原点,修改道路坐标
    # OSM导出的坐标过大,无法正常加载
    geometries = root.findall('.//geometry')
    for geometry in geometries:
    x = float(geometry.attrib.get('x'))
    y = float(geometry.attrib.get('y'))
    new_x = str(round(x - west,6))
    new_y = str(round(y - south,6))
    # 修改 x 和 y 属性值
    geometry.set('x', new_x)
    geometry.set('y', new_y)
    # 读取修改后的 x 和 y 属性值
    new_x = geometry.attrib.get('x')
    new_y = geometry.attrib.get('y')
    
    # 保存修改后的 XML 数据到文件中
    tree = ET.ElementTree(root)
    tree.write('modified_file.xodr')
    
    # 保存修改后的 XODR 数据到文件中
    with open(r"C:\Users\Desktop\map2.xodr", 'w') as f:
    f.write(ET.tostring(root, encoding='unicode'))
    
    
    python
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/OFzR82sEXKUPyxiwSJBgAe6DQCaN.png)

四、CARLA加载XODR

1)打开CARLA客户端

在这里插入图片描述

2)脚本加载XODR

复制代码
    import carla
    
    try:
    print("================ Starting ================")
    # 创建一个客户端
    client = carla.Client('localhost', 2000)
    client.set_timeout(5)
    # 加载OpenDrive地图
    xodr_path = r'C:\Users\mini\Desktop\map2.xodr'
    with open(xodr_path, encoding='utf-8') as od_file:
        data = od_file.read()
        vertex_distance = 2.0  # in meters
        max_road_length = 500.0  # in meters
        wall_height = 0.5      # in meters
        extra_width = 1      # in meters
        world = client.generate_opendrive_world(
            data, carla.OpendriveGenerationParameters(
                vertex_distance=vertex_distance,
                max_road_length=max_road_length,
                wall_height=wall_height,
                additional_width=extra_width,
                smooth_junctions=True,
                enable_mesh_visibility=True))
    print("the current world is:", world)
    #
    except Exception as e:
    print("Exception detected:", e)
    finally:
    pass
    print("================ ending ================")
    
    
    python
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/NiAD6TK9UesvXwSkQWgucH2a18P7.png)
在这里插入图片描述

注:加载完成后的地图状态如下所示;由于地图尺寸较大,在车辆与目标地点之间存在一定的距离。然而这并不会影响使用体验,在CARLA模拟环境中可以通过将摄像头绑定至NPC角色身上来实现对道路区域的观察。从而使得视野范围内包含该道路区域的信息内容。


五、CARLA工程修改

1)打开CARLA工程

在这里插入图片描述

2)修改spawn_npc_sumo.py

spawn_npc_sumo.py是需要优化或调整的,主要原因在于CARLA中的NPC视野切换,这样才能观察到车辆在道路上行驶.

在这里插入图片描述
复制代码
    synchronization.tick(flag)
    #切换NPC视野
    if flag:
    start_time = start
    flag = False
    else:
    process_time = time.time() - start_time
    #经过8s就自动切换NPC视野
    if process_time >= 8.0:
        flag = True
    
    
    python
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/jflx7nLW5QReN6q2dVaDv0EYH31G.png)

3)修改run_synchronization.py

在这里插入图片描述
在这里插入图片描述
复制代码
    #genarate camera in carla
    if flag:
    # 查找Camera蓝图
    camera_bp = self.carla.world.get_blueprint_library().find('sensor.camera.rgb')
    # 设置生成Camera的附加类型为SpringArmGhost
    Atment_SpringArmGhost = carla.libcarla.AttachmentType.Rigid
    # 设置Camera的安装坐标系
    Camera_transform = carla.Transform(carla.Location(x=-10, y=0, z=5),
                        carla.Rotation(pitch=-10, yaw=0, roll=0))
    #获取carla中的actor
    vehicle_list = self.carla.world.get_actors().filter('vehicle.*')
    if vehicle_list:
        actor = random.choice(vehicle_list)
    # 生成Camera
    self.camera = self.carla.world.spawn_actor(camera_bp, Camera_transform, attach_to=actor,
                                        attachment_type=Atment_SpringArmGhost)
    # 设置观察者视图
    if self.camera:
    spectator = self.carla.world.get_spectator()
    spectator.set_transform(self.camera.get_transform())
    
    
    python
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/GP5ZjIdo1u8vyfzsETnx2wQctlKY.png)

六、开始联合仿真

1)终端spawn_npc_sumo.py(确保SUMO正常安装,网上很多安装教程)

复制代码
    python spawn_npc_sumo.py -n 10 -w 20 --tls-manager carla --sumo-gui
    
    
    python

spawn_npc_sumo.py之后,SUMO GUI会自动打开,并且看到路网被正确加载。

在这里插入图片描述

2)SUMO
![!在这里插入图片描述\((https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/NIC68HmuoLWbShVxRtnAjapvOPJ4.png)

在这里插入图片描述
在这里插入图片描述

七、仿真结束

在Pycharm终端启动时按下Ctrl+C后需手动关闭SUMO图形界面才能完成此次联合仿真

此次联合仿真的主要难点我认为在于将OSM转换为XODR的过程中,在此之前由于最初使用从脚本导出的XODR无法直接导入到CARLA环境中 因此必须经过反复调整和优化OSM2XODR脚本后才能成功加载

另外,我新创建了一个公众号,有兴趣的可以关注下~

在这里插入图片描述

全部评论 (0)

还没有任何评论哟~