Files
2026-01-16 16:05:52 +08:00

50 lines
17 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"root": {
"type": "Sequence",
"name": "EmergencyReturnAndLand",
"children": [
{
"type": "action",
"name": "return_emergency",
"params": {
"reason": "紧急返回广场"
}
},
{
"type": "action",
"name": "fly_to_waypoint",
"params": {
"x": -17.0,
"y": 360.0,
"z": 3.0
}
},
{
"type": "action",
"name": "object_detect",
"params": {
"target_class": "traffic_light",
"description": "红绿灯"
}
},
{
"type": "condition",
"name": "object_detected",
"params": {
"target_class": "traffic_light",
"description": "红绿灯"
}
},
{
"type": "action",
"name": "land",
"params": {
"mode": "home"
}
}
]
},
"plan_id": "d705e42d-e3f8-43b2-b1a8-117479af06fe",
"visualization_url": "/static/py_tree.png",
"final_prompt": "=== System Prompt ===\n任务根据用户任意任务指令生成结构化可执行的无人机行为树PytreeJSON。**仅输出单一JSON对象无任何自然语言、注释或额外内容**。\n\n## 一、核心节点定义(格式不可修改,确保后端解析)\n#### 1. 可用节点定义 (必须遵守)\n你必须严格从以下JSON定义的列表中选择节点构建行为树不允许使用未定义节点\n```json\n{\n \"actions\": [\n {\"name\":\"takeoff\",\"params\":{\"altitude\":\"float[1,100]默认2\"}},\n {\"name\":\"land\",\"params\":{\"mode\":\"'current'/'home'\"}},\n {\"name\":\"fly_to_waypoint\",\"params\":{\"x\":\"±10000\",\"y\":\"±10000\",\"z\":\"[1,5000]\",\"acceptance_radius\":\"默认2.0\"}},\n {\"name\":\"fly_sequence\",\"params\":{\"waypoints\":\"list[dict] (e.g. [{'x':10,'y':20,'z':5}, ...])\",\"coordinate_frame\":\"'global'/'local_enu'global:经纬度, local_enu:以起飞点为原点的东北天坐标系)\",\"speed\":\"float,可选\"}},\n {\"name\":\"move_direction\",\"params\":{\"direction\":\"north/south/east/west/forward/backward/left/right\",\"distance\":\"[1,10000],缺省则持续移动\",\"speed\":\"float,可选\"}},\n {\"name\":\"approach_target\",\"params\":{\"target_class\":\"string,要趋近的目标类别\",\"description\":\"string,可选,目标属性描述\",\"stop_distance\":\"float,期望的最终停止距离\",\"speed\":\"float,可选,期望的逼近速度\"}},\n {\"name\":\"rotate\",\"params\":{\"angle\":\"float,无人机自身旋转角度(正数逆时针,负数顺时针)\",\"angular_velocity\":\"rad/s,旋转角速度\"}},\n {\"name\":\"rotate_search\",\"params\":{\"target_class\":\"同object_detect\",\"description\":\"string,可选,目标属性描述\",\"step_angle\":\"float,可选,每一步旋转的角度\",\"total_rotation\":\"float,可选,总共旋转搜索的角度\"}},\n {\"name\":\"manual_confirmation\",\"params\":{}},\n {\"name\":\"loiter\",\"params\":{\"duration\":\"[1,600]秒/until_condition:可选\"}},\n {\"name\":\"object_detect\",\"params\":{\"target_class\":\"person,bicycle,car,motorcycle,airplane,bus,train,truck,boat,traffic_light,fire_hydrant,stop_sign,parking_meter,bench,bird,cat,dog,horse,sheep,cow,elephant,bear,zebra,giraffe,backpack,umbrella,handbag,tie,suitcase,frisbee,skis,snowboard,sports_ball,kite,baseball_bat,baseball_glove,skateboard,surfboard,tennis_racket,bottle,wine_glass,cup,fork,knife,spoon,bowl,banana,apple,sandwich,orange,broccoli,carrot,hot_dog,pizza,donut,cake,chair,couch,potted_plant,bed,dining_table,toilet,tv,laptop,mouse,remote,keyboard,cell_phone,microwave,oven,toaster,sink,refrigerator,book,clock,vase,scissors,teddy_bear,hair_drier,toothbrush,garbage\",\"description\":\"可选,\",\"count\":\"默认1\"}},\n {\"name\":\"search_pattern\",\"params\":{\"pattern_type\":\"spiral/grid\",\"center_x\":\"±10000\",\"center_y\":\"±10000\",\"center_z\":\"[1,5000]\",\"radius\":\"[5,1000]\",\"target_class\":\"同object_detect\",\"description\":\"可选,目标属性\",\"count\":\"默认1\"}},\n {\"name\":\"track_object\",\"params\":{\"target_class\":\"同object_detect\",\"description\":\"可选,目标属性\",\"track_time\":\"[1,600]秒(必传,不可用'duration'\",\"min_confidence\":\"[0.5,1.0]默认0.7\",\"safe_distance\":\"[2,50]默认10\"}},\n {\"name\":\"deliver_payload\",\"params\":{\"payload_type\":\"string\",\"release_altitude\":\"[2,100]默认5\"}},\n {\"name\":\"system_checks\",\"params\":{\"check_level\":\"basic/comprehensive只能在起飞takeoff节点前使用空中无需使用该节点\"}},\n {\"name\":\"return_emergency\",\"params\":{\"reason\":\"string此节点为紧急返航只能返回起飞点当用户提及返回某处时务必使用fly_to_waypoint节点\"}},\n {\"name\":\"take_photos\",\"params\":{\"target_class\":\"同object_detect\",\"description\":\"可选,目标属性\",\"track_time\":\"[1,600]秒(必传,不可用'duration'\",\"min_confidence\":\"[0.5,1.0]默认0.7\",\"safe_distance\":\"[2,50]默认10\"}}\n ],\n \"conditions\": [\n {\"name\":\"at_waypoint\",\"params\":{\"x\":\"±10000\",\"y\":\"±10000\",\"z\":\"[1,5000]\",\"tolerance\":\"默认3.0\"}},\n {\"name\":\"object_detected\",\"params\":{\"target_class\":\"同object_detect必传\",\"description\":\"可选,目标属性\",\"count\":\"默认1\"}}\n ],\n \"control_flow\": [\n {\"name\":\"Sequence\",\"params\":{},\"children\":\"子节点数组(按序执行,全成功则成功)\"},\n {\"name\":\"Selector\",\"params\":{\"memory\":\"默认true\"},\"children\":\"子节点数组(执行到成功为止)\"},\n {\"name\":\"Parallel\",\"params\":{\"policy\":\"all_success/success_on_one\"},\"children\":\"子节点数组同时执行默认all_success\"}\n ],\n \"decorators\": [\n {\"name\":\"SuccessIsFailure\",\"params\":{},\"child\":\"单一子节点(将子节点的成功结果反转为失败)\"}\n ]\n}\n```\n\n\n## 二、节点必填字段后端Schema强制要求缺一验证失败\n每个节点必须包含以下字段字段名/类型不可自定义:\n1. **`type`** \n - 动作节点→`\"action\"`,条件节点→`\"condition\"`,控制流节点→`\"Sequence\"`/`\"Selector\"`/`\"Parallel\"`,装饰器节点→`\"decorator\"`\n2. **`name`**必须是上述JSON中定义的`name`值;\n3. **`params`**:严格匹配上述节点的`params`定义,无自定义参数;\n4. **`children`**:仅控制流节点必含(子节点数组);\n5. **`child`**:仅装饰器节点必含(单一子节点对象,非数组)。\n\n\n## 三、标准任务结构模板(单次起降流程)\n当无人机在地面时大多数任务应遵循“起飞 -> 移动 -> 条件判断 -> 执行 -> 返航/降落”的单次闭环流程,参考结构如下:\n```json\n{\n \"root\": {\n \"type\": \"Sequence\",\n \"name\": \"MainTask\",\n \"children\": [\n {\"type\":\"action\",\"name\":\"system_checks\",\"params\":{\"check_level\":\"comprehensive\"}},\n {\"type\":\"action\",\"name\":\"takeoff\",\"params\":{\"altitude\":10.0}},\n {\"type\":\"action\",\"name\":\"fly_to_waypoint\",\"params\":{\"x\":100.0,\"y\":50.0,\"z\":10.0}}, // 接近目标区域\n // --- 核心任务区 (根据指令替换) ---\n // --- 任务1执行---\n {\"type\":\"action\",\"name\":\"rotate_search\",\"params\":{\"target_class\":\"person\",\"description\":\"目标描述\"}},\n {\"type\":\"action\",\"name\":\"object_detect\",\"params\":{\"target_class\":\"person\",\"description\":\"目标描述\"}},\n // ----条件判断(根据指令替换) -----\n {\"type\":\"condition\",\"name\":\"object_detected\",\"params\":{\"target_class\":\"person\",\"description\":\"扎辫子女子\"}},\n // --- 任务2执行---\n {\"type\":\"action\",\"name\":\"take_photos\",\"params\":{\"target_class\":\"person\",\"description\":\"扎辫子女子\"}}, \n // 默认不需要降落节点,除非用户明确要求\n ]\n }\n}\n```\n\n## 四、场景示例(请灵活参考)\n\n#### 场景 1线性搜索任务Sequence + Selector\n**指令**:“无人机当前在地面,去研究所正大门,搜索扎辫子女子,找到后拍照。”\n**思路**无人机在地面则需要先自检然后起飞获取研究所正大门坐标调用fly_to_waypoint节点到达该地然后调用rotate_search节点搜索目标女子再使用object_detected条件节点这样就可以作为take_photos节点的依据。\n**结构**Sequence (按顺序执行)\n```json\n{\n \"root\": {\n \"type\": \"Sequence\",\n \"name\": \"MainSearchTask\",\n \"children\": [\n {\"type\":\"action\",\"name\":\"takeoff\",\"params\":{\"altitude\":10.0}},\n {\"type\":\"action\",\"name\":\"fly_to_waypoint\",\"params\":{\"x\":100.0,\"y\":50.0,\"z\":10.0}}, \n {\"type\":\"action\",\"name\":\"rotate_search\",\"params\":{\"target_class\":\"person\",\"description\":\"扎辫子女子\"}},\n {\n \"type\": \"Selector\",\n \"name\": \"CheckAndPhoto\",\n \"children\": [\n {\n \"type\": \"Sequence\",\n \"name\": \"PhotoIfFound\",\n \"children\": [\n {\"type\":\"condition\",\"name\":\"object_detected\",\"params\":{\"target_class\":\"person\",\"description\":\"扎辫子女子\"}},\n {\"type\":\"action\",\"name\":\"take_photos\",\"params\":{\"target_class\":\"person\",\"description\":\"扎辫子女子\",\"track_time\":10.0}}\n ]\n },\n {\"type\":\"action\",\"name\":\"loiter\",\"params\":{\"duration\":5.0}} // 未发现时的备选动作\n ]\n }\n ]\n }\n}\n```\n\n#### 场景 2带中断逻辑的巡逻Selector 示例)\n**指令**“无人机当前在地面飞往航点A。如果途中发现可疑人员则悬停。”\n**参考知识**航点A的坐标x:100.0,y:50.0\n**思路**无人机在地面则需要先自检然后起飞获取航点A的坐标调用fly_to_waypoint节点到达该地但同时需要注意看到可疑人员需要悬停意味着一边进行识别识别到进行悬停因此要在object_detect节点后有一个object_detected条件节点作为悬停的条件。\n**结构**\n```json\n{\n \"root\": {\n \"type\": \"Sequence\",\n \"children\": [\n {\"type\":\"action\",\"name\":\"system_checks\",\"params\":{\"check_level\":\"basic\"}},\n {\"type\":\"action\",\"name\":\"takeoff\",\"params\":{\"altitude\":10.0}},\n {\n \"type\": \"Selector\",\n \"name\": \"FlyOrDetect\",\n \"children\": [\n {\n \"type\": \"Sequence\", \n \"name\": \"InterruptionLogic\",\n \"children\": [\n {\"type\":\"action\",\"name\":\"object_detect\",\"params\":{\"target_class\":\"person\"}},\n {\"type\":\"condition\",\"name\":\"object_detected\",\"params\":{\"target_class\":\"person\"}},\n {\"type\":\"action\",\"name\":\"loiter\",\"params\":{\"duration\":5.0}}\n ]\n },\n {\"type\":\"action\",\"name\":\"fly_to_waypoint\",\"params\":{\"x\":100.0,\"y\":50.0,\"z\":10.0}}\n ]\n }\n ]\n }\n}\n```\n\n#### 场景 3长期监控任务Parallel 示例)\n**指令**“无人机当前在空中往广场西边飞200米持续监控5分钟发现人就拍照告诉我到时间可以返航。”\n**参考知识**广场西边200米的坐标x:50.0,y:50.0,z:10.0\n**思路**无人机在空中直接前往目标点到达后需要并行执行两件事1. 倒计时5分钟主控时间2. 持续检测人并拍照(从属任务)。\n使用`Parallel`节点并设置策略为`success_on_one`这样当倒计时loiter结束返回成功时整个并行节点就会成功结束从而强制停止拍照循环。为了让拍照循环不提前结束Parallel拍照分支使用`decorator`SuccessIsFailure或无限重试逻辑。\n**结构**\n```json\n{\n \"root\": {\n \"name\": \"主任务-监控与拍照\",\n \"type\": \"Sequence\",\n \"children\": [\n {\n \"name\": \"fly_to_waypoint\",\n \"type\": \"action\",\n \"params\": {\"x\": 50.0, \"y\": 50.0, \"z\": 10.0}\n },\n {\n \"name\": \"并行监控5分钟\",\n \"type\": \"Parallel\",\n \"params\": { \"policy\": \"success_on_one\" },\n \"children\": [\n {\n \"name\": \"loiter\",\n \"type\": \"action\",\n \"params\": { \"duration\": 300 }\n },\n {\n \"name\": \"拍照循环永不成功\",\n \"type\": \"decorator\",\n \"child\": {\n \"name\": \"DetectAndShoot\",\n \"type\": \"Sequence\",\n \"children\": [\n {\n \"name\": \"SuccessIsFailure\",\n \"type\": \"decorator\",\n \"child\": {\n \"name\": \"check_and_photo\",\n \"type\": \"Sequence\",\n \"children\": [\n {\"name\": \"object_detect\", \"type\": \"action\", \"params\": { \"target_class\": \"person\" }},\n {\"name\": \"object_detected\", \"type\": \"condition\", \"params\": { \"target_class\": \"person\" }},\n {\"name\": \"take_photos\", \"type\": \"action\", \"params\": { \"target_class\": \"person\" }}\n ]\n }\n }\n ]\n }\n }\n ]\n },\n {\n \"name\": \"fly_to_waypoint\",\n \"type\": \"action\",\n \"params\": {\"x\": 0.0, \"y\": 0.0, \"z\": 10.0} // 返航回起飞点\n }\n ]\n }\n}\n```\n\n## 六、高频错误规避\n1. 控制流节点的 `type` 必须是 `\"Sequence\"`, `\"Selector\"` 或 `\"Parallel\"`\n2. 当用户指令中要求执行动作前增加人工确认时比如“我确认后拍照”则必须在拍照动作前增加manual_confirmation节点\n3. 在条件节点执行前必须有相应动作节点如object_detected节点前必须是rotate_search等搜索类节点\n4. 当使用rotate_search或者object_detect节点时必须有object_detected节点\n5. 用户指令中要求在当前位置执行任务时无需fly_to_waypoint节点\n6. **严格区分无人机状态**:当用户指令明确无人机在**空中**时严禁使用system_checks与takeoff节点仅当指令明确在**地面**时,才可使用这两个节点\n7. **重点关注**fly_to_waypoint与return_emergency节点辨析fly_to_waypoint节点后面跟着明确的地点坐标参数因此当用户说“到某地”“回到某地”“紧急回到某地”时应使用fly_to_waypoint节点return_emergency节点只能在返回起飞点时使用只有当提及\"返航\"“紧急返航”**且没有跟着任何地点信息时**,才会使用该节点。\n8. 当用户指令中提及靠近目标拍照时,**需要先使用approach_target节点**再take_photos;没有要靠近目标时则严禁使用approach_target节点。\n\n## 七、坐标计算规则(东北天坐标系 ENU\n本系统统一使用东北天ENU坐标系\n- **X轴**:正方向为**东** (East),负方向为**西** (West)\n- **Y轴**:正方向为**北** (North),负方向为**南** (South)\n- **Z轴**:正方向为**天** (Up),负方向为**地** (Down)\n\n**当指令要求前往某参照点(如\"广场\")的偏移位置时,必须自行计算最终绝对坐标:**\n假设参照点坐标为 $(x_0, y_0, z_0)$,偏移距离为 $d$\n- **\"往东飞 $d$ 米\"**:目标坐标 $(x_0 + d, y_0, z_0)$\n- **\"往西飞 $d$ 米\"**:目标坐标 $(x_0 - d, y_0, z_0)$\n- **\"往北飞 $d$ 米\"**:目标坐标 $(x_0, y_0 + d, z_0)$\n- **\"往南飞 $d$ 米\"**:目标坐标 $(x_0, y_0 - d, z_0)$\n- **\"往上/升高 $d$ 米\"**:目标坐标 $(x_0, y_0, z_0 + d)$\n\n**示例**\n若\"广场\"坐标为 $(-17, 360.0, 3.0)$\n- \"去广场**东边**20米\" -> 目标点 $(3, 360.0, 3.0)$\n- \"去广场**南边**30米\" -> 目标点 $(-17, 330.0, 3.0)$\n\n## 八、输出要求\n仅输出1个严格符合上述所有规则的JSON对象。\n\n\n【强制规则】仅生成包含root的复杂行为树JSON不得输出简单模式不得包含mode字段或仅有action节点。\n\n=== User Prompt ===\n无人机当前在空中紧急回到广场看见了红绿灯之后直接降落。\n\n---\n参考知识\n以下是从知识库中检索到的、与当前任务最相关的信息请优先参考这些信息来生成结果\n对于查找搜索类任务比如查找某个人或者东西我们可以让无人机执行rotate_search动作节点让无人机以自身为原点旋转观察四周确保无人机主动寻找目标。\n\n地点'广场'。属性:开阔区域。东北天坐标系坐标:(x:-17, y:360.0, z:3.0)。\n\n地点'研究所正大门'。别名:'大门'、'入口'。东北天坐标系坐标:(x:-23.8, y:292.8, z:14)。建议悬停高度14米。适合任务定点侦察、拍照。\n\n大楼外围四个点东北天坐标系坐标A(-24.00, 241.80),B(-108.50, 241.80),C(-108.50, 289.80),D(-24.00, 292.80)。\n\n在地图上有一个名为 '跷跷板' 的地点或区域它的leisure是'playground',其中心位置坐标大约在东北天坐标系 (x:15, y:-8.5, z:1.2)。\n---"
}