add auto_scan_all_environment
This commit is contained in:
@@ -520,6 +520,8 @@ def create_uav_tools(client: UAVAPIClient) -> list:
|
|||||||
return "Error: drone_id is required"
|
return "Error: drone_id is required"
|
||||||
|
|
||||||
result = client.return_home(drone_id)
|
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)
|
return json.dumps(result, indent=2)
|
||||||
except json.JSONDecodeError as e:
|
except json.JSONDecodeError as e:
|
||||||
return f"Error parsing JSON input: {str(e)}. Expected format: {{\"drone_id\": \"drone-001\"}}"
|
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:
|
else:
|
||||||
return f"Finished path. Final coverage: {current_coverage:.2%}. Wait for a while and continue calling this function! return [TASK DONE] this time"
|
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 all tools
|
||||||
return [
|
return [
|
||||||
@@ -1469,5 +1578,6 @@ def create_uav_tools(client: UAVAPIClient) -> list:
|
|||||||
charge,
|
charge,
|
||||||
get_nearest_waypoint,
|
get_nearest_waypoint,
|
||||||
get_all_waypoints,
|
get_all_waypoints,
|
||||||
get_targets
|
get_targets,
|
||||||
|
auto_scan_all_environment
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user