[2026-01-02 14:09:56] ================================================================================ [2026-01-02 14:09:56] --- API Test: Scene 1: Search at Gate (Expected.csv Row 2) --- [2026-01-02 14:09:56] URL: http://127.0.0.1:8000/generate_plan [2026-01-02 14:09:56] Sending Prompt: "地面待命,去研究所正大门,搜索扎辫子女子并拍照。" [2026-01-02 14:10:05] ✅ Received Response: [2026-01-02 14:10:05] 📝 组织后的Prompt: [2026-01-02 14:10:05] === System Prompt === 任务:根据用户任意任务指令,生成结构化可执行的无人机行为树(Pytree)JSON。**仅输出单一JSON对象,无任何自然语言、注释或额外内容**。 ## 一、核心节点定义(格式不可修改,确保后端解析) #### 1. 可用节点定义 (必须遵守) 你必须严格从以下JSON定义的列表中选择节点构建行为树,不允许使用未定义节点: ```json { "actions": [ {"name":"takeoff","params":{"altitude":"float[1,100],默认2"}}, {"name":"land","params":{"mode":"'current'/'home'"}}, {"name":"fly_to_waypoint","params":{"x":"±10000","y":"±10000","z":"[1,5000]","acceptance_radius":"默认2.0"}}, {"name":"move_direction","params":{"direction":"north/south/east/west/forward/backward/left/right","distance":"[1,10000],缺省持续移动"}}, {"name":"orbit_around_point","params":{"center_x":"±10000","center_y":"±10000","center_z":"[1,5000]","radius":"[5,1000]","laps":"[1,20]","clockwise":"默认true","speed_mps":"[0.5,15]","gimbal_lock":"默认true"}}, {"name":"orbit_around_target","params":{"target_class":"见object_detect列表","description":"可选,目标属性","radius":"[5,1000]","laps":"[1,20]","clockwise":"默认true","speed_mps":"[0.5,15]","gimbal_lock":"默认true"}}, {"name":"loiter","params":{"duration":"[1,600]秒/until_condition:可选"}}, {"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","description":"可选,","count":"默认1"}}, {"name":"strike_target","params":{"target_class":"同object_detect","description":"可选,目标属性","count":"默认1"}}, {"name":"battle_damage_assessment","params":{"target_class":"同object_detect","assessment_time":"[5,60],默认15"}}, {"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"}}, {"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"}}, {"name":"deliver_payload","params":{"payload_type":"string","release_altitude":"[2,100]默认5"}}, {"name":"preflight_checks","params":{"check_level":"basic/comprehensive"}}, {"name":"emergency_return","params":{"reason":"string"}}, {"name":"rotate_search","params":{"center_x":"±10000","center_y":"±10000","center_z":"[1,5000]","radius":"[5,100]","speed_mps":"[0.5,10]","duration":"[10,600]秒"}}, {"name":"wait_for_confirmation","params":{"message":"string","timeout":"[10,600]秒"}} ], "conditions": [ {"name":"battery_above","params":{"threshold":"[0.0,1.0],必传"}}, {"name":"at_waypoint","params":{"x":"±10000","y":"±10000","z":"[1,5000]","tolerance":"默认3.0"}}, {"name":"object_detected","params":{"target_class":"同object_detect(必传)","description":"可选,目标属性","count":"默认1"}}, {"name":"target_destroyed","params":{"target_class":"同object_detect","description":"可选,目标属性","confidence":"[0.5,1.0]默认0.8"}}, {"name":"time_elapsed","params":{"duration":"[1,2700]秒"}}, {"name":"gps_status","params":{"min_satellites":"int[6,15],必传(如8)"}} ], "control_flow": [ {"name":"Sequence","params":{},"children":"子节点数组(按序执行,全成功则成功)"}, {"name":"Selector","params":{"memory":"默认true"},"children":"子节点数组(执行到成功为止)"}, {"name":"Parallel","params":{"policy":"all_success"},"children":"子节点数组(同时执行,严禁用'one_success')"} ], "decorators": [ {"name":"SuccessIsFailure","params":{},"child":"单个子节点(成功转失败,失败仍失败)"} ] } ``` ## 二、节点必填字段(后端Schema强制要求,缺一验证失败) 每个节点必须包含以下字段,字段名/类型不可自定义: 1. **`type`**: - 动作节点→`"action"`,条件节点→`"condition"`,装饰器节点→`"decorator"`,控制流节点→`"Sequence"`/`"Selector"`/`"Parallel"`(与`name`字段值完全一致); 2. **`name`**:必须是上述JSON中`actions`/`conditions`/`control_flow`/`decorators`下的`name`值; 3. **`params`**:严格匹配上述节点的`params`定义,无自定义参数; 4. **`children`**:仅控制流节点必含(子节点数组); 5. **`child`**:仅装饰器节点必含(单个子节点对象)。 ## 三、行为树固定结构(通用不变) 根节点通常是 `Sequence` 或 `Selector`,直接包含任务逻辑。不再强制包含 `SafetyMonitor` 或 `Parallel` 根节点。 示例结构(简单顺序任务): ```json { "root": { "type": "Sequence", "name": "MainTask", "params": {}, "children": [ {"type":"action","name":"takeoff","params":{"altitude":10.0}}, {"type":"action","name":"fly_to_waypoint","params":{"x":200.0,"y":150.0,"z":10.0}}, {"type":"action","name":"land","params":{"mode":"home"}} ] } } ``` ## 四、优先级排序任务通用示例 当用户指令中明确提出有多个待考察且具有优先级关系的物体时,节点描述须为优先级关系。比如当指令为已知有三个气球,危险级关系为红色气球大于蓝色气球大于绿色气球,要求优先跟踪最危险的气球时,节点的描述参考下表情形。 | 用户指令场景 | `target_class` | `description` | 核心节点示例(search_pattern) | |-----------------------------|-----------------|-------------------------|------------------------------------------------------------------------------------------------| | 红气球>蓝气球>绿气球 | `balloon` | `(红>蓝>绿)` | `{"type":"action","name":"search_pattern","params":{"pattern_type":"grid","center_x":200,"center_y":150,"center_z":10,"radius":50,"target_class":"balloon","description":"(红>蓝>绿)"}}` | | 军用卡车>民用卡车>面包车 | `truck` | `(军用卡车>民用卡车>面包车)` | `{"type":"action","name":"object_detect","params":{"target_class":"truck","description":"(军用卡车>民用卡车>面包车)"}}` | ## 五、高频错误规避(确保验证通过) 1. 优先级排序不可修改`target_class`:如“民用卡车、面包车与军用卡车中,军用卡车优先”,`target_class`仍为`truck`,仅用`description`填排序规则; 2. 在没有明确指出物体之间的优先级关系情况下,`description`字段只描述物体属性本身,严禁与用户指令中不存在的物体进行排序; 3. `track_object`必传`track_time`:不可用`duration`替代(如跟踪30秒填`"track_time":30.0`); 4. `gps_status`的`min_satellites`必须在6-15之间(如8,不可缺省); 5. 无自定义节点:“锁定高优先级目标”需通过`object_detect`+`object_detected`实现,不可用“lock_high_risk_target”。 ## 六、新场景模式指南 (New Scenarios) ### 1. 预期场景 (Expected Scenarios) 当用户指令包含“旋转搜索”、“人工确认”等特定词汇时,请使用以下对应关系: - **"旋转搜索"** -> 使用 `rotate_search` 动作。 - **"人工确认"** -> 使用 `wait_for_confirmation` 动作(通常放在 `object_detect` 或 `object_detected` 之后)。 **示例:** "到研究所广场,寻找黄色衣服男子,我确认后再对其拍照。" ```json { "type": "Sequence", "name": "SearchAndConfirm", "children": [ {"type":"action", "name":"fly_to_waypoint", "params":{"x":20, "y":150, "z":10}}, {"type":"action", "name":"rotate_search", "params":{"center_x":20, "y":150, "z":10, "radius":30, "duration":60}}, {"type":"action", "name":"wait_for_confirmation", "params":{"message":"Found yellow shirt male, confirm to photo?", "timeout":60}}, {"type":"action", "name":"strike_target", "params":{"target_class":"person", "description":"yellow shirt"}} ] } ``` ### 2. 环绕侦察 (Circular Reconnaissance with Interrupts) 当用户要求“环绕侦察”或“巡逻中发现目标即拍照”时,必须使用 `Selector` + `SuccessIsFailure` (Decorator) + `fly_to_waypoint` 的组合模式。 **逻辑解释:** 这是一个“顺路侦察”模式。无人机在飞往下一个航点的过程中(Selector),先尝试检测目标(ReactiveWork)。如果检测到目标并拍照成功,`SuccessIsFailure` 会欺骗 Selector 说“失败了”,从而迫使 Selector 继续执行 `fly_to_waypoint`,确保无人机不会因为拍了照就停在半路,而是继续飞向终点。 **结构模板:** ```json { "name": "GoToWaypointX", "type": "Selector", "children": [ {"type": "condition", "name": "at_waypoint", "params": {"target_position": [x, y, z]}}, { "name": "ReactiveWork", "type": "Selector", "children": [ { "name": "SuccessIsFailure", "type": "decorator", "child": { "name": "DetectHoverPhoto", "type": "Sequence", "children": [ {"name": "object_detect", "type": "action", "params": {"target_class": "person"}}, {"name": "loiter", "type": "action", "params": {"time": 2.0}} ] } }, {"name": "fly_to_waypoint", "type": "action", "params": {"x": x, "y": y, "z": z}} ] } ] } ``` ## 七、输出要求 仅输出1个严格符合上述所有规则的JSON对象,**确保:1. 优先级排序逻辑正确填入`description`;2. `target_class`匹配预定义列表;3. 行为树结构不变;4. 后端解析与Schema验证无错误**,无任何冗余内容。 【强制规则】仅生成包含root的复杂行为树JSON,不得输出简单模式(不得包含mode字段或仅有action节点)。 === User Prompt === 地面待命,去研究所正大门,搜索扎辫子女子并拍照。 [2026-01-02 14:10:05] 完整响应内容: [2026-01-02 14:10:05] { "root": { "type": "Sequence", "name": "MainTask", "children": [ { "type": "action", "name": "preflight_checks", "params": { "check_level": "basic" } }, { "type": "action", "name": "fly_to_waypoint", "params": { "x": 200, "y": 150, "z": 10 } }, { "type": "action", "name": "rotate_search", "params": { "center_x": 200, "center_y": 150, "center_z": 10, "radius": 30, "duration": 60 } }, { "type": "action", "name": "wait_for_confirmation", "params": { "message": "Found woman with braid, confirm to photo?", "timeout": 60 } }, { "type": "action", "name": "object_detect", "params": { "target_class": "person", "description": "(扎辫子女子)" } }, { "type": "action", "name": "strike_target", "params": { "target_class": "person", "description": "扎辫子女子" } } ] }, "plan_id": "06a44e45-153e-4f15-9c73-bcebd24e08cd", "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\":\"move_direction\",\"params\":{\"direction\":\"north/south/east/west/forward/backward/left/right\",\"distance\":\"[1,10000],缺省持续移动\"}},\n {\"name\":\"orbit_around_point\",\"params\":{\"center_x\":\"±10000\",\"center_y\":\"±10000\",\"center_z\":\"[1,5000]\",\"radius\":\"[5,1000]\",\"laps\":\"[1,20]\",\"clockwise\":\"默认true\",\"speed_mps\":\"[0.5,15]\",\"gimbal_lock\":\"默认true\"}},\n {\"name\":\"orbit_around_target\",\"params\":{\"target_class\":\"见object_detect列表\",\"description\":\"可选,目标属性\",\"radius\":\"[5,1000]\",\"laps\":\"[1,20]\",\"clockwise\":\"默认true\",\"speed_mps\":\"[0.5,15]\",\"gimbal_lock\":\"默认true\"}},\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\",\"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\":\"preflight_checks\",\"params\":{\"check_level\":\"basic/comprehensive\"}},\n {\"name\":\"emergency_return\",\"params\":{\"reason\":\"string\"}},\n {\"name\":\"rotate_search\",\"params\":{\"center_x\":\"±10000\",\"center_y\":\"±10000\",\"center_z\":\"[1,5000]\",\"radius\":\"[5,100]\",\"speed_mps\":\"[0.5,10]\",\"duration\":\"[10,600]秒\"}},\n {\"name\":\"wait_for_confirmation\",\"params\":{\"message\":\"string\",\"timeout\":\"[10,600]秒\"}}\n ],\n \"conditions\": [\n {\"name\":\"battery_above\",\"params\":{\"threshold\":\"[0.0,1.0],必传\"}},\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\"`,装饰器节点→`\"decorator\"`,控制流节点→`\"Sequence\"`/`\"Selector\"`/`\"Parallel\"`(与`name`字段值完全一致);\n2. **`name`**:必须是上述JSON中`actions`/`conditions`/`control_flow`/`decorators`下的`name`值;\n3. **`params`**:严格匹配上述节点的`params`定义,无自定义参数;\n4. **`children`**:仅控制流节点必含(子节点数组);\n5. **`child`**:仅装饰器节点必含(单个子节点对象)。\n\n\n## 三、行为树固定结构(通用不变)\n根节点通常是 `Sequence` 或 `Selector`,直接包含任务逻辑。不再强制包含 `SafetyMonitor` 或 `Parallel` 根节点。\n\n示例结构(简单顺序任务):\n```json\n{\n \"root\": {\n \"type\": \"Sequence\",\n \"name\": \"MainTask\",\n \"params\": {},\n \"children\": [\n {\"type\":\"action\",\"name\":\"takeoff\",\"params\":{\"altitude\":10.0}},\n {\"type\":\"action\",\"name\":\"fly_to_waypoint\",\"params\":{\"x\":200.0,\"y\":150.0,\"z\":10.0}},\n {\"type\":\"action\",\"name\":\"land\",\"params\":{\"mode\":\"home\"}}\n ]\n }\n}\n```\n\n\n## 四、优先级排序任务通用示例\n当用户指令中明确提出有多个待考察且具有优先级关系的物体时,节点描述须为优先级关系。比如当指令为已知有三个气球,危险级关系为红色气球大于蓝色气球大于绿色气球,要求优先跟踪最危险的气球时,节点的描述参考下表情形。\n| 用户指令场景 | `target_class` | `description` | 核心节点示例(search_pattern) |\n|-----------------------------|-----------------|-------------------------|------------------------------------------------------------------------------------------------|\n| 红气球>蓝气球>绿气球 | `balloon` | `(红>蓝>绿)` | `{\"type\":\"action\",\"name\":\"search_pattern\",\"params\":{\"pattern_type\":\"grid\",\"center_x\":200,\"center_y\":150,\"center_z\":10,\"radius\":50,\"target_class\":\"balloon\",\"description\":\"(红>蓝>绿)\"}}` |\n| 军用卡车>民用卡车>面包车 | `truck` | `(军用卡车>民用卡车>面包车)` | `{\"type\":\"action\",\"name\":\"object_detect\",\"params\":{\"target_class\":\"truck\",\"description\":\"(军用卡车>民用卡车>面包车)\"}}` |\n\n\n## 五、高频错误规避(确保验证通过)\n1. 优先级排序不可修改`target_class`:如“民用卡车、面包车与军用卡车中,军用卡车优先”,`target_class`仍为`truck`,仅用`description`填排序规则;\n2. 在没有明确指出物体之间的优先级关系情况下,`description`字段只描述物体属性本身,严禁与用户指令中不存在的物体进行排序;\n3. `track_object`必传`track_time`:不可用`duration`替代(如跟踪30秒填`\"track_time\":30.0`);\n4. `gps_status`的`min_satellites`必须在6-15之间(如8,不可缺省);\n5. 无自定义节点:“锁定高优先级目标”需通过`object_detect`+`object_detected`实现,不可用“lock_high_risk_target”。\n\n\n## 六、新场景模式指南 (New Scenarios)\n\n### 1. 预期场景 (Expected Scenarios)\n当用户指令包含“旋转搜索”、“人工确认”等特定词汇时,请使用以下对应关系:\n- **\"旋转搜索\"** -> 使用 `rotate_search` 动作。\n- **\"人工确认\"** -> 使用 `wait_for_confirmation` 动作(通常放在 `object_detect` 或 `object_detected` 之后)。\n\n**示例:** \"到研究所广场,寻找黄色衣服男子,我确认后再对其拍照。\"\n```json\n{\n \"type\": \"Sequence\",\n \"name\": \"SearchAndConfirm\",\n \"children\": [\n {\"type\":\"action\", \"name\":\"fly_to_waypoint\", \"params\":{\"x\":20, \"y\":150, \"z\":10}},\n {\"type\":\"action\", \"name\":\"rotate_search\", \"params\":{\"center_x\":20, \"y\":150, \"z\":10, \"radius\":30, \"duration\":60}},\n {\"type\":\"action\", \"name\":\"wait_for_confirmation\", \"params\":{\"message\":\"Found yellow shirt male, confirm to photo?\", \"timeout\":60}},\n {\"type\":\"action\", \"name\":\"strike_target\", \"params\":{\"target_class\":\"person\", \"description\":\"yellow shirt\"}}\n ]\n}\n```\n\n### 2. 环绕侦察 (Circular Reconnaissance with Interrupts)\n当用户要求“环绕侦察”或“巡逻中发现目标即拍照”时,必须使用 `Selector` + `SuccessIsFailure` (Decorator) + `fly_to_waypoint` 的组合模式。\n**逻辑解释:** 这是一个“顺路侦察”模式。无人机在飞往下一个航点的过程中(Selector),先尝试检测目标(ReactiveWork)。如果检测到目标并拍照成功,`SuccessIsFailure` 会欺骗 Selector 说“失败了”,从而迫使 Selector 继续执行 `fly_to_waypoint`,确保无人机不会因为拍了照就停在半路,而是继续飞向终点。\n\n**结构模板:**\n```json\n{\n \"name\": \"GoToWaypointX\",\n \"type\": \"Selector\",\n \"children\": [\n {\"type\": \"condition\", \"name\": \"at_waypoint\", \"params\": {\"target_position\": [x, y, z]}},\n {\n \"name\": \"ReactiveWork\",\n \"type\": \"Selector\",\n \"children\": [\n {\n \"name\": \"SuccessIsFailure\",\n \"type\": \"decorator\",\n \"child\": {\n \"name\": \"DetectHoverPhoto\",\n \"type\": \"Sequence\",\n \"children\": [\n {\"name\": \"object_detect\", \"type\": \"action\", \"params\": {\"target_class\": \"person\"}},\n {\"name\": \"loiter\", \"type\": \"action\", \"params\": {\"time\": 2.0}}\n ]\n }\n },\n {\"name\": \"fly_to_waypoint\", \"type\": \"action\", \"params\": {\"x\": x, \"y\": y, \"z\": z}}\n ]\n }\n ]\n}\n```\n\n\n## 七、输出要求\n仅输出1个严格符合上述所有规则的JSON对象,**确保:1. 优先级排序逻辑正确填入`description`;2. `target_class`匹配预定义列表;3. 行为树结构不变;4. 后端解析与Schema验证无错误**,无任何冗余内容。\n\n\n【强制规则】仅生成包含root的复杂行为树JSON,不得输出简单模式(不得包含mode字段或仅有action节点)。\n\n=== User Prompt ===\n地面待命,去研究所正大门,搜索扎辫子女子并拍照。" } [2026-01-02 14:10:05] --- Validation Checks --- [2026-01-02 14:10:05] PASS: Response is a valid JSON object. [2026-01-02 14:10:05] PASS: Response contains a valid 'root' key. [2026-01-02 14:10:05] PASS: Response contains a valid 'visualization_url': /static/py_tree.png [2026-01-02 14:10:05] ✅ Test completed successfully [2026-01-02 14:10:05] ================================================================================ [2026-01-02 14:10:05] [2026-01-02 14:10:05] ================================================================================ [2026-01-02 14:10:05] --- API Test: Scene 2: Search with Confirmation (Expected.csv Row 5) --- [2026-01-02 14:10:05] URL: http://127.0.0.1:8000/generate_plan [2026-01-02 14:10:05] Sending Prompt: "空中待命/任务中,到研究所广场,寻找黄色衣服男子,我确认后再对其拍照。" [2026-01-02 14:10:11] ✅ Received Response: [2026-01-02 14:10:11] 📝 组织后的Prompt: [2026-01-02 14:10:11] === System Prompt === 任务:根据用户任意任务指令,生成结构化可执行的无人机行为树(Pytree)JSON。**仅输出单一JSON对象,无任何自然语言、注释或额外内容**。 ## 一、核心节点定义(格式不可修改,确保后端解析) #### 1. 可用节点定义 (必须遵守) 你必须严格从以下JSON定义的列表中选择节点构建行为树,不允许使用未定义节点: ```json { "actions": [ {"name":"takeoff","params":{"altitude":"float[1,100],默认2"}}, {"name":"land","params":{"mode":"'current'/'home'"}}, {"name":"fly_to_waypoint","params":{"x":"±10000","y":"±10000","z":"[1,5000]","acceptance_radius":"默认2.0"}}, {"name":"move_direction","params":{"direction":"north/south/east/west/forward/backward/left/right","distance":"[1,10000],缺省持续移动"}}, {"name":"orbit_around_point","params":{"center_x":"±10000","center_y":"±10000","center_z":"[1,5000]","radius":"[5,1000]","laps":"[1,20]","clockwise":"默认true","speed_mps":"[0.5,15]","gimbal_lock":"默认true"}}, {"name":"orbit_around_target","params":{"target_class":"见object_detect列表","description":"可选,目标属性","radius":"[5,1000]","laps":"[1,20]","clockwise":"默认true","speed_mps":"[0.5,15]","gimbal_lock":"默认true"}}, {"name":"loiter","params":{"duration":"[1,600]秒/until_condition:可选"}}, {"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","description":"可选,","count":"默认1"}}, {"name":"strike_target","params":{"target_class":"同object_detect","description":"可选,目标属性","count":"默认1"}}, {"name":"battle_damage_assessment","params":{"target_class":"同object_detect","assessment_time":"[5,60],默认15"}}, {"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"}}, {"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"}}, {"name":"deliver_payload","params":{"payload_type":"string","release_altitude":"[2,100]默认5"}}, {"name":"preflight_checks","params":{"check_level":"basic/comprehensive"}}, {"name":"emergency_return","params":{"reason":"string"}}, {"name":"rotate_search","params":{"center_x":"±10000","center_y":"±10000","center_z":"[1,5000]","radius":"[5,100]","speed_mps":"[0.5,10]","duration":"[10,600]秒"}}, {"name":"wait_for_confirmation","params":{"message":"string","timeout":"[10,600]秒"}} ], "conditions": [ {"name":"battery_above","params":{"threshold":"[0.0,1.0],必传"}}, {"name":"at_waypoint","params":{"x":"±10000","y":"±10000","z":"[1,5000]","tolerance":"默认3.0"}}, {"name":"object_detected","params":{"target_class":"同object_detect(必传)","description":"可选,目标属性","count":"默认1"}}, {"name":"target_destroyed","params":{"target_class":"同object_detect","description":"可选,目标属性","confidence":"[0.5,1.0]默认0.8"}}, {"name":"time_elapsed","params":{"duration":"[1,2700]秒"}}, {"name":"gps_status","params":{"min_satellites":"int[6,15],必传(如8)"}} ], "control_flow": [ {"name":"Sequence","params":{},"children":"子节点数组(按序执行,全成功则成功)"}, {"name":"Selector","params":{"memory":"默认true"},"children":"子节点数组(执行到成功为止)"}, {"name":"Parallel","params":{"policy":"all_success"},"children":"子节点数组(同时执行,严禁用'one_success')"} ], "decorators": [ {"name":"SuccessIsFailure","params":{},"child":"单个子节点(成功转失败,失败仍失败)"} ] } ``` ## 二、节点必填字段(后端Schema强制要求,缺一验证失败) 每个节点必须包含以下字段,字段名/类型不可自定义: 1. **`type`**: - 动作节点→`"action"`,条件节点→`"condition"`,装饰器节点→`"decorator"`,控制流节点→`"Sequence"`/`"Selector"`/`"Parallel"`(与`name`字段值完全一致); 2. **`name`**:必须是上述JSON中`actions`/`conditions`/`control_flow`/`decorators`下的`name`值; 3. **`params`**:严格匹配上述节点的`params`定义,无自定义参数; 4. **`children`**:仅控制流节点必含(子节点数组); 5. **`child`**:仅装饰器节点必含(单个子节点对象)。 ## 三、行为树固定结构(通用不变) 根节点通常是 `Sequence` 或 `Selector`,直接包含任务逻辑。不再强制包含 `SafetyMonitor` 或 `Parallel` 根节点。 示例结构(简单顺序任务): ```json { "root": { "type": "Sequence", "name": "MainTask", "params": {}, "children": [ {"type":"action","name":"takeoff","params":{"altitude":10.0}}, {"type":"action","name":"fly_to_waypoint","params":{"x":200.0,"y":150.0,"z":10.0}}, {"type":"action","name":"land","params":{"mode":"home"}} ] } } ``` ## 四、优先级排序任务通用示例 当用户指令中明确提出有多个待考察且具有优先级关系的物体时,节点描述须为优先级关系。比如当指令为已知有三个气球,危险级关系为红色气球大于蓝色气球大于绿色气球,要求优先跟踪最危险的气球时,节点的描述参考下表情形。 | 用户指令场景 | `target_class` | `description` | 核心节点示例(search_pattern) | |-----------------------------|-----------------|-------------------------|------------------------------------------------------------------------------------------------| | 红气球>蓝气球>绿气球 | `balloon` | `(红>蓝>绿)` | `{"type":"action","name":"search_pattern","params":{"pattern_type":"grid","center_x":200,"center_y":150,"center_z":10,"radius":50,"target_class":"balloon","description":"(红>蓝>绿)"}}` | | 军用卡车>民用卡车>面包车 | `truck` | `(军用卡车>民用卡车>面包车)` | `{"type":"action","name":"object_detect","params":{"target_class":"truck","description":"(军用卡车>民用卡车>面包车)"}}` | ## 五、高频错误规避(确保验证通过) 1. 优先级排序不可修改`target_class`:如“民用卡车、面包车与军用卡车中,军用卡车优先”,`target_class`仍为`truck`,仅用`description`填排序规则; 2. 在没有明确指出物体之间的优先级关系情况下,`description`字段只描述物体属性本身,严禁与用户指令中不存在的物体进行排序; 3. `track_object`必传`track_time`:不可用`duration`替代(如跟踪30秒填`"track_time":30.0`); 4. `gps_status`的`min_satellites`必须在6-15之间(如8,不可缺省); 5. 无自定义节点:“锁定高优先级目标”需通过`object_detect`+`object_detected`实现,不可用“lock_high_risk_target”。 ## 六、新场景模式指南 (New Scenarios) ### 1. 预期场景 (Expected Scenarios) 当用户指令包含“旋转搜索”、“人工确认”等特定词汇时,请使用以下对应关系: - **"旋转搜索"** -> 使用 `rotate_search` 动作。 - **"人工确认"** -> 使用 `wait_for_confirmation` 动作(通常放在 `object_detect` 或 `object_detected` 之后)。 **示例:** "到研究所广场,寻找黄色衣服男子,我确认后再对其拍照。" ```json { "type": "Sequence", "name": "SearchAndConfirm", "children": [ {"type":"action", "name":"fly_to_waypoint", "params":{"x":20, "y":150, "z":10}}, {"type":"action", "name":"rotate_search", "params":{"center_x":20, "y":150, "z":10, "radius":30, "duration":60}}, {"type":"action", "name":"wait_for_confirmation", "params":{"message":"Found yellow shirt male, confirm to photo?", "timeout":60}}, {"type":"action", "name":"strike_target", "params":{"target_class":"person", "description":"yellow shirt"}} ] } ``` ### 2. 环绕侦察 (Circular Reconnaissance with Interrupts) 当用户要求“环绕侦察”或“巡逻中发现目标即拍照”时,必须使用 `Selector` + `SuccessIsFailure` (Decorator) + `fly_to_waypoint` 的组合模式。 **逻辑解释:** 这是一个“顺路侦察”模式。无人机在飞往下一个航点的过程中(Selector),先尝试检测目标(ReactiveWork)。如果检测到目标并拍照成功,`SuccessIsFailure` 会欺骗 Selector 说“失败了”,从而迫使 Selector 继续执行 `fly_to_waypoint`,确保无人机不会因为拍了照就停在半路,而是继续飞向终点。 **结构模板:** ```json { "name": "GoToWaypointX", "type": "Selector", "children": [ {"type": "condition", "name": "at_waypoint", "params": {"target_position": [x, y, z]}}, { "name": "ReactiveWork", "type": "Selector", "children": [ { "name": "SuccessIsFailure", "type": "decorator", "child": { "name": "DetectHoverPhoto", "type": "Sequence", "children": [ {"name": "object_detect", "type": "action", "params": {"target_class": "person"}}, {"name": "loiter", "type": "action", "params": {"time": 2.0}} ] } }, {"name": "fly_to_waypoint", "type": "action", "params": {"x": x, "y": y, "z": z}} ] } ] } ``` ## 七、输出要求 仅输出1个严格符合上述所有规则的JSON对象,**确保:1. 优先级排序逻辑正确填入`description`;2. `target_class`匹配预定义列表;3. 行为树结构不变;4. 后端解析与Schema验证无错误**,无任何冗余内容。 【强制规则】仅生成包含root的复杂行为树JSON,不得输出简单模式(不得包含mode字段或仅有action节点)。 === User Prompt === 空中待命/任务中,到研究所广场,寻找黄色衣服男子,我确认后再对其拍照。 [2026-01-02 14:10:11] 完整响应内容: [2026-01-02 14:10:11] { "root": { "type": "Sequence", "name": "SearchAndConfirm", "children": [ { "type": "action", "name": "fly_to_waypoint", "params": { "x": 20, "y": 150, "z": 10 } }, { "type": "action", "name": "rotate_search", "params": { "center_x": 20, "y": 150, "z": 10, "radius": 30, "duration": 60 } }, { "type": "action", "name": "wait_for_confirmation", "params": { "message": "Found yellow shirt male, confirm to photo?", "timeout": 60 } }, { "type": "action", "name": "strike_target", "params": { "target_class": "person", "description": "yellow shirt" } } ] }, "plan_id": "6631de0c-b13d-4367-96c1-0109896291aa", "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\":\"move_direction\",\"params\":{\"direction\":\"north/south/east/west/forward/backward/left/right\",\"distance\":\"[1,10000],缺省持续移动\"}},\n {\"name\":\"orbit_around_point\",\"params\":{\"center_x\":\"±10000\",\"center_y\":\"±10000\",\"center_z\":\"[1,5000]\",\"radius\":\"[5,1000]\",\"laps\":\"[1,20]\",\"clockwise\":\"默认true\",\"speed_mps\":\"[0.5,15]\",\"gimbal_lock\":\"默认true\"}},\n {\"name\":\"orbit_around_target\",\"params\":{\"target_class\":\"见object_detect列表\",\"description\":\"可选,目标属性\",\"radius\":\"[5,1000]\",\"laps\":\"[1,20]\",\"clockwise\":\"默认true\",\"speed_mps\":\"[0.5,15]\",\"gimbal_lock\":\"默认true\"}},\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\",\"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\":\"preflight_checks\",\"params\":{\"check_level\":\"basic/comprehensive\"}},\n {\"name\":\"emergency_return\",\"params\":{\"reason\":\"string\"}},\n {\"name\":\"rotate_search\",\"params\":{\"center_x\":\"±10000\",\"center_y\":\"±10000\",\"center_z\":\"[1,5000]\",\"radius\":\"[5,100]\",\"speed_mps\":\"[0.5,10]\",\"duration\":\"[10,600]秒\"}},\n {\"name\":\"wait_for_confirmation\",\"params\":{\"message\":\"string\",\"timeout\":\"[10,600]秒\"}}\n ],\n \"conditions\": [\n {\"name\":\"battery_above\",\"params\":{\"threshold\":\"[0.0,1.0],必传\"}},\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\"`,装饰器节点→`\"decorator\"`,控制流节点→`\"Sequence\"`/`\"Selector\"`/`\"Parallel\"`(与`name`字段值完全一致);\n2. **`name`**:必须是上述JSON中`actions`/`conditions`/`control_flow`/`decorators`下的`name`值;\n3. **`params`**:严格匹配上述节点的`params`定义,无自定义参数;\n4. **`children`**:仅控制流节点必含(子节点数组);\n5. **`child`**:仅装饰器节点必含(单个子节点对象)。\n\n\n## 三、行为树固定结构(通用不变)\n根节点通常是 `Sequence` 或 `Selector`,直接包含任务逻辑。不再强制包含 `SafetyMonitor` 或 `Parallel` 根节点。\n\n示例结构(简单顺序任务):\n```json\n{\n \"root\": {\n \"type\": \"Sequence\",\n \"name\": \"MainTask\",\n \"params\": {},\n \"children\": [\n {\"type\":\"action\",\"name\":\"takeoff\",\"params\":{\"altitude\":10.0}},\n {\"type\":\"action\",\"name\":\"fly_to_waypoint\",\"params\":{\"x\":200.0,\"y\":150.0,\"z\":10.0}},\n {\"type\":\"action\",\"name\":\"land\",\"params\":{\"mode\":\"home\"}}\n ]\n }\n}\n```\n\n\n## 四、优先级排序任务通用示例\n当用户指令中明确提出有多个待考察且具有优先级关系的物体时,节点描述须为优先级关系。比如当指令为已知有三个气球,危险级关系为红色气球大于蓝色气球大于绿色气球,要求优先跟踪最危险的气球时,节点的描述参考下表情形。\n| 用户指令场景 | `target_class` | `description` | 核心节点示例(search_pattern) |\n|-----------------------------|-----------------|-------------------------|------------------------------------------------------------------------------------------------|\n| 红气球>蓝气球>绿气球 | `balloon` | `(红>蓝>绿)` | `{\"type\":\"action\",\"name\":\"search_pattern\",\"params\":{\"pattern_type\":\"grid\",\"center_x\":200,\"center_y\":150,\"center_z\":10,\"radius\":50,\"target_class\":\"balloon\",\"description\":\"(红>蓝>绿)\"}}` |\n| 军用卡车>民用卡车>面包车 | `truck` | `(军用卡车>民用卡车>面包车)` | `{\"type\":\"action\",\"name\":\"object_detect\",\"params\":{\"target_class\":\"truck\",\"description\":\"(军用卡车>民用卡车>面包车)\"}}` |\n\n\n## 五、高频错误规避(确保验证通过)\n1. 优先级排序不可修改`target_class`:如“民用卡车、面包车与军用卡车中,军用卡车优先”,`target_class`仍为`truck`,仅用`description`填排序规则;\n2. 在没有明确指出物体之间的优先级关系情况下,`description`字段只描述物体属性本身,严禁与用户指令中不存在的物体进行排序;\n3. `track_object`必传`track_time`:不可用`duration`替代(如跟踪30秒填`\"track_time\":30.0`);\n4. `gps_status`的`min_satellites`必须在6-15之间(如8,不可缺省);\n5. 无自定义节点:“锁定高优先级目标”需通过`object_detect`+`object_detected`实现,不可用“lock_high_risk_target”。\n\n\n## 六、新场景模式指南 (New Scenarios)\n\n### 1. 预期场景 (Expected Scenarios)\n当用户指令包含“旋转搜索”、“人工确认”等特定词汇时,请使用以下对应关系:\n- **\"旋转搜索\"** -> 使用 `rotate_search` 动作。\n- **\"人工确认\"** -> 使用 `wait_for_confirmation` 动作(通常放在 `object_detect` 或 `object_detected` 之后)。\n\n**示例:** \"到研究所广场,寻找黄色衣服男子,我确认后再对其拍照。\"\n```json\n{\n \"type\": \"Sequence\",\n \"name\": \"SearchAndConfirm\",\n \"children\": [\n {\"type\":\"action\", \"name\":\"fly_to_waypoint\", \"params\":{\"x\":20, \"y\":150, \"z\":10}},\n {\"type\":\"action\", \"name\":\"rotate_search\", \"params\":{\"center_x\":20, \"y\":150, \"z\":10, \"radius\":30, \"duration\":60}},\n {\"type\":\"action\", \"name\":\"wait_for_confirmation\", \"params\":{\"message\":\"Found yellow shirt male, confirm to photo?\", \"timeout\":60}},\n {\"type\":\"action\", \"name\":\"strike_target\", \"params\":{\"target_class\":\"person\", \"description\":\"yellow shirt\"}}\n ]\n}\n```\n\n### 2. 环绕侦察 (Circular Reconnaissance with Interrupts)\n当用户要求“环绕侦察”或“巡逻中发现目标即拍照”时,必须使用 `Selector` + `SuccessIsFailure` (Decorator) + `fly_to_waypoint` 的组合模式。\n**逻辑解释:** 这是一个“顺路侦察”模式。无人机在飞往下一个航点的过程中(Selector),先尝试检测目标(ReactiveWork)。如果检测到目标并拍照成功,`SuccessIsFailure` 会欺骗 Selector 说“失败了”,从而迫使 Selector 继续执行 `fly_to_waypoint`,确保无人机不会因为拍了照就停在半路,而是继续飞向终点。\n\n**结构模板:**\n```json\n{\n \"name\": \"GoToWaypointX\",\n \"type\": \"Selector\",\n \"children\": [\n {\"type\": \"condition\", \"name\": \"at_waypoint\", \"params\": {\"target_position\": [x, y, z]}},\n {\n \"name\": \"ReactiveWork\",\n \"type\": \"Selector\",\n \"children\": [\n {\n \"name\": \"SuccessIsFailure\",\n \"type\": \"decorator\",\n \"child\": {\n \"name\": \"DetectHoverPhoto\",\n \"type\": \"Sequence\",\n \"children\": [\n {\"name\": \"object_detect\", \"type\": \"action\", \"params\": {\"target_class\": \"person\"}},\n {\"name\": \"loiter\", \"type\": \"action\", \"params\": {\"time\": 2.0}}\n ]\n }\n },\n {\"name\": \"fly_to_waypoint\", \"type\": \"action\", \"params\": {\"x\": x, \"y\": y, \"z\": z}}\n ]\n }\n ]\n}\n```\n\n\n## 七、输出要求\n仅输出1个严格符合上述所有规则的JSON对象,**确保:1. 优先级排序逻辑正确填入`description`;2. `target_class`匹配预定义列表;3. 行为树结构不变;4. 后端解析与Schema验证无错误**,无任何冗余内容。\n\n\n【强制规则】仅生成包含root的复杂行为树JSON,不得输出简单模式(不得包含mode字段或仅有action节点)。\n\n=== User Prompt ===\n空中待命/任务中,到研究所广场,寻找黄色衣服男子,我确认后再对其拍照。" } [2026-01-02 14:10:11] --- Validation Checks --- [2026-01-02 14:10:11] PASS: Response is a valid JSON object. [2026-01-02 14:10:11] PASS: Response contains a valid 'root' key. [2026-01-02 14:10:11] PASS: Response contains a valid 'visualization_url': /static/py_tree.png [2026-01-02 14:10:11] ✅ Test completed successfully [2026-01-02 14:10:11] ================================================================================ [2026-01-02 14:10:11] [2026-01-02 14:10:11] ================================================================================ [2026-01-02 14:10:11] --- API Test: Scene 3: Circular Reconnaissance (Selector Logic) --- [2026-01-02 14:10:11] URL: http://127.0.0.1:8000/generate_plan [2026-01-02 14:10:11] Sending Prompt: "执行环绕侦察任务,沿着研究所外围巡逻,如果发现人就悬停拍照。" [2026-01-02 14:10:27] ✅ Received Response: [2026-01-02 14:10:27] 📝 组织后的Prompt: [2026-01-02 14:10:27] === System Prompt === 任务:根据用户任意任务指令,生成结构化可执行的无人机行为树(Pytree)JSON。**仅输出单一JSON对象,无任何自然语言、注释或额外内容**。 ## 一、核心节点定义(格式不可修改,确保后端解析) #### 1. 可用节点定义 (必须遵守) 你必须严格从以下JSON定义的列表中选择节点构建行为树,不允许使用未定义节点: ```json { "actions": [ {"name":"takeoff","params":{"altitude":"float[1,100],默认2"}}, {"name":"land","params":{"mode":"'current'/'home'"}}, {"name":"fly_to_waypoint","params":{"x":"±10000","y":"±10000","z":"[1,5000]","acceptance_radius":"默认2.0"}}, {"name":"move_direction","params":{"direction":"north/south/east/west/forward/backward/left/right","distance":"[1,10000],缺省持续移动"}}, {"name":"orbit_around_point","params":{"center_x":"±10000","center_y":"±10000","center_z":"[1,5000]","radius":"[5,1000]","laps":"[1,20]","clockwise":"默认true","speed_mps":"[0.5,15]","gimbal_lock":"默认true"}}, {"name":"orbit_around_target","params":{"target_class":"见object_detect列表","description":"可选,目标属性","radius":"[5,1000]","laps":"[1,20]","clockwise":"默认true","speed_mps":"[0.5,15]","gimbal_lock":"默认true"}}, {"name":"loiter","params":{"duration":"[1,600]秒/until_condition:可选"}}, {"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","description":"可选,","count":"默认1"}}, {"name":"strike_target","params":{"target_class":"同object_detect","description":"可选,目标属性","count":"默认1"}}, {"name":"battle_damage_assessment","params":{"target_class":"同object_detect","assessment_time":"[5,60],默认15"}}, {"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"}}, {"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"}}, {"name":"deliver_payload","params":{"payload_type":"string","release_altitude":"[2,100]默认5"}}, {"name":"preflight_checks","params":{"check_level":"basic/comprehensive"}}, {"name":"emergency_return","params":{"reason":"string"}}, {"name":"rotate_search","params":{"center_x":"±10000","center_y":"±10000","center_z":"[1,5000]","radius":"[5,100]","speed_mps":"[0.5,10]","duration":"[10,600]秒"}}, {"name":"wait_for_confirmation","params":{"message":"string","timeout":"[10,600]秒"}} ], "conditions": [ {"name":"battery_above","params":{"threshold":"[0.0,1.0],必传"}}, {"name":"at_waypoint","params":{"x":"±10000","y":"±10000","z":"[1,5000]","tolerance":"默认3.0"}}, {"name":"object_detected","params":{"target_class":"同object_detect(必传)","description":"可选,目标属性","count":"默认1"}}, {"name":"target_destroyed","params":{"target_class":"同object_detect","description":"可选,目标属性","confidence":"[0.5,1.0]默认0.8"}}, {"name":"time_elapsed","params":{"duration":"[1,2700]秒"}}, {"name":"gps_status","params":{"min_satellites":"int[6,15],必传(如8)"}} ], "control_flow": [ {"name":"Sequence","params":{},"children":"子节点数组(按序执行,全成功则成功)"}, {"name":"Selector","params":{"memory":"默认true"},"children":"子节点数组(执行到成功为止)"}, {"name":"Parallel","params":{"policy":"all_success"},"children":"子节点数组(同时执行,严禁用'one_success')"} ], "decorators": [ {"name":"SuccessIsFailure","params":{},"child":"单个子节点(成功转失败,失败仍失败)"} ] } ``` ## 二、节点必填字段(后端Schema强制要求,缺一验证失败) 每个节点必须包含以下字段,字段名/类型不可自定义: 1. **`type`**: - 动作节点→`"action"`,条件节点→`"condition"`,装饰器节点→`"decorator"`,控制流节点→`"Sequence"`/`"Selector"`/`"Parallel"`(与`name`字段值完全一致); 2. **`name`**:必须是上述JSON中`actions`/`conditions`/`control_flow`/`decorators`下的`name`值; 3. **`params`**:严格匹配上述节点的`params`定义,无自定义参数; 4. **`children`**:仅控制流节点必含(子节点数组); 5. **`child`**:仅装饰器节点必含(单个子节点对象)。 ## 三、行为树固定结构(通用不变) 根节点通常是 `Sequence` 或 `Selector`,直接包含任务逻辑。不再强制包含 `SafetyMonitor` 或 `Parallel` 根节点。 示例结构(简单顺序任务): ```json { "root": { "type": "Sequence", "name": "MainTask", "params": {}, "children": [ {"type":"action","name":"takeoff","params":{"altitude":10.0}}, {"type":"action","name":"fly_to_waypoint","params":{"x":200.0,"y":150.0,"z":10.0}}, {"type":"action","name":"land","params":{"mode":"home"}} ] } } ``` ## 四、优先级排序任务通用示例 当用户指令中明确提出有多个待考察且具有优先级关系的物体时,节点描述须为优先级关系。比如当指令为已知有三个气球,危险级关系为红色气球大于蓝色气球大于绿色气球,要求优先跟踪最危险的气球时,节点的描述参考下表情形。 | 用户指令场景 | `target_class` | `description` | 核心节点示例(search_pattern) | |-----------------------------|-----------------|-------------------------|------------------------------------------------------------------------------------------------| | 红气球>蓝气球>绿气球 | `balloon` | `(红>蓝>绿)` | `{"type":"action","name":"search_pattern","params":{"pattern_type":"grid","center_x":200,"center_y":150,"center_z":10,"radius":50,"target_class":"balloon","description":"(红>蓝>绿)"}}` | | 军用卡车>民用卡车>面包车 | `truck` | `(军用卡车>民用卡车>面包车)` | `{"type":"action","name":"object_detect","params":{"target_class":"truck","description":"(军用卡车>民用卡车>面包车)"}}` | ## 五、高频错误规避(确保验证通过) 1. 优先级排序不可修改`target_class`:如“民用卡车、面包车与军用卡车中,军用卡车优先”,`target_class`仍为`truck`,仅用`description`填排序规则; 2. 在没有明确指出物体之间的优先级关系情况下,`description`字段只描述物体属性本身,严禁与用户指令中不存在的物体进行排序; 3. `track_object`必传`track_time`:不可用`duration`替代(如跟踪30秒填`"track_time":30.0`); 4. `gps_status`的`min_satellites`必须在6-15之间(如8,不可缺省); 5. 无自定义节点:“锁定高优先级目标”需通过`object_detect`+`object_detected`实现,不可用“lock_high_risk_target”。 ## 六、新场景模式指南 (New Scenarios) ### 1. 预期场景 (Expected Scenarios) 当用户指令包含“旋转搜索”、“人工确认”等特定词汇时,请使用以下对应关系: - **"旋转搜索"** -> 使用 `rotate_search` 动作。 - **"人工确认"** -> 使用 `wait_for_confirmation` 动作(通常放在 `object_detect` 或 `object_detected` 之后)。 **示例:** "到研究所广场,寻找黄色衣服男子,我确认后再对其拍照。" ```json { "type": "Sequence", "name": "SearchAndConfirm", "children": [ {"type":"action", "name":"fly_to_waypoint", "params":{"x":20, "y":150, "z":10}}, {"type":"action", "name":"rotate_search", "params":{"center_x":20, "y":150, "z":10, "radius":30, "duration":60}}, {"type":"action", "name":"wait_for_confirmation", "params":{"message":"Found yellow shirt male, confirm to photo?", "timeout":60}}, {"type":"action", "name":"strike_target", "params":{"target_class":"person", "description":"yellow shirt"}} ] } ``` ### 2. 环绕侦察 (Circular Reconnaissance with Interrupts) 当用户要求“环绕侦察”或“巡逻中发现目标即拍照”时,必须使用 `Selector` + `SuccessIsFailure` (Decorator) + `fly_to_waypoint` 的组合模式。 **逻辑解释:** 这是一个“顺路侦察”模式。无人机在飞往下一个航点的过程中(Selector),先尝试检测目标(ReactiveWork)。如果检测到目标并拍照成功,`SuccessIsFailure` 会欺骗 Selector 说“失败了”,从而迫使 Selector 继续执行 `fly_to_waypoint`,确保无人机不会因为拍了照就停在半路,而是继续飞向终点。 **结构模板:** ```json { "name": "GoToWaypointX", "type": "Selector", "children": [ {"type": "condition", "name": "at_waypoint", "params": {"target_position": [x, y, z]}}, { "name": "ReactiveWork", "type": "Selector", "children": [ { "name": "SuccessIsFailure", "type": "decorator", "child": { "name": "DetectHoverPhoto", "type": "Sequence", "children": [ {"name": "object_detect", "type": "action", "params": {"target_class": "person"}}, {"name": "loiter", "type": "action", "params": {"time": 2.0}} ] } }, {"name": "fly_to_waypoint", "type": "action", "params": {"x": x, "y": y, "z": z}} ] } ] } ``` ## 七、输出要求 仅输出1个严格符合上述所有规则的JSON对象,**确保:1. 优先级排序逻辑正确填入`description`;2. `target_class`匹配预定义列表;3. 行为树结构不变;4. 后端解析与Schema验证无错误**,无任何冗余内容。 【强制规则】仅生成包含root的复杂行为树JSON,不得输出简单模式(不得包含mode字段或仅有action节点)。 === User Prompt === 执行环绕侦察任务,沿着研究所外围巡逻,如果发现人就悬停拍照。 [2026-01-02 14:10:27] 完整响应内容: [2026-01-02 14:10:27] { "root": { "type": "Selector", "name": "CircumferentialReconnaissance", "children": [ { "type": "decorator", "name": "SuccessIsFailure", "child": { "type": "Sequence", "name": "DetectAndPhoto", "children": [ { "type": "action", "name": "object_detect", "params": { "target_class": "person", "description": "(优先级:人)" } }, { "type": "action", "name": "loiter", "params": { "time": 2.0 } } ] } }, { "type": "action", "name": "orbit_around_point", "params": { "center_x": 200, "center_y": 150, "center_z": 10, "radius": 50, "laps": 2, "clockwise": true, "speed_mps": 5.0, "gimbal_lock": true } } ] }, "plan_id": "46a55010-9707-4972-8563-08d332917dbc", "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\":\"move_direction\",\"params\":{\"direction\":\"north/south/east/west/forward/backward/left/right\",\"distance\":\"[1,10000],缺省持续移动\"}},\n {\"name\":\"orbit_around_point\",\"params\":{\"center_x\":\"±10000\",\"center_y\":\"±10000\",\"center_z\":\"[1,5000]\",\"radius\":\"[5,1000]\",\"laps\":\"[1,20]\",\"clockwise\":\"默认true\",\"speed_mps\":\"[0.5,15]\",\"gimbal_lock\":\"默认true\"}},\n {\"name\":\"orbit_around_target\",\"params\":{\"target_class\":\"见object_detect列表\",\"description\":\"可选,目标属性\",\"radius\":\"[5,1000]\",\"laps\":\"[1,20]\",\"clockwise\":\"默认true\",\"speed_mps\":\"[0.5,15]\",\"gimbal_lock\":\"默认true\"}},\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\",\"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\":\"preflight_checks\",\"params\":{\"check_level\":\"basic/comprehensive\"}},\n {\"name\":\"emergency_return\",\"params\":{\"reason\":\"string\"}},\n {\"name\":\"rotate_search\",\"params\":{\"center_x\":\"±10000\",\"center_y\":\"±10000\",\"center_z\":\"[1,5000]\",\"radius\":\"[5,100]\",\"speed_mps\":\"[0.5,10]\",\"duration\":\"[10,600]秒\"}},\n {\"name\":\"wait_for_confirmation\",\"params\":{\"message\":\"string\",\"timeout\":\"[10,600]秒\"}}\n ],\n \"conditions\": [\n {\"name\":\"battery_above\",\"params\":{\"threshold\":\"[0.0,1.0],必传\"}},\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\"`,装饰器节点→`\"decorator\"`,控制流节点→`\"Sequence\"`/`\"Selector\"`/`\"Parallel\"`(与`name`字段值完全一致);\n2. **`name`**:必须是上述JSON中`actions`/`conditions`/`control_flow`/`decorators`下的`name`值;\n3. **`params`**:严格匹配上述节点的`params`定义,无自定义参数;\n4. **`children`**:仅控制流节点必含(子节点数组);\n5. **`child`**:仅装饰器节点必含(单个子节点对象)。\n\n\n## 三、行为树固定结构(通用不变)\n根节点通常是 `Sequence` 或 `Selector`,直接包含任务逻辑。不再强制包含 `SafetyMonitor` 或 `Parallel` 根节点。\n\n示例结构(简单顺序任务):\n```json\n{\n \"root\": {\n \"type\": \"Sequence\",\n \"name\": \"MainTask\",\n \"params\": {},\n \"children\": [\n {\"type\":\"action\",\"name\":\"takeoff\",\"params\":{\"altitude\":10.0}},\n {\"type\":\"action\",\"name\":\"fly_to_waypoint\",\"params\":{\"x\":200.0,\"y\":150.0,\"z\":10.0}},\n {\"type\":\"action\",\"name\":\"land\",\"params\":{\"mode\":\"home\"}}\n ]\n }\n}\n```\n\n\n## 四、优先级排序任务通用示例\n当用户指令中明确提出有多个待考察且具有优先级关系的物体时,节点描述须为优先级关系。比如当指令为已知有三个气球,危险级关系为红色气球大于蓝色气球大于绿色气球,要求优先跟踪最危险的气球时,节点的描述参考下表情形。\n| 用户指令场景 | `target_class` | `description` | 核心节点示例(search_pattern) |\n|-----------------------------|-----------------|-------------------------|------------------------------------------------------------------------------------------------|\n| 红气球>蓝气球>绿气球 | `balloon` | `(红>蓝>绿)` | `{\"type\":\"action\",\"name\":\"search_pattern\",\"params\":{\"pattern_type\":\"grid\",\"center_x\":200,\"center_y\":150,\"center_z\":10,\"radius\":50,\"target_class\":\"balloon\",\"description\":\"(红>蓝>绿)\"}}` |\n| 军用卡车>民用卡车>面包车 | `truck` | `(军用卡车>民用卡车>面包车)` | `{\"type\":\"action\",\"name\":\"object_detect\",\"params\":{\"target_class\":\"truck\",\"description\":\"(军用卡车>民用卡车>面包车)\"}}` |\n\n\n## 五、高频错误规避(确保验证通过)\n1. 优先级排序不可修改`target_class`:如“民用卡车、面包车与军用卡车中,军用卡车优先”,`target_class`仍为`truck`,仅用`description`填排序规则;\n2. 在没有明确指出物体之间的优先级关系情况下,`description`字段只描述物体属性本身,严禁与用户指令中不存在的物体进行排序;\n3. `track_object`必传`track_time`:不可用`duration`替代(如跟踪30秒填`\"track_time\":30.0`);\n4. `gps_status`的`min_satellites`必须在6-15之间(如8,不可缺省);\n5. 无自定义节点:“锁定高优先级目标”需通过`object_detect`+`object_detected`实现,不可用“lock_high_risk_target”。\n\n\n## 六、新场景模式指南 (New Scenarios)\n\n### 1. 预期场景 (Expected Scenarios)\n当用户指令包含“旋转搜索”、“人工确认”等特定词汇时,请使用以下对应关系:\n- **\"旋转搜索\"** -> 使用 `rotate_search` 动作。\n- **\"人工确认\"** -> 使用 `wait_for_confirmation` 动作(通常放在 `object_detect` 或 `object_detected` 之后)。\n\n**示例:** \"到研究所广场,寻找黄色衣服男子,我确认后再对其拍照。\"\n```json\n{\n \"type\": \"Sequence\",\n \"name\": \"SearchAndConfirm\",\n \"children\": [\n {\"type\":\"action\", \"name\":\"fly_to_waypoint\", \"params\":{\"x\":20, \"y\":150, \"z\":10}},\n {\"type\":\"action\", \"name\":\"rotate_search\", \"params\":{\"center_x\":20, \"y\":150, \"z\":10, \"radius\":30, \"duration\":60}},\n {\"type\":\"action\", \"name\":\"wait_for_confirmation\", \"params\":{\"message\":\"Found yellow shirt male, confirm to photo?\", \"timeout\":60}},\n {\"type\":\"action\", \"name\":\"strike_target\", \"params\":{\"target_class\":\"person\", \"description\":\"yellow shirt\"}}\n ]\n}\n```\n\n### 2. 环绕侦察 (Circular Reconnaissance with Interrupts)\n当用户要求“环绕侦察”或“巡逻中发现目标即拍照”时,必须使用 `Selector` + `SuccessIsFailure` (Decorator) + `fly_to_waypoint` 的组合模式。\n**逻辑解释:** 这是一个“顺路侦察”模式。无人机在飞往下一个航点的过程中(Selector),先尝试检测目标(ReactiveWork)。如果检测到目标并拍照成功,`SuccessIsFailure` 会欺骗 Selector 说“失败了”,从而迫使 Selector 继续执行 `fly_to_waypoint`,确保无人机不会因为拍了照就停在半路,而是继续飞向终点。\n\n**结构模板:**\n```json\n{\n \"name\": \"GoToWaypointX\",\n \"type\": \"Selector\",\n \"children\": [\n {\"type\": \"condition\", \"name\": \"at_waypoint\", \"params\": {\"target_position\": [x, y, z]}},\n {\n \"name\": \"ReactiveWork\",\n \"type\": \"Selector\",\n \"children\": [\n {\n \"name\": \"SuccessIsFailure\",\n \"type\": \"decorator\",\n \"child\": {\n \"name\": \"DetectHoverPhoto\",\n \"type\": \"Sequence\",\n \"children\": [\n {\"name\": \"object_detect\", \"type\": \"action\", \"params\": {\"target_class\": \"person\"}},\n {\"name\": \"loiter\", \"type\": \"action\", \"params\": {\"time\": 2.0}}\n ]\n }\n },\n {\"name\": \"fly_to_waypoint\", \"type\": \"action\", \"params\": {\"x\": x, \"y\": y, \"z\": z}}\n ]\n }\n ]\n}\n```\n\n\n## 七、输出要求\n仅输出1个严格符合上述所有规则的JSON对象,**确保:1. 优先级排序逻辑正确填入`description`;2. `target_class`匹配预定义列表;3. 行为树结构不变;4. 后端解析与Schema验证无错误**,无任何冗余内容。\n\n\n【强制规则】仅生成包含root的复杂行为树JSON,不得输出简单模式(不得包含mode字段或仅有action节点)。\n\n=== User Prompt ===\n执行环绕侦察任务,沿着研究所外围巡逻,如果发现人就悬停拍照。" } [2026-01-02 14:10:27] --- Validation Checks --- [2026-01-02 14:10:27] PASS: Response is a valid JSON object. [2026-01-02 14:10:27] PASS: Response contains a valid 'root' key. [2026-01-02 14:10:27] PASS: Response contains a valid 'visualization_url': /static/py_tree.png [2026-01-02 14:10:27] ✅ Test completed successfully [2026-01-02 14:10:27] ================================================================================ [2026-01-02 14:10:27]