CoolFace
Apppublic

heet6017/police-control-room-env

sourceHugging Faceupdated 6mo agoView on Hugging Face
0likes
App README

Police Control Room AI — OpenEnv Environment

A real-world reinforcement learning environment simulating an emergency police dispatch control room. An AI agent receives live incident reports and must decide — without any hardcoded rules — how many police units, ambulances, and fire trucks to deploy, which unit types to send, and how to triage when resources are scarce.

Built for the Meta PyTorch × Hugging Face OpenEnv Hackathon.


Why this environment?

Real police dispatchers make high-stakes allocation decisions every day under time pressure and resource constraints. This environment models those exact decisions:

  • An armed robbery at night with 2 suspects — how many units, which type, ambulance standby?
  • A vehicle collision with spreading fire and trapped civilians — police + fire + ambulance coordination?
  • 5 simultaneous incidents across the city with only 8 police units available — triage under pressure?

These are not toy problems. They are simplified but faithful models of real dispatch decisions.


Environment overview

PropertyValue
Tasks3 (easy → medium → hard)
Action spacePoliceDispatchAction / SurgeAllocationAction
Observation spaceIncidentObservation
Reward range(0.0, 1.0) — strictly exclusive
Reward typeContinuous with partial credit
Episode typeSingle-step
Grader typeDeterministic

Tasks

Task 1 — Single dispatch (easy)

Scenario: Armed robbery in progress. Night. 2 armed suspects. 3 civilians at risk. 2.4km away.

The agent must send the correct number and type of police units, decide on ambulance standby, and set the right priority level.

Grader: Unit count (±1 of optimal), unit type correctness, priority level, ambulance decision, officers per unit.

Expected score: 0.75 – 1.0


Task 2 — Multi-agency incident (medium)

Scenario: Vehicle collision with spreading fire. 2 injured, 1 trapped. Rain. 1.1km away.

The agent must coordinate three services simultaneously — police, fire, and ambulance — with the right counts and types.

Grader: Fire truck dispatch (critical — missing = −0.40), ambulance dispatch (critical — missing = −0.30), police count and type, priority level.

Expected score: 0.40 – 0.80


Task 3 — Resource-constrained surge (hard)

Scenario: 5 simultaneous incidents across the city. Only 8 police units, 2 ambulances, 1 fire truck available. INC-A: hostage severity=5 distance=3.2km INC-B: vehicle fire severity=5 distance=0.8km fire=true medical=true INC-C: riot severity=3 distance=1.5km INC-D: break-in severity=2 distance=4.1km INC-E: medical severity=4 distance=2.0km medical=true

The agent must triage all 5 incidents and allocate all available resources optimally — no idle units.

Grader: Severity-based priority (sev-5 incidents get resources first), correct service assignment per incident, no over-staffing of low-severity calls, full resource utilisation.

Expected score: 0.20 – 0.60


Observation space

IncidentObservation (Pydantic model):

FieldTypeDescription
incident_typestrType of emergency
severityint (1–5)Incident severity
urgencyint (1–5)Response urgency
distance_kmfloatDistance to scene
civilians_at_riskintCivilians in danger
civilians_injuredintConfirmed injuries
fire_riskboolFire present
fire_spreadingboolFire actively spreading
armed_suspectsboolArmed individuals present
time_of_daystrmorning/afternoon/evening/night
weatherstrclear/rain/fog/storm
resourcesResourcePoolAvailable units
surge_incidentslistTask 3 only — 5 incidents

Action space

Tasks 1 & 2 — `PoliceDispatchAction`:

FieldTypeDescription
police_unitsint (0–20)Units to dispatch
officers_per_unitint (1–8)Officers per unit
unit_typestrpatrol/swat/k9/traffic/riot/detective
send_ambulanceboolDispatch ambulance
ambulance_countintNumber of ambulances
send_fire_truckboolDispatch fire truck
fire_truck_countintNumber of fire trucks
priority_levelint (1–3)1 = highest
reasoningstrAgent's explanation

Task 3 — `SurgeAllocationAction`: Dict of 5 SingleIncidentAllocation objects keyed by INC-A through INC-E.


Reward function

All rewards strictly in (0.0, 1.0) with partial credit at every component:

Task 1 components:

  • Unit count in optimal range [2–4]: +0.30
  • Correct unit type (patrol/swat): +0.25
  • Priority level = 1: +0.20
  • Ambulance sent: +0.15
  • Officers per unit in range [3–5]: +0.10
  • Over-dispatch (>6 units): −0.15
  • Zero units sent: −1.00 (critical fail)

