增加了导弹的红外和紫外辐射强度属性

This commit is contained in:
Tian jianyong 2025-05-19 16:35:37 +08:00
parent b37c5ddec2
commit 17eb9826b5
15 changed files with 484 additions and 38 deletions

View File

@ -19,6 +19,7 @@
- 增加了SwerlingRCS回波模型
- 在毫米波制导中使用SwerlingRCS回波模型获取目标RCS
- 增加了扫描周期计时器用于控制RCS的更新
- 增加了导弹的红外和紫外辐射强度属性
## [1.1.19] - 2025-05-18
- 增加了装备的RCS特征矩阵

View File

@ -0,0 +1,388 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ThreatSource.Utils;
using ThreatSource.Equipment;
namespace ThreatSource.Tests
{
[TestClass]
public class SwerlingRcsModelTests
{
private const double DefaultAverageRcs = 10.0; // 默认平均RCS值单位平方米
private const string TargetId1 = "target_tank_001"; // 测试用目标ID 1
private const string TargetId2 = "target_heli_002"; // 测试用目标ID 2
private const int TestSeed = 12345; // 测试用随机数种子
/// <summary>
/// 测试:默认构造函数应成功初始化。
/// </summary>
[TestMethod]
public void Constructor_DefaultSeed_InitializesSuccessfully()
{
// 准备 (Arrange)
SwerlingRcsModel model;
// 操作 (Act)
model = new SwerlingRcsModel();
// 断言 (Assert)
Assert.IsNotNull(model, "使用默认种子构造模型实例不应为null。");
}
/// <summary>
/// 测试:带特定种子的构造函数应成功初始化。
/// </summary>
[TestMethod]
public void Constructor_WithSpecificSeed_InitializesSuccessfully()
{
// 准备 (Arrange)
SwerlingRcsModel model;
// 操作 (Act)
model = new SwerlingRcsModel(TestSeed);
// 断言 (Assert)
Assert.IsNotNull(model, "使用特定种子构造模型实例不应为null。");
}
/// <summary>
/// 测试当目标是坦克且静止时其RCS行为应类似Swerling I (慢起伏,使用缓存)。
/// </summary>
[TestMethod]
public void GetRealtimeRcs_Tank_Static_BehavesAsSwerlingI()
{
// 准备 (Arrange)
var model = new SwerlingRcsModel(TestSeed);
// 操作 (Act)
// 第一次调用isNewScanPeriod为false但由于是首次应采样并缓存
double rcs1 = model.GetRealtimeRcs(TargetId1, EquipmentType.Tank, MotionStateType.Static, DefaultAverageRcs, false);
// 第二次调用isNewScanPeriod为false应从缓存获取
double rcs2 = model.GetRealtimeRcs(TargetId1, EquipmentType.Tank, MotionStateType.Static, DefaultAverageRcs, false);
// 断言 (Assert)
Assert.AreEqual(rcs1, rcs2, "对于Swerling I模型 (Tank, Static)在同一扫描周期内isNewScanPeriod=falseRCS值应从缓存读取且保持不变。");
Assert.IsTrue(rcs1 > 0, "RCS值应大于0。");
}
/// <summary>
/// 测试当目标是直升机且静止时其RCS行为应类似Swerling II (快起伏,不使用缓存)。
/// </summary>
[TestMethod]
public void GetRealtimeRcs_Helicopter_Static_BehavesAsSwerlingII()
{
// 准备 (Arrange)
var model = new SwerlingRcsModel(TestSeed);
// 操作 (Act)
double rcs1 = model.GetRealtimeRcs(TargetId1, EquipmentType.Helicopter, MotionStateType.Static, DefaultAverageRcs, false);
double rcs2 = model.GetRealtimeRcs(TargetId1, EquipmentType.Helicopter, MotionStateType.Static, DefaultAverageRcs, false);
// 断言 (Assert)
// 对于快起伏即使ID相同种子固定情况下连续调用也应基于随机数序列产生可预测的不同值
// 注意:这里比较的是"不同",但因为种子固定,这两个值本身是确定的。
// 如果需要严格验证"不同",可以比较两者差的绝对值大于某个小量,但更简单的做法是验证它们不相等。
Assert.AreNotEqual(rcs1, rcs2, "对于Swerling II模型 (Helicopter, Static)连续调用RCS值理论上应不同因为是快起伏每次都重新采样。");
Assert.IsTrue(rcs1 > 0, "第一个RCS值应大于0。");
Assert.IsTrue(rcs2 > 0, "第二个RCS值应大于0。");
}
/// <summary>
/// 测试当目标是坦克且机动时其RCS行为应类似Swerling III (慢起伏,使用缓存)。
/// </summary>
[TestMethod]
public void GetRealtimeRcs_Tank_Maneuvering_BehavesAsSwerlingIII()
{
// 准备 (Arrange)
var model = new SwerlingRcsModel(TestSeed);
// 操作 (Act)
double rcs1 = model.GetRealtimeRcs(TargetId1, EquipmentType.Tank, MotionStateType.Maneuvering, DefaultAverageRcs, false);
double rcs2 = model.GetRealtimeRcs(TargetId1, EquipmentType.Tank, MotionStateType.Maneuvering, DefaultAverageRcs, false);
// 断言 (Assert)
Assert.AreEqual(rcs1, rcs2, "对于Swerling III模型 (Tank, Maneuvering)在同一扫描周期内RCS值应从缓存读取且保持不变。");
Assert.IsTrue(rcs1 > 0, "RCS值应大于0。");
}
/// <summary>
/// 测试当目标是直升机且机动时其RCS行为应类似Swerling IV (快起伏,不使用缓存)。
/// </summary>
[TestMethod]
public void GetRealtimeRcs_Helicopter_Maneuvering_BehavesAsSwerlingIV()
{
// 准备 (Arrange)
var model = new SwerlingRcsModel(TestSeed);
// 操作 (Act)
double rcs1 = model.GetRealtimeRcs(TargetId1, EquipmentType.Helicopter, MotionStateType.Maneuvering, DefaultAverageRcs, false);
double rcs2 = model.GetRealtimeRcs(TargetId1, EquipmentType.Helicopter, MotionStateType.Maneuvering, DefaultAverageRcs, false);
// 断言 (Assert)
Assert.AreNotEqual(rcs1, rcs2, "对于Swerling IV模型 (Helicopter, Maneuvering)连续调用RCS值应不同。");
Assert.IsTrue(rcs1 > 0, "第一个RCS值应大于0。");
Assert.IsTrue(rcs2 > 0, "第二个RCS值应大于0。");
}
/// <summary>
/// 测试当目标是坦克且匀速运动时其RCS行为应类似Swerling I (慢起伏,使用缓存)。
/// </summary>
[TestMethod]
public void GetRealtimeRcs_Tank_ConstantVelocity_BehavesAsSwerlingI()
{
// 准备 (Arrange)
var model = new SwerlingRcsModel(TestSeed);
// 操作 (Act)
double rcs1 = model.GetRealtimeRcs(TargetId1, EquipmentType.Tank, MotionStateType.ConstantVelocity, DefaultAverageRcs, false);
double rcs2 = model.GetRealtimeRcs(TargetId1, EquipmentType.Tank, MotionStateType.ConstantVelocity, DefaultAverageRcs, false);
// 断言 (Assert)
Assert.AreEqual(rcs1, rcs2, "对于Swerling I模型 (Tank, ConstantVelocity)在同一扫描周期内RCS值应从缓存读取且保持不变。");
Assert.IsTrue(rcs1 > 0, "RCS值应大于0。");
}
/// <summary>
/// 测试当目标是直升机且匀速运动时其RCS行为应类似Swerling II (快起伏,不使用缓存)。
/// </summary>
[TestMethod]
public void GetRealtimeRcs_Helicopter_ConstantVelocity_BehavesAsSwerlingII()
{
// 准备 (Arrange)
var model = new SwerlingRcsModel(TestSeed);
// 操作 (Act)
double rcs1 = model.GetRealtimeRcs(TargetId1, EquipmentType.Helicopter, MotionStateType.ConstantVelocity, DefaultAverageRcs, false);
double rcs2 = model.GetRealtimeRcs(TargetId1, EquipmentType.Helicopter, MotionStateType.ConstantVelocity, DefaultAverageRcs, false);
// 断言 (Assert)
Assert.AreNotEqual(rcs1, rcs2, "对于Swerling II模型 (Helicopter, ConstantVelocity)连续调用RCS值应不同。");
Assert.IsTrue(rcs1 > 0, "第一个RCS值应大于0。");
Assert.IsTrue(rcs2 > 0, "第二个RCS值应大于0。");
}
/// <summary>
/// 测试当目标类型未知时应默认为Swerling I行为。
/// </summary>
[TestMethod]
public void GetRealtimeRcs_UnknownEquipment_BehavesAsSwerlingI()
{
// 准备 (Arrange)
var model = new SwerlingRcsModel(TestSeed);
// 操作 (Act)
double rcs1 = model.GetRealtimeRcs(TargetId1, EquipmentType.Unknown, MotionStateType.Static, DefaultAverageRcs, false);
double rcs2 = model.GetRealtimeRcs(TargetId1, EquipmentType.Unknown, MotionStateType.Static, DefaultAverageRcs, false);
// 断言 (Assert)
Assert.AreEqual(rcs1, rcs2, "对于未知装备类型应默认为Swerling I行为RCS值在同一扫描周期内应保持不变。");
Assert.IsTrue(rcs1 > 0, "RCS值应大于0。");
}
/// <summary>
/// 测试慢起伏模型在同一扫描周期内isNewScanPeriod=false应返回缓存的RCS值。
/// </summary>
[TestMethod]
public void GetRealtimeRcs_SlowFluctuation_SameScanPeriod_ReturnsCachedValue()
{
// 准备 (Arrange)
var model = new SwerlingRcsModel(TestSeed);
// 首次调用isNewScanPeriod 为 true 或 false 都会导致采样和缓存 (对于Swerling I)
double initialRcs = model.GetRealtimeRcs(TargetId1, EquipmentType.Tank, MotionStateType.Static, DefaultAverageRcs, true);
// 操作 (Act)
// 后续调用isNewScanPeriod 为 false
double cachedRcs = model.GetRealtimeRcs(TargetId1, EquipmentType.Tank, MotionStateType.Static, DefaultAverageRcs, false);
// 断言 (Assert)
Assert.AreEqual(initialRcs, cachedRcs, "慢起伏模型在同一扫描周期内应返回相同的缓存RCS值。");
}
/// <summary>
/// 测试慢起伏模型在新扫描周期开始时isNewScanPeriod=true应更新并返回新的缓存RCS值。
/// </summary>
[TestMethod]
public void GetRealtimeRcs_SlowFluctuation_NewScanPeriod_UpdatesAndReturnsNewCachedValue()
{
// 准备 (Arrange)
var model = new SwerlingRcsModel(TestSeed); // 使用固定种子
double rcsScan1 = model.GetRealtimeRcs(TargetId1, EquipmentType.Tank, MotionStateType.Static, DefaultAverageRcs, false);
// 操作 (Act)
// 新扫描周期开始
double rcsScan2PeriodStart = model.GetRealtimeRcs(TargetId1, EquipmentType.Tank, MotionStateType.Static, DefaultAverageRcs, true);
// 在新扫描周期内再次获取,应与周期开始时相同
double rcsScan2SamePeriod = model.GetRealtimeRcs(TargetId1, EquipmentType.Tank, MotionStateType.Static, DefaultAverageRcs, false);
// 断言 (Assert)
// 由于种子固定rcsScan1 和 rcsScan2PeriodStart 应该不同(因为重新采样了)
// 但对于不同的随机数序列,它们也可能偶然相同,所以这个断言不是绝对的,更多的是检查行为
// 更可靠的测试是验证 rcsScan2PeriodStart 和 rcsScan2SamePeriod 相同
Assert.AreNotEqual(rcsScan1, rcsScan2PeriodStart, "新扫描周期开始时RCS值应重新采样与旧周期的值不同高概率。");
Assert.AreEqual(rcsScan2PeriodStart, rcsScan2SamePeriod, "在新扫描周期内后续获取的RCS值应与周期开始时采样并缓存的值相同。");
Assert.IsTrue(rcsScan1 > 0, "第一个扫描周期的RCS值应大于0。");
Assert.IsTrue(rcsScan2PeriodStart > 0, "第二个扫描周期开始的RCS值应大于0。");
}
/// <summary>
/// 测试当平均RCS为0时GetRealtimeRcs应返回0。
/// </summary>
[TestMethod]
public void GetRealtimeRcs_AverageRcsZero_ReturnsZero()
{
// 准备 (Arrange)
var model = new SwerlingRcsModel();
// 操作 (Act)
double rcsS1 = model.GetRealtimeRcs(TargetId1, EquipmentType.Tank, MotionStateType.Static, 0.0, false);
double rcsS2 = model.GetRealtimeRcs(TargetId1, EquipmentType.Helicopter, MotionStateType.Static, 0.0, false);
double rcsS3 = model.GetRealtimeRcs(TargetId1, EquipmentType.Tank, MotionStateType.Maneuvering, 0.0, false);
double rcsS4 = model.GetRealtimeRcs(TargetId1, EquipmentType.Helicopter, MotionStateType.Maneuvering, 0.0, false);
// 断言 (Assert)
Assert.AreEqual(0.0, rcsS1, "Swerling I平均RCS为0时应返回0。");
Assert.AreEqual(0.0, rcsS2, "Swerling II平均RCS为0时应返回0。");
Assert.AreEqual(0.0, rcsS3, "Swerling III平均RCS为0时应返回0。");
Assert.AreEqual(0.0, rcsS4, "Swerling IV平均RCS为0时应返回0。");
}
/// <summary>
/// 测试当平均RCS为负数时GetRealtimeRcs应返回0。
/// </summary>
[TestMethod]
public void GetRealtimeRcs_AverageRcsNegative_ReturnsZero()
{
// 准备 (Arrange)
var model = new SwerlingRcsModel();
// 操作 (Act)
double rcs = model.GetRealtimeRcs(TargetId1, EquipmentType.Tank, MotionStateType.Static, -5.0, false);
// 断言 (Assert)
Assert.AreEqual(0.0, rcs, "平均RCS为负数时应返回0。");
}
/// <summary>
/// 测试对于Swerling I模型如果targetId为null应抛出ArgumentNullException。
/// </summary>
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void GetRealtimeRcs_SwerlingI_NullTargetId_ThrowsArgumentNullException()
{
// 准备 (Arrange)
var model = new SwerlingRcsModel();
// 操作 (Act)
model.GetRealtimeRcs(null!, EquipmentType.Tank, MotionStateType.Static, DefaultAverageRcs, false);
}
/// <summary>
/// 测试对于Swerling I模型如果targetId为空字符串应抛出ArgumentNullException。
/// </summary>
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void GetRealtimeRcs_SwerlingI_EmptyTargetId_ThrowsArgumentNullException()
{
// 准备 (Arrange)
var model = new SwerlingRcsModel();
// 操作 (Act)
model.GetRealtimeRcs(string.Empty, EquipmentType.Tank, MotionStateType.Static, DefaultAverageRcs, false);
}
/// <summary>
/// 测试对于Swerling III模型如果targetId为null应抛出ArgumentNullException。
/// </summary>
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void GetRealtimeRcs_SwerlingIII_NullTargetId_ThrowsArgumentNullException()
{
// 准备 (Arrange)
var model = new SwerlingRcsModel();
// 操作 (Act)
model.GetRealtimeRcs(null!, EquipmentType.Tank, MotionStateType.Maneuvering, DefaultAverageRcs, false);
}
/// <summary>
/// 测试ClearCachedRcs应清除特定目标的缓存导致下次调用重新采样。
/// </summary>
[TestMethod]
public void ClearCachedRcs_SlowFluctuation_ForcesNewSampleForSpecificTarget()
{
// 准备 (Arrange)
var model = new SwerlingRcsModel(TestSeed);
double rcs1Target1 = model.GetRealtimeRcs(TargetId1, EquipmentType.Tank, MotionStateType.Static, DefaultAverageRcs, false);
double rcs1Target2 = model.GetRealtimeRcs(TargetId2, EquipmentType.Tank, MotionStateType.Static, DefaultAverageRcs, false); // 另一个目标以验证其缓存不受影响
// 操作 (Act)
model.ClearCachedRcs(TargetId1); // 清除TargetId1的缓存
double rcs2Target1 = model.GetRealtimeRcs(TargetId1, EquipmentType.Tank, MotionStateType.Static, DefaultAverageRcs, false); // 重新获取TargetId1的RCS
double rcs2Target2 = model.GetRealtimeRcs(TargetId2, EquipmentType.Tank, MotionStateType.Static, DefaultAverageRcs, false); // 再次获取TargetId2的RCS
// 断言 (Assert)
Assert.AreNotEqual(rcs1Target1, rcs2Target1, "清除缓存后TargetId1的RCS值应重新采样而不同高概率。");
Assert.AreEqual(rcs1Target2, rcs2Target2, "清除TargetId1的缓存不应影响TargetId2的缓存值。");
Assert.IsTrue(rcs1Target1 > 0);
Assert.IsTrue(rcs2Target1 > 0);
}
/// <summary>
/// 测试ClearAllCachedRcs应清除所有目标的缓存导致下次所有慢起伏目标调用都重新采样。
/// </summary>
[TestMethod]
public void ClearAllCachedRcs_SlowFluctuation_ForcesNewSamplesForAllTargets()
{
// 准备 (Arrange)
var model = new SwerlingRcsModel(TestSeed);
double rcs1Target1 = model.GetRealtimeRcs(TargetId1, EquipmentType.Tank, MotionStateType.Static, DefaultAverageRcs, false);
double rcs1Target2 = model.GetRealtimeRcs(TargetId2, EquipmentType.Tank, MotionStateType.Static, DefaultAverageRcs, false);
// 操作 (Act)
model.ClearAllCachedRcs(); // 清除所有缓存
double rcs2Target1 = model.GetRealtimeRcs(TargetId1, EquipmentType.Tank, MotionStateType.Static, DefaultAverageRcs, false);
double rcs2Target2 = model.GetRealtimeRcs(TargetId2, EquipmentType.Tank, MotionStateType.Static, DefaultAverageRcs, false);
// 断言 (Assert)
Assert.AreNotEqual(rcs1Target1, rcs2Target1, "清除所有缓存后TargetId1的RCS值应重新采样而不同高概率。");
Assert.AreNotEqual(rcs1Target2, rcs2Target2, "清除所有缓存后TargetId2的RCS值应重新采样而不同高概率。");
Assert.IsTrue(rcs1Target1 > 0);
Assert.IsTrue(rcs1Target2 > 0);
Assert.IsTrue(rcs2Target1 > 0);
Assert.IsTrue(rcs2Target2 > 0);
}
/// <summary>
/// 测试使用相同种子的两个SwerlingRcsModel实例应产生可复现的RCS序列。
/// </summary>
[TestMethod]
public void GetRealtimeRcs_WithSameSeed_GeneratesReproducibleSequence()
{
// 准备 (Arrange)
var model1 = new SwerlingRcsModel(TestSeed);
var model2 = new SwerlingRcsModel(TestSeed);
// 操作 (Act) & 断言 (Assert)
// 以Swerling II (快起伏) 为例因为它不依赖缓存和isNewScanPeriod
for (int i = 0; i < 10; i++)
{
double rcsM1 = model1.GetRealtimeRcs(TargetId1, EquipmentType.Helicopter, MotionStateType.Static, DefaultAverageRcs, false);
double rcsM2 = model2.GetRealtimeRcs(TargetId1, EquipmentType.Helicopter, MotionStateType.Static, DefaultAverageRcs, false);
Assert.AreEqual(rcsM1, rcsM2, $"在第 {i+1} 次调用时使用相同种子的两个模型产生的RCS值应相同。");
Assert.IsTrue(rcsM1 > 0, $"Model1, 调用 {i+1}, RCS 值应大于0。");
}
// 测试Swerling I (慢起伏)
double rcsS1M1_Initial = model1.GetRealtimeRcs(TargetId2, EquipmentType.Tank, MotionStateType.Static, DefaultAverageRcs, true);
double rcsS1M2_Initial = model2.GetRealtimeRcs(TargetId2, EquipmentType.Tank, MotionStateType.Static, DefaultAverageRcs, true);
Assert.AreEqual(rcsS1M1_Initial, rcsS1M2_Initial, "Swerling I相同种子首次调用(isNewScanPeriod=true)RCS值应相同。");
double rcsS1M1_Cached = model1.GetRealtimeRcs(TargetId2, EquipmentType.Tank, MotionStateType.Static, DefaultAverageRcs, false);
double rcsS1M2_Cached = model2.GetRealtimeRcs(TargetId2, EquipmentType.Tank, MotionStateType.Static, DefaultAverageRcs, false);
Assert.AreEqual(rcsS1M1_Cached, rcsS1M2_Cached, "Swerling I相同种子后续调用(isNewScanPeriod=false)缓存的RCS值应相同。");
Assert.AreEqual(rcsS1M1_Initial, rcsS1M1_Cached, "Swerling IModel1后续调用应返回首次缓存的值。");
}
}
}

