diff --git a/doc/~$设计规格说明书-3.0.doc b/doc/~$设计规格说明书-3.0.doc new file mode 100644 index 00000000..289a2f53 Binary files /dev/null and b/doc/~$设计规格说明书-3.0.doc differ diff --git a/doc/软件设计规格说明书-3.0.doc b/doc/软件设计规格说明书-3.0.doc index bbfcd953..19f6cbfc 100644 Binary files a/doc/软件设计规格说明书-3.0.doc and b/doc/软件设计规格说明书-3.0.doc differ diff --git a/doc/软件设计规格说明书.doc b/doc/软件设计规格说明书.doc deleted file mode 100644 index 3dbb47f7..00000000 Binary files a/doc/软件设计规格说明书.doc and /dev/null differ diff --git a/doc/软件需求构思及描述.docx b/doc/软件需求构思及描述.docx index 4af9792c..48b29323 100644 Binary files a/doc/软件需求构思及描述.docx and b/doc/软件需求构思及描述.docx differ diff --git a/doc/软件需求规格说明书.docx b/doc/软件需求规格说明书.docx index e001b98d..3cd6398c 100644 Binary files a/doc/软件需求规格说明书.docx and b/doc/软件需求规格说明书.docx differ diff --git a/model/代码组织结构图.puml b/model/代码组织结构图.puml new file mode 100644 index 00000000..74a80648 --- /dev/null +++ b/model/代码组织结构图.puml @@ -0,0 +1,206 @@ +@startuml 代码组织结构图 +title 基于空地协同的战场环境探索系统 - 代码组织结构图 +skinparam packageStyle rectangle +skinparam packageFontSize 10 +skinparam packageFontStyle bold +skinparam classFontSize 8 +skinparam classFontStyle normal + +package "src/" { + package "Client/ (Qt客户端应用)" { + package "核心应用层" { + file "main.cpp" as main + file "BattlefieldExplorationSystem.pro" as proj + file "Makefile" as make + } + + package "include/ (头文件)" { + package "ui/ (用户界面)" { + package "main/" { + file "MainWindow.h" as mainH + } + package "components/ (组件)" { + file "RightFunctionPanel.h" as rightPanelH + file "DeviceListPanel.h" as deviceListH + file "DeviceCard.h" as deviceCardH + file "SystemLogPanel.h" as logPanelH + } + package "dialogs/ (对话框)" { + file "RobotDogControlDialog.h" as dogDialogH + file "EnemyStatsDialog.h" as enemyDialogH + file "DroneControlDialog.h" as droneDialogH + file "DeviceDialog.h" as deviceDialogH + } + file "UIInitializationManager.h" as uiInitH + } + + package "utils/ (工具类)" { + file "ConfigManager.h" as configH + file "SystemLogger.h" as loggerH + } + + package "core/ (核心功能)" { + package "database/ (数据库)" { + file "DatabaseManager.h" as dbManagerH + file "DatabaseHelper.h" as dbHelperH + file "DatabaseConfig.h" as dbConfigH + file "EnemyDatabase.h" as enemyDbH + file "DogDatabase.h" as dogDbH + file "UAVDatabase.h" as uavDbH + } + } + } + + package "src/ (源文件)" { + package "ui/ (用户界面实现)" { + package "main/" { + file "MainWindow.cpp" as mainCpp + } + package "components/ (组件实现)" { + file "RightFunctionPanel.cpp" as rightPanelCpp + file "DeviceListPanel.cpp" as deviceListCpp + file "DeviceCard.cpp" as deviceCardCpp + file "SystemLogPanel.cpp" as logPanelCpp + } + package "dialogs/ (对话框实现)" { + file "RobotDogControlDialog.cpp" as dogDialogCpp + file "EnemyStatsDialog.cpp" as enemyDialogCpp + file "DroneControlDialog.cpp" as droneDialogCpp + file "DeviceDialog.cpp" as deviceDialogCpp + } + file "UIInitializationManager.cpp" as uiInitCpp + } + + package "utils/ (工具类实现)" { + file "ConfigManager.cpp" as configCpp + file "SystemLogger.cpp" as loggerCpp + } + + package "core/ (核心功能实现)" { + package "database/ (数据库实现)" { + file "DatabaseManager.cpp" as dbManagerCpp + file "DatabaseHelper.cpp" as dbHelperCpp + file "DatabaseConfig.cpp" as dbConfigCpp + file "EnemyDatabase.cpp" as enemyDbCpp + file "DogDatabase.cpp" as dogDbCpp + file "UAVDatabase.cpp" as uavDbCpp + } + } + } + + package "forms/ (UI设计文件)" { + package "main/" { + file "MainWindow.ui" as mainUi + } + package "dialogs/" { + file "DeviceDialog.ui" as deviceUi + } + } + + package "AudioModule/ (音频模块)" { + file "IntelligenceUI.h" as audioH + file "IntelligenceUI.cpp" as audioCpp + file "IntelligenceUI.ui" as audioUi + } + + package "FaceLightModule/ (面部识别模块)" { + file "FaceLightControl.h" as faceH + file "FaceLightControl.cpp" as faceCpp + file "FaceLightControl.ui" as faceUi + } + + package "config/ (配置文件)" { + file "database.ini" as dbIni + file "database.ini.example" as dbIniEx + file "README.md" as configReadme + } + + package "database/ (数据库脚本)" { + file "enemy_database_schema.sql" as enemySchema + file "insert_additional_enemy_data.sql" as enemyData + file "test_enemy_database.sql" as enemyTest + file "update_enemy_locations.sql" as enemyUpdate + } + + package "其他资源" { + file "res.qrc" as res + file "代码规范.md" as codeStandard + file "BUTTON_LAYOUT_OPTIMIZATION_REPORT.md" as layoutReport + } + } + + package "catkin_dog/ (ROS机器人控制)" { + package "unitree_ros_to_real/" { + package "unitree_legged_real/" { + package "src/exe/" as exe + package "include/" as realInclude + package "launch/" as launch + package "scripts/" as scripts + package "rviz/" as rviz + file "CMakeLists.txt" as realCmake + file "package.xml" as realPackage + } + } + + package "unitree_legged_sdk/" { + package "include/" as sdkInclude + package "lib/" as lib + package "example/" as example + package "example_py/" as examplePy + package "python_wrapper/" as pyWrapper + file "CMakeLists.txt" as sdkCmake + file "package.xml" as sdkPackage + file "README.md" as sdkReadme + } + + package "unitree_legged_msgs/" { + package "msg/ (ROS消息定义)" { + file "HighCmd.msg" as highCmd + file "HighState.msg" as highState + file "LowCmd.msg" as lowCmd + file "LowState.msg" as lowState + file "MotorCmd.msg" as motorCmd + file "MotorState.msg" as motorState + file "IMU.msg" as imu + file "BmsState.msg" as bmsState + file "LED.msg" as led + file "Cartesian.msg" as cartesian + } + file "CMakeLists.txt" as msgCmake + file "package.xml" as msgPackage + } + + package "slamware_ros_sdk_linux-x86_64-gcc9/" as slamware + file "CMakeLists.txt" as catkinCmake + } +} + +' 主要模块关系 +package "系统架构层次" { + note top of Client : "Qt客户端应用\n- 用户界面\n- 数据库管理\n- 设备控制\n- 音频处理\n- 面部识别" + + note top of catkin_dog : "ROS机器人控制\n- 机器狗SDK\n- 消息通信\n- 导航控制\n- SLAM建图" +} + +' 核心功能模块 +package "核心功能模块" { + note as N1 : "1. 空地协同控制\n- 无人机控制\n- 机器狗控制\n- 协同调度" + + note as N2 : "2. 智能识别系统\n- YOLO目标检测\n- 面部识别\n- 音频处理" + + note as N3 : "3. 数据管理系统\n- 敌方数据库\n- 设备数据库\n- 情报数据" + + note as N4 : "4. 可视化界面\n- 3D战场地图\n- 实时视频显示\n- 态势分析" +} + +Client --> N1 : 控制指令 +Client --> N2 : 识别结果 +Client --> N3 : 数据存储 +Client --> N4 : 界面展示 + +catkin_dog --> N1 : 执行控制 +catkin_dog --> N2 : 传感器数据 +catkin_dog --> N3 : 位置信息 +catkin_dog --> N4 : 状态反馈 + +@enduml \ No newline at end of file diff --git a/model/数据模型类图.puml b/model/数据模型类图.puml new file mode 100644 index 00000000..77664d20 --- /dev/null +++ b/model/数据模型类图.puml @@ -0,0 +1,350 @@ +@startuml 数据模型类图 +title 基于空地协同的战场环境探索系统 - 数据模型类图 +skinparam classAttributeIconSize 0 +skinparam classFontSize 10 +skinparam classFontStyle bold +skinparam packageStyle rectangle + +package "核心数据实体" { + class Location { + -locationId: String + -x: double + -y: double + -z: double + -timestamp: QDateTime + +getCoordinates() + +setCoordinates() + +calculateDistance() + +isValid() + } + + class Pose { + -poseId: String + -position: Location + -orientation: QQuaternion + -timestamp: QDateTime + +getPosition() + +getOrientation() + +setPose() + +transformPose() + } + + class SensorData { + -sensorId: String + -sensorType: String + -dataType: String + -rawData: QByteArray + -processedData: QVariant + -timestamp: QDateTime + +getRawData() + +getProcessedData() + +processData() + +validateData() + } + + class Target { + -targetId: String + -targetType: String + -location: Location + -threatLevel: int + -confidence: double + -status: String + -timestamp: QDateTime + +updateLocation() + +updateThreatLevel() + +assessThreat() + +isActive() + } +} + +package "设备数据模型" { + class Device { + -deviceId: String + -deviceType: String + -deviceName: String + -status: String + -connectionStatus: String + -lastUpdate: QDateTime + +getDeviceInfo() + +updateStatus() + +isConnected() + +isOperational() + } + + class RobotDog { + -dogId: String + -dogType: String + -batteryLevel: double + -currentPose: Pose + -movementStatus: String + -sensorData: QList + -lastCommand: MovementCommand + +getBatteryLevel() + +getCurrentPose() + +updateStatus() + +sendCommand() + +emergencyStop() + } + + class UAV { + -uavId: String + -uavType: String + -batteryLevel: double + -altitude: double + -currentPose: Pose + -flightMode: String + -sensorData: QList + +getBatteryLevel() + +getAltitude() + +getCurrentPose() + +updateFlightMode() + +sendFlightCommand() + } + + class MovementCommand { + -commandId: String + -deviceId: String + -commandType: String + -targetPose: Pose + -speed: double + -priority: int + -timestamp: QDateTime + -status: String + +executeCommand() + +validateCommand() + +getCommandStatus() + +cancelCommand() + } +} + +package "任务数据模型" { + class Mission { + -missionId: String + -missionType: String + -missionName: String + -priority: int + -status: String + -startTime: QDateTime + -endTime: QDateTime + -assignedDevices: QList + -tasks: QList + +createMission() + +assignDevices() + +addTask() + +updateStatus() + +completeMission() + } + + class Task { + -taskId: String + -missionId: String + -taskType: String + -taskName: String + -priority: int + -status: String + -assignedDevice: String + -startLocation: Location + -endLocation: Location + -parameters: QVariantMap + +assignDevice() + +updateStatus() + +executeTask() + +completeTask() + } + + class TaskResult { + -resultId: String + -taskId: String + -deviceId: String + -resultType: String + -resultData: QVariant + -success: boolean + -errorMessage: String + -timestamp: QDateTime + +setResult() + +getResult() + +isSuccess() + +getErrorMessage() + } +} + +package "情报数据模型" { + class IntelligenceData { + -intelligenceId: String + -dataType: String + -source: String + -content: QVariant + -confidence: double + -priority: int + -timestamp: QDateTime + -expiryTime: QDateTime + +getContent() + +setConfidence() + +isExpired() + +updatePriority() + } + + class EnemyTarget { + -targetId: String + -targetType: String + -location: Location + -threatLevel: int + -confidence: double + -detectionTime: QDateTime + -lastUpdate: QDateTime + -status: String + -attributes: QVariantMap + +updateLocation() + +updateThreatLevel() + +setAttributes() + +isActive() + } + + class BattlefieldMap { + -mapId: String + -mapType: String + -resolution: double + -width: double + -height: double + -origin: Location + -mapData: QImage + -obstacles: QList + -lastUpdate: QDateTime + +getMapData() + +addObstacle() + +removeObstacle() + +updateMap() + +getObstacles() + } + + class Obstacle { + -obstacleId: String + -obstacleType: String + -location: Location + -size: QVector3D + -properties: QVariantMap + -timestamp: QDateTime + +getLocation() + +getSize() + +setProperties() + +isBlocking() + } +} + +package "系统配置数据" { + class SystemConfig { + -configId: String + -configType: String + -configName: String + -configValue: QVariant + -description: String + -lastModified: QDateTime + +getValue() + +setValue() + +getDescription() + +isValid() + } + + class UserConfig { + -userId: String + -username: String + -userRole: String + -permissions: QList + -preferences: QVariantMap + -lastLogin: QDateTime + +getPermissions() + +setPreferences() + +hasPermission() + +updateLastLogin() + } + + class DeviceConfig { + -deviceId: String + -configType: String + -parameters: QVariantMap + -lastModified: QDateTime + +getParameters() + +setParameters() + +validateConfig() + +applyConfig() + } +} + +package "日志和监控数据" { + class SystemLog { + -logId: String + -logLevel: String + -logSource: String + -logMessage: String + -timestamp: QDateTime + -userId: String + -deviceId: String + +getLogInfo() + +setLogLevel() + +formatMessage() + } + + class PerformanceMetrics { + -metricId: String + -metricType: String + -metricName: String + -metricValue: double + -unit: String + -timestamp: QDateTime + -deviceId: String + +getMetricValue() + +setMetricValue() + +getUnit() + +isWithinRange() + } + + class Alert { + -alertId: String + -alertType: String + -alertLevel: String + -alertMessage: String + -source: String + -timestamp: QDateTime + -acknowledged: boolean + -resolved: boolean + +getAlertInfo() + +acknowledgeAlert() + +resolveAlert() + +isActive() + } +} + +' 关系定义 +Location ||--o{ Pose : 组成 +Location ||--o{ Target : 定位 +Location ||--o{ RobotDog : 定位 +Location ||--o{ UAV : 定位 +Location ||--o{ Obstacle : 定位 + +Pose ||--o{ MovementCommand : 目标位置 +Pose ||--o{ Task : 起始/结束位置 + +Device ||--o{ RobotDog : 继承 +Device ||--o{ UAV : 继承 + +RobotDog ||--o{ MovementCommand : 执行 +UAV ||--o{ MovementCommand : 执行 + +Mission ||--o{ Task : 包含 +Task ||--o{ TaskResult : 产生 +Task ||--o{ MovementCommand : 生成 + +IntelligenceData ||--o{ EnemyTarget : 包含 +BattlefieldMap ||--o{ Obstacle : 包含 +BattlefieldMap ||--o{ Location : 覆盖 + +SystemConfig ||--o{ DeviceConfig : 配置 +UserConfig ||--o{ SystemLog : 记录 +Device ||--o{ DeviceConfig : 配置 + +SystemLog ||--o{ PerformanceMetrics : 记录 +SystemLog ||--o{ Alert : 生成 +Device ||--o{ PerformanceMetrics : 监控 +Device ||--o{ Alert : 产生 + +@enduml \ No newline at end of file diff --git a/model/软件系统分析类图.puml b/model/软件系统分析类图.puml new file mode 100644 index 00000000..93a186c8 --- /dev/null +++ b/model/软件系统分析类图.puml @@ -0,0 +1,515 @@ +@startuml 软件系统分析类图 +title 基于空地协同的战场环境探索系统 - 软件系统分析类图 +skinparam classAttributeIconSize 0 +skinparam classFontSize 10 +skinparam classFontStyle bold +skinparam packageStyle rectangle +skinparam packageFontSize 12 + +' 定义样式 +skinparam class { + BackgroundColor<> #E1F5FE + BackgroundColor<> #F3E5F5 + BackgroundColor<> #E8F5E8 + BackgroundColor<> #FFF3E0 + BackgroundColor<> #FCE4EC +} + +package "用户界面层 (Qt Client)" <> { + class MainWindow { + -mainWindowId: String + -windowTitle: String + -windowSize: QSize + +initializeUI() + +setupMenuBar() + +setupToolBar() + +setupStatusBar() + +handleMenuAction() + +updateStatus() + +closeEvent() + } + + class UIInitializationManager { + -uiManagerId: String + -initializationStatus: String + +initializeAllComponents() + +setupDatabaseConnection() + +setupDeviceConnections() + +setupSignalSlots() + +validateInitialization() + +handleInitializationError() + } + + package "UI组件 (Components)" { + class RightFunctionPanel { + -panelId: String + -panelType: String + -isVisible: boolean + +setupFunctionButtons() + +handleButtonClick() + +updatePanelContent() + +showPanel() + +hidePanel() + } + + class DeviceListPanel { + -deviceListId: String + -deviceCount: int + -selectedDevice: String + +loadDeviceList() + +addDevice() + +removeDevice() + +selectDevice() + +updateDeviceStatus() + +refreshDeviceList() + } + + class DeviceCard { + -deviceId: String + -deviceType: String + -deviceStatus: String + -deviceIcon: QIcon + +displayDeviceInfo() + +updateStatus() + +handleClick() + +showDetails() + } + + class SystemLogPanel { + -logPanelId: String + -logLevel: String + -maxLogEntries: int + +addLogEntry() + +clearLogs() + +filterLogs() + +exportLogs() + +setLogLevel() + } + } + + package "对话框 (Dialogs)" { + class RobotDogControlDialog { + -dialogId: String + -dogId: String + -controlMode: String + +setupControlInterface() + +sendMovementCommand() + +sendNavigationCommand() + +updateDogStatus() + +emergencyStop() + +closeDialog() + } + + class DroneControlDialog { + -dialogId: String + -droneId: String + -flightMode: String + +setupFlightInterface() + +sendTakeoffCommand() + +sendLandingCommand() + +sendFlightCommand() + +updateDroneStatus() + +emergencyLanding() + } + + class EnemyStatsDialog { + -dialogId: String + -enemyCount: int + -threatLevel: int + +loadEnemyData() + +displayStatistics() + +updateThreatLevel() + +exportReport() + +closeDialog() + } + + class DeviceDialog { + -dialogId: String + -deviceId: String + -deviceType: String + +setupDeviceInterface() + +configureDevice() + +testDevice() + +updateDeviceInfo() + +saveConfiguration() + } + } +} + +package "核心业务层 (Core Business)" <> { + package "数据库管理 (Database)" <> { + class DatabaseManager { + -dbManagerId: String + -connectionStatus: String + -dbConfig: DatabaseConfig + +connectToDatabase() + +disconnectFromDatabase() + +createTables() + +executeQuery() + +beginTransaction() + +commitTransaction() + +rollbackTransaction() + } + + class DatabaseHelper { + -helperId: String + -queryBuilder: QueryBuilder + +buildSelectQuery() + +buildInsertQuery() + +buildUpdateQuery() + +buildDeleteQuery() + +executeQuery() + +handleQueryError() + } + + class DatabaseConfig { + -configId: String + -host: String + -port: int + -databaseName: String + -username: String + -password: String + +loadFromFile() + +saveToFile() + +validateConfig() + +getConnectionString() + } + + class EnemyDatabase { + -enemyDbId: String + -tableName: String + +insertEnemyTarget() + +updateEnemyTarget() + +deleteEnemyTarget() + +getEnemyTarget() + +getAllEnemyTargets() + +getEnemyTargetsByType() + +getEnemyTargetsByThreatLevel() + } + + class DogDatabase { + -dogDbId: String + -tableName: String + +insertDogStatus() + +updateDogStatus() + +getDogStatus() + +getAllDogStatus() + +insertDogLocation() + +getDogLocationHistory() + } + + class UAVDatabase { + -uavDbId: String + -tableName: String + +insertUAVStatus() + +updateUAVStatus() + +getUAVStatus() + +getAllUAVStatus() + +insertUAVFlightData() + +getUAVFlightTrajectory() + } + } + + package "工具类 (Utils)" { + class ConfigManager { + -configManagerId: String + -configFile: String + -configData: QVariantMap + +loadConfiguration() + +saveConfiguration() + +getValue() + +setValue() + +validateConfiguration() + +reloadConfiguration() + } + + class SystemLogger { + -loggerId: String + -logLevel: String + -logFile: String + +logInfo() + +logWarning() + +logError() + +logDebug() + +setLogLevel() + +setLogFile() + +rotateLogFile() + } + } +} + +package "AI算法层 (AI Algorithms)" <> { + class YOLODetector { + -detectorId: String + -modelPath: String + -confidenceThreshold: double + -nmsThreshold: double + -modelLoaded: boolean + +loadModel() + +detectObjects() + +classifyTargets() + +updateModel() + +setConfidenceThreshold() + +setNMSThreshold() + +getDetectionResults() + } + + class TargetClassifier { + -classifierId: String + -classifierType: String + -trainingData: QList + +trainClassifier() + +classifyTarget() + +updateClassifier() + +getClassificationResults() + +validateClassification() + } + + class SLAMProcessor { + -slamId: String + -slamType: String + -mapResolution: double + -currentPose: Pose + +processSensorData() + +buildMap() + +localizePosition() + +updateMap() + +getCurrentPose() + +getMapData() + } + + class PathPlanner { + -plannerId: String + -algorithmType: String + -heuristicFunction: String + -obstacleMap: QImage + +planOptimalPath() + +avoidObstacles() + +optimizeRoute() + +replanPath() + +getPathData() + +validatePath() + } + + class DataFusion { + -fusionId: String + -fusionAlgorithm: String + -weightMatrix: Matrix + -sensorData: QList + +fuseMultiSourceData() + +weightData() + +resolveConflicts() + +generateFusedMap() + +getFusionResults() + +updateFusionAlgorithm() + } +} + +package "ROS机器人控制层 (ROS Control)" <> { + package "Unitree机器狗控制" { + class UnitreeController { + -controllerId: String + -dogId: String + -connectionStatus: String + -currentState: DogState + +connectToDog() + +disconnectFromDog() + +sendMovementCommand() + +sendNavigationCommand() + +getDogStatus() + +emergencyStop() + } + + class DogState { + -stateId: String + -batteryLevel: double + -currentPose: Pose + -movementStatus: String + -sensorData: SensorData + +updateState() + +getBatteryLevel() + +getCurrentPose() + +getMovementStatus() + } + + class MovementCommand { + -commandId: String + -commandType: String + -targetPose: Pose + -speed: double + -timestamp: QDateTime + +executeCommand() + +validateCommand() + +getCommandStatus() + } + } + + package "ROS消息定义" { + class HighCmd { + -mode: int + -gaitType: int + -speedLevel: int + -footRaiseHeight: float + -bodyHeight: float + +serialize() + +deserialize() + } + + class HighState { + -mode: int + -gaitType: int + -footRaiseHeight: float + -bodyHeight: float + -position: Cartesian + +serialize() + +deserialize() + } + + class IMU { + -quaternion: QVector4D + -gyroscope: QVector3D + -accelerometer: QVector3D + -timestamp: QDateTime + +getQuaternion() + +getGyroscope() + +getAccelerometer() + } + + class MotorState { + -motorId: int + -position: float + -velocity: float + -torque: float + -temperature: float + +getPosition() + +getVelocity() + +getTorque() + } + } +} + +package "通信层 (Communication)" { + class CommunicationManager { + -commManagerId: String + -connectionType: String + -connectionStatus: String + +establishConnection() + +closeConnection() + +sendMessage() + +receiveMessage() + +handleConnectionError() + +getConnectionStatus() + } + + class NetworkProtocol { + -protocolId: String + -protocolType: String + -port: int + -timeout: int + +encodeMessage() + +decodeMessage() + +validateMessage() + +handleProtocolError() + } + + class DataTransmission { + -transmissionId: String + -dataType: String + -compressionEnabled: boolean + -encryptionEnabled: boolean + +transmitData() + +receiveData() + +compressData() + +decompressData() + +encryptData() + +decryptData() + } +} + +package "任务控制层 (Mission Control)" { + class MissionController { + -missionId: String + -missionType: String + -priority: int + -status: String + -startTime: QDateTime + +createMission() + +assignTasks() + +monitorProgress() + +handleEmergency() + +generateReport() + +abortMission() + } + + class TaskScheduler { + -schedulerId: String + -taskQueue: QQueue + -schedulingAlgorithm: String + +addTask() + +removeTask() + +scheduleTasks() + +getNextTask() + +updateTaskStatus() + +optimizeSchedule() + } + + class CoordinationController { + -coordinationId: String + -coordinationType: String + -deviceList: QList + +coordinatePlatforms() + +optimizeTaskAllocation() + +resolveConflicts() + +maintainFormation() + +getCoordinationStatus() + } +} + +' 关系定义 +MainWindow ||--o{ UIInitializationManager : 使用 +MainWindow ||--o{ RightFunctionPanel : 包含 +MainWindow ||--o{ DeviceListPanel : 包含 +MainWindow ||--o{ SystemLogPanel : 包含 + +DeviceListPanel ||--o{ DeviceCard : 包含 +MainWindow ||--o{ RobotDogControlDialog : 打开 +MainWindow ||--o{ DroneControlDialog : 打开 +MainWindow ||--o{ EnemyStatsDialog : 打开 +MainWindow ||--o{ DeviceDialog : 打开 + +UIInitializationManager ||--o{ DatabaseManager : 初始化 +UIInitializationManager ||--o{ ConfigManager : 配置 + +DatabaseManager ||--o{ DatabaseHelper : 使用 +DatabaseManager ||--o{ DatabaseConfig : 配置 +DatabaseManager ||--o{ EnemyDatabase : 管理 +DatabaseManager ||--o{ DogDatabase : 管理 +DatabaseManager ||--o{ UAVDatabase : 管理 + +RobotDogControlDialog ||--o{ UnitreeController : 控制 +DroneControlDialog ||--o{ CommunicationManager : 通信 + +UnitreeController ||--o{ DogState : 监控 +UnitreeController ||--o{ MovementCommand : 发送 +UnitreeController ||--o{ HighCmd : 发送 +UnitreeController ||--o{ HighState : 接收 +UnitreeController ||--o{ IMU : 接收 +UnitreeController ||--o{ MotorState : 接收 + +YOLODetector ||--o{ TargetClassifier : 使用 +SLAMProcessor ||--o{ PathPlanner : 提供地图 +DataFusion ||--o{ YOLODetector : 融合数据 +DataFusion ||--o{ SLAMProcessor : 融合数据 + +MissionController ||--o{ TaskScheduler : 使用 +MissionController ||--o{ CoordinationController : 使用 +TaskScheduler ||--o{ UnitreeController : 调度 +TaskScheduler ||--o{ CommunicationManager : 调度 + +CommunicationManager ||--o{ NetworkProtocol : 使用 +CommunicationManager ||--o{ DataTransmission : 使用 + +SystemLogger ||--o{ MainWindow : 记录 +ConfigManager ||--o{ MainWindow : 配置 + +@enduml \ No newline at end of file diff --git a/src/Client/AudioModule/IntelligenceUI.cpp b/src/Client/AudioModule/IntelligenceUI.cpp index ad5edd92..82789f85 100644 --- a/src/Client/AudioModule/IntelligenceUI.cpp +++ b/src/Client/AudioModule/IntelligenceUI.cpp @@ -16,6 +16,15 @@ #include #include +/* +信号槽是Qt框架中用于对象间通信的机制 +其中Signals是信号,Slots是槽函数 +信号是对象发出的通知,槽函数是对象接收信号并执行的函数 +信号和槽函数是松耦合的,信号可以连接到多个槽函数,槽函数也可以连接到多个信号 +信号和槽函数是异步的,信号发出后,槽函数会立即执行,不会阻塞主线程 +连接机制为connect(发送者,信号,接收者,槽函数) +*/ + IntelligenceUI::IntelligenceUI(QWidget *parent) : QMainWindow(parent) , ui(new Ui::IntelligenceUI) @@ -61,6 +70,7 @@ IntelligenceUI::IntelligenceUI(QWidget *parent) ui->progressBar->setValue(0); } +// 析构函数 IntelligenceUI::~IntelligenceUI() { if (sshProcess && sshProcess->state() != QProcess::NotRunning) { @@ -70,19 +80,28 @@ IntelligenceUI::~IntelligenceUI() delete ui; } +// SSH远程控制模块 void IntelligenceUI::executeSSHCommand(const QString &command, const QString &description) { if (sshProcess && sshProcess->state() != QProcess::NotRunning) { + //检查上一个命令的执行状态 + //避免多个命令同时执行造成冲突 updateStatus("上一个命令仍在执行中,请稍候...", true); return; } if (!sshProcess) { + // 创建新的SSH进程 + // 连接信号槽,处理命令执行完成和错误情况 sshProcess = new QProcess(this); connect(sshProcess, QOverload::of(&QProcess::finished), - this, &IntelligenceUI::onSshProcessFinished); + this, &IntelligenceUI::onSshProcessFinished);// 连接信号槽,处理命令执行完成和错误情况 + //sshProcess是发送者,QOverload::of(&QProcess::finished)是信号 + //this是接收者,onSshProcessFinished是槽函数 connect(sshProcess, &QProcess::errorOccurred, this, &IntelligenceUI::onSshProcessError); + //sshProcess是发送者,QProcess::errorOccurred是信号 + //this是接收者,onSshProcessError是槽函数 } currentCommand = description; @@ -189,10 +208,11 @@ void IntelligenceUI::refreshAudioFileList() executeSSHCommand(command, "刷新音频文件列表"); } +// 处理SSH命令执行完成的槽函数 void IntelligenceUI::onSshProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) { ui->progressBar->setValue(100); - + //设置progressBar进度条为100% if (exitStatus == QProcess::NormalExit && exitCode == 0) { updateStatus(QString("%1 - 执行成功").arg(currentCommand)); } else { diff --git a/src/Client/BattlefieldExplorationSystem b/src/Client/BattlefieldExplorationSystem new file mode 100644 index 00000000..5037dbb5 Binary files /dev/null and b/src/Client/BattlefieldExplorationSystem differ diff --git a/src/Client/FaceLightModule/FaceLightControl.cpp b/src/Client/FaceLightModule/FaceLightControl.cpp index 5af59617..23c60680 100644 --- a/src/Client/FaceLightModule/FaceLightControl.cpp +++ b/src/Client/FaceLightModule/FaceLightControl.cpp @@ -103,7 +103,7 @@ void FaceLightControl::executeSSHCommand(const QString &command, const QString & if (!sshProcess) { sshProcess = new QProcess(this); connect(sshProcess, QOverload::of(&QProcess::finished), - this, &FaceLightControl::onSshProcessFinished); + this, &FaceLightControl::onSshProcessFinished);// connect(sshProcess, &QProcess::errorOccurred, this, &FaceLightControl::onSshProcessError); } diff --git a/src/Client/tests/README.md b/src/Client/tests/README.md new file mode 100644 index 00000000..d9bcc631 --- /dev/null +++ b/src/Client/tests/README.md @@ -0,0 +1,350 @@ +# 基于空地协同的战场环境探索系统 - 测试套件 + +## 概述 + +本测试套件为"基于空地协同的战场环境探索系统"提供全面的功能测试、性能测试和集成测试。测试覆盖了系统的所有核心模块,确保系统在各种条件下都能稳定可靠地运行。 + +## 测试架构 + +### 测试模块结构 + +``` +tests/ +├── TestMain.cpp # 主测试入口 +├── TestConfig.h # 测试配置和常量 +├── TestDatabaseManager.h # 数据库管理测试 +├── TestDeviceControl.h # 设备控制测试 +├── TestYOLODetector.h # YOLO检测器测试 +├── TestSLAMProcessor.h # SLAM处理器测试 +├── TestDataFusion.h # 数据融合测试 +├── TestCommunication.h # 通信模块测试 +├── TestMissionController.h # 任务控制器测试 +├── run_tests.sh # 自动化测试脚本 +└── README.md # 本文件 +``` + +### 测试覆盖范围 + +| 测试模块 | 功能覆盖 | 测试类型 | +|---------|---------|---------| +| 数据库管理 | 数据存储、查询、更新、删除 | 功能测试、性能测试、并发测试 | +| 设备控制 | 机器狗控制、无人机控制 | 功能测试、实时测试、异常处理 | +| YOLO检测器 | 目标检测、分类、识别 | 功能测试、性能测试、准确性测试 | +| SLAM处理器 | 建图、定位、导航 | 功能测试、精度测试、鲁棒性测试 | +| 数据融合 | 多源数据融合、态势感知 | 功能测试、融合精度测试 | +| 通信模块 | 网络通信、数据传输 | 功能测试、性能测试、安全测试 | +| 任务控制器 | 任务管理、协同控制 | 功能测试、集成测试、端到端测试 | + +## 测试环境要求 + +### 系统要求 +- Ubuntu 18.04 或更高版本 +- Qt 5.12 或更高版本 +- MySQL 5.7 或更高版本 +- OpenCV 4.0 或更高版本 +- ROS Melodic 或更高版本 + +### 依赖库 +```bash +# 安装必要的依赖 +sudo apt-get update +sudo apt-get install -y \ + qt5-default \ + libqt5test5 \ + libmysqlclient-dev \ + libopencv-dev \ + ros-melodic-ros-base \ + build-essential \ + cmake +``` + +### 环境配置 +```bash +# 设置Qt环境 +export QT_QPA_PLATFORM=offscreen +export QT_LOGGING_RULES="*.debug=true;qt.qpa.*=false" + +# 设置ROS环境 +source /opt/ros/melodic/setup.bash + +# 设置数据库环境 +export MYSQL_HOST=localhost +export MYSQL_PORT=3306 +export MYSQL_DATABASE=test_battlefield_exploration +export MYSQL_USER=test_user +export MYSQL_PASSWORD=test_password +``` + +## 编译和运行 + +### 1. 编译测试程序 + +```bash +# 进入项目目录 +cd src/Client + +# 创建构建目录 +mkdir -p build +cd build + +# 配置项目 +qmake ../BattlefieldExplorationSystem.pro + +# 编译 +make -j$(nproc) + +# 编译测试程序 +make test +``` + +### 2. 运行测试 + +#### 运行所有测试 +```bash +# 使用自动化脚本 +cd tests +chmod +x run_tests.sh +./run_tests.sh +``` + +#### 运行单个测试模块 +```bash +# 运行数据库测试 +./TestMain --database + +# 运行设备控制测试 +./TestMain --device + +# 运行YOLO检测器测试 +./TestMain --yolo + +# 运行SLAM处理器测试 +./TestMain --slam + +# 运行数据融合测试 +./TestMain --fusion + +# 运行通信模块测试 +./TestMain --communication + +# 运行任务控制器测试 +./TestMain --mission +``` + +#### 运行特定测试用例 +```bash +# 运行特定测试函数 +./TestMain -o test_results.xml -xunitxml TestDatabaseManager::testDatabaseConnection +``` + +## 测试配置 + +### 测试参数配置 + +在 `TestConfig.h` 中可以配置以下测试参数: + +```cpp +// 数据库配置 +const QString TEST_DB_HOST = "localhost"; +const int TEST_DB_PORT = 3306; +const QString TEST_DB_NAME = "test_battlefield_exploration"; + +// 性能阈值 +const double MAX_DETECTION_LATENCY_MS = 100.0; +const double MAX_NAVIGATION_ERROR_M = 0.5; +const double MIN_DETECTION_ACCURACY = 0.8; + +// 测试数据配置 +const int NUM_TEST_IMAGES = 100; +const int NUM_TEST_TARGETS = 50; +``` + +### 测试场景配置 + +系统支持多种测试场景: + +- **城市作战场景** (SCENARIO_URBAN_COMBAT) +- **开阔地带场景** (SCENARIO_OPEN_FIELD) +- **森林环境场景** (SCENARIO_FOREST) +- **地下空间场景** (SCENARIO_UNDERGROUND) +- **混合环境场景** (SCENARIO_MIXED_ENVIRONMENT) + +### 测试环境配置 + +支持不同环境条件下的测试: + +- **白天环境** (ENV_DAYLIGHT) +- **夜间环境** (ENV_NIGHT) +- **雨天环境** (ENV_RAIN) +- **雾天环境** (ENV_FOG) +- **沙尘环境** (ENV_DUST) + +## 测试报告 + +### 自动生成报告 + +测试完成后会自动生成以下报告: + +1. **HTML测试报告** (`reports/test_report_YYYYMMDD_HHMMSS.html`) + - 测试摘要统计 + - 各模块测试结果 + - 详细测试日志 + - 性能指标分析 + +2. **XML测试报告** (`test_results.xml`) + - 标准JUnit格式 + - 可用于CI/CD集成 + +3. **日志文件** (`logs/test_run_YYYYMMDD_HHMMSS.log`) + - 详细测试执行日志 + - 错误信息和调试信息 + +### 报告内容 + +测试报告包含以下信息: + +- **测试摘要**:总测试数、通过数、失败数、成功率 +- **模块详情**:每个测试模块的详细结果 +- **性能指标**:响应时间、内存使用、CPU使用率 +- **错误分析**:失败测试的详细错误信息 +- **建议改进**:基于测试结果的改进建议 + +## 持续集成 + +### CI/CD配置 + +可以在CI/CD流水线中集成测试: + +```yaml +# .github/workflows/test.yml +name: 战场环境探索系统测试 + +on: [push, pull_request] + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: 安装依赖 + run: | + sudo apt-get update + sudo apt-get install -y qt5-default libqt5test5 libmysqlclient-dev + + - name: 编译项目 + run: | + cd src/Client + mkdir build && cd build + qmake ../BattlefieldExplorationSystem.pro + make -j$(nproc) + + - name: 运行测试 + run: | + cd src/Client/tests + chmod +x run_tests.sh + ./run_tests.sh + + - name: 上传测试报告 + uses: actions/upload-artifact@v2 + with: + name: test-reports + path: src/Client/tests/reports/ +``` + +## 故障排除 + +### 常见问题 + +1. **测试编译失败** + ```bash + # 检查Qt环境 + qmake --version + + # 检查依赖库 + pkg-config --list-all | grep -E "(opencv|mysql)" + ``` + +2. **数据库连接失败** + ```bash + # 检查MySQL服务 + sudo systemctl status mysql + + # 检查数据库配置 + mysql -u test_user -p test_battlefield_exploration + ``` + +3. **测试超时** + ```bash + # 增加超时时间 + export TEST_TIMEOUT_MS=10000 + + # 检查系统资源 + top + free -h + ``` + +4. **内存不足** + ```bash + # 减少并发测试数量 + export QT_TEST_MAX_THREADS=2 + + # 清理系统缓存 + sudo sync && sudo echo 3 > /proc/sys/vm/drop_caches + ``` + +### 调试模式 + +启用调试模式获取更多信息: + +```bash +# 设置调试环境变量 +export TEST_DEBUG_MODE=true +export QT_LOGGING_RULES="*.debug=true" + +# 运行测试 +./TestMain --verbose +``` + +## 扩展测试 + +### 添加新的测试用例 + +1. 在对应的测试头文件中添加测试函数声明 +2. 在测试实现文件中添加测试逻辑 +3. 在 `TestMain.cpp` 中注册新的测试模块 + +### 自定义测试数据 + +1. 在 `TestConfig.h` 中添加新的配置参数 +2. 在测试类中实现数据生成函数 +3. 在测试用例中使用自定义数据 + +### 性能基准测试 + +```cpp +// 添加性能基准测试 +void testPerformanceBenchmark() { + QElapsedTimer timer; + timer.start(); + + // 执行被测试的功能 + performTestOperation(); + + qint64 elapsed = timer.elapsed(); + QVERIFY(elapsed < TestConfig::MAX_OPERATION_TIME_MS); +} +``` + +## 联系信息 + +如有问题或建议,请联系: + +- **项目负责人**:系统开发团队 +- **技术支持**:tech-support@battlefield-system.com +- **问题反馈**:https://github.com/battlefield-system/issues + +--- + +**注意**:本测试套件仅用于开发和测试环境,请勿在生产环境中使用测试配置。 \ No newline at end of file diff --git a/src/Client/tests/TestCommunication.h b/src/Client/tests/TestCommunication.h new file mode 100644 index 00000000..0519ecba --- /dev/null +++ b/src/Client/tests/TestCommunication.h @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/Client/tests/TestConfig.h b/src/Client/tests/TestConfig.h new file mode 100644 index 00000000..e02f3336 --- /dev/null +++ b/src/Client/tests/TestConfig.h @@ -0,0 +1,153 @@ +#ifndef TESTCONFIG_H +#define TESTCONFIG_H + +#include +#include +#include + +// 测试配置常量 +namespace TestConfig { + // 测试数据库配置 + const QString TEST_DB_HOST = "localhost"; + const int TEST_DB_PORT = 3306; + const QString TEST_DB_NAME = "test_battlefield_exploration"; + const QString TEST_DB_USER = "test_user"; + const QString TEST_DB_PASSWORD = "test_password"; + + // 测试文件路径 + const QString TEST_DATA_DIR = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/battlefield_test_data"; + const QString TEST_IMAGES_DIR = TEST_DATA_DIR + "/images"; + const QString TEST_VIDEOS_DIR = TEST_DATA_DIR + "/videos"; + const QString TEST_MAPS_DIR = TEST_DATA_DIR + "/maps"; + const QString TEST_LOGS_DIR = TEST_DATA_DIR + "/logs"; + + // 测试图像配置 + const int TEST_IMAGE_WIDTH = 640; + const int TEST_IMAGE_HEIGHT = 480; + const QString TEST_IMAGE_FORMAT = "PNG"; + + // 测试视频配置 + const int TEST_VIDEO_FPS = 30; + const int TEST_VIDEO_DURATION = 10; // 秒 + + // 测试地图配置 + const double TEST_MAP_WIDTH = 100.0; // 米 + const double TEST_MAP_HEIGHT = 100.0; // 米 + const double TEST_MAP_RESOLUTION = 0.1; // 米/像素 + + // 测试设备配置 + const QString TEST_DRONE_ID = "TEST_DRONE_001"; + const QString TEST_DOG_ID = "TEST_DOG_001"; + const QString TEST_SENSOR_ID = "TEST_SENSOR_001"; + + // 测试目标配置 + const QString TEST_ENEMY_ID = "TEST_ENEMY_001"; + const QString TEST_TARGET_TYPE = "TANK"; + const double TEST_THREAT_LEVEL = 8.0; + const double TEST_CONFIDENCE = 0.95; + + // 测试位置配置 + const double TEST_START_X = 0.0; + const double TEST_START_Y = 0.0; + const double TEST_START_Z = 0.0; + const double TEST_END_X = 50.0; + const double TEST_END_Y = 50.0; + const double TEST_END_Z = 0.0; + + // 测试时间配置 + const int TEST_TIMEOUT_MS = 5000; + const int TEST_INTERVAL_MS = 100; + const int TEST_DURATION_MS = 10000; + + // 测试性能阈值 + const double MAX_DETECTION_LATENCY_MS = 100.0; + const double MAX_NAVIGATION_ERROR_M = 0.5; + const double MAX_FUSION_ERROR = 0.1; + const double MIN_DETECTION_ACCURACY = 0.8; + + // 测试网络配置 + const QString TEST_SERVER_HOST = "127.0.0.1"; + const int TEST_SERVER_PORT = 8080; + const int TEST_CLIENT_PORT = 8081; + + // 测试加密配置 + const QString TEST_ENCRYPTION_KEY = "test_encryption_key_12345"; + const QString TEST_IV = "test_iv_12345678"; + + // 测试日志配置 + const QString TEST_LOG_LEVEL = "DEBUG"; + const bool TEST_LOG_TO_FILE = true; + const bool TEST_LOG_TO_CONSOLE = true; + + // 测试模式配置 + const bool TEST_SIMULATION_MODE = true; + const bool TEST_REAL_DEVICE_MODE = false; + const bool TEST_DEBUG_MODE = true; + + // 测试数据生成配置 + const int NUM_TEST_IMAGES = 100; + const int NUM_TEST_TARGETS = 50; + const int NUM_TEST_WAYPOINTS = 20; + const int NUM_TEST_OBSTACLES = 10; + + // 测试场景配置 + enum TestScenario { + SCENARIO_URBAN_COMBAT, + SCENARIO_OPEN_FIELD, + SCENARIO_FOREST, + SCENARIO_UNDERGROUND, + SCENARIO_MIXED_ENVIRONMENT + }; + + // 测试环境配置 + enum TestEnvironment { + ENV_DAYLIGHT, + ENV_NIGHT, + ENV_RAIN, + ENV_FOG, + ENV_DUST + }; + + // 测试难度配置 + enum TestDifficulty { + DIFFICULTY_EASY, + DIFFICULTY_MEDIUM, + DIFFICULTY_HARD, + DIFFICULTY_EXTREME + }; +} + +// 测试工具函数 +namespace TestUtils { + // 创建测试目录 + bool createTestDirectories(); + + // 清理测试数据 + void cleanupTestData(); + + // 生成测试图像 + QString generateTestImage(const QString& filename, int width = TestConfig::TEST_IMAGE_WIDTH, int height = TestConfig::TEST_IMAGE_HEIGHT); + + // 生成测试视频 + QString generateTestVideo(const QString& filename, int duration = TestConfig::TEST_VIDEO_DURATION); + + // 生成测试地图 + QString generateTestMap(const QString& filename); + + // 生成测试传感器数据 + QByteArray generateTestSensorData(); + + // 生成测试目标数据 + QByteArray generateTestTargetData(); + + // 验证测试结果 + bool verifyTestResult(const QString& testName, bool result, const QString& message = ""); + + // 记录测试日志 + void logTestResult(const QString& testName, bool passed, const QString& details = ""); + + // 计算测试统计 + void calculateTestStatistics(); +} + +#endif // TESTCONFIG_H \ No newline at end of file diff --git a/src/Client/tests/TestDataFusion.h b/src/Client/tests/TestDataFusion.h new file mode 100644 index 00000000..fefd810a --- /dev/null +++ b/src/Client/tests/TestDataFusion.h @@ -0,0 +1,105 @@ +#ifndef TESTDATAFUSION_H +#define TESTDATAFUSION_H + +#include +#include +#include +#include +#include +#include +#include + +// 包含被测试的类 +#include "../include/core/DataFusion.h" +#include "../include/core/SensorFusion.h" +#include "../include/core/KalmanFilter.h" + +class TestDataFusion : public QObject +{ + Q_OBJECT + +private slots: + // 初始化测试环境 + void initTestCase(); + void init(); + void cleanup(); + void cleanupTestCase(); + + // 数据融合初始化测试 + void testDataFusionInitialization(); + void testSensorRegistration(); + void testCoordinateTransformation(); + void testFusionAlgorithmSetup(); + + // 多源数据融合测试 + void testMultiSensorFusion(); + void testTemporalFusion(); + void testSpatialFusion(); + void testFeatureFusion(); + + // 传感器数据融合测试 + void testLidarCameraFusion(); + void testIMUGPSFusion(); + void testRadarLidarFusion(); + void testOpticalInfraredFusion(); + + // 目标跟踪融合测试 + void testTargetTrackingFusion(); + void testMultiTargetTracking(); + void testTrackAssociation(); + void testTrackPrediction(); + + // 地图融合测试 + void testMapFusion(); + void testOccupancyGridFusion(); + void testFeatureMapFusion(); + void testSemanticMapFusion(); + + // 态势感知融合测试 + void testSituationalAwareness(); + void testThreatAssessment(); + void testRiskEvaluation(); + void testDecisionSupport(); + + // 数据质量测试 + void testDataQualityAssessment(); + void testOutlierDetection(); + void testNoiseFiltering(); + void testDataValidation(); + + // 性能测试 + void testFusionSpeed(); + void testMemoryUsage(); + void testRealTimePerformance(); + void testScalability(); + + // 鲁棒性测试 + void testSensorFailureHandling(); + void testDataLossHandling(); + void testInconsistentDataHandling(); + void testDynamicSensorConfiguration(); + +private: + DataFusion* m_dataFusion; + SensorFusion* m_sensorFusion; + KalmanFilter* m_kalmanFilter; + + // 测试数据 + QList m_testSensorData; + QList m_testTargetData; + QList m_testMapData; + + // 测试数据准备 + void prepareTestSensorData(); + void prepareTestTargetData(); + void prepareTestMapData(); + void cleanupTestData(); + + // 测试辅助函数 + bool verifyFusionResult(const FusionResult& result); + double calculateFusionAccuracy(const QList& results); + bool verifyDataConsistency(const QList& data); + void simulateFusionScenario(const QString& scenario); +}; + +#endif // TESTDATAFUSION_H \ No newline at end of file diff --git a/src/Client/tests/TestDatabaseManager.cpp b/src/Client/tests/TestDatabaseManager.cpp new file mode 100644 index 00000000..637dbfab --- /dev/null +++ b/src/Client/tests/TestDatabaseManager.cpp @@ -0,0 +1,542 @@ +#include "TestDatabaseManager.h" +#include +#include +#include +#include +#include + +void TestDatabaseManager::initTestCase() +{ + qDebug() << "初始化数据库管理测试环境..."; + + // 创建测试数据库目录 + QString testDbPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/test_battlefield_db"; + QDir().mkpath(testDbPath); + + // 初始化数据库管理器 + m_dbManager = new DatabaseManager(); + m_enemyDb = new EnemyDatabase(); + m_dogDb = new DogDatabase(); + m_uavDb = new UAVDatabase(); +} + +void TestDatabaseManager::init() +{ + qDebug() << "准备测试数据..."; + createTestData(); +} + +void TestDatabaseManager::cleanup() +{ + qDebug() << "清理测试数据..."; + cleanupTestData(); +} + +void TestDatabaseManager::cleanupTestCase() +{ + qDebug() << "清理数据库管理测试环境..."; + + delete m_uavDb; + delete m_dogDb; + delete m_enemyDb; + delete m_dbManager; +} + +void TestDatabaseManager::testDatabaseConnection() +{ + qDebug() << "测试数据库连接..."; + + // 测试数据库连接 + bool connected = m_dbManager->connectToDatabase(); + QVERIFY(connected); + + // 测试连接状态 + QVERIFY(m_dbManager->isConnected()); + + qDebug() << "✅ 数据库连接测试通过"; +} + +void TestDatabaseManager::testDatabaseCreation() +{ + qDebug() << "测试数据库创建..."; + + // 测试数据库表创建 + bool tablesCreated = m_dbManager->createTables(); + QVERIFY(tablesCreated); + + // 验证表是否存在 + QSqlDatabase db = QSqlDatabase::database(); + QStringList tables = db.tables(); + + QVERIFY(tables.contains("enemy_targets")); + QVERIFY(tables.contains("dog_status")); + QVERIFY(tables.contains("uav_status")); + QVERIFY(tables.contains("intelligence_data")); + + qDebug() << "✅ 数据库创建测试通过"; +} + +void TestDatabaseManager::testDatabaseConfig() +{ + qDebug() << "测试数据库配置..."; + + // 测试配置文件读取 + DatabaseConfig config; + bool configLoaded = config.loadFromFile("../config/database.ini"); + QVERIFY(configLoaded); + + // 验证配置参数 + QVERIFY(!config.getHost().isEmpty()); + QVERIFY(config.getPort() > 0); + QVERIFY(!config.getDatabaseName().isEmpty()); + + qDebug() << "✅ 数据库配置测试通过"; +} + +void TestDatabaseManager::testEnemyDatabaseOperations() +{ + qDebug() << "测试敌方数据库操作..."; + + // 测试敌方目标插入 + EnemyTarget target; + target.id = "TEST_ENEMY_001"; + target.type = "TANK"; + target.location.x = 100.0; + target.location.y = 200.0; + target.location.z = 0.0; + target.threatLevel = 8; + target.confidence = 0.95; + target.timestamp = QDateTime::currentDateTime(); + + bool inserted = m_enemyDb->insertEnemyTarget(target); + QVERIFY(inserted); + + // 测试敌方目标查询 + EnemyTarget retrieved = m_enemyDb->getEnemyTarget("TEST_ENEMY_001"); + QCOMPARE(retrieved.id, target.id); + QCOMPARE(retrieved.type, target.type); + QCOMPARE(retrieved.threatLevel, target.threatLevel); + + qDebug() << "✅ 敌方数据库操作测试通过"; +} + +void TestDatabaseManager::testEnemyDataInsertion() +{ + qDebug() << "测试敌方数据插入..."; + + // 插入多个敌方目标 + QList targets; + for (int i = 1; i <= 5; ++i) { + EnemyTarget target; + target.id = QString("TEST_ENEMY_%1").arg(i, 3, 10, QChar('0')); + target.type = (i % 2 == 0) ? "TANK" : "SOLDIER"; + target.location.x = i * 50.0; + target.location.y = i * 100.0; + target.location.z = 0.0; + target.threatLevel = (i % 5) + 1; + target.confidence = 0.8 + (i * 0.02); + target.timestamp = QDateTime::currentDateTime(); + targets.append(target); + } + + bool batchInserted = m_enemyDb->insertEnemyTargets(targets); + QVERIFY(batchInserted); + + // 验证插入的数据 + QList retrieved = m_enemyDb->getAllEnemyTargets(); + QVERIFY(retrieved.size() >= targets.size()); + + qDebug() << "✅ 敌方数据插入测试通过"; +} + +void TestDatabaseManager::testEnemyDataQuery() +{ + qDebug() << "测试敌方数据查询..."; + + // 测试按类型查询 + QList tanks = m_enemyDb->getEnemyTargetsByType("TANK"); + QVERIFY(!tanks.isEmpty()); + + // 测试按威胁等级查询 + QList highThreat = m_enemyDb->getEnemyTargetsByThreatLevel(5, 10); + QVERIFY(!highThreat.isEmpty()); + + // 测试按位置范围查询 + QList nearby = m_enemyDb->getEnemyTargetsInRange(0, 0, 300, 300); + QVERIFY(!nearby.isEmpty()); + + qDebug() << "✅ 敌方数据查询测试通过"; +} + +void TestDatabaseManager::testEnemyDataUpdate() +{ + qDebug() << "测试敌方数据更新..."; + + // 更新敌方目标信息 + EnemyTarget target = m_enemyDb->getEnemyTarget("TEST_ENEMY_001"); + target.threatLevel = 10; + target.confidence = 0.99; + target.location.x = 150.0; + target.location.y = 250.0; + + bool updated = m_enemyDb->updateEnemyTarget(target); + QVERIFY(updated); + + // 验证更新结果 + EnemyTarget retrieved = m_enemyDb->getEnemyTarget("TEST_ENEMY_001"); + QCOMPARE(retrieved.threatLevel, 10); + QCOMPARE(retrieved.confidence, 0.99); + + qDebug() << "✅ 敌方数据更新测试通过"; +} + +void TestDatabaseManager::testEnemyDataDeletion() +{ + qDebug() << "测试敌方数据删除..."; + + // 删除测试数据 + bool deleted = m_enemyDb->deleteEnemyTarget("TEST_ENEMY_001"); + QVERIFY(deleted); + + // 验证删除结果 + EnemyTarget retrieved = m_enemyDb->getEnemyTarget("TEST_ENEMY_001"); + QVERIFY(retrieved.id.isEmpty()); + + qDebug() << "✅ 敌方数据删除测试通过"; +} + +void TestDatabaseManager::testDogDatabaseOperations() +{ + qDebug() << "测试机器狗数据库操作..."; + + // 测试机器狗状态插入 + DogStatus status; + status.dogId = "TEST_DOG_001"; + status.status = "ACTIVE"; + status.batteryLevel = 85.5; + status.location.x = 50.0; + status.location.y = 75.0; + status.location.z = 0.0; + status.timestamp = QDateTime::currentDateTime(); + + bool inserted = m_dogDb->insertDogStatus(status); + QVERIFY(inserted); + + // 测试机器狗状态查询 + DogStatus retrieved = m_dogDb->getDogStatus("TEST_DOG_001"); + QCOMPARE(retrieved.dogId, status.dogId); + QCOMPARE(retrieved.status, status.status); + QCOMPARE(retrieved.batteryLevel, status.batteryLevel); + + qDebug() << "✅ 机器狗数据库操作测试通过"; +} + +void TestDatabaseManager::testDogStatusUpdate() +{ + qDebug() << "测试机器狗状态更新..."; + + // 更新机器狗状态 + DogStatus status = m_dogDb->getDogStatus("TEST_DOG_001"); + status.batteryLevel = 75.0; + status.location.x = 60.0; + status.location.y = 85.0; + status.status = "EXPLORING"; + + bool updated = m_dogDb->updateDogStatus(status); + QVERIFY(updated); + + // 验证更新结果 + DogStatus retrieved = m_dogDb->getDogStatus("TEST_DOG_001"); + QCOMPARE(retrieved.batteryLevel, 75.0); + QCOMPARE(retrieved.status, "EXPLORING"); + + qDebug() << "✅ 机器狗状态更新测试通过"; +} + +void TestDatabaseManager::testDogLocationTracking() +{ + qDebug() << "测试机器狗位置跟踪..."; + + // 插入位置历史记录 + QList locations; + for (int i = 0; i < 10; ++i) { + DogLocation location; + location.dogId = "TEST_DOG_001"; + location.x = 50.0 + i * 5.0; + location.y = 75.0 + i * 3.0; + location.z = 0.0; + location.timestamp = QDateTime::currentDateTime().addSecs(i * 30); + locations.append(location); + } + + bool inserted = m_dogDb->insertDogLocations(locations); + QVERIFY(inserted); + + // 查询位置历史 + QList history = m_dogDb->getDogLocationHistory("TEST_DOG_001", 10); + QCOMPARE(history.size(), 10); + + qDebug() << "✅ 机器狗位置跟踪测试通过"; +} + +void TestDatabaseManager::testUAVDatabaseOperations() +{ + qDebug() << "测试无人机数据库操作..."; + + // 测试无人机状态插入 + UAVStatus status; + status.uavId = "TEST_UAV_001"; + status.status = "FLYING"; + status.batteryLevel = 90.0; + status.altitude = 100.0; + status.location.x = 200.0; + status.location.y = 300.0; + status.location.z = 100.0; + status.timestamp = QDateTime::currentDateTime(); + + bool inserted = m_uavDb->insertUAVStatus(status); + QVERIFY(inserted); + + // 测试无人机状态查询 + UAVStatus retrieved = m_uavDb->getUAVStatus("TEST_UAV_001"); + QCOMPARE(retrieved.uavId, status.uavId); + QCOMPARE(retrieved.status, status.status); + QCOMPARE(retrieved.altitude, status.altitude); + + qDebug() << "✅ 无人机数据库操作测试通过"; +} + +void TestDatabaseManager::testUAVStatusUpdate() +{ + qDebug() << "测试无人机状态更新..."; + + // 更新无人机状态 + UAVStatus status = m_uavDb->getUAVStatus("TEST_UAV_001"); + status.batteryLevel = 80.0; + status.altitude = 120.0; + status.location.x = 220.0; + status.location.y = 320.0; + status.status = "SCANNING"; + + bool updated = m_uavDb->updateUAVStatus(status); + QVERIFY(updated); + + // 验证更新结果 + UAVStatus retrieved = m_uavDb->getUAVStatus("TEST_UAV_001"); + QCOMPARE(retrieved.batteryLevel, 80.0); + QCOMPARE(retrieved.altitude, 120.0); + QCOMPARE(retrieved.status, "SCANNING"); + + qDebug() << "✅ 无人机状态更新测试通过"; +} + +void TestDatabaseManager::testUAVFlightData() +{ + qDebug() << "测试无人机飞行数据..."; + + // 插入飞行数据 + QList flightData; + for (int i = 0; i < 20; ++i) { + UAVFlightData data; + data.uavId = "TEST_UAV_001"; + data.altitude = 100.0 + i * 2.0; + data.speed = 15.0 + i * 0.5; + data.heading = i * 18.0; // 每30秒转向18度 + data.location.x = 200.0 + i * 10.0; + data.location.y = 300.0 + i * 8.0; + data.location.z = 100.0 + i * 2.0; + data.timestamp = QDateTime::currentDateTime().addSecs(i * 30); + flightData.append(data); + } + + bool inserted = m_uavDb->insertUAVFlightData(flightData); + QVERIFY(inserted); + + // 查询飞行轨迹 + QList trajectory = m_uavDb->getUAVFlightTrajectory("TEST_UAV_001", 20); + QCOMPARE(trajectory.size(), 20); + + qDebug() << "✅ 无人机飞行数据测试通过"; +} + +void TestDatabaseManager::testDatabasePerformance() +{ + qDebug() << "测试数据库性能..."; + + // 性能测试:批量插入 + QList targets; + for (int i = 0; i < 1000; ++i) { + EnemyTarget target; + target.id = QString("PERF_TEST_%1").arg(i, 4, 10, QChar('0')); + target.type = "SOLDIER"; + target.location.x = i * 10.0; + target.location.y = i * 15.0; + target.location.z = 0.0; + target.threatLevel = (i % 10) + 1; + target.confidence = 0.7 + (i % 30) * 0.01; + target.timestamp = QDateTime::currentDateTime(); + targets.append(target); + } + + QElapsedTimer timer; + timer.start(); + bool inserted = m_enemyDb->insertEnemyTargets(targets); + qint64 insertTime = timer.elapsed(); + + QVERIFY(inserted); + QVERIFY(insertTime < 5000); // 5秒内完成1000条记录插入 + + qDebug() << "批量插入1000条记录耗时:" << insertTime << "毫秒"; + + // 性能测试:查询 + timer.restart(); + QList results = m_enemyDb->getEnemyTargetsByType("SOLDIER"); + qint64 queryTime = timer.elapsed(); + + QVERIFY(queryTime < 1000); // 1秒内完成查询 + QVERIFY(results.size() >= 1000); + + qDebug() << "查询1000条记录耗时:" << queryTime << "毫秒"; + + qDebug() << "✅ 数据库性能测试通过"; +} + +void TestDatabaseManager::testConcurrentAccess() +{ + qDebug() << "测试并发访问..."; + + // 创建多个线程同时访问数据库 + QList threads; + QList results; + + for (int i = 0; i < 5; ++i) { + QThread* thread = QThread::create([this, i, &results]() { + // 每个线程执行不同的数据库操作 + switch (i % 3) { + case 0: { + // 插入操作 + EnemyTarget target; + target.id = QString("CONCURRENT_%1").arg(i); + target.type = "TANK"; + target.location.x = i * 100.0; + target.location.y = i * 200.0; + target.threatLevel = i + 1; + target.confidence = 0.8; + target.timestamp = QDateTime::currentDateTime(); + results.append(m_enemyDb->insertEnemyTarget(target)); + break; + } + case 1: { + // 查询操作 + QList targets = m_enemyDb->getAllEnemyTargets(); + results.append(!targets.isEmpty()); + break; + } + case 2: { + // 更新操作 + if (i > 0) { + EnemyTarget target = m_enemyDb->getEnemyTarget(QString("CONCURRENT_%1").arg(i-1)); + if (!target.id.isEmpty()) { + target.threatLevel = 10; + results.append(m_enemyDb->updateEnemyTarget(target)); + } else { + results.append(false); + } + } else { + results.append(true); + } + break; + } + } + }); + + threads.append(thread); + thread->start(); + } + + // 等待所有线程完成 + for (QThread* thread : threads) { + thread->wait(); + delete thread; + } + + // 验证所有操作都成功 + for (bool result : results) { + QVERIFY(result); + } + + qDebug() << "✅ 并发访问测试通过"; +} + +void TestDatabaseManager::testDataIntegrity() +{ + qDebug() << "测试数据完整性..."; + + // 测试事务回滚 + m_dbManager->beginTransaction(); + + EnemyTarget target; + target.id = "INTEGRITY_TEST"; + target.type = "TANK"; + target.location.x = 500.0; + target.location.y = 600.0; + target.threatLevel = 5; + target.confidence = 0.9; + target.timestamp = QDateTime::currentDateTime(); + + bool inserted = m_enemyDb->insertEnemyTarget(target); + QVERIFY(inserted); + + // 故意制造错误(插入重复ID) + EnemyTarget duplicate = target; + bool duplicateInserted = m_enemyDb->insertEnemyTarget(duplicate); + + if (duplicateInserted) { + // 如果允许重复,则回滚整个事务 + m_dbManager->rollbackTransaction(); + } else { + // 如果不允许重复,则提交事务 + m_dbManager->commitTransaction(); + } + + // 验证数据完整性 + EnemyTarget retrieved = m_enemyDb->getEnemyTarget("INTEGRITY_TEST"); + if (duplicateInserted) { + QVERIFY(retrieved.id.isEmpty()); // 应该被回滚 + } else { + QVERIFY(!retrieved.id.isEmpty()); // 应该被提交 + } + + qDebug() << "✅ 数据完整性测试通过"; +} + +void TestDatabaseManager::createTestData() +{ + // 创建测试数据的实现 + // 这里可以添加一些基础的测试数据 +} + +void TestDatabaseManager::cleanupTestData() +{ + // 清理测试数据 + m_enemyDb->deleteEnemyTarget("TEST_ENEMY_001"); + m_enemyDb->deleteEnemyTarget("INTEGRITY_TEST"); + + // 清理性能测试数据 + for (int i = 0; i < 1000; ++i) { + m_enemyDb->deleteEnemyTarget(QString("PERF_TEST_%1").arg(i, 4, 10, QChar('0'))); + } + + // 清理并发测试数据 + for (int i = 0; i < 5; ++i) { + m_enemyDb->deleteEnemyTarget(QString("CONCURRENT_%1").arg(i)); + } +} + +bool TestDatabaseManager::verifyTestData() +{ + // 验证测试数据的实现 + return true; +} + +QTEST_MAIN(TestDatabaseManager) \ No newline at end of file diff --git a/src/Client/tests/TestDatabaseManager.h b/src/Client/tests/TestDatabaseManager.h new file mode 100644 index 00000000..8f85e640 --- /dev/null +++ b/src/Client/tests/TestDatabaseManager.h @@ -0,0 +1,69 @@ +#ifndef TESTDATABASEMANAGER_H +#define TESTDATABASEMANAGER_H + +#include +#include +#include +#include +#include +#include +#include +#include + +// 包含被测试的类 +#include "../include/core/database/DatabaseManager.h" +#include "../include/core/database/EnemyDatabase.h" +#include "../include/core/database/DogDatabase.h" +#include "../include/core/database/UAVDatabase.h" + +class TestDatabaseManager : public QObject +{ + Q_OBJECT + +private slots: + // 初始化测试环境 + void initTestCase(); + void init(); + void cleanup(); + void cleanupTestCase(); + + // 数据库连接测试 + void testDatabaseConnection(); + void testDatabaseCreation(); + void testDatabaseConfig(); + + // 敌方数据库测试 + void testEnemyDatabaseOperations(); + void testEnemyDataInsertion(); + void testEnemyDataQuery(); + void testEnemyDataUpdate(); + void testEnemyDataDeletion(); + + // 机器狗数据库测试 + void testDogDatabaseOperations(); + void testDogStatusUpdate(); + void testDogLocationTracking(); + + // 无人机数据库测试 + void testUAVDatabaseOperations(); + void testUAVStatusUpdate(); + void testUAVFlightData(); + + // 数据库性能测试 + void testDatabasePerformance(); + void testConcurrentAccess(); + void testDataIntegrity(); + +private: + DatabaseManager* m_dbManager; + EnemyDatabase* m_enemyDb; + DogDatabase* m_dogDb; + UAVDatabase* m_uavDb; + + // 测试数据 + void createTestData(); + void cleanupTestData(); + bool verifyTestData(); +}; + +#endif // TESTDATABASEMANAGER_H \ No newline at end of file diff --git a/src/Client/tests/TestDeviceControl.h b/src/Client/tests/TestDeviceControl.h new file mode 100644 index 00000000..7b55f6a2 --- /dev/null +++ b/src/Client/tests/TestDeviceControl.h @@ -0,0 +1,76 @@ +#ifndef TESTDEVICECONTROL_H +#define TESTDEVICECONTROL_H + +#include +#include +#include +#include +#include +#include + +// 包含被测试的类 +#include "../include/ui/dialogs/RobotDogControlDialog.h" +#include "../include/ui/dialogs/DroneControlDialog.h" +#include "../include/ui/components/DeviceListPanel.h" + +class TestDeviceControl : public QObject +{ + Q_OBJECT + +private slots: + // 初始化测试环境 + void initTestCase(); + void init(); + void cleanup(); + void cleanupTestCase(); + + // 机器狗控制测试 + void testRobotDogInitialization(); + void testRobotDogMovement(); + void testRobotDogNavigation(); + void testRobotDogStatusMonitoring(); + void testRobotDogEmergencyStop(); + + // 无人机控制测试 + void testDroneInitialization(); + void testDroneTakeoff(); + void testDroneFlight(); + void testDroneLanding(); + void testDroneStatusMonitoring(); + void testDroneEmergencyLanding(); + + // 设备列表管理测试 + void testDeviceListManagement(); + void testDeviceConnection(); + void testDeviceDisconnection(); + void testDeviceStatusUpdate(); + + // 协同控制测试 + void testCoordinatedMovement(); + void testFormationControl(); + void testTaskAllocation(); + void testConflictResolution(); + + // 通信测试 + void testDeviceCommunication(); + void testCommandTransmission(); + void testStatusFeedback(); + void testErrorHandling(); + + // 性能测试 + void testControlLatency(); + void testResponseTime(); + void testConcurrentControl(); + +private: + RobotDogControlDialog* m_robotDogDialog; + DroneControlDialog* m_droneDialog; + DeviceListPanel* m_deviceListPanel; + + // 模拟设备状态 + void simulateDeviceStatus(); + void simulateCommunicationDelay(); + bool verifyDeviceResponse(); +}; + +#endif // TESTDEVICECONTROL_H \ No newline at end of file diff --git a/src/Client/tests/TestMain.cpp b/src/Client/tests/TestMain.cpp new file mode 100644 index 00000000..b0c8750b --- /dev/null +++ b/src/Client/tests/TestMain.cpp @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#include + +// 测试模块头文件 +#include "TestDatabaseManager.h" +#include "TestDeviceControl.h" +#include "TestYOLODetector.h" +#include "TestSLAMProcessor.h" +#include "TestDataFusion.h" +#include "TestCommunication.h" +#include "TestMissionController.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + qDebug() << "=== 基于空地协同的战场环境探索系统 - 测试套件 ==="; + qDebug() << "开始执行测试..."; + + int testResult = 0; + + // 1. 数据库管理测试 + qDebug() << "\n--- 执行数据库管理测试 ---"; + TestDatabaseManager dbTest; + testResult += QTest::qExec(&dbTest, argc, argv); + + // 2. 设备控制测试 + qDebug() << "\n--- 执行设备控制测试 ---"; + TestDeviceControl deviceTest; + testResult += QTest::qExec(&deviceTest, argc, argv); + + // 3. YOLO检测器测试 + qDebug() << "\n--- 执行YOLO检测器测试 ---"; + TestYOLODetector yoloTest; + testResult += QTest::qExec(&yoloTest, argc, argv); + + // 4. SLAM处理器测试 + qDebug() << "\n--- 执行SLAM处理器测试 ---"; + TestSLAMProcessor slamTest; + testResult += QTest::qExec(&slamTest, argc, argv); + + // 5. 数据融合测试 + qDebug() << "\n--- 执行数据融合测试 ---"; + TestDataFusion fusionTest; + testResult += QTest::qExec(&fusionTest, argc, argv); + + // 6. 通信模块测试 + qDebug() << "\n--- 执行通信模块测试 ---"; + TestCommunication commTest; + testResult += QTest::qExec(&commTest, argc, argv); + + // 7. 任务控制器测试 + qDebug() << "\n--- 执行任务控制器测试 ---"; + TestMissionController missionTest; + testResult += QTest::qExec(&missionTest, argc, argv); + + // 测试结果汇总 + qDebug() << "\n=== 测试结果汇总 ==="; + if (testResult == 0) { + qDebug() << "✅ 所有测试通过!"; + } else { + qDebug() << "❌ 有" << testResult << "个测试失败"; + } + + return testResult; +} \ No newline at end of file diff --git a/src/Client/tests/TestMissionController.h b/src/Client/tests/TestMissionController.h new file mode 100644 index 00000000..81f3a039 --- /dev/null +++ b/src/Client/tests/TestMissionController.h @@ -0,0 +1,96 @@ +#ifndef TESTMISSIONCONTROLLER_H +#define TESTMISSIONCONTROLLER_H + +#include +#include +#include +#include +#include +#include + +// 包含被测试的类 +#include "../include/core/MissionController.h" +#include "../include/core/TaskScheduler.h" +#include "../include/core/CoordinationController.h" + +class TestMissionController : public QObject +{ + Q_OBJECT + +private slots: + // 初始化测试环境 + void initTestCase(); + void init(); + void cleanup(); + void cleanupTestCase(); + + // 任务管理测试 + void testMissionCreation(); + void testMissionPlanning(); + void testMissionExecution(); + void testMissionMonitoring(); + + // 任务调度测试 + void testTaskScheduling(); + void testTaskAllocation(); + void testTaskPrioritization(); + void testTaskDependencies(); + + // 协同控制测试 + void testCoordinatedControl(); + void testFormationControl(); + void testConflictResolution(); + void testResourceSharing(); + + // 任务执行测试 + void testExplorationMission(); + void testSurveillanceMission(); + void testReconnaissanceMission(); + void testIntelligenceGatheringMission(); + + // 状态管理测试 + void testMissionStateManagement(); + void testDeviceStateTracking(); + void testSystemHealthMonitoring(); + void testPerformanceMetrics(); + + // 异常处理测试 + void testMissionAbort(); + void testDeviceFailureHandling(); + void testEmergencyResponse(); + void testRecoveryProcedures(); + + // 性能测试 + void testMissionExecutionSpeed(); + void testResourceUtilization(); + void testConcurrentMissions(); + void testScalability(); + + // 集成测试 + void testEndToEndMission(); + void testMultiDeviceIntegration(); + void testSystemIntegration(); + void testUserInterfaceIntegration(); + +private: + MissionController* m_missionController; + TaskScheduler* m_taskScheduler; + CoordinationController* m_coordinationController; + + // 测试数据 + QList m_testMissions; + QList m_testTasks; + + // 测试数据准备 + void prepareTestMissions(); + void prepareTestTasks(); + void cleanupTestData(); + + // 测试辅助函数 + bool verifyMissionExecution(const Mission& mission); + double calculateMissionSuccessRate(const QList& missions); + bool verifyTaskCompletion(const Task& task); + void simulateMissionScenario(const QString& scenario); +}; + +#endif // TESTMISSIONCONTROLLER_H \ No newline at end of file diff --git a/src/Client/tests/TestSLAMProcessor.h b/src/Client/tests/TestSLAMProcessor.h new file mode 100644 index 00000000..f9aa1a6c --- /dev/null +++ b/src/Client/tests/TestSLAMProcessor.h @@ -0,0 +1,105 @@ +#ifndef TESTSLAMPROCESSOR_H +#define TESTSLAMPROCESSOR_H + +#include +#include +#include +#include +#include +#include +#include + +// 包含被测试的类 +#include "../include/core/SLAMProcessor.h" +#include "../include/core/PathPlanner.h" +#include "../include/core/MapBuilder.h" + +class TestSLAMProcessor : public QObject +{ + Q_OBJECT + +private slots: + // 初始化测试环境 + void initTestCase(); + void init(); + void cleanup(); + void cleanupTestCase(); + + // SLAM初始化测试 + void testSLAMInitialization(); + void testSensorCalibration(); + void testCoordinateSystemSetup(); + void testParameterConfiguration(); + + // 传感器数据处理测试 + void testLidarDataProcessing(); + void testIMUDataProcessing(); + void testCameraDataProcessing(); + void testMultiSensorFusion(); + + // 定位测试 + void testLocalization(); + void testPoseEstimation(); + void testPositionTracking(); + void testOrientationEstimation(); + + // 建图测试 + void testMapBuilding(); + void testOccupancyGridGeneration(); + void testFeatureExtraction(); + void testLoopClosureDetection(); + + // 路径规划测试 + void testPathPlanning(); + void testObstacleAvoidance(); + void testGlobalPathPlanning(); + void testLocalPathPlanning(); + + // 导航测试 + void testNavigation(); + void testWaypointFollowing(); + void testDynamicObstacleAvoidance(); + void testNavigationAccuracy(); + + // 地图管理测试 + void testMapLoading(); + void testMapSaving(); + void testMapUpdating(); + void testMapOptimization(); + + // 性能测试 + void testProcessingSpeed(); + void testMemoryEfficiency(); + void testRealTimePerformance(); + void testScalability(); + + // 鲁棒性测试 + void testSensorFailureHandling(); + void testNoiseRobustness(); + void testDynamicEnvironment(); + void testLongTermOperation(); + +private: + SLAMProcessor* m_slamProcessor; + PathPlanner* m_pathPlanner; + MapBuilder* m_mapBuilder; + + // 测试数据 + QList m_testSensorData; + QList m_testTrajectory; + QList m_testObstacles; + + // 测试数据准备 + void prepareTestSensorData(); + void generateSyntheticTrajectory(); + void createTestEnvironment(); + void cleanupTestData(); + + // 测试辅助函数 + bool verifyPoseEstimation(const Pose& estimated, const Pose& groundTruth); + double calculateLocalizationAccuracy(const QList& estimated, const QList& groundTruth); + bool verifyPathFeasibility(const QList& path); + void simulateNavigationScenario(const QString& scenario); +}; + +#endif // TESTSLAMPROCESSOR_H \ No newline at end of file diff --git a/src/Client/tests/TestYOLODetector.h b/src/Client/tests/TestYOLODetector.h new file mode 100644 index 00000000..78629bf9 --- /dev/null +++ b/src/Client/tests/TestYOLODetector.h @@ -0,0 +1,95 @@ +#ifndef TESTYOLODETECTOR_H +#define TESTYOLODETECTOR_H + +#include +#include +#include +#include +#include +#include +#include +#include + +// 包含被测试的类 +#include "../include/core/YOLODetector.h" +#include "../include/core/TargetClassifier.h" + +class TestYOLODetector : public QObject +{ + Q_OBJECT + +private slots: + // 初始化测试环境 + void initTestCase(); + void init(); + void cleanup(); + void cleanupTestCase(); + + // 模型加载测试 + void testModelLoading(); + void testModelValidation(); + void testModelPerformance(); + + // 目标检测测试 + void testObjectDetection(); + void testTargetClassification(); + void testConfidenceScoring(); + void testBoundingBoxAccuracy(); + + // 图像处理测试 + void testImagePreprocessing(); + void testImageResizing(); + void testImageNormalization(); + void testBatchProcessing(); + + // 特定目标检测测试 + void testMilitaryVehicleDetection(); + void testPersonDetection(); + void testWeaponDetection(); + void testBuildingDetection(); + + // 实时检测测试 + void testRealTimeDetection(); + void testVideoStreamProcessing(); + void testDetectionLatency(); + void testDetectionAccuracy(); + + // 多目标检测测试 + void testMultipleObjectDetection(); + void testObjectTracking(); + void testOcclusionHandling(); + void testSmallObjectDetection(); + + // 环境适应性测试 + void testLightingConditions(); + void testWeatherConditions(); + void testDistanceVariation(); + void testAngleVariation(); + + // 性能优化测试 + void testDetectionSpeed(); + void testMemoryUsage(); + void testGPUAcceleration(); + void testModelOptimization(); + +private: + YOLODetector* m_yoloDetector; + TargetClassifier* m_targetClassifier; + + // 测试图像 + QList m_testImages; + QList m_testImagePaths; + + // 测试数据准备 + void prepareTestImages(); + void createSyntheticTestImages(); + void loadRealTestImages(); + void cleanupTestImages(); + + // 测试辅助函数 + bool verifyDetectionResult(const DetectionResult& result); + double calculateDetectionAccuracy(const QList& results); + void simulateDetectionScenario(const QString& scenario); +}; + +#endif // TESTYOLODETECTOR_H \ No newline at end of file diff --git a/src/Client/tests/run_tests.sh b/src/Client/tests/run_tests.sh new file mode 100644 index 00000000..a406a2a7 --- /dev/null +++ b/src/Client/tests/run_tests.sh @@ -0,0 +1,212 @@ +#!/bin/bash + +# 基于空地协同的战场环境探索系统 - 测试运行脚本 +# 作者: 系统开发团队 +# 日期: 2024年 + +echo "==========================================" +echo "基于空地协同的战场环境探索系统 - 测试套件" +echo "==========================================" + +# 设置环境变量 +export QT_QPA_PLATFORM=offscreen +export QT_LOGGING_RULES="*.debug=true;qt.qpa.*=false" + +# 测试配置 +TEST_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BUILD_DIR="$TEST_DIR/../build" +BIN_DIR="$BUILD_DIR/bin" +LOG_DIR="$TEST_DIR/logs" +REPORT_DIR="$TEST_DIR/reports" + +# 创建必要的目录 +mkdir -p "$LOG_DIR" +mkdir -p "$REPORT_DIR" + +# 测试时间戳 +TIMESTAMP=$(date +"%Y%m%d_%H%M%S") +LOG_FILE="$LOG_DIR/test_run_$TIMESTAMP.log" +REPORT_FILE="$REPORT_DIR/test_report_$TIMESTAMP.html" + +echo "测试开始时间: $(date)" +echo "日志文件: $LOG_FILE" +echo "报告文件: $REPORT_FILE" +echo "" + +# 检查构建目录 +if [ ! -d "$BUILD_DIR" ]; then + echo "❌ 错误: 构建目录不存在,请先编译项目" + echo "运行: cd $BUILD_DIR && make" + exit 1 +fi + +# 检查可执行文件 +TEST_EXECUTABLE="$BIN_DIR/TestMain" +if [ ! -f "$TEST_EXECUTABLE" ]; then + echo "❌ 错误: 测试可执行文件不存在: $TEST_EXECUTABLE" + echo "请先编译测试程序" + exit 1 +fi + +# 函数:运行单个测试模块 +run_test_module() { + local module_name="$1" + local test_args="$2" + + echo "🧪 运行 $module_name 测试..." + echo "----------------------------------------" + + # 运行测试并捕获输出 + if [ -n "$test_args" ]; then + "$TEST_EXECUTABLE" $test_args 2>&1 | tee -a "$LOG_FILE" + else + "$TEST_EXECUTABLE" 2>&1 | tee -a "$LOG_FILE" + fi + + local exit_code=${PIPESTATUS[0]} + + if [ $exit_code -eq 0 ]; then + echo "✅ $module_name 测试通过" + return 0 + else + echo "❌ $module_name 测试失败 (退出码: $exit_code)" + return 1 + fi +} + +# 函数:生成测试报告 +generate_test_report() { + echo "📊 生成测试报告..." + + cat > "$REPORT_FILE" << EOF + + + + 战场环境探索系统 - 测试报告 + + + + +
+

基于空地协同的战场环境探索系统 - 测试报告

+

生成时间: $(date)

+

测试环境: $(uname -a)

+
+ +
+

测试摘要

+

总测试模块: 7

+

通过模块: $PASSED_COUNT

+

失败模块: $FAILED_COUNT

+

成功率: $((PASSED_COUNT * 100 / (PASSED_COUNT + FAILED_COUNT)))%

+
+ +
+

测试模块详情

+ $(cat "$LOG_DIR/test_results_$TIMESTAMP.txt" 2>/dev/null || echo "

无详细结果

") +
+ +
+

测试日志

+
$(tail -n 100 "$LOG_FILE" 2>/dev/null || echo "无日志数据")
+
+ + +EOF + + echo "📄 测试报告已生成: $REPORT_FILE" +} + +# 主测试流程 +echo "🚀 开始执行测试套件..." +echo "" + +# 初始化计数器 +PASSED_COUNT=0 +FAILED_COUNT=0 + +# 1. 数据库管理测试 +if run_test_module "数据库管理" "--database"; then + ((PASSED_COUNT++)) +else + ((FAILED_COUNT++)) +fi + +# 2. 设备控制测试 +if run_test_module "设备控制" "--device"; then + ((PASSED_COUNT++)) +else + ((FAILED_COUNT++)) +fi + +# 3. YOLO检测器测试 +if run_test_module "YOLO检测器" "--yolo"; then + ((PASSED_COUNT++)) +else + ((FAILED_COUNT++)) +fi + +# 4. SLAM处理器测试 +if run_test_module "SLAM处理器" "--slam"; then + ((PASSED_COUNT++)) +else + ((FAILED_COUNT++)) +fi + +# 5. 数据融合测试 +if run_test_module "数据融合" "--fusion"; then + ((PASSED_COUNT++)) +else + ((FAILED_COUNT++)) +fi + +# 6. 通信模块测试 +if run_test_module "通信模块" "--communication"; then + ((PASSED_COUNT++)) +else + ((FAILED_COUNT++)) +fi + +# 7. 任务控制器测试 +if run_test_module "任务控制器" "--mission"; then + ((PASSED_COUNT++)) +else + ((FAILED_COUNT++)) +fi + +# 测试结果汇总 +echo "" +echo "==========================================" +echo "测试结果汇总" +echo "==========================================" +echo "总测试模块: $((PASSED_COUNT + FAILED_COUNT))" +echo "通过模块: $PASSED_COUNT" +echo "失败模块: $FAILED_COUNT" +echo "成功率: $((PASSED_COUNT * 100 / (PASSED_COUNT + FAILED_COUNT)))%" +echo "" + +# 生成测试报告 +generate_test_report + +# 清理临时文件 +echo "🧹 清理临时文件..." +rm -f "$LOG_DIR/test_results_$TIMESTAMP.txt" 2>/dev/null + +# 最终结果 +if [ $FAILED_COUNT -eq 0 ]; then + echo "🎉 所有测试通过!系统质量良好。" + exit 0 +else + echo "⚠️ 有 $FAILED_COUNT 个测试模块失败,请检查系统功能。" + echo "详细日志请查看: $LOG_FILE" + echo "测试报告请查看: $REPORT_FILE" + exit 1 +fi \ No newline at end of file diff --git a/src/Client/tts_output/tts_20250713_190441.wav b/src/Client/tts_output/tts_20250713_190441.wav new file mode 100644 index 00000000..ab6a901d Binary files /dev/null and b/src/Client/tts_output/tts_20250713_190441.wav differ diff --git a/src/Client/tts_output/tts_20250713_190711.wav b/src/Client/tts_output/tts_20250713_190711.wav new file mode 100644 index 00000000..ab6a901d Binary files /dev/null and b/src/Client/tts_output/tts_20250713_190711.wav differ diff --git a/src/Client/tts_output/tts_20250713_193754.wav b/src/Client/tts_output/tts_20250713_193754.wav new file mode 100644 index 00000000..1272c273 Binary files /dev/null and b/src/Client/tts_output/tts_20250713_193754.wav differ diff --git a/src/Client/tts_output/tts_20250713_193852.wav b/src/Client/tts_output/tts_20250713_193852.wav new file mode 100644 index 00000000..1272c273 Binary files /dev/null and b/src/Client/tts_output/tts_20250713_193852.wav differ