You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用traci.simulationStep()反复触发车辆未知错误的技术求助

调用traci.simulationStep()反复触发车辆未知错误的技术求助

看起来你在使用SUMO的TRACI接口做仿真时遇到了挺棘手的问题——当编队车辆离开路网后,每次调用traci.simulationStep()都会触发“车辆未知”的错误,而且还反复出现。我帮你梳理下问题根源和解决办法:

先揪出一个明显的代码bug

你的while循环里缺少了sim_step += 1!这会导致循环永远无法退出,一直重复调用traci.simulationStep(),这也是错误反复出现的直接原因之一。先把这个补上,不然你的仿真会无限跑下去:

sim_step = 0
while sim_step < 10:
    try:
        traci.simulationStep()
    except:
        print('1')
    drop, done, coll = self.is_done()
    sim_step += 1  # 一定要加这句!

核心问题:车辆离开后仍被代码引用

当车辆离开仿真路网时,SUMO会自动将其从仿真实例中移除,但你的代码后续操作还在尝试访问这些已经失效的车辆ID,尤其是在is_done()函数里的碰撞检测环节。具体来说:

  • 你先调用了traci.simulation.getCollidingVehiclesIDList(),再处理车辆离开的清理工作,这时候碰撞检测函数可能会尝试访问已经被移除的车辆,触发“车辆未知”错误。
  • 遍历lv_topology中的车辆ID时,没有先校验这些ID是否还存在于当前路网中。

针对性的修复方案

1. 调整is_done()的执行顺序:先清理再检测

把车辆离开的逻辑移到碰撞检测之前,确保后续操作只处理当前存在的车辆:

def is_done(self):
    drop = False
    done = False
    coll = {}

    # 第一步:先清理已离开路网的车辆,更新lv_topology
    veh_list = traci.vehicle.getIDList()
    pl_set = set(
        vehicle_id for vehicle_id in veh_list
        if vehicle_id.startswith('pl') and vehicle_id.endswith('0'))
    lv_set = set(self.lv_topology.keys())
    
    # 移除lv_topology中已离开的主车辆
    if lv_set - pl_set:
        drop = True
        for del_id in lv_set - pl_set:
            del self.lv_topology[del_id]
    
    # 处理不在编队中的pl车辆
    if pl_set - lv_set:
        drop = True

    # 第二步:再获取碰撞车辆列表,此时所有车辆都是有效的
    coll_list = traci.simulation.getCollidingVehiclesIDList()

    # 遍历有效车辆做碰撞检测
    for lv_id in self.lv_topology.keys():
        pl_ids = list(self.lv_topology[lv_id])
        pl_ids.append(lv_id)
        coll[lv_id] = False
        for pl in pl_ids:
            # 额外校验车辆是否存在,双重保险
            if pl in veh_list and pl in coll_list:
                done = True
                coll[lv_id] = True
        if done:
            print('1')
    
    return drop, done, coll

2. 精准捕获TRACI异常,做针对性清理

原来的try-except太宽泛,只会打印1却不处理错误根源。改成捕获TRACI专属异常,针对“车辆未知”的情况直接清理无效ID:

sim_step = 0
while sim_step < 10:
    try:
        traci.simulationStep()
    except traci.exceptions.TraCIException as e:
        err_msg = str(e)
        if "is not known" in err_msg:
            # 提取报错的车辆ID
            veh_id = err_msg.split("'")[1]
            print(f"检测到车辆{veh_id}已离开路网,自动清理相关数据")
            # 从lv_topology中移除该车辆的相关条目
            if veh_id in self.lv_topology:
                del self.lv_topology[veh_id]
            # 清理编队中关联的车辆
            for lv_id in list(self.lv_topology.keys()):
                if veh_id in self.lv_topology[lv_id]:
                    self.lv_topology[lv_id].remove(veh_id)
                    # 如果编队为空,直接移除主车辆条目
                    if not self.lv_topology[lv_id]:
                        del self.lv_topology[lv_id]
        else:
            print(f"TRACI其他错误: {e}")
    except Exception as e:
        print(f"其他未知错误: {e}")
    
    drop, done, coll = self.is_done()
    sim_step += 1

这样调整后,应该就能解决反复触发的“车辆未知”错误了——既修复了无限循环的bug,又确保代码只操作当前路网中存在的车辆,同时对意外出现的无效ID做了针对性清理。

备注:内容来源于stack exchange,提问作者1231

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.20 11:55:32