增加了效能评估模型,修改了设计文档,更新了README

This commit is contained in:
Tian jianyong 2024-11-01 16:27:24 +08:00
parent 1802ffb31a
commit 07df86d407
30 changed files with 902 additions and 154 deletions

View File

@ -4,6 +4,7 @@ using ActiveProtect.Simulation;
using ActiveProtect.Models;
using ActiveProtect.Utility;
using System.Collections.Generic;
using ActiveProtect.Evaluation;
namespace ActiveProtect
{
@ -37,7 +38,7 @@ namespace ActiveProtect
MaxArmor = 100,
InfraredRadiationIntensity = 150,
RadarCrossSection = 10,
RadiationTemperature = 10,
MillimeterWaveRadiationTemperature = 100,
HasLaserWarner = false,
HasLaserJammer = true
}
@ -79,7 +80,6 @@ namespace ActiveProtect
// 激光半主动制导导弹配置
new() {
Id = "LSGM_1",
TargetId = "Tank_1",
InitialPosition = new Vector3D(2000, 100, 100),
InitialOrientation = new Orientation(Math.PI, -0.1, 0),
InitialSpeed = 700,
@ -98,7 +98,6 @@ namespace ActiveProtect
// 激光驾束制导导弹配置
new() {
Id = "LBRM_1",
TargetId = "Tank_1",
InitialPosition = new Vector3D(2000, 10, 100),
InitialOrientation = new Orientation(Math.PI, 0.0, 0.0),
InitialSpeed = 300,
@ -117,7 +116,6 @@ namespace ActiveProtect
// 末敏弹配置
new() {
Id = "TSM_1",
TargetId = "Tank_1",
InitialPosition = new Vector3D(3000, 0, 100), // 发射位置
InitialOrientation = new Orientation(Math.PI, 0, 0), // 使用计算得到的发射角度
InitialSpeed = 800,
@ -136,7 +134,6 @@ namespace ActiveProtect
// 红外指令制导导弹配置
new() {
Id = "ICGM_1",
TargetId = "Tank_1",
InitialPosition = new Vector3D(2000, 10, 100),
InitialOrientation = new Orientation(Math.PI, 0.0, 0),
InitialSpeed = 300,
@ -155,9 +152,8 @@ namespace ActiveProtect
// 红外成像末制导导弹配置
new() {
Id = "ITGM_1",
TargetId = "Tank_1",
InitialPosition = new Vector3D(2000, 100, 100),
InitialOrientation = new Orientation(Math.PI, 0.0, 0),
InitialPosition = new Vector3D(2000, 20, 100),
InitialOrientation = new Orientation(Math.PI, 0.0, 0),
InitialSpeed = 300,
MaxSpeed = 400,
MaxFlightTime = 60,
@ -174,8 +170,7 @@ namespace ActiveProtect
// 毫米波导引头制导导弹配置
new() {
Id = "MMWG_1",
TargetId = "Tank_1",
InitialPosition = new Vector3D(2000, 10, 100),
InitialPosition = new Vector3D(2000, 200, 100),
InitialOrientation = new Orientation(Math.PI, 0.0, 0),
InitialSpeed = 300,
MaxSpeed = 400,
@ -220,6 +215,8 @@ namespace ActiveProtect
}
Console.WriteLine("仿真结束");
EvaluationExample.RunAllExamples();
}
}
}

125
README.md
View File

@ -101,7 +101,7 @@ graph TD
- 可能会抛掉一些辅助推进装置(如有)
3. 巡航阶段
- 导弹保持相对稳定的速度飞向<EFBFBD><EFBFBD>
- 导弹保持相对稳定的速度飞向
- 根据导引系统类型,可能会进行中途修正
4. 终端制导阶段
@ -123,44 +123,28 @@ graph TD
```csharp
ActiveProtect/
├── Docs/ # 文档目录
── Design.md # 设计文档
├── docs/ # 文档目录
── Design.md # 设计文档
│ └── DesignMissile.md # 导弹设计文档
│ └── DesignSeeker.md # 导引头设计文档
│ └── DesignEvaluation.md # 效能评估设计文档
├── Models/ # 仿真模型目录
│ ├── BasicGuidanceSystem.cs # 基础制导系统类
│ ├── Common.cs # 公共类
│ │── InfraredCommandGuidanceSystem.cs # 红外指令制导系统类
│ │── InfraredCommandGuidanceMissile.cs # 红外指令制导导弹类
│ │── InfraredImagingGuidanceSystem.cs # 红外成像制导系统类
│ │── InfraredImagingGuidanceMissile.cs # 红外成像制导导弹类
│ │── ILaserIlluminatable.cs # 可被激光照射的接口定义
│ │── LaserBeamRider.cs # 激光驾束仪类
│ ├── LaserBeamRiderGuidanceSystem.cs # 激光驾束制导系统类
│ ├── LaserBeamRiderMissile.cs # 激光驾束导弹类
│ ├── LaserDesignator.cs # 激光指示器类
│ ├── LaserJammer.cs # 激光干扰器类
│ ├── LaserSemiActiveGuidanceSystem.cs # 激光半主动制导系统类
│ ├── LaserSemiActiveGuidedMissile.cs # 激光半主动制导导弹类
│ ├── LaserWarner.cs # 激光告警器类
│ ├── MillimeterWaveGuidanceSystem.cs # 毫米波制导系统类
│ ├── MillimeterWaveTerminalGuidedMissile.cs # 毫米波末制导导弹类
│ ├── MissileBase.cs # 导弹基类
│ ├── SensorBase.cs # 传感器基类
│ ├── Tank.cs # 坦克模型类
│ ├── TerminalSensitiveBomb.cs # 末敏弹(母弹)类
│ ├── TerminalSensitiveBombBullet.cs # 末敏弹(子弹)类
├── src/ # 源码目录
│ ├── DataProcessing/ # 数据处理目录
│ ├── Evaluation/ # 效能评估模型目录
│ ├── Models/ # 仿真模型目录
│ │ ├── Equipment/ # 设备目录
│ │ ├── Guidance/ # 制导系统目录
│ │ ├── Indicator/ # 指示器目录
│ │ ├── Jammer/ # 干扰器目录
│ │ ├── Missile/ # 导弹目录
│ │ ├── Sensor/ # 传感器目录
│ │ └── Warner/ # 告警器目录
│ ├── Simulation/ # 仿真目录
│ └── Utils/ # 工具类目录
├── SimulationEnvironment/ # 仿真环境目录
│ ├── SimulationConfig.cs # 仿真配置类
│ ├── SimulationElement.cs # 仿真元素基类
│ ├── SimulationEvents.cs # 仿真事件定义类
│ └── SimulationManager.cs # 真管理器类
├── Program.cs # 程序入口点
├── README.md # 项目说明文档
└── Design.md # 设计文档
├── Program.cs # 程序入口点
└── README.md # 项目说明文档
```
## 如何运行
@ -215,3 +199,74 @@ ActiveProtect/
4. **SimulationTimeStep = 0.1**:这是较低的时间步长,仿真精确度很低,用于快速验证。
用户可以根据具体需求选择合适的时间步长,以平衡仿真精度和计算效率。
## 效能评估模型
系统提供了多种评估模型,用于评估防护系统的性能:
### 1. 模糊评价模型
适用于不确定性强的指标评估。通过建立隶属度矩阵,对多个评价指标进行综合评估。
特点:
- 能够处理模糊性和不确定性
- 支持多指标综合评价
- 通过隶属度函数量化定性指标
### 2. AHP层次分析模型
适用于层次分明的指标体系,通过建立判断矩阵进行评估。
特点:
- 层次结构清晰
- 考虑指标间的相对重要性
- 结果具有较好的可解释性
### 3. 灰色关联分析模型
适用于数据不完整的情况,通过计算评估指标与参考序列的关联度进行评估。
特点:
- 适应不完整信息
- 计算简单直观
- 能反映系统发展趋势
### 4. 贝叶斯网络模型
适用于具有不确定性和条件依赖关系的指标评估。
特点:
- 考虑指标间的概率依赖关系
- 支持先验知识的引入
- 可进行概率推理和预测
### 评估指标体系
主要评估维度包括:
1. 时间维度
- 告警响应时间
- 干扰启动时间
- 系统反应延迟
2. 空间维度
- 探测覆盖范围
- 干扰防护范围
- 方位角覆盖
3. 可靠性维度
- 探测可靠性
- 干扰可靠性
- 系统稳定性
### 评估模型选择建议
- 对于不确定性强的指标,优先使用模糊评价或贝叶斯网络
- 对于有大量历史数据的指标,可以使用神经网络模型
- 对于层次分明的指标体系适合使用AHP方法
- 对于数据不完整的情况,可以考虑灰色关联分析
- 在实际应用中,常采用多模型组合评估方法,以获得更可靠的评估结果

75
docs/DesignEvaluation.md Normal file
View File

@ -0,0 +1,75 @@
# 坦克主动干扰系统效能评估指标体系
## 1. 告警效能评估
### 1.1 告警探测能力
### 1.2 告警定位能力
## 2. 干扰效能评估
### 2.1 干扰防护能力
### 2.2 综合评估系统
## 3. 效能评估方法
### 3.1 仿真数据收集
### 3.2 评估指标计算
## 4. 关键评估维度
1. 时间维度
- 告警响应时间
- 干扰启动时间
- 系统反应延迟
2. 空间维度
- 探测覆盖范围
- 干扰防护范围
- 方位角覆盖
3. 可靠性维度
- 探测可靠性
- 干扰可靠性
- 系统稳定性
## 5. 评估流程
1. 数据采集阶段
- 记录每次仿真的原始数据
- 建立数据库存储系统
2. 数据处理阶段
- 数据清洗和预处理
- 计算各项指标值
3. 效能分析阶段
- 单项指标评估
- 综合效能计算
- 对比分析
4. 结果输出阶段
- 生成评估报告
- 可视化展示
- 提供优化建议
## 6. 建议
1. 重点关注告警系统的及时性和准确性
2. 评估干扰系统对不同类型威胁的防护效果
3. 分析系统在不同作战环境下的表现
4. 考虑系统协同工作的效能提升
5. 定期进行效能评估和系统优化
## 评估模型
这些评估模型可以根据具体的评估需求和数据特征进行选择和组合使用。建议:
1. 对于不确定性强的指标,优先使用模糊评价或贝叶斯网络
2. 对于有大量历史数据的指标,可以使用神经网络模型
3. 对于层次分明的指标体系适合使用AHP方法
4. 对于数据不完整的情况,可以考虑灰色关联分析
5. 在实际应用中,常采用多模型组合评估方法,以获得更可靠的评估结果

View File

@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace ActiveProtect.Evaluation
{
/// <summary>
/// 层次分析法评估模型
/// 适用于层次分明的指标体系
/// </summary>
public class AHPEvaluationModel : IEvaluationModel
{
private readonly float[,] judgmentMatrix; // 判断矩阵
private readonly float[] weights; // 计算得到的权重
public string ModelName => "层次分析法模型";
public AHPEvaluationModel(float[,] judgmentMatrix)
{
this.judgmentMatrix = judgmentMatrix;
this.weights = CalculateWeights();
}
public float Evaluate(Dictionary<string, float> evaluationData)
{
float result = 0;
int i = 0;
foreach (var data in evaluationData)
{
result += weights[i] * data.Value;
i++;
}
return result;
}
private float[] CalculateWeights()
{
int n = judgmentMatrix.GetLength(0);
float[] weights = new float[n];
// 计算每行几何平均值
for (int i = 0; i < n; i++)
{
float product = 1.0f;
for (int j = 0; j < n; j++)
{
product *= judgmentMatrix[i, j];
}
weights[i] = (float)Math.Pow(product, 1.0 / n);
}
// 归一化处理
float sum = weights.Sum();
for (int i = 0; i < n; i++)
{
weights[i] /= sum;
}
return weights;
}
}
}

View File

@ -0,0 +1,112 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace ActiveProtect.Evaluation
{
/// <summary>
/// 贝叶斯网络评估模型
/// 适用于具有不确定性和条件依赖关系的指标评估
/// </summary>
public class BayesianNetworkModel : IEvaluationModel
{
// 节点之间的条件概率表
private readonly Dictionary<string, Dictionary<string, float>> conditionalProbabilities;
// 先验概率
private readonly Dictionary<string, float> priorProbabilities;
// 节点之间的依赖关系
private readonly Dictionary<string, List<string>> dependencies;
public string ModelName => "贝叶斯网络模型";
/// <summary>
/// 构造函数
/// </summary>
/// <param name="priorProbabilities">先验概率</param>
/// <param name="conditionalProbabilities">条件概率表</param>
/// <param name="dependencies">节点依赖关系</param>
public BayesianNetworkModel(
Dictionary<string, float> priorProbabilities,
Dictionary<string, Dictionary<string, float>> conditionalProbabilities,
Dictionary<string, List<string>> dependencies)
{
this.priorProbabilities = priorProbabilities;
this.conditionalProbabilities = conditionalProbabilities;
this.dependencies = dependencies;
}
public float Evaluate(Dictionary<string, float> evaluationData)
{
float result = 0;
// 对每个评估指标进行概率计算
foreach (var node in evaluationData.Keys)
{
float nodeProb = CalculateNodeProbability(node, evaluationData);
result += nodeProb * evaluationData[node];
}
// 归一化处理
return result / evaluationData.Count;
}
/// <summary>
/// 计算节点的后验概率
/// </summary>
private float CalculateNodeProbability(string node, Dictionary<string, float> evidence)
{
// 如果是根节点,直接返回先验概率
if (!dependencies.ContainsKey(node) || dependencies[node].Count == 0)
{
return priorProbabilities.ContainsKey(node) ? priorProbabilities[node] : 1.0f;
}
float probability = 1.0f;
// 获取父节点
var parents = dependencies[node];
// 计算条件概率
foreach (var parent in parents)
{
if (evidence.ContainsKey(parent) && conditionalProbabilities.ContainsKey(node))
{
var condProb = conditionalProbabilities[node];
if (condProb.ContainsKey(parent))
{
probability *= condProb[parent] * evidence[parent];
}
}
}
return probability;
}
/// <summary>
/// 更新条件概率表
/// </summary>
public void UpdateConditionalProbability(string node, string parent, float probability)
{
if (!conditionalProbabilities.ContainsKey(node))
{
conditionalProbabilities[node] = new Dictionary<string, float>();
}
conditionalProbabilities[node][parent] = probability;
}
/// <summary>
/// 添加新的依赖关系
/// </summary>
public void AddDependency(string node, string parent)
{
if (!dependencies.ContainsKey(node))
{
dependencies[node] = new List<string>();
}
if (!dependencies[node].Contains(parent))
{
dependencies[node].Add(parent);
}
}
}
}

View File

@ -0,0 +1,130 @@
using System;
using System.Collections.Generic;
namespace ActiveProtect.Evaluation
{
/// <summary>
/// 评估模型示例类
/// </summary>
public class EvaluationExample
{
/// <summary>
/// 运行所有评估模型示例
/// </summary>
public static void RunAllExamples()
{
// 准备评估数据
Dictionary<string, float> evaluationData = new Dictionary<string, float>
{
{ "告警响应时间", 0.85f },
{ "探测覆盖范围", 0.92f },
{ "系统稳定性", 0.78f }
};
// 1. 模糊评价模型示例
DemoFuzzyEvaluation(evaluationData);
// 2. AHP层次分析模型示例
DemoAHPEvaluation(evaluationData);
// 3. 灰色关联分析模型示例
DemoGreyRelationEvaluation(evaluationData);
// 4. 贝叶斯网络模型示例
DemoBayesianEvaluation(evaluationData);
}
/// <summary>
/// 模糊评价模型示例
/// </summary>
private static void DemoFuzzyEvaluation(Dictionary<string, float> evaluationData)
{
Console.WriteLine("\n=== 模糊评价模型示例 ===");
float[,] membershipMatrix = new float[3,3] {
{0.5f, 0.3f, 0.2f}, // 告警响应时间的隶属度分布
{0.4f, 0.4f, 0.2f}, // 探测覆盖范围的隶属度分布
{0.3f, 0.4f, 0.3f} // 系统稳定性的隶属度分布
};
float[] weights = new float[] { 0.4f, 0.3f, 0.3f };
var fuzzyModel = EvaluationModelFactory.CreateModel("fuzzy",
new object[] { membershipMatrix, weights });
float result = fuzzyModel.Evaluate(evaluationData);
Console.WriteLine($"模糊评价结果: {result:F4}");
}
/// <summary>
/// AHP层次分析模型示例
/// </summary>
private static void DemoAHPEvaluation(Dictionary<string, float> evaluationData)
{
Console.WriteLine("\n=== AHP层次分析模型示例 ===");
float[,] judgmentMatrix = new float[3,3] {
{1.0f, 2.0f, 3.0f},
{0.5f, 1.0f, 2.0f},
{0.33f, 0.5f, 1.0f}
};
var ahpModel = EvaluationModelFactory.CreateModel("ahp",
new object[] { judgmentMatrix });
float result = ahpModel.Evaluate(evaluationData);
Console.WriteLine($"AHP评价结果: {result:F4}");
}
/// <summary>
/// 灰色关联分析模型示例
/// </summary>
private static void DemoGreyRelationEvaluation(Dictionary<string, float> evaluationData)
{
Console.WriteLine("\n=== 灰色关联分析模型示例 ===");
float[] referenceSequence = new float[] { 0.9f, 0.95f, 0.85f };
var greyModel = EvaluationModelFactory.CreateModel("grey",
new object[] { referenceSequence });
float result = greyModel.Evaluate(evaluationData);
Console.WriteLine($"灰色关联评价结果: {result:F4}");
}
/// <summary>
/// 贝叶斯网络模型示例
/// </summary>
private static void DemoBayesianEvaluation(Dictionary<string, float> evaluationData)
{
Console.WriteLine("\n=== 贝叶斯网络模型示例 ===");
var priorProbabilities = new Dictionary<string, float>
{
{ "告警响应时间", 0.8f },
{ "探测覆盖范围", 0.7f },
{ "系统稳定性", 0.9f }
};
var conditionalProbabilities = new Dictionary<string, Dictionary<string, float>>
{
{ "系统稳定性", new Dictionary<string, float>
{
{ "告警响应时间", 0.85f },
{ "探测覆盖范围", 0.75f }
}
}
};
var dependencies = new Dictionary<string, List<string>>
{
{ "系统稳定性", new List<string> { "告警响应时间", "探测覆盖范围" } }
};
var bayesianModel = EvaluationModelFactory.CreateModel("bayesian",
new object[] { priorProbabilities, conditionalProbabilities, dependencies });
float result = bayesianModel.Evaluate(evaluationData);
Console.WriteLine($"贝叶斯网络评价结果: {result:F4}");
}
}
}

View File

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
namespace ActiveProtect.Evaluation
{
/// <summary>
/// 评估模型工厂类
/// 用于创建和管理不同的评估模型
/// </summary>
public class EvaluationModelFactory
{
public static IEvaluationModel CreateModel(string modelType, object[] parameters)
{
switch (modelType.ToLower())
{
case "fuzzy":
return new FuzzyEvaluationModel(
(float[,])parameters[0],
(float[])parameters[1]
);
case "ahp":
return new AHPEvaluationModel(
(float[,])parameters[0]
);
case "grey":
return new GreyRelationModel(
(float[])parameters[0]
);
case "bayesian":
return new BayesianNetworkModel(
(Dictionary<string, float>)parameters[0],
(Dictionary<string, Dictionary<string, float>>)parameters[1],
(Dictionary<string, List<string>>)parameters[2]
);
default:
throw new ArgumentException($"不支持的评估模型类型: {modelType}");
}
}
}
}

View File

@ -0,0 +1,108 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace ActiveProtect.Evaluation
{
/// <summary>
/// 模糊评价模型
/// 适用于不确定性强的指标评估
/// </summary>
public class FuzzyEvaluationModel : IEvaluationModel
{
private readonly float[,] membershipMatrix; // 隶属度矩阵,每一行表示一个指标对不同评价等级的隶属度分布
private readonly float[] weights; // 权重向量,表示各个指标的权重
public string ModelName => "模糊评价模型";
public FuzzyEvaluationModel(float[,] membershipMatrix, float[] weights)
{
this.membershipMatrix = membershipMatrix;
this.weights = weights;
if (!ValidateMembershipMatrix())
{
throw new ArgumentException("隶属度矩阵无效");
}
}
public float Evaluate(Dictionary<string, float> evaluationData)
{
int factorCount = evaluationData.Count; // 评价因素个数
int gradeCount = membershipMatrix.GetLength(1); // 评价等级个数
// 计算模糊关系矩阵 R
float[,] fuzzyMatrix = new float[factorCount, gradeCount];
int i = 0;
foreach (var data in evaluationData)
{
for (int j = 0; j < gradeCount; j++)
{
fuzzyMatrix[i, j] = membershipMatrix[i, j] * data.Value;
}
i++;
}
// 计算加权模糊综合评价结果
float[] result = new float[gradeCount];
for (int j = 0; j < gradeCount; j++)
{
float sum = 0;
for (i = 0; i < factorCount; i++)
{
sum += weights[i] * fuzzyMatrix[i, j];
}
result[j] = sum;
}
// 计算最终评价值(加权平均)
float finalResult = 0;
float gradeStep = 1.0f / (gradeCount - 1); // 评价等级的步长
for (i = 0; i < gradeCount; i++)
{
finalResult += result[i] * (i * gradeStep);
}
// 归一化处理
return finalResult / result.Sum();
}
/// <summary>
/// 验证隶属度矩阵的有效性
/// </summary>
private bool ValidateMembershipMatrix()
{
int rows = membershipMatrix.GetLength(0);
int cols = membershipMatrix.GetLength(1);
// 检查矩阵元素是否都在[0,1]区间内
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (membershipMatrix[i, j] < 0 || membershipMatrix[i, j] > 1)
{
return false;
}
}
}
// 检查每行的隶属度之和是否接近1
const float tolerance = 0.0001f;
for (int i = 0; i < rows; i++)
{
float sum = 0;
for (int j = 0; j < cols; j++)
{
sum += membershipMatrix[i, j];
}
if (Math.Abs(sum - 1) > tolerance)
{
return false;
}
}
return true;
}
}
}

