降低检测器数据获取频率,修复仅获取单车道数据的问题

This commit is contained in:
Zihan Ye 2026-03-29 02:18:13 +08:00
parent f64d74b986
commit d4eadccbf3
1 changed files with 54 additions and 46 deletions

View File

@ -76,14 +76,18 @@ class SUMOEdgeVSLEnvironment:
net_file=self.net_file,
)
# 为每条边构建检测器映射(只用第一个检测器获取边级数据
self.edge_detector_map: Dict[str, str] = {}
# 为每条边构建第一组检测器映射(所有车道
self.edge_detector_map: Dict[str, List[str]] = {}
for edge_id in self.control_edges:
ei = self.parser.edge_info.get(edge_id)
if ei and ei.detectors:
# 取第一个检测器作为该边的代表
first_det = list(ei.detectors.values())[0]
self.edge_detector_map[edge_id] = first_det
# 获取第一组检测器pos_index=0的所有交通车道
first_group_dets = []
for lane_idx in ei.traffic_lane_indices:
det_id = ei.detectors.get((lane_idx, 0))
if det_id:
first_group_dets.append(det_id)
self.edge_detector_map[edge_id] = first_group_dets
# 动作空间: 每条边独立选速度
self.action_dims = [self.num_speed_actions] * self.num_edges
@ -181,8 +185,10 @@ class SUMOEdgeVSLEnvironment:
self._interval_arrived += traci.simulation.getArrivedNumber()
self._interval_departed += traci.simulation.getDepartedNumber()
state = self._collect_state()
info = self._collect_metrics()
# 只读取一次检测器数据
detector_data = self._get_edge_detector_data()
state = self._collect_state(detector_data)
info = self._collect_metrics(detector_data)
reward = self._calculate_reward(info)
self._last_reward = reward
@ -209,32 +215,54 @@ class SUMOEdgeVSLEnvironment:
for i, edge_id in enumerate(self.control_edges):
traci.edge.setMaxSpeed(edge_id, float(edge_speeds[i]))
def _collect_state(self) -> np.ndarray:
"""收集状态:每条边的平均速度/占有率/流量"""
state_parts = []
def _get_edge_detector_data(self) -> Tuple[List[float], List[float], List[int], List[float]]:
"""获取所有控制边的检测器数据(速度、占有率、车辆数、有效速度)"""
speeds, occs, counts, valid_speeds = [], [], [], []
for edge_id in self.control_edges:
det_id = self.edge_detector_map.get(edge_id)
if det_id:
det_ids = self.edge_detector_map.get(edge_id, [])
if not det_ids:
speeds.append(self.free_flow_speed)
occs.append(0.0)
counts.append(0)
continue
# 获取所有车道的数据
lane_speeds, lane_occs, lane_counts = [], [], []
for det_id in det_ids:
try:
spd = traci.inductionloop.getLastIntervalMeanSpeed(det_id)
occ = traci.inductionloop.getLastIntervalOccupancy(det_id)
cnt = traci.inductionloop.getLastIntervalVehicleNumber(det_id)
if spd <= 0:
spd = traci.lane.getMaxSpeed(traci.inductionloop.getLaneID(det_id))
if spd > 0:
lane_speeds.append(spd)
lane_occs.append(occ)
lane_counts.append(cnt)
except Exception:
spd = self.free_flow_speed
occ = 0.0
cnt = 0
else:
spd = self.free_flow_speed
occ = 0.0
cnt = 0
pass
# 聚合
speeds.append(np.mean(lane_speeds) if lane_speeds else self.free_flow_speed)
occs.append(np.mean(lane_occs) if lane_occs else 0.0)
counts.append(sum(lane_counts))
if lane_speeds:
valid_speeds.append(np.mean(lane_speeds))
return speeds, occs, counts, valid_speeds
def _collect_state(self, detector_data: Optional[Tuple[List[float], List[float], List[int], List[float]]] = None) -> np.ndarray:
"""收集状态:每条边的平均速度/占有率/流量"""
state_parts = []
if detector_data is None:
speeds, occs, counts, _ = self._get_edge_detector_data()
else:
speeds, occs, counts, _ = detector_data
for spd, occ, cnt in zip(speeds, occs, counts):
mean_speed_norm = np.clip(spd / self.free_flow_speed, 0.0, 1.5)
mean_occ = np.clip(occ / 100.0, 0.0, 1.0)
flow_norm = min(cnt / 50.0, 1.0)
state_parts.extend([mean_speed_norm, mean_occ, flow_norm])
# 边限速
@ -252,7 +280,7 @@ class SUMOEdgeVSLEnvironment:
return np.array(state_parts, dtype=np.float32)
def _collect_metrics(self) -> Dict:
def _collect_metrics(self, detector_data: Tuple[List[float], List[float], List[int], List[float]]) -> Dict:
"""收集交通指标"""
info = {}
@ -263,34 +291,14 @@ class SUMOEdgeVSLEnvironment:
info["departed_count"] = self._interval_departed
# 每条边的速度和占有率
edge_speeds = []
edge_occs = []
all_speeds = []
for edge_id in self.control_edges:
det_id = self.edge_detector_map.get(edge_id)
if det_id:
try:
spd = traci.inductionloop.getLastIntervalMeanSpeed(det_id)
occ = traci.inductionloop.getLastIntervalOccupancy(det_id)
if spd <= 0:
spd = traci.lane.getMaxSpeed(traci.inductionloop.getLaneID(det_id))
edge_speeds.append(spd)
edge_occs.append(occ)
all_speeds.append(spd)
except Exception:
edge_speeds.append(self.free_flow_speed)
edge_occs.append(0.0)
else:
edge_speeds.append(self.free_flow_speed)
edge_occs.append(0.0)
edge_speeds, edge_occs, _, valid_speeds = detector_data
info["edge_speeds_ms"] = edge_speeds
info["edge_occupancies"] = edge_occs
info["mean_speed"] = np.mean(all_speeds) if all_speeds else 0.0
info["mean_speed"] = np.mean(valid_speeds) if valid_speeds else 0.0
info["mean_speed_kmh"] = info["mean_speed"] * 3.6
info["mean_occupancy"] = np.mean(edge_occs) if edge_occs else 0.0
info["speed_std"] = np.std(all_speeds) if len(all_speeds) > 1 else 0.0
info["speed_std"] = np.std(valid_speeds) if len(valid_speeds) > 1 else 0.0
# 车辆数和密度
try: