{ "root": { "type": "Sequence", "name": "MainSearchTask", "children": [ { "type": "action", "name": "fly_to_waypoint", "params": { "x": -24.0, "y": 241.8, "z": 14.0 } }, { "type": "action", "name": "rotate_search", "params": { "target_class": "person", "description": "黄色衣服男子", "step_angle": 10.0, "total_rotation": 360.0 } }, { "type": "Selector", "name": "CheckAndPhoto", "children": [ { "type": "Sequence", "name": "PhotoIfFound", "children": [ { "type": "condition", "name": "object_detected", "params": { "target_class": "person", "description": "黄色衣服男子", "count": 1 } }, { "type": "action", "name": "approach_target", "params": { "target_class": "person", "description": "黄色衣服男子", "stop_distance": 2.0, "speed": 1.0 } }, { "type": "action", "name": "manual_confirmation", "params": {} }, { "type": "action", "name": "take_photos", "params": { "target_class": "person", "description": "黄色衣服男子", "track_time": 10.0, "min_confidence": 0.7, "safe_distance": 10.0 } } ] }, { "type": "action", "name": "loiter", "params": { "duration": 5.0 } } ] } ] }, "plan_id": "2595d035-5b5a-4f7a-ab39-94392dd6aa57", "visualization_url": "/static/py_tree.png", "final_prompt": "=== System Prompt ===\n任务:根据用户任意任务指令,生成结构化可执行的无人机行为树(Pytree)JSON。**仅输出单一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\":\"string,要搜寻的目标类别\",\"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\":\"strike_target\",\"params\":{\"target_class\":\"同object_detect\",\"description\":\"可选,目标属性\",\"count\":\"默认1\"}},\n {\"name\":\"battle_damage_assessment\",\"params\":{\"target_class\":\"同object_detect\",\"assessment_time\":\"[5,60],默认15\"}},\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\"}},\n {\"name\":\"return\",\"params\":{\"reason\":\"string\"}},\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 {\"name\":\"target_destroyed\",\"params\":{\"target_class\":\"同object_detect\",\"description\":\"可选,目标属性\",\"confidence\":\"[0.5,1.0]默认0.8\"}},\n {\"name\":\"time_elapsed\",\"params\":{\"duration\":\"[1,2700]秒\"}},\n {\"name\":\"gps_status\",\"params\":{\"min_satellites\":\"int[6,15],必传(如8)\"}}\n ],\n \"control_flow\": [\n {\"name\":\"Sequence\",\"params\":{},\"children\":\"子节点数组(按序执行,全成功则成功)\"},\n {\"name\":\"Selector\",\"params\":{\"memory\":\"默认true\"},\"children\":\"子节点数组(执行到成功为止)\"},\n {\"name\":\"Parallel\",\"params\":{\"policy\":\"all_success\"},\"children\":\"子节点数组(同时执行,严禁用'one_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 {\"type\":\"action\",\"name\":\"rotate_search\",\"params\":{\"target_class\":\"person\",\"description\":\"目标描述\"}},\n {\"type\":\"action\",\"name\":\"object_detect\",\"params\":{\"target_class\":\"person\",\"description\":\"目标描述\"}},\n // -------------------------------\n // 默认不需要降落节点,除非用户明确要求\n ]\n }\n}\n```\n当无人机在飞行状态中时,则无需飞行前检查与起飞节点\n\n## 四、场景示例(请灵活参考)\n\n#### 场景 1:线性搜索任务(Sequence + Selector)\n**指令**:“无人机当前在地面,去研究所正大门,搜索扎辫子女子,找到后近距离拍照。”\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\":\"approach_target\",\"params\":{\"target_class\":\"person\",\"description\":\"扎辫子女子\",\"stop_distance\":2.0,\"speed\":1.0}},\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**结构**:\n```json\n{\n \"root\": {\n \"type\": \"Sequence\",\n \"children\": [\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\":\"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:环绕侦察类任务\n**指令**:“无人机当前在地面,去面前的大楼12米高处,绕着外围看有没有打开的窗户,发现则进行拍照。”\n**参考知识**:{\"text\": \"大楼外围四个点坐标:A(-24.00, 241.80),B(-108.50, 241.80),C(-108.50, 289.80),D(-24.00, 292.80)。\"}\n**结构**:Sequence (按顺序执行)\n```json\n{\n \"root\": {\n \"type\": \"Sequence\",\n \"name\": \"SurroundAndInspect\",\n \"children\": [\n {\"type\":\"action\",\"name\":\"takeoff\",\"params\":{\"altitude\":12.0}},\n // 沿点A->B->C->D飞行,并在此过程中持续检测\n {\n \"type\": \"Parallel\",\n \"name\": \"FlyAndInspectToA\",\n \"children\": [\n {\n \"type\": \"action\",\n \"name\": \"fly_sequence\",\n \"params\": {\n \"waypoints\": [\n {\"x\":-24.0, \"y\":241.8, \"z\":12.0},\n {\"x\":-108.5, \"y\":241.8, \"z\":12.0},\n {\"x\":-108.5, \"y\":289.8, \"z\":12.0},\n {\"x\":-24.0, \"y\":292.8, \"z\":12.0}\n ],\n \"coordinate_frame\": \"local_enu\"\n }\n },\n {\n \"type\": \"Selector\", \n \"name\": \"OpportunisticPhoto\",\n \"children\": [\n {\n \"type\": \"decorator\",\n \"name\": \"SuccessIsFailure\",\n \"child\": {\n \"type\": \"Sequence\",\n \"name\": \"DetectAndCapture\",\n \"children\": [\n {\"type\":\"action\",\"name\":\"object_detect\",\"params\":{\"target_class\":\"window\",\"description\":\"open window\"}},\n {\"type\":\"condition\",\"name\":\"object_detected\",\"params\":{\"target_class\":\"window\",\"description\":\"open window\"}},\n {\"type\":\"action\",\"name\":\"take_photos\",\"params\":{\"target_class\":\"window\",\"description\":\"open window\",\"track_time\":5.0}}\n ]\n }\n },\n {\"type\":\"action\",\"name\":\"loiter\",\"params\":{\"duration\":0.1}} // 占位动作\n ]\n }\n ]\n }\n ]\n }\n}\n```\n\n## 六、高频错误规避\n1. 优先级排序不可修改`target_class`,仅用`description`填排序规则;\n2. `track_object`必传`track_time`;\n3. `gps_status`的`min_satellites`必须在6-15之间;\n4. 严禁输出 markdown 代码块标记,直接输出 JSON 纯文本;\n5. 控制流节点的 `type` 必须是 `\"Sequence\"`, `\"Selector\"` 或 `\"Parallel\"`;\n6. rotate与rotate_search动作节点意思是无人机以自身为原点旋转,而非围绕外部点旋转\n7. 当用户指令中要求执行动作前增加人工确认时,比如“我确认后拍照”,则必须在拍照动作前增加manual_confirmation节点\n8. 搜索/寻找类任务(如“寻找xxx”、“搜索xxx”),在 `object_detected` 条件节点之前,必须先安排 `rotate_search` 动作节点,确保无人机主动寻找目标。\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:-24.0, y:241.8, z:14)。建议搜索半径:30米。适合任务:寻找人员、旋转搜索。\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在地图上有一个名为 '学生宿舍' 的地点或区域,它的building是'dormitory',其中心位置坐标大约在 (x:5, y:3, z:2)。\n---" }