
Carla自动驾驶仿真七:CARLA&SUMO真实世界交通流仿真
OpenStreetMap(OSM)是一个合作项目,旨在创建一个自由且可编辑的世界地图。它由志愿者使用GPS设备、航空摄影、其他免费资源或者直接的地面观察来收集数据。
一、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> 标签
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脚本才能正常加载。
另外,我新创建了一个公众号,有兴趣的可以关注下~
更多推荐
所有评论(0)