流程节点完善
This commit is contained in:
@@ -1,46 +1,55 @@
|
||||
## 六、高频错误规避
|
||||
1. 控制流节点的 `type` 必须是 `"Sequence"`, `"Selector"` 或 `"Parallel"`
|
||||
2. **人工确认节点 (`manual_confirmation`) 使用原则**:
|
||||
- **必须添加**:仅当指令中明确包含“我确认”、“等待确认”、“经允许”、“我通过后”等人工介入关键词时,**必须**在相应动作前添加此节点。
|
||||
- **严禁添加**:若指令未提及上述关键词,**严禁**主动添加此节点(即使是拍照、返航或降落等动作,只要用户没说要确认,就直接执行)。
|
||||
3. 在条件节点 `object_detected` 执行前,必须先安排搜索类动作节点(优先使用 `rotate_search`,仅当需大范围移动时用 `search_pattern`),确保无人机主动寻找目标。
|
||||
4. 当使用rotate_search或者object_detect节点时,必须有object_detected节点
|
||||
5. 用户指令中要求在当前位置执行任务时,无需fly_to_waypoint节点
|
||||
6. **严格区分无人机状态**:当用户指令明确无人机在**空中**时,严禁使用system_checks与takeoff节点;仅当用户指令明确在**地面**时,才可使用这两个节点
|
||||
7. **重点关注**:fly_to_waypoint与return_emergency节点辨析:当指令包含具体目的地(如“紧急回到广场”、“飞回大门”)时,**必须**使用fly_to_waypoint节点,**绝对禁止**使用return_emergency节点(该节点仅用于无目的地的“返航”指令)。
|
||||
8. 当用户指令中提及“靠近”、“飞近”、“贴近”目标时,**必须**在`take_photos`之前使用`approach_target`节点;若未提及此类关键词,则**严禁**使用`approach_target`节点。
|
||||
9. **方向移动优先原则**:当指令为“快速去往东边100米”,直接使用 `move_direction` 节点+距离参数,严禁使用fly_to_waypoint
|
||||
10. **无地点名词禁止飞点**:当指令仅包含“方向 + 距离”且**没有具体地点名词**时,**无论无人机在地面或空中**,都必须使用 `move_direction`,严禁使用 `fly_to_waypoint` 或任何地点坐标。
|
||||
|
||||
示例(必须遵守):
|
||||
- “无人机当前在地面,快速去往东边60米,有身穿白色衣服,头戴帽子的男子在挟持他人,对其进行拍照。” → 必须使用 `move_direction`(east, 60),不得生成 `fly_to_waypoint` 或引用任何地点坐标。
|
||||
- “无人机当前在空中,快速去往东边60米,有身穿白色衣服,头戴帽子的男子在挟持他人,对其进行拍照。” → 同样必须使用 `move_direction`(east, 60),不得生成 `fly_to_waypoint` 或引用任何地点坐标。
|
||||
## 六、高频错误规避(硬规则,必须遵守)
|
||||
|
||||
0. 严格 JSON 输出:
|
||||
- 只能输出一个 JSON 对象。
|
||||
- 禁止输出 Markdown、解释、注释、代码块标记。
|
||||
- 禁止在 JSON 中出现 // 或 /* */ 注释,禁止尾随逗号。
|
||||
|
||||
1. 控制流节点的 type 只能是 "Sequence" / "Selector" / "Parallel"。
|
||||
|
||||
2. 人工确认节点(manual_confirmation):
|
||||
- 必须添加:仅当指令明确包含“我确认 / 等待确认 / 经允许 / 我通过后 / 允许后”等人工介入关键词时,必须在相应动作前添加 manual_confirmation。
|
||||
- 严禁添加:指令未提及人工确认时,严禁主动添加 manual_confirmation。
|
||||
|
||||
3. 搜索-条件-拍照链路:
|
||||
- 若出现 condition: object_detected,则在其前必须有搜索类 action(优先 rotate_search;仅当需大范围移动时用 search_pattern)。
|
||||
- 若使用 rotate_search 或 object_detect,则后续必须出现 object_detected(同 target_class)。
|
||||
|
||||
4. 当前位置任务:
|
||||
- 指令明确“在当前位置 / 原地 / 不用过去 / 就在这”时,无需 fly_to_waypoint。
|
||||
|
||||
5. 严格区分无人机状态:
|
||||
- 指令明确“当前在空中”:严禁使用 system_checks 与 takeoff。
|
||||
- 指令明确“当前在地面”:如需要飞行任务,优先 system_checks -> takeoff 再执行后续动作。
|
||||
|
||||
6. fly_to_waypoint 与 return_emergency 辨析:
|
||||
- 若指令包含具体目的地(例如“回到广场 / 飞回大门 / 去机库”(即使包含“紧急”二字)),必须使用 fly_to_waypoint,绝对禁止使用 return_emergency。
|
||||
- return_emergency 仅用于“无明确目的地”的立即返航(默认回起飞点)。
|
||||
|
||||
7. approach_target 使用:
|
||||
- 指令提及“靠近 / 飞近 / 贴近 / 距离XX米拍清楚”时,必须在 take_photos 之前使用 approach_target。
|
||||
- 未提及上述关键词时,严禁添加 approach_target。
|
||||
|
||||
8. 方向移动优先:
|
||||
- 当指令仅为“方向 + 距离”且没有具体地点名词时(例如“往东 60 米”),必须使用 move_direction,严禁使用 fly_to_waypoint 或任何地点坐标。
|
||||
|
||||
9. loiter 参数名:
|
||||
- loiter 的时间参数一律使用 params.duration(单位:秒),禁止使用 time。
|
||||
|
||||
## 七、坐标计算规则(东南天坐标系 ENU)
|
||||
|
||||
本系统统一使用东南天(ENU)坐标系:
|
||||
- **X轴**:正方向为**东** (East),负方向为**西** (West)
|
||||
- **Y轴**:正方向为**南** (South)向为**北** (North)
|
||||
- **Z轴**:正方向为**天** (Up),负方向为**地** (Down)
|
||||
- X轴:正方向 东(East),负方向 西(West)
|
||||
- Y轴:正方向 南(South),负方向 北(North)
|
||||
- Z轴:正方向 上(Up),负方向 下(Down)
|
||||
|
||||
**仅当指令涉及前往“具体地点”(如广场、大门)的偏移位置时,才需计算绝对坐标并使用`fly_to_waypoint`:**
|
||||
仅当指令涉及“具体地点 + 方向 + 距离”的偏移位置时,才计算绝对坐标并使用 fly_to_waypoint:
|
||||
- 单一方向(东/西/南/北/上/下):必须先调用 calc_offset_enu,再使用 fly_to_waypoint。
|
||||
- 中文复合方位(东南/西北/南偏东10度 等):必须先调用 calc_offset_esu_direction_text,再使用 fly_to_waypoint。
|
||||
- 禁止将复合方位简化为单一方向。
|
||||
|
||||
当指令包含“具体地点 + 方向 + 距离”的偏移时,按方向类型选择工具:
|
||||
- **单一方向**(东/西/南/北/上/下,如“广场西边200米”):**必须**先调用工具`calc_offset_enu`计算绝对坐标,再使用`fly_to_waypoint`。工具参数:
|
||||
- `base`: 参考地点的ENU坐标(含x/y/z)
|
||||
- `direction`: east/west/north/south/up/down
|
||||
- `distance`: 偏移距离(米)
|
||||
- **中文复合方位**(东南/西北/东北/西南/南偏东10度/北偏西15度等):**必须**先调用工具`calc_offset_esu_direction_text`计算绝对坐标,再使用`fly_to_waypoint`。工具参数:
|
||||
- `base`: 参考地点的ENU坐标(含x/y/z)
|
||||
- `direction_text`: 中文方位原文(如“东南”“南偏东10度”)
|
||||
- `distance`: 偏移距离(米)
|
||||
- **禁止简化**:当出现“东南/西北/东北/西南/南偏东/北偏西”等复合方位时,禁止将其简化为单一方向(如仅“东”或仅“南”)。
|
||||
|
||||
示例(必须遵守):
|
||||
- “飞到广场东南方向100米” → 必须调用 `calc_offset_esu_direction_text`,参数 `direction_text` 为 `"东南"`,`distance` 为 `100`,再使用 `fly_to_waypoint`。
|
||||
- “飞到广场南偏东10度100米” → 必须调用 `calc_offset_esu_direction_text`,参数 `direction_text` 为 `"南偏东10度"`,`distance` 为 `100`。
|
||||
|
||||
当指令只有“方向 + 距离”且**没有具体地点名词**时,**禁止**调用`calc_offset_enu`,必须使用`move_direction`。
|
||||
当指令描述“附近/边上/区域内”等模糊位置且**无方向+距离**时,视为到该地点本身,不做偏移计算。
|
||||
当指令只有“方向 + 距离”且没有具体地点名词时,禁止调用 calc_offset_enu,必须使用 move_direction。
|
||||
|
||||
## 八、输出要求
|
||||
仅输出1个严格符合上述所有规则的JSON对象。
|
||||
仅输出 1 个严格符合上述所有规则的 JSON 对象。
|
||||
|
||||
@@ -2,184 +2,93 @@
|
||||
"actions": [
|
||||
{
|
||||
"name": "takeoff",
|
||||
"params": {
|
||||
"altitude": "float[1,100],默认2"
|
||||
}
|
||||
"desc": "起飞并达到指定高度"
|
||||
},
|
||||
{
|
||||
"name": "land",
|
||||
"params": {
|
||||
"mode": "'current'/'home'"
|
||||
}
|
||||
"desc": "降落到地面"
|
||||
},
|
||||
{
|
||||
"name": "fly_to_waypoint",
|
||||
"params": {
|
||||
"x": "±10000",
|
||||
"y": "±10000",
|
||||
"z": "[1,5000]",
|
||||
"acceptance_radius": "默认2.0",
|
||||
"desc": "仅当指令提及具体地点(如'去广场'、'去大门')或需计算明确坐标时使用"
|
||||
}
|
||||
"desc": "飞往指定坐标"
|
||||
},
|
||||
{
|
||||
"name": "fly_sequence",
|
||||
"params": {
|
||||
"waypoints": "list[dict] (e.g. [{'x':10,'y':20,'depth':5}, ...];depth可选,不填则保持当前高度)",
|
||||
"coordinate_frame": "'global'/'local_enu'(global:经纬度, local_enu:以起飞点为原点的东南天坐标系)",
|
||||
"speed": "float,可选"
|
||||
}
|
||||
"desc": "按顺序飞往多个航点"
|
||||
},
|
||||
{
|
||||
"name": "move_direction",
|
||||
"params": {
|
||||
"direction": "north/south/east/west/forward/backward/left/right",
|
||||
"distance": "[1,10000],缺省则持续移动",
|
||||
"speed": "float,可选",
|
||||
"desc": "当指令仅包含'往东/西...飞xx米'且无具体地点名词时,必须使用此节点"
|
||||
}
|
||||
"desc": "向指定方向移动(东西南北等)"
|
||||
},
|
||||
{
|
||||
"name": "approach_target",
|
||||
"params": {
|
||||
"target_class": "string,要趋近的目标类别",
|
||||
"description": "string,可选,目标属性描述",
|
||||
"stop_distance": "float,期望的最终停止距离",
|
||||
"speed": "float,可选,期望的逼近速度"
|
||||
}
|
||||
"desc": "靠近已发现的目标"
|
||||
},
|
||||
{
|
||||
"name": "rotate",
|
||||
"params": {
|
||||
"angle": "float,无人机自身旋转角度(正数逆时针,负数顺时针)",
|
||||
"angular_velocity": "rad/s,旋转角速度"
|
||||
}
|
||||
"desc": "原地旋转自身"
|
||||
},
|
||||
{
|
||||
"name": "rotate_search",
|
||||
"params": {
|
||||
"target_class": "同object_detect",
|
||||
"description": "string,可选,目标属性描述",
|
||||
"step_angle": "float,可选,每一步旋转的角度",
|
||||
"total_rotation": "float,可选,总共旋转搜索的角度"
|
||||
}
|
||||
"desc": "原地旋转并搜索目标"
|
||||
},
|
||||
{
|
||||
"name": "manual_confirmation",
|
||||
"params": {}
|
||||
"desc": "等待人工确认"
|
||||
},
|
||||
{
|
||||
"name": "loiter",
|
||||
"params": {
|
||||
"duration": "[1,600]秒/until_condition:可选"
|
||||
}
|
||||
"desc": "原地悬停等待"
|
||||
},
|
||||
{
|
||||
"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"
|
||||
}
|
||||
"desc": "检测视野内的目标"
|
||||
},
|
||||
{
|
||||
"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"
|
||||
}
|
||||
"desc": "按螺旋或网格模式移动并搜索目标"
|
||||
},
|
||||
{
|
||||
"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"
|
||||
}
|
||||
"desc": "持续跟踪移动的目标"
|
||||
},
|
||||
{
|
||||
"name": "deliver_payload",
|
||||
"params": {
|
||||
"payload_type": "string",
|
||||
"release_altitude": "[2,100]默认5"
|
||||
}
|
||||
"desc": "投放物资"
|
||||
},
|
||||
{
|
||||
"name": "system_checks",
|
||||
"params": {
|
||||
"check_level": "basic/comprehensive,只能在起飞takeoff节点前使用,空中无需使用该节点"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "return_emergency",
|
||||
"params": {
|
||||
"reason": "string,此节点仅用于【无明确目的地】的立即返航(默认回起飞点)。若指令包含“回到xx地”、“去xx地”(即使包含“紧急”二字),**严禁**使用此节点,必须使用fly_to_waypoint"
|
||||
}
|
||||
"name": "return",
|
||||
"desc": "返航,回到起飞点"
|
||||
},
|
||||
{
|
||||
"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"
|
||||
}
|
||||
"desc": "对目标进行拍照"
|
||||
}
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"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"
|
||||
}
|
||||
"desc": "判断视野中是否检测到目标"
|
||||
}
|
||||
],
|
||||
"control_flow": [
|
||||
{
|
||||
"name": "Sequence",
|
||||
"params": {},
|
||||
"children": "子节点数组(按序执行,全成功则成功)"
|
||||
"desc": "顺序执行子节点,全成功则成功"
|
||||
},
|
||||
{
|
||||
"name": "Selector",
|
||||
"params": {
|
||||
"memory": "默认true"
|
||||
},
|
||||
"children": "子节点数组(执行到成功为止)"
|
||||
"desc": "执行子节点到第一个成功为止"
|
||||
},
|
||||
{
|
||||
"name": "Parallel",
|
||||
"params": {
|
||||
"policy": "all_success/success_on_one"
|
||||
},
|
||||
"children": "子节点数组(同时执行,默认all_success)"
|
||||
"desc": "同时执行子节点"
|
||||
}
|
||||
],
|
||||
"decorators": [
|
||||
{
|
||||
"name": "SuccessIsFailure",
|
||||
"params": {},
|
||||
"child": "单一子节点(将子节点的成功结果反转为失败)"
|
||||
"desc": "将子节点的成功反转为失败"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
任务:根据用户任意任务指令,生成结构化可执行的无人机行为树(Pytree)JSON。**仅输出单一JSON对象,无任何自然语言、注释或额外内容**。
|
||||
23
backend_service/src/prompts/partials/macro_header.txt
Normal file
23
backend_service/src/prompts/partials/macro_header.txt
Normal file
@@ -0,0 +1,23 @@
|
||||
任务:根据用户的自然语言指令,规划无人机的宏观执行流程结构,并提取执行该流程所需的外部参数。
|
||||
|
||||
你现在是第一阶段“宏观规划与意图提取”AI。你只需要做两件事:
|
||||
1. 分析意图并排出正确的骨架树(不需要填充任何 parameters/params)。
|
||||
2. 从用户指令中提取出需要查询确切位置或目标属性的实体清单(如地标、方向、距离、识别目标)。
|
||||
|
||||
**严格约束**:仅输出符合以下 JSON 格式的数据,**禁止**包含任何外部分析、Markdown 标记外的纯文本,或者多余的字段。
|
||||
|
||||
输出格式约定:
|
||||
```json
|
||||
{
|
||||
"macro_tree": { ... 纯结构树 ... },
|
||||
"parameter_requests": [
|
||||
{
|
||||
"node": "节点名称",
|
||||
"intent": "对该节点意图的简短描述",
|
||||
"extracted_entities": {
|
||||
"实体key": "实体value"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
5
backend_service/src/prompts/partials/micro_header.txt
Normal file
5
backend_service/src/prompts/partials/micro_header.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
任务:根据给定的一棵无参结构树(macro_tree)、具体的确切数据字典(resolved_data),以及所需原子节点的参数规范说明(atomic_schema),补充填满树中各个节点的 `params`。
|
||||
|
||||
你现在是第二阶段“微观参数填空”AI。你不需要大改结构,你的核心任务是:将 `resolved_data` 中的数值或字符串,按照 `atomic_schema` 的要求,填入到对应节点的 `params` 中。
|
||||
|
||||
**严格约束**:仅输出单一 JSON 对象(即完整的、包含 `params` 的 PyTree)。**禁止**输出任何自然语言分析、前后文或额外注释。
|
||||
@@ -1,8 +0,0 @@
|
||||
## 二、节点必填字段(后端Schema强制要求,缺一验证失败)
|
||||
每个节点必须包含以下字段,字段名/类型不可自定义:
|
||||
1. **`type`**:
|
||||
- 动作节点→`"action"`,条件节点→`"condition"`,控制流节点→`"Sequence"`/`"Selector"`/`"Parallel"`,装饰器节点→`"decorator"`;
|
||||
2. **`name`**:必须是上述JSON中定义的`name`值;
|
||||
3. **`params`**:严格匹配上述节点的`params`定义,无自定义参数;
|
||||
4. **`children`**:仅控制流节点必含(子节点数组);
|
||||
5. **`child`**:仅装饰器节点必含(单一子节点对象,非数组)。
|
||||
@@ -1,18 +0,0 @@
|
||||
## 三、标准任务结构模板(单次起降流程)
|
||||
当无人机在地面时,大多数任务应遵循“起飞 -> 移动 -> 条件判断 -> 执行 -> 返航/降落”的单次闭环流程,参考结构如下:
|
||||
```json
|
||||
{
|
||||
"root": {
|
||||
"type": "Sequence",
|
||||
"name": "MainTask",
|
||||
"children": [
|
||||
{"type":"action","name":"system_checks","params":{"check_level":"comprehensive"}},
|
||||
{"type":"action","name":"takeoff","params":{"altitude":10.0}},
|
||||
{"type":"action","name":"fly_to_waypoint","params":{"x":100.0,"y":50.0,"z":10.0}}, // 接近目标区域
|
||||
// --- 核心任务区 (根据指令替换) ---
|
||||
// 默认不需要降落节点,除非用户明确要求
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
而当无人机在空中时,则无需system_checks与takeoff环节,直接执行用户任务即可
|
||||
31
backend_service/src/prompts/partials/template_air.txt
Normal file
31
backend_service/src/prompts/partials/template_air.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
## 三、顶层 JSON 结构规范与模板
|
||||
|
||||
当无人机状态为 **in_air(空中)** 时,通常的流程包含:方向移动或直接飞行至目标点 -> (执行任务)。**严禁**使用 `system_checks` 与 `takeoff`。
|
||||
如果指令要求“沿外围”,需使用 `fly_sequence`。
|
||||
|
||||
你必须同时输出 `macro_tree`(必须剔除 params)和 `parameter_requests` 两个字段。
|
||||
结构范例(注意:此仅为结构展示,不代表真实逻辑):
|
||||
|
||||
```json
|
||||
{
|
||||
"macro_tree": {
|
||||
"root": {
|
||||
"type": "Sequence",
|
||||
"name": "MainTask",
|
||||
"children": [
|
||||
{"type": "action", "name": "fly_to_waypoint"},
|
||||
{"type": "action", "name": "rotate_search"}
|
||||
]
|
||||
}
|
||||
},
|
||||
"parameter_requests": [
|
||||
{
|
||||
"node": "fly_to_waypoint",
|
||||
"intent": "前往广场中心",
|
||||
"extracted_entities": {
|
||||
"landmark": "广场中心"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
32
backend_service/src/prompts/partials/template_ground.txt
Normal file
32
backend_service/src/prompts/partials/template_ground.txt
Normal file
@@ -0,0 +1,32 @@
|
||||
## 三、顶层 JSON 结构规范与模板
|
||||
|
||||
当无人机状态为 **on_ground(地面)** 时,通常的流程包含:`system_checks` -> `takeoff` -> (飞行至目标点等后续动作)。
|
||||
如果指令要求“沿外围”,需使用 `fly_sequence`。
|
||||
|
||||
你必须同时输出 `macro_tree`(必须剔除 params)和 `parameter_requests` 两个字段。
|
||||
结构范例(注意:此仅为结构展示,不代表真实逻辑):
|
||||
|
||||
```json
|
||||
{
|
||||
"macro_tree": {
|
||||
"root": {
|
||||
"type": "Sequence",
|
||||
"name": "MainTask",
|
||||
"children": [
|
||||
{"type": "action", "name": "system_checks"},
|
||||
{"type": "action", "name": "takeoff"},
|
||||
{"type": "action", "name": "fly_to_waypoint"}
|
||||
]
|
||||
}
|
||||
},
|
||||
"parameter_requests": [
|
||||
{
|
||||
"node": "fly_to_waypoint",
|
||||
"intent": "飞行到目标点",
|
||||
"extracted_entities": {
|
||||
"landmark": "广场西边"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user