Files
DronePlanningV2/# 无人机行为规划后端系统(重建版)需求说明.md
2026-03-17 10:51:32 +08:00

10 KiB
Raw Blame History

无人机行为规划后端系统(重建版)需求说明

目标:基于端侧 Qwen3-4Bllama-server和行为树重建一个从自然语言到无人机行为树 JSON 的后端系统,支持未来扩展 RAG 和动态语义地图。

一、总体架构理念(务必遵守)

  1. 大小脑解耦

    • 大模型4B小模型 = 「大脑」:只做语义理解、意图拆解、行为树结构生成,不直接管起飞/降落/避障。
    • Python + py_trees + PX4/仿真 = 「小脑」:负责状态机管理、物理安全、控制执行(起飞、悬停、返航等)。
  2. 四层流水线结构

  • 🔴 Layer 0感知层Perception & State
    纯代码。维护一个全局状态黑板 DroneStateBlackboard,至少包含:

    • is_in_air: bool
    • position: {x, y, z}ENU
    • 后续可扩展电量、模式等。
  • 🟡 Layer 1意图路由层Stage 1 Intent Router
    调用 LLM 做极简意图分类和实体抽取,只输出:

    • intents: list[str]
    • entities: dict 并实现 Fast-Path 短路机制
    • 若指令是纯原子控制(如“起飞”、“降落”、“悬停”),直接由代码执行,不进入规划阶段。
  • 🟢 Layer 2动态组装与外部计算Dynamic Composer & MCP/RAG
    纯代码。

    • 根据 intentsentities,从本地 node_schema.json 裁剪出最小必要的节点定义(行为树节点)。
    • 使用工具(后续接 RAG解析地点到坐标ENU大模型不做算术。
    • 生成发给 Stage 2 LLM 的 精简 System Prompt
  • 🔵 Layer 3宏观行为规划Stage 2 Macro Planner
    调用 LLMQwen3-4B

    • 输入Layer 2 生成的 System Prompt + 用户原文(含 RAG 上下文)。
    • 输出:业务行为树 JSON不包含起飞/降落)。
  • 🟣 Layer 4执行包装与安全逻辑Execution Wrapper
    纯代码 + py_trees

    • 将业务树解析为 py_trees 对象。
    • 如果 is_in_air == False,自动在业务树前面插入 [SystemCheck -> Takeoff] 子树
    • 提供 tick 循环和未来的中断(用户打断、动态重规划)预留。

二、节点定义(给 LLM 的行为树节点池)

请在 config/node_schema.json 定义一个简洁的行为节点池LLM 可见的动作),结构类似:

{
  "_instruction": "作为行为树规划器,你只能使用以下定义的节点和参数。",
  "actions": {
    "fly_to_waypoint": { "desc": "...", "params": { "x": "float", "y": "float", "z": "float" } },
    "fly_sequence": { "desc": "...", "params": { "waypoints": "array of {x,y,z}" } },
    "move_direction": { "desc": "...", "params": { "direction": "front|back|left|right|up|down", "distance": "float" } },
    "search_pattern": { "desc": "...", "params": { "pattern_type": "spiral|grid", "radius": "float", "target_class": "string" } },
    "rotate_search": { "desc": "...", "params": { "target_class": "string" } },
    "track_object": { "desc": "...", "params": { "target_class": "string", "track_time": "float" } },
    "take_photos": { "desc": "...", "params": { "target_class": "string", "count": "int" } },
    "report_message": { "desc": "...", "params": { "message": "string" } },
    "manual_confirmation": { "desc": "...", "params": { "prompt_message": "string" } }
  },
  "conditions": {
    "object_detected": { "desc": "...", "params": { "target_class": "string" } }
  },
  "control_flow": {
    "Sequence": { "desc": "...", "params": {}, "requires_children": true },
    "Selector": { "desc": "...", "params": {}, "requires_children": true },
    "Parallel": { "desc": "...", "params": { "policy": "success_on_one|success_on_all" }, "requires_children": true }
  },
  "decorators": {
    "Timeout": { "desc": "...", "params": { "max_time": "float" }, "requires_child": true },
    "Repeat": { "desc": "...", "params": { "times": "int" }, "requires_child": true }
  }
}

注意:起飞/降落等底层动作不要出现在这里,由 Layer 4 包装硬编码处理。


三、Stage 1 Intent Router 的设计(重点)

1. LLM 提示词Router System Prompt

要求使用简洁、正交的 Intent 集合(避免同义词过多):

  • 原子意图Atomic Intents仅用于 Fast-Path

    • atomic_takeoff
    • atomic_land
    • atomic_hover
  • 业务意图Business Intents

    • fly_task:所有涉及空间移动/路径/巡逻
    • search_task:搜索/侦查
    • track_task:跟踪
    • photo_task:拍照
    • interact_task:上报/请求确认

实体提取要求:

  • 地点实体统一用 "locations",且必须为列表:

    • {"locations": ["大门"]}
    • {"locations": ["大门", "广场"]}支持“先去A再去B”
  • 目标实体用 "targets" 列表:

    • {"targets": ["汽车", "行人"]}
  • 其他参数如 "direction", "distance" 直接提取。

2. Python 层的“硬编码冲突处理”逻辑

pipeline/router.py 中:

  • 定义集合:
