616 lines
24 KiB
Python
616 lines
24 KiB
Python
"""
|
||
路径规划算法插件主文件
|
||
提供多种路径规划算法的实现和可视化工具
|
||
"""
|
||
|
||
import time
|
||
import json
|
||
from plugins.plugin_manager import BasePlugin
|
||
from .core.algorithm_manager import AlgorithmManager
|
||
from .visualization.visualization_manager import VisualizationManager
|
||
from .editor.pathfinding_editor import PathfindingEditor
|
||
|
||
class Plugin(BasePlugin):
|
||
"""
|
||
路径规划算法插件
|
||
提供多种经典和现代路径规划算法的实现
|
||
"""
|
||
|
||
def __init__(self, plugin_manager, name):
|
||
super().__init__(plugin_manager, name)
|
||
self.config = {
|
||
"version": "1.0.0",
|
||
"author": "EG Team",
|
||
"description": "路径规划算法插件,包含多种经典和现代路径规划算法实现"
|
||
}
|
||
|
||
# 核心组件
|
||
self.algorithm_manager = None
|
||
self.visualization_manager = None
|
||
self.editor = None
|
||
|
||
# GUI元素
|
||
self.gui_elements = []
|
||
|
||
# 事件处理器
|
||
self.event_handlers = {}
|
||
|
||
# 插件状态
|
||
self.is_initialized = False
|
||
self.is_enabled = False
|
||
|
||
# 性能监控
|
||
self.performance_stats = {
|
||
'initialization_time': 0.0,
|
||
'enable_time': 0.0,
|
||
'last_update_time': 0.0,
|
||
'total_updates': 0
|
||
}
|
||
|
||
# 当前场景数据
|
||
self.current_grid = None
|
||
self.current_start = (0, 0)
|
||
self.current_goal = (9, 9)
|
||
|
||
def initialize(self) -> bool:
|
||
"""
|
||
初始化插件
|
||
"""
|
||
try:
|
||
if self.is_initialized:
|
||
return True
|
||
|
||
init_start_time = time.time()
|
||
print(f"初始化路径规划算法插件: {self.name}")
|
||
|
||
# 初始化算法管理器
|
||
self.algorithm_manager = AlgorithmManager()
|
||
|
||
# 初始化可视化管理器
|
||
self.visualization_manager = VisualizationManager(self.plugin_manager.world)
|
||
|
||
# 初始化编辑器
|
||
self.editor = PathfindingEditor(
|
||
self.plugin_manager.world,
|
||
self.algorithm_manager,
|
||
self.visualization_manager
|
||
)
|
||
|
||
self.is_initialized = True
|
||
self.performance_stats['initialization_time'] = time.time() - init_start_time
|
||
print("✓ 路径规划算法插件初始化完成")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 路径规划算法插件初始化失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def enable(self) -> bool:
|
||
"""
|
||
启用插件
|
||
"""
|
||
if not super().enable():
|
||
return False
|
||
|
||
if self.is_enabled:
|
||
return True
|
||
|
||
try:
|
||
enable_start_time = time.time()
|
||
print(f"启用路径规划算法插件: {self.name}")
|
||
|
||
# 启用可视化管理器
|
||
if self.visualization_manager:
|
||
self.visualization_manager.enable()
|
||
|
||
# 注册事件处理器
|
||
self._register_event_handlers()
|
||
|
||
# 创建GUI界面
|
||
self._create_gui()
|
||
|
||
self.is_enabled = True
|
||
self.performance_stats['enable_time'] = time.time() - enable_start_time
|
||
print("✓ 路径规划算法插件启用成功")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 路径规划算法插件启用失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def disable(self) -> bool:
|
||
"""
|
||
禁用插件
|
||
"""
|
||
if not super().disable():
|
||
return False
|
||
|
||
if not self.is_enabled:
|
||
return True
|
||
|
||
try:
|
||
print(f"禁用路径规划算法插件: {self.name}")
|
||
|
||
# 清理GUI界面
|
||
self._cleanup_gui()
|
||
|
||
# 移除事件处理器
|
||
self._unregister_event_handlers()
|
||
|
||
# 禁用可视化管理器
|
||
if self.visualization_manager:
|
||
self.visualization_manager.disable()
|
||
|
||
self.is_enabled = False
|
||
print("✓ 路径规划算法插件禁用成功")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 路径规划算法插件禁用失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def finalize(self):
|
||
"""
|
||
清理插件资源
|
||
"""
|
||
print(f"清理路径规划算法插件资源: {self.name}")
|
||
|
||
# 清理所有组件
|
||
if self.editor:
|
||
self.editor.cleanup()
|
||
self.editor = None
|
||
|
||
if self.visualization_manager:
|
||
self.visualization_manager.cleanup()
|
||
self.visualization_manager = None
|
||
|
||
if self.algorithm_manager:
|
||
self.algorithm_manager = None
|
||
|
||
self.is_initialized = False
|
||
self.is_enabled = False
|
||
self.current_grid = None
|
||
|
||
def _register_event_handlers(self):
|
||
"""
|
||
注册事件处理器
|
||
"""
|
||
world = self.plugin_manager.world
|
||
|
||
# 路径规划系统控制快捷键
|
||
self.event_handlers['f1'] = self.toggle_editor
|
||
self.event_handlers['f2'] = self.toggle_visualization
|
||
self.event_handlers['f3'] = self.run_demo
|
||
self.event_handlers['f4'] = self.clear_visualization
|
||
self.event_handlers['f5'] = self.compare_algorithms
|
||
self.event_handlers['f6'] = self.show_stats
|
||
self.event_handlers['f7'] = self.generate_report
|
||
self.event_handlers['f8'] = self.optimize_paths
|
||
self.event_handlers['f9'] = self.generate_random_scenario
|
||
self.event_handlers['f10'] = self.toggle_animation
|
||
self.event_handlers['f11'] = self.show_algorithm_info
|
||
self.event_handlers['f12'] = self.export_detailed_report
|
||
|
||
# 注册事件
|
||
for event, handler in self.event_handlers.items():
|
||
world.accept(event, handler)
|
||
world.accept(event.upper(), handler) # 同时注册大写事件
|
||
|
||
def _unregister_event_handlers(self):
|
||
"""
|
||
移除事件处理器
|
||
"""
|
||
world = self.plugin_manager.world
|
||
|
||
for event in self.event_handlers.keys():
|
||
world.ignore(event)
|
||
world.ignore(event.upper())
|
||
|
||
self.event_handlers.clear()
|
||
|
||
def _create_gui(self):
|
||
"""
|
||
创建GUI界面
|
||
"""
|
||
try:
|
||
world = self.plugin_manager.world
|
||
|
||
# 检查是否有GUI管理器
|
||
if not hasattr(world, 'gui_manager') or not world.gui_manager:
|
||
print("⚠ GUI管理器不可用,跳过GUI创建")
|
||
return
|
||
|
||
gui_manager = world.gui_manager
|
||
|
||
# 创建路径规划控制面板
|
||
panel_button = gui_manager.createGUIButton(
|
||
pos=(0.02, 0, 0.75),
|
||
text="路径规划",
|
||
size=0.06
|
||
)
|
||
self.gui_elements.append(panel_button)
|
||
|
||
# 创建功能按钮
|
||
functions = [
|
||
("编辑器 [F1]", self.toggle_editor),
|
||
("可视化 [F2]", self.toggle_visualization),
|
||
("运行演示 [F3]", self.run_demo),
|
||
("清除视图 [F4]", self.clear_visualization),
|
||
("算法比较 [F5]", self.compare_algorithms),
|
||
("显示统计 [F6]", self.show_stats),
|
||
("生成报告 [F7]", self.generate_report),
|
||
("优化路径 [F8]", self.optimize_paths),
|
||
("随机场景 [F9]", self.generate_random_scenario),
|
||
("动画切换 [F10]", self.toggle_animation),
|
||
("算法信息 [F11]", self.show_algorithm_info),
|
||
("导出报告 [F12]", self.export_detailed_report)
|
||
]
|
||
|
||
for i, (name, callback) in enumerate(functions):
|
||
button = gui_manager.createGUIButton(
|
||
pos=(0.02, 0, 0.68 - i * 0.055),
|
||
text=name,
|
||
size=0.045
|
||
)
|
||
self.gui_elements.append(button)
|
||
world.accept(f"pathfinding_function_{i}", callback)
|
||
|
||
except Exception as e:
|
||
print(f"⚠ GUI创建失败: {e}")
|
||
|
||
def _cleanup_gui(self):
|
||
"""
|
||
清理GUI界面
|
||
"""
|
||
try:
|
||
world = self.plugin_manager.world
|
||
|
||
if hasattr(world, 'gui_manager') and world.gui_manager:
|
||
gui_manager = world.gui_manager
|
||
|
||
# 删除所有GUI元素
|
||
for element in self.gui_elements:
|
||
gui_manager.deleteGUIElement(element)
|
||
|
||
self.gui_elements.clear()
|
||
|
||
except Exception as e:
|
||
print(f"⚠ GUI清理失败: {e}")
|
||
|
||
# 事件处理方法
|
||
def toggle_editor(self):
|
||
"""切换编辑器显示"""
|
||
if self.editor:
|
||
self.editor.toggle_visibility()
|
||
print("✓ 编辑器显示已切换")
|
||
|
||
def toggle_visualization(self):
|
||
"""切换可视化显示"""
|
||
if self.visualization_manager:
|
||
self.visualization_manager.toggle_visibility()
|
||
print("✓ 可视化显示已切换")
|
||
|
||
def run_demo(self):
|
||
"""运行演示"""
|
||
if self.algorithm_manager and self.visualization_manager:
|
||
print("✓ 运行路径规划演示...")
|
||
# 运行一个简单的演示
|
||
from .utils.demo_scenarios import create_simple_grid
|
||
self.current_grid = create_simple_grid(10, 10)
|
||
self.current_start = (0, 0)
|
||
self.current_goal = (9, 9)
|
||
|
||
# 使用A*算法查找路径
|
||
path, stats = self.algorithm_manager.find_path("astar", self.current_grid, self.current_start, self.current_goal)
|
||
|
||
if path:
|
||
print(f"✓ 找到路径,长度: {len(path)}")
|
||
print(f" 访问节点数: {stats.get('nodes_visited', 0)}")
|
||
print(f" 耗时: {stats.get('time_taken', 0):.6f}秒")
|
||
# 可视化路径
|
||
self.visualization_manager.visualize_path(path, self.current_grid)
|
||
self.visualization_manager.visualize_grid(self.current_grid)
|
||
else:
|
||
print("✗ 未找到路径")
|
||
|
||
def clear_visualization(self):
|
||
"""清除可视化"""
|
||
if self.visualization_manager:
|
||
self.visualization_manager.clear_visualization()
|
||
print("✓ 可视化已清除")
|
||
|
||
def compare_algorithms(self):
|
||
"""比较算法性能"""
|
||
if self.algorithm_manager:
|
||
print("✓ 比较路径规划算法...")
|
||
from .utils.demo_scenarios import create_simple_grid
|
||
self.current_grid = create_simple_grid(20, 20)
|
||
self.current_start = (0, 0)
|
||
self.current_goal = (19, 19)
|
||
|
||
algorithms = ["astar", "dijkstra", "bfs", "dfs"]
|
||
results = {}
|
||
|
||
for algorithm in algorithms:
|
||
path, stats = self.algorithm_manager.find_path(algorithm, self.current_grid, self.current_start, self.current_goal)
|
||
results[algorithm] = {
|
||
"path_length": len(path) if path else 0,
|
||
"nodes_visited": stats.get("nodes_visited", 0),
|
||
"time_taken": stats.get("time_taken", 0),
|
||
"success": stats.get("success", False)
|
||
}
|
||
|
||
print("=== 算法性能比较 ===")
|
||
for algorithm, result in results.items():
|
||
print(f"{algorithm}:")
|
||
print(f" 路径长度: {result['path_length']}")
|
||
print(f" 访问节点数: {result['nodes_visited']}")
|
||
print(f" 耗时: {result['time_taken']:.6f}秒")
|
||
print(f" 成功: {'是' if result['success'] else '否'}")
|
||
|
||
def show_stats(self):
|
||
"""显示统计信息"""
|
||
if self.algorithm_manager:
|
||
stats = self.algorithm_manager.get_stats()
|
||
print("=== 路径规划算法统计 ===")
|
||
for key, value in stats.items():
|
||
if key != 'algorithm_usage':
|
||
print(f" {key}: {value}")
|
||
print(" 算法使用统计:")
|
||
for algo, count in stats.get('algorithm_usage', {}).items():
|
||
print(f" {algo}: {count}次")
|
||
|
||
def generate_report(self):
|
||
"""生成报告"""
|
||
if self.algorithm_manager:
|
||
print("✓ 生成路径规划算法报告...")
|
||
report = self.algorithm_manager.generate_report()
|
||
# 简化输出报告摘要
|
||
print(f"报告生成时间: {time.ctime(report.get('timestamp', 0))}")
|
||
print(f"总算法数: {len(report.get('algorithms', []))}")
|
||
print(f"总测试数: {report.get('total_tests', 0)}")
|
||
print(f"成功率: {report.get('success_rate', 0):.2%}")
|
||
|
||
def optimize_paths(self):
|
||
"""优化路径"""
|
||
print("✓ 路径优化功能...")
|
||
if self.current_grid and self.algorithm_manager:
|
||
# 根据网格特点推荐算法
|
||
rows = len(self.current_grid)
|
||
cols = len(self.current_grid[0]) if rows > 0 else 0
|
||
obstacle_count = sum(sum(row) for row in self.current_grid)
|
||
obstacle_density = obstacle_count / (rows * cols) if rows * cols > 0 else 0
|
||
|
||
recommended_algo = self.algorithm_manager.get_algorithm_recommendation(
|
||
(rows, cols), obstacle_density, True)
|
||
print(f" 根据当前场景特点推荐算法: {recommended_algo}")
|
||
|
||
def generate_random_scenario(self):
|
||
"""生成随机场景"""
|
||
if self.visualization_manager:
|
||
print("✓ 生成随机路径规划场景...")
|
||
from .utils.demo_scenarios import create_random_grid
|
||
self.current_grid = create_random_grid(15, 15, 0.25) # 25%障碍物
|
||
self.current_start = (0, 0)
|
||
self.current_goal = (14, 14)
|
||
|
||
self.visualization_manager.visualize_grid(self.current_grid)
|
||
print("✓ 随机场景已生成")
|
||
|
||
def toggle_animation(self):
|
||
"""切换动画"""
|
||
if self.visualization_manager:
|
||
# 这里可以实现动画切换逻辑
|
||
print("✓ 动画切换功能待实现...")
|
||
|
||
def show_algorithm_info(self):
|
||
"""显示算法信息"""
|
||
if self.algorithm_manager:
|
||
algorithms = self.algorithm_manager.get_available_algorithms()
|
||
print("=== 可用算法信息 ===")
|
||
for algo in algorithms:
|
||
description = self.algorithm_manager.get_algorithm_description(algo)
|
||
complexity = self.algorithm_manager.get_algorithm_complexity(algo)
|
||
print(f"{algo}:")
|
||
print(f" 描述: {description}")
|
||
print(f" 复杂度: {complexity}")
|
||
print()
|
||
|
||
def export_detailed_report(self):
|
||
"""导出详细报告"""
|
||
if self.algorithm_manager:
|
||
print("✓ 导出详细报告...")
|
||
timestamp = int(time.time())
|
||
filename = f"pathfinding_report_{timestamp}.json"
|
||
success = self.algorithm_manager.export_report(filename)
|
||
if success:
|
||
print(f"✓ 详细报告已导出到: {filename}")
|
||
else:
|
||
print("✗ 导出详细报告失败")
|
||
|
||
def get_info(self) -> dict:
|
||
"""
|
||
获取插件信息
|
||
"""
|
||
info = super().get_info()
|
||
info.update({
|
||
"version": self.config.get("version", "1.0.0"),
|
||
"author": self.config.get("author", "EG Team"),
|
||
"description": self.config.get("description", "路径规划算法插件"),
|
||
"is_enabled": self.is_enabled,
|
||
"is_initialized": self.is_initialized,
|
||
"available_algorithms": self.algorithm_manager.get_available_algorithms() if self.algorithm_manager else []
|
||
})
|
||
return info
|
||
|
||
# 公共接口方法
|
||
def find_path(self, algorithm, grid, start, goal):
|
||
"""查找路径"""
|
||
if self.algorithm_manager:
|
||
return self.algorithm_manager.find_path(algorithm, grid, start, goal)
|
||
return None, {}
|
||
|
||
def add_algorithm(self, name, algorithm_class, description=""):
|
||
"""添加新算法"""
|
||
if self.algorithm_manager:
|
||
self.algorithm_manager.add_algorithm(name, algorithm_class, description)
|
||
|
||
def remove_algorithm(self, name):
|
||
"""移除算法"""
|
||
if self.algorithm_manager:
|
||
self.algorithm_manager.remove_algorithm(name)
|
||
|
||
def get_available_algorithms(self):
|
||
"""获取可用算法列表"""
|
||
if self.algorithm_manager:
|
||
return self.algorithm_manager.get_available_algorithms()
|
||
return []
|
||
|
||
def get_algorithm_description(self, algorithm):
|
||
"""获取算法描述"""
|
||
if self.algorithm_manager:
|
||
return self.algorithm_manager.get_algorithm_description(algorithm)
|
||
return ""
|
||
|
||
def set_algorithm_parameter(self, algorithm, parameter, value):
|
||
"""设置算法参数"""
|
||
if self.algorithm_manager:
|
||
self.algorithm_manager.set_algorithm_parameter(algorithm, parameter, value)
|
||
|
||
def get_algorithm_parameters(self, algorithm):
|
||
"""获取算法参数"""
|
||
if self.algorithm_manager:
|
||
return self.algorithm_manager.get_algorithm_parameters(algorithm)
|
||
return {}
|
||
|
||
def visualize_path(self, path, grid=None):
|
||
"""可视化路径"""
|
||
if self.visualization_manager:
|
||
self.visualization_manager.visualize_path(path, grid)
|
||
|
||
def visualize_grid(self, grid):
|
||
"""可视化网格"""
|
||
if self.visualization_manager:
|
||
self.visualization_manager.visualize_grid(grid)
|
||
|
||
def visualize_visited_nodes(self, visited_nodes):
|
||
"""可视化已访问节点"""
|
||
if self.visualization_manager:
|
||
self.visualization_manager.visualize_visited_nodes(visited_nodes)
|
||
|
||
def visualize_open_list(self, open_list):
|
||
"""可视化开放列表"""
|
||
if self.visualization_manager:
|
||
self.visualization_manager.visualize_open_list(open_list)
|
||
|
||
def clear_path_visualization(self):
|
||
"""清除路径可视化"""
|
||
if self.visualization_manager:
|
||
self.visualization_manager.clear_path_visualization()
|
||
|
||
def set_visualization_settings(self, settings):
|
||
"""设置可视化参数"""
|
||
if self.visualization_manager:
|
||
self.visualization_manager.set_settings(settings)
|
||
|
||
def get_visualization_settings(self):
|
||
"""获取可视化参数"""
|
||
if self.visualization_manager:
|
||
return self.visualization_manager.get_settings()
|
||
return {}
|
||
|
||
def enable_visualization_animation(self, enable=True):
|
||
"""启用可视化动画"""
|
||
if self.visualization_manager:
|
||
self.visualization_manager.enable_animation(enable)
|
||
|
||
def update(self, dt: float):
|
||
"""更新插件状态"""
|
||
self.performance_stats['total_updates'] += 1
|
||
self.performance_stats['last_update_time'] = time.time()
|
||
|
||
# 更新编辑器
|
||
if self.editor:
|
||
self.editor.update(dt)
|
||
|
||
# 更新可视化动画
|
||
if self.visualization_manager:
|
||
self.visualization_manager.update_animation(dt)
|
||
|
||
def batch_test_algorithms(self, algorithms, test_cases):
|
||
"""批量测试算法"""
|
||
if self.algorithm_manager:
|
||
return self.algorithm_manager.batch_test(algorithms, test_cases)
|
||
return {}
|
||
|
||
def compare_algorithms_detailed(self, algorithms, grid, start, goal):
|
||
"""详细比较算法"""
|
||
if self.algorithm_manager:
|
||
return self.algorithm_manager.compare_algorithms(algorithms, grid, start, goal)
|
||
return {}
|
||
|
||
def get_cached_performance_data(self, algorithm):
|
||
"""获取缓存的性能数据"""
|
||
if self.algorithm_manager:
|
||
return self.algorithm_manager.get_cached_performance_data(algorithm)
|
||
return []
|
||
|
||
def clear_performance_cache(self):
|
||
"""清除性能缓存"""
|
||
if self.algorithm_manager:
|
||
self.algorithm_manager.clear_performance_cache()
|
||
|
||
def reset_statistics(self):
|
||
"""重置统计信息"""
|
||
if self.algorithm_manager:
|
||
self.algorithm_manager.reset_stats()
|
||
print("✓ 统计信息已重置")
|
||
|
||
def validate_grid_data(self, grid):
|
||
"""验证网格数据"""
|
||
if self.algorithm_manager:
|
||
return self.algorithm_manager.validate_grid(grid)
|
||
return {'valid': False, 'error': '算法管理器未初始化'}
|
||
|
||
def get_algorithm_complexity(self, algorithm):
|
||
"""获取算法复杂度信息"""
|
||
if self.algorithm_manager:
|
||
return self.algorithm_manager.get_algorithm_complexity(algorithm)
|
||
return "未知"
|
||
|
||
def benchmark_algorithm(self, algorithm, grid, start, goal, iterations=100):
|
||
"""对算法进行基准测试"""
|
||
if self.algorithm_manager and algorithm in self.algorithm_manager.algorithms:
|
||
# 创建算法实例
|
||
algo_class = self.algorithm_manager.algorithms[algorithm]
|
||
algo_instance = algo_class()
|
||
|
||
# 设置参数
|
||
if algorithm in self.algorithm_manager.algorithm_parameters:
|
||
for param, value in self.algorithm_manager.algorithm_parameters[algorithm].items():
|
||
if hasattr(algo_instance, param):
|
||
setattr(algo_instance, param, value)
|
||
|
||
# 执行基准测试
|
||
if hasattr(algo_instance, 'benchmark'):
|
||
return algo_instance.benchmark(grid, start, goal, iterations)
|
||
else:
|
||
print(f"算法 {algorithm} 不支持基准测试")
|
||
return {}
|
||
return {}
|
||
|
||
def optimize_algorithm_for_grid(self, algorithm, grid):
|
||
"""为特定网格优化算法"""
|
||
if algorithm == 'jps' and self.algorithm_manager:
|
||
from .algorithms.jps import JPS
|
||
jps_instance = JPS()
|
||
jps_instance.optimize_for_map(grid)
|
||
print(f"✓ JPS算法已为当前网格优化")
|
||
else:
|
||
print(f"算法 {algorithm} 不支持自动优化") |