diff --git a/Doc/~$人机后勤输送路径规划系统“软件设计规格说明书.doc b/Doc/~$人机后勤输送路径规划系统“软件设计规格说明书.doc new file mode 100644 index 00000000..3a1b11ea Binary files /dev/null and b/Doc/~$人机后勤输送路径规划系统“软件设计规格说明书.doc differ diff --git a/Src/command_center/__init__.py b/Src/command_center/__init__.py new file mode 100644 index 00000000..122acb7e --- /dev/null +++ b/Src/command_center/__init__.py @@ -0,0 +1 @@ +# 指挥控制中心包 \ No newline at end of file diff --git a/Src/command_center/main.py b/Src/command_center/main.py new file mode 100644 index 00000000..32baec59 --- /dev/null +++ b/Src/command_center/main.py @@ -0,0 +1,67 @@ +import sys +from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, + QHBoxLayout, QTabWidget, QPushButton, QLabel, + QGroupBox, QComboBox, QSpinBox, QDoubleSpinBox, + QProgressBar, QCheckBox) +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QFont +from ui.login_view import LoginView +from ui.main_view import MainView +from ui.map_view import MapView +from ui.threat_layer_view import ThreatLayerView +from ui.path_layer_view import PathLayerView +from ui.drone_list_view import DroneListView +from ui.drone_detail_view import DroneDetailView +from ui.status_dashboard import StatusDashboard +from ui.path_planning_view import PathPlanningView +from ui.algorithm_config_view import AlgorithmConfigView +from ui.path_simulation_view import PathSimulationView + +class CommandCenterApp(QMainWindow): + def __init__(self): + super().__init__() + self.init_ui() + + def init_ui(self): + # 设置窗口标题和大小 + self.setWindowTitle("无人机后勤输送系统 - 指挥控制中心") + self.setMinimumSize(1200, 800) + + # 创建主窗口部件 + central_widget = QWidget() + self.setCentralWidget(central_widget) + + # 创建主布局 + main_layout = QVBoxLayout(central_widget) + + # 创建标签页 + self.tab_widget = QTabWidget() + + # 添加各个功能标签页 + self.tab_widget.addTab(MapView(), "地图视图") + self.tab_widget.addTab(ThreatLayerView(), "威胁层") + self.tab_widget.addTab(PathLayerView(), "路径层") + self.tab_widget.addTab(DroneListView(), "无人机列表") + self.tab_widget.addTab(DroneDetailView(), "无人机详情") + self.tab_widget.addTab(StatusDashboard(), "状态仪表板") + self.tab_widget.addTab(PathPlanningView(), "路径规划") + self.tab_widget.addTab(AlgorithmConfigView(), "算法配置") + self.tab_widget.addTab(PathSimulationView(), "路径模拟") + + main_layout.addWidget(self.tab_widget) + + # 显示登录窗口 + self.show_login() + + def show_login(self): + self.login_view = LoginView() + self.login_view.show() + + # 连接登录成功信号 + # TODO: 实现登录成功后的处理逻辑 + +if __name__ == '__main__': + app = QApplication(sys.argv) + window = CommandCenterApp() + window.show() + sys.exit(app.exec_()) \ No newline at end of file diff --git a/Src/command_center/ui/__init__.py b/Src/command_center/ui/__init__.py new file mode 100644 index 00000000..db1f1c7a --- /dev/null +++ b/Src/command_center/ui/__init__.py @@ -0,0 +1 @@ +# UI组件包 \ No newline at end of file diff --git a/Src/command_center/ui/__pycache__/__init__.cpython-312.pyc b/Src/command_center/ui/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..d489b6e5 Binary files /dev/null and b/Src/command_center/ui/__pycache__/__init__.cpython-312.pyc differ diff --git a/Src/command_center/ui/__pycache__/algorithm_config_view.cpython-312.pyc b/Src/command_center/ui/__pycache__/algorithm_config_view.cpython-312.pyc new file mode 100644 index 00000000..cc912ff5 Binary files /dev/null and b/Src/command_center/ui/__pycache__/algorithm_config_view.cpython-312.pyc differ diff --git a/Src/command_center/ui/__pycache__/drone_detail_view.cpython-312.pyc b/Src/command_center/ui/__pycache__/drone_detail_view.cpython-312.pyc new file mode 100644 index 00000000..ccde15eb Binary files /dev/null and b/Src/command_center/ui/__pycache__/drone_detail_view.cpython-312.pyc differ diff --git a/Src/command_center/ui/__pycache__/drone_list_view.cpython-312.pyc b/Src/command_center/ui/__pycache__/drone_list_view.cpython-312.pyc new file mode 100644 index 00000000..48140a8a Binary files /dev/null and b/Src/command_center/ui/__pycache__/drone_list_view.cpython-312.pyc differ diff --git a/Src/command_center/ui/__pycache__/login_view.cpython-312.pyc b/Src/command_center/ui/__pycache__/login_view.cpython-312.pyc new file mode 100644 index 00000000..e840d68c Binary files /dev/null and b/Src/command_center/ui/__pycache__/login_view.cpython-312.pyc differ diff --git a/Src/command_center/ui/__pycache__/main_view.cpython-312.pyc b/Src/command_center/ui/__pycache__/main_view.cpython-312.pyc new file mode 100644 index 00000000..b781628c Binary files /dev/null and b/Src/command_center/ui/__pycache__/main_view.cpython-312.pyc differ diff --git a/Src/command_center/ui/__pycache__/map_view.cpython-312.pyc b/Src/command_center/ui/__pycache__/map_view.cpython-312.pyc new file mode 100644 index 00000000..4813c46c Binary files /dev/null and b/Src/command_center/ui/__pycache__/map_view.cpython-312.pyc differ diff --git a/Src/command_center/ui/__pycache__/path_layer_view.cpython-312.pyc b/Src/command_center/ui/__pycache__/path_layer_view.cpython-312.pyc new file mode 100644 index 00000000..c36f3922 Binary files /dev/null and b/Src/command_center/ui/__pycache__/path_layer_view.cpython-312.pyc differ diff --git a/Src/command_center/ui/__pycache__/path_planning_view.cpython-312.pyc b/Src/command_center/ui/__pycache__/path_planning_view.cpython-312.pyc new file mode 100644 index 00000000..ad35ab26 Binary files /dev/null and b/Src/command_center/ui/__pycache__/path_planning_view.cpython-312.pyc differ diff --git a/Src/command_center/ui/__pycache__/path_simulation_view.cpython-312.pyc b/Src/command_center/ui/__pycache__/path_simulation_view.cpython-312.pyc new file mode 100644 index 00000000..300a9620 Binary files /dev/null and b/Src/command_center/ui/__pycache__/path_simulation_view.cpython-312.pyc differ diff --git a/Src/command_center/ui/__pycache__/status_dashboard.cpython-312.pyc b/Src/command_center/ui/__pycache__/status_dashboard.cpython-312.pyc new file mode 100644 index 00000000..02dc1706 Binary files /dev/null and b/Src/command_center/ui/__pycache__/status_dashboard.cpython-312.pyc differ diff --git a/Src/command_center/ui/__pycache__/threat_layer_view.cpython-312.pyc b/Src/command_center/ui/__pycache__/threat_layer_view.cpython-312.pyc new file mode 100644 index 00000000..a5fefa0f Binary files /dev/null and b/Src/command_center/ui/__pycache__/threat_layer_view.cpython-312.pyc differ diff --git a/Src/command_center/ui/algorithm_config_view.py b/Src/command_center/ui/algorithm_config_view.py new file mode 100644 index 00000000..265299c4 --- /dev/null +++ b/Src/command_center/ui/algorithm_config_view.py @@ -0,0 +1,103 @@ +from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, + QPushButton, QGroupBox, QFormLayout, QComboBox, + QSpinBox, QDoubleSpinBox, QCheckBox) +from PyQt5.QtCore import Qt + +class AlgorithmConfigView(QWidget): + def __init__(self): + super().__init__() + self.init_ui() + + def init_ui(self): + # 创建主布局 + main_layout = QVBoxLayout() + + # 创建A*算法配置组 + astar_group = QGroupBox("A*算法配置") + astar_layout = QFormLayout() + + self.astar_heuristic = QComboBox() + self.astar_heuristic.addItems(["欧几里得距离", "曼哈顿距离", "对角线距离"]) + + self.astar_weight = QDoubleSpinBox() + self.astar_weight.setRange(0.1, 10.0) + self.astar_weight.setValue(1.0) + self.astar_weight.setSingleStep(0.1) + + astar_layout.addRow("启发函数:", self.astar_heuristic) + astar_layout.addRow("权重:", self.astar_weight) + + astar_group.setLayout(astar_layout) + main_layout.addWidget(astar_group) + + # 创建遗传算法配置组 + ga_group = QGroupBox("遗传算法配置") + ga_layout = QFormLayout() + + self.ga_population = QSpinBox() + self.ga_population.setRange(10, 1000) + self.ga_population.setValue(100) + + self.ga_generations = QSpinBox() + self.ga_generations.setRange(10, 1000) + self.ga_generations.setValue(100) + + self.ga_mutation_rate = QDoubleSpinBox() + self.ga_mutation_rate.setRange(0.01, 1.0) + self.ga_mutation_rate.setValue(0.1) + self.ga_mutation_rate.setSingleStep(0.01) + + ga_layout.addRow("种群大小:", self.ga_population) + ga_layout.addRow("迭代次数:", self.ga_generations) + ga_layout.addRow("变异率:", self.ga_mutation_rate) + + ga_group.setLayout(ga_layout) + main_layout.addWidget(ga_group) + + # 创建RRT算法配置组 + rrt_group = QGroupBox("RRT算法配置") + rrt_layout = QFormLayout() + + self.rrt_step_size = QDoubleSpinBox() + self.rrt_step_size.setRange(0.1, 10.0) + self.rrt_step_size.setValue(1.0) + self.rrt_step_size.setSingleStep(0.1) + + self.rrt_goal_bias = QDoubleSpinBox() + self.rrt_goal_bias.setRange(0.0, 1.0) + self.rrt_goal_bias.setValue(0.1) + self.rrt_goal_bias.setSingleStep(0.01) + + self.rrt_smooth_path = QCheckBox("平滑路径") + self.rrt_smooth_path.setChecked(True) + + rrt_layout.addRow("步长:", self.rrt_step_size) + rrt_layout.addRow("目标偏向:", self.rrt_goal_bias) + rrt_layout.addRow("", self.rrt_smooth_path) + + rrt_group.setLayout(rrt_layout) + main_layout.addWidget(rrt_group) + + # 创建控制按钮 + button_layout = QHBoxLayout() + self.save_config_btn = QPushButton("保存配置") + self.reset_config_btn = QPushButton("重置配置") + + button_layout.addWidget(self.save_config_btn) + button_layout.addWidget(self.reset_config_btn) + + main_layout.addLayout(button_layout) + + self.setLayout(main_layout) + + # 连接信号 + self.save_config_btn.clicked.connect(self.save_config) + self.reset_config_btn.clicked.connect(self.reset_config) + + def save_config(self): + # TODO: 实现保存配置功能 + pass + + def reset_config(self): + # TODO: 实现重置配置功能 + pass \ No newline at end of file diff --git a/Src/command_center/ui/drone_detail_view.py b/Src/command_center/ui/drone_detail_view.py new file mode 100644 index 00000000..cc0d6731 --- /dev/null +++ b/Src/command_center/ui/drone_detail_view.py @@ -0,0 +1,84 @@ +from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, + QPushButton, QGroupBox, QFormLayout) +from PyQt5.QtCore import Qt + +class DroneDetailView(QWidget): + def __init__(self): + super().__init__() + self.init_ui() + + def init_ui(self): + # 创建主布局 + main_layout = QVBoxLayout() + + # 创建基本信息组 + basic_info_group = QGroupBox("基本信息") + basic_layout = QFormLayout() + + self.id_label = QLabel("") + self.model_label = QLabel("") + self.status_label = QLabel("") + self.battery_label = QLabel("") + + basic_layout.addRow("ID:", self.id_label) + basic_layout.addRow("型号:", self.model_label) + basic_layout.addRow("状态:", self.status_label) + basic_layout.addRow("电量:", self.battery_label) + + basic_info_group.setLayout(basic_layout) + main_layout.addWidget(basic_info_group) + + # 创建位置信息组 + position_group = QGroupBox("位置信息") + position_layout = QFormLayout() + + self.latitude_label = QLabel("") + self.longitude_label = QLabel("") + self.altitude_label = QLabel("") + self.speed_label = QLabel("") + + position_layout.addRow("纬度:", self.latitude_label) + position_layout.addRow("经度:", self.longitude_label) + position_layout.addRow("高度:", self.altitude_label) + position_layout.addRow("速度:", self.speed_label) + + position_group.setLayout(position_layout) + main_layout.addWidget(position_group) + + # 创建控制按钮 + button_layout = QHBoxLayout() + self.takeoff_btn = QPushButton("起飞") + self.land_btn = QPushButton("降落") + self.return_btn = QPushButton("返航") + self.emergency_btn = QPushButton("紧急停止") + + button_layout.addWidget(self.takeoff_btn) + button_layout.addWidget(self.land_btn) + button_layout.addWidget(self.return_btn) + button_layout.addWidget(self.emergency_btn) + + main_layout.addLayout(button_layout) + + self.setLayout(main_layout) + + # 连接信号 + self.takeoff_btn.clicked.connect(self.takeoff) + self.land_btn.clicked.connect(self.land) + self.return_btn.clicked.connect(self.return_home) + self.emergency_btn.clicked.connect(self.emergency_stop) + + def takeoff(self): + # TODO: 实现起飞功能 + pass + + def land(self): + # TODO: 实现降落功能 + pass + + def return_home(self): + # TODO: 实现返航功能 + pass + + def emergency_stop(self): + # TODO: 实现紧急停止功能 + pass \ No newline at end of file diff --git a/Src/command_center/ui/drone_list_view.py b/Src/command_center/ui/drone_list_view.py new file mode 100644 index 00000000..5ce4fa4d --- /dev/null +++ b/Src/command_center/ui/drone_list_view.py @@ -0,0 +1,57 @@ +from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, + QPushButton, QTableWidget, QTableWidgetItem) +from PyQt5.QtCore import Qt + +class DroneListView(QWidget): + def __init__(self): + super().__init__() + self.init_ui() + + def init_ui(self): + # 创建主布局 + main_layout = QVBoxLayout() + + # 创建无人机列表 + self.drone_table = QTableWidget() + self.drone_table.setColumnCount(5) + self.drone_table.setHorizontalHeaderLabels(["ID", "型号", "状态", "位置", "电量"]) + self.drone_table.setStyleSheet("QTableWidget { border: 1px solid #ccc; }") + main_layout.addWidget(self.drone_table) + + # 创建控制按钮 + button_layout = QHBoxLayout() + self.add_drone_btn = QPushButton("添加无人机") + self.edit_drone_btn = QPushButton("编辑信息") + self.delete_drone_btn = QPushButton("删除无人机") + self.refresh_btn = QPushButton("刷新状态") + + button_layout.addWidget(self.add_drone_btn) + button_layout.addWidget(self.edit_drone_btn) + button_layout.addWidget(self.delete_drone_btn) + button_layout.addWidget(self.refresh_btn) + + main_layout.addLayout(button_layout) + + self.setLayout(main_layout) + + # 连接信号 + self.add_drone_btn.clicked.connect(self.add_drone) + self.edit_drone_btn.clicked.connect(self.edit_drone) + self.delete_drone_btn.clicked.connect(self.delete_drone) + self.refresh_btn.clicked.connect(self.refresh_status) + + def add_drone(self): + # TODO: 实现添加无人机功能 + pass + + def edit_drone(self): + # TODO: 实现编辑无人机信息功能 + pass + + def delete_drone(self): + # TODO: 实现删除无人机功能 + pass + + def refresh_status(self): + # TODO: 实现刷新状态功能 + pass \ No newline at end of file diff --git a/Src/command_center/ui/login_view.py b/Src/command_center/ui/login_view.py new file mode 100644 index 00000000..b256be98 --- /dev/null +++ b/Src/command_center/ui/login_view.py @@ -0,0 +1,69 @@ +from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, + QLineEdit, QPushButton, QMessageBox) +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QFont + +class LoginView(QWidget): + def __init__(self): + super().__init__() + self.setWindowTitle("无人机后勤输送系统 - 登录") + self.setFixedSize(400, 300) + self.init_ui() + + def init_ui(self): + # 创建主布局 + main_layout = QVBoxLayout() + main_layout.setAlignment(Qt.AlignCenter) + main_layout.setSpacing(20) + + # 标题 + title_label = QLabel("无人机后勤输送系统") + title_label.setFont(QFont('Arial', 16, QFont.Bold)) + title_label.setAlignment(Qt.AlignCenter) + main_layout.addWidget(title_label) + + # 用户名输入 + username_layout = QHBoxLayout() + username_label = QLabel("用户名:") + self.username_input = QLineEdit() + self.username_input.setPlaceholderText("请输入用户名") + username_layout.addWidget(username_label) + username_layout.addWidget(self.username_input) + main_layout.addLayout(username_layout) + + # 密码输入 + password_layout = QHBoxLayout() + password_label = QLabel("密码:") + self.password_input = QLineEdit() + self.password_input.setPlaceholderText("请输入密码") + self.password_input.setEchoMode(QLineEdit.Password) + password_layout.addWidget(password_label) + password_layout.addWidget(self.password_input) + main_layout.addLayout(password_layout) + + # 按钮区域 + button_layout = QHBoxLayout() + login_button = QPushButton("登录") + register_button = QPushButton("注册") + login_button.clicked.connect(self.handle_login) + register_button.clicked.connect(self.handle_register) + button_layout.addWidget(login_button) + button_layout.addWidget(register_button) + main_layout.addLayout(button_layout) + + self.setLayout(main_layout) + + def handle_login(self): + username = self.username_input.text() + password = self.password_input.text() + + if not username or not password: + QMessageBox.warning(self, "错误", "请输入用户名和密码") + return + + # TODO: 实现实际的登录逻辑 + print(f"尝试登录 - 用户名: {username}, 密码: {password}") + + def handle_register(self): + # TODO: 实现注册功能 + QMessageBox.information(self, "提示", "注册功能待实现") \ No newline at end of file diff --git a/Src/command_center/ui/main_view.py b/Src/command_center/ui/main_view.py new file mode 100644 index 00000000..36ffd5f0 --- /dev/null +++ b/Src/command_center/ui/main_view.py @@ -0,0 +1,87 @@ +from PyQt5.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, + QLabel, QPushButton, QTabWidget, QMessageBox) +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QFont + +class MainView(QMainWindow): + def __init__(self): + super().__init__() + self.setWindowTitle("无人机后勤输送系统 - 指挥控制中心") + self.setMinimumSize(800, 600) + self.init_ui() + + def init_ui(self): + # 创建主窗口部件 + central_widget = QWidget() + self.setCentralWidget(central_widget) + main_layout = QVBoxLayout(central_widget) + + # 顶部工具栏 + toolbar = QHBoxLayout() + self.status_label = QLabel("系统状态: 正常") + self.status_label.setFont(QFont('Arial', 10)) + logout_button = QPushButton("退出登录") + logout_button.clicked.connect(self.handle_logout) + + toolbar.addWidget(self.status_label) + toolbar.addStretch() + toolbar.addWidget(logout_button) + main_layout.addLayout(toolbar) + + # 主内容区域 + self.tab_widget = QTabWidget() + + # 创建各个功能标签页 + self.tab_widget.addTab(self.create_drone_management_tab(), "无人机管理") + self.tab_widget.addTab(self.create_task_management_tab(), "任务管理") + self.tab_widget.addTab(self.create_monitoring_tab(), "实时监控") + self.tab_widget.addTab(self.create_system_settings_tab(), "系统设置") + + main_layout.addWidget(self.tab_widget) + + def create_drone_management_tab(self): + tab = QWidget() + layout = QVBoxLayout(tab) + + # 添加无人机管理相关的控件 + layout.addWidget(QLabel("无人机管理功能待实现")) + + return tab + + def create_task_management_tab(self): + tab = QWidget() + layout = QVBoxLayout(tab) + + # 添加任务管理相关的控件 + layout.addWidget(QLabel("任务管理功能待实现")) + + return tab + + def create_monitoring_tab(self): + tab = QWidget() + layout = QVBoxLayout(tab) + + # 添加实时监控相关的控件 + layout.addWidget(QLabel("实时监控功能待实现")) + + return tab + + def create_system_settings_tab(self): + tab = QWidget() + layout = QVBoxLayout(tab) + + # 添加系统设置相关的控件 + layout.addWidget(QLabel("系统设置功能待实现")) + + return tab + + def handle_logout(self): + reply = QMessageBox.question(self, '确认退出', + '确定要退出登录吗?', + QMessageBox.Yes | QMessageBox.No, + QMessageBox.No) + + if reply == QMessageBox.Yes: + # TODO: 实现实际的登出逻辑 + self.close() + # 这里应该触发登录窗口的显示 \ No newline at end of file diff --git a/Src/command_center/ui/map_view.py b/Src/command_center/ui/map_view.py new file mode 100644 index 00000000..20110f16 --- /dev/null +++ b/Src/command_center/ui/map_view.py @@ -0,0 +1,67 @@ +from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, + QPushButton, QToolBar, QAction) +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QIcon + +class MapView(QWidget): + def __init__(self): + super().__init__() + self.init_ui() + + def init_ui(self): + # 创建主布局 + main_layout = QVBoxLayout() + + # 创建工具栏 + toolbar = QToolBar() + toolbar.setMovable(False) + + # 添加工具栏按钮 + zoom_in_action = QAction("放大", self) + zoom_out_action = QAction("缩小", self) + pan_action = QAction("平移", self) + measure_action = QAction("测量", self) + + toolbar.addAction(zoom_in_action) + toolbar.addAction(zoom_out_action) + toolbar.addAction(pan_action) + toolbar.addAction(measure_action) + + main_layout.addWidget(toolbar) + + # 创建地图显示区域 + self.map_widget = QLabel("地图显示区域") + self.map_widget.setAlignment(Qt.AlignCenter) + self.map_widget.setStyleSheet("background-color: #f0f0f0; border: 1px solid #ccc;") + main_layout.addWidget(self.map_widget) + + # 创建图层控制区域 + layer_control = QHBoxLayout() + self.threat_layer_btn = QPushButton("威胁层") + self.path_layer_btn = QPushButton("路径层") + self.base_layer_btn = QPushButton("基础层") + + layer_control.addWidget(self.threat_layer_btn) + layer_control.addWidget(self.path_layer_btn) + layer_control.addWidget(self.base_layer_btn) + + main_layout.addLayout(layer_control) + + self.setLayout(main_layout) + + # 连接信号 + self.threat_layer_btn.clicked.connect(self.toggle_threat_layer) + self.path_layer_btn.clicked.connect(self.toggle_path_layer) + self.base_layer_btn.clicked.connect(self.toggle_base_layer) + + def toggle_threat_layer(self): + # TODO: 实现威胁层的显示/隐藏 + pass + + def toggle_path_layer(self): + # TODO: 实现路径层的显示/隐藏 + pass + + def toggle_base_layer(self): + # TODO: 实现基础层的显示/隐藏 + pass \ No newline at end of file diff --git a/Src/command_center/ui/path_layer_view.py b/Src/command_center/ui/path_layer_view.py new file mode 100644 index 00000000..c4e40da4 --- /dev/null +++ b/Src/command_center/ui/path_layer_view.py @@ -0,0 +1,63 @@ +from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, + QPushButton, QTableWidget, QTableWidgetItem) +from PyQt5.QtCore import Qt + +class PathLayerView(QWidget): + def __init__(self): + super().__init__() + self.init_ui() + + def init_ui(self): + # 创建主布局 + main_layout = QVBoxLayout() + + # 创建路径列表 + self.path_table = QTableWidget() + self.path_table.setColumnCount(4) + self.path_table.setHorizontalHeaderLabels(["ID", "起点", "终点", "状态"]) + self.path_table.setStyleSheet("QTableWidget { border: 1px solid #ccc; }") + main_layout.addWidget(self.path_table) + + # 创建控制按钮 + button_layout = QHBoxLayout() + self.add_path_btn = QPushButton("添加路径") + self.edit_path_btn = QPushButton("编辑路径") + self.delete_path_btn = QPushButton("删除路径") + self.simulate_path_btn = QPushButton("模拟路径") + + button_layout.addWidget(self.add_path_btn) + button_layout.addWidget(self.edit_path_btn) + button_layout.addWidget(self.delete_path_btn) + button_layout.addWidget(self.simulate_path_btn) + + main_layout.addLayout(button_layout) + + # 创建路径详情区域 + self.path_detail = QLabel("路径详情") + self.path_detail.setAlignment(Qt.AlignCenter) + self.path_detail.setStyleSheet("background-color: #f0f0f0; border: 1px solid #ccc;") + main_layout.addWidget(self.path_detail) + + self.setLayout(main_layout) + + # 连接信号 + self.add_path_btn.clicked.connect(self.add_path) + self.edit_path_btn.clicked.connect(self.edit_path) + self.delete_path_btn.clicked.connect(self.delete_path) + self.simulate_path_btn.clicked.connect(self.simulate_path) + + def add_path(self): + # TODO: 实现添加路径功能 + pass + + def edit_path(self): + # TODO: 实现编辑路径功能 + pass + + def delete_path(self): + # TODO: 实现删除路径功能 + pass + + def simulate_path(self): + # TODO: 实现路径模拟功能 + pass \ No newline at end of file diff --git a/Src/command_center/ui/path_planning_view.py b/Src/command_center/ui/path_planning_view.py new file mode 100644 index 00000000..e2d84cf3 --- /dev/null +++ b/Src/command_center/ui/path_planning_view.py @@ -0,0 +1,88 @@ +from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, + QPushButton, QGroupBox, QFormLayout, QComboBox, + QSpinBox, QDoubleSpinBox) +from PyQt5.QtCore import Qt + +class PathPlanningView(QWidget): + def __init__(self): + super().__init__() + self.init_ui() + + def init_ui(self): + # 创建主布局 + main_layout = QVBoxLayout() + + # 创建算法配置组 + algorithm_group = QGroupBox("算法配置") + algorithm_layout = QFormLayout() + + self.algorithm_combo = QComboBox() + self.algorithm_combo.addItems(["A*算法", "遗传算法", "RRT算法"]) + + self.max_iterations = QSpinBox() + self.max_iterations.setRange(100, 10000) + self.max_iterations.setValue(1000) + + self.safety_margin = QDoubleSpinBox() + self.safety_margin.setRange(0.1, 10.0) + self.safety_margin.setValue(1.0) + self.safety_margin.setSingleStep(0.1) + + algorithm_layout.addRow("路径规划算法:", self.algorithm_combo) + algorithm_layout.addRow("最大迭代次数:", self.max_iterations) + algorithm_layout.addRow("安全距离(m):", self.safety_margin) + + algorithm_group.setLayout(algorithm_layout) + main_layout.addWidget(algorithm_group) + + # 创建路径参数组 + path_group = QGroupBox("路径参数") + path_layout = QFormLayout() + + self.start_lat = QDoubleSpinBox() + self.start_lon = QDoubleSpinBox() + self.end_lat = QDoubleSpinBox() + self.end_lon = QDoubleSpinBox() + + for spinbox in [self.start_lat, self.start_lon, self.end_lat, self.end_lon]: + spinbox.setRange(-180, 180) + spinbox.setDecimals(6) + + path_layout.addRow("起点纬度:", self.start_lat) + path_layout.addRow("起点经度:", self.start_lon) + path_layout.addRow("终点纬度:", self.end_lat) + path_layout.addRow("终点经度:", self.end_lon) + + path_group.setLayout(path_layout) + main_layout.addWidget(path_group) + + # 创建控制按钮 + button_layout = QHBoxLayout() + self.plan_path_btn = QPushButton("规划路径") + self.clear_path_btn = QPushButton("清除路径") + self.export_path_btn = QPushButton("导出路径") + + button_layout.addWidget(self.plan_path_btn) + button_layout.addWidget(self.clear_path_btn) + button_layout.addWidget(self.export_path_btn) + + main_layout.addLayout(button_layout) + + self.setLayout(main_layout) + + # 连接信号 + self.plan_path_btn.clicked.connect(self.plan_path) + self.clear_path_btn.clicked.connect(self.clear_path) + self.export_path_btn.clicked.connect(self.export_path) + + def plan_path(self): + # TODO: 实现路径规划功能 + pass + + def clear_path(self): + # TODO: 实现清除路径功能 + pass + + def export_path(self): + # TODO: 实现导出路径功能 + pass \ No newline at end of file diff --git a/Src/command_center/ui/path_simulation_view.py b/Src/command_center/ui/path_simulation_view.py new file mode 100644 index 00000000..2f21a1b1 --- /dev/null +++ b/Src/command_center/ui/path_simulation_view.py @@ -0,0 +1,109 @@ +from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, + QPushButton, QGroupBox, QFormLayout, QProgressBar, + QSpinBox, QDoubleSpinBox) +from PyQt5.QtCore import Qt, QTimer + +class PathSimulationView(QWidget): + def __init__(self): + super().__init__() + self.init_ui() + self.simulation_timer = QTimer() + self.simulation_timer.timeout.connect(self.update_simulation) + self.simulation_progress = 0 + + def init_ui(self): + # 创建主布局 + main_layout = QVBoxLayout() + + # 创建模拟控制组 + control_group = QGroupBox("模拟控制") + control_layout = QFormLayout() + + self.speed_spinbox = QDoubleSpinBox() + self.speed_spinbox.setRange(0.1, 10.0) + self.speed_spinbox.setValue(1.0) + self.speed_spinbox.setSingleStep(0.1) + + self.interval_spinbox = QSpinBox() + self.interval_spinbox.setRange(10, 1000) + self.interval_spinbox.setValue(100) + self.interval_spinbox.setSingleStep(10) + + control_layout.addRow("模拟速度:", self.speed_spinbox) + control_layout.addRow("更新间隔(ms):", self.interval_spinbox) + + control_group.setLayout(control_layout) + main_layout.addWidget(control_group) + + # 创建模拟进度条 + self.progress_bar = QProgressBar() + self.progress_bar.setRange(0, 100) + self.progress_bar.setValue(0) + main_layout.addWidget(self.progress_bar) + + # 创建控制按钮 + button_layout = QHBoxLayout() + self.start_btn = QPushButton("开始模拟") + self.pause_btn = QPushButton("暂停") + self.stop_btn = QPushButton("停止") + self.reset_btn = QPushButton("重置") + + button_layout.addWidget(self.start_btn) + button_layout.addWidget(self.pause_btn) + button_layout.addWidget(self.stop_btn) + button_layout.addWidget(self.reset_btn) + + main_layout.addLayout(button_layout) + + # 创建状态显示组 + status_group = QGroupBox("模拟状态") + status_layout = QFormLayout() + + self.time_label = QLabel("0.0s") + self.distance_label = QLabel("0.0m") + self.altitude_label = QLabel("0.0m") + self.speed_label = QLabel("0.0m/s") + + status_layout.addRow("已用时间:", self.time_label) + status_layout.addRow("飞行距离:", self.distance_label) + status_layout.addRow("当前高度:", self.altitude_label) + status_layout.addRow("当前速度:", self.speed_label) + + status_group.setLayout(status_layout) + main_layout.addWidget(status_group) + + self.setLayout(main_layout) + + # 连接信号 + self.start_btn.clicked.connect(self.start_simulation) + self.pause_btn.clicked.connect(self.pause_simulation) + self.stop_btn.clicked.connect(self.stop_simulation) + self.reset_btn.clicked.connect(self.reset_simulation) + + def start_simulation(self): + self.simulation_timer.start(self.interval_spinbox.value()) + + def pause_simulation(self): + self.simulation_timer.stop() + + def stop_simulation(self): + self.simulation_timer.stop() + self.simulation_progress = 0 + self.progress_bar.setValue(0) + + def reset_simulation(self): + self.simulation_progress = 0 + self.progress_bar.setValue(0) + self.time_label.setText("0.0s") + self.distance_label.setText("0.0m") + self.altitude_label.setText("0.0m") + self.speed_label.setText("0.0m/s") + + def update_simulation(self): + # TODO: 实现模拟更新逻辑 + self.simulation_progress += self.speed_spinbox.value() + if self.simulation_progress > 100: + self.simulation_progress = 100 + self.simulation_timer.stop() + + self.progress_bar.setValue(int(self.simulation_progress)) \ No newline at end of file diff --git a/Src/command_center/ui/status_dashboard.py b/Src/command_center/ui/status_dashboard.py new file mode 100644 index 00000000..6e13ecdc --- /dev/null +++ b/Src/command_center/ui/status_dashboard.py @@ -0,0 +1,128 @@ +from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, + QProgressBar, QGroupBox) +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QColor, QPalette + +class StatusDashboard(QWidget): + def __init__(self): + super().__init__() + self.init_ui() + + def init_ui(self): + # 创建主布局 + main_layout = QVBoxLayout() + + # 创建系统状态组 + system_status_group = QGroupBox("系统状态") + system_layout = QVBoxLayout() + + # 创建状态指示器 + self.connection_status = self.create_status_indicator("通信状态", "未连接") + self.gps_status = self.create_status_indicator("GPS状态", "未定位") + self.battery_status = self.create_battery_indicator("电池状态", 0) + self.signal_status = self.create_signal_indicator("信号强度", 0) + + system_layout.addWidget(self.connection_status) + system_layout.addWidget(self.gps_status) + system_layout.addWidget(self.battery_status) + system_layout.addWidget(self.signal_status) + + system_status_group.setLayout(system_layout) + main_layout.addWidget(system_status_group) + + # 创建性能指标组 + performance_group = QGroupBox("性能指标") + performance_layout = QVBoxLayout() + + self.cpu_usage = self.create_progress_bar("CPU使用率", 0) + self.memory_usage = self.create_progress_bar("内存使用率", 0) + self.network_usage = self.create_progress_bar("网络使用率", 0) + + performance_layout.addWidget(self.cpu_usage) + performance_layout.addWidget(self.memory_usage) + performance_layout.addWidget(self.network_usage) + + performance_group.setLayout(performance_layout) + main_layout.addWidget(performance_group) + + self.setLayout(main_layout) + + def create_status_indicator(self, label_text, status_text): + widget = QWidget() + layout = QHBoxLayout() + + label = QLabel(label_text) + status = QLabel(status_text) + status.setStyleSheet("color: red;") + + layout.addWidget(label) + layout.addWidget(status) + layout.addStretch() + + widget.setLayout(layout) + return widget + + def create_battery_indicator(self, label_text, value): + widget = QWidget() + layout = QHBoxLayout() + + label = QLabel(label_text) + progress = QProgressBar() + progress.setValue(value) + progress.setStyleSheet(""" + QProgressBar { + border: 1px solid #ccc; + border-radius: 5px; + text-align: center; + } + QProgressBar::chunk { + background-color: #4CAF50; + } + """) + + layout.addWidget(label) + layout.addWidget(progress) + layout.addStretch() + + widget.setLayout(layout) + return widget + + def create_signal_indicator(self, label_text, value): + widget = QWidget() + layout = QHBoxLayout() + + label = QLabel(label_text) + progress = QProgressBar() + progress.setValue(value) + progress.setStyleSheet(""" + QProgressBar { + border: 1px solid #ccc; + border-radius: 5px; + text-align: center; + } + QProgressBar::chunk { + background-color: #2196F3; + } + """) + + layout.addWidget(label) + layout.addWidget(progress) + layout.addStretch() + + widget.setLayout(layout) + return widget + + def create_progress_bar(self, label_text, value): + widget = QWidget() + layout = QHBoxLayout() + + label = QLabel(label_text) + progress = QProgressBar() + progress.setValue(value) + + layout.addWidget(label) + layout.addWidget(progress) + layout.addStretch() + + widget.setLayout(layout) + return widget \ No newline at end of file diff --git a/Src/command_center/ui/threat_layer_view.py b/Src/command_center/ui/threat_layer_view.py new file mode 100644 index 00000000..e77b9cb6 --- /dev/null +++ b/Src/command_center/ui/threat_layer_view.py @@ -0,0 +1,56 @@ +from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, + QPushButton, QTableWidget, QTableWidgetItem) +from PyQt5.QtCore import Qt + +class ThreatLayerView(QWidget): + def __init__(self): + super().__init__() + self.init_ui() + + def init_ui(self): + # 创建主布局 + main_layout = QVBoxLayout() + + # 创建威胁列表 + self.threat_table = QTableWidget() + self.threat_table.setColumnCount(4) + self.threat_table.setHorizontalHeaderLabels(["ID", "类型", "位置", "威胁等级"]) + self.threat_table.setStyleSheet("QTableWidget { border: 1px solid #ccc; }") + main_layout.addWidget(self.threat_table) + + # 创建控制按钮 + button_layout = QHBoxLayout() + self.add_threat_btn = QPushButton("添加威胁") + self.edit_threat_btn = QPushButton("编辑威胁") + self.delete_threat_btn = QPushButton("删除威胁") + + button_layout.addWidget(self.add_threat_btn) + button_layout.addWidget(self.edit_threat_btn) + button_layout.addWidget(self.delete_threat_btn) + + main_layout.addLayout(button_layout) + + # 创建威胁详情区域 + self.threat_detail = QLabel("威胁详情") + self.threat_detail.setAlignment(Qt.AlignCenter) + self.threat_detail.setStyleSheet("background-color: #f0f0f0; border: 1px solid #ccc;") + main_layout.addWidget(self.threat_detail) + + self.setLayout(main_layout) + + # 连接信号 + self.add_threat_btn.clicked.connect(self.add_threat) + self.edit_threat_btn.clicked.connect(self.edit_threat) + self.delete_threat_btn.clicked.connect(self.delete_threat) + + def add_threat(self): + # TODO: 实现添加威胁功能 + pass + + def edit_threat(self): + # TODO: 实现编辑威胁功能 + pass + + def delete_threat(self): + # TODO: 实现删除威胁功能 + pass \ No newline at end of file diff --git a/Src/基于侦察信息为无人机运输物资路径规划系统.txt b/Src/基于侦察信息为无人机运输物资路径规划系统.txt deleted file mode 100644 index e69de29b..00000000