Download backend/drone_vra.py from bapi143/CropAI: direct link, hf CLI and curl.
- Browser
- Download file 5.01 kB
-
https://huggingface.co/spaces/bapi143/CropAI/resolve/main/backend/drone_vra.py
- Command line
-
hf download hf://spaces/bapi143/CropAI/backend/drone_vra.py
-
curl -L -o drone_vra.py https://huggingface.co/spaces/bapi143/CropAI/resolve/main/backend/drone_vra.py
5.01 kB
| """ | |
| CropAI Drone Autonomous Spot-Spraying & Variable Rate Application (VRA) Protocol | |
| Generates waypoint flight plans (GeoJSON / KML / QGroundControl format) for Kisan Drones, | |
| enabling micro-droplet spot-spraying that reduces pesticide consumption by 85-90%. | |
| """ | |
| import json | |
| from typing import Dict, Any, List, Tuple | |
| class DroneVRAEngine: | |
| """Variable Rate Application (VRA) Waypoint & Spray Flight Mission Generator.""" | |
| def generate_vra_flight_plan( | |
| field_id: str, | |
| center_lat: float, | |
| center_lng: float, | |
| field_area_acres: float, | |
| infected_clusters: List[Dict[str, Any]], | |
| spray_altitude_meters: float = 2.5, | |
| flight_speed_ms: float = 3.0, | |
| swath_width_meters: float = 4.0 | |
| ) -> Dict[str, Any]: | |
| """ | |
| Generates autonomous flight grid waypoints with variable spray flow rates (liters/min) | |
| matching the specific location of diagnosed disease clusters. | |
| """ | |
| # Grid bounds based on acreage (approximate 63.6m per square acre) | |
| half_side = (field_area_acres ** 0.5) * 31.8 / 111139.0 # degrees approx | |
| grid_lines = 5 | |
| waypoints = [] | |
| waypoint_id = 1 | |
| total_spray_liquid_liters = 0.0 | |
| # Generate lawnmower flight grid | |
| for i in range(grid_lines): | |
| lat = center_lat - half_side + (2 * half_side * i / (grid_lines - 1)) | |
| # Alternate direction for efficient battery usage | |
| lng_start = center_lng - half_side if i % 2 == 0 else center_lng + half_side | |
| lng_end = center_lng + half_side if i % 2 == 0 else center_lng - half_side | |
| # Intermediate spray nodes | |
| for step in range(4): | |
| step_lng = lng_start + (lng_end - lng_start) * (step / 3.0) | |
| # Check proximity to any infected cluster | |
| is_hotspot = False | |
| for cluster in infected_clusters: | |
| c_lat = cluster.get("lat", center_lat) | |
| c_lng = cluster.get("lng", center_lng) | |
| dist = ((lat - c_lat) ** 2 + (step_lng - c_lng) ** 2) ** 0.5 | |
| if dist < 0.0003: # approx within 30 meters | |
| is_hotspot = True | |
| break | |
| # Variable Rate Application (VRA) flow rate | |
| if is_hotspot: | |
| flow_rate_lpm = 1.8 # 100% targeted micro-droplet spot spray | |
| spray_mode = "TARGETED_CURATIVE_SPOT_SPRAY" | |
| total_spray_liquid_liters += 0.45 | |
| else: | |
| flow_rate_lpm = 0.0 # 0% chemical on healthy canopy | |
| spray_mode = "ZERO_SPRAY_CANOPY_BYPASS" | |
| waypoints.append({ | |
| "waypoint_index": waypoint_id, | |
| "latitude": round(lat, 6), | |
| "longitude": round(step_lng, 6), | |
| "altitude_agl_m": spray_altitude_meters, | |
| "speed_ms": flight_speed_ms, | |
| "pump_flow_rate_lpm": flow_rate_lpm, | |
| "spray_action": spray_mode | |
| }) | |
| waypoint_id += 1 | |
| # Calculate chemical and water savings vs blanket spray | |
| blanket_spray_liters = field_area_acres * 15.0 # standard 15L/acre drone blanket | |
| savings_percentage = max(0.0, round((1.0 - (total_spray_liquid_liters / max(1.0, blanket_spray_liters))) * 100.0, 1)) | |
| # Generate standard GeoJSON FeatureCollection | |
| geojson_features = [ | |
| { | |
| "type": "Feature", | |
| "geometry": { | |
| "type": "Point", | |
| "coordinates": [wp["longitude"], wp["latitude"], wp["altitude_agl_m"]] | |
| }, | |
| "properties": { | |
| "index": wp["waypoint_index"], | |
| "flow_rate_lpm": wp["pump_flow_rate_lpm"], | |
| "action": wp["spray_action"] | |
| } | |
| } | |
| for wp in waypoints | |
| ] | |
| flight_mission_geojson = { | |
| "type": "FeatureCollection", | |
| "mission_id": f"MISSION-{field_id.upper()}", | |
| "features": geojson_features | |
| } | |
| return { | |
| "mission_id": f"DRONE-VRA-{field_id.upper()}", | |
| "field_area_acres": field_area_acres, | |
| "flight_altitude_meters": spray_altitude_meters, | |
| "swath_width_meters": swath_width_meters, | |
| "total_waypoints": len(waypoints), | |
| "estimated_flight_duration_minutes": round((len(waypoints) * 8) / 60.0, 1), | |
| "vra_spot_spray_liters": round(total_spray_liquid_liters, 2), | |
| "traditional_blanket_spray_liters": round(blanket_spray_liters, 1), | |
| "chemical_savings_percentage": f"{savings_percentage}%", | |
| "waypoints": waypoints, | |
| "geojson_flight_plan": flight_mission_geojson, | |
| "qgroundcontrol_format_compatible": True | |
| } | |
| drone_vra_engine = DroneVRAEngine() | |