Spaces:
Sleeping
Sleeping
| """ | |
| decision.py — Tactical Decision Layer | |
| --------------------------------------- | |
| Receives ETA and hit probability from models.py and converts them into | |
| a human-readable threat level and tactical recommendation. | |
| This module knows nothing about models, physics, or metadata. | |
| Its only job is: predictions in, decision out. | |
| """ | |
| from src.schemas import DECISION_THRESHOLDS | |
| def get_recommendation(eta_seconds, hit_probability, no_aa_capability, enemy_generation, friendly_generation): | |
| """ | |
| Converts model predictions and platform data into a tactical recommendation. | |
| Args: | |
| eta_seconds (float): Predicted evasion time in seconds, clipped at 0. | |
| hit_probability (float): Probability of hit after evasion maneuvers (0.0 - 1.0). | |
| no_aa_capability (int): 1 if enemy has no air-to-air capability, 0 otherwise. | |
| enemy_generation (float): Enemy aircraft generation (e.g. 4.0, 4.5, 5.0). | |
| friendly_generation (float): Friendly aircraft generation (e.g. 4.0, 4.5, 5.0). | |
| Returns: | |
| str: Tactical recommendation string for the pilot. | |
| """ | |
| # Check first air-to-air capability | |
| if no_aa_capability == 1: | |
| return "NON-THREAT PLATFORM - MONITOR" | |
| # Calculate the generational gap | |
| gen_gap = friendly_generation - enemy_generation | |
| # Define combat posture | |
| if gen_gap >= DECISION_THRESHOLDS['gen_advantage_threshold']: | |
| combat_posture = "Friendly advantage" | |
| elif gen_gap <= -DECISION_THRESHOLDS['gen_disadvantage_threshold']: | |
| combat_posture = "Enemy advantage" | |
| else: | |
| combat_posture = "Parity" | |
| # Get the ETA status | |
| if eta_seconds <= DECISION_THRESHOLDS['eta_critical']: | |
| eta_status = "Low ETA" | |
| else: | |
| eta_status = "High ETA" | |
| # Get the Hit probability status | |
| if hit_probability >= DECISION_THRESHOLDS['hit_prob_high']: | |
| hit_status = "High hit probability" | |
| elif DECISION_THRESHOLDS['hit_prob_medium'] <= hit_probability <= DECISION_THRESHOLDS['hit_prob_high']: | |
| hit_status = "Medium hit probability" | |
| else: | |
| hit_status = "Low hit probability" | |
| # Get the recommendation based on decisions | |
| if eta_status == "Low ETA": | |
| if hit_status == "High hit probability": | |
| # Critical threat - missile close, high chance of hit | |
| if combat_posture == "Friendly advantage": | |
| return "BREAK HARD + DEPLOY CM + COUNTER-ENGAGE" | |
| elif combat_posture == "Parity": | |
| return "BREAK HARD + DEPLOY CM" | |
| else: | |
| # Outmatched - survive first, disengage | |
| return "BREAK HARD + DEPLOY CM + DISENGAGE IMMEDIATELY" | |
| elif hit_status == "Medium hit probability": | |
| # Elevated threat - missile close, uncertain outcome | |
| if combat_posture == "Friendly advantage": | |
| return "DEPLOY CM + DEFENSIVE MANEUVERS + ENGAGE" | |
| elif combat_posture == "Parity": | |
| return "DEPLOY CM + DEFENSIVE MANEUVERS" | |
| else: | |
| # Disadvantaged - don't risk engagement | |
| return "DEPLOY CM + DEFENSIVE MANEUVERS + DISENGAGE" | |
| else: | |
| # Missile close but likely evadable - redirect and reassess | |
| if combat_posture == "Friendly advantage": | |
| return "DEPLOY CM + CHANGE FLIGHT PATH + ENGAGE" | |
| elif combat_posture == "Parity": | |
| return "DEPLOY CM + CHANGE FLIGHT PATH" | |
| else: | |
| return "DEPLOY CM + CHANGE FLIGHT PATH + DISENGAGE" | |
| else: | |
| if hit_status == "High hit probability": | |
| # Time available but threat is serious - prepare now | |
| if combat_posture == "Friendly advantage": | |
| return "DEFENSIVE MANEUVERS + PREPARE CM + COUNTER-ENGAGE" | |
| elif combat_posture == "Parity": | |
| return "DEFENSIVE MANEUVERS + PREPARE CM" | |
| else: | |
| # Outmatched - use the time to create distance | |
| return "DEFENSIVE MANEUVERS + PREPARE CM + MAINTAIN DISTANCE" | |
| elif hit_status == "Medium hit probability": | |
| # Uncertain threat with time to monitor - stay ready | |
| if combat_posture == "Friendly advantage": | |
| return "PREPARE CM + MONITOR + ENGAGE WHEN READY" | |
| elif combat_posture == "Parity": | |
| return "PREPARE CM + MONITOR TRAJECTORY" | |
| else: | |
| return "PREPARE CM + MAINTAIN DISTANCE" | |
| else: | |
| # Low threat - missile unlikely to hit, time available | |
| if combat_posture == "Friendly advantage": | |
| return "STAY SHARP + CLOSE AND ENGAGE" | |
| elif combat_posture == "Parity": | |
| return "STAY SHARP + MONITOR TRAJECTORY" | |
| else: | |
| # Disadvantaged even in low threat - keep distance | |
| return "STAY SHARP + MAINTAIN DISTANCE" |