View File

@ -19,6 +19,8 @@ Mass = 25.0
ExplosionRadius = 5.5
HitProbability = 0.9
SelfDestructHeight = 0.0
InfraredRadiationIntensity = 96.0 # 红外辐射强度 (瓦特/球面度)
UltravioletRadiationIntensity = 100.0 # 紫外辐射强度 (瓦特/球面度)
# --- 复合制导特定属性 ---
CompositeWorkMode = "Serial" # 工作模式Serial (串行) 或 Parallel (并行)
# FusionStrategy = "UseHighestPriority" # 仅在并行模式下相关

View File

@ -19,6 +19,8 @@ Mass = 23.5 # 质量 (千克)
ExplosionRadius = 5.0 # 爆炸半径 (米)
HitProbability = 0.9 # 命中概率
SelfDestructHeight = 0.0 # 自毁高度 (米)
InfraredRadiationIntensity = 96.0 # 红外辐射强度 (瓦特/球面度)
UltravioletRadiationIntensity = 100.0 # 紫外辐射强度 (瓦特/球面度)
# TrackerSensitivity, CommandLatency, IrSignature 在JSON中为null此处省略
[InfraredCommandGuidanceConfig]

View File

@ -19,6 +19,8 @@ Mass = 25.0
ExplosionRadius = 5.5
HitProbability = 0.9
SelfDestructHeight = 0.0
InfraredRadiationIntensity = 96.0 # 红外辐射强度 (瓦特/球面度)
UltravioletRadiationIntensity = 100.0 # 紫外辐射强度 (瓦特/球面度)
[InfraredImagingGuidanceConfig]
MaxDetectionRange = 1000.0 # 最大探测距离 (米), JSON中为1000对应C#默认为1000.0