View File

@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace ActiveProtect.Evaluation
{
/// <summary>
/// 灰色关联分析模型
/// 适用于数据不完整的情况
/// </summary>
public class GreyRelationModel : IEvaluationModel
{
private readonly float[] referenceSequence; // 参考数列
private readonly float resolution = 0.5f; // 分辨系数
public string ModelName => "灰色关联分析模型";
public GreyRelationModel(float[] referenceSequence)
{
this.referenceSequence = referenceSequence;
}
public float Evaluate(Dictionary<string, float> evaluationData)
{
float[] compareSequence = evaluationData.Values.ToArray();
// 计算关联系数
float[] correlationCoefficients = new float[compareSequence.Length];
for (int i = 0; i < compareSequence.Length; i++)
{
correlationCoefficients[i] = CalculateCorrelationCoefficient(
referenceSequence[i],
compareSequence[i]
);
}
// 计算关联度
return correlationCoefficients.Average();
}
private float CalculateCorrelationCoefficient(float refValue, float compValue)
{
float delta = Math.Abs(refValue - compValue);
float minDelta = 0.0f;
float maxDelta = 1.0f;
return (minDelta + resolution * maxDelta) / (delta + resolution * maxDelta);
}
}
}

View File

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
namespace ActiveProtect.Evaluation
{
/// <summary>
/// 评估模型接口
/// </summary>
public interface IEvaluationModel
{
/// <summary>
/// 执行评估
/// </summary>
/// <param name="evaluationData">评估数据</param>
/// <returns>评估结果</returns>
float Evaluate(Dictionary<string, float> evaluationData);
/// <summary>
/// 获取评估模型名称
/// </summary>
string ModelName { get; }
}
}

