add auto_scan_all_environment

This commit is contained in:
abnerhexu
2026-01-27 16:36:24 +08:00
parent e32c782909
commit 65ef6ef39b

View File

@@ -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
]