View File

@ -19,6 +19,8 @@ Mass = 24.5 # 质量 (千克)
ExplosionRadius = 5.0 # 爆炸半径 (米)
HitProbability = 0.9 # 命中概率
SelfDestructHeight = 0.0 # 自毁高度 (米)
InfraredRadiationIntensity = 96.0 # 红外辐射强度 (瓦特/球面度)
UltravioletRadiationIntensity = 100.0 # 紫外辐射强度 (瓦特/球面度)
[Properties.LaserCodeConfig] # 激光编码配置
IsCodeEnabled = true # 是否启用编码

View File

@ -20,6 +20,8 @@ Mass = 22.0 # 导弹质量 (kg)
ExplosionRadius = 5.0 # 爆炸半径 (米)
HitProbability = 0.9 # 固有命中概率 (0.0 到 1.0)
SelfDestructHeight = 0.0 # 离地自毁高度 (米)
InfraredRadiationIntensity = 96.0 # 红外辐射强度 (瓦特/球面度)
UltravioletRadiationIntensity = 100.0 # 紫外辐射强度 (瓦特/球面度)
[Properties.LaserCodeConfig] # properties内部的激光编码配置
IsCodeEnabled = true # 激光编码系统是否启用?

View File

@ -19,6 +19,8 @@ Mass = 28.0 # 质量 (千克)
ExplosionRadius = 5.0 # 爆炸半径 (米)
HitProbability = 0.9 # 命中概率
SelfDestructHeight = 0.0 # 自毁高度 (米)
InfraredRadiationIntensity = 96.0 # 红外辐射强度 (瓦特/球面度)
UltravioletRadiationIntensity = 100.0 # 紫外辐射强度 (瓦特/球面度)
[MillimeterWaveGuidanceConfig]
MaxDetectionRange = 5000.0 # 最大探测距离 (米)

