Compare commits
10 Commits
9cb4537528
...
24d7737399
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
24d7737399 | ||
|
|
5c667941be | ||
|
|
65ef6ef39b | ||
|
|
e32c782909 | ||
|
|
6c29be2fcb | ||
|
|
37933eb22b | ||
|
|
ab8bb2e220 | ||
|
|
aab416c588 | ||
|
|
10333df568 | ||
|
|
e23371182e |
9
failures.md
Normal file
9
failures.md
Normal file
@@ -0,0 +1,9 @@
|
||||
target assignment large scale 1
|
||||
|
||||
- Drones Drone 3 and Drone 19 form a line formation: both take off to 15 meters. Drone 3 positions at (248, 494, 15) and Drone 19 positions 19 meters behind at (248, 162, 15). Both maintain formation for monitoring. 任务描述有问题,自相矛盾
|
||||
|
||||
- Drones Drone 15 and Drone 14 form a line formation: both take off to 16 meters. Drone 15 positions at (522, 538, 16) and Drone 14 positions 24 meters behind at (522, 19, 16). Both maintain formation for monitoring. 任务描述有问题,自相矛盾
|
||||
|
||||
- Five-drone coordination exercise: Drone 7, Drone 10, Drone 2, Drone 8, and Drone 20 take off together to 24 meters altitude, then hold formation at positions (435, 516, 24), (557, 331, 24), (790, 445, 24), (663, 685, 24), and (398, 666, 24) respectively for synchronized operation. Then all five drones move north for 89m, and next move east for 92m. Each drone must complete the specified directional movements (north 89m, then east 92m) regardless of starting position - if obstacles block the path, drones should adjust position as needed to complete the full directed distance in each heading. 不清楚drone_has_moved_directed_distance的计算准则,似乎不是叠加的。
|
||||
|
||||
- Four-drone target sweep: Drone 14, Drone 7, Drone 18, and Drone 6 take off together to 20 meters altitude. Drone 14 flies to target Fixed Target 8, Drone 7 flies to target Fixed Target 21, Drone 18 flies to target Fixed Target 25, and Drone 6 flies to target Fixed Target 4. After reaching the targets, all four drones move west for 80m, then south for 72m, then north for 56m together. Each drone must complete the specified directional movements (west 80m, south 72m, north 56m) regardless of starting position - if obstacles block the path, drones should adjust position as needed to complete the full directed distance in each heading. 不清楚drone_has_moved_directed_distance的计算准则,似乎不是叠加的。
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"selected_provider": "Kimi",
|
||||
"selected_provider": "OpenAI",
|
||||
"provider_configs": {
|
||||
"Ollama": {
|
||||
"type": "ollama",
|
||||
@@ -17,22 +17,21 @@
|
||||
},
|
||||
"OpenAI": {
|
||||
"type": "openai-compatible",
|
||||
"base_url": "https://api.openai.com/v1",
|
||||
"base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
||||
"models_endpoint": "/models",
|
||||
"chat_endpoint": "/chat/completions",
|
||||
"requires_api_key": true,
|
||||
"api_key": "",
|
||||
"api_key": "sk-2f228b8c30964dba84e888b565add0a8",
|
||||
"encoding": "utf-8",
|
||||
"default_model": "gpt-4o-mini",
|
||||
"default_model": "deepseek-v3.2",
|
||||
"default_models": [
|
||||
"gpt-4o-mini",
|
||||
"gpt-4o",
|
||||
"gpt-4.1-mini",
|
||||
"gpt-3.5-turbo"
|
||||
"deepseek-v3.2",
|
||||
"qwen-flash",
|
||||
"qwen3-30b-a3b-instruct-2507"
|
||||
],
|
||||
"allow_endpoint_edit": true,
|
||||
"allow_api_toggle": true,
|
||||
"system_prompt": ""
|
||||
"system_prompt": "You are a very friendly drone control agent. No matter what language I use to give you instructions, please call the tools to perform the task and then reply in Chinese."
|
||||
},
|
||||
"Kimi": {
|
||||
"type": "openai-compatible",
|
||||
@@ -42,9 +41,9 @@
|
||||
"requires_api_key": true,
|
||||
"api_key": "sk-2gCgINOEErD1ctdxIB7ALIPnHboZPrQRj1hvVJtEydT1JbXv",
|
||||
"encoding": "utf-8",
|
||||
"default_model": "kimi-k2-0711-preview",
|
||||
"default_model": "kimi-k2-0905-preview",
|
||||
"default_models": [
|
||||
"kimi-k2-0711-preview"
|
||||
"kimi-k2-0905-preview"
|
||||
],
|
||||
"allow_endpoint_edit": true,
|
||||
"allow_api_toggle": true,
|
||||
|
||||
294
paper.md
294
paper.md
@@ -1,260 +1,552 @@
|
||||
补全auto_navigate_move_towards函数,函数的输入包含drone_id,方向和在该方向上的预期移动距离。在遇到障碍物时,需要越过障碍物,并继续移动。最终到达的位置和初始位置相比,在指定的方向上移动的距离应当不小于预期移动距离。
|
||||
|
||||
@tool
|
||||
def auto_navigate_move_towards(input_json: str) -> str:
|
||||
try:
|
||||
params = json.loads(input_json) if isinstance(input_json, str) else input_json
|
||||
pass
|
||||
|
||||
现在先补全函数,可以调用`get_obstacles`函数获取障碍物信息。该函数返回一个列表。obstacles的种类有4类,是point、circle、polygon、ellipse。这个列表形如:
|
||||
|
||||
[
|
||||
|
||||
{
|
||||
|
||||
"id": "bb07b327",
|
||||
|
||||
"name": "Point Obstacle 1",
|
||||
|
||||
"type": "point",
|
||||
|
||||
"position": {
|
||||
|
||||
"x": 609.0,
|
||||
|
||||
"y": 459.0,
|
||||
|
||||
"z": 0.0
|
||||
|
||||
},
|
||||
|
||||
"description": "",
|
||||
|
||||
"radius": 30.0,
|
||||
|
||||
"vertices": [],
|
||||
|
||||
"width": null,
|
||||
|
||||
"length": null,
|
||||
|
||||
"height": 0.0,
|
||||
|
||||
"area": 2827.4333882308138,
|
||||
|
||||
"created_at": 1766327750.018749,
|
||||
|
||||
"last_updated": 1766327750.018749
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
"id": "fd0760b8",
|
||||
|
||||
"name": "Point Obstacle 2",
|
||||
|
||||
"type": "point",
|
||||
|
||||
"position": {
|
||||
|
||||
"x": 896.0,
|
||||
|
||||
"y": 241.0,
|
||||
|
||||
"z": 0.0
|
||||
|
||||
},
|
||||
|
||||
"description": "",
|
||||
|
||||
"radius": 6.0,
|
||||
|
||||
"vertices": [],
|
||||
|
||||
"width": null,
|
||||
|
||||
"length": null,
|
||||
|
||||
"height": 0.0,
|
||||
|
||||
"area": 113.09733552923255,
|
||||
|
||||
"created_at": 1766327750.0221481,
|
||||
|
||||
"last_updated": 1766327750.0221481
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
"id": "1d817ce2",
|
||||
|
||||
"name": "Point Obstacle 3",
|
||||
|
||||
"type": "point",
|
||||
|
||||
"position": {
|
||||
|
||||
"x": 809.0,
|
||||
|
||||
"y": 14.0,
|
||||
|
||||
"z": 0.0
|
||||
|
||||
},
|
||||
|
||||
"description": "",
|
||||
|
||||
"radius": 8.0,
|
||||
|
||||
"vertices": [],
|
||||
|
||||
"width": null,
|
||||
|
||||
"length": null,
|
||||
|
||||
"height": 0.0,
|
||||
|
||||
"area": 201.06192982974676,
|
||||
|
||||
"created_at": 1766327750.025595,
|
||||
|
||||
"last_updated": 1766327750.025595
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
"id": "2b38acd5",
|
||||
|
||||
"name": "Circle Obstacle 1",
|
||||
|
||||
"type": "circle",
|
||||
|
||||
"position": {
|
||||
|
||||
"x": 438.0,
|
||||
|
||||
"y": 465.0,
|
||||
|
||||
"z": 0.0
|
||||
|
||||
},
|
||||
|
||||
"description": "",
|
||||
|
||||
"radius": 40.0,
|
||||
|
||||
"vertices": [],
|
||||
|
||||
"width": null,
|
||||
|
||||
"length": null,
|
||||
|
||||
"height": 0.0,
|
||||
|
||||
"area": 5026.548245743669,
|
||||
|
||||
"created_at": 1766327750.019903,
|
||||
|
||||
"last_updated": 1766327750.019903
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
"id": "fa67aa30",
|
||||
|
||||
"name": "Circle Obstacle 2",
|
||||
|
||||
"type": "circle",
|
||||
|
||||
"position": {
|
||||
|
||||
"x": 431.0,
|
||||
|
||||
"y": 605.0,
|
||||
|
||||
"z": 0.0
|
||||
|
||||
},
|
||||
|
||||
"description": "",
|
||||
|
||||
"radius": 55.0,
|
||||
|
||||
"vertices": [],
|
||||
|
||||
"width": null,
|
||||
|
||||
"length": null,
|
||||
|
||||
"height": 0.0,
|
||||
|
||||
"area": 9503.317777109125,
|
||||
|
||||
"created_at": 1766327750.0267,
|
||||
|
||||
"last_updated": 1766327750.0267
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
"id": "845b6b36",
|
||||
|
||||
"name": "Polygon Obstacle 1",
|
||||
|
||||
"type": "polygon",
|
||||
|
||||
"position": {
|
||||
|
||||
"x": 686.0,
|
||||
|
||||
"y": 669.0,
|
||||
|
||||
"z": 0.0
|
||||
|
||||
},
|
||||
|
||||
"description": "",
|
||||
|
||||
"radius": null,
|
||||
|
||||
"vertices": [
|
||||
|
||||
{
|
||||
|
||||
"x": 611.0,
|
||||
|
||||
"y": 594.0
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
"x": 761.0,
|
||||
|
||||
"y": 594.0
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
"x": 761.0,
|
||||
|
||||
"y": 744.0
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
"x": 611.0,
|
||||
|
||||
"y": 744.0
|
||||
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
"width": null,
|
||||
|
||||
"length": null,
|
||||
|
||||
"height": 0.0,
|
||||
|
||||
"area": 22500.0,
|
||||
|
||||
"created_at": 1766327750.021056,
|
||||
|
||||
"last_updated": 1766327750.021056
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
"id": "8603630e",
|
||||
|
||||
"name": "Polygon Obstacle 2",
|
||||
|
||||
"type": "polygon",
|
||||
|
||||
"position": {
|
||||
|
||||
"x": 312.0,
|
||||
|
||||
"y": 232.0,
|
||||
|
||||
"z": 0.0
|
||||
|
||||
},
|
||||
|
||||
"description": "",
|
||||
|
||||
"radius": null,
|
||||
|
||||
"vertices": [
|
||||
|
||||
{
|
||||
|
||||
"x": 247.0,
|
||||
|
||||
"y": 167.0
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
"x": 377.0,
|
||||
|
||||
"y": 167.0
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
"x": 377.0,
|
||||
|
||||
"y": 297.0
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
"x": 247.0,
|
||||
|
||||
"y": 297.0
|
||||
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
"width": null,
|
||||
|
||||
"length": null,
|
||||
|
||||
"height": 0.0,
|
||||
|
||||
"area": 16900.0,
|
||||
|
||||
"created_at": 1766327750.023377,
|
||||
|
||||
"last_updated": 1766327750.023377
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
"id": "b32c509b",
|
||||
|
||||
"name": "Polygon Obstacle 3",
|
||||
|
||||
"type": "polygon",
|
||||
|
||||
"position": {
|
||||
|
||||
"x": 691.0,
|
||||
|
||||
"y": 344.0,
|
||||
|
||||
"z": 0.0
|
||||
|
||||
},
|
||||
|
||||
"description": "",
|
||||
|
||||
"radius": null,
|
||||
|
||||
"vertices": [
|
||||
|
||||
{
|
||||
|
||||
"x": 625.0,
|
||||
|
||||
"y": 278.0
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
"x": 757.0,
|
||||
|
||||
"y": 278.0
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
"x": 757.0,
|
||||
|
||||
"y": 410.0
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
"x": 625.0,
|
||||
|
||||
"y": 410.0
|
||||
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
"width": null,
|
||||
|
||||
"length": null,
|
||||
|
||||
"height": 0.0,
|
||||
|
||||
"area": 17424.0,
|
||||
|
||||
"created_at": 1766327750.027871,
|
||||
|
||||
"last_updated": 1766327750.027871
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
"id": "b6a5ec7c",
|
||||
|
||||
"name": "Polygon Obstacle 4",
|
||||
|
||||
"type": "polygon",
|
||||
|
||||
"position": {
|
||||
|
||||
"x": 237.0,
|
||||
|
||||
"y": 555.0,
|
||||
|
||||
"z": 0.0
|
||||
|
||||
},
|
||||
|
||||
"description": "",
|
||||
|
||||
"radius": null,
|
||||
|
||||
"vertices": [
|
||||
|
||||
{
|
||||
|
||||
"x": 181.0,
|
||||
|
||||
"y": 499.0
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
"x": 293.0,
|
||||
|
||||
"y": 499.0
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
"x": 293.0,
|
||||
|
||||
"y": 611.0
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
"x": 181.0,
|
||||
|
||||
"y": 611.0
|
||||
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
"width": null,
|
||||
|
||||
"length": null,
|
||||
|
||||
"height": 0.0,
|
||||
|
||||
"area": 12544.0,
|
||||
|
||||
"created_at": 1766327750.0289862,
|
||||
|
||||
"last_updated": 1766327750.0289862
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
|
||||
"id": "9bf135c3",
|
||||
|
||||
"name": "Ellipse Obstacle 1",
|
||||
|
||||
"type": "ellipse",
|
||||
|
||||
"position": {
|
||||
|
||||
"x": 475.0,
|
||||
|
||||
"y": 156.0,
|
||||
|
||||
"z": 0.0
|
||||
|
||||
},
|
||||
|
||||
"description": "",
|
||||
|
||||
"radius": null,
|
||||
|
||||
"vertices": [],
|
||||
|
||||
"width": 46.0,
|
||||
|
||||
"length": 34.0,
|
||||
|
||||
"height": 0.0,
|
||||
|
||||
"area": 4913.450910214437,
|
||||
|
||||
"created_at": 1766327750.0245,
|
||||
|
||||
"last_updated": 1766327750.0245
|
||||
|
||||
}
|
||||
]
|
||||
|
||||
]
|
||||
|
||||
对于高度不为0的obstacles,如果无人机的最大可达高度大于obstacle的高度,就能够飞跃。对于不能飞跃的和高度为0的obstacles,需要绕路。
|
||||
|
||||
该函数只需为无人机确定一个要到达的目标坐标点。该坐标点需要与障碍物保持一定的距离。确定好目标坐标点后,调用auto_navigate_to函数
|
||||
|
||||
```
|
||||
def auto_navigate_to(input_json: str) -> str:
|
||||
"""
|
||||
Plan an obstacle-avoiding path using analytic geometry for precise collision detection.
|
||||
|
||||
Input should be a JSON string with:
|
||||
- drone_id: The ID of the drone (required)
|
||||
- x: Target X coordinate in meters (required)
|
||||
- y: Target Y coordinate in meters (required)
|
||||
- z: Target Z coordinate (altitude) in meters (required)
|
||||
|
||||
Example: {{"drone_id": "drone-001", "x": 100.0, "y": 50.0, "z": 20.0}}
|
||||
"""
|
||||
```
|
||||
|
||||
即可将无人机从当前位置导航到目标位置,并避开所有障碍物。
|
||||
|
||||
现在请补全auto_navigate_move_towards函数。
|
||||
@@ -87,8 +87,14 @@ Tips for you to finish task in the most efficient way:
|
||||
6. Reaching to a higher latitude can help you see targets, but do not exceed the drone's limit.
|
||||
7. Cannot move from current status: DroneStatus.IDLE means you need to take off first then move.
|
||||
8. If the start point is different with the current position of the drone, first go to the start point, then continue the left paths.
|
||||
|
||||
9. Moving X meters in a given direction means reaching a location that is at a distance of X meters from the current point along that direction. The distance must not be reduced due to detouring, nor should the detour proceed in the opposite direction. Obstacle avoidance do not mean you can reduce the distance. Only increase the distance is allowed.
|
||||
10. Line formation means after finishing the task the two (or more) drones should move to a same position.
|
||||
Begin!
|
||||
11. Before executing a task or moving to a new position, must get the nearby entities first.
|
||||
12. The max moving distance for a single move_to or navigate_to command is 500 meters. If the distance is longer than that, find a mediam point to go first.
|
||||
13. When targets cannot be found, call `auto_scan_all_environment` as early as possible.
|
||||
14. When `auto_scan_all_environment` is not completed, control multiple active drones move to unvisited scan points , use `get_scan_points` to get the list of scan points categorized by visited status and current drone positions.
|
||||
15. Executing tasks implicitly performs environment perception, so avoid using the `get_nearby_entities` API as much as possible.
|
||||
|
||||
Question: {input}
|
||||
Thought:{agent_scratchpad}"""
|
||||
|
||||
@@ -15,6 +15,6 @@ REMINDER - Action Input must be valid JSON:
|
||||
- For multiple parameters: {{"drone_id": "drone-001", "altitude": 15.0}}
|
||||
- Numbers WITHOUT quotes, strings WITH quotes
|
||||
- We put your answer to langchain, so if you want to return {{ or }}, return double of the characters.
|
||||
- When the task is done, simply output "Final Answer:\n[TASK DONE]"
|
||||
- When the task is done, IMMEDIATELY output ONLY "Final Answer:\n[TASK DONE]" and nothing else after that.
|
||||
|
||||
Please try again with proper JSON format."""
|
||||
|
||||
89
uav_agent.py
89
uav_agent.py
@@ -20,26 +20,56 @@ import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
# from langchain.agents import create_tool_calling_agent
|
||||
# from langchain.agents import create_react_agent as create_react_agent_anthropic
|
||||
# from langchain.agents import AgentExecutor as AgentExecutorAnthropic
|
||||
|
||||
class EnhancedChatOpenAI(ChatOpenAI):
|
||||
"""ChatOpenAI subclass that captures reasoning_content if provided by the API"""
|
||||
class EnhancedChatAnthropic(ChatAnthropic):
|
||||
"""
|
||||
针对 Anthropic 的增强类:
|
||||
1. 提取 'thinking' 块并将其转换为 ReAct 格式的 'Thought: ...'
|
||||
2. 防止因为只有工具调用而导致的 content 为空
|
||||
"""
|
||||
|
||||
def _create_chat_result(self, response: Any) -> ChatResult:
|
||||
result = super()._create_chat_result(response)
|
||||
def generate(self, response: Any) -> ChatResult:
|
||||
result = super().generate(response)
|
||||
|
||||
if hasattr(response, "choices") and response.choices:
|
||||
for i, choice in enumerate(response.choices):
|
||||
# Handle MiniMax reasoning_details
|
||||
if hasattr(choice.message, "reasoning_details") and choice.message.reasoning_details:
|
||||
reasoning = choice.message.reasoning_details[0].get('text', '')
|
||||
if reasoning and i < len(result.generations):
|
||||
gen = result.generations[i]
|
||||
if isinstance(gen.message, AIMessage):
|
||||
# Store in additional_kwargs
|
||||
gen.message.additional_kwargs["reasoning_content"] = reasoning
|
||||
# Prepend to content for ReAct agent visibility
|
||||
if "Thought:" not in gen.message.content:
|
||||
gen.message.content = f"Thought: {reasoning}\n" + gen.message.content
|
||||
for generation in result.generations:
|
||||
message = generation.message
|
||||
raw_content = message.content
|
||||
|
||||
# --- 逻辑 A: 处理思维链 (Thinking Blocks) ---
|
||||
# 如果 content 是列表 (Anthropic 标准格式),提取 thinking
|
||||
if isinstance(raw_content, list):
|
||||
text_parts = []
|
||||
thought_parts = []
|
||||
|
||||
for block in raw_content:
|
||||
if isinstance(block, dict):
|
||||
if block.get("type") == "thinking":
|
||||
# 获取思考内容
|
||||
thinking = block.get("thinking", "")
|
||||
# 存入 additional_kwargs (保持与其他代码一致)
|
||||
message.additional_kwargs["reasoning_content"] = thinking
|
||||
thought_parts.append(f"Thought: {thinking}\n")
|
||||
elif block.get("type") == "text":
|
||||
text_parts.append(block.get("text", ""))
|
||||
|
||||
# 重组 Content,把思考放在最前面,欺骗 ReAct 解析器
|
||||
final_text = "".join(text_parts)
|
||||
if thought_parts and "Thought:" not in final_text:
|
||||
message.content = "".join(thought_parts) + final_text
|
||||
else:
|
||||
message.content = final_text
|
||||
|
||||
# --- 逻辑 B: 处理纯工具调用导致的空字符串 ---
|
||||
# 如果 content 为空,但有工具调用,我们手动补一个 Thought
|
||||
# 这样 ReAct 解析器就不会报错说 "No action found"
|
||||
if not message.content and message.tool_calls:
|
||||
tool_name = message.tool_calls[0]['name']
|
||||
# 伪造一个 Thought,让 Log 好看,也让解析器通过
|
||||
message.content = f"Thought: I should use the {tool_name} tool to proceed.\n"
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@@ -284,12 +314,12 @@ class UAVControlAgent:
|
||||
# Create LLM instance
|
||||
if llm_provider == "anthropic-compatible":
|
||||
kwargs = {
|
||||
"model_name": llm_model,
|
||||
"model": llm_model,
|
||||
"temperature": temperature,
|
||||
"api_key": llm_api_key,
|
||||
"base_url": final_base_url
|
||||
}
|
||||
self.llm = ChatAnthropic(**kwargs)
|
||||
self.llm = EnhancedChatAnthropic(**kwargs)
|
||||
else:
|
||||
kwargs = {
|
||||
"model": llm_model,
|
||||
@@ -328,11 +358,22 @@ class UAVControlAgent:
|
||||
# Create ReAct agent
|
||||
if self.debug:
|
||||
print("🤖 Creating ReAct agent...")
|
||||
self.agent = create_react_agent(
|
||||
llm=self.llm,
|
||||
tools=self.tools,
|
||||
prompt=self.prompt
|
||||
)
|
||||
if llm_provider in ["anthropic", "anthropic-compatible"]:
|
||||
if self.debug:
|
||||
print("🤖 Using Tool Calling Agent (Better for Claude)")
|
||||
self.agent = create_react_agent(
|
||||
llm=self.llm,
|
||||
tools=self.tools,
|
||||
prompt=self.prompt
|
||||
)
|
||||
else:
|
||||
if self.debug:
|
||||
print("🤖 Using React Agent (GPT-3 and older)")
|
||||
self.agent = create_react_agent(
|
||||
llm=self.llm,
|
||||
tools=self.tools,
|
||||
prompt=self.prompt
|
||||
)
|
||||
|
||||
if self.debug:
|
||||
print("✅ ReAct agent created")
|
||||
|
||||
@@ -311,14 +311,14 @@ class UAVAPIClient:
|
||||
"""Get current weather conditions"""
|
||||
return self._request('GET', '/environments/current')
|
||||
|
||||
def get_targets(self) -> List[Dict[str, Any]]:
|
||||
"""Get all targets in the session"""
|
||||
fixed = self._request('GET', '/targets/type/fixed')
|
||||
moving = self._request('GET', '/targets/type/moving')
|
||||
waypoint = self._request('GET', '/targets/type/waypoint')
|
||||
circle = self._request('GET', '/targets/type/circle')
|
||||
polygen = self._request('GET', '/targets/type/polygon')
|
||||
return fixed + moving + waypoint + circle + polygen
|
||||
# def get_targets(self) -> List[Dict[str, Any]]:
|
||||
# """Get all targets in the session"""
|
||||
# fixed = self._request('GET', '/targets/type/fixed')
|
||||
# moving = self._request('GET', '/targets/type/moving')
|
||||
# waypoint = self._request('GET', '/targets/type/waypoint')
|
||||
# circle = self._request('GET', '/targets/type/circle')
|
||||
# polygen = self._request('GET', '/targets/type/polygon')
|
||||
# return fixed + moving + waypoint + circle + polygen
|
||||
|
||||
def get_target_status(self, target_id: str) -> Dict[str, Any]:
|
||||
"""Get information about a specific target"""
|
||||
@@ -333,13 +333,13 @@ class UAVAPIClient:
|
||||
return self._request('GET', '/targets/waypoints/nearest',
|
||||
json={'x': x, 'y': y, 'z': z})
|
||||
|
||||
def get_obstacles(self) -> List[Dict[str, Any]]:
|
||||
"""Get all obstacles in the session"""
|
||||
point = self._request('GET', '/obstacles/type/point')
|
||||
circle = self._request('GET', '/obstacles/type/circle')
|
||||
polygon = self._request('GET', '/obstacles/type/polygon')
|
||||
ellipse = self._request('GET', '/obstacles/type/ellipse')
|
||||
return point + circle + polygon + ellipse
|
||||
# def get_obstacles(self) -> List[Dict[str, Any]]:
|
||||
# """Get all obstacles in the session"""
|
||||
# point = self._request('GET', '/obstacles/type/point')
|
||||
# circle = self._request('GET', '/obstacles/type/circle')
|
||||
# polygon = self._request('GET', '/obstacles/type/polygon')
|
||||
# ellipse = self._request('GET', '/obstacles/type/ellipse')
|
||||
# return point + circle + polygon + ellipse
|
||||
|
||||
def get_nearby_entities(self, drone_id: str) -> Dict[str, Any]:
|
||||
"""Get entities near a drone (within perceived radius)"""
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user