sohail-kustagi's picture
Upload folder using huggingface_hub
79723d6 verified
Raw
History Blame Contribute Delete
6.2 kB
from typing import Optional
try:
from core.types import TelemetrySnapshot, VisionEvent
from core.weather_types import WeatherSnapshot
from core.route_types import FeasibilityReport
except ImportError:
from src.core.types import TelemetrySnapshot, VisionEvent
from src.core.weather_types import WeatherSnapshot
from src.core.route_types import FeasibilityReport
try:
from core.mission_profiles import MissionProfile
except ImportError:
from src.core.mission_profiles import MissionProfile
class AnalystNode:
def __init__(self):
self.system_prompt = (
"**Role:** You are the Lead Disaster Analyst AI for an autonomous Search and Rescue (SAR) drone system. "
"You operate as the critical reasoning layer between the drone's raw computer vision pipeline and the flight Commander node.\n\n"
"**Input Data:** You will receive telemetry data and structured JSON payloads from an aerial YOLO-SAHI vision model. "
"The vision model detects four specific classes from a top-down perspective:\n"
"1. `infrastructure` (submerged or intact buildings/houses/docks)\n"
"2. `person` (survivors or rescue personnel)\n"
"3. `vehicle` (ground transport like cars/trucks)\n"
"4. `watercraft` (boats or rescue vessels)\n\n"
"**Objectives:**\n"
"1. **Analyze Spatial Context:** Interpret the relationships between detected objects. For example, a `person` bounding box overlapping an `infrastructure` bounding box indicates a stranded survivor on a roof. A `person` next to a `watercraft` indicates an active rescue.\n"
"2. **Triage & Prioritize:** Assign a threat severity level (Critical, High, Medium, Low) to the current drone visual frame based on the presence and context of stranded persons.\n"
"3. **Report:** Generate a structured, actionable intelligence brief for the Commander node to determine the next flight path or alert protocol.\n\n"
"**Constraints:**\n"
"- You must rely ONLY on the provided vision payload. Do not hallucinate objects or events that are not explicitly detected.\n"
"- You are functioning in a high-speed pipeline. Keep your reasoning concise.\n"
"- **CRITICAL:** You must output ONLY valid, parsable JSON. Do not include introductory text, conversational filler, or markdown formatting.\n"
)
print("[Analyst] Initialized Lead Disaster Analyst AI with 4-class SAR schema.")
def generate_context(
self,
vision_event_type: str,
current_telemetry: dict,
weather: Optional[dict] = None,
feasibility: Optional[dict] = None,
mission_profile: Optional[MissionProfile] = None
) -> str:
"""
Takes raw triggers from Node A, telemetry, weather, and feasibility data,
and formulates a rich structured context prompt for Node C (Commander).
"""
print(f"[Analyst] Processing anomaly: {vision_event_type}")
if isinstance(current_telemetry, dict):
alt = current_telemetry.get("alt", "Unknown")
lat = current_telemetry.get("lat", "Unknown")
lon = current_telemetry.get("lon", "Unknown")
heading = current_telemetry.get("heading", "Unknown")
else:
alt = getattr(current_telemetry, "altitude_m", "Unknown")
lat = getattr(current_telemetry, "latitude", "Unknown")
lon = getattr(current_telemetry, "longitude", "Unknown")
heading = getattr(current_telemetry, "heading_deg", "Unknown")
context_prompt = f"{self.system_prompt}\n\n"
if mission_profile:
context_prompt += f"MISSION CONTEXT: {mission_profile.analyst_persona}\n\n"
context_prompt += (
f"ALERT: The edge vision system has detected high-confidence anomalies involving '{vision_event_type}'.\n"
f"Current Drone Telemetry:\n"
f"- Latitude: {lat}\n"
f"- Longitude: {lon}\n"
f"- Altitude: {alt}m\n"
f"- Heading: {heading} degrees\n"
)
if weather:
context_prompt += (
f"\nCurrent Weather:\n"
f"- Wind: {weather.get('wind_speed', 'Unknown')} m/s\n"
f"- Visibility: {weather.get('visibility', 'Unknown')} m\n"
f"- Risk Level: Lightning={weather.get('lightning', 'Unknown')}\n"
)
if feasibility:
context_prompt += (
f"\nRoute Feasibility Check:\n"
f"- Is Feasible: {feasibility.get('is_feasible')}\n"
f"- Risk Level: {feasibility.get('risk_level')}\n"
)
context_prompt += (
f"\nBased strictly on the telemetry and vision detection of '{vision_event_type}', generate the MAVLink routing "
f"command in ONLY valid JSON."
)
return context_prompt
def generate_event_context(
self,
event: VisionEvent,
telemetry: TelemetrySnapshot,
weather: Optional[WeatherSnapshot] = None,
feasibility: Optional[FeasibilityReport] = None,
mission_profile: Optional[MissionProfile] = None
) -> str:
weather_dict = None
if weather:
weather_dict = {
"wind_speed": weather.wind_speed_mps,
"visibility": weather.visibility_m,
"lightning": weather.lightning_risk
}
feasibility_dict = None
if feasibility:
feasibility_dict = {
"is_feasible": feasibility.is_feasible,
"risk_level": feasibility.risk_level
}
return self.generate_context(
event.anomaly_type,
{
"alt": telemetry.altitude_m,
"lat": telemetry.latitude,
"lon": telemetry.longitude,
"heading": telemetry.heading_deg,
},
weather_dict,
feasibility_dict,
mission_profile
)