View File

@ -1,3 +1,4 @@
using System.Reflection;
using ThreatSource.Simulation;
namespace ThreatSource.Equipment
@ -104,15 +105,22 @@ namespace ThreatSource.Equipment
{
// 获取基础状态信息
var statusInfo = base.GetStatusInfo();
// 添加装备特有属性
statusInfo.ExtendedProperties["Health"] = Health;
statusInfo.ExtendedProperties["Length"] = Properties.Length;
statusInfo.ExtendedProperties["Width"] = Properties.Width;
statusInfo.ExtendedProperties["Height"] = Properties.Height;
statusInfo.ExtendedProperties["InfraredRadiationIntensity"] = Properties.InfraredRadiationIntensity;
statusInfo.ExtendedProperties["MillimeterWaveRadiationIntensity"] = Properties.MillimeterWaveRadiationIntensity;
statusInfo.ExtendedProperties["UltravioletRadiationIntensity"] = Properties.UltravioletRadiationIntensity;
if (Properties != null)
{
var propertiesType = Properties.GetType();
var props = propertiesType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var prop in props)
{
if (prop.CanRead) // 确保属性是可读的
{
object? propValue = prop.GetValue(Properties);
statusInfo.ExtendedProperties[prop.Name] = propValue ?? string.Empty;
}
}
}
return statusInfo;
}

