增加环绕侦察场景适配

This commit is contained in:
2026-01-08 15:44:38 +08:00
parent 3eba1f962b
commit 10c5bb5a8a
5441 changed files with 40219 additions and 379695 deletions

View File

@@ -0,0 +1,101 @@
import os
import json
import logging
import time
from .visualizer import generate_visualization
# 配置日志
logging.basicConfig(level=logging.INFO, format='%(message)s')
def run_json_visualization():
print("\n🚀 进入 JSON 文件可视化模式")
print("说明: 读取包含行为树(Pytree)结构的 JSON 文件并生成 PNG 图片。")
print(" 支持的 JSON 结构: 直接是 Pytree 根节点对象,或包含 'root'/'data' 字段的对象。")
while True:
try:
file_path = input("\n请输入 JSON 文件路径 (输入 'q' 返回): ").strip()
if file_path.lower() in ['q', 'exit', 'quit']:
break
if not file_path:
continue
# 处理相对路径
if not os.path.isabs(file_path):
# 尝试相对于当前工作目录
if not os.path.exists(file_path):
# 尝试相对于 tools/test_validate
base_dir = os.path.dirname(os.path.dirname(__file__))
alt_path = os.path.join(base_dir, file_path)
if os.path.exists(alt_path):
file_path = alt_path
if not os.path.exists(file_path):
print(f"❌ 文件不存在: {file_path}")
continue
if not os.path.isfile(file_path):
print(f"❌ 路径不是一个文件: {file_path}")
continue
print(f"📖 正在读取: {file_path}")
try:
with open(file_path, 'r', encoding='utf-8') as f:
data = json.load(f)
except json.JSONDecodeError as e:
print(f"❌ JSON 解析失败: {e}")
continue
except Exception as e:
print(f"❌ 读取文件失败: {e}")
continue
# 尝试提取 root 节点
root_node = None
# 情况 1: 顶层就是 root 节点 (包含 name 和 type)
if isinstance(data, dict) and 'name' in data and 'type' in data:
root_node = data
print(" 识别到顶层即为 Pytree 根节点")
# 情况 2: 包含 root 字段
elif isinstance(data, dict) and 'root' in data:
root_node = data['root']
print("'root' 字段提取节点")
# 情况 3: 包含 data 字段data 里有 root
elif isinstance(data, dict) and 'data' in data and isinstance(data['data'], dict) and 'root' in data['data']:
root_node = data['data']['root']
print("'data.root' 字段提取节点")
# 情况 4: 包含 data 字段data 本身就是 root
elif isinstance(data, dict) and 'data' in data and isinstance(data['data'], dict) and 'name' in data['data']:
root_node = data['data']
print("'data' 字段提取节点")
if not root_node:
print("❌ 无法识别 Pytree 结构。JSON 对象必须包含 'name''type' 字段,或在 'root'/'data' 字段中包含它们。")
continue
# 生成输出路径
dir_name = os.path.dirname(file_path)
base_name = os.path.splitext(os.path.basename(file_path))[0]
output_path = os.path.join(dir_name, f"{base_name}.png")
print("🎨 正在生成可视化...")
if generate_visualization(root_node, output_path):
print(f"✅ 可视化图已生成: {output_path}")
# 尝试打开图片 (仅限支持的系统)
# if os.name == 'posix':
# os.system(f"xdg-open '{output_path}'")
else:
print("❌ 生成失败,请检查 graphviz 是否安装正确")
except KeyboardInterrupt:
print("\n已取消")
break
except Exception as e:
print(f"❌ 发生未预期的错误: {e}")
print("\n已返回主菜单")

View File

@@ -97,6 +97,11 @@ def _add_nodes_and_edges(node: dict, dot, parent_id: str | None = None) -> str:
shape = 'ellipse'
style = 'filled'
fillcolor = '#e1d5e7' # 紫色
elif node_type == 'decorator':
shape = 'diamond'
style = 'filled'
fillcolor = '#f5f5f5' # 浅灰
border_color = '#333333'
# 特别标记安全相关节点
if node.get('name') in ['battery_above', 'gps_status', 'SafetyMonitor']:
@@ -111,6 +116,11 @@ def _add_nodes_and_edges(node: dict, dot, parent_id: str | None = None) -> str:
# 递归处理子节点
children = node.get("children", [])
# 处理 decorator 类型的 child 字段(单一子节点)
if node_type == 'decorator' and 'child' in node:
children = [node['child']]
if not children:
return current_id

View File

@@ -11,6 +11,7 @@ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from modules.interactive_test import run_interactive_test
from modules.batch_runner import run_batch_test
from modules.json_visualizer import run_json_visualization
def clear_screen():
os.system('cls' if os.name == 'nt' else 'clear')
@@ -82,10 +83,11 @@ def main():
print(" - 读取指令文件,支持多轮压力测试,生成统计报告")
print("3. 上传任务到无人机 (Drone Uploader)")
print("4. LLM 服务连通性测试 (LLM Tester)")
print("5. JSON 文件可视化 (Visualize JSON File)")
print("0. 退出")
print("-" * 60)
choice = input("请输入选项 [0-4]: ").strip()
choice = input("请输入选项 [0-5]: ").strip()
if choice == '1':
try:
@@ -106,6 +108,9 @@ def main():
elif choice == '4':
run_legacy_module("llm_tester.py")
elif choice == '5':
run_json_visualization()
elif choice == '0':
print("\n👋 再见!")