From 65ef6ef39bee83746939dd2ef042ba81d42b87a3 Mon Sep 17 00:00:00 2001 From: abnerhexu <20591243+abnerhexu@users.noreply.github.com> Date: Tue, 27 Jan 2026 16:36:24 +0800 Subject: [PATCH] add auto_scan_all_environment --- uav_langchain_tools.py | 112 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 111 insertions(+), 1 deletion(-) diff --git a/uav_langchain_tools.py b/uav_langchain_tools.py index adc655e..3e6e71c 100644 --- a/uav_langchain_tools.py +++ b/uav_langchain_tools.py @@ -520,6 +520,8 @@ def create_uav_tools(client: UAVAPIClient) -> list: return "Error: drone_id is required" result = client.return_home(drone_id) + if result["status"] == "error": + result["info"] = "If the drone is IDLE, first take off, then return home." return json.dumps(result, indent=2) except json.JSONDecodeError as e: return f"Error parsing JSON input: {str(e)}. Expected format: {{\"drone_id\": \"drone-001\"}}" @@ -1438,6 +1440,113 @@ def create_uav_tools(client: UAVAPIClient) -> list: else: return f"Finished path. Final coverage: {current_coverage:.2%}. Wait for a while and continue calling this function! return [TASK DONE] this time" + @tool + def auto_scan_all_environment() -> str: + """ + Command all available drones to collaboratively scan the area (0,0) to (1024,1024) using obstacle avoidance. + Drones will plan safe paths to grid points, avoiding known obstacles, and detecting new ones along the way. + + No input required. + """ + global targets_expolred, obstacles_detected + import math + import json + + try: + # 1. 初始化:获取无人机并起飞 + drones = client.list_drones() + if not drones: + return "Error: No drones available for scanning." + + drone_ids = [d['id'] for d in drones] + active_drones = [] + + # 起飞高度设置为 20m,既能避开低矮障碍,也能获得较好视野 + scan_altitude = 20.0 + + for did in drone_ids: + status = client.get_drone_status(did) + if status.get('state') == 'ground' or status['position']['z'] < 1.0: + client.take_off(did, altitude=scan_altitude) + active_drones.append(did) + + # 初始感知:起飞后先看一眼,建立初步地图 + env_perception() + + # 2. 生成扫描网格 (Grid Generation) + # 区域 1024x1024。步长设为 250m,平衡覆盖率与时间成本 + scan_points = [] + area_size = 1024.0 + step_size = 250.0 + + x = step_size / 2 + while x < area_size: + y = step_size / 2 + while y < area_size: + scan_points.append((x, y)) + y += step_size + x += step_size + + # 3. 任务分配 (Round-Robin) + tasks = {did: [] for did in active_drones} + num_drones = len(active_drones) + for i, point in enumerate(scan_points): + assigned_drone = active_drones[i % num_drones] + tasks[assigned_drone].append(point) + + scan_log = [] + max_points = max([len(t) for t in tasks.values()]) if tasks else 0 + + # 4. 执行循环:规划 -> 移动 -> 感知 + for i in range(max_points): + for did in active_drones: + if i < len(tasks[did]): + tx, ty = tasks[did][i] + + # 构造导航参数 + nav_payload = json.dumps({ + "drone_id": did, + "x": tx, + "y": ty, + "z": scan_altitude + }) + + # === 核心修改:调用 auto_navigate_to_non_tool 进行路径规划 === + # 该函数会利用当前 obstacles_detected 里的数据计算避障路径 + # 如果目标点在障碍物内,它会返回错误信息,我们只需记录并跳过 + try: + # 1. 尝试导航 + nav_result_str = auto_navigate_to_non_tool(nav_payload) + nav_result = json.loads(nav_result_str) + + status = nav_result.get("status", "error") + + # 2. 无论导航成功与否(可能半路停下),都进行感知 + # 这对于"一边撞墙一边开图"的探索过程至关重要 + new_entities_found = env_perception() + + log_msg = f"Drone {did} -> ({tx:.1f}, {ty:.1f}): {status}" + if new_entities_found: + log_msg += " [New Entities Detected]" + scan_log.append(log_msg) + + except Exception as nav_err: + scan_log.append(f"Drone {did} nav error: {str(nav_err)}") + # 即使出错,也要尝试感知当前位置 + env_perception() + + # 5. 汇总结果 + return json.dumps({ + "status": "success", + "message": f"Global smart scan completed with {num_drones} drones.", + "total_targets_detected": len(targets_expolred), + "total_obstacles_detected": len(obstacles_detected), + "scan_details": scan_log + }, indent=2) + + except Exception as e: + return f"Error during smart scanning: {str(e)}" + # Return all tools return [ @@ -1469,5 +1578,6 @@ def create_uav_tools(client: UAVAPIClient) -> list: charge, get_nearest_waypoint, get_all_waypoints, - get_targets + get_targets, + auto_scan_all_environment ]