View File

@ -478,8 +478,6 @@ namespace ThreatSource.Guidance
// 将合成激光信号传递给四象限探测器
quadrantDetector.ProcessLaserSignal(ReceivedLaserPower, spotOffset);
Debug.WriteLine($"处理激光信号: 总功率={ReceivedLaserPower:E}W, 目标位置={TargetPosition}");
}
catch (Exception ex)
{

View File

@ -245,7 +245,7 @@ namespace ThreatSource.Indicator
// 获取基类状态信息
var statusInfo = base.GetStatusInfo();
// 添加制导系统特有属性
// 添加指示器特有属性
statusInfo.ExtendedProperties["TargetId"] = TargetId ?? "";
statusInfo.ExtendedProperties["MissileId"] = MissileId ?? "";
statusInfo.ExtendedProperties["lastKnownTargetPosition"] = _lastKnownTargetPosition ?? Vector3D.Zero;

View File

@ -223,7 +223,7 @@ namespace ThreatSource.Jammer
// 获取基类状态信息
var statusInfo = base.GetStatusInfo();
// 添加制导系统特有属性
// 添加干扰器特有属性
statusInfo.ExtendedProperties["JammingType"] = JammingType;
statusInfo.ExtendedProperties["State"] = State;
statusInfo.ExtendedProperties["IsJamming"] = IsJamming;

View File

@ -1,6 +1,7 @@
using System.Diagnostics;
using ThreatSource.Simulation;
using ThreatSource.Utils;
using System.Reflection;
namespace ThreatSource.Missile
{
@ -456,22 +457,38 @@ namespace ThreatSource.Missile
// 获取基础状态信息
var statusInfo = base.GetStatusInfo();
// 添加导弹固有属性通过MissileProperties
statusInfo.ExtendedProperties["Type"] = Properties.Type;
statusInfo.ExtendedProperties["MaxSpeed"] = Properties.MaxSpeed;
statusInfo.ExtendedProperties["MaxAcceleration"] = Properties.MaxAcceleration;
statusInfo.ExtendedProperties["MaxRange"] = Properties.MaxFlightDistance;
statusInfo.ExtendedProperties["MaxFlightTime"] = Properties.MaxFlightTime;
statusInfo.ExtendedProperties["ExplosionRadius"] = Properties.ExplosionRadius;
statusInfo.ExtendedProperties["Mass"] = Properties.Mass;
// 使用反射动态添加来自 this.Properties 的导弹固有属性
if (Properties != null)
{
var propertiesType = Properties.GetType();
var props = propertiesType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var prop in props)
{
if (prop.CanRead)
{
// 复合制导导弹才有复合制导系统参数
if ((prop.Name == nameof(MissileProperties.GuidanceSuite) ||
prop.Name == nameof(MissileProperties.CompositeWorkMode) ||
prop.Name == nameof(MissileProperties.FusionStrategy)) &&
Properties.Type != MissileType.CompositeGuidance)
{
continue;
}
object? propValue = prop.GetValue(Properties);
statusInfo.ExtendedProperties[prop.Name] = propValue ?? string.Empty;
}
}
}
// 添加导弹运行时状态
statusInfo.ExtendedProperties["FlightTime"] = FlightTime;
statusInfo.ExtendedProperties["FlightDistance"] = FlightDistance;
statusInfo.ExtendedProperties["EngineBurnTime"] = EngineBurnTime;
statusInfo.ExtendedProperties["IsGuidance"] = IsGuidance;
// 添加 BaseMissile 类的运行时状态参数
statusInfo.ExtendedProperties["FlightTime"] = FlightTime;
statusInfo.ExtendedProperties["FlightDistance"] = FlightDistance;
statusInfo.ExtendedProperties["EngineBurnTime"] = EngineBurnTime;
statusInfo.ExtendedProperties["IsGuidance"] = IsGuidance;
statusInfo.ExtendedProperties["LostGuidanceTime"] = LostGuidanceTime;
statusInfo.ExtendedProperties["GuidanceAcceleration"] = GuidanceAcceleration;
statusInfo.ExtendedProperties["GuidanceAcceleration"] = GuidanceAcceleration;
return statusInfo;
}

