调用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
相关产品推荐
相关产品推荐