ATOMIC_INTENTS = {"atomic_takeoff", "atomic_land", "atomic_hover"}
BUSINESS_INTENTS = {"fly_task", "search_task", "track_task", "photo_task", "interact_task"}
  • 处理流程:

    • intents 非空且 全部属于 ATOMIC_INTENTS
      → 允许 Fast-Path直接执行原子命令

    • intents 同时包含 atomic 和 business["atomic_takeoff", "fly_task"]
      删除所有 atomic,仅保留 business走正常规划起飞由 Layer 4 自动包装)。

    • intents 为空或包含未识别标签(小模型幻觉):
      → 兜底为 ["fly_task", "search_task"],保证系统不崩。


四、RAG 模块设计Layer 2 可选扩展)

1. 目录结构

src/drone_planning/rag/

  • embedding_client.py:封装 Qwen Embeddingllama-server 8090
  • vector_store.pyChromaDB 客户端,管理三个 Collection
    • map_db
    • rule_db
    • few_shot_db
  • retriever.pyRAGRetriever
    • dynamic_memory:热数据表占位(未来语义地图)。
    • retrieve_context(intents, entities, user_text) -> dict
  • ingestion.py:从 data/knowledge/*.jsonl 读 NDJSON 灌入 ChromaDB。
  • schemas.py(可选):约定 JSONL 字段结构。

2. JSONL 格式约定(统一用 .jsonl,一行一 JSON

  • data/knowledge/map_db.jsonl
{"document": "喷泉在广场正中央,坐标 x=10, y=20", "location": "喷泉", "x": 10, "y": 20, "z": 0}
{"document": "A区是禁飞区不得进入", "location": "A区", "zone_type": "no_fly"}
  • data/knowledge/rule_db.jsonl
{"document": "夜间巡逻必须开启热成像", "intent": "search_task", "scene": "night"}
{"document": "起飞必须先做系统检查", "intent": "fly_task", "priority": "high"}
  • data/knowledge/few_shot_db.jsonl
{"document": "飞到大门然后拍照", "intent": "fly_task", "tree_json": "{\"root\": {...}}"}

3. 检索策略(在 retriever.py

  • 热数据优先Dynamic Semantic Map

    • dynamic_memory = {"locations": {...}, "targets": {...}}
    • 若某 location 在热内存中有坐标,直接返回,不要查 ChromaDB
  • 冷库次之ChromaDB

    • 根据 entities["locations"]intents 用 metadata + 向量检索,从 map_dbrule_db 获取上下文。
    • 使用 user_textfew_shot_db 中查 12 个相似任务的行为树,作为 few-shot 示例。

RAG 返回统一结构:

{
  "map_context": "若干行文本或结构化信息",
  "rule_context": "规则文本汇总",
  "few_shot_examples": [
    {"instruction": "...", "tree_json": {...}},
    ...
  ]
}

4. 与 Composer 集成(pipeline/composer.py

  • build_system_prompt(...) 增加参数 rag_context: dict | None

  • 在 Prompt 中插入三个区块(若非空):

    • ## RAG 地图上下文
    • ## RAG 规则约束
    • ## RAG 示例行为树
  • 坐标解析优先级:

    1. 动态内存(语义地图,未来接入)。
    2. RAG 地图map_db 的 x,y,z
    3. geo.py 的硬编码 landmark_to_enu()(兜底,不删除,作为最后一层 fallback

五、执行包装层Layer 4execution

1. 行为节点实现(execution/nodes.py

实现继承自 py_trees.behaviour.Behaviour 的 Mock 节点:

  • SystemCheckCondition
  • TakeoffAction
  • LandAction
  • FlyToWaypointAction
  • GenericAction(兜底)

目前只打印日志并返回 SUCCESS,后续预留 ROS2/PX4 接口。

2. 树包装与 Tick 循环(execution/tree_wrapper.py

  • parse_json_to_tree(node_dict):递归将 Planner 的 JSON 转换为 py_trees 树。
  • wrap_and_build_tree(business_tree)
    • 读取 DroneStateBlackboard.is_in_air
      • False:创建 Sequence("Safe_Execution"),依次添加:
        • SystemCheckCondition()
        • TakeoffAction()
        • business_tree
      • True:直接返回 business_tree

六、API 接口与 Orchestrator

  • 使用 FastAPI 暴露 POST /api/plan
    • 输入:{"text": "用户自然语言指令"}
    • 调用顺序:
      1. Layer 1 Router若 Fast-Path直接返回执行结果。
      2. 否则,调用 RAG → Composer → Planner → Tree Wrapper返回行为树 JSON 和日志。

七、请 Cursor 的工作顺序建议

  1. 生成项目目录和基础依赖(requirements.txtpyproject.toml)。
  2. 实现:
    • core/blackboard.py
    • llm_client/client.py(指向 http://localhost:8080/v1 for chathttp://localhost:8090/v1 for embeddings 可在 embedding_client 中配置)
  3. 实现 config/node_schema.json
  4. 实现 pipeline/router.py(含 intents/entities 提取与 Fast-Path 短路 + 冲突处理)。
  5. 实现 tools/geo.py(仅作为 fallback 静态坐标表)。
  6. 实现 rag/*embedding_client, vector_store, ingestion, retriever
  7. 实现 pipeline/composer.pypipeline/planner.py(加入 rag_context
  8. 实现 execution/nodes.pyexecution/tree_wrapper.py
  9. 实现 api/routes.pymain.py
  10. 最后补充简单的 tests/ 或手动 curl 示例。

请从目录结构 + 模块职责开始规划,确认后再逐步生成代码。