基于RLlib与SUMO的交通灯RL训练异常:SUMO-GUI无响应报错
RLlib + SUMO交通灯管控训练故障排查与修复
问题分析
从错误日志可定位两个核心故障:
- Gym接口不兼容:RLlib调用
reset(seed=None, options={})时,自定义环境的reset方法未适配该参数,触发TypeError。 - TRACI连接冲突:环境初始化时直接启动TRACI,多Worker模式下多个环境实例抢占连接,导致通信失败,出现
FatalTraCIError。
修复后的完整代码
import gymnasium as gym from gymnasium import spaces import numpy as np import traci from ray import tune from ray.rllib.agents.ppo import PPOTrainer import ray class SumoEnv(gym.Env): def __init__(self, env_config): self.sumo_binary = env_config["sumo_binary"] self.sumocfg = env_config["sumocfg"] self.num_lanes = env_config["num_lanes"] self.action_map = {"G": 'GGgrrrGGgrrr', "R": 'rrrGGgrrrGGg'} self.observation_space = spaces.Box(low=0, high=np.inf, shape=(self.num_lanes,)) self.action_space = spaces.Discrete(2) # 初始化时不启动TRACI,连接管理交给reset方法 self.traci_conn = None def reset(self, seed=None, options=None): # 适配Gymnasium标准reset接口 super().reset(seed=seed) # 关闭旧连接避免资源泄漏 if self.traci_conn is not None: self.traci_conn.close() # 使用随机端口启动TRACI,避免多实例连接冲突 free_port = traci.getFreePort() sumo_cmd = [self.sumo_binary, "-c", self.sumocfg, "--remote-port", str(free_port)] self.traci_conn = traci.connect(port=free_port) # 返回符合Gymnasium要求的(观测, 信息)元组 return self.get_observation(), {} def step(self, action): action_str = ["G", "R"][int(action)] self.traci_conn.simulationStep() self.traci_conn.trafficlight.setPhase("tl", self.action_map[action_str]) obs = self.get_observation() reward = self.get_reward() done = self.is_done() # 返回Gymnasium标准step输出格式 return obs, reward, done, False, {} def get_observation(self): lanes = self.traci_conn.lane.getIDList() obs = [self.traci_conn.lane.getLastStepVehicleNumber(lane) for lane in lanes] return np.array(obs, dtype=np.float32) def get_reward(self): lanes = self.traci_conn.lane.getIDList() return -sum([self.traci_conn.lane.getWaitingTime(lane) for lane in lanes]) def is_done(self): return self.traci_conn.simulation.getMinExpectedNumber() <= 0 def close(self): # 环境销毁时释放TRACI连接 if self.traci_conn is not None: self.traci_conn.close() self.traci_conn = None if __name__ == "__main__": ray.init() env_config = { "sumo_binary": 'C:\\Program Files (x86)\\Eclipse\\Sumo\\bin\\sumo-gui.exe', "sumocfg": "configuration.sumocfg", "num_lanes": 8 } config = { "env": SumoEnv, "env_config": env_config, "num_workers": 1, "num_gpus": 0, "lr": 1e-4, } tune.run(PPOTrainer, config=config)
关键修改说明
- 适配Gymnasium接口:
reset方法添加seed和options参数,返回(观测, 信息)元组,符合框架规范。step方法调整返回格式,包含terminated和truncated字段,匹配RLlib调用要求。
- 修复TRACI连接问题:
- 取消
__init__中的TRACI启动逻辑,改为每次reset时创建带随机端口的新连接,避免多实例冲突。 - 添加
close方法,确保环境销毁时释放TRACI连接资源。
- 取消
- 代码健壮性优化:
- 用
self.traci_conn显式管理连接,避免全局TRACI模块的状态混乱。 - 观测值转为
float32类型,适配RLlib的输入数据格式要求。
- 用
内容的提问来源于stack exchange,提问作者shi ft
相关产品推荐
相关产品推荐

