降低检测器数据获取频率,修复仅获取单车道数据的问题
This commit is contained in:
parent
f64d74b986
commit
d4eadccbf3
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Reference in New Issue