文章目录

一、SUMO&CARLA背景二、OpenSteerMap使用三、OSM TO XODR四、CARLA加载XODR五、CARLA工程修改六、开始联合仿真七、仿真结束

一、SUMO&CARLA背景

SUMO (Simulation of Urban MObility) 是一个开源的交通模拟软件包,被广泛用于模拟城市交通系统,包括车辆、公交和行人流动。而CARLA (Car Learning to Act) 是一个开源的自动驾驶仿真模拟器,提供了一个用于自动驾驶研究的实验平台,包括物理和感知模拟。

本文主要介绍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(OpenDrive)给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 = 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'))

四、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 ================")

注:加载之后地图是这样的,因为地图比较大,道路离原点比较远。不过这不影响使用,在运行CARLA的时候可以绑定Camera到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

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())

六、开始联合仿真

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

python spawn_npc_sumo.py -n 10 -w 20 --tls-manager carla --sumo-gui

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

2)SUMO运行

七、仿真结束

1)在Pycharm终端按下CTRL+C,然后手动关闭SUMO GUI才能结束这次联合仿真。

2)此次联合仿真的难点我认为在于OSM转换成XODR的时候,因为刚开始使用脚本导出的XODR并不能直接加载到CARLA中去,后续不断尝试修改OSM2XODR脚本才能正常加载。

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

推荐链接

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