View File

@ -41,9 +41,27 @@ namespace ActiveProtect.Models
{
if (!IsActive) return;
// 辐射事件发布
PublishRadiationEvent();
UpdatePosition(deltaTime);
}
/// <summary>
/// 辐射事件发布
/// </summary>
private void PublishRadiationEvent()
{
SimulationManager.PublishEvent(new TankRadiationEvent
{
LaserReflectionIntensity = 100,
MillimeterWaveReflectionIntensity = 100,
MillimeterWaveRadiationTemperature = TankProperties.MillimeterWaveRadiationTemperature,
InfraredRadiationIntensity = TankProperties.InfraredRadiationIntensity,
SenderId = Id
});
}
/// <summary>
/// 更新坦克位置
/// </summary>

View File

@ -48,9 +48,9 @@ namespace ActiveProtect.Models
public double RadarCrossSection { get; set; }
/// <summary>
/// 辐射温度(K),默认为 0 K
/// 毫米波辐射温度(K),默认为 0 K
/// </summary>
public double RadiationTemperature { get; set; }
public double MillimeterWaveRadiationTemperature { get; set; }
/// <summary>
/// 是否装备激光告警器
@ -95,7 +95,7 @@ namespace ActiveProtect.Models
HasLaserJammer = false;
HasMillimeterWaveJammer = false;
InfraredRadiationIntensity = 0;
RadiationTemperature = 0;
MillimeterWaveRadiationTemperature = 0;
}
// 验证方法

