针对场景4进行修改

This commit is contained in:
2026-01-16 16:05:52 +08:00
parent fb473dcf1a
commit 5d1c02fb5b
602 changed files with 15130 additions and 3169 deletions

View File

@@ -1,8 +1,8 @@
你是一个严格的任务分类器。只输出一个JSON对象不要输出解释或多余文本。
根据用户指令与下述可用节点定义,判断其为“简单”或“复杂”。
- 简单:单一原子动作即可完成(例如"起飞""飞机自检""移动到某地(已给定坐标)""对着某点环绕XY圈如'对着学生宿舍环绕三十两圈'"等),且无需行为树。
- 复杂:需要多步流程、搜索/检测/跟踪/评估、战损确认、或需要模板化任务结构。
- 简单:单一动作节点即可完成(例如"起飞""飞机自检""移动到某地(已给定坐标)"等),且无需行为树。
- 复杂:需要两个动作及以上、多步流程、搜索/检测/跟踪/评估、战损确认、或需要模板化任务结构。
输出格式(严格遵守):
{"mode":"simple"} 或 {"mode":"complex"}
@@ -11,14 +11,43 @@
```json
{
"actions": [
{"name": "takeoff"}, {"name": "land"}, {"name": "fly_to_waypoint"}, {"name": "move_direction"}, {"name": "orbit_around_point"}, {"name": "orbit_around_target"}, {"name": "loiter"},
{"name": "object_detect"}, {"name": "strike_target"}, {"name": "battle_damage_assessment"},
{"name": "search_pattern"}, {"name": "track_object"}, {"name": "deliver_payload"},
{"name": "preflight_checks"}, {"name": "take_picture"}
{"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":"fly_sequence","params":{"waypoints":"list[dict] (e.g. [{'x':10,'y':20,'z':5}, ...])","coordinate_frame":"'global'/'local_enu'global:经纬度, local_enu:以起飞点为原点的东北天坐标系)","speed":"float,可选"}},
{"name":"move_direction","params":{"direction":"north/south/east/west/forward/backward/left/right","distance":"[1,10000],缺省持续移动","speed":"float,可选"}},
{"name":"approach_target","params":{"target_class":"string,要趋近的目标类别","description":"string,可选,目标属性描述","stop_distance":"float,期望的最终停止距离","speed":"float,可选,期望的逼近速度"}},
{"name":"rotate","params":{"angle":"float,无人机自身旋转角度(正数逆时针,负数顺时针)","angular_velocity":"rad/s,旋转角速度"}},
{"name":"rotate_search","params":{"target_class":"string,要搜寻的目标类别","description":"string,可选,目标属性描述","step_angle":"float,可选,每一步旋转的角度","total_rotation":"float,可选,总共旋转搜索的角度"}},
{"name":"manual_confirmation","params":{}},
{"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,garbage","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":"system_checks","params":{"check_level":"basic/comprehensive"}},
{"name":"emergency_return","params":{"reason":"string"}},
{"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"}}
],
"conditions": [
{"name": "at_waypoint"}, {"name": "object_detected"},
{"name": "target_destroyed"}, {"name": "time_elapsed"}
{"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":"单一子节点(将子节点的成功结果反转为失败)"}
]
}
```
# 需要辨析的情况
1. "无人机当前在空中往东边飞50米,停个20s就好返航了。"这样的指令应该被判定为复杂,因为需要多步执行。

View File

@@ -9,37 +9,38 @@
示例:
- “起飞到10米” → {"root":{"type":"action","name":"takeoff","params":{"altitude":10.0}}}
- “移动到(120,80,20)” → {"root":{"type":"action","name":"fly_to_waypoint","params":{"x":120.0,"y":80.0,"z":20.0,"acceptance_radius":2.0}}}
- “飞机自检” → {"root":{"type":"action","name":"preflight_checks","params":{"check_level":"comprehensive"}}}
- “飞机自检” → {"root":{"type":"action","name":"system_checks","params":{"check_level":"comprehensive"}}}
—— 可用节点定义——
```json
{
"actions": [
{"name": "takeoff", "description": "无人机从当前位置垂直起飞到指定的海拔高度。", "params": {"altitude": "float, 目标海拔高度(米),范围[1, 100],默认2"}},
{"name": "land", "description": "降落无人机。可选择当前位置或返航点降落。", "params": {"mode": "string, 可选值: 'current'(当前位置), 'home'(返航点)"}},
{"name": "fly_to_waypoint", "description": "导航至一个指定坐标点。使用相对坐标系x,y,z单位为米。", "params": {"x": "float", "y": "float", "z": "float", "acceptance_radius": "float, 可选,默认2.0"}},
{"name": "move_direction", "description": "按指定方向直线移动。方向可为绝对方位或相对机体朝向。", "params": {"direction": "string: north|south|east|west|forward|backward|left|right", "distance": "float[1,10000], 可选, 不指定则持续移动", "speed": "float, 可选"}},
{"name": "approach_target", "description": "快速趋近目标至固定距离。", "params": {"target_class": "string, 要趋近的目标类别", "description": "string, 可选", "stop_distance": "float, 期望的最终停止距离", "speed": "float, 可选"}},
{"name": "rotate", "description": "旋转固定角度。", "params": {"angle": "float, 旋转角度(正数逆时针, 负数顺时针)", "angular_velocity": "rad/s, 旋转角速度"}},
{"name": "rotate_search", "description": "原地旋转搜索目标。", "params": {"target_class": "string, 要搜寻的目标类别", "description": "string, 可选", "step_angle": "float, 可选, 每一步旋转角度", "total_rotation": "float, 可选, 总共旋转搜索的角度"}},
{"name": "manual_confirmation", "description": "前端弹窗是否继续执行后续任务。", "params": {}},
{"name": "orbit_around_point", "description": "以给定中心点为中心,等速圆周飞行指定圈数。", "params": {"center_x": "float", "center_y": "float", "center_z": "float", "radius": "float[5,1000]", "laps": "int[1,20]", "clockwise": "boolean, 可选, 默认true", "speed_mps": "float[0.5,15], 可选", "gimbal_lock": "boolean, 可选, 默认true"}},
{"name": "orbit_around_target", "description": "以目标为中心,等速圆周飞行指定圈数(需已有目标)。", "params": {"target_class": "string, 取值同object_detect列表", "description": "string, 可选", "radius": "float[5,1000]", "laps": "int[1,20]", "clockwise": "boolean, 可选, 默认true", "speed_mps": "float[0.5,15], 可选", "gimbal_lock": "boolean, 可选, 默认true"}},
{"name": "loiter", "description": "在当前位置上空悬停一段时间或直到条件触发。", "params": {"duration": "float, 可选[1,600]", "until_condition": "string, 可选"}},
{"name": "object_detect", "description": "识别特定目标对象。一般是用户提到的需要检测的目标;如果用户给出了需要探索的目标的优先级,比如蓝色球危险性大于红色球大于绿色球,需要检测最危险的球,此处应给出检测优先级,描述应当为 '蓝>红>绿'", "params": {"target_class": "string, 要识别的目标类别,必须为以下值之一: balloon,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": "string, 可选", "count": "int, 可选, 默认1"}},
{"name": "strike_target", "description": "对已识别目标进行打击。", "params": {"target_class": "string", "description": "string, 可选", "count": "int, 可选, 默认1"}},
{"name": "battle_damage_assessment", "description": "战损评估。", "params": {"target_class": "string", "assessment_time": "float[5-60], 默认15.0"}},
{"name": "search_pattern", "description": "按模式搜索。", "params": {"pattern_type": "string: spiral|grid", "center_x": "float", "center_y": "float", "center_z": "float", "radius": "float[5,1000]", "target_class": "string", "description": "string, 可选", "count": "int, 可选, 默认1"}},
{"name": "track_object", "description": "持续跟踪目标。", "params": {"target_class": "string, 取值同object_detect列表", "description": "string, 可选", "track_time": "float[1,600], 默认30.0", "min_confidence": "float[0.5-1.0], 默认0.7", "safe_distance": "float[2-50], 默认10.0"}},
{"name": "deliver_payload", "description": "投放物资。", "params": {"payload_type": "string", "release_altitude": "float[2,100], 默认5.0"}},
{"name": "preflight_checks", "description": "飞行前系统自检。", "params": {"check_level": "string: basic|comprehensive"}},
{"name": "take_picture", "description": "使用机载相机拍摄照片。", "params": {}}
{"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":"fly_sequence","params":{"waypoints":"list[dict] (e.g. [{'x':10,'y':20,'z':5}, ...])","coordinate_frame":"'global'/'local_enu'global:经纬度, local_enu:以起飞点为原点的东北天坐标系)","speed":"float,可选"}},
{"name":"move_direction","params":{"direction":"north/south/east/west/forward/backward/left/right","distance":"[1,10000],缺省持续移动","speed":"float,可选"}},
{"name":"approach_target","params":{"target_class":"string,要趋近的目标类别","description":"string,可选,目标属性描述","stop_distance":"float,期望的最终停止距离","speed":"float,可选,期望的逼近速度"}},
{"name":"rotate","params":{"angle":"float,无人机自身旋转角度(正数逆时针,负数顺时针)","angular_velocity":"rad/s,旋转角速度"}},
{"name":"rotate_search","params":{"target_class":"string,要搜寻的目标类别","description":"string,可选,目标属性描述","step_angle":"float,可选,每一步旋转的角度","total_rotation":"float,可选,总共旋转搜索的角度"}},
{"name":"manual_confirmation","params":{}},
{"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,garbage","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":"system_checks","params":{"check_level":"basic/comprehensive"}},
{"name":"return","params":{"reason":"string"}},
{"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"}}
],
"conditions": [
{"name": "at_waypoint", "description": "在指定坐标容差范围内。", "params": {"x": "float", "y": "float", "z": "float", "tolerance": "float, 可选, 默认3.0"}},
{"name": "object_detected", "description": "检测到特定目标。", "params": {"target_class": "string", "description": "string, 可选", "count": "int, 可选, 默认1"}},
{"name": "target_destroyed", "description": "目标已被摧毁。", "params": {"target_class": "string", "description": "string, 可选", "confidence": "float[0.5-1.0], 默认0.8"}},
{"name": "time_elapsed", "description": "时间经过。", "params": {"duration": "float[1,2700]"}}
{"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"}}
]
}
```
@@ -50,14 +51,4 @@
- fly_to_waypoint.x,y: [-10000, 10000]
- search_pattern.radius: [5, 1000]
- move_direction.distance: [1, 10000]
- orbit_around_point.radius: [5, 1000]
- orbit_around_target.radius: [5, 1000]
- orbit_around_point/target.laps: [1, 20]
- orbit_around_point/target.speed_mps: [0.5, 15]
- 若参考知识提供坐标,必须使用并裁剪到约束范围内
—— 口令转化规则(环绕类)——
- “环绕X米Y圈” → 若有目标上下文则使用 `orbit_around_target`,否则根据是否给出中心坐标选择 `orbit_around_point``radius=X``laps=Y`,默认 `clockwise=true``gimbal_lock=true`
- “顺时针/逆时针” → `clockwise=true/false`
- “等速” → 若未给速度则 `speed_mps` 采用默认值例如3.0);若口令指明速度,裁剪到[0.5,15]
- “以(x,y,z)为中心”/“当前位置为中心” → 选择 `orbit_around_point` 并填充 `center_x/center_y/center_z`