Task 2 components:

  • Fire truck sent: +0.30 | Missing fire truck: −0.40
  • Ambulance sent: +0.25 | Missing ambulance: −0.30
  • Police count correct: +0.20
  • Correct unit type: +0.10
  • Priority = 1: +0.15

Task 3 components:

  • Sev-5 incidents get majority resources: +0.35
  • INC-B gets fire truck: +0.20
  • Medical incidents get ambulance: +0.15
  • Sev-2 not over-staffed: +0.10
  • All 8 units allocated: +0.10
  • SWAT for hostage: +0.10
  • Inverted priority (sev-2 > sev-5): −0.30

Baseline scores (Qwen/Qwen2.5-72B-Instruct)

TaskScoreResult
single_dispatch0.850success
multi_agency0.970success
resource_surge0.999success
Mean0.940

Live demo & links

ResourceLink
HF Spacehttps://huggingface.co/spaces/heet6017/police-control-room-env
Live UIhttps://heet6017-police-control-room-env.hf.space/ui
Health checkhttps://heet6017-police-control-room-env.hf.space/ping
Resethttps://heet6017-police-control-room-env.hf.space/reset?taskid=singledispatch
Stephttps://heet6017-police-control-room-env.hf.space/step?taskid=singledispatch
Scenarioshttps://heet6017-police-control-room-env.hf.space/scenarios
GitHubhttps://github.com/heet6017/police-control-room-env

Setup & running

Local setup

bash
git clone https://huggingface.co/spaces/heet6017/police-control-room-env
cd police-control-room-env
python -m venv venv
venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env
# Add your HF_TOKEN in .env

Run tests

bash
pytest tests/ -v
# Expected: 16 passed in 0.23s

Run baseline inference

bash
python inference.py

Expected output: [START] task=singledispatch env=policecontrolroom model=Qwen/Qwen2.5-72B-Instruct [STEP] step=1 action=4xswatpri1 reward=0.85 done=true error=null [END] success=true steps=1 score=0.850 rewards=0.85 [START] task=multiagency env=policecontrolroom model=Qwen/Qwen2.5-72B-Instruct [STEP] step=1 action=2xpatrolpri1 reward=0.97 done=true error=null [END] success=true steps=1 score=0.970 rewards=0.97 [START] task=resourcesurge env=policecontrolroom model=Qwen/Qwen2.5-72B-Instruct [STEP] step=1 action=Prioritizedby_severity reward=1.00 done=true error=null [END] success=true steps=1 score=0.999 rewards=1.00

Run UI locally

bash
python app.py
# Open http://localhost:7860

Docker

bash
docker build -t police-control-room-env .
docker run -p 7860:7860 -e HF_TOKEN=your_token police-control-room-env

API endpoints

EndpointMethodDescription
/pingGETHealth check
/reset?task_id=single_dispatchPOSTReset, get observation
/step?task_id=single_dispatchPOSTSubmit action, get reward
/state?task_id=single_dispatchGETCurrent state
/scenariosGETPreview all 3 scenarios

Example API call

python
import httpx

BASE = "https://heet6017-police-control-room-env.hf.space"

obs = httpx.post(f"{BASE}/reset?task_id=single_dispatch").json()

action = {
    "police_units": 3, "officers_per_unit": 4, "unit_type": "swat",
    "send_ambulance": True, "ambulance_count": 1,
    "send_fire_truck": False, "fire_truck_count": 0,
    "priority_level": 1, "cordon_area": False,
    "notify_supervisor": False, "reasoning": "armed robbery at night"
}

result = httpx.post(f"{BASE}/step?task_id=single_dispatch", json=action).json()
print(result["reward"], result["feedback"])

Project structure

police-control-room-env/ ├── models.py — Pydantic models (Observation, Action, Reward) ├── scenarios.py — Deterministic incident generators ├── reward.py — Quantified grader functions ├── graders.py — Task router ├── env.py — OpenEnv interface (reset/step/state) ├── inference.py — Baseline inference script ├── app.py — Gradio UI + FastAPI server ├── openenv.yaml — OpenEnv metadata ├── Dockerfile — Container definition ├── pyproject.toml — Package config ├── uv.lock — Dependency lock file ├── requirements.txt — Dependencies ├── README.md — This file └── tests/ ├── testmodels.py ├── testgraders.py └── test_env.py


License

MIT