View File

@ -71,6 +71,7 @@ namespace ActiveProtect.Models
if (distance <= MAX_DETECTION_RANGE)
{
double angle = Math.Acos(Vector3D.DotProduct(toTarget.Normalize(), missileVelocity.Normalize()));
//Console.WriteLine($"Angle: {angle} / Field of View: {FIELD_OF_VIEW}");
if (angle <= FIELD_OF_VIEW / 2)
{
double snr = CalculateSNR(tank, distance);

View File

@ -94,12 +94,11 @@ namespace ActiveProtect.Models
if (distance <= MAX_DETECTION_RANGE)
{
double angle = Math.Acos(Vector3D.DotProduct(toTarget.Normalize(), missileVelocity.Normalize()));
//Console.WriteLine($"Angle: {angle} / Field of View: {FIELD_OF_VIEW}");
if (angle <= FIELD_OF_VIEW / 2)
{
// 模拟毫米波探测
double snr = CalculateSNR(distance, tank.TankProperties.RadarCrossSection);
Console.WriteLine($" 80信噪比 {snr}");
if(snr > RECOGNITION_SNR_THRESHOLD && random.NextDouble() < TARGET_RECOGNITION_PROBABILITY)
{

View File

@ -108,10 +108,6 @@ namespace ActiveProtect.Models
HasGuidance = true;
guidanceSystem.Update(deltaTime, Position, Velocity);
GuidanceAcceleration = guidanceSystem.GetGuidanceAcceleration();
if (DistanceToTarget <= MissileProperties.ExplosionRadius)
{
currentStage = ICGM_Stage.Explode;
}
if(ShouldSelfDestruct())
{
currentStage = ICGM_Stage.SelfDestruct;

View File

@ -73,8 +73,7 @@ namespace ActiveProtect.Models
/// </summary>
private void UpdateLaunchStage(double deltaTime)
{
// 实现发射阶段逻辑
if (FlightTime > 0.1) // 假设发射阶段持续0.1秒
if (FlightTime > 1) // 假设发射阶段持续1秒
{
currentStage = IRTG_Stage.Cruise;
}
@ -85,8 +84,7 @@ namespace ActiveProtect.Models
/// </summary>
private void UpdateCruiseStage(double deltaTime)
{
// 实现巡航阶段逻辑
if (DistanceToTarget <= TERMINAL_GUIDANCE_DISTANCE)
if (FlightTime > 4) // 假设巡航阶段持续3秒
{
currentStage = IRTG_Stage.TerminalGuidance;
}
@ -100,11 +98,6 @@ namespace ActiveProtect.Models
HasGuidance = true;
guidanceSystem.Update(deltaTime, Position, Velocity);
GuidanceAcceleration = guidanceSystem.GetGuidanceAcceleration();
if (DistanceToTarget <= MissileProperties.ExplosionRadius)
{
currentStage = IRTG_Stage.Explode;
}
}
/// <summary>

View File

@ -122,10 +122,6 @@ namespace ActiveProtect.Models
HasGuidance = true;
LaserBeamRiderGuidanceSystem.Update(deltaTime, Position, Velocity);
GuidanceAcceleration = LaserBeamRiderGuidanceSystem.GetGuidanceAcceleration();
if (DistanceToTarget <= MissileProperties.ExplosionRadius)
{
currentStage = LBRM_Stage.Explode;
}
if(ShouldSelfDestruct())
{
currentStage = LBRM_Stage.SelfDestruct;

View File

@ -142,10 +142,6 @@ namespace ActiveProtect.Models
HasGuidance = true;
LaserGuidanceSystem.Update(deltaTime, Position, Velocity);
GuidanceAcceleration = LaserGuidanceSystem.GetGuidanceAcceleration();
if (DistanceToTarget <= MissileProperties.ExplosionRadius)
{
currentStage = LSAGM_Stage.Explode;
}
if(ShouldSelfDestruct())
{
currentStage = LSAGM_Stage.SelfDestruct;

View File

@ -72,8 +72,7 @@ namespace ActiveProtect.Models
/// </summary>
private void UpdateLaunchStage(double deltaTime)
{
// 实现发射阶段逻辑
if (FlightTime > 3) // 假设发射阶段持续3秒
if (FlightTime > 0.1) // 假设发射阶段持续1秒
{
currentStage = MWTG_Stage.Cruise;
Console.WriteLine($"导弹 {Id} 进入巡航阶段");
@ -85,8 +84,7 @@ namespace ActiveProtect.Models
/// </summary>
private void UpdateCruiseStage(double deltaTime)
{
// 实现巡航阶段逻辑
if (DistanceToTarget <= TERMINAL_GUIDANCE_DISTANCE)
if (FlightTime > 3) // 假设巡航阶段持续3秒
{
currentStage = MWTG_Stage.TerminalGuidance;
Console.WriteLine($"导弹 {Id} 进入末制导阶段");
@ -101,12 +99,6 @@ namespace ActiveProtect.Models
HasGuidance = true;
guidanceSystem.Update(deltaTime, Position, Velocity);
GuidanceAcceleration = guidanceSystem.GetGuidanceAcceleration();
if (DistanceToTarget <= MissileProperties.ExplosionRadius)
{
currentStage = MWTG_Stage.Explode;
Console.WriteLine($"导弹 {Id} 进入爆炸阶段");
}
}
/// <summary>

View File

@ -20,12 +20,7 @@ namespace ActiveProtect.Models
/// 当前飞行距离(米)
/// </summary>
public double FlightDistance { get; protected set; }
/// <summary>
/// 与目标的距离(米)
/// </summary>
public double DistanceToTarget { get; protected set; }
/// <summary>
/// 当前发动机燃烧时间(秒)
/// </summary>
@ -77,7 +72,6 @@ namespace ActiveProtect.Models
EngineBurnTime = 0;
GuidanceAcceleration = Vector3D.Zero;
ThrustAcceleration = Vector3D.Zero;
DistanceToTarget = Vector3D.Distance(Position, SimulationManager.GetEntityById(properties.TargetId).Position);
}
/// <summary>
@ -127,7 +121,7 @@ namespace ActiveProtect.Models
FlightTime += deltaTime;
FlightDistance += Speed * deltaTime;
DistanceToTarget = Vector3D.Distance(Position, SimulationManager.GetEntityById(MissileProperties.TargetId).Position);
//DistanceToTarget = Vector3D.Distance(Position, SimulationManager.GetEntityById(MissileProperties.TargetId).Position);
}
/// <summary>
@ -201,7 +195,29 @@ namespace ActiveProtect.Models
protected virtual void Explode()
{
Deactivate();
SimulationManager.HandleTargetHit(MissileProperties.TargetId, Id);
}
public override void Activate()
{
base.Activate();
SimulationManager.SubscribeToEvent<TargetHitEvent>(OnTargetHitEvent);
}
public override void Deactivate()
{
base.Deactivate();
SimulationManager.UnsubscribeFromEvent<TargetHitEvent>(OnTargetHitEvent);
}
/// <summary>
/// 处理目标被击中事件
/// </summary>
private void OnTargetHitEvent(TargetHitEvent eventData)
{
if (eventData.MissileId == Id)
{
Explode();
}
}
/// <summary>
@ -234,7 +250,6 @@ namespace ActiveProtect.Models
$" 朝向: {missileRunningState.Orientation}\n" +
$" 飞行时间: {missileRunningState.FlightTime:F2}/{MissileProperties.MaxFlightTime:F2}\n" +
$" 飞行距离: {missileRunningState.FlightDistance:F2}/{MissileProperties.MaxFlightDistance:F2}\n" +
$" 距离目标: {missileRunningState.DistanceToTarget:F2}\n" +
$" 发动机工作时间: {missileRunningState.EngineBurnTime:F2}/{MissileProperties.MaxEngineBurnTime:F2}\n" +
$" 有引导: {(missileRunningState.HasGuidance ? "" : "")}\n" +
$" 失去引导时间: {missileRunningState.LostGuidanceTime:F2}\n";
@ -260,7 +275,6 @@ namespace ActiveProtect.Models
Speed = Speed,
FlightTime = FlightTime,
FlightDistance = FlightDistance,
DistanceToTarget = DistanceToTarget,
HasGuidance = HasGuidance,
LostGuidanceTime = LostGuidanceTime,
EngineBurnTime = EngineBurnTime,
@ -314,11 +328,6 @@ namespace ActiveProtect.Models
/// </summary>
public double FlightDistance { get; set; }
/// <summary>
/// 与目标的距离(米)
/// </summary>
public double DistanceToTarget { get; set; }
/// <summary>
/// 是否有制导
/// </summary>

View File

@ -27,11 +27,6 @@ namespace ActiveProtect.Models
/// </summary>
public string Id { get; set; }
/// <summary>
/// 目标ID
/// </summary>
public string TargetId { get; set; }
/// <summary>
/// 初始位置
/// </summary>
@ -110,7 +105,6 @@ namespace ActiveProtect.Models
SetDefaultValues();
Id = "";
TargetId = "";
InitialPosition = new Vector3D(0, 0, 0);
InitialOrientation = new Orientation(0, 0, 0);
Type = MissileType.LaserSemiActiveGuidance;
@ -123,7 +117,6 @@ namespace ActiveProtect.Models
SetDefaultValues();
Id = $"Missile_{mIniInfo.nMisID}";
TargetId = "";
InitialPosition = new Vector3D(mIniInfo.xm, mIniInfo.ym, mIniInfo.zm);
InitialOrientation = new Orientation(mIniInfo.psi_m, mIniInfo.theta_m, 0);
InitialSpeed = mIniInfo.vm;

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Runtime;
using ActiveProtect.Simulation;
using ActiveProtect.Utility;
@ -20,15 +21,15 @@ namespace ActiveProtect.Models
// 分离点位置
private readonly Vector3D separationPoint;
public TerminalSensitiveMissile(MissileProperties properties, ISimulationManager manager)
private readonly string TargetId;
public TerminalSensitiveMissile(string targetId, MissileProperties properties, ISimulationManager manager)
: base(properties, manager)
{
TargetId = targetId;
submunitions = new TerminalSensitiveSubmunition[SubmunitionCount];
//计算分离点坐标高度为SeparationHeight距离目标的距离为SeparationDistance
separationPoint = Vector3D.PointOnLine(base.SimulationManager.GetEntityById(properties.TargetId).Position, base.Position, SeparationDistance) + new Vector3D(0, SeparationHeight, 0);
Console.WriteLine($"Position: {Position}, 分离点: {separationPoint}, speed: {Speed}, Speed: {properties.InitialSpeed}");
separationPoint = Vector3D.PointOnLine(base.SimulationManager.GetEntityById(TargetId).Position, base.Position, SeparationDistance) + new Vector3D(0, SeparationHeight, 0);
//计算导弹发射角度
(Orientation? launchOrientation, Vector3D? launchVelocity) = MotionAlgorithm.CalculateBestLaunchOrientation(Position, separationPoint, Speed);
if (!launchOrientation.HasValue || launchVelocity is null)
@ -40,7 +41,6 @@ namespace ActiveProtect.Models
{
Orientation = launchOrientation.Value;
Velocity = launchVelocity;
Console.WriteLine($"发射方向: {launchOrientation}");
}
GuidanceAcceleration = new Vector3D(0, -9.81, 0);
@ -71,7 +71,7 @@ namespace ActiveProtect.Models
private void PerformSeparation()
{
// 获取目标位置
Vector3D targetPosition = SimulationManager.GetEntityById(MissileProperties.TargetId).Position;
Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
// 计算子弹朝向目标的方向
Vector3D directionToTarget = (targetPosition - this.Position).Normalize();
Orientation orientationToTarget = Orientation.FromVector(directionToTarget);
@ -80,10 +80,10 @@ namespace ActiveProtect.Models
for (int i = 0; i < SubmunitionCount; i++)
{
submunitions[i] = new TerminalSensitiveSubmunition(
TargetId,
new MissileProperties
{
Id = $"{Id}_Sub_{i}",
TargetId = MissileProperties.TargetId,
InitialPosition = Position,
InitialOrientation = orientationToTarget,
InitialSpeed = 200, // 子弹初始速度

View File

@ -64,14 +64,18 @@ namespace ActiveProtect.Models
private readonly MillimeterWaveAltimeter altimeter;
private readonly LaserRangefinder rangefinder;
private readonly string TargetId;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="properites">导弹配置</param>
/// <param name="manager">模拟管理器</param>
public TerminalSensitiveSubmunition(MissileProperties properties, ISimulationManager manager)
public TerminalSensitiveSubmunition(string targetId, MissileProperties properties, ISimulationManager manager)
: base(properties, manager)
{
TargetId = targetId;
currentStage = SubmunitionStage.Separation;
spiralAngle = 0;
scanDirection = new Vector3D(0, 0, 0);
@ -245,7 +249,7 @@ namespace ActiveProtect.Models
{
Console.WriteLine("攻击阶段");
// 攻击逻辑
Vector3D targetPosition = SimulationManager.GetEntityById(MissileProperties.TargetId).Position;
Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
Vector3D direction = (targetPosition - Position).Normalize();
Velocity = direction * AttackSpeed;
if ((targetPosition - Position).Magnitude() <= MissileProperties.ExplosionRadius)
@ -277,13 +281,22 @@ namespace ActiveProtect.Models
/// <returns>在扫描方向上是否检测到目标</returns>
public bool DetectTarget(double fieldOfView)
{
Vector3D targetPosition = SimulationManager.GetEntityById(MissileProperties.TargetId).Position;
Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
Vector3D toTarget = (targetPosition - Position).Normalize();
// 检查目标是否在扫描视场内
return Vector3D.DotProduct(scanDirection, toTarget) > Math.Cos(fieldOfView * Math.PI / 180);
}
/// <summary>
/// 激活子弹
/// </summary>
public override void Activate()
{
base.Activate();
SimulationManager.SubscribeToEvent<TankRadiationEvent>(OnTankRadiationEvent);
}
/// <summary>
/// 销毁子弹
/// </summary>
@ -296,6 +309,18 @@ namespace ActiveProtect.Models
rangefinder.Deactivate();
}
/// <summary>
/// 处理坦克辐射事件
/// </summary>
/// <param name="evt">坦克辐射事件</param>
private void OnTankRadiationEvent(TankRadiationEvent evt)
{
if (evt.SenderId == TargetId)
{
Console.WriteLine("检测到目标辐射");
}
}
/// <summary>
/// 获取子弹状态
/// </summary>

View File

@ -222,4 +222,47 @@ namespace ActiveProtect.Simulation
/// </summary>
public double JammingPower { get; set; }
}
/// <summary>
/// 坦克辐射事件
/// </summary>
public class TankRadiationEvent : SimulationEvent
{
/// <summary>
/// 激光漫反射强度
/// </summary>
public double LaserReflectionIntensity { get; set; }
/// <summary>
/// 毫米波反射强度
/// </summary>
public double MillimeterWaveReflectionIntensity { get; set; }
/// <summary>
/// 毫米波辐射温度
/// </summary>
public double MillimeterWaveRadiationTemperature { get; set; }
/// <summary>
/// 红外辐射强度
/// </summary>
public double InfraredRadiationIntensity { get; set; }
}
/// <summary>
/// 目标被击中事件
/// </summary>
public class TargetHitEvent : SimulationEvent
{
/// <summary>
/// 目标ID
/// </summary>
public string? TargetId { get; set; }
/// <summary>
/// 导弹ID
/// </summary>
public string? MissileId { get; set; }
}
}

View File

@ -34,7 +34,7 @@ namespace ActiveProtect.Simulation
/// <summary>
/// 处理目标被击中事件
/// </summary>
void HandleTargetHit(string targetId, string missileId);
void HandleTargetHit();
/// <summary>
/// 发布仿真事件
@ -163,7 +163,7 @@ namespace ActiveProtect.Simulation
missile = new LaserBeamRiderMissile(missileProperties, this);
break;
case MissileType.TerminalSensitiveMissile:
missile = new TerminalSensitiveMissile(missileProperties, this);
missile = new TerminalSensitiveMissile("Tank_1", missileProperties, this);
break;
case MissileType.InfraredCommandGuidance:
missile = new InfraredCommandGuidedMissile(missileProperties, this);
@ -221,10 +221,10 @@ namespace ActiveProtect.Simulation
Elements.Add(infraredTracker);
// 激活所有元素
ActivateAllElements();
//ActivateAllElements();
// 激活部分元素
//ActivateSomeElements();
ActivateSomeElements();
}
//激活所有元素
@ -239,7 +239,7 @@ namespace ActiveProtect.Simulation
private void ActivateSomeElements()
{
// 激活坦克
Elements.FindAll(e => e.Id == "Tank_1").ForEach(e => e.Activate());
//Elements.FindAll(e => e.Id == "Tank_1").ForEach(e => e.Activate());
// 激活激光告警器
//Elements.FindAll(e => e.Id == "LW_1").ForEach(e => e.Activate());
@ -269,7 +269,7 @@ namespace ActiveProtect.Simulation
//Elements.FindAll(e => e.Id == "MMWG_1").ForEach(e => e.Activate());
// 激活末敏弹
Elements.FindAll(e => e.Id == "TSM_1").ForEach(e => e.Activate());
//Elements.FindAll(e => e.Id == "TSM_1").ForEach(e => e.Activate());
// 激活毫米波干扰器
//Elements.FindAll(e => e.Id == "MMWJ_1").ForEach(e => e.Activate());
@ -281,11 +281,20 @@ namespace ActiveProtect.Simulation
public void PublishEvent(SimulationEvent evt)
{
var eventType = evt.GetType();
if (eventHandlers.TryGetValue(eventType, out var handlers))
if (eventHandlers.TryGetValue(eventType, out var handlers))
{
foreach (var handler in handlers)
// 创建handlers的副本进行遍历
var handlersCopy = handlers.ToList();
foreach (var handler in handlersCopy)
{
handler.DynamicInvoke(evt);
try
{
handler.DynamicInvoke(evt);
}
catch (Exception ex)
{
Console.WriteLine($"事件处理异常: {ex.Message}");
}
}
}
else
@ -380,6 +389,9 @@ namespace ActiveProtect.Simulation
}
}
// 处理目标被导弹击中的情况
HandleTargetHit();
// 移除不活跃的元素
Elements.RemoveAll(e => !e.IsActive);
@ -390,6 +402,52 @@ namespace ActiveProtect.Simulation
}
}
/// <summary>
/// 处理目标被导弹击中的情况
/// </summary>
public void HandleTargetHit()
{
try
{
// 创建活跃导弹和坦克的快照
var activeMissiles = Elements.Where(e => e is MissileBase && e.IsActive).ToList();
var activeTanks = Elements.Where(e => e is Tank && e.IsActive).ToList();
var hitEvents = new List<(Tank tank, MissileBase missile, double damage)>();
// 首先收集所有的命中信息
foreach (var missile in activeMissiles)
{
if (missile is MissileBase actualMissile)
{
foreach (var tank in activeTanks)
{
if (tank is Tank actualTank)
{
double distance = Vector3D.Distance(missile.Position, tank.Position);
if (distance <= actualMissile.MissileProperties.ExplosionRadius)
{
double damage = CalculateMissileDamage(actualMissile);
hitEvents.Add((actualTank, actualMissile, damage));
}
}
}
}
}
// 然后处理所有命中事件
foreach (var (tank, missile, damage) in hitEvents)
{
PublishEvent(new TargetHitEvent { TargetId = tank.Id, MissileId = missile.Id });
tank.TakeDamage(damage, true);
LogHitEvent(tank.Id, missile.Id, damage);
}
}
catch (Exception ex)
{
Console.WriteLine($"处理命中事件时发生错误: {ex.Message}");
}
}
/// <summary>
/// 打印仿真状态
/// </summary>
@ -422,33 +480,6 @@ namespace ActiveProtect.Simulation
return Elements.FirstOrDefault(e => e.Id == id) ?? throw new InvalidOperationException($"Entity with id {id} not found");
}
/// <summary>
/// 处理目标被击中事件
/// </summary>
public void HandleTargetHit(string targetId, string missileId)
{
if (GetEntityById(targetId) is Tank tank && GetEntityById(missileId) is MissileBase missile)
{
// 生成随机数决定是否命中
Random random = new();
//bool isHit = random.NextDouble() <= missile.MissileProperties.HitProbability;
bool isHit = true;
if (!isHit)
{
Console.WriteLine($"导弹 {missileId} 未命中目标 {targetId}");
return;
}
// 计算导弹造成的伤害
double damage = CalculateMissileDamage(missile);
// 对坦克造成伤害
tank.TakeDamage(damage, true);
// 记录击中事件
LogHitEvent(targetId, missileId, damage);
}
}
/// <summary>
/// 计算导弹造成的伤害
/// </summary>

View File

@ -56,9 +56,7 @@ namespace ActiveProtect.Utility
double v0_4 = v0_2 * v0_2;
double discriminant = v0_4 - g * (g * x * x + 2 * y * v0_2);
Console.WriteLine($"判别式: {discriminant}");
if (discriminant < 0)
{
Console.WriteLine("无实数解 - 目标不可达");