View File

@ -209,6 +209,15 @@ namespace ThreatSource.Missile
/// </remarks>
public class MissileProperties
{
/// <summary>
/// 获取或设置导弹的类型
/// </summary>
/// <remarks>
/// 决定导弹的制导方式和行为特征
/// 影响导弹的性能参数和作战能力
/// </remarks>
public MissileType Type { get; set; }
/// <summary>
/// 获取或设置导弹的最大速度限制
/// </summary>
@ -319,13 +328,22 @@ namespace ThreatSource.Missile
public double MaxEngineBurnTime { get; set; }
/// <summary>
/// 获取或设置导弹的类型
/// 获取或设置红外辐射强度
/// </summary>
/// <remarks>
/// 决定导弹的制导方式和行为特征
/// 影响导弹的性能参数和作战能力
/// 单位:瓦特/球面度
/// 表示导弹在红外波段的发射功率
/// </remarks>
public MissileType Type { get; set; }
public double InfraredRadiationIntensity { get; set; }
/// <summary>
/// 获取或设置紫外辐射强度
/// </summary>
/// <remarks>
/// 单位:瓦特/球面度
/// 表示导弹在紫外波段的发射功率
/// </remarks>
public double UltravioletRadiationIntensity { get; set; }
/// <summary>
/// 获取或设置激光编码配置
@ -357,13 +375,13 @@ namespace ThreatSource.Missile
/// 复合制导模式下,多个制导系统的工作方式。默认为串行。
/// 仅当 Type 为 CompositeGuidance 时有效。
/// </summary>
public CompositeWorkType CompositeWorkMode { get; set; } = CompositeWorkType.Serial;
public CompositeWorkType CompositeWorkMode { get; set; }
/// <summary>
/// 并行工作模式下的指令融合策略。默认为使用最高优先级的指令。
/// 仅当 Type 为 CompositeGuidance 且 CompositeWorkMode 为 Parallel 时有效。
/// </summary>
public CommandFusionStrategy FusionStrategy { get; set; } = CommandFusionStrategy.UseHighestPriority;
public CommandFusionStrategy FusionStrategy { get; set; }
/// <summary>
/// 初始化导弹配置类的新实例
@ -377,8 +395,6 @@ namespace ThreatSource.Missile
public MissileProperties()
{
SetDefaultValues();
Type = MissileType.StandardMissile;
LaserCodeConfig = new LaserCodeConfig();
GuidanceSuite = [];
}
@ -395,6 +411,7 @@ namespace ThreatSource.Missile
/// </remarks>
public void SetDefaultValues()
{
Type = MissileType.StandardMissile;
MaxSpeed = 400;
MaxFlightTime = 60;
MaxFlightDistance = 5000;
@ -407,11 +424,16 @@ namespace ThreatSource.Missile
ExplosionRadius = 5;
HitProbability = 0.9;
SelfDestructHeight = 0;
InfraredRadiationIntensity = 100.0;
UltravioletRadiationIntensity = 100.0;
LaserCodeConfig = new LaserCodeConfig();
// 重置复合制导相关属性的默认值
CompositeWorkMode = CompositeWorkType.Serial;
FusionStrategy = CommandFusionStrategy.UseHighestPriority;
if (GuidanceSuite != null) GuidanceSuite.Clear(); else GuidanceSuite = new List<GuidanceComponentConfig>();
if(Type == MissileType.CompositeGuidance)
{
CompositeWorkMode = CompositeWorkType.Serial;
FusionStrategy = CommandFusionStrategy.UseHighestPriority;
}
}
}
}

View File

@ -303,7 +303,7 @@ namespace ThreatSource.Sensor
// 获取基础状态信息
var statusInfo = base.GetStatusInfo();
// 添加传感器状态
// 添加传感器特有状态信息
statusInfo.ExtendedProperties["IsJammed"] = IsJammed.ToString();
statusInfo.ExtendedProperties["IsBlockingJammed"] = IsBlockingJammed.ToString();
statusInfo.ExtendedProperties["SensorData"] = GetSensorData().ToString() ?? "无数据";