View File

@@ -8,34 +8,30 @@
"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],缺省持续移动","speed":"float,可选"}},
{"name":"fly_to_waypoint","params":{"x":"±10000","y":"±10000","z":"[1,5000]","acceptance_radius":"默认2.0","desc":"仅当指令提及具体地点(如'去广场'、'去大门')或需计算明确坐标时使用"}},
{"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,可选"}},
{"name":"move_direction","params":{"direction":"north/south/east/west/forward/backward/left/right","distance":"[1,10000],缺省则持续移动","speed":"float,可选","desc":"当指令仅包含'往东/西...飞xx米'且无具体地点名词时,必须使用此节点"}},
{"name":"approach_target","params":{"target_class":"string,要趋近的目标类别","description":"string,可选,目标属性描述","stop_distance":"float,期望的最终停止距离","speed":"float,可选,期望的逼近速度"}},
{"name":"rotate","params":{"angle":"float,无人机自身旋转角度(正数逆时针,负数顺时针)","angular_velocity":"rad/s,旋转角速度"}},
{"name":"rotate_search","params":{"target_class":"string,要搜寻的目标类别","description":"string,可选,目标属性描述","step_angle":"float,可选,每一步旋转的角度","total_rotation":"float,可选,总共旋转搜索的角度"}},
{"name":"rotate_search","params":{"target_class":"同object_detect","description":"string,可选,目标属性描述","step_angle":"float,可选,每一步旋转的角度","total_rotation":"float,可选,总共旋转搜索的角度"}},
{"name":"manual_confirmation","params":{}},
{"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,garbage","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":"system_checks","params":{"check_level":"basic/comprehensive只能在起飞takeoff节点前使用空中无需使用该节点"}},
{"name":"return_emergency","params":{"reason":"string此节点仅用于【无明确目的地】的立即返航默认回起飞点。若指令包含“回到xx地”、“去xx地”即使包含“紧急”二字**严禁**使用此节点必须使用fly_to_waypoint"}},
{"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"}}
],
"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"}},
{"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"}}
{"name":"object_detected","params":{"target_class":"同object_detect必传","description":"可选,目标属性","count":"默认1"}}
],
"control_flow": [
{"name":"Sequence","params":{},"children":"子节点数组(按序执行,全成功则成功)"},
{"name":"Selector","params":{"memory":"默认true"},"children":"子节点数组(执行到成功为止)"},
{"name":"Parallel","params":{"policy":"all_success"},"children":"子节点数组(同时执行,严禁用'one_success'"}
{"name":"Parallel","params":{"policy":"all_success/success_on_one"},"children":"子节点数组(同时执行,默认all_success"}
],
"decorators": [
{"name":"SuccessIsFailure","params":{},"child":"单一子节点(将子节点的成功结果反转为失败)"}
@@ -55,20 +51,24 @@
## 三、标准任务结构模板(单次起降流程)
大多数任务应遵循“起飞 -> 接近 -> 执行 -> 返航/降落”的单次闭环流程,参考结构如下:
当无人机在地面时,大多数任务应遵循“起飞 -> 移动 -> 条件判断 -> 执行 -> 返航/降落”的单次闭环流程,参考结构如下:
```json
{
"root": {
"type": "Sequence",
"name": "MainTask",
"children": [
{"type":"action","name":"preflight_checks","params":{"check_level":"comprehensive"}},
{"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}}, // 接近目标区域
// --- 核心任务区 (根据指令替换) ---
// --- 任务1执行---
{"type":"action","name":"rotate_search","params":{"target_class":"person","description":"目标描述"}},
{"type":"action","name":"object_detect","params":{"target_class":"person","description":"目标描述"}},
// -------------------------------
// ----条件判断(根据指令替换) -----
{"type":"condition","name":"object_detected","params":{"target_class":"person","description":"扎辫子女子"}},
// --- 任务2执行---
{"type":"action","name":"take_photos","params":{"target_class":"person","description":"扎辫子女子"}},
// 默认不需要降落节点,除非用户明确要求
]
}
@@ -78,7 +78,8 @@
## 四、场景示例(请灵活参考)
#### 场景 1线性搜索任务Sequence + Selector
**指令**:“去研究所正大门,搜索扎辫子女子拍照。”
**指令**:“无人机当前在地面,去研究所正大门,搜索扎辫子女子,找到后拍照。”
**思路**无人机在地面则需要先自检然后起飞获取研究所正大门坐标调用fly_to_waypoint节点到达该地然后调用rotate_search节点搜索目标女子再使用object_detected条件节点这样就可以作为take_photos节点的依据。
**结构**Sequence (按顺序执行)
```json
{
@@ -110,13 +111,16 @@
```
#### 场景 2带中断逻辑的巡逻Selector 示例)
**指令**“飞往航点A。如果途中发现可疑人员则悬停。”
**指令**:“无人机当前在地面,飞往航点A。如果途中发现可疑人员则悬停。”
**参考知识**航点A的坐标x:100.0,y:50.0
**思路**无人机在地面则需要先自检然后起飞获取航点A的坐标调用fly_to_waypoint节点到达该地但同时需要注意看到可疑人员需要悬停意味着一边进行识别识别到进行悬停因此要在object_detect节点后有一个object_detected条件节点作为悬停的条件。
**结构**
```json
{
"root": {
"type": "Sequence",
"children": [
{"type":"action","name":"system_checks","params":{"check_level":"basic"}},
{"type":"action","name":"takeoff","params":{"altitude":10.0}},
{
"type": "Selector",
@@ -127,6 +131,7 @@
"name": "InterruptionLogic",
"children": [
{"type":"action","name":"object_detect","params":{"target_class":"person"}},
{"type":"condition","name":"object_detected","params":{"target_class":"person"}},
{"type":"action","name":"loiter","params":{"duration":5.0}}
]
},
@@ -138,149 +143,98 @@
}
```
#### 场景 3环绕侦察类任务
**指令**:“去面前的大楼三层/12米高绕着外围看有没有打开的窗户发现则进行拍照。”
**参考知识**{"text": "面前的大楼外围四个点坐标A(-24.00, 241.80),B(-108.50, 241.80),C(-108.50, 289.80),D(-24.00, 292.80)。"}
**结构**Sequence (按顺序执行)
#### 场景 3长期监控任务Parallel 示例)
**指令**:“无人机当前在空中往广场西边飞200米持续监控5分钟发现人就拍照告诉我到时间可以返航。”
**参考知识**广场西边200米的坐标x:50.0,y:50.0,z:10.0
**思路**无人机在空中直接前往目标点到达后需要并行执行两件事1. 倒计时5分钟主控时间2. 持续检测人并拍照(从属任务)。
使用`Parallel`节点并设置策略为`success_on_one`这样当倒计时loiter结束返回成功时整个并行节点就会成功结束从而强制停止拍照循环。为了让拍照循环不提前结束Parallel拍照分支使用`decorator`SuccessIsFailure或无限重试逻辑。
**结构**
```json
{
"root": {
"name": "主任务-监控与拍照",
"type": "Sequence",
"name": "SurroundAndInspect",
"children": [
{"type":"action","name":"takeoff","params":{"altitude":12.0}},
// 移动到A点并在此过程中持续检测
{
"name": "fly_to_waypoint",
"type": "action",
"params": {"x": 50.0, "y": 50.0, "z": 10.0}
},
{
"name": "并行监控5分钟",
"type": "Parallel",
"name": "FlyAndInspectToA",
"children": [
{"type":"action","name":"fly_to_waypoint","params":{"x":-24.0,"y":241.8,"z":12.0}},
{
"type": "Selector",
"name": "OpportunisticPhoto",
"params": { "policy": "success_on_one" },
"children": [
{
"name": "loiter",
"type": "action",
"params": { "duration": 300 }
},
{
"name": "拍照循环永不成功",
"type": "decorator",
"name": "SuccessIsFailure",
"child": {
"name": "DetectAndShoot",
"type": "Sequence",
"name": "DetectAndCapture",
"children": [
{"type":"action","name":"object_detect","params":{"target_class":"window","description":"open window"}},
{"type":"condition","name":"object_detected","params":{"target_class":"window","description":"open window"}},
{"type":"action","name":"take_photos","params":{"target_class":"window","description":"open window","track_time":5.0}}
]
}
},
{"type":"action","name":"loiter","params":{"duration":0.1}} // 占位动作
]
}
]
},
// 移动到B点...
{
"type": "Parallel",
"name": "FlyAndInspectToB",
"children": [
{"type":"action","name":"fly_to_waypoint","params":{"x":-108.5,"y":241.8,"z":12.0}},
{
"type": "Selector",
"name": "OpportunisticPhoto",
"children": [
{
"name": "SuccessIsFailure",
"type": "decorator",
"name": "SuccessIsFailure",
"child": {
"name": "check_and_photo",
"type": "Sequence",
"name": "DetectAndCapture",
"children": [
{"type":"action","name":"object_detect","params":{"target_class":"window","description":"open window"}},
{"type":"condition","name":"object_detected","params":{"target_class":"window","description":"open window"}},
{"type":"action","name":"take_photos","params":{"target_class":"window","description":"open window","track_time":5.0}}
{"name": "object_detect", "type": "action", "params": { "target_class": "person" }},
{"name": "object_detected", "type": "condition", "params": { "target_class": "person" }},
{"name": "take_photos", "type": "action", "params": { "target_class": "person" }}
]
}
},
{"type":"action","name":"loiter","params":{"duration":0.1}}
}
]
}
}
]
},
// 移动到C点...
{
"type": "Parallel",
"name": "FlyAndInspectToC",
"children": [
{"type":"action","name":"fly_to_waypoint","params":{"x":-108.5,"y":289.8,"z":12.0}},
{
"type": "Selector",
"name": "OpportunisticPhoto",
"children": [
{
"type": "decorator",
"name": "SuccessIsFailure",
"child": {
"type": "Sequence",
"name": "DetectAndCapture",
"children": [
{"type":"action","name":"object_detect","params":{"target_class":"window","description":"open window"}},
{"type":"condition","name":"object_detected","params":{"target_class":"window","description":"open window"}},
{"type":"action","name":"take_photos","params":{"target_class":"window","description":"open window","track_time":5.0}}
]
}
},
{"type":"action","name":"loiter","params":{"duration":0.1}}
]
}
]
},
// 移动到D点...
{
"type": "Parallel",
"name": "FlyAndInspectToD",
"children": [
{"type":"action","name":"fly_to_waypoint","params":{"x":-24.0,"y":292.8,"z":12.0}},
{
"type": "Selector",
"name": "OpportunisticPhoto",
"children": [
{
"type": "decorator",
"name": "SuccessIsFailure",
"child": {
"type": "Sequence",
"name": "DetectAndCapture",
"children": [
{"type":"action","name":"object_detect","params":{"target_class":"window","description":"open window"}},
{"type":"condition","name":"object_detected","params":{"target_class":"window","description":"open window"}},
{"type":"action","name":"take_photos","params":{"target_class":"window","description":"open window","track_time":5.0}}
]
}
},
{"type":"action","name":"loiter","params":{"duration":0.1}}
]
}
]
"name": "return_emergency",
"type": "action",
"params": {"reason": "返航"} // 返航回起飞点
}
]
}
}
```
## 五、优先级排序任务通用示例
当用户指令中明确提出有多个待考察且具有优先级关系的物体时,节点描述须为优先级关系。
| 用户指令场景 | `target_class` | `description` |
|-----------------------------|-----------------|-------------------------|
| 红气球>蓝气球>绿气球 | `balloon` | `(红>蓝>绿)` |
| 军用卡车>民用卡车>面包车 | `truck` | `(军用卡车>民用卡车>面包车)` |
## 六、高频错误规避
1. 优先级排序不可修改`target_class`,仅用`description`填排序规则;
2. `track_object`必传`track_time`
3. `gps_status`的`min_satellites`必须在6-15之间
4. 严禁输出 markdown 代码块标记,直接输出 JSON 纯文本;
5. 控制流节点的 `type` 必须是 `"Sequence"`, `"Selector"` 或 `"Parallel"`
6. rotate与rotate_search动作节点意思是无人机以自身为原点旋转而非围绕外部点旋转
7. 当用户指令中要求执行动作前增加人工确认时比如“我确认后拍照”则必须在拍照动作前增加manual_confirmation节点
1. 控制流节点的 `type` 必须是 `"Sequence"`, `"Selector"` 或 `"Parallel"`
2. 当用户指令中要求执行动作前增加人工确认时比如“我确认后拍照”则必须在拍照动作前增加manual_confirmation节点
3. 在条件节点执行前必须有相应动作节点如object_detected节点前必须是rotate_search等搜索类节点
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. **方向移动优先原则**:当指令仅要求“往/向/去往 + 东/西/南/北/前/后/左/右 + 飞/移动 + X米”基于当前位置相对移动且**未提及具体参照地点名词**(如“广场”、“大门”)时,**必须**使用`move_direction`节点,**严禁**计算坐标使用`fly_to_waypoint`。
## 七、输出要求
## 七、坐标计算规则(东北天坐标系 ENU
本系统统一使用东北天ENU坐标系
- **X轴**:正方向为**东** (East),负方向为**西** (West)
- **Y轴**:正方向为**北** (North),负方向为**南** (South)
- **Z轴**:正方向为**天** (Up),负方向为**地** (Down)
**仅当指令涉及前往“具体地点”(如广场、大门)的偏移位置时,才需计算绝对坐标并使用`fly_to_waypoint`**
假设参照点坐标为 $(x_0, y_0, z_0)$,偏移距离为 $d$
- **"去广场东边 $d$ 米"**:目标坐标 $(x_0 + d, y_0, z_0)$ (使用 `fly_to_waypoint`
- **"去广场西边 $d$ 米"**:目标坐标 $(x_0 - d, y_0, z_0)$ (使用 `fly_to_waypoint`
- **"去广场北边 $d$ 米"**:目标坐标 $(x_0, y_0 + d, z_0)$ (使用 `fly_to_waypoint`
- **"去广场南边 $d$ 米"**:目标坐标 $(x_0, y_0 - d, z_0)$ (使用 `fly_to_waypoint`
- **"往上/升高 $d$ 米"**:目标坐标 $(x_0, y_0, z_0 + d)$
注意比如指令为“飞往东边100米”请直接使用 `move_direction` 节点,无需计算坐标)
**示例**
若"广场"坐标为 $(-17, 360, 3)$
- "去广场**东边**20米" -> 目标点 $(3, 360, 3)$
- "去广场**南边**30米" -> 目标点 $(-17, 330, 3)$
## 八、输出要求
仅输出1个严格符合上述所有规则的JSON对象。

View File

@@ -282,6 +282,65 @@ def _generate_pytree_schema(allowed_actions: set, allowed_conditions: set) -> di
}
}
}
},
# 飞行序列节点的参数验证
{
"if": {
"properties": {
"type": {"pattern": "^[Aa][Cc][Tt][Ii][Oo][Nn]$"},
"name": {"const": "fly_sequence"}
}
},
"then": {
"properties": {
"params": {
"type": "object",
"properties": {
"waypoints": {
"type": "array",
"items": {
"type": "object",
"properties": {
"x": {"type": "number"},
"y": {"type": "number"},
"z": {"type": "number"}
},
"required": ["x", "y", "z"]
},
"minItems": 1
},
"coordinate_frame": {"type": "string", "enum": ["global", "local_enu"]},
"speed": {"type": "number"}
},
"required": ["waypoints", "coordinate_frame"],
"additionalProperties": False
}
}
}
},
# 抵近目标节点的参数验证
{
"if": {
"properties": {
"type": {"pattern": "^[Aa][Cc][Tt][Ii][Oo][Nn]$"},
"name": {"const": "approach_target"}
}
},
"then": {
"properties": {
"params": {
"type": "object",
"properties": {
"target_class": {"type": "string"},
"description": {"type": "string"},
"stop_distance": {"type": "number"},
"speed": {"type": "number"}
},
"required": ["target_class", "stop_distance"],
"additionalProperties": False
}
}
}
}
]
}
@@ -602,6 +661,30 @@ class PyTreeGenerator:
logging.error(f"从向量数据库检索时发生错误: {e}")
return None
def _save_history(self, prompt: str, result_dict: dict):
"""保存请求和响应历史记录"""
import datetime
try:
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
# 确保history目录存在
history_dir = os.path.join(self.base_dir, '..', 'history')
os.makedirs(history_dir, exist_ok=True)
history_file = os.path.join(history_dir, f"{timestamp}_plan.json")
record = {
"timestamp": datetime.datetime.now().isoformat(),
"request": prompt,
"response": result_dict
}
with open(history_file, 'w', encoding='utf-8') as f:
json.dump(record, f, ensure_ascii=False, indent=2)
logging.info(f"💾 历史记录已保存: {history_file}")
except Exception as e:
logging.error(f"保存历史记录失败: {e}")
async def generate(self, user_prompt: str) -> Dict[str, Any]:
"""
Generates a py_tree.json structure based on the user's prompt.
@@ -798,6 +881,10 @@ class PyTreeGenerator:
logging.warning(f"保存推理链Markdown失败: {e}")
# 添加 final_prompt 到返回结果
pytree_dict['final_prompt'] = final_prompt
# 保存历史记录
self._save_history(user_prompt, pytree_dict)
return pytree_dict
# 验证生成的复杂行为树
@@ -832,6 +919,10 @@ class PyTreeGenerator:
logging.warning(f"保存推理链Markdown失败: {e}")
# 添加 final_prompt 到返回结果
pytree_dict['final_prompt'] = final_prompt
# 保存历史记录
self._save_history(user_prompt, pytree_dict)
return pytree_dict
else:
# 打印未通过验证的Pytree以便排查

View File

@@ -288,6 +288,21 @@ start_services() {
print_info "启动FastAPI后端服务 (端口 ${API_PORT})..."
cd "${PROJECT_ROOT}"
# 尝试找到 dot 命令 (Graphviz) 路径,以便后端生成图片
DOT_PATH=$(which dot || true)
DOT_DIR=""
if [ -n "$DOT_PATH" ]; then
DOT_DIR=$(dirname "$DOT_PATH")
print_info "找到 Graphviz dot 命令: $DOT_PATH"
else
print_warning "未找到 dot 命令,可视化图片生成可能会失败"
# 尝试默认的 miniconda 路径作为备选
if [ -f "/home/a/miniconda3/bin/dot" ]; then
DOT_DIR="/home/a/miniconda3/bin"
print_info "使用备选路径: $DOT_DIR"
fi
fi
# 激活venv虚拟环境并启动FastAPI服务
# 使用bash -c来在新的shell中激活venv环境
bash -c "
@@ -295,6 +310,12 @@ start_services() {
if [ -f '${ros2_setup}' ]; then
source '${ros2_setup}'
fi
# 确保 Graphviz 在 PATH 中
if [ -n '${DOT_DIR}' ]; then
export PATH=\"${DOT_DIR}:\$PATH\"
fi
# 直接使用虚拟环境中的Python启动
cd '${PROJECT_ROOT}/backend_service' && \
'${venv_path_expanded}/bin/python' -m uvicorn src.main:app --host 0.0.0.0 --port ${API_PORT}

477
start_all_vllm.sh Executable file
View File

@@ -0,0 +1,477 @@
#!/bin/bash
# ==============================================================================
# 无人机自然语言控制项目 - vLLM 一键启动脚本(新增,不修改 start_all.sh
# ==============================================================================
# 功能启动所有必需的服务vLLM推理模型、llama-server embedding模型、FastAPI后端
# 用法:./start_all_vllm.sh [选项]
# ==============================================================================
set -e # 遇到错误立即退出
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 默认配置(可通过环境变量覆盖)
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LLAMA_SERVER_DIR="${LLAMA_SERVER_DIR:-~/llama.cpp/build/bin}"
INFERENCE_MODEL_DIR="${INFERENCE_MODEL_DIR:-/home/a/models/AWQ/Qwen3-4B-Instruct-2507}"
VLLM_CONDA_ENV="${VLLM_CONDA_ENV:-VLLM}"
VLLM_SPECULATIVE_CONFIG="${VLLM_SPECULATIVE_CONFIG:-}"
VLLM_GPU_MEMORY_UTILIZATION="${VLLM_GPU_MEMORY_UTILIZATION:-0.6}"
VLLM_SERVED_MODEL_NAME="${VLLM_SERVED_MODEL_NAME:-local-model}"
EMBEDDING_MODEL="${EMBEDDING_MODEL:-~/models/gguf/Qwen3/Qwen3-Embedding-4B/Qwen3-Embedding-4B-Q5_K_M.gguf}"
VENV_PATH="${VENV_PATH:-${PROJECT_ROOT}/backend_service/venv}"
LOG_DIR="${LOG_DIR:-${PROJECT_ROOT}/logs}"
PID_FILE="${LOG_DIR}/services_vllm.pid"
# 端口配置
INFERENCE_PORT="${INFERENCE_PORT:-8081}"
EMBEDDING_PORT="${EMBEDDING_PORT:-8090}"
API_PORT="${API_PORT:-8000}"
# 创建日志目录
mkdir -p "${LOG_DIR}"
# ==============================================================================
# 辅助函数
# ==============================================================================
print_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查命令是否存在
check_command() {
if ! command -v "$1" &> /dev/null; then
print_error "$1 命令未找到,请先安装"
return 1
fi
return 0
}
# 检查端口是否被占用
check_port() {
local port=$1
if lsof -Pi :${port} -sTCP:LISTEN -t >/dev/null 2>&1 ; then
return 0 # 端口被占用
else
return 1 # 端口空闲
fi
}
# 等待服务就绪
wait_for_service() {
local url=$1
local service_name=$2
local max_attempts=30
local attempt=0
print_info "等待 ${service_name} 启动..."
while [ $attempt -lt $max_attempts ]; do
if curl -s "${url}" > /dev/null 2>&1; then
print_success "${service_name} 已就绪"
return 0
fi
attempt=$((attempt + 1))
sleep 1
done
print_error "${service_name} 启动超时"
return 1
}
# 停止所有服务
stop_services() {
print_info "正在停止所有服务..."
if [ -f "${PID_FILE}" ]; then
while read -r pid; do
if ps -p "$pid" > /dev/null 2>&1; then
print_info "停止进程 PID: $pid"
kill "$pid" 2>/dev/null || true
fi
done < "${PID_FILE}"
rm -f "${PID_FILE}"
fi
# 尝试通过端口停止服务
for port in ${INFERENCE_PORT} ${EMBEDDING_PORT} ${API_PORT}; do
if check_port ${port}; then
local pid
pid=$(lsof -ti:${port})
if [ -n "$pid" ]; then
print_info "停止占用端口 ${port} 的进程 (PID: $pid)"
kill $pid 2>/dev/null || true
fi
fi
done
print_success "所有服务已停止"
}
# 清理函数(脚本退出时调用)
cleanup() {
if [ "$?" -ne 0 ]; then
print_error "启动过程中发生错误,正在清理..."
fi
# 注意:这里不自动停止服务,让用户手动控制
}
trap cleanup EXIT
# ==============================================================================
# 主函数
# ==============================================================================
start_services() {
print_info "=========================================="
print_info " 无人机自然语言控制项目 - vLLM 服务启动"
print_info "=========================================="
echo ""
# 检查必要的命令
print_info "检查必要的命令..."
check_command "python3" || exit 1
check_command "curl" || exit 1
check_command "lsof" || print_warning "lsof 未安装,将无法检查端口占用"
check_command "conda" || exit 1
echo ""
# 检查端口占用
print_info "检查端口占用..."
if check_port ${INFERENCE_PORT}; then
print_warning "端口 ${INFERENCE_PORT} 已被占用,推理模型可能已在运行"
fi
if check_port ${EMBEDDING_PORT}; then
print_warning "端口 ${EMBEDDING_PORT} 已被占用Embedding模型可能已在运行"
fi
if check_port ${API_PORT}; then
print_error "端口 ${API_PORT} 已被占用,请先停止占用该端口的服务"
exit 1
fi
echo ""
# 检查llama-server用于 embedding展开路径中的 ~
local llama_server_dir_expanded
llama_server_dir_expanded=$(eval echo "${LLAMA_SERVER_DIR}")
local llama_server="${llama_server_dir_expanded}/llama-server"
if [ ! -f "${llama_server}" ]; then
print_error "llama-server 未找到: ${llama_server}"
print_info "请设置 LLAMA_SERVER_DIR 环境变量指向正确的路径"
print_info "当前路径: ${LLAMA_SERVER_DIR}"
print_info "展开后路径: ${llama_server_dir_expanded}"
exit 1
fi
print_success "找到 llama-server: ${llama_server}"
echo ""
# 检查模型路径
local inference_model_dir_expanded
inference_model_dir_expanded=$(eval echo "${INFERENCE_MODEL_DIR}")
local embedding_model_expanded
embedding_model_expanded=$(eval echo "${EMBEDDING_MODEL}")
if [ ! -e "${inference_model_dir_expanded}" ]; then
print_error "推理模型目录未找到: ${inference_model_dir_expanded}"
print_info "请设置 INFERENCE_MODEL_DIR 环境变量指向正确的模型目录"
exit 1
fi
if [ ! -d "${inference_model_dir_expanded}" ]; then
print_warning "推理模型路径不是目录: ${inference_model_dir_expanded}"
print_warning "vLLM 通常需要传入模型目录(包含 config/tokenizer/权重等)"
fi
print_success "找到推理模型目录: ${inference_model_dir_expanded}"
if [ ! -f "${embedding_model_expanded}" ]; then
print_error "Embedding模型文件未找到: ${embedding_model_expanded}"
print_info "请设置 EMBEDDING_MODEL 环境变量指向正确的模型路径"
exit 1
fi
print_success "找到Embedding模型: ${embedding_model_expanded}"
echo ""
# 检查ROS2环境
local ros2_setup="${PROJECT_ROOT}/install/setup.bash"
if [ ! -f "${ros2_setup}" ]; then
print_warning "ROS2 setup文件未找到: ${ros2_setup}"
print_warning "如果项目已与ROS2解耦可以忽略此警告"
else
print_success "找到ROS2 setup文件: ${ros2_setup}"
fi
echo ""
# 检查venv虚拟环境
local venv_path_expanded
venv_path_expanded=$(eval echo "${VENV_PATH}")
print_info "检查venv虚拟环境: ${venv_path_expanded}"
if [ ! -d "${venv_path_expanded}" ]; then
print_error "venv虚拟环境目录不存在: ${venv_path_expanded}"
print_info "请先创建venv环境: python3 -m venv ${venv_path_expanded}"
print_info "然后安装依赖: ${venv_path_expanded}/bin/pip install -r backend_service/requirements.txt"
exit 1
fi
if [ ! -f "${venv_path_expanded}/bin/activate" ]; then
print_error "venv激活脚本不存在: ${venv_path_expanded}/bin/activate"
print_error "这看起来不是一个有效的venv环境"
exit 1
fi
print_success "venv虚拟环境存在: ${venv_path_expanded}"
echo ""
# 初始化PID文件
> "${PID_FILE}"
# ==========================================================================
# 启动推理模型服务vLLM
# ==========================================================================
print_info "启动推理模型服务(vLLM) (端口 ${INFERENCE_PORT})..."
bash -lc "
set -e
CONDA_BASE=\$(conda info --base)
if [ -z \"\${CONDA_BASE}\" ] || [ ! -f \"\${CONDA_BASE}/etc/profile.d/conda.sh\" ]; then
echo \"[ERROR] conda.sh 未找到:\${CONDA_BASE}/etc/profile.d/conda.sh\" 1>&2
exit 1
fi
source \"\${CONDA_BASE}/etc/profile.d/conda.sh\"
conda activate \"${VLLM_CONDA_ENV}\"
export VLLM_USE_V1=1
echo \"[DEBUG] conda_env=${VLLM_CONDA_ENV}\"
echo \"[DEBUG] CONDA_PREFIX=\${CONDA_PREFIX}\"
echo \"[DEBUG] which python: \$(which python)\"
echo \"[DEBUG] which vllm: \$(which vllm)\"
vllm --version || true
python -c \"import sys; print('[DEBUG] python:', sys.version)\" || true
python -c \"import torch; print('[DEBUG] torch:', torch.__version__, 'cuda:', torch.version.cuda, 'available:', torch.cuda.is_available())\" || true
SPEC_ARGS=()
if [ -n \"${VLLM_SPECULATIVE_CONFIG}\" ]; then
SPEC_ARGS+=(--speculative-config \"${VLLM_SPECULATIVE_CONFIG}\")
fi
exec vllm serve \"${inference_model_dir_expanded}\" \
--host=0.0.0.0 \
--port=${INFERENCE_PORT} \
--dtype=auto \
--max-num-seqs=1 \
--max-model-len=16384 \
\"\${SPEC_ARGS[@]}\" \
--served-model-name \"${VLLM_SERVED_MODEL_NAME}\" \
--trust-remote-code \
--gpu-memory-utilization=${VLLM_GPU_MEMORY_UTILIZATION} \
--uvicorn-log-level=debug \
--max-parallel-loading-workers 4
" > "${LOG_DIR}/vllm_inference_model.log" 2>&1 &
local inference_pid=$!
echo $inference_pid >> "${PID_FILE}"
print_success "推理模型服务(vLLM)已启动 (PID: $inference_pid)"
print_info "日志文件: ${LOG_DIR}/vllm_inference_model.log"
echo ""
# ==========================================================================
# 启动Embedding模型服务llama-server
# ==========================================================================
print_info "启动Embedding模型服务 (端口 ${EMBEDDING_PORT})..."
cd "${llama_server_dir_expanded}"
nohup ./llama-server \
-m "${embedding_model_expanded}" \
--gpu-layers 36 \
--port ${EMBEDDING_PORT} \
--embeddings \
--pooling last \
--host 0.0.0.0 \
> "${LOG_DIR}/embedding_model.log" 2>&1 &
local embedding_pid=$!
echo $embedding_pid >> "${PID_FILE}"
print_success "Embedding模型服务已启动 (PID: $embedding_pid)"
print_info "日志文件: ${LOG_DIR}/embedding_model.log"
echo ""
# ==========================================================================
# 等待模型服务就绪
# ==========================================================================
print_info "等待模型服务就绪..."
sleep 3 # 给服务一些启动时间
# 等待推理模型服务vLLM
if ! wait_for_service "http://localhost:${INFERENCE_PORT}/health" "推理模型服务(vLLM)"; then
if ! wait_for_service "http://localhost:${INFERENCE_PORT}/v1/models" "推理模型服务(vLLM)"; then
print_warning "推理模型服务(vLLM)可能未完全就绪,但将继续启动"
fi
fi
# 等待Embedding模型服务
if ! wait_for_service "http://localhost:${EMBEDDING_PORT}/health" "Embedding模型服务"; then
if ! wait_for_service "http://localhost:${EMBEDDING_PORT}/v1/models" "Embedding模型服务"; then
print_warning "Embedding模型服务可能未完全就绪但将继续启动"
fi
fi
echo ""
# ==========================================================================
# 启动FastAPI后端服务
# ==========================================================================
print_info "启动FastAPI后端服务 (端口 ${API_PORT})..."
cd "${PROJECT_ROOT}"
# 尝试找到 dot 命令 (Graphviz) 路径,以便后端生成图片
DOT_PATH=$(which dot || true)
DOT_DIR=""
if [ -n "$DOT_PATH" ]; then
DOT_DIR=$(dirname "$DOT_PATH")
print_info "找到 Graphviz dot 命令: $DOT_PATH"
else
print_warning "未找到 dot 命令,可视化图片生成可能会失败"
# 尝试默认的 miniconda 路径作为备选
if [ -f "/home/a/miniconda3/bin/dot" ]; then
DOT_DIR="/home/a/miniconda3/bin"
print_info "使用备选路径: $DOT_DIR"
fi
fi
bash -c "
# 激活ROS2环境如果存在
if [ -f '${ros2_setup}' ]; then
source '${ros2_setup}'
fi
# 确保 Graphviz 在 PATH 中
if [ -n '${DOT_DIR}' ]; then
export PATH=\"${DOT_DIR}:\$PATH\"
fi
# 让后端默认使用 vLLM 暴露的模型名,避免请求 local-model 导致 404
OPENAI_MODEL=\"\${OPENAI_MODEL:-${VLLM_SERVED_MODEL_NAME}}\" \
CLASSIFIER_MODEL=\"\${CLASSIFIER_MODEL:-${VLLM_SERVED_MODEL_NAME}}\" \
SIMPLE_MODEL=\"\${SIMPLE_MODEL:-${VLLM_SERVED_MODEL_NAME}}\" \
COMPLEX_MODEL=\"\${COMPLEX_MODEL:-${VLLM_SERVED_MODEL_NAME}}\" \
cd '${PROJECT_ROOT}/backend_service' && \
'${venv_path_expanded}/bin/python' -m uvicorn src.main:app --host 0.0.0.0 --port ${API_PORT}
" > "${LOG_DIR}/fastapi.log" 2>&1 &
local api_pid=$!
echo $api_pid >> "${PID_FILE}"
print_success "FastAPI服务已启动 (PID: $api_pid)"
print_info "日志文件: ${LOG_DIR}/fastapi.log"
echo ""
# 等待FastAPI服务就绪
sleep 3
if wait_for_service "http://localhost:${API_PORT}/docs" "FastAPI服务"; then
print_success "所有服务已成功启动!"
else
print_warning "FastAPI服务可能未完全就绪请检查日志: ${LOG_DIR}/fastapi.log"
fi
echo ""
# 显示服务访问信息
print_info "=========================================="
print_info " 服务启动完成!"
print_info "=========================================="
print_info "推理模型API(vLLM): http://localhost:${INFERENCE_PORT}/v1"
print_info "Embedding模型API: http://localhost:${EMBEDDING_PORT}/v1"
print_info "FastAPI后端: http://localhost:${API_PORT}"
print_info "API文档: http://localhost:${API_PORT}/docs"
print_info ""
print_info "日志文件位置:"
print_info " - 推理模型(vLLM): ${LOG_DIR}/vllm_inference_model.log"
print_info " - Embedding模型: ${LOG_DIR}/embedding_model.log"
print_info " - FastAPI服务: ${LOG_DIR}/fastapi.log"
print_info ""
print_info "按 Ctrl+C 停止所有服务"
print_info "=========================================="
echo ""
# 设置信号处理确保Ctrl+C时能清理
trap 'print_info "\n正在停止服务..."; stop_services; exit 0' INT TERM
# 保持脚本运行
print_info "所有服务正在运行中,查看日志请使用:"
print_info " tail -f ${LOG_DIR}/*.log"
echo ""
wait
}
# ==============================================================================
# 脚本入口
# ==============================================================================
case "${1:-start}" in
start)
start_services
;;
stop)
stop_services
;;
restart)
stop_services
sleep 2
start_services
;;
status)
print_info "检查服务状态..."
if [ -f "${PID_FILE}" ]; then
print_info "已记录的服务进程:"
while read -r pid; do
if ps -p "$pid" > /dev/null 2>&1; then
print_success "PID $pid: 运行中"
else
print_warning "PID $pid: 已停止"
fi
done < "${PID_FILE}"
else
print_info "未找到PID文件服务可能未启动"
fi
echo ""
print_info "端口占用情况:"
for port in ${INFERENCE_PORT} ${EMBEDDING_PORT} ${API_PORT}; do
if check_port ${port}; then
local pid
pid=$(lsof -ti:${port})
print_success "端口 ${port}: 被占用 (PID: $pid)"
else
print_warning "端口 ${port}: 空闲"
fi
done
;;
*)
echo "用法: $0 {start|stop|restart|status}"
echo ""
echo "命令说明:"
echo " start - 启动所有服务(默认)"
echo " stop - 停止所有服务"
echo " restart - 重启所有服务"
echo " status - 查看服务状态"
echo ""
echo "环境变量配置:"
echo " LLAMA_SERVER_DIR - llama-server所在目录 (默认: ~/llama.cpp/build/bin)"
echo " INFERENCE_MODEL_DIR - 推理模型目录(vLLM) (默认: /home/a/models/safetensors/Qwen3-4B)"
echo " VLLM_CONDA_ENV - conda环境名 (默认: vllm如果你的是 VLLM请设置为 VLLM)"
echo " VLLM_SPECULATIVE_CONFIG - vLLM speculative JSON可选例如: {\"model\":\"/home/a/qwen3-4b-eagle3\",\"num_speculative_tokens\":5,\"method\":\"eagle3\"}"
echo " VLLM_GPU_MEMORY_UTILIZATION - vLLM 显存占用比例 (默认: 0.85)"
echo " VLLM_SERVED_MODEL_NAME - vLLM 对外模型名 (默认: local-model后端也会用它作为默认模型名)"
echo " EMBEDDING_MODEL - Embedding模型路径 (默认: ~/models/gguf/Qwen3/Qwen3-Embedding-4B/Qwen3-Embedding-4B-Q5_K_M.gguf)"
echo " VENV_PATH - venv虚拟环境路径 (默认: \${PROJECT_ROOT}/backend_service/venv)"
echo " LOG_DIR - 日志目录 (默认: \${PROJECT_ROOT}/logs)"
echo " INFERENCE_PORT - 推理端口 (默认: 8081)"
echo " EMBEDDING_PORT - embedding端口 (默认: 8090)"
echo " API_PORT - 后端端口 (默认: 8000)"
exit 1
;;
esac

View File

@@ -1,6 +0,0 @@
{"text": "在地图上有一个名为 '跷跷板' 的地点或区域它的leisure是'playground',其中心位置坐标大约在 (x:15, y:-8.5, z:1.2)。"}
{"text": "在地图上有一个名为 'A地' 的地点或区域它的building是'commercial',其中心位置坐标大约在 (x:10, y:-10, z:2)。"}
{"text": "在地图上有一个名为 '学生宿舍' 的地点或区域它的building是'dormitory',其中心位置坐标大约在 (x:5, y:3, z:2)。"}
{"text": "地点:'研究所正大门'。别名:'大门'、'入口'。坐标:(x:-23.8, y:292.8, z:14)。建议悬停高度14米。适合任务定点侦察、拍照。"}
{"text": "地点:'研究所广场'。属性:开阔区域。坐标:(x:-24.0, y:241.8, z:14)。建议搜索半径30米。适合任务寻找人员、旋转搜索。"}
{"text": "路线:'研究所外围巡逻'。关键航点序列:[(x:-24.0, y:241.8), (x:-107.8, y:289.8), (x:-106.5, y:241.3), (x:-23.80, y:292.80)]。高度14米。适合环绕侦察任务。"}

View File

@@ -0,0 +1,8 @@
{"text": "在地图上有一个名为 '跷跷板' 的地点或区域它的leisure是'playground',其中心位置坐标大约在东北天坐标系 (x:15, y:-8.5, z:1.2)。"}
{"text": "在地图上有一个名为 'A地' 的地点或区域它的building是'commercial',其中心位置坐标大约在东北天坐标系 (x:10, y:-10, z:2)。"}
{"text": "在地图上有一个名为 '学生宿舍' 的地点或区域它的building是'dormitory',其中心位置坐标大约在东北天坐标系 (x:5, y:3, z:2)。"}
{"text": "地点:'研究所正大门'。别名:'大门'、'入口'。东北天坐标系坐标:(x:-23.8, y:292.8, z:14)。建议悬停高度14米。适合任务定点侦察、拍照。"}
{"text": "地点:'广场'。属性:开阔区域。东北天坐标系坐标:(x:-17, y:360.0, z:3.0)。"}
{"text": "对于查找搜索类任务比如查找某个人或者东西我们可以让无人机执行rotate_search动作节点让无人机以自身为原点旋转观察四周确保无人机主动寻找目标。"}
{"text": "大楼外围四个点东北天坐标系坐标A(-24.00, 241.80),B(-108.50, 241.80),C(-108.50, 289.80),D(-24.00, 292.80)。"}
{"text": "当指令中要求紧急返航到某地时必须使用fly_to_waypoint节点严禁使用return_emergency节点。"}

File diff suppressed because one or more lines are too long

View File

@@ -1,14 +0,0 @@
起飞
起飞后移动到学生宿舍上方降落
起飞后移动到学生宿舍上方查找蓝色的车
起飞后移动到学生宿舍上方寻找蓝色的车
起飞后移动到学生宿舍上方检测蓝色的车
飞到学生宿舍上方查找蓝色的车
飞到学生宿舍上方查找蓝色车辆并进行打击
起飞后移动到学生宿舍上方搜索蓝色车辆,并进行打击
起飞到学生宿舍上方搜索被困人员,并为被困人员投递救援物资
飞到学生宿舍上方搜索方圆10米范围内的蓝色车辆
飞到学生宿舍上方搜索半径为10米区域范围内的蓝色车辆
起飞到学生宿舍搜索有没有被困人员,然后抛洒救援物资

View File

@@ -0,0 +1,2 @@
无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。
无人机当前在空中,回到广场,对长发可疑男子进行拍照。

View File

@@ -1,5 +1,10 @@
去研究所正大门,搜索扎辫子女子并拍照。
查找戴帽子的女子,找到后近距离拍照。
到研究所广场,对长发可疑男子进行拍照
到研究所广场,寻找黄色衣服男子,我确认后再对其拍照
立即返航。
无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。
无人机当前在空中,回到广场,对戴帽子的人进行拍照。
无人机当前在空中去广场西边200米对过往的公交车拍张照然后返航
无人机当前在空中,到广场查找绿色公交车,看见了拍个照片
无人机当前在空中,搜索小汽车,搜索到了我确认后再决定要不要拍照。
无人机当前在空中往广场西边飞200米持续监控5分钟发现人就拍照告诉我到时间可以返航。
无人机当前在空中,到广场边上的施工区域内,发现有没带安全帽的飞近后拍照。
无人机当前在空中,紧急回到广场,看见了红绿灯之后直接降落。
无人机当前在空中快速去往东边100米有身穿黑色衣服头戴帽子的男子在挟持他人对其进行拍照。
无人机当前在空中离黑色衣服戴帽子的人太远了照片看不清贴近到3米距离拍拍完可以直接返航。

View File

@@ -154,8 +154,8 @@ def send_api_request(prompt, instruction_idx, run_number):
def collect_nodes(current_node):
if current_node.get('type') == 'action':
action_name = current_node.get('name', '')
if action_name not in ['deliver_payload', 'emergency_return', 'fly_to_waypoint',
'land', 'loiter', 'object_detect', 'preflight_checks',
if action_name not in ['deliver_payload', 'return', 'fly_to_waypoint',
'land', 'loiter', 'object_detect', 'system_checks',
'search_pattern', 'strike_target', 'battle_damage_assessment', 'takeoff']:
invalid_actions.append(action_name)
@@ -178,8 +178,8 @@ def send_api_request(prompt, instruction_idx, run_number):
elif is_simple_mode:
# 简单模式检查action名称是否有效
action_name = root_node.get('name', '')
if action_name and action_name not in ['deliver_payload', 'emergency_return', 'fly_to_waypoint',
'land', 'loiter', 'object_detect', 'preflight_checks',
if action_name and action_name not in ['deliver_payload', 'return', 'fly_to_waypoint',
'land', 'loiter', 'object_detect', 'system_checks',
'search_pattern', 'strike_target', 'battle_damage_assessment', 'takeoff']:
invalid_actions.append(action_name)

View File

@@ -0,0 +1,10 @@
无人机当前在地面,去研究所正大门,搜索扎辫子女子并拍照。
无人机当前在空中,查找戴帽子的女子,找到后近距离拍照。
无人机当前在地面,到研究所广场,对长发可疑男子进行拍照。
无人机当前在空中,到研究所广场,寻找黄色衣服男子,我确认后再对其拍照。
无人机当前在空中,立即返航。
无人机当前在地面,去面前的大楼的三层/12米高,绕着外围侦察杂物堆积情况,如有发现拍照返回。
无人机当前在地面,去面前的大楼的三层/12米高,绕着外围看有没有打开的窗户,发现则进行拍照。
无人机当前在地面飞到前面大楼3层/12米高,沿着外围查找打开的窗户,看到停下即可。
无人机当前在空中,这层楼外围飞行过程中只要看到人,就拍照。
无人机当前在空中往上飞1层/3米高,接着绕这栋楼外围查有没有杂物堆积,看到了就拍照传回来。

View File

@@ -0,0 +1,11 @@
instruction,run_id,success,latency,error
无人机当前在地面,去研究所正大门,搜索扎辫子女子并拍照。,1,True,6.720000505447388,
无人机当前在空中,查找戴帽子的女子,找到后近距离拍照。,1,True,4.619004487991333,
无人机当前在地面,到研究所广场,对长发可疑男子进行拍照。,1,True,5.849743366241455,
无人机当前在空中,到研究所广场,寻找黄色衣服男子,我确认后再对其拍照。,1,True,5.915772438049316,
无人机当前在空中,立即返航。,1,True,0.7678096294403076,
"无人机当前在地面,去面前的大楼的三层/12米高,绕着外围侦察杂物堆积情况,如有发现拍照返回。",1,True,26.149285554885864,
"无人机当前在地面,去面前的大楼的三层/12米高,绕着外围看有没有打开的窗户,发现则进行拍照。",1,True,8.941612958908081,
"无人机当前在地面飞到前面大楼3层/12米高,沿着外围查找打开的窗户,看到停下即可。",1,True,5.791374444961548,
"无人机当前在空中,这层楼外围飞行过程中只要看到人,就拍照。",1,True,5.722065687179565,
"无人机当前在空中往上飞1层/3米高,接着绕这栋楼外围查有没有杂物堆积,看到了就拍照传回来。",1,True,22.41797375679016,
1 instruction run_id success latency error
2 无人机当前在地面,去研究所正大门,搜索扎辫子女子并拍照。 1 True 6.720000505447388
3 无人机当前在空中,查找戴帽子的女子,找到后近距离拍照。 1 True 4.619004487991333
4 无人机当前在地面,到研究所广场,对长发可疑男子进行拍照。 1 True 5.849743366241455
5 无人机当前在空中,到研究所广场,寻找黄色衣服男子,我确认后再对其拍照。 1 True 5.915772438049316
6 无人机当前在空中,立即返航。 1 True 0.7678096294403076
7 无人机当前在地面,去面前的大楼的三层/12米高,绕着外围侦察杂物堆积情况,如有发现拍照返回。 1 True 26.149285554885864
8 无人机当前在地面,去面前的大楼的三层/12米高,绕着外围看有没有打开的窗户,发现则进行拍照。 1 True 8.941612958908081
9 无人机当前在地面,飞到前面大楼3层/12米高,沿着外围查找打开的窗户,看到停下即可。 1 True 5.791374444961548
10 无人机当前在空中,这层楼外围飞行过程中只要看到人,就拍照。 1 True 5.722065687179565
11 无人机当前在空中,往上飞1层/3米高,接着绕这栋楼外围查有没有杂物堆积,看到了就拍照传回来。 1 True 22.41797375679016

View File

@@ -0,0 +1,11 @@
Instruction,Total Runs,Success Runs,Success Rate,Avg Latency
无人机当前在地面,去研究所正大门,搜索扎辫子女子并拍照。,1,1,100.0%,6.72s
无人机当前在空中,查找戴帽子的女子,找到后近距离拍照。,1,1,100.0%,4.62s
无人机当前在地面,到研究所广场,对长发可疑男子进行拍照。,1,1,100.0%,5.85s
无人机当前在空中,到研究所广场,寻找黄色衣服男子,我确认后再对其拍照。,1,1,100.0%,5.92s
无人机当前在空中,立即返航。,1,1,100.0%,0.77s
"无人机当前在地面,去面前的大楼的三层/12米高,绕着外围侦察杂物堆积情况,如有发现拍照返回。",1,1,100.0%,26.15s
"无人机当前在地面,去面前的大楼的三层/12米高,绕着外围看有没有打开的窗户,发现则进行拍照。",1,1,100.0%,8.94s
"无人机当前在地面飞到前面大楼3层/12米高,沿着外围查找打开的窗户,看到停下即可。",1,1,100.0%,5.79s
"无人机当前在空中,这层楼外围飞行过程中只要看到人,就拍照。",1,1,100.0%,5.72s
"无人机当前在空中往上飞1层/3米高,接着绕这栋楼外围查有没有杂物堆积,看到了就拍照传回来。",1,1,100.0%,22.42s
1 Instruction Total Runs Success Runs Success Rate Avg Latency
2 无人机当前在地面,去研究所正大门,搜索扎辫子女子并拍照。 1 1 100.0% 6.72s
3 无人机当前在空中,查找戴帽子的女子,找到后近距离拍照。 1 1 100.0% 4.62s
4 无人机当前在地面,到研究所广场,对长发可疑男子进行拍照。 1 1 100.0% 5.85s
5 无人机当前在空中,到研究所广场,寻找黄色衣服男子,我确认后再对其拍照。 1 1 100.0% 5.92s
6 无人机当前在空中,立即返航。 1 1 100.0% 0.77s
7 无人机当前在地面,去面前的大楼的三层/12米高,绕着外围侦察杂物堆积情况,如有发现拍照返回。 1 1 100.0% 26.15s
8 无人机当前在地面,去面前的大楼的三层/12米高,绕着外围看有没有打开的窗户,发现则进行拍照。 1 1 100.0% 8.94s
9 无人机当前在地面,飞到前面大楼3层/12米高,沿着外围查找打开的窗户,看到停下即可。 1 1 100.0% 5.79s
10 无人机当前在空中,这层楼外围飞行过程中只要看到人,就拍照。 1 1 100.0% 5.72s
11 无人机当前在空中,往上飞1层/3米高,接着绕这栋楼外围查有没有杂物堆积,看到了就拍照传回来。 1 1 100.0% 22.42s

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@@ -0,0 +1,2 @@
无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。
无人机当前在空中,回到广场,对长发可疑男子进行拍照。

View File

@@ -0,0 +1,3 @@
instruction,run_id,success,latency,error
无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。,1,True,6.9019341468811035,
无人机当前在空中,回到广场,对长发可疑男子进行拍照。,1,True,5.214093923568726,
1 instruction run_id success latency error
2 无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。 1 True 6.9019341468811035
3 无人机当前在空中,回到广场,对长发可疑男子进行拍照。 1 True 5.214093923568726

View File

@@ -0,0 +1,3 @@
Instruction,Total Runs,Success Runs,Success Rate,Avg Latency
无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。,1,1,100.0%,6.90s
无人机当前在空中,回到广场,对长发可疑男子进行拍照。,1,1,100.0%,5.21s
1 Instruction Total Runs Success Runs Success Rate Avg Latency
2 无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。 1 1 100.0% 6.90s
3 无人机当前在空中,回到广场,对长发可疑男子进行拍照。 1 1 100.0% 5.21s

View File

@@ -0,0 +1,2 @@
无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。
无人机当前在空中,回到广场,对长发可疑男子进行拍照。

View File

@@ -0,0 +1,3 @@
instruction,run_id,success,latency,error
无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。,1,True,7.12662148475647,
无人机当前在空中,回到广场,对长发可疑男子进行拍照。,1,True,5.365821123123169,
1 instruction run_id success latency error
2 无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。 1 True 7.12662148475647
3 无人机当前在空中,回到广场,对长发可疑男子进行拍照。 1 True 5.365821123123169

View File

@@ -0,0 +1,3 @@
Instruction,Total Runs,Success Runs,Success Rate,Avg Latency
无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。,1,1,100.0%,7.13s
无人机当前在空中,回到广场,对长发可疑男子进行拍照。,1,1,100.0%,5.37s
1 Instruction Total Runs Success Runs Success Rate Avg Latency
2 无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。 1 1 100.0% 7.13s
3 无人机当前在空中,回到广场,对长发可疑男子进行拍照。 1 1 100.0% 5.37s

View File

@@ -0,0 +1,2 @@
无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。
无人机当前在空中,回到广场,对长发可疑男子进行拍照。

View File

@@ -0,0 +1,3 @@
instruction,run_id,success,latency,error
无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。,1,True,7.271864414215088,
无人机当前在空中,回到广场,对长发可疑男子进行拍照。,1,True,4.198384046554565,
1 instruction run_id success latency error
2 无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。 1 True 7.271864414215088
3 无人机当前在空中,回到广场,对长发可疑男子进行拍照。 1 True 4.198384046554565

View File

@@ -0,0 +1,3 @@
Instruction,Total Runs,Success Runs,Success Rate,Avg Latency
无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。,1,1,100.0%,7.27s
无人机当前在空中,回到广场,对长发可疑男子进行拍照。,1,1,100.0%,4.20s
1 Instruction Total Runs Success Runs Success Rate Avg Latency
2 无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。 1 1 100.0% 7.27s
3 无人机当前在空中,回到广场,对长发可疑男子进行拍照。 1 1 100.0% 4.20s

View File

@@ -0,0 +1,2 @@
无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。
无人机当前在空中,回到广场,对长发可疑男子进行拍照。

View File

@@ -0,0 +1,3 @@
instruction,run_id,success,latency,error
无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。,1,True,6.254483222961426,
无人机当前在空中,回到广场,对长发可疑男子进行拍照。,1,True,4.200452089309692,
1 instruction run_id success latency error
2 无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。 1 True 6.254483222961426
3 无人机当前在空中,回到广场,对长发可疑男子进行拍照。 1 True 4.200452089309692

View File

@@ -0,0 +1,3 @@
Instruction,Total Runs,Success Runs,Success Rate,Avg Latency
无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。,1,1,100.0%,6.25s
无人机当前在空中,回到广场,对长发可疑男子进行拍照。,1,1,100.0%,4.20s
1 Instruction Total Runs Success Runs Success Rate Avg Latency
2 无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。 1 1 100.0% 6.25s
3 无人机当前在空中,回到广场,对长发可疑男子进行拍照。 1 1 100.0% 4.20s

View File

@@ -0,0 +1,10 @@
无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。
无人机当前在空中,回到广场,对戴帽子的人进行拍照。
无人机当前在空中去广场西边200米,对过往的公交车拍张照,然后返航。
无人机当前在空中,到广场查找绿色公交车,看见了拍个照片。
无人机当前在空中,搜索小汽车,搜索到了我确认后再决定要不要拍照。
无人机当前在空中往东边飞50米,停个20s就好返航了。
无人机当前在空中,到广场边上的施工区域内,发现有没带安全帽的飞近后拍照。
无人机当前在空中,紧急回到广场,看见了红绿灯之后直接降落。
无人机当前在空中快速去往东边100米,有身穿黑色衣服,头戴帽子的男子在挟持他人,对其进行拍照。
无人机当前在空中,离黑色衣服戴帽子的人太远了照片看不清,贴近到3米距离拍,拍完司以直接返航。

View File

@@ -0,0 +1,11 @@
instruction,run_id,success,latency,error
"无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。",1,True,6.352114677429199,
"无人机当前在空中,回到广场,对戴帽子的人进行拍照。",1,True,5.022204637527466,
"无人机当前在空中去广场西边200米,对过往的公交车拍张照,然后返航。",1,True,3.8677239418029785,
"无人机当前在空中,到广场查找绿色公交车,看见了拍个照片。",1,True,4.64957594871521,
"无人机当前在空中,搜索小汽车,搜索到了我确认后再决定要不要拍照。",1,True,3.5267481803894043,
"无人机当前在空中往东边飞50米,停个20s就好返航了。",1,True,0.8441617488861084,
"无人机当前在空中,到广场边上的施工区域内,发现有没带安全帽的飞近后拍照。",1,True,4.096853733062744,
"无人机当前在空中,紧急回到广场,看见了红绿灯之后直接降落。",1,True,2.7230677604675293,
"无人机当前在空中快速去往东边100米,有身穿黑色衣服,头戴帽子的男子在挟持他人,对其进行拍照。",1,True,5.245810031890869,
"无人机当前在空中,离黑色衣服戴帽子的人太远了照片看不清,贴近到3米距离拍,拍完司以直接返航。",1,True,2.8097290992736816,
1 instruction run_id success latency error
2 无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。 1 True 6.352114677429199
3 无人机当前在空中,回到广场,对戴帽子的人进行拍照。 1 True 5.022204637527466
4 无人机当前在空中,去广场西边200米,对过往的公交车拍张照,然后返航。 1 True 3.8677239418029785
5 无人机当前在空中,到广场查找绿色公交车,看见了拍个照片。 1 True 4.64957594871521
6 无人机当前在空中,搜索小汽车,搜索到了我确认后再决定要不要拍照。 1 True 3.5267481803894043
7 无人机当前在空中,往东边飞50米,停个20s就好返航了。 1 True 0.8441617488861084
8 无人机当前在空中,到广场边上的施工区域内,发现有没带安全帽的飞近后拍照。 1 True 4.096853733062744
9 无人机当前在空中,紧急回到广场,看见了红绿灯之后直接降落。 1 True 2.7230677604675293
10 无人机当前在空中,快速去往东边100米,有身穿黑色衣服,头戴帽子的男子在挟持他人,对其进行拍照。 1 True 5.245810031890869
11 无人机当前在空中,离黑色衣服戴帽子的人太远了照片看不清,贴近到3米距离拍,拍完司以直接返航。 1 True 2.8097290992736816

View File

@@ -0,0 +1,11 @@
Instruction,Total Runs,Success Runs,Success Rate,Avg Latency
"无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。",1,1,100.0%,6.35s
"无人机当前在空中,回到广场,对戴帽子的人进行拍照。",1,1,100.0%,5.02s
"无人机当前在空中去广场西边200米,对过往的公交车拍张照,然后返航。",1,1,100.0%,3.87s
"无人机当前在空中,到广场查找绿色公交车,看见了拍个照片。",1,1,100.0%,4.65s
"无人机当前在空中,搜索小汽车,搜索到了我确认后再决定要不要拍照。",1,1,100.0%,3.53s
"无人机当前在空中往东边飞50米,停个20s就好返航了。",1,1,100.0%,0.84s
"无人机当前在空中,到广场边上的施工区域内,发现有没带安全帽的飞近后拍照。",1,1,100.0%,4.10s
"无人机当前在空中,紧急回到广场,看见了红绿灯之后直接降落。",1,1,100.0%,2.72s
"无人机当前在空中快速去往东边100米,有身穿黑色衣服,头戴帽子的男子在挟持他人,对其进行拍照。",1,1,100.0%,5.25s
"无人机当前在空中,离黑色衣服戴帽子的人太远了照片看不清,贴近到3米距离拍,拍完司以直接返航。",1,1,100.0%,2.81s
1 Instruction Total Runs Success Runs Success Rate Avg Latency
2 无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。 1 1 100.0% 6.35s
3 无人机当前在空中,回到广场,对戴帽子的人进行拍照。 1 1 100.0% 5.02s
4 无人机当前在空中,去广场西边200米,对过往的公交车拍张照,然后返航。 1 1 100.0% 3.87s
5 无人机当前在空中,到广场查找绿色公交车,看见了拍个照片。 1 1 100.0% 4.65s
6 无人机当前在空中,搜索小汽车,搜索到了我确认后再决定要不要拍照。 1 1 100.0% 3.53s
7 无人机当前在空中,往东边飞50米,停个20s就好返航了。 1 1 100.0% 0.84s
8 无人机当前在空中,到广场边上的施工区域内,发现有没带安全帽的飞近后拍照。 1 1 100.0% 4.10s
9 无人机当前在空中,紧急回到广场,看见了红绿灯之后直接降落。 1 1 100.0% 2.72s
10 无人机当前在空中,快速去往东边100米,有身穿黑色衣服,头戴帽子的男子在挟持他人,对其进行拍照。 1 1 100.0% 5.25s
11 无人机当前在空中,离黑色衣服戴帽子的人太远了照片看不清,贴近到3米距离拍,拍完司以直接返航。 1 1 100.0% 2.81s

View File

@@ -0,0 +1,10 @@
无人机当前在地面,到广场查找穿黄色衣服的男子,找到后近距离拍照。
无人机当前在空中,回到广场,对戴帽子的人进行拍照。
无人机当前在空中去广场西边200米,对过往的公交车拍张照,然后返航。
无人机当前在空中,到广场查找绿色公交车,看见了拍个照片。
无人机当前在空中,搜索小汽车,搜索到了我确认后再决定要不要拍照。
无人机当前在空中往东边飞50米,停个20s就好返航了。
无人机当前在空中,到广场边上的施工区域内,发现有没带安全帽的飞近后拍照。
无人机当前在空中,紧急回到广场,看见了红绿灯之后直接降落。
无人机当前在空中快速去往东边100米,有身穿黑色衣服,头戴帽子的男子在挟持他人,对其进行拍照。
无人机当前在空中,离黑色衣服戴帽子的人太远了照片看不清,贴近到3米距离拍,拍完司以直接返航。

Some files were not shown because too many files have changed in this diff Show More