Traffic-Control-Env / grader.py
dootisaha25's picture
Initial OpenEnv traffic signal environment
852e969
Raw
History Blame Contribute Delete
2.71 kB
from typing import Iterable, Optional
from baseline import baseline_policy
from env import IndianTrafficEnv
from models import GraderOutput, TrafficAction
MIN_SCORE = 0.001
MAX_SCORE = 0.999
def _clamp(value: float) -> float:
"""Clamp grader outputs into the validator-safe open interval (0, 1)."""
return max(MIN_SCORE, min(MAX_SCORE, float(value)))
def grade_rollout(
task_id: str = "single_intersection",
seed: int = 42,
actions: Optional[Iterable[TrafficAction]] = None,
max_steps: Optional[int] = None,
) -> GraderOutput:
env = IndianTrafficEnv(task_id=task_id)
env.reset(seed=seed, task_id=task_id)
limit = max_steps or int(env.task.constraints["max_steps"])
provided_actions = list(actions) if actions is not None else None
total_reward = 0.0
for step_idx in range(limit):
if provided_actions is None:
action = baseline_policy(env.get_state())
elif step_idx < len(provided_actions):
action = provided_actions[step_idx]
else:
action = TrafficAction.ALL_RED
_, reward, done, _ = env.step(action)
total_reward += reward
if done:
break
metrics = env.metrics
average_waiting_time = (
metrics.total_wait_observations / metrics.wait_samples if metrics.wait_samples else 0.0
)
emergency_efficiency = (
metrics.emergency_cleared_fast / metrics.emergency_seen if metrics.emergency_seen else 1.0
)
wait_score = 1.0 - min(1.0, average_waiting_time / 950.0)
queue_score = 1.0 - min(1.0, metrics.max_queue_length / float(env.task.constraints["max_queue_before_failure"]))
clearance_score = min(1.0, metrics.total_vehicles_cleared / float(env.task.termination["target_cleared"]))
safety_score = 1.0 - min(1.0, metrics.unsafe_switches / 18.0)
score = (
0.30 * wait_score
+ 0.22 * queue_score
+ 0.25 * clearance_score
+ 0.18 * emergency_efficiency
+ 0.05 * safety_score
)
return GraderOutput(
score=round(_clamp(score), 4),
average_waiting_time=round(average_waiting_time, 3),
max_queue_length=metrics.max_queue_length,
total_vehicles_cleared=metrics.total_vehicles_cleared,
emergency_handling_efficiency=round(emergency_efficiency, 4),
details={
"task_id": task_id,
"seed": seed,
"total_reward": round(total_reward, 4),
"unsafe_switches": metrics.unsafe_switches,
"emergency_seen": metrics.emergency_seen,
"emergency_cleared_fast": metrics.emergency_cleared_fast,
"full_clearances": metrics.full_clearances,
},
)