SUMO与CARLA联合仿真实现遇到的问题求助
SUMO-CARLA联合仿真整合方案(自车CARLA控制+其余车流SUMO控制)
核心思路
联合仿真的关键是双向状态同步:SUMO负责全局车流的路径规划与状态更新,CARLA负责自车的感知、决策与控制,两者通过固定步长的仿真循环,实时交换车辆位置、速度、航向等核心数据,确保场景一致性。
步骤拆解与实现代码
1. 环境与基础准备
- 确保版本兼容:推荐使用SUMO 1.16+、CARLA 0.9.14+,避免API不匹配问题
- 安装依赖:SUMO的
traci接口(随SUMO安装自带)、CARLA Python客户端包 - 场景地图对齐:用SUMO的
netconvert工具将CARLA的OpenDRIVE地图转换为SUMO路网,或反向导出,确保两者坐标系匹配
2. 坐标系转换(关键)
SUMO采用笛卡尔坐标系,CARLA基于UE4坐标系,需编写转换函数对齐:
import math def sumo_to_carla(sumo_x, sumo_y, sumo_angle): # 根据你的场景调整缩放/偏移系数,示例为反向y轴 carla_x = sumo_x carla_y = -sumo_y carla_yaw = sumo_angle # 若角度方向不一致,需加180或调整正负 return carla_x, carla_y, carla_yaw def carla_to_sumo(carla_x, carla_y, carla_yaw): sumo_x = carla_x sumo_y = -carla_y sumo_angle = carla_yaw return sumo_x, sumo_y, sumo_angle
3. 仿真启动与同步框架
启动SUMO并连接
import traci # 启动SUMO,设置固定步长0.1s sumo_cfg_path = "./your_scenario.sumocfg" sumo_cmd = ["sumo", "-c", sumo_cfg_path, "--step-length", "0.1"] traci.start(sumo_cmd) # 将SUMO中的自车设置为受控状态(避免SUMO自动控制) traci.vehicle.setSpeedMode("ego_vehicle", 0) # 禁用SUMO的速度控制 traci.vehicle.setLaneChangeMode("ego_vehicle", 0) # 禁用SUMO的变道控制
启动CARLA并加载地图
import carla client = carla.Client("localhost", 2000) client.set_timeout(10.0) world = client.load_world("Town03") # 替换为你的场景地图 settings = world.get_settings() settings.fixed_delta_seconds = 0.1 # 与SUMO步长保持一致 world.apply_settings(settings) # 生成CARLA自车(需与SUMO中自车ID对应) blueprint_library = world.get_blueprint_library() ego_bp = blueprint_library.find("vehicle.tesla.model3") ego_spawn_point = carla.Transform(carla.Location(x=0, y=0, z=0.5)) # 初始位置与SUMO对齐 ego_vehicle = world.spawn_actor(ego_bp, ego_spawn_point)
4. 双向状态同步
SUMO车流同步到CARLA
遍历SUMO中除自车外的所有车辆,更新CARLA中对应车辆的状态:
# 预存CARLA车辆字典,避免重复生成 carla_vehicles = {} def sync_sumo_to_carla(): sumo_veh_ids = traci.vehicle.getIDList() for veh_id in sumo_veh_ids: if veh_id == "ego_vehicle": continue # 获取SUMO车辆状态 sumo_pos = traci.vehicle.getPosition(veh_id) sumo_speed = traci.vehicle.getSpeed(veh_id) sumo_angle = traci.vehicle.getAngle(veh_id) # 转换为CARLA坐标 carla_x, carla_y, carla_yaw = sumo_to_carla(sumo_pos[0], sumo_pos[1], sumo_angle) # 生成或更新CARLA车辆 if veh_id not in carla_vehicles: veh_bp = blueprint_library.find("vehicle.tesla.model3") # 替换为对应车型 spawn_transform = carla.Transform( carla.Location(x=carla_x, y=carla_y, z=0.5), carla.Rotation(yaw=carla_yaw) ) carla_veh = world.spawn_actor(veh_bp, spawn_transform) carla_vehicles[veh_id] = carla_veh else: carla_veh = carla_vehicles[veh_id] # 更新位置与速度 target_transform = carla.Transform( carla.Location(x=carla_x, y=carla_y, z=0.5), carla.Rotation(yaw=carla_yaw) ) carla_veh.set_transform(target_transform) carla_veh.set_target_velocity(carla.Vector3D(x=sumo_speed, y=0, z=0))
CARLA自车同步到SUMO
将CARLA中自车的实时状态反馈给SUMO,确保车流能避让自车:
def sync_carla_to_sumo(): ego_transform = ego_vehicle.get_transform() ego_vel = ego_vehicle.get_velocity() # 转换为SUMO坐标与状态 sumo_x, sumo_y, sumo_angle = carla_to_sumo( ego_transform.location.x, ego_transform.location.y, ego_transform.rotation.yaw ) sumo_speed = math.sqrt(ego_vel.x**2 + ego_vel.y**2) # 更新SUMO自车状态 traci.vehicle.setPosition("ego_vehicle", (sumo_x, sumo_y)) traci.vehicle.setSpeed("ego_vehicle", sumo_speed) traci.vehicle.setAngle("ego_vehicle", sumo_angle)
5. 主仿真循环
import time # 替换为你的自车掉头控制逻辑 def get_ego_driving_control(): # 示例:简单的掉头控制,可替换为PID/强化学习模型 control = carla.VehicleControl() control.throttle = 0.3 control.steer = 0.5 # 左转掉头,根据场景调整 return control try: while traci.simulation.getMinExpectedNumber() > 0: # 1. 同步SUMO车流到CARLA sync_sumo_to_carla() # 2. 执行CARLA自车控制 ego_control = get_ego_driving_control() ego_vehicle.apply_control(ego_control) # 3. 同步CARLA自车到SUMO sync_carla_to_sumo() # 4. 推进仿真步 traci.simulationStep() time.sleep(0.1) # 与步长保持一致 finally: # 清理资源 traci.close() ego_vehicle.destroy() for veh in carla_vehicles.values(): veh.destroy()
关键注意事项
- 步长严格同步:SUMO与CARLA的仿真步长必须完全一致,否则会出现状态错位
- SUMO自车配置:在SUMO的
rou.xml中需将自车标记为controlled="true",避免SUMO自动干预 - 碰撞规避:若出现车流与自车碰撞,可调整SUMO的
carFollowModel参数(如增加安全距离),或优化状态同步的延迟 - 性能优化:避免在每一步都重复生成车辆,用字典缓存已生成的CARLA车辆实例
内容的提问来源于stack exchange,提问作者Kristof Papp
相关产品推荐
相关产品推荐

