From 639bb2b4456d1f2f3cf90aa718c333344fd0f6e2 Mon Sep 17 00:00:00 2001
From: Tian jianyong <11429339@qq.com>
Date: Wed, 9 Apr 2025 19:42:08 +0800
Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E9=A3=8E=E5=90=91?=
=?UTF-8?q?=E9=A3=8E=E9=80=9F=E7=9A=84=E5=BD=B1=E5=93=8D=EF=BC=8C=E5=A2=9E?=
=?UTF-8?q?=E5=8A=A0=E5=A4=A7=E6=B0=94=E9=80=8F=E8=BF=87=E7=8E=87=E5=BD=B1?=
=?UTF-8?q?=E5=93=8D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
CHANGELOG.md | 6 +-
ThreatSource.Tests/ThreatSource.Tests.csproj | 7 +
.../LaserSemiActiveGuidanceSystemCodeTests.cs | 16 +-
.../src/Indicator/LaserDesignatorCodeTests.cs | 2 +-
.../src/Indicator/LaserDesignatorTests.cs | 3 +-
.../src/Jamming/LaserDecoyTests.cs | 15 +-
.../Jamming/LaserDesignatorJammingTests.cs | 3 +-
.../LaserSemiActiveGuidedMissileCodeTests.cs | 15 +-
...SemiActiveGuidedMissileIntegrationTests.cs | 5 +-
.../src/Simulation/SimulationManagerTests.cs | 4 +-
.../src/Utils/AtmosphereDllWrapperTests.cs | 181 ++++
ThreatSource/ThreatSource.csproj | 7 +
.../indicators/laser_beamriders/br_001.json | 1 +
.../indicators/laser_designators/ld_001.json | 7 +-
.../missiles/laser_semi_active/lsgm_001.json | 11 +-
ThreatSource/data/weathers/heavy_fog.json | 15 +
ThreatSource/data/weathers/heavy_rain.json | 15 +
ThreatSource/data/weathers/heavy_snow.json | 15 +
ThreatSource/data/weathers/light_fog.json | 15 +
ThreatSource/data/weathers/light_rain.json | 15 +
ThreatSource/data/weathers/light_snow.json | 15 +
ThreatSource/data/weathers/medium_fog.json | 15 +
ThreatSource/data/weathers/medium_rain.json | 15 +
ThreatSource/data/weathers/medium_snow.json | 15 +
ThreatSource/data/weathers/sandstorm.json | 15 +
ThreatSource/data/weathers/sunny.json | 15 +
ThreatSource/lib/AirTransmission.dll | Bin 0 -> 18944 bytes
ThreatSource/lib/AirTransmission.xml | 908 ++++++++++++++++++
.../src/Data/{Models.cs => DataModels.cs} | 94 +-
.../src/Data/ThreatSourceDataManager.cs | 52 +
ThreatSource/src/Data/ThreatSourceFactory.cs | 22 +
.../Guidance/InfraredCommandGuidanceSystem.cs | 70 +-
.../src/Guidance/InfraredImageGenerator.cs | 104 +-
.../Guidance/InfraredImagingGuidanceSystem.cs | 15 +-
.../src/Guidance/InfraredTargetRecognizer.cs | 65 +-
.../Guidance/LaserBeamRiderGuidanceSystem.cs | 25 +-
.../Guidance/LaserSemiActiveGuidanceSystem.cs | 487 ++++------
.../Guidance/MillimeterWaveGuidanceSystem.cs | 17 +-
ThreatSource/src/Indicator/LaserDesignator.cs | 52 +-
ThreatSource/src/MIssile/BaseMissile.cs | 89 +-
.../MIssile/LaserSemiActiveGuidedMissile.cs | 30 +-
ThreatSource/src/Sensor/QuadrantDetector.cs | 98 +-
ThreatSource/src/Simulation/DecoyTarget.cs | 52 +-
.../src/Simulation/ISimulationManager.cs | 29 +-
.../src/Simulation/SimulationConfig.cs | 78 +-
.../src/Simulation/SimulationEvents.cs | 80 +-
.../src/Simulation/SimulationManager.cs | 45 +-
ThreatSource/src/Target/Tank.cs | 36 +-
.../src/Utils/AtmosphereDllWrapper.cs | 157 +++
ThreatSource/src/Utils/LaserCode.cs | 2 -
ThreatSource/src/Utils/MotionAlgorithm.cs | 24 +
VERSION | 2 +-
docs/project/develop_log.md | 28 +
docs/project/theory.md | 126 +++
tools/ComprehensiveMissileSimulator.cs | 59 +-
tools/ThreatSource.Tools.csproj | 4 +
56 files changed, 2554 insertions(+), 744 deletions(-)
create mode 100644 ThreatSource.Tests/src/Utils/AtmosphereDllWrapperTests.cs
create mode 100644 ThreatSource/data/weathers/heavy_fog.json
create mode 100644 ThreatSource/data/weathers/heavy_rain.json
create mode 100644 ThreatSource/data/weathers/heavy_snow.json
create mode 100644 ThreatSource/data/weathers/light_fog.json
create mode 100644 ThreatSource/data/weathers/light_rain.json
create mode 100644 ThreatSource/data/weathers/light_snow.json
create mode 100644 ThreatSource/data/weathers/medium_fog.json
create mode 100644 ThreatSource/data/weathers/medium_rain.json
create mode 100644 ThreatSource/data/weathers/medium_snow.json
create mode 100644 ThreatSource/data/weathers/sandstorm.json
create mode 100644 ThreatSource/data/weathers/sunny.json
create mode 100644 ThreatSource/lib/AirTransmission.dll
create mode 100644 ThreatSource/lib/AirTransmission.xml
rename ThreatSource/src/Data/{Models.cs => DataModels.cs} (82%)
create mode 100644 ThreatSource/src/Utils/AtmosphereDllWrapper.cs
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 67d28d0..4a11aec 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,12 +12,14 @@
- 支持与 Simulink 模型的数据交互
- 实现实时仿真数据同步
- 处理不同时间步长的协调
-- 增加风向风速的影响
-- 增加大气透过率影响
- 毫米波跟踪和锁定阶段采用脉冲多普勒制导、目标 RCS 特征矩阵
- 多种发射弹道模式:低平弹道、高抛弹道、俯冲弹道
- 双模、多模制导
+## [0.2.10] - 2025-04-09
+- 增加了风向风速的影响
+- 增加大气透过率影响
+
## [0.2.9] - 2025-04-04
- 增加了半主动激光制导的假目标干扰和测试用例
diff --git a/ThreatSource.Tests/ThreatSource.Tests.csproj b/ThreatSource.Tests/ThreatSource.Tests.csproj
index 3d1a722..d80fbcc 100644
--- a/ThreatSource.Tests/ThreatSource.Tests.csproj
+++ b/ThreatSource.Tests/ThreatSource.Tests.csproj
@@ -20,5 +20,12 @@
+
+
+
+ ..\ThreatSource\lib\AirTransmission.dll
+ True
+
+
\ No newline at end of file
diff --git a/ThreatSource.Tests/src/Guidance/LaserSemiActiveGuidanceSystemCodeTests.cs b/ThreatSource.Tests/src/Guidance/LaserSemiActiveGuidanceSystemCodeTests.cs
index 3f51530..6948a26 100644
--- a/ThreatSource.Tests/src/Guidance/LaserSemiActiveGuidanceSystemCodeTests.cs
+++ b/ThreatSource.Tests/src/Guidance/LaserSemiActiveGuidanceSystemCodeTests.cs
@@ -80,7 +80,7 @@ namespace ThreatSource.Tests.Guidance
// Arrange
_guidanceSystem.SetExpectedLaserCode(LaserCodeType.PRF, 1234);
- var illuminationEvent = new LaserIlluminationStartEvent
+ var illuminationEvent = new LaserIlluminationUpdateEvent
{
LaserDesignatorId = "laser1",
TargetId = "target1",
@@ -96,7 +96,7 @@ namespace ThreatSource.Tests.Guidance
};
// Act
- _guidanceSystem.ProcessLaserIlluminationEvent(illuminationEvent);
+ _guidanceSystem.ProcessLaserIlluminationUpdateEvent(illuminationEvent);
// Assert
var matchEvents = _testAdapter.GetPublishedEvents();
@@ -116,7 +116,7 @@ namespace ThreatSource.Tests.Guidance
// Arrange
_guidanceSystem.SetExpectedLaserCode(LaserCodeType.PRF, 1234);
- var illuminationEvent = new LaserIlluminationStartEvent
+ var illuminationEvent = new LaserIlluminationUpdateEvent
{
LaserDesignatorId = "laser1",
TargetId = "target1",
@@ -132,7 +132,7 @@ namespace ThreatSource.Tests.Guidance
};
// Act
- _guidanceSystem.ProcessLaserIlluminationEvent(illuminationEvent);
+ _guidanceSystem.ProcessLaserIlluminationUpdateEvent(illuminationEvent);
// Assert
var mismatchEvents = _testAdapter.GetPublishedEvents();
@@ -155,7 +155,7 @@ namespace ThreatSource.Tests.Guidance
// Arrange
_guidanceSystem.SetExpectedLaserCode(LaserCodeType.PRF, 1234);
- var illuminationEvent = new LaserIlluminationStartEvent
+ var illuminationEvent = new LaserIlluminationUpdateEvent
{
LaserDesignatorId = "laser1",
TargetId = "target1",
@@ -171,7 +171,7 @@ namespace ThreatSource.Tests.Guidance
};
// Act
- _guidanceSystem.ProcessLaserIlluminationEvent(illuminationEvent);
+ _guidanceSystem.ProcessLaserIlluminationUpdateEvent(illuminationEvent);
// Assert
var mismatchEvents = _testAdapter.GetPublishedEvents();
@@ -194,7 +194,7 @@ namespace ThreatSource.Tests.Guidance
// Arrange
_guidanceSystem.SetExpectedLaserCode(LaserCodeType.PRF, 1234);
- var illuminationEvent = new LaserIlluminationStartEvent
+ var illuminationEvent = new LaserIlluminationUpdateEvent
{
LaserDesignatorId = "laser1",
TargetId = "target1",
@@ -210,7 +210,7 @@ namespace ThreatSource.Tests.Guidance
};
// Act
- _guidanceSystem.ProcessLaserIlluminationEvent(illuminationEvent);
+ _guidanceSystem.ProcessLaserIlluminationUpdateEvent(illuminationEvent);
// Assert - No mismatch events should be published
var mismatchEvents = _testAdapter.GetPublishedEvents();
diff --git a/ThreatSource.Tests/src/Indicator/LaserDesignatorCodeTests.cs b/ThreatSource.Tests/src/Indicator/LaserDesignatorCodeTests.cs
index a4ba138..c3b7d84 100644
--- a/ThreatSource.Tests/src/Indicator/LaserDesignatorCodeTests.cs
+++ b/ThreatSource.Tests/src/Indicator/LaserDesignatorCodeTests.cs
@@ -172,7 +172,7 @@ namespace ThreatSource.Tests.Indicator
_laserDesignator.Activate();
// Assert - Start event should include code
- var startEvents = _testAdapter.GetPublishedEvents();
+ var startEvents = _testAdapter.GetPublishedEvents();
Assert.NotEmpty(startEvents);
var startEvent = startEvents[startEvents.Count - 1];
Assert.NotNull(startEvent.LaserCodeConfig);
diff --git a/ThreatSource.Tests/src/Indicator/LaserDesignatorTests.cs b/ThreatSource.Tests/src/Indicator/LaserDesignatorTests.cs
index 83d1ca0..75c26f0 100644
--- a/ThreatSource.Tests/src/Indicator/LaserDesignatorTests.cs
+++ b/ThreatSource.Tests/src/Indicator/LaserDesignatorTests.cs
@@ -27,8 +27,7 @@ namespace ThreatSource.Tests.Indicator
LaserPower = 1000,
LaserDivergenceAngle = 0.001,
JammingResistanceThreshold = 10000,
- MinWavelength = 1.0,
- MaxWavelength = 1.1
+ LaserWavelength = 1.06
};
var tankInitialMotion = new InitialMotionParameters
diff --git a/ThreatSource.Tests/src/Jamming/LaserDecoyTests.cs b/ThreatSource.Tests/src/Jamming/LaserDecoyTests.cs
index b3c33ee..6bd5fbd 100644
--- a/ThreatSource.Tests/src/Jamming/LaserDecoyTests.cs
+++ b/ThreatSource.Tests/src/Jamming/LaserDecoyTests.cs
@@ -163,8 +163,7 @@ namespace ThreatSource.Tests.Jamming
}
},
JammingResistanceThreshold = 1.0,
- MinWavelength = 1.06,
- MaxWavelength = 1.07
+ LaserWavelength = 1.06
};
// 创建虚拟激光指示器并注册 - 更靠近目标
@@ -296,8 +295,7 @@ namespace ThreatSource.Tests.Jamming
}
},
JammingResistanceThreshold = 1.0,
- MinWavelength = 1.06,
- MaxWavelength = 1.07
+ LaserWavelength = 1.06
};
// 创建虚拟激光指示器并注册
@@ -419,8 +417,7 @@ namespace ThreatSource.Tests.Jamming
}
},
JammingResistanceThreshold = 1.0,
- MinWavelength = 1.06,
- MaxWavelength = 1.07
+ LaserWavelength = 1.06
};
// 创建虚拟激光指示器并注册
@@ -558,8 +555,7 @@ namespace ThreatSource.Tests.Jamming
}
},
JammingResistanceThreshold = 1.0,
- MinWavelength = 1.06,
- MaxWavelength = 1.07
+ LaserWavelength = 1.06
};
// 创建虚拟激光指示器并注册
@@ -821,8 +817,7 @@ namespace ThreatSource.Tests.Jamming
}
},
JammingResistanceThreshold = 1.0,
- MinWavelength = 1.06,
- MaxWavelength = 1.07
+ LaserWavelength = 1.06
};
// 创建虚拟激光指示器并注册 - 距离目标2000米
diff --git a/ThreatSource.Tests/src/Jamming/LaserDesignatorJammingTests.cs b/ThreatSource.Tests/src/Jamming/LaserDesignatorJammingTests.cs
index 6c974c3..c71f1e6 100644
--- a/ThreatSource.Tests/src/Jamming/LaserDesignatorJammingTests.cs
+++ b/ThreatSource.Tests/src/Jamming/LaserDesignatorJammingTests.cs
@@ -31,8 +31,7 @@ namespace ThreatSource.Tests.Jamming
LaserPower = 100,
LaserDivergenceAngle = 0.001,
JammingResistanceThreshold = 0.01, // 设置干扰抗性阈值为10mW,适应球面扩散模型
- MinWavelength = 1.0,
- MaxWavelength = 1.1
+ LaserWavelength = 1.06
};
// 初始化激光指示器
diff --git a/ThreatSource.Tests/src/Missile/LaserSemiActiveGuidedMissileCodeTests.cs b/ThreatSource.Tests/src/Missile/LaserSemiActiveGuidedMissileCodeTests.cs
index 95a52c5..ba24f50 100644
--- a/ThreatSource.Tests/src/Missile/LaserSemiActiveGuidedMissileCodeTests.cs
+++ b/ThreatSource.Tests/src/Missile/LaserSemiActiveGuidedMissileCodeTests.cs
@@ -112,8 +112,7 @@ namespace ThreatSource.Tests.Missile
{
LaserPower = 100,
LaserDivergenceAngle = 0.001,
- MinWavelength = 1.0,
- MaxWavelength = 1.1
+ LaserWavelength = 1.06
}, new InitialMotionParameters
{
Position = new Vector3D(100, 0, 0),
@@ -211,7 +210,7 @@ namespace ThreatSource.Tests.Missile
_laserDesignator.LaserPower = 100; // 设置足够高的激光功率
// Act - Send matching code illumination
- var illuminationEvent = new LaserIlluminationStartEvent
+ var illuminationEvent = new LaserIlluminationUpdateEvent
{
LaserDesignatorId = "laser1",
TargetId = "target1",
@@ -256,7 +255,7 @@ namespace ThreatSource.Tests.Missile
_laserDesignator.LaserPower = 100; // 设置足够高的激光功率
// Act - Send mismatching code illumination
- var illuminationEvent = new LaserIlluminationStartEvent
+ var illuminationEvent = new LaserIlluminationUpdateEvent
{
LaserDesignatorId = "laser1",
TargetId = "target1",
@@ -301,8 +300,8 @@ namespace ThreatSource.Tests.Missile
_laserDesignator.LaserPower = 100; // 设置足够高的激光功率
// Act - Send illumination with code disabled
- var illuminationEvent = new LaserIlluminationStartEvent
- {
+ var illuminationEvent = new LaserIlluminationUpdateEvent
+ {
LaserDesignatorId = "laser1",
TargetId = "target1",
LaserCodeConfig = new LaserCodeConfig
@@ -339,7 +338,7 @@ namespace ThreatSource.Tests.Missile
_missile.Update(0.1); // Move past launch stage
// Act - Send illumination with code disabled
- var illuminationEvent = new LaserIlluminationStartEvent
+ var illuminationEvent = new LaserIlluminationUpdateEvent
{
LaserDesignatorId = "laser1",
TargetId = "target1",
@@ -382,7 +381,7 @@ namespace ThreatSource.Tests.Missile
_laserDesignator.LaserPower = 100; // 设置足够高的激光功率
// First enable guidance with matching code
- var startEvent = new LaserIlluminationStartEvent
+ var startEvent = new LaserIlluminationUpdateEvent
{
LaserDesignatorId = "laser1",
TargetId = "target1",
diff --git a/ThreatSource.Tests/src/Missile/LaserSemiActiveGuidedMissileIntegrationTests.cs b/ThreatSource.Tests/src/Missile/LaserSemiActiveGuidedMissileIntegrationTests.cs
index e4ff4dd..80edf4b 100644
--- a/ThreatSource.Tests/src/Missile/LaserSemiActiveGuidedMissileIntegrationTests.cs
+++ b/ThreatSource.Tests/src/Missile/LaserSemiActiveGuidedMissileIntegrationTests.cs
@@ -77,8 +77,7 @@ namespace ThreatSource.Tests.Missile
{
LaserPower = 100,
LaserDivergenceAngle = 0.001,
- MinWavelength = 1.0,
- MaxWavelength = 1.1
+ LaserWavelength = 1.06
};
_laserDesignator = new LaserDesignator(
@@ -164,7 +163,7 @@ namespace ThreatSource.Tests.Missile
}
// 手动创建并发布激光照射开始事件,确保事件被正确传递到制导系统
- var illuminationEvent = new LaserIlluminationStartEvent
+ var illuminationEvent = new LaserIlluminationUpdateEvent
{
LaserDesignatorId = _laserDesignator.Id,
TargetId = _target.Id,
diff --git a/ThreatSource.Tests/src/Simulation/SimulationManagerTests.cs b/ThreatSource.Tests/src/Simulation/SimulationManagerTests.cs
index 2767310..4d8e5d2 100644
--- a/ThreatSource.Tests/src/Simulation/SimulationManagerTests.cs
+++ b/ThreatSource.Tests/src/Simulation/SimulationManagerTests.cs
@@ -83,14 +83,14 @@ namespace ThreatSource.Tests.Simulation
public void TestExternalEventReception()
{
// Arrange
- var externalEvent = new LaserIlluminationStartEvent
+ var externalEvent = new LaserIlluminationUpdateEvent
{
LaserDesignatorId = "laser1",
TargetId = "target1"
};
bool eventReceived = false;
- _simulationManager.SubscribeToEvent(evt =>
+ _simulationManager.SubscribeToEvent(evt =>
{
eventReceived = true;
Assert.Equal("laser1", evt.LaserDesignatorId);
diff --git a/ThreatSource.Tests/src/Utils/AtmosphereDllWrapperTests.cs b/ThreatSource.Tests/src/Utils/AtmosphereDllWrapperTests.cs
new file mode 100644
index 0000000..6a49aeb
--- /dev/null
+++ b/ThreatSource.Tests/src/Utils/AtmosphereDllWrapperTests.cs
@@ -0,0 +1,181 @@
+using System;
+using Xunit;
+using ThreatSource.Utils;
+using AirTransmission;
+
+namespace ThreatSource.Tests.Utils
+{
+ public class AtmosphereDllWrapperTests
+ {
+ [Fact]
+ public void CalculateTransmittance_LaserType_ReturnsExpectedValue()
+ {
+ // Arrange - 创建一个标准天气条件
+ var weather = new Weather(
+ type: WeatherType.Clear,
+ temperature: 20.0,
+ relativeHumidity: 50.0,
+ visibility: 10.0, // 单位:km
+ precipitation: 0.0
+ );
+
+ double distance = 1.0; // 1km
+ var radiationType = RadiationType.Laser;
+ double wavelength = 1.064; // 常见的YAG激光波长(微米)
+
+ // Act - 调用被测试方法
+ double transmittance = AtmosphereDllWrapper.CalculateTransmittance(
+ distance * 1000, // 转换为米
+ radiationType,
+ wavelength,
+ weather
+ );
+
+ // Assert - 验证结果在合理范围内
+ Console.WriteLine($"激光透过率: {transmittance:F6}");
+ Assert.True(transmittance >= 0.0);
+ Assert.True(transmittance <= 1.0);
+ Assert.NotEqual(0.0, transmittance); // 确保不是0
+ }
+
+ [Fact]
+ public void CalculateTransmittance_InfraredType_ReturnsExpectedValue()
+ {
+ // Arrange - 创建一个标准天气条件
+ var weather = new Weather(
+ type: WeatherType.Clear,
+ temperature: 20.0,
+ relativeHumidity: 50.0,
+ visibility: 10.0, // 单位:km
+ precipitation: 0.0
+ );
+
+ double distance = 1.0; // 1km
+ var radiationType = RadiationType.Infrared;
+ double wavelength = 8.0; // 中波红外波长(微米)
+
+ // Act - 调用被测试方法
+ double transmittance = AtmosphereDllWrapper.CalculateTransmittance(
+ distance * 1000, // 转换为米
+ radiationType,
+ wavelength,
+ weather
+ );
+
+ // Assert - 验证结果在合理范围内
+ Console.WriteLine($"红外透过率: {transmittance:F6}");
+ Assert.True(transmittance >= 0.0);
+ Assert.True(transmittance <= 1.0);
+ Assert.NotEqual(0.0, transmittance); // 确保不是0
+ }
+
+ [Fact]
+ public void CalculateAtmosphericTurbulence_ReturnsExpectedValue()
+ {
+ // Arrange - 创建一个标准天气条件
+ var weather = new Weather(
+ type: WeatherType.Clear,
+ temperature: 20.0,
+ relativeHumidity: 50.0,
+ visibility: 10.0, // 单位:km
+ precipitation: 0.0
+ );
+
+ double wavelength = 1.064; // 常见的YAG激光波长(微米)
+ double distance = 1.0; // 1km
+ double height = 10.0; // 10m高度
+
+ // Act - 调用被测试方法
+ double turbulenceEffect = AtmosphereDllWrapper.CalculateAtmosphericTurbulence(
+ wavelength,
+ distance * 1000, // 转换为米
+ weather,
+ height
+ );
+
+ // Assert - 验证结果在合理范围内
+ Console.WriteLine($"湍流效应: {turbulenceEffect:F6}");
+ Assert.True(turbulenceEffect >= 0.0);
+ Assert.True(turbulenceEffect <= 1.0);
+ Assert.NotEqual(0.0, turbulenceEffect); // 确保不是0
+ }
+
+ [Fact]
+ public void CalculateSmokeScreenTransmittance_ReturnsExpectedValue()
+ {
+ double wavelength = 1.064; // 常见的YAG激光波长(微米)
+ double smokeConcentration = 1.0; // 烟雾浓度(g/m³)
+ double smokeThickness = 50.0; // 烟幕厚度(m)
+
+ // Act - 调用被测试方法
+ double smokeTransmittance = AtmosphereDllWrapper.CalculateSmokeScreenTransmittance(
+ wavelength,
+ smokeConcentration,
+ smokeThickness
+ );
+
+ // Assert - 验证结果在合理范围内
+ Console.WriteLine($"烟幕透过率: {smokeTransmittance:F6}");
+ Assert.True(smokeTransmittance >= 0.0);
+ Assert.True(smokeTransmittance <= 1.0);
+ }
+
+ [Fact]
+ public void CalculateTransmittance_DifferentWeatherConditions_ShowsVariation()
+ {
+ // Arrange - 创建不同的天气条件
+ var clearWeather = new Weather(
+ type: WeatherType.Clear,
+ temperature: 25.0,
+ relativeHumidity: 50.0,
+ visibility: 10.0, // 单位:km
+ precipitation: 0.0
+ );
+
+ var foggyWeather = new Weather(
+ type: WeatherType.Fog,
+ temperature: 15.0,
+ relativeHumidity: 90.0,
+ visibility: 0.5, // 单位:km
+ precipitation: 0.0
+ );
+
+ var rainyWeather = new Weather(
+ type: WeatherType.Rain,
+ temperature: 18.0,
+ relativeHumidity: 95.0,
+ visibility: 2.0, // 单位:km
+ precipitation: 5.0
+ );
+
+ double distance = 1.0; // 1km
+ var radiationType = RadiationType.Laser;
+ double wavelength = 1.064; // 常见的YAG激光波长(微米)
+
+ // Act - 调用被测试方法
+ double clearTransmittance = AtmosphereDllWrapper.CalculateTransmittance(
+ distance * 1000, radiationType, wavelength, clearWeather); // 转换为米
+
+ double foggyTransmittance = AtmosphereDllWrapper.CalculateTransmittance(
+ distance * 1000, radiationType, wavelength, foggyWeather); // 转换为米
+
+ double rainyTransmittance = AtmosphereDllWrapper.CalculateTransmittance(
+ distance * 1000, radiationType, wavelength, rainyWeather); // 转换为米
+
+ // Assert - 验证不同天气条件对透过率有影响
+ Console.WriteLine($"晴天透过率: {clearTransmittance:F6}");
+ Console.WriteLine($"雾天透过率: {foggyTransmittance:F6}");
+ Console.WriteLine($"雨天透过率: {rainyTransmittance:F6}");
+
+ // 验证所有值在有效范围内
+ Assert.True(clearTransmittance >= 0.0 && clearTransmittance <= 1.0);
+ Assert.True(foggyTransmittance >= 0.0 && foggyTransmittance <= 1.0);
+ Assert.True(rainyTransmittance >= 0.0 && rainyTransmittance <= 1.0);
+
+ // 确保所有透过率都不是0
+ Assert.NotEqual(0.0, clearTransmittance);
+ Assert.NotEqual(0.0, foggyTransmittance);
+ Assert.NotEqual(0.0, rainyTransmittance);
+ }
+ }
+}
\ No newline at end of file
diff --git a/ThreatSource/ThreatSource.csproj b/ThreatSource/ThreatSource.csproj
index f9254cc..77b6cfd 100644
--- a/ThreatSource/ThreatSource.csproj
+++ b/ThreatSource/ThreatSource.csproj
@@ -12,4 +12,11 @@
+
+
+ $(ProjectDir)lib\AirTransmission.dll
+ True
+
+
+
\ No newline at end of file
diff --git a/ThreatSource/data/indicators/laser_beamriders/br_001.json b/ThreatSource/data/indicators/laser_beamriders/br_001.json
index a686115..b19de60 100644
--- a/ThreatSource/data/indicators/laser_beamriders/br_001.json
+++ b/ThreatSource/data/indicators/laser_beamriders/br_001.json
@@ -6,6 +6,7 @@
"type": "LaserBeamRider",
"beamRiderConfig": {
"laserPower": 1000,
+ "laserWavelength": 1.06,
"controlFieldDiameter": 6.0,
"laserCodeConfig": {
"code": {
diff --git a/ThreatSource/data/indicators/laser_designators/ld_001.json b/ThreatSource/data/indicators/laser_designators/ld_001.json
index bc4b84a..9dc8216 100644
--- a/ThreatSource/data/indicators/laser_designators/ld_001.json
+++ b/ThreatSource/data/indicators/laser_designators/ld_001.json
@@ -5,10 +5,9 @@
},
"type": "LaserDesignator",
"designatorConfig": {
- "laserPower": 1000,
- "laserDivergenceAngle": 0.0002,
- "minWavelength": 1.0,
- "maxWavelength": 1.1,
+ "laserPower": 5000,
+ "laserDivergenceAngle": 0.0003,
+ "laserWavelength": 1.06,
"laserCodeConfig": {
"code": {
"codeType": "PRF",
diff --git a/ThreatSource/data/missiles/laser_semi_active/lsgm_001.json b/ThreatSource/data/missiles/laser_semi_active/lsgm_001.json
index bbc0434..2c85ffb 100644
--- a/ThreatSource/data/missiles/laser_semi_active/lsgm_001.json
+++ b/ThreatSource/data/missiles/laser_semi_active/lsgm_001.json
@@ -8,8 +8,8 @@
"maxSpeed": 800.0,
"maxFlightTime": 60.0,
"maxFlightDistance": 4000.0,
- "maxAcceleration": 100.0,
- "proportionalNavigationCoefficient": 3.0,
+ "maxAcceleration": 50.0,
+ "proportionalNavigationCoefficient": 2.0,
"launchAcceleration": 100.0,
"maxEngineBurnTime": 0.1,
"cruiseTime": 5.0,
@@ -34,7 +34,10 @@
"reflectionCoefficient": 0.2,
"targetReflectiveArea": 1.0,
"lockThreshold": 1e-12,
- "spotOffsetSensitivity": 0.5,
- "jammingResistanceThreshold": 1e-3
+ "spotOffsetSensitivity": 0.05,
+ "jammingResistanceThreshold": 1e-3,
+ "transmitterEfficiency": 0.85,
+ "receiverEfficiency": 0.8,
+ "laserWavelength": 1.06
}
}
\ No newline at end of file
diff --git a/ThreatSource/data/weathers/heavy_fog.json b/ThreatSource/data/weathers/heavy_fog.json
new file mode 100644
index 0000000..ca03b1e
--- /dev/null
+++ b/ThreatSource/data/weathers/heavy_fog.json
@@ -0,0 +1,15 @@
+{
+ "name": {
+ "zh": "浓雾",
+ "en": "Heavy Fog"
+ },
+ "type": "Fog",
+ "temperature": 8.0,
+ "relativeHumidity": 99.0,
+ "visibility": 0.1,
+ "precipitation": 0.0,
+ "cO2Concentration": 415.0,
+ "pressure": 998.0,
+ "windSpeed": 0.0,
+ "windDirection": 0.0
+}
\ No newline at end of file
diff --git a/ThreatSource/data/weathers/heavy_rain.json b/ThreatSource/data/weathers/heavy_rain.json
new file mode 100644
index 0000000..f7c99e2
--- /dev/null
+++ b/ThreatSource/data/weathers/heavy_rain.json
@@ -0,0 +1,15 @@
+{
+ "name": {
+ "zh": "大雨",
+ "en": "Heavy Rain"
+ },
+ "type": "Rain",
+ "temperature": 16.0,
+ "relativeHumidity": 95.0,
+ "visibility": 2.0,
+ "precipitation": 25.0,
+ "cO2Concentration": 415.0,
+ "pressure": 985.0,
+ "windSpeed": 8.0,
+ "windDirection": 180.0
+}
\ No newline at end of file
diff --git a/ThreatSource/data/weathers/heavy_snow.json b/ThreatSource/data/weathers/heavy_snow.json
new file mode 100644
index 0000000..3a929d1
--- /dev/null
+++ b/ThreatSource/data/weathers/heavy_snow.json
@@ -0,0 +1,15 @@
+{
+ "name": {
+ "zh": "大雪",
+ "en": "Heavy Snow"
+ },
+ "type": "Snow",
+ "temperature": -7.0,
+ "relativeHumidity": 85.0,
+ "visibility": 1.0,
+ "precipitation": 8.0,
+ "cO2Concentration": 410.0,
+ "pressure": 990.0,
+ "windSpeed": 6.0,
+ "windDirection": 270.0
+}
\ No newline at end of file
diff --git a/ThreatSource/data/weathers/light_fog.json b/ThreatSource/data/weathers/light_fog.json
new file mode 100644
index 0000000..693e6f5
--- /dev/null
+++ b/ThreatSource/data/weathers/light_fog.json
@@ -0,0 +1,15 @@
+{
+ "name": {
+ "zh": "轻雾",
+ "en": "Light Fog"
+ },
+ "type": "Fog",
+ "temperature": 12.0,
+ "relativeHumidity": 95.0,
+ "visibility": 0.8,
+ "precipitation": 0.0,
+ "cO2Concentration": 415.0,
+ "pressure": 1000.0,
+ "windSpeed": 0.5,
+ "windDirection": 20.0
+}
\ No newline at end of file
diff --git a/ThreatSource/data/weathers/light_rain.json b/ThreatSource/data/weathers/light_rain.json
new file mode 100644
index 0000000..38bcfb5
--- /dev/null
+++ b/ThreatSource/data/weathers/light_rain.json
@@ -0,0 +1,15 @@
+{
+ "name": {
+ "zh": "小雨",
+ "en": "Light Rain"
+ },
+ "type": "Rain",
+ "temperature": 20.0,
+ "relativeHumidity": 80.0,
+ "visibility": 6.0,
+ "precipitation": 5.0,
+ "cO2Concentration": 415.0,
+ "pressure": 1005.0,
+ "windSpeed": 3.0,
+ "windDirection": 180.0
+}
\ No newline at end of file
diff --git a/ThreatSource/data/weathers/light_snow.json b/ThreatSource/data/weathers/light_snow.json
new file mode 100644
index 0000000..bb656e0
--- /dev/null
+++ b/ThreatSource/data/weathers/light_snow.json
@@ -0,0 +1,15 @@
+{
+ "name": {
+ "zh": "小雪",
+ "en": "Light Snow"
+ },
+ "type": "Snow",
+ "temperature": -3.0,
+ "relativeHumidity": 75.0,
+ "visibility": 4.0,
+ "precipitation": 2.0,
+ "cO2Concentration": 410.0,
+ "pressure": 1002.0,
+ "windSpeed": 3.0,
+ "windDirection": 270.0
+}
\ No newline at end of file
diff --git a/ThreatSource/data/weathers/medium_fog.json b/ThreatSource/data/weathers/medium_fog.json
new file mode 100644
index 0000000..5236375
--- /dev/null
+++ b/ThreatSource/data/weathers/medium_fog.json
@@ -0,0 +1,15 @@
+{
+ "name": {
+ "zh": "中雾",
+ "en": "Medium Fog"
+ },
+ "type": "Fog",
+ "temperature": 10.0,
+ "relativeHumidity": 98.0,
+ "visibility": 0.4,
+ "precipitation": 0.0,
+ "cO2Concentration": 415.0,
+ "pressure": 1000.0,
+ "windSpeed": 0.2,
+ "windDirection": 10.0
+}
\ No newline at end of file
diff --git a/ThreatSource/data/weathers/medium_rain.json b/ThreatSource/data/weathers/medium_rain.json
new file mode 100644
index 0000000..4fe1d6f
--- /dev/null
+++ b/ThreatSource/data/weathers/medium_rain.json
@@ -0,0 +1,15 @@
+{
+ "name": {
+ "zh": "中雨",
+ "en": "Medium Rain"
+ },
+ "type": "Rain",
+ "temperature": 18.0,
+ "relativeHumidity": 90.0,
+ "visibility": 4.0,
+ "precipitation": 15.0,
+ "cO2Concentration": 415.0,
+ "pressure": 995.0,
+ "windSpeed": 6.0,
+ "windDirection": 180.0
+}
diff --git a/ThreatSource/data/weathers/medium_snow.json b/ThreatSource/data/weathers/medium_snow.json
new file mode 100644
index 0000000..1b43fe4
--- /dev/null
+++ b/ThreatSource/data/weathers/medium_snow.json
@@ -0,0 +1,15 @@
+{
+ "name": {
+ "zh": "中雪",
+ "en": "Medium Snow"
+ },
+ "type": "Snow",
+ "temperature": -5.0,
+ "relativeHumidity": 80.0,
+ "visibility": 2.0,
+ "precipitation": 4.0,
+ "cO2Concentration": 410.0,
+ "pressure": 1000.0,
+ "windSpeed": 4.0,
+ "windDirection": 270.0
+}
\ No newline at end of file
diff --git a/ThreatSource/data/weathers/sandstorm.json b/ThreatSource/data/weathers/sandstorm.json
new file mode 100644
index 0000000..992bec2
--- /dev/null
+++ b/ThreatSource/data/weathers/sandstorm.json
@@ -0,0 +1,15 @@
+{
+ "name": {
+ "zh": "沙尘",
+ "en": "Sandstorm"
+ },
+ "type": "Dust",
+ "temperature": 30.0,
+ "relativeHumidity": 25.0,
+ "visibility": 1.5,
+ "precipitation": 0.0,
+ "cO2Concentration": 430.0,
+ "pressure": 1005.0,
+ "windSpeed": 12.0,
+ "windDirection": 315.0
+}
\ No newline at end of file
diff --git a/ThreatSource/data/weathers/sunny.json b/ThreatSource/data/weathers/sunny.json
new file mode 100644
index 0000000..6dbbffa
--- /dev/null
+++ b/ThreatSource/data/weathers/sunny.json
@@ -0,0 +1,15 @@
+{
+ "name": {
+ "zh": "晴天",
+ "en": "Sunny"
+ },
+ "type": "Clear",
+ "temperature": 25.0,
+ "relativeHumidity": 45.0,
+ "visibility": 15.0,
+ "precipitation": 0.0,
+ "cO2Concentration": 415.0,
+ "pressure": 1018.0,
+ "windSpeed": 1.2,
+ "windDirection": 90.0
+}
\ No newline at end of file
diff --git a/ThreatSource/lib/AirTransmission.dll b/ThreatSource/lib/AirTransmission.dll
new file mode 100644
index 0000000000000000000000000000000000000000..26c424a37d0d32835a02ed4f6a47ae1557d69fd3
GIT binary patch
literal 18944
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
literal 0
HcmV?d00001
diff --git a/ThreatSource/lib/AirTransmission.xml b/ThreatSource/lib/AirTransmission.xml
new file mode 100644
index 0000000..b54dc0c
--- /dev/null
+++ b/ThreatSource/lib/AirTransmission.xml
@@ -0,0 +1,908 @@
+
+
+
+ AirTransmission
+
+
+
+
+ 天气参数结构体,用于封装天气相关的参数
+
+
+
+
+ 辐射类型枚举,用于指定不同类型的电磁波
+
+
+
+
+ 大气透过率计算器,提供各种电磁波在大气中传输的透过率计算方法
+
+
+ 支持以下电磁波类型的透过率计算:
+ - 激光(包含湍流效应)
+ - 红外线
+ - 紫外线
+ - 毫米波
+ 可以处理各种天气条件和烟雾环境
+
+
+
+
+ 计算激光在给定天气条件和距离下的大气透过率
+
+ 天气条件
+ 传输距离(米)
+ 大气透过率
+
+
+
+ 计算红外线在给定条件下的大气透过率
+
+ 天气条件
+ 传输距离(米)
+ 大气透过率
+
+
+
+ 计算毫米波在给定条件下的大气透过率
+
+ 天气条件
+ 传输距离(米)
+ 大气透过率
+
+
+
+ 计算紫外线在给定天气条件和距离下的大气透过率
+
+ 天气条件
+ 传输距离(米)
+ 大气透过率
+
+
+
+ 计算湍流效应对激光透过率的影响
+
+ 天气条件
+ 传输距离(米)
+ 传输高度(米)
+ 大气透过率
+
+
+
+ 计算烟幕对电磁波的透过率
+
+ 波长(微米)
+ 烟幕浓度(g/m³)
+ 烟幕厚度(米)
+ 烟幕透过率(0到1之间的值)
+
+
+
+ 计算双程传输后接收到的辐射功率
+
+ 大气透过率
+ 激光能量(焦耳)
+ 脉冲宽度(纳秒)
+ 目标距离(米)
+ 接收器距离(米)
+ 目标反射率
+ 接收到的辐射功率(瓦特)
+
+
+
+ 计算单程传输后接收到的辐射功率
+
+ 大气透过率
+ 目标辐射(W/Sr)
+ 接收器距离(米)
+ 接收到的辐射功率(W/Sr)
+
+
+
+ 导出函数:计算大气透过率
+
+ 辐射类型(0:激光, 1:红外, 2:紫外, 3:毫米波)
+ 波长(微米)
+ 传输距离(米)
+ 天气参数
+ 透过率(0到1之间的值)
+
+
+
+ 导出函数:计算大气湍流影响
+
+ 波长(微米)
+ 传输距离(米)
+ 天气参数
+ 传输高度(米)
+ 湍流效应(0到1之间的值,1表示无影响,0表示完全衰减)
+
+
+
+ 导出函数:计算烟幕透过率
+
+ 波长(微米)
+ 烟幕浓度(g/m³)
+ 烟幕厚度(米)
+ 烟幕透过率(0到1之间的值)
+
+
+
+ 大气湍流模型类,用于计算大气湍流对光传输的影响
+
+
+ 主要功能:
+ - 计算大气折射率结构常数
+ - 计算湍流引起的光束抖动
+ - 计算闪烁指数
+ - 评估湍流对光传输的综合影响
+
+
+
+
+ 波数常量,单位:m^-1
+
+
+ 基于1.06微米波长(常用的Nd:YAG激光器波长)计算:k = 2π/λ
+
+
+
+
+ 计算大气湍流对光传输的综合影响
+
+ 传输距离(公里)
+ 传输高度(米)
+ 天气条件
+ 湍流效应(0到1之间的值,1表示无影响,0表示完全衰减)
+
+
+
+ 使用标准的 Hufnagel-Valley 模型计算大气折射率结构常数
+
+ 高度(米)
+ 风速(米/秒)
+ 大气折射率结构常数
+
+
+
+ 计算弗里德参数(Fried parameter)
+
+ 大气折射率结构常数
+ 传输距离(公里)
+ 弗里德参数(米)
+
+
+
+ 计算闪烁指数(Scintillation Index)
+
+ 大气折射率结构常数
+ 波数
+ 传输距离(公里)
+ 闪烁指数(无量纲)
+
+
+
+ 计算光束漂移(Beam Wander)
+
+ 大气折射率结构常数
+ 传输距离(公里)
+ 传输高度(米)
+ 光束漂移(弧度)
+
+
+
+ 计算相干长度(Coherence Length)
+
+ 大气折射率结构常数
+ 传输距离(公里)
+ 相干长度(米)
+
+
+
+ 计算到达角(Angle of Arrival)
+
+ 大气折射率结构常数
+ 传输距离(公里)
+ 接收器口径(米)
+ 到达角(弧度)
+
+
+
+ 计算等晕角(Isoplanatism Angle)
+
+ 大气折射率结构常数
+ 传输距离(公里)
+ 等晕角(弧度)
+
+
+
+ 红外线透过率计算模型,用于计算红外线在大气中的传输特性
+
+
+ 主要功能:
+ - 计算红外线在不同天气条件下的透过率
+ - 使用光谱模型法进行计算
+ - 考虑大气分子吸收(主要是水汽和CO2)
+ - 计算各种天气条件(雨、雪、雾、沙尘)的衰减效应
+
+
+
+
+ 红外波段最小波长,单位:微米
+
+
+
+
+ 红外波段最大波长,单位:微米
+
+
+
+
+ 光谱分段数
+
+
+
+
+ 主要计算波长,单位:微米
+
+
+ 选择10μm作为主要计算波长,因为这是大气窗口区
+
+
+
+
+ 计算给定距离的红外线透过率
+
+ 传输距离,单位:米
+ 红外线透过率,范围:0-1
+
+ 计算过程:
+ 1. 将光谱分为多个波段
+ 2. 对每个波段计算衰减
+ 3. 考虑天气条件的影响
+ 4. 综合得到最终透过率
+
+
+
+
+ 计算特定波长的波段衰减
+
+ 波长,单位:微米
+ 波段衰减系数,单位:km^-1
+
+ 包含三种衰减机制:
+ - 瑞利散射(Rayleigh散射)
+ - 米氏散射(Mie散射)
+ - 分子吸收
+
+
+
+
+ 计算瑞利散射系数
+
+ 波长,单位:微米
+ 瑞利散射系数,单位:km^-1
+
+ 使用改进的瑞利散射公式,考虑温度和压力的影响
+
+
+
+
+ 计算米氏散射系数
+
+ 波长,单位:微米
+ 米氏散射系数,单位:km^-1
+
+ 基于能见度和气溶胶密度计算米氏散射
+
+
+
+
+ 计算分子吸收系数
+
+ 波长,单位:微米
+ 分子吸收系数,单位:km^-1
+
+ 主要考虑水汽和CO2的吸收
+
+
+
+
+ 获取特定波长的光谱权重
+
+ 波长,单位:微米
+ 光谱权重,范围:0-1
+
+ 根据黑体辐射理论计算光谱权重
+
+
+
+
+ 计算天气效应对透过率的影响
+
+ 传输距离,单位:米
+ 天气影响因子,范围:0-1
+
+ 综合考虑:
+ - 降水(雨、雪)的影响
+ - 雾的衰减效应
+ - 沙尘的影响
+
+
+
+
+ 激光透过率计算模型,用于计算激光在大气中的传输特性
+
+
+ 主要功能:
+ - 计算激光在不同天气条件下的透过率
+ - 考虑大气湍流效应
+ - 处理烟雾对激光传输的影响
+ - 计算各种天气条件(雨、雪、雾、沙尘)的衰减效应
+
+
+
+
+ 激光透过率计算模型,用于计算激光在大气中的传输特性
+
+
+ 主要功能:
+ - 计算激光在不同天气条件下的透过率
+ - 考虑大气湍流效应
+ - 处理烟雾对激光传输的影响
+ - 计算各种天气条件(雨、雪、雾、沙尘)的衰减效应
+
+
+
+
+ 激光波长常量,单位:微米
+
+
+ 默认使用1.06μm波长,对应Nd:YAG激光器的基频输出
+
+
+
+
+ 计算给定距离的激光透过率
+
+ 传输距离,单位:米
+ 激光透过率,范围:0-1
+
+ 计算过程考虑:
+ - 分子散射和吸收
+ - 气溶胶散射
+ - 降水(雨、雪)衰减
+ - 雾和沙尘的影响
+
+
+
+
+ 计算雨对激光的衰减系数K
+
+ 波长(微米)
+ 雨衰减系数K
+
+
+
+ 计算雨对激光的衰减系数α
+
+ 波长(微米)
+ 雨衰减系数α
+
+
+
+ 计算雪对激光的衰减系数K
+
+ 波长(微米)
+ 雪衰减系数K
+
+
+
+ 计算雪对激光的衰减系数α
+
+ 波长(微米)
+ 雪衰减系数α
+
+
+
+ 计算激光的总衰减因子
+
+ 激光总衰减因子
+
+
+
+ 计算分子散射因子
+
+ 分子散射因子
+
+
+
+ 计算气溶胶散射因子
+
+ 气溶胶散射因子
+
+
+
+ 计算雾对激光的衰减
+
+ 传输路径长度(米)
+ 雾对激光的衰减
+
+
+
+ 毫米波透过率计算模型,用于计算毫米波在大气中的传输特性
+
+
+ 主要功能:
+ - 计算毫米波在不同天气条件下的透过率
+ - 考虑大气分子散射和吸收
+ - 处理水汽和氧气的吸收
+ - 计算各种天气条件(雨、雪、雾、沙尘)的衰减效应
+
+ 波长说明:
+ 虽然毫米波通常用毫米表示波长,但为了与其他电磁波计算保持一致,
+ 本模型中统一使用微米(μm)作为波长单位。
+ 例如:3.19mm = 3190μm
+
+
+
+
+ 毫米波波长常量,单位:微米
+
+
+ 3.19mm = 3190μm,对应94GHz频率
+ 该频率是毫米波雷达常用工作频率
+
+
+
+
+ 计算给定距离的毫米波透过率
+
+ 传输距离,单位:米
+ 毫米波透过率,范围:0-1
+
+ 计算过程考虑:
+ - 分子散射和吸收
+ - 水汽吸收
+ - 氧气吸收
+ - 降水(雨、雪)衰减
+ - 雾和沙尘的影响
+
+
+
+
+ 计算分子散射系数
+
+ 分子散射系数,单位:km^-1
+
+ 使用修正的瑞利散射公式,考虑温度和压力的影响
+
+
+
+
+ 计算气溶胶散射系数
+
+ 气溶胶散射系数(km^-1)
+
+
+
+ 计算水汽吸收系数
+
+ 水汽吸收系数(km^-1)
+
+
+
+ 计算水汽密度
+
+ 水汽密度(g/m³)
+
+
+
+ 计算氧气吸收系数
+
+ 氧气吸收系数(km^-1)
+
+
+
+ 计算雾对毫米波的衰减
+
+ 传输路径长度(米)
+ 雾衰减
+
+
+
+ 烟幕透过率模型,用于计算不同波长电磁波在烟幕中的透过率
+
+
+
+
+ 计算烟幕对电磁波的透过率
+
+ 波长(微米)
+ 烟幕浓度(g/m³)
+ 烟幕厚度(米)
+ 烟幕透过率(0到1之间的值)
+
+
+
+ 根据波长获取烟幕衰减系数
+
+ 波长(微米)
+ 烟幕衰减系数(m²/g)
+
+
+
+ 大气透过率计算的基础模型类,提供了各种大气条件下的透过率计算方法
+
+
+ 包含以下主要衰减机制的计算:
+ - 分子散射和吸收
+ - 气溶胶散射和吸收
+ - 降水(雨、雪)衰减
+ - 沙尘和雾的衰减
+
+ 所有波长相关计算统一使用微米(μm)作为单位:
+ - 激光:1.06μm
+ - 红外:3-12μm
+ - 紫外:0.2-0.4μm
+ - 毫米波:3190μm(3.19mm,对应94GHz)
+
+
+
+
+ 大气透过率计算的基础模型类,提供了各种大气条件下的透过率计算方法
+
+
+ 包含以下主要衰减机制的计算:
+ - 分子散射和吸收
+ - 气溶胶散射和吸收
+ - 降水(雨、雪)衰减
+ - 沙尘和雾的衰减
+
+ 所有波长相关计算统一使用微米(μm)作为单位:
+ - 激光:1.06μm
+ - 红外:3-12μm
+ - 紫外:0.2-0.4μm
+ - 毫米波:3190μm(3.19mm,对应94GHz)
+
+
+
+
+ 标准大气透过率常量
+
+
+ 在标准大气条件下(23km能见度,1013.25hPa气压,20℃温度)的透过率值
+
+
+
+
+ 标准能见度常量,单位:千米
+
+
+
+
+ 标准气溶胶密度常量,单位:粒子/立方厘米
+
+
+
+
+ 当前天气条件对象
+
+
+
+
+ 温度,单位:开尔文
+
+
+ 由摄氏度转换而来:K = ℃ + 273.15
+
+
+
+
+ 大气压力(百帕)
+
+
+
+
+ 相对湿度(百分比)
+
+
+
+
+ 气溶胶密度(粒子/立方厘米)
+
+
+
+
+ 能见度(公里)
+
+
+
+
+ 是否下雨
+
+
+
+
+ 降雨量(毫米/小时)
+
+
+
+
+ 是否有雾
+
+
+
+
+ 是否有沙尘
+
+
+
+
+ 是否下雪
+
+
+
+
+ 降雪量(毫米/小时)
+
+
+
+
+ 二氧化碳浓度(ppm)
+
+
+
+
+ 计算给定距离的大气透过率
+
+ 传输距离(米)
+ 大气透过率(0到1之间的值)
+
+
+
+ 根据能见度计算气溶胶密度
+
+ 能见度(公里)
+ 气溶胶密度(粒子/立方厘米)
+
+
+
+ 计算雨对电磁波的衰减系数K
+
+ 波长(微米)
+ 雨衰减系数K
+
+
+
+ 计算雨对电磁波的衰减系数α
+
+ 波长(微米)
+ 雨衰减系数α
+
+
+
+ 计算雪对电磁波的衰减系数K
+
+ 波长(微米)
+ 雪衰减系数K
+
+
+
+ 计算雪对电磁波的衰减系数α
+
+ 波长(微米)
+ 雪衰减系数α
+
+
+
+ 计算雨对电磁波的衰减
+
+ 传输路径长度(米)
+ 波长(微米)
+ 雨衰减(dB)
+
+
+
+ 计算雪对电磁波的衰减
+
+ 传输路径长度(米)
+ 波长(微米)
+ 雪衰减(dB)
+
+
+
+ 计算沙尘对电磁波的衰减
+
+ 传输路径长度(米)
+ 沙尘衰减(dB)
+
+
+
+ 计算能见度因子
+
+ 能见度因子
+
+
+
+ 紫外线透过率计算模型,用于计算紫外线在大气中的传输特性
+
+
+ 主要功能:
+ - 计算紫外线在不同天气条件下的透过率
+ - 使用光谱模型法进行计算
+ - 考虑臭氧层吸收
+ - 计算各种天气条件(雨、雪、雾、沙尘)的衰减效应
+
+
+
+
+ 紫外波段最小波长,单位:微米
+
+
+
+
+ 紫外波段最大波长,单位:微米
+
+
+
+
+ 光谱分段数
+
+
+
+
+ 主要计算波长,单位:微米
+
+
+ 选择0.308μm作为主要计算波长,这是XeCl准分子激光器的输出波长
+
+
+
+
+ 计算给定距离的紫外线透过率
+
+ 传输距离,单位:米
+ 紫外线透过率,范围:0-1
+
+ 计算过程:
+ 1. 将光谱分为多个波段
+ 2. 对每个波段计算衰减
+ 3. 考虑天气条件的影响
+ 4. 综合得到最终透过率
+
+
+
+
+ 天气条件类,用于描述大气传输计算所需的天气参数
+
+
+ 包含以下主要天气参数:
+ - 天气类型(晴天、雨天、雪天等)
+ - 温度
+ - 相对湿度
+ - 能见度
+ - 降水量
+ - CO2浓度
+
+ 天气类型
+ 温度(摄氏度)
+ 相对湿度(百分比)
+ 能见度(公里)
+ 降水量(毫米/小时),可选
+ 二氧化碳浓度(ppm),默认415ppm
+ 大气压力(hPa),默认1013.25hPa
+ 风速(m/s),默认0m/s
+ 风向(0-360度),默认0度
+
+
+
+ 天气条件类,用于描述大气传输计算所需的天气参数
+
+
+ 包含以下主要天气参数:
+ - 天气类型(晴天、雨天、雪天等)
+ - 温度
+ - 相对湿度
+ - 能见度
+ - 降水量
+ - CO2浓度
+
+ 天气类型
+ 温度(摄氏度)
+ 相对湿度(百分比)
+ 能见度(公里)
+ 降水量(毫米/小时),可选
+ 二氧化碳浓度(ppm),默认415ppm
+ 大气压力(hPa),默认1013.25hPa
+ 风速(m/s),默认0m/s
+ 风向(0-360度),默认0度
+
+
+
+ 天气类型
+
+
+
+
+ 温度(摄氏度)
+
+
+
+
+ 相对湿度(百分比)
+
+
+
+
+ 能见度(公里)
+
+
+
+
+ 降水量(毫米/小时)
+
+
+
+
+ 二氧化碳浓度(ppm)
+
+
+
+
+ 大气压力(hPa)
+
+
+
+
+ 风速(m/s)
+
+
+
+
+ 风向(0-360度, 0度为北, 顺时针)
+
+
+
+
+ 打印天气信息
+
+ 天气条件对象
+
+ 输出格式:
+ 天气类型: [类型], 温度: [温度]°C, 相对湿度: [湿度]%, 能见度: [能见度]km, 降水量: [降水量]mm/h, 大气压力: [大气压力]kPa, 风速: [风速]m/s, 风向: [风向]度
+
+
+
+
+ 天气类型枚举
+
+
+
+
+ 晴朗天气
+
+
+
+
+ 雨天
+
+
+
+
+ 雪天
+
+
+
+
+ 雾天
+
+
+
+
+ 沙尘天气
+
+
+
+
diff --git a/ThreatSource/src/Data/Models.cs b/ThreatSource/src/Data/DataModels.cs
similarity index 82%
rename from ThreatSource/src/Data/Models.cs
rename to ThreatSource/src/Data/DataModels.cs
index 43790bd..a3ab9e6 100644
--- a/ThreatSource/src/Data/Models.cs
+++ b/ThreatSource/src/Data/DataModels.cs
@@ -1,8 +1,7 @@
-using System.Collections.Generic;
-using ThreatSource.Utils;
using ThreatSource.Missile;
using ThreatSource.Simulation;
using ThreatSource.Target;
+using AirTransmission;
namespace ThreatSource.Data
{
///
@@ -432,4 +431,95 @@ namespace ThreatSource.Data
return new ThermalPattern(ThermalPattern.StaticPattern, ThermalPattern.MovingPattern);
}
}
+
+ ///
+ /// 天气数据模型
+ ///
+ ///
+ /// 包含天气的基本信息和参数
+ /// 用于创建和初始化天气实例
+ ///
+ public class WeatherData
+ {
+ ///
+ /// 获取或设置天气的多语言名称
+ ///
+ ///
+ /// 包含中英文名称
+ /// 用于显示和文档
+ ///
+ public LocalizedName Name { get; set; } = new();
+
+ ///
+ /// 获取或设置天气类型
+ ///
+ ///
+ /// 可选值:Clear(晴天)、Rain(雨天)、Snow(雪天)、Fog(雾天)、Dust(沙尘天气)
+ ///
+ public WeatherType Type { get; set; } = WeatherType.Clear;
+
+ ///
+ /// 获取或设置温度(摄氏度)
+ ///
+ ///
+ /// 影响大气透过率和探测效果
+ ///
+ public double Temperature { get; set; } = 25.0;
+
+ ///
+ /// 获取或设置相对湿度(百分比)
+ ///
+ ///
+ /// 影响大气透过率和探测效果
+ ///
+ public double RelativeHumidity { get; set; } = 50.0;
+
+ ///
+ /// 获取或设置能见度(公里)
+ ///
+ ///
+ /// 影响可视区域和探测范围
+ ///
+ public double Visibility { get; set; } = 10.0;
+
+ ///
+ /// 获取或设置降水量(毫米/小时)
+ ///
+ ///
+ /// 可选项,影响天气效果和探测精度
+ ///
+ public double Precipitation { get; set; } = 0.0;
+
+ ///
+ /// 获取或设置二氧化碳浓度(ppm)
+ ///
+ ///
+ /// 影响大气成分和透过率
+ ///
+ public double CO2Concentration { get; set; } = 415.0;
+
+ ///
+ /// 获取或设置大气压力(hPa)
+ ///
+ ///
+ /// 影响大气透过率和探测效果
+ ///
+ public double Pressure { get; set; } = 1013.25;
+
+ ///
+ /// 获取或设置风速(米/秒)
+ ///
+ ///
+ /// 影响弹道计算和飞行路径
+ ///
+ public double WindSpeed { get; set; } = 0.0;
+
+ ///
+ /// 获取或设置风向(角度,0为北,顺时针增加)
+ ///
+ ///
+ /// 影响弹道计算和飞行路径
+ ///
+ public double WindDirection { get; set; } = 0.0;
+ }
}
\ No newline at end of file
diff --git a/ThreatSource/src/Data/ThreatSourceDataManager.cs b/ThreatSource/src/Data/ThreatSourceDataManager.cs
index c64a554..55ffe8c 100644
--- a/ThreatSource/src/Data/ThreatSourceDataManager.cs
+++ b/ThreatSource/src/Data/ThreatSourceDataManager.cs
@@ -36,6 +36,7 @@ namespace ThreatSource.Data
private readonly Dictionary _indicators = new();
private readonly Dictionary _sensors = new();
private readonly Dictionary _targets = new();
+ private readonly Dictionary _weathers = new();
///
/// 初始化威胁源数据管理器
@@ -59,6 +60,7 @@ namespace ThreatSource.Data
LoadIndicators(Path.Combine(path, "indicators"));
LoadSensors(Path.Combine(path, "sensors"));
LoadTargets(Path.Combine(path, "targets"));
+ LoadWeathers(Path.Combine(path, "weathers"));
}
///
@@ -214,6 +216,39 @@ namespace ThreatSource.Data
}
}
+ ///
+ /// 加载天气数据
+ ///
+ /// 天气数据目录路径
+ private void LoadWeathers(string path)
+ {
+ if (!Directory.Exists(path))
+ {
+ Console.WriteLine($"天气数据目录不存在:{path}");
+ return;
+ }
+
+ foreach (var file in Directory.GetFiles(path, "*.json", SearchOption.AllDirectories))
+ {
+ try
+ {
+ var jsonContent = File.ReadAllText(file);
+ var data = JsonSerializer.Deserialize(jsonContent, _jsonOptions);
+ if (data != null)
+ {
+ string model = Path.GetFileNameWithoutExtension(file);
+ _weathers[model] = data;
+ Console.WriteLine($"已加载天气数据:{model}");
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"加载天气数据文件失败:{file},错误:{ex.Message}");
+ Console.WriteLine($"异常堆栈:{ex.StackTrace}");
+ }
+ }
+ }
+
///
/// 获取导弹配置数据
///
@@ -262,6 +297,18 @@ namespace ThreatSource.Data
throw new KeyNotFoundException($"Target {model} not found");
}
+ ///
+ /// 获取天气配置数据
+ ///
+ /// 天气类型
+ /// 天气配置数据
+ public WeatherData GetWeather(string weatherType)
+ {
+ if (_weathers.TryGetValue(weatherType, out var data))
+ return data;
+ throw new KeyNotFoundException($"Weather {weatherType} not found");
+ }
+
///
/// 获取所有可用的导弹ID列表
///
@@ -281,5 +328,10 @@ namespace ThreatSource.Data
/// 获取所有可用的目标ID列表
///
public IEnumerable GetAvailableTargets() => _targets.Keys;
+
+ ///
+ /// 获取所有可用的天气ID列表
+ ///
+ public IEnumerable GetAvailableWeathers() => _weathers.Keys;
}
}
\ No newline at end of file
diff --git a/ThreatSource/src/Data/ThreatSourceFactory.cs b/ThreatSource/src/Data/ThreatSourceFactory.cs
index 40265ab..8a1c927 100644
--- a/ThreatSource/src/Data/ThreatSourceFactory.cs
+++ b/ThreatSource/src/Data/ThreatSourceFactory.cs
@@ -3,6 +3,7 @@ using ThreatSource.Missile;
using ThreatSource.Indicator;
using ThreatSource.Target;
using ThreatSource.Simulation;
+using AirTransmission; // 直接引用AirTransmission命名空间,以便使用WeatherCondition
namespace ThreatSource.Data
{
@@ -238,5 +239,26 @@ namespace ThreatSource.Data
throw new ArgumentException($"不支持的目标类型: {data.Type}");
}
}
+
+ ///
+ /// 创建天气实例
+ ///
+ /// 天气模型
+ /// 天气条件
+ public Weather CreateWeather(string weatherModel)
+ {
+ var data = _dataManager.GetWeather(weatherModel);
+ return new Weather(
+ data.Type,
+ data.Temperature,
+ data.RelativeHumidity,
+ data.Visibility,
+ data.Precipitation,
+ data.CO2Concentration,
+ data.Pressure,
+ data.WindSpeed,
+ data.WindDirection
+ );
+ }
}
}
\ No newline at end of file
diff --git a/ThreatSource/src/Guidance/InfraredCommandGuidanceSystem.cs b/ThreatSource/src/Guidance/InfraredCommandGuidanceSystem.cs
index b20fc30..ccf886b 100644
--- a/ThreatSource/src/Guidance/InfraredCommandGuidanceSystem.cs
+++ b/ThreatSource/src/Guidance/InfraredCommandGuidanceSystem.cs
@@ -94,7 +94,7 @@ namespace ThreatSource.Guidance
lastTrackerToTargetVector = Vector3D.Zero;
lastDesiredDirection = Vector3D.Zero;
turnRate = 0;
- InitializeJamming(guidanceConfig.JammingResistanceThreshold, new List { JammingType.Infrared });
+ InitializeJamming(guidanceConfig.JammingResistanceThreshold, [JammingType.Infrared]);
}
///
@@ -113,7 +113,14 @@ namespace ThreatSource.Guidance
base.Update(deltaTime, missilePosition, missileVelocity);
if (!IsJammed)
{
- CalculateGuidanceAcceleration(deltaTime);
+ if (HasGuidance)
+ {
+ CalculateGuidanceAcceleration(deltaTime);
+ }
+ else
+ {
+ GuidanceAcceleration = Vector3D.Zero;
+ }
}
else
{
@@ -152,43 +159,36 @@ namespace ThreatSource.Guidance
/// - 生成制导指令
/// - 限制最大加速度
///
- protected void CalculateGuidanceAcceleration(double deltaTime)
+ protected void CalculateGuidanceAcceleration(double deltaTime)
{
- if (HasGuidance)
- {
- // 计算期望飞行方向(从导弹指向目标)
- Vector3D currentDesiredDirection = (lastTrackerToTargetVector - lastTrackerToMissileVector).Normalize();
+ // 计算期望飞行方向(从导弹指向目标)
+ Vector3D currentDesiredDirection = (lastTrackerToTargetVector - lastTrackerToMissileVector).Normalize();
- // 计算当前飞行方向
- Vector3D currentDirection = Velocity.Normalize();
- // 更新转向速率
- if (lastDesiredDirection != Vector3D.Zero)
- {
- double instantTurnRate = Vector3D.CrossProduct(lastDesiredDirection, currentDesiredDirection).Magnitude() / deltaTime;
- turnRate = turnRate * (1 - TurnRateSmoothingFactor) + instantTurnRate * TurnRateSmoothingFactor;
- }
-
- // 计算带有提前量的期望方向
- Vector3D leadDirection = Vector3D.CrossProduct(currentDesiredDirection, Vector3D.CrossProduct(currentDesiredDirection, currentDirection).Normalize());
- Vector3D desiredDirectionWithLead = (currentDesiredDirection + leadDirection * turnRate * LeadTimeFactor).Normalize();
- // 计算转向轴
- Vector3D turnAxis = Vector3D.CrossProduct(currentDirection, desiredDirectionWithLead).Normalize();
- // 计算所需转向角度
- double turnAngle = Vector3D.AngleBetween(currentDirection, desiredDirectionWithLead);
- // 计算制导加速度
- double accelerationMagnitude = ProportionalNavigationCoefficient * turnAngle * Velocity.Magnitude();
- GuidanceAcceleration = Vector3D.CrossProduct(turnAxis, currentDirection) * accelerationMagnitude;
- // 限制最大加速度
- if (GuidanceAcceleration.Magnitude() > MaxAcceleration)
- {
- GuidanceAcceleration = GuidanceAcceleration.Normalize() * MaxAcceleration;
- }
- lastDesiredDirection = currentDesiredDirection;
- }
- else
+ // 计算当前飞行方向
+ Vector3D currentDirection = Velocity.Normalize();
+ // 更新转向速率
+ if (lastDesiredDirection != Vector3D.Zero)
{
- GuidanceAcceleration = Vector3D.Zero;
+ double instantTurnRate = Vector3D.CrossProduct(lastDesiredDirection, currentDesiredDirection).Magnitude() / deltaTime;
+ turnRate = turnRate * (1 - TurnRateSmoothingFactor) + instantTurnRate * TurnRateSmoothingFactor;
}
+
+ // 计算带有提前量的期望方向
+ Vector3D leadDirection = Vector3D.CrossProduct(currentDesiredDirection, Vector3D.CrossProduct(currentDesiredDirection, currentDirection).Normalize());
+ Vector3D desiredDirectionWithLead = (currentDesiredDirection + leadDirection * turnRate * LeadTimeFactor).Normalize();
+ // 计算转向轴
+ Vector3D turnAxis = Vector3D.CrossProduct(currentDirection, desiredDirectionWithLead).Normalize();
+ // 计算所需转向角度
+ double turnAngle = Vector3D.AngleBetween(currentDirection, desiredDirectionWithLead);
+ // 计算制导加速度
+ double accelerationMagnitude = ProportionalNavigationCoefficient * turnAngle * Velocity.Magnitude();
+ GuidanceAcceleration = Vector3D.CrossProduct(turnAxis, currentDirection) * accelerationMagnitude;
+ // 限制最大加速度
+ if (GuidanceAcceleration.Magnitude() > MaxAcceleration)
+ {
+ GuidanceAcceleration = GuidanceAcceleration.Normalize() * MaxAcceleration;
+ }
+ lastDesiredDirection = currentDesiredDirection;
}
///
diff --git a/ThreatSource/src/Guidance/InfraredImageGenerator.cs b/ThreatSource/src/Guidance/InfraredImageGenerator.cs
index 6c44906..9042584 100644
--- a/ThreatSource/src/Guidance/InfraredImageGenerator.cs
+++ b/ThreatSource/src/Guidance/InfraredImageGenerator.cs
@@ -1,6 +1,7 @@
using System;
using ThreatSource.Target;
using ThreatSource.Utils;
+using AirTransmission; // 添加引用
namespace ThreatSource.Guidance
{
@@ -12,6 +13,7 @@ namespace ThreatSource.Guidance
/// - 计算目标在图像平面上的投影
/// - 根据目标特性生成红外强度
/// - 添加背景噪声
+ /// - 考虑大气透过率影响
///
public class InfraredImageGenerator
{
@@ -35,6 +37,11 @@ namespace ThreatSource.Guidance
///
private readonly double backgroundIntensity;
+ ///
+ /// 红外波长,单位:微米
+ ///
+ private readonly double wavelength;
+
///
/// 随机数生成器
///
@@ -52,16 +59,19 @@ namespace ThreatSource.Guidance
/// 图像高度
/// 视场角
/// 背景辐射强度,单位:W/sr,典型地表背景约0.01-0.1 W/sr
+ /// 红外波长,单位:微米,默认为3.0(中波红外)
public InfraredImageGenerator(
int imageWidth = 640,
int imageHeight = 512,
double fieldOfView = Math.PI / 18,
- double backgroundIntensity = 0.01)
+ double backgroundIntensity = 0.01,
+ double wavelength = 3.0)
{
this.imageWidth = imageWidth;
this.imageHeight = imageHeight;
this.fieldOfView = fieldOfView;
this.backgroundIntensity = backgroundIntensity;
+ this.wavelength = wavelength;
// Initialize coordinate system with default values
forward = Vector3D.UnitZ;
@@ -77,7 +87,7 @@ namespace ThreatSource.Guidance
// 计算视线方向
forward = (targetPosition - missilePosition).Normalize();
- Console.WriteLine($"Line of sight direction: {forward}");
+ Console.WriteLine($"视线方向: {forward}");
// 选择合适的上方向
Vector3D worldUp = Math.Abs(Vector3D.DotProduct(forward, Vector3D.UnitZ)) > 0.99
@@ -105,7 +115,7 @@ namespace ThreatSource.Guidance
double angleX = Math.Atan2(x, z);
double angleY = Math.Atan2(y, z);
- Console.WriteLine($"Projection angles: X={angleX:F6} rad, Y={angleY:F6} rad");
+ Console.WriteLine($"投影角度: X={angleX:F6} 弧度, Y={angleY:F6} 弧度");
return (angleX, angleY);
}
@@ -119,20 +129,46 @@ namespace ThreatSource.Guidance
int pixelX = imageWidth/2 + (int)(angleX / pixelSize);
int pixelY = imageHeight/2 + (int)(angleY / pixelSize);
-
- Console.WriteLine($"Pixel coordinates: X={pixelX}, Y={pixelY}");
-
+
return (pixelX, pixelY);
}
+ ///
+ /// 计算大气透过率
+ ///
+ /// 距离(米)
+ /// 天气条件
+ /// 大气透过率(0-1之间)
+ private double CalculateAtmosphericTransmittance(double distance, Weather? weather)
+ {
+ double transmittance;
+
+ if (weather == null)
+ {
+ // 如果没有天气信息,使用基于距离的简化模型
+ transmittance = Math.Exp(-0.2 * distance / 1000.0); // 0.2/km的衰减率
+ return transmittance;
+ }
+
+ // 使用AtmosphereDllWrapper计算红外波段的透过率
+ transmittance = AtmosphereDllWrapper.CalculateTransmittance(
+ distance,
+ RadiationType.Infrared,
+ wavelength,
+ weather);
+
+ return transmittance;
+ }
+
///
/// 生成目标的红外图像
///
/// 目标对象
/// 导弹位置
/// 导弹速度
+ /// 天气条件
/// 红外图像
- public InfraredImage GenerateImage(ITarget target, Vector3D missilePosition, Vector3D missileVelocity)
+ public InfraredImage GenerateImage(ITarget target, Vector3D missilePosition, Vector3D missileVelocity, Weather? weather)
{
// 更新视线坐标系
UpdateLineOfSightFrame(missilePosition, target.Position);
@@ -156,14 +192,13 @@ namespace ThreatSource.Guidance
pixelLength = Math.Max(1, pixelLength);
pixelWidth = Math.Max(1, pixelWidth);
- Console.WriteLine($"Generated image for target {target.Id} with dimensions: {pixelLength}x{pixelWidth} pixels");
- Console.WriteLine($"Target center at: ({centerX}, {centerY})");
+ Console.WriteLine($"生成目标 {target.Id} 的图像,尺寸: {pixelLength}x{pixelWidth} 像素,目标中心: ({centerX}, {centerY})");
- // 生成目标图像
- GenerateTargetIntensity(image, centerX, centerY, pixelLength, pixelWidth, target, distance);
+ // 生成目标图像,传递距离参数
+ GenerateTargetIntensity(image, centerX, centerY, pixelLength, pixelWidth, target, distance, weather);
// 添加背景和噪声
- AddBackgroundAndNoise(image);
+ AddBackgroundAndNoise(image, weather);
return image;
}
@@ -178,10 +213,14 @@ namespace ThreatSource.Guidance
int pixelLength,
int pixelWidth,
ITarget target,
- double distance)
+ double distance,
+ Weather? weather)
{
- // 计算目标辐射强度
- double targetIntensity = target.InfraredRadiationIntensity / Math.Pow(distance, 1.8);
+ // 计算大气透过率
+ double transmittance = CalculateAtmosphericTransmittance(distance, weather);
+
+ // 计算目标辐射强度,考虑距离和大气透过率的影响
+ double targetIntensity = target.InfraredRadiationIntensity * transmittance / Math.Pow(distance, 1.8);
// 计算分布参数
double sigmaX = pixelLength / 6.0;
@@ -218,20 +257,41 @@ namespace ThreatSource.Guidance
}
}
- Console.WriteLine($"Target intensity distribution:");
- Console.WriteLine($" Pixels set: {pixelsSet}");
- Console.WriteLine($" Max set intensity: {maxSetIntensity:F6} W/sr");
+ Console.WriteLine($"目标强度分布: 像素设置: {pixelsSet}, 最大强度: {maxSetIntensity:F6} W/sr");
}
///
/// 添加背景辐射和噪声
///
- private void AddBackgroundAndNoise(InfraredImage image)
+ private void AddBackgroundAndNoise(InfraredImage image, Weather? weather)
{
double maxIntensityBefore = double.MinValue;
double maxIntensityAfter = double.MinValue;
int pixelsModified = 0;
+ // 根据天气条件调整背景噪声水平
+ double noiseLevel = 0.2; // 默认噪声水平
+ double bgIntensity = backgroundIntensity;
+
+ if (weather != null)
+ {
+ // 雾、雨、雪等天气增加背景噪声
+ if (weather.Type == WeatherType.Fog)
+ {
+ noiseLevel = 0.5;
+ bgIntensity *= (1.0 + (1.0 - weather.Visibility / 10.0)); // 雾增加背景辐射
+ }
+ else if (weather.Type == WeatherType.Rain || weather.Type == WeatherType.Snow)
+ {
+ noiseLevel = 0.3;
+ // 降水增加噪声水平
+ if (weather.Precipitation > 0)
+ {
+ noiseLevel += 0.1 * Math.Min(1.0, weather.Precipitation / 10.0);
+ }
+ }
+ }
+
for (int y = 0; y < image.Height; y++)
{
for (int x = 0; x < image.Width; x++)
@@ -240,14 +300,14 @@ namespace ThreatSource.Guidance
maxIntensityBefore = Math.Max(maxIntensityBefore, currentIntensity);
// 只在非目标区域添加背景
- if (currentIntensity < backgroundIntensity * 0.1)
+ if (currentIntensity < bgIntensity * 0.1)
{
- currentIntensity = backgroundIntensity;
+ currentIntensity = bgIntensity;
pixelsModified++;
}
// 添加高斯噪声
- double noise = (random.NextDouble() - 0.5) * backgroundIntensity * 0.2;
+ double noise = (random.NextDouble() - 0.5) * bgIntensity * noiseLevel;
currentIntensity += noise;
// 确保非负
diff --git a/ThreatSource/src/Guidance/InfraredImagingGuidanceSystem.cs b/ThreatSource/src/Guidance/InfraredImagingGuidanceSystem.cs
index eb70ab4..7b3c6a5 100644
--- a/ThreatSource/src/Guidance/InfraredImagingGuidanceSystem.cs
+++ b/ThreatSource/src/Guidance/InfraredImagingGuidanceSystem.cs
@@ -4,6 +4,7 @@ using ThreatSource.Target;
using ThreatSource.Utils;
using ThreatSource.Jamming;
using System.Diagnostics;
+using AirTransmission; // 添加引用
namespace ThreatSource.Guidance
{
@@ -121,13 +122,15 @@ namespace ThreatSource.Guidance
this.targetType = targetType;
this.config = guidanceConfig;
targetRecognizer = new InfraredTargetRecognizer(simulationManager);
+
+ // 首先创建图像生成器
imageGenerator = new InfraredImageGenerator(
imageWidth: guidanceConfig.ImageWidth,
imageHeight: guidanceConfig.ImageHeight,
fieldOfView: guidanceConfig.SearchFieldOfView,
backgroundIntensity: guidanceConfig.BackgroundIntensity
);
- InitializeJamming(guidanceConfig.JammingResistanceThreshold, new List { JammingType.Infrared });
+ InitializeJamming(guidanceConfig.JammingResistanceThreshold, [JammingType.Infrared]);
SwitchToSearchMode(); // 初始化为搜索模式
}
@@ -300,13 +303,15 @@ namespace ThreatSource.Guidance
currentMode = WorkMode.Search;
HasTarget = false;
targetLostTimer = 0; // 重置丢失计时器
+
+ // 创建图像生成器
imageGenerator = new InfraredImageGenerator(
imageWidth: config.ImageWidth,
imageHeight: config.ImageHeight,
fieldOfView: config.SearchFieldOfView,
backgroundIntensity: config.BackgroundIntensity
);
- Console.WriteLine($"Switched to search mode with FOV: {config.SearchFieldOfView * 180 / Math.PI} degrees");
+ Console.WriteLine($"切换到搜索模式, 视场角: {config.SearchFieldOfView * 180 / Math.PI} 度");
}
///
@@ -322,13 +327,15 @@ namespace ThreatSource.Guidance
{
currentMode = WorkMode.Track;
lockConfirmationTimer = 0; // 重置锁定确认计时器
+
+ // 创建图像生成器
imageGenerator = new InfraredImageGenerator(
imageWidth: config.ImageWidth,
imageHeight: config.ImageHeight,
fieldOfView: config.TrackFieldOfView,
backgroundIntensity: config.BackgroundIntensity
);
- Console.WriteLine($"Switched to track mode with FOV: {config.TrackFieldOfView * 180 / Math.PI} degrees");
+ Console.WriteLine($"切换到跟踪模式, 视场角: {config.TrackFieldOfView * 180 / Math.PI} 度");
}
///
@@ -386,7 +393,7 @@ namespace ThreatSource.Guidance
if (angle <= currentFov / 2)
{
// 生成红外图像
- var image = imageGenerator.GenerateImage(target, missilePosition, missileVelocity);
+ var image = imageGenerator.GenerateImage(target, missilePosition, missileVelocity, SimulationManager.CurrentWeather );
switch (currentMode)
{
diff --git a/ThreatSource/src/Guidance/InfraredTargetRecognizer.cs b/ThreatSource/src/Guidance/InfraredTargetRecognizer.cs
index f2d06f4..10895d3 100644
--- a/ThreatSource/src/Guidance/InfraredTargetRecognizer.cs
+++ b/ThreatSource/src/Guidance/InfraredTargetRecognizer.cs
@@ -118,23 +118,32 @@ namespace ThreatSource.Guidance
/// 识别结果
public RecognitionResult RecognizeTarget(InfraredImage image, ITarget target)
{
- // 1. 图像分割,提取目标区域
+ // 图像分割,提取目标区域
var segment = SegmentTarget(image);
if (!segment.IsValid)
{
- Console.WriteLine("No valid segment found in image");
+ Console.WriteLine("没有有效的分割区域");
return new RecognitionResult(TargetType.Unknown, 0.0, (0, 0), (0, 0));
}
- // 2. 提取目标特征
+ // 检查目标区域尺寸是否足够大
+ int minRequiredWidth = 10;
+ int minRequiredHeight = 5;
+ if (segment.Size.Width < minRequiredWidth && segment.Size.Height < minRequiredHeight)
+ {
+ Console.WriteLine($"目标区域过小: {segment.Size.Width}x{segment.Size.Height} 像素,低于最小要求 {minRequiredWidth}x{minRequiredHeight}");
+ return new RecognitionResult(TargetType.Unknown, 0.0, segment.Center, segment.Size);
+ }
+
+ // 提取目标特征
var features = ExtractFeatures(image, segment, target);
- Console.WriteLine($"Extracted features: AspectRatio={features.AspectRatio:F2}, Size={features.Size:F2}, IntensityPattern={features.IntensityPattern:F2}, TemperatureGradient={features.TemperatureGradient:F2}");
+ Console.WriteLine($"提取的特征: 长宽比={features.AspectRatio:F2}, 尺寸={features.Size:F2}, 强度模式={features.IntensityPattern:F2}, 温度梯度={features.TemperatureGradient:F2}");
- // 3. 特征匹配和分类
+ // 特征匹配和分类
var (type, confidence) = ClassifyTarget(features);
- Console.WriteLine($"Classification result: Type={type}, Confidence={confidence:F2}");
+ Console.WriteLine($"分类结果: 类型={type}, 置信度={confidence:F2}");
- // 4. 返回识别结果
+ // 返回识别结果
return new RecognitionResult(
type,
confidence,
@@ -172,12 +181,12 @@ namespace ThreatSource.Guidance
}
}
- Console.WriteLine($"Segmentation results:");
- Console.WriteLine($" Pixels above threshold: {pixelsAboveThreshold}");
+ Console.WriteLine($"分割结果:");
+ Console.WriteLine($" 像素超过阈值: {pixelsAboveThreshold}");
if (found)
{
- Console.WriteLine($" Target bounds: ({minX},{minY}) to ({maxX},{maxY})");
- Console.WriteLine($" Target size: {maxX - minX + 1}x{maxY - minY + 1} pixels");
+ Console.WriteLine($" 目标边界: ({minX},{minY}) 到 ({maxX},{maxY})");
+ Console.WriteLine($" 目标尺寸: {maxX - minX + 1}x{maxY - minY + 1} 像素");
}
if (!found)
@@ -225,13 +234,13 @@ namespace ThreatSource.Guidance
// 取两个基准中的较大值作为最终阈值
double threshold = Math.Max(backgroundThreshold, targetThreshold);
- Console.WriteLine($"Image statistics:");
- Console.WriteLine($" Max intensity: {maxIntensity:F6}");
- Console.WriteLine($" Min intensity: {minIntensity:F6}");
- Console.WriteLine($" Mean intensity: {mean:F6}");
- Console.WriteLine($" Background threshold: {backgroundThreshold:F6}");
- Console.WriteLine($" Target threshold: {targetThreshold:F6}");
- Console.WriteLine($" Final threshold: {threshold:F6}");
+ Console.WriteLine($"图像统计:");
+ Console.WriteLine($" 最大强度: {maxIntensity:F6}");
+ Console.WriteLine($" 最小强度: {minIntensity:F6}");
+ Console.WriteLine($" 平均强度: {mean:F6}");
+ Console.WriteLine($" 背景阈值: {backgroundThreshold:F6}");
+ Console.WriteLine($" 目标阈值: {targetThreshold:F6}");
+ Console.WriteLine($" 最终阈值: {threshold:F6}");
return threshold;
}
@@ -312,7 +321,7 @@ namespace ThreatSource.Guidance
double[,] thermalPattern = target.GetCurrentThermalPattern();
if (thermalPattern == null)
{
- Console.WriteLine("No thermal pattern available, using image-based gradient calculation");
+ Console.WriteLine("没有温度分布数据, 使用图像计算梯度");
return CalculateImageBasedGradient(image, segment);
}
@@ -320,7 +329,7 @@ namespace ThreatSource.Guidance
// 判断目标是否在运动
bool isMoving = IsTargetMoving(image, segment);
- Console.WriteLine($"Target movement status: {(isMoving ? "Moving" : "Static")}");
+ Console.WriteLine($"目标运动状态: {(isMoving ? "移动" : "静止")}");
// 使用温度分布模式计算梯度特征
double gradientFeature = pattern.CalculateGradientFeature(isMoving);
@@ -550,7 +559,7 @@ namespace ThreatSource.Guidance
foreach (var kvp in targetFeatures)
{
double score = CalculateMatchScore(features, kvp.Value, weights);
- Console.WriteLine($"Match score for {kvp.Key}: {score:F2}");
+ Console.WriteLine($"匹配得分: {kvp.Key}: {score:F2}");
if (score > bestScore)
{
bestScore = score;
@@ -560,7 +569,7 @@ namespace ThreatSource.Guidance
// 使用自适应阈值
double threshold = CalculateAdaptiveThreshold(features);
- Console.WriteLine($"Adaptive threshold: {threshold:F2}");
+ Console.WriteLine($"自适应阈值: {threshold:F2}");
return bestScore > threshold ?
(bestMatch, bestScore) :
@@ -613,11 +622,11 @@ namespace ThreatSource.Guidance
double gradientScore = 1 - Math.Min(1, Math.Abs(features.TemperatureGradient - template.TemperatureGradient));
// 输出详细的匹配分数
- Console.WriteLine($"Feature match scores:");
- Console.WriteLine($" Aspect Ratio: {aspectRatioScore:F2} (weight: {weights[0]:F2})");
- Console.WriteLine($" Size: {sizeScore:F2} (weight: {weights[1]:F2})");
- Console.WriteLine($" Pattern: {patternScore:F2} (weight: {weights[2]:F2})");
- Console.WriteLine($" Gradient: {gradientScore:F2} (weight: {weights[3]:F2})");
+ Console.WriteLine($"特征匹配得分:");
+ Console.WriteLine($" 长宽比: {aspectRatioScore:F2} (权重: {weights[0]:F2})");
+ Console.WriteLine($" 尺寸: {sizeScore:F2} (权重: {weights[1]:F2})");
+ Console.WriteLine($" 模式: {patternScore:F2} (权重: {weights[2]:F2})");
+ Console.WriteLine($" 梯度: {gradientScore:F2} (权重: {weights[3]:F2})");
// 加权平均
double totalScore = aspectRatioScore * weights[0] +
@@ -625,7 +634,7 @@ namespace ThreatSource.Guidance
patternScore * weights[2] +
gradientScore * weights[3];
- Console.WriteLine($" Total Score: {totalScore:F2}");
+ Console.WriteLine($" 总得分: {totalScore:F2}");
return totalScore;
}
diff --git a/ThreatSource/src/Guidance/LaserBeamRiderGuidanceSystem.cs b/ThreatSource/src/Guidance/LaserBeamRiderGuidanceSystem.cs
index 6e4a2c4..f9c8108 100644
--- a/ThreatSource/src/Guidance/LaserBeamRiderGuidanceSystem.cs
+++ b/ThreatSource/src/Guidance/LaserBeamRiderGuidanceSystem.cs
@@ -2,6 +2,7 @@ using ThreatSource.Utils;
using ThreatSource.Simulation;
using System.Diagnostics;
using ThreatSource.Jamming;
+using AirTransmission;
namespace ThreatSource.Guidance
{
@@ -193,7 +194,7 @@ namespace ThreatSource.Guidance
IsCodeEnabled = true,
IsCodeMatchRequired = true
};
- InitializeJamming(guidanceConfig.JammingResistanceThreshold, new List { JammingType.Laser });
+ InitializeJamming(guidanceConfig.JammingResistanceThreshold, [JammingType.Laser]);
}
///
@@ -404,6 +405,7 @@ namespace ThreatSource.Guidance
}
else
{
+ HasGuidance = false;
GuidanceAcceleration = Vector3D.Zero;
}
}
@@ -482,8 +484,19 @@ namespace ThreatSource.Guidance
double receivedPower = powerDensity * detectorArea;
// 考虑大气衰减(可选)
- // double atmosphericTransmittance = Math.Exp(-attenuationCoefficient * distance);
- // receivedPower *= atmosphericTransmittance;
+ // 计算大气透过率,如果当前天气为null,则认为大气透过率为1.0
+ double atmosphericTransmittance = 1.0;
+
+ if(SimulationManager.CurrentWeather != null)
+ {
+ atmosphericTransmittance = AtmosphereDllWrapper.CalculateTransmittance(
+ distance,
+ RadiationType.Laser,
+ config.LaserWavelength,
+ SimulationManager.CurrentWeather);
+ }
+
+ receivedPower *= atmosphericTransmittance;
return receivedPower;
}
@@ -504,12 +517,6 @@ namespace ThreatSource.Guidance
///
protected void CalculateGuidanceAcceleration(double deltaTime)
{
- if (!HasGuidance)
- {
- GuidanceAcceleration = Vector3D.Zero;
- return;
- }
-
// 计算导弹到激光束的最短距离
Vector3D shortestDistanceVector = CalculateShortestDistanceToLaserBeam();
diff --git a/ThreatSource/src/Guidance/LaserSemiActiveGuidanceSystem.cs b/ThreatSource/src/Guidance/LaserSemiActiveGuidanceSystem.cs
index 743a30c..0b35187 100644
--- a/ThreatSource/src/Guidance/LaserSemiActiveGuidanceSystem.cs
+++ b/ThreatSource/src/Guidance/LaserSemiActiveGuidanceSystem.cs
@@ -4,9 +4,7 @@ using ThreatSource.Sensor;
using ThreatSource.Indicator;
using System.Diagnostics;
using ThreatSource.Jamming;
-using System;
-using System.Collections.Generic;
-using System.Linq;
+using AirTransmission;
namespace ThreatSource.Guidance
{
@@ -34,6 +32,15 @@ namespace ThreatSource.Guidance
///
private Vector3D TargetPosition { get; set; }
+ ///
+ /// 获取或设置接收到的激光功率
+ ///
+ ///
+ /// 记录接收到的激光功率
+ /// 用于制导计算
+ ///
+ private double ReceivedLaserPower { get; set; }
+
///
/// 获取或设置激光照射状态
///
@@ -43,33 +50,6 @@ namespace ThreatSource.Guidance
///
private bool LaserIlluminationOn { get; set; }
- ///
- /// 获取或设置激光指示器位置
- ///
- ///
- /// 记录激光发射源的三维位置
- /// 用于功率计算
- ///
- private Vector3D LaserDesignatorPosition { get; set; }
-
- ///
- /// 获取或设置激光功率,单位:瓦特
- ///
- ///
- /// 记录激光源的发射功率
- /// 影响系统的探测距离
- ///
- private double LaserPower { get; set; }
-
- ///
- /// 获取或设置激光发散角,单位:弧度
- ///
- ///
- /// 记录激光束的发散角度
- /// 影响光斑大小和功率密度
- ///
- private double LaserDivergenceAngle { get; set; }
-
///
/// 获取或设置期望的激光编码
///
@@ -87,12 +67,12 @@ namespace ThreatSource.Guidance
/// 定义导弹支持的编码类型
/// 默认支持PRF、PPM和PWM编码
///
- private readonly List supportedCodeTypes = new List
- {
+ private readonly List supportedCodeTypes =
+ [
LaserCodeType.PRF,
LaserCodeType.PPM,
LaserCodeType.PWM
- };
+ ];
///
/// 四象限探测器实例
@@ -110,29 +90,32 @@ namespace ThreatSource.Guidance
///
/// 定义了四象限探测器对光斑偏移的响应灵敏度
/// 影响制导系统的响应速度和稳定性
- /// 典型值为0.5
+ /// 典型值为0.05
///
- private double SpotOffsetSensitivity { get; set; } = 0.5;
+ private double SpotOffsetSensitivity { get; set; } = 0.05;
///
- /// 当前跟踪的目标ID
+ /// 上一次的制导加速度,用于平滑处理
///
- private string? CurrentTargetId { get; set; }
+ ///
+ /// 用于实现加速度平滑处理
+ /// 减少加速度突变,使导弹飞行更稳定
+ ///
+ private Vector3D PreviousGuidanceAcceleration { get; set; } = Vector3D.Zero;
///
- /// 激光源列表,包括真实目标和诱偏目标
+ /// 加速度平滑系数
///
- private readonly List<(SimulationElement Source, Vector3D Position, double Power)> laserSources = [];
+ ///
+ /// 范围(0,1],值越小平滑效果越强
+ /// 影响加速度的平滑程度
+ ///
+ private const double AccelerationSmoothingFactor = 0.5;
///
- /// 上次更新激光源的时间
+ /// 激光目标列表,包括真实目标和诱偏目标
///
- private DateTime LastLaserSourceUpdateTime { get; set; } = DateTime.MinValue;
-
- ///
- /// 激光源更新间隔,单位:秒
- ///
- private double LaserSourceUpdateInterval { get; set; } = 0.1;
+ private readonly List<(SimulationElement Target, SimulationElement Source)> laserTargets = [];
///
/// 初始化激光半主动制导系统的新实例
@@ -164,8 +147,6 @@ namespace ThreatSource.Guidance
TargetPosition = Vector3D.Zero;
LaserIlluminationOn = false;
- LaserDesignatorPosition = Vector3D.Zero;
- LaserPower = 0;
InternalLaserCodeConfig = laserCodeConfig;
// 创建四象限探测器实例,使用配置中的参数
@@ -177,7 +158,10 @@ namespace ThreatSource.Guidance
// 设置光斑偏移灵敏度
SpotOffsetSensitivity = config.SpotOffsetSensitivity;
- InitializeJamming(guidanceConfig.JammingResistanceThreshold, new List { JammingType.Laser });
+ // 初始化加速度平滑处理
+ PreviousGuidanceAcceleration = Vector3D.Zero;
+
+ InitializeJamming(guidanceConfig.JammingResistanceThreshold, [JammingType.Laser]);
}
///
@@ -193,11 +177,13 @@ namespace ThreatSource.Guidance
{
base.Activate();
// 订阅激光照射事件
- SimulationManager.SubscribeToEvent(OnLaserIlluminationStart);
SimulationManager.SubscribeToEvent(OnLaserIlluminationUpdate);
SimulationManager.SubscribeToEvent(OnLaserIlluminationStop);
// 订阅激光干扰事件
SimulationManager.SubscribeToEvent(OnLaserJamming);
+
+ // 订阅诱偏目标照射事件
+ SimulationManager.SubscribeToEvent(OnDecoyTargetIllumination);
}
///
@@ -212,41 +198,14 @@ namespace ThreatSource.Guidance
{
base.Deactivate();
// 取消订阅激光照射事件
- SimulationManager.UnsubscribeFromEvent(OnLaserIlluminationStart);
SimulationManager.UnsubscribeFromEvent(OnLaserIlluminationUpdate);
SimulationManager.UnsubscribeFromEvent(OnLaserIlluminationStop);
- SimulationManager.UnsubscribeFromEvent(OnLaserJamming);
- }
- ///
- /// 处理激光照射开始事件
- ///
- /// 激光照射开始事件
- private void OnLaserIlluminationStart(LaserIlluminationStartEvent evt)
- {
- if (evt?.LaserDesignatorId != null && evt?.TargetId != null)
- {
- try
- {
- LaserDesignator laserDesignator = SimulationManager.GetEntityById(evt.LaserDesignatorId) as LaserDesignator ?? throw new Exception("激光指示器不存在");
- SimulationElement target = SimulationManager.GetEntityById(evt.TargetId) as SimulationElement ?? throw new Exception("目标不存在");
-
- // 更新激光指示器信息
- UpdateLaserDesignator(laserDesignator.Position, target.Position,
- laserDesignator.LaserPower, laserDesignator.LaserDivergenceAngle);
-
- // 处理激光照射开始事件
- ProcessLaserIlluminationEvent(evt);
- }
- catch (Exception ex)
- {
- Trace.WriteLine($"处理激光照射开始事件时出错: {ex.Message}");
- }
- }
- else
- {
- Trace.WriteLine("警告:激光照射开始事件缺少必要参数");
- }
+ // 取消订阅激光干扰事件
+ SimulationManager.UnsubscribeFromEvent(OnLaserJamming);
+
+ // 取消订阅诱偏目标照射事件
+ SimulationManager.UnsubscribeFromEvent(OnDecoyTargetIllumination);
}
///
@@ -261,11 +220,13 @@ namespace ThreatSource.Guidance
{
LaserDesignator laserDesignator = SimulationManager.GetEntityById(evt.LaserDesignatorId) as LaserDesignator ?? throw new Exception("激光指示器不存在");
SimulationElement target = SimulationManager.GetEntityById(evt.TargetId) as SimulationElement ?? throw new Exception("目标不存在");
-
- // 更新激光指示器信息
- UpdateLaserDesignator(laserDesignator.Position, target.Position,
- laserDesignator.LaserPower, laserDesignator.LaserDivergenceAngle);
+ // 添加激光目标
+ if (!laserTargets.Any(t => t.Target.Id == target.Id))
+ {
+ laserTargets.Add((target, laserDesignator));
+ }
+
// 处理激光照射更新事件
ProcessLaserIlluminationUpdateEvent(evt);
}
@@ -285,12 +246,29 @@ namespace ThreatSource.Guidance
///
/// 激光照射停止事件
private void OnLaserIlluminationStop(LaserIlluminationStopEvent evt)
- {
- // 停用激光指示器
- DeactivateLaserDesignator();
-
+ {
LaserIlluminationOn = false;
HasGuidance = false; // 禁用制导
+ PreviousGuidanceAcceleration = Vector3D.Zero; // 重置历史加速度
+ }
+
+ ///
+ /// 处理诱偏目标照射事件
+ ///
+ /// 诱偏目标照射事件
+ private void OnDecoyTargetIllumination(DecoyTargetIlluminationEvent evt)
+ {
+ if (evt?.DecoyTargetId != null)
+ {
+ DecoyTarget decoyTarget = SimulationManager.GetEntityById(evt.DecoyTargetId) as DecoyTarget ?? throw new Exception("诱偏目标不存在");
+ SimulationElement decoySource = SimulationManager.GetEntityById(decoyTarget.SourceId) as SimulationElement ?? throw new Exception("诱偏源不存在");
+
+ if (!laserTargets.Any(t => t.Target.Id == decoyTarget.Id))
+ {
+ laserTargets.Add((decoyTarget, decoySource));
+ }
+ Console.WriteLine($"诱偏目标照射事件,诱偏目标ID: {evt.DecoyTargetId},诱偏源ID: {decoySource.Id},诱偏目标位置: {decoyTarget.Position}");
+ }
}
///
@@ -344,6 +322,7 @@ namespace ThreatSource.Guidance
{
LaserIlluminationOn = false;
HasGuidance = false;
+ PreviousGuidanceAcceleration = Vector3D.Zero; // 重置历史加速度
}
}
}
@@ -362,49 +341,6 @@ namespace ThreatSource.Guidance
}
}
- ///
- /// 更新激光指示器参数
- ///
- /// 激光源位置,单位:米
- /// 目标位置,单位:米
- /// 激光功率,单位:瓦特
- /// 激光发散角,单位:弧度
- ///
- /// 更新过程:
- /// - 激活激光照射
- /// - 更新位置信息
- /// - 更新目标信息
- /// - 更新激光参数
- ///
- public void UpdateLaserDesignator(Vector3D sourcePosition, Vector3D targetPosition, double laserPower, double laserDivergenceAngle)
- {
- LaserIlluminationOn = true;
- LaserDesignatorPosition = sourcePosition;
- TargetPosition = targetPosition;
- LaserPower = laserPower;
- LaserDivergenceAngle = laserDivergenceAngle;
- }
-
- ///
- /// 关闭激光照射系统
- ///
- ///
- /// 关闭过程:
- /// - 停止激光照射
- /// - 清除位置信息
- /// - 清除目标信息
- /// - 清除激光参数
- /// - 重置光斑偏移标志
- ///
- public void DeactivateLaserDesignator()
- {
- LaserIlluminationOn = false;
- LaserDesignatorPosition = Vector3D.Zero;
- TargetPosition = Vector3D.Zero;
- LaserPower = 0;
- LaserDivergenceAngle = 0;
- }
-
///
/// 更新制导系统的状态和计算结果
///
@@ -416,16 +352,9 @@ namespace ThreatSource.Guidance
base.Update(deltaTime, missilePosition, missileVelocity);
if (!IsJammed)
- {
- // 定期更新视野内的激光源
- if ((DateTime.Now - LastLaserSourceUpdateTime).TotalSeconds >= LaserSourceUpdateInterval)
- {
- UpdateLaserSources();
- LastLaserSourceUpdateTime = DateTime.Now;
- }
-
+ {
// 处理接收到的所有激光信号
- ProcessLaserSignals();
+ ProcessLaserTargets();
if (LaserIlluminationOn)
{
@@ -439,138 +368,102 @@ namespace ThreatSource.Guidance
else
{
GuidanceAcceleration = Vector3D.Zero;
+ PreviousGuidanceAcceleration = Vector3D.Zero; // 重置历史加速度
}
}
else
{
HasGuidance = false;
GuidanceAcceleration = Vector3D.Zero;
+ PreviousGuidanceAcceleration = Vector3D.Zero; // 重置历史加速度
}
}
else
{
HasGuidance = false;
GuidanceAcceleration = Vector3D.Zero;
- }
- }
-
- ///
- /// 更新视野内的激光源
- ///
- ///
- /// 收集视野内的所有激光源,包括真实目标和诱偏目标
- ///
- private void UpdateLaserSources()
- {
- try
- {
- // 清空现有激光源
- laserSources.Clear();
-
- // 如果当前有激光照射的真实目标,添加到激光源列表
- if (TargetPosition != Vector3D.Zero && LaserIlluminationOn)
- {
- if (SimulationManager.GetEntityById(CurrentTargetId ?? "") is SimulationElement targetEntity)
- {
- laserSources.Add((targetEntity, TargetPosition, LaserPower));
- }
- }
-
- // 获取所有诱偏目标
- var decoyTargets = SimulationManager.GetEntitiesByType();
- foreach (var decoy in decoyTargets)
- {
- if (decoy.IsActive())
- {
- laserSources.Add((decoy, decoy.Position, decoy.DecoyPower));
- }
- }
-
- Debug.WriteLine($"更新激光源: 共{laserSources.Count}个激光源");
- }
- catch (Exception ex)
- {
- Trace.WriteLine($"更新激光源时出错: {ex.Message}");
+ PreviousGuidanceAcceleration = Vector3D.Zero; // 重置历史加速度
}
}
///
- /// 处理接收到的所有激光信号
+ /// 处理接收到的所有激光目标
///
///
- /// 基于接收到的激光信号计算合成光斑位置
+ /// 基于接收到的激光目标计算合成光斑位置
///
- private void ProcessLaserSignals()
+ private void ProcessLaserTargets()
{
try
{
+ Console.WriteLine($"处理激光信号: 激光目标数量={laserTargets.Count}");
+
// 如果没有激光源,返回
- if (laserSources.Count == 0)
+ if (laserTargets.Count == 0)
{
LaserIlluminationOn = false;
return;
}
// 计算所有激光源的总接收功率和加权位置
- double totalPower = 0;
+ ReceivedLaserPower = 0.0;
Vector3D weightedPosition = Vector3D.Zero;
- Vector3D weightedSourcePosition = Vector3D.Zero;
- double weightedPower = 0;
- foreach (var source in laserSources)
+ foreach (var target in laserTargets)
{
- // 计算接收功率
- double receivedPower = CalculateReceivedPower(source.Position);
-
// 计算角度偏差,判断是否在视野范围内
- double angleDeviation = CalculateAngleDeviation(source.Position);
+ double angleDeviation = CalculateAngleDeviation(target.Target.Position);
if (angleDeviation > config.FieldOfViewAngleInRadians / 2)
{
+ Console.WriteLine($"处理激光信号: 目标超出视野范围,目标ID: {target.Target.Id}");
continue; // 目标超出视野范围
}
+
+ double receivedPower = 0;
+ Console.WriteLine($"处理激光信号: 目标ID: {target.Target.Id}");
+ if (target.Target is DecoyTarget decoy)
+ {
+ // 计算接收功率
+ receivedPower = CalculateReceivedPower(target.Source.Position, target.Target.Position, decoy.DecoyPower, decoy.DecoyLaserDivergenceAngle);
+ Console.WriteLine($"处理激光信号: 诱偏目标接收功率={receivedPower:E}W, 诱偏目标ID: {target.Target.Id}");
+ }
+ else if (target.Source is LaserDesignator laserDesignator)
+ {
+ // 计算接收功率
+ receivedPower = CalculateReceivedPower(target.Source.Position, target.Target.Position, laserDesignator.LaserPower, laserDesignator.LaserDivergenceAngle);
+ Console.WriteLine($"处理激光信号: 真实目标接收功率={receivedPower:E}W, 真实目标ID: {target.Target.Id}");
+ }
// 累加功率
- totalPower += receivedPower;
+ ReceivedLaserPower += receivedPower;
+ Console.WriteLine($"处理激光信号: 总功率={ReceivedLaserPower:E}W");
// 加权位置
- weightedPosition += source.Position * receivedPower;
-
- // 如果是诱偏目标,获取其诱偏源位置和功率
- if (source.Source is DecoyTarget decoy)
- {
- weightedSourcePosition += decoy.SourcePosition * receivedPower;
- weightedPower += decoy.DecoyPower * receivedPower;
- }
- else
- {
- // 对于真实目标,使用已知的LaserDesignatorPosition
- weightedSourcePosition += LaserDesignatorPosition * receivedPower;
- weightedPower += LaserPower * receivedPower;
- }
+ weightedPosition += target.Target.Position * receivedPower;
+ Console.WriteLine($"处理激光信号: 加权位置={weightedPosition}");
}
// 如果总功率为0,表示没有在视野范围内的激光源
- if (totalPower <= 0)
+ if (ReceivedLaserPower <= 0)
{
LaserIlluminationOn = false;
return;
}
// 计算加权平均位置
- TargetPosition = weightedPosition / totalPower;
+ TargetPosition = weightedPosition / ReceivedLaserPower;
+
+ Console.WriteLine($"处理激光信号: 总功率={ReceivedLaserPower:E}W, 加权平均目标位置={TargetPosition}");
// 更新激光照射参数
- LaserIlluminationOn = true;
- LaserDesignatorPosition = weightedSourcePosition / totalPower;
- LaserPower = weightedPower / totalPower;
-
+ LaserIlluminationOn = true;
// 计算光斑偏移
Vector2D spotOffset = CalculateSpotOffset();
// 将合成激光信号传递给四象限探测器
- quadrantDetector.ProcessLaserSignal(totalPower, spotOffset);
+ quadrantDetector.ProcessLaserSignal(ReceivedLaserPower, spotOffset);
- Debug.WriteLine($"处理激光信号: 总功率={totalPower:E}W, 目标位置={TargetPosition}");
+ Debug.WriteLine($"处理激光信号: 总功率={ReceivedLaserPower:E}W, 目标位置={TargetPosition}");
}
catch (Exception ex)
{
@@ -581,18 +474,41 @@ namespace ThreatSource.Guidance
///
/// 计算从特定位置接收到的激光功率
///
+ /// 激光源位置
/// 目标位置
+ /// 激光功率
+ /// 激光发散角
/// 接收到的激光功率,单位:瓦特
- private double CalculateReceivedPower(Vector3D targetPos)
+ private double CalculateReceivedPower(Vector3D sourcePos, Vector3D targetPos, double laserPower, double laserDivergenceAngle)
{
- double distanceDesignatorToTarget = (LaserDesignatorPosition - targetPos).Magnitude();
+ double distanceDesignatorToTarget = (sourcePos - targetPos).Magnitude();
double distanceMissileToTarget = (Position - targetPos).Magnitude();
+ // 计算大气透过率 (1.使用从激光源到目标的单程透过率,2.使用从目标到导弹的单程透过率)
+ // 如果当前天气为null,则认为大气透过率为1.0
+ double atmosphericTransmittanceToTarget = 1.0;
+ double atmosphericTransmittanceToMissile = 1.0;
+
+ if(SimulationManager.CurrentWeather != null)
+ {
+ atmosphericTransmittanceToTarget = AtmosphereDllWrapper.CalculateTransmittance(
+ distanceDesignatorToTarget,
+ RadiationType.Laser,
+ config.LaserWavelength,
+ SimulationManager.CurrentWeather);
+
+ atmosphericTransmittanceToMissile = AtmosphereDllWrapper.CalculateTransmittance(
+ distanceMissileToTarget,
+ RadiationType.Laser,
+ config.LaserWavelength,
+ SimulationManager.CurrentWeather);
+ }
+
// 计算目标处的光斑面积
- double spotAreaAtTarget = Math.PI * Math.Pow(distanceDesignatorToTarget * Math.Tan(LaserDivergenceAngle), 2);
+ double spotAreaAtTarget = Math.PI * Math.Pow(distanceDesignatorToTarget * Math.Tan(laserDivergenceAngle), 2);
- // 计算目标处的激光功率密度
- double powerDensityAtTarget = LaserPower / spotAreaAtTarget;
+ // 计算目标处的激光功率密度,考虑大气衰减和发射系统透过率
+ double powerDensityAtTarget = laserPower * atmosphericTransmittanceToTarget * config.TransmitterEfficiency / spotAreaAtTarget;
// 计算从目标反射的总功率
double reflectedPower = powerDensityAtTarget * config.TargetReflectiveArea * config.ReflectionCoefficient;
@@ -600,8 +516,8 @@ namespace ThreatSource.Guidance
// 计算反射光在导弹处的扩散面积(假设漫反射)
double reflectedSpotArea = 2 * Math.PI * Math.Pow(distanceMissileToTarget, 2);
- // 计算导弹接收到的功率
- double receivedPower = reflectedPower / reflectedSpotArea;
+ // 计算导弹接收到的功率,考虑大气衰减和接收系统透过率
+ double receivedPower = reflectedPower * atmosphericTransmittanceToMissile * config.ReceiverEfficiency / reflectedSpotArea;
// 计算镜头接收到的功率比例
double lensArea = Math.PI * Math.Pow(config.LensDiameter / 2, 2);
@@ -615,6 +531,10 @@ namespace ThreatSource.Guidance
// 计算最终接收到的功率
double finalReceivedPower = receivedPower * powerRatio * focusingFactor;
+
+ Debug.WriteLine($"激光功率计算: 源->目标距离={distanceDesignatorToTarget:F1}m (透过率={atmosphericTransmittanceToTarget:F3}), " +
+ $"目标->导弹距离={distanceMissileToTarget:F1}m (透过率={atmosphericTransmittanceToMissile:F3}), " +
+ $"最终功率={finalReceivedPower:E}W");
return finalReceivedPower;
}
@@ -698,6 +618,7 @@ namespace ThreatSource.Guidance
/// - 使用四象限探测器获取目标方向
/// - 计算比例导引加速度
/// - 限制最大加速度
+ /// - 应用加速度平滑处理
///
protected void CalculateGuidanceAcceleration(double deltaTime)
{
@@ -719,15 +640,22 @@ namespace ThreatSource.Guidance
guidanceDirection = guidanceDirection.Normalize() * 0.01;
}
- // 计算制导加速度,与速度垂直
- GuidanceAcceleration = guidanceDirection * ProportionalNavigationCoefficient * Velocity.Magnitude();
+ // 计算新的制导加速度,与速度垂直
+ Vector3D newGuidanceAcceleration = guidanceDirection * ProportionalNavigationCoefficient * Velocity.Magnitude();
// 限制最大加速度
double maxAcceleration = MaxAcceleration;
- if (GuidanceAcceleration.Magnitude() > maxAcceleration)
+ if (newGuidanceAcceleration.Magnitude() > maxAcceleration)
{
- GuidanceAcceleration = GuidanceAcceleration.Normalize() * maxAcceleration;
+ newGuidanceAcceleration = newGuidanceAcceleration.Normalize() * maxAcceleration;
}
+
+ // 应用加速度平滑处理
+ GuidanceAcceleration = PreviousGuidanceAcceleration * (1 - AccelerationSmoothingFactor) +
+ newGuidanceAcceleration * AccelerationSmoothingFactor;
+
+ // 保存当前加速度用于下次平滑计算
+ PreviousGuidanceAcceleration = GuidanceAcceleration;
}
///
@@ -745,8 +673,7 @@ namespace ThreatSource.Guidance
public override string GetStatus()
{
return base.GetStatus() +
- $" 激光目标指示器功率: {LaserPower}," +
- $" 接收到的激光功率: {CalculateReceivedPower(TargetPosition):E} W," +
+ $" 接收到的激光功率: {ReceivedLaserPower:E} W," +
$" 锁定阈值: {config.LockThreshold:E} W," +
$" 四象限探测器: {quadrantDetector.GetStatus()}";
}
@@ -845,28 +772,6 @@ namespace ThreatSource.Guidance
}
}
- ///
- /// 处理激光照射事件
- ///
- /// 激光照射事件
- ///
- /// 处理过程:
- /// - 检查编码是否匹配
- /// - 如果要求匹配且不匹配,则忽略信号
- /// - 如果匹配或不要求匹配,则处理信号
- /// - 更新激光照射状态
- /// - 计算接收到的激光功率
- /// - 计算光斑偏移并传递给四象限探测器
- /// - 根据四象限探测器的锁定状态更新制导状态
- ///
- public void ProcessLaserIlluminationEvent(LaserIlluminationStartEvent illuminationEvent)
- {
- ProcessLaserIlluminationCommon(
- illuminationEvent.LaserDesignatorId,
- illuminationEvent.LaserCodeConfig,
- true); // 初始照射
- }
-
///
/// 处理激光照射更新事件
///
@@ -877,74 +782,29 @@ namespace ThreatSource.Guidance
/// - 如果要求匹配且不匹配,则忽略信号
/// - 如果匹配或不要求匹配,则处理信号
/// - 更新激光照射状态
- /// - 计算接收到的激光功率
- /// - 计算光斑偏移并传递给四象限探测器
- /// - 根据四象限探测器的锁定状态更新制导状态
///
public void ProcessLaserIlluminationUpdateEvent(LaserIlluminationUpdateEvent illuminationEvent)
{
- ProcessLaserIlluminationCommon(
- illuminationEvent.LaserDesignatorId,
- illuminationEvent.LaserCodeConfig,
- false); // 更新照射
- }
-
- ///
- /// 处理激光照射事件的共同逻辑
- ///
- /// 激光指示器ID
- /// 激光编码配置
- /// 是否是初始照射(开始事件)
- ///
- /// 处理过程:
- /// - 检查编码是否匹配
- /// - 如果要求匹配且不匹配,则忽略信号
- /// - 如果匹配或不要求匹配,则处理信号
- /// - 更新激光照射状态
- /// - 计算接收到的激光功率
- /// - 计算光斑偏移并传递给四象限探测器
- /// - 根据四象限探测器的锁定状态更新制导状态
- ///
- private void ProcessLaserIlluminationCommon(string? laserDesignatorId,
- LaserCodeConfig? laserCodeConfig, bool isInitialIllumination)
- {
- if (laserCodeConfig != null)
+ if (illuminationEvent.LaserCodeConfig != null)
{
- bool codeMatched = InternalLaserCodeConfig?.CheckCodeMatch(laserCodeConfig) ?? false;
+ bool codeMatched = InternalLaserCodeConfig?.CheckCodeMatch(illuminationEvent.LaserCodeConfig) ?? false;
if (!codeMatched)
{
// 发布编码不匹配事件
- PublishCodeMismatchEvent(laserDesignatorId, laserCodeConfig);
+ PublishCodeMismatchEvent(illuminationEvent.LaserDesignatorId, illuminationEvent.LaserCodeConfig);
Trace.WriteLine("激光半主动制导系统接收到不匹配的激光编码,忽略信号");
HasGuidance = false; // 禁用制导
LaserIlluminationOn = false; // 禁用激光照射状态,确保四象限探测器不处理信号
// 重置四象限探测器状态
quadrantDetector.ProcessLaserSignal(0, new Vector2D(0, 0));
+ PreviousGuidanceAcceleration = Vector3D.Zero; // 重置历史加速度
return;
}
else
- {
- // 如果编码匹配,继续处理
- // 只有在初始照射或激光尚未开启时才发布编码匹配事件
- if (isInitialIllumination || !LaserIlluminationOn)
- {
- // 发布编码匹配事件
- PublishCodeMatchEvent(laserDesignatorId, laserCodeConfig);
- }
-
+ {
// 更新激光照射状态
LaserIlluminationOn = true;
-
- // 计算接收到的激光功率
- double receivedPower = CalculateReceivedPower(TargetPosition);
-
- // 计算光斑偏移并传递给四象限探测器
- Vector2D spotOffset = CalculateSpotOffset();
- quadrantDetector.ProcessLaserSignal(receivedPower, spotOffset);
-
- // 更新制导状态 - 根据四象限探测器的锁定状态
- HasGuidance = quadrantDetector.IsTargetLocked;
}
}
}
@@ -964,29 +824,6 @@ namespace ThreatSource.Guidance
HasGuidance = false; // 禁用制导
}
- ///
- /// 发布编码匹配事件
- ///
- /// 激光定位器ID
- /// 匹配的编码配置
- ///
- /// 发布过程:
- /// - 创建事件对象
- /// - 设置事件属性
- /// - 发布到事件系统
- ///
- private void PublishCodeMatchEvent(string? designatorId, LaserCodeConfig? matchedCodeConfig)
- {
- var matchEvent = new LaserCodeMatchEvent
- {
- MissileId = ParentId,
- DesignatorId = designatorId,
- MatchedCodeConfig = matchedCodeConfig
- };
-
- PublishEvent(matchEvent);
- }
-
///
/// 发布编码不匹配事件
///
diff --git a/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs b/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs
index 9ad2f2a..1672411 100644
--- a/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs
+++ b/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs
@@ -3,6 +3,7 @@ using ThreatSource.Utils;
using ThreatSource.Target;
using System.Diagnostics;
using ThreatSource.Jamming;
+using AirTransmission;
namespace ThreatSource.Guidance
{
@@ -161,7 +162,7 @@ namespace ThreatSource.Guidance
lastTargetPosition = Vector3D.Zero;
lastTargetVelocity = Vector3D.Zero;
- InitializeJamming(config.JammingResistanceThreshold, new List { JammingType.MillimeterWave });
+ InitializeJamming(config.JammingResistanceThreshold, [JammingType.MillimeterWave]);
SwitchToSearchMode(); // 初始化为搜索模式
}
@@ -696,6 +697,20 @@ namespace ThreatSource.Guidance
double signalPower = (transmitPower * Math.Pow(antennaGain, 2) * Math.Pow(wavelength, 2) * radarCrossSection)
/ (Math.Pow(4 * Math.PI, 3) * Math.Pow(distance, 4) * totalLoss);
+ // 考虑大气透过率,如果当前天气为null,则认为大气透过率为1.0
+ double atmosphericTransmittance = 1.0;
+
+ if(SimulationManager.CurrentWeather != null)
+ {
+ atmosphericTransmittance = AtmosphereDllWrapper.CalculateTransmittance(
+ distance,
+ RadiationType.MillimeterWave,
+ wavelength,
+ SimulationManager.CurrentWeather);
+ }
+
+ signalPower *= atmosphericTransmittance;
+
// 计算噪声功率
double noisePower = k * T0 * bandwidth * noiseFigure;
diff --git a/ThreatSource/src/Indicator/LaserDesignator.cs b/ThreatSource/src/Indicator/LaserDesignator.cs
index d1d94e6..e9c3bfc 100644
--- a/ThreatSource/src/Indicator/LaserDesignator.cs
+++ b/ThreatSource/src/Indicator/LaserDesignator.cs
@@ -79,22 +79,13 @@ namespace ThreatSource.Indicator
public LaserCodeConfig LaserCodeConfig { get; set; }
///
- /// 获取或设置最小工作波长,单位:微米
+ /// 获取或设置工作波长,单位:微米
///
///
- /// 指示器工作所需的最小波长
+ /// 指示器工作所需的工作波长
/// 用于波长范围匹配检查
///
- public double MinWavelength { get; private set; } = 1.0;
-
- ///
- /// 获取或设置最大工作波长,单位:微米
- ///
- ///
- /// 指示器工作所需的最大波长
- /// 用于波长范围匹配检查
- ///
- public double MaxWavelength { get; private set; } = 1.1;
+ public double Wavelength { get; private set; } = 1.06;
///
/// 初始化激光指示器的新实例
@@ -123,8 +114,7 @@ namespace ThreatSource.Indicator
LaserDivergenceAngle = config.LaserDivergenceAngle;
LaserCodeConfig = config.LaserCodeConfig;
JammingThreshold = config.JammingResistanceThreshold;
- MinWavelength = config.MinWavelength;
- MaxWavelength = config.MaxWavelength;
+ Wavelength = config.LaserWavelength;
// 设置干扰阈值并添加支持的干扰类型
InitializeJamming(JammingThreshold, [JammingType.Laser]);
@@ -183,7 +173,7 @@ namespace ThreatSource.Indicator
if (!IsIlluminationOn)
{
IsIlluminationOn = true;
- PublishIlluminationStartEvent();
+ PublishIlluminationUpdateEvent();
}
}
@@ -232,7 +222,7 @@ namespace ThreatSource.Indicator
};
// 检查波长匹配(激光特定逻辑)
- bool isWavelengthInRange = evt.Wavelength >= MinWavelength && evt.Wavelength <= MaxWavelength;
+ bool isWavelengthInRange = evt.Wavelength == Wavelength;
// 使用JammableComponent进行干扰判断
if (isWavelengthInRange)
@@ -334,36 +324,6 @@ namespace ThreatSource.Indicator
}
}
- ///
- /// 发布激光照射开始事件
- ///
- ///
- /// 发布过程:
- /// - 创建事件对象
- /// - 设置事件属性
- /// - 添加编码信息
- /// - 发布到事件系统
- ///
- private void PublishIlluminationStartEvent()
- {
- Debug.WriteLine($"激光照射开始事件: {Id}, TargetId: {TargetId}");
-
- var illuminationEvent = new LaserIlluminationStartEvent
- {
- LaserDesignatorId = Id,
- TargetId = TargetId
- };
-
- // 添加编码信息
- if (LaserCodeConfig != null)
- {
- illuminationEvent.LaserCodeConfig = LaserCodeConfig;
- }
-
- // 发布事件
- PublishEvent(illuminationEvent);
- }
-
///
/// 发布激光照射更新事件
///
diff --git a/ThreatSource/src/MIssile/BaseMissile.cs b/ThreatSource/src/MIssile/BaseMissile.cs
index cbc0ad1..a55e040 100644
--- a/ThreatSource/src/MIssile/BaseMissile.cs
+++ b/ThreatSource/src/MIssile/BaseMissile.cs
@@ -177,29 +177,22 @@ namespace ThreatSource.Missile
/// 时间步长,单位:秒
///
/// 更新过程:
- /// - 计算合加速度
+ /// - 计算包含风影响的合加速度
/// - 根据制导状态选择运动更新方法
/// - 更新导弹的位置和速度
///
protected virtual void UpdateMotionState(double deltaTime)
{
- //Vector3D acceleration = CalculateAcceleration(Velocity);
-
- Vector3D acceleration;
+ // 计算包含风影响的合加速度
+ Vector3D acceleration = CalculateAcceleration(Velocity);
if (IsGuidance)
{
- // 在有制导情况下使用制导加速度
- acceleration = GuidanceAcceleration;
-
// 制导条件下,使用四阶龙格-库塔方法更新导弹的位置和速度
(Position, Velocity) = MotionAlgorithm.RungeKutta4(deltaTime, Position, Velocity, acceleration);
}
else
{
- // 在无制导情况下使用零向量作为加速度
- acceleration = Vector3D.Zero;
-
// 无制导条件下,使用运动学方程更新导弹的位置和速度
(Position, Velocity) = MotionAlgorithm.CalculateBallisticMotion(Position, Velocity, acceleration, deltaTime);
}
@@ -228,18 +221,25 @@ namespace ThreatSource.Missile
/// 合加速度向量
///
/// 计算过程:
- /// - 计算空气阻力加速度
- /// - 合成制导、推力和阻力加速度
+ /// - 获取当前风速向量
+ /// - 计算空气阻力加速度(已考虑风)
+ /// - 合成总加速度(制导加速度 + 推力加速度 + 空气阻力加速度)
/// - 限制合加速度不超过最大值
///
private Vector3D CalculateAcceleration(Vector3D velocity)
{
- // 计算空气阻力的影响
- Vector3D dragAcceleration = velocity.Normalize() * -1 * CalculateDrag(velocity.Magnitude()) / Properties.Mass;
+ // 获取当前风速向量
+ Vector3D windVector = GetWindVectorFromWeather();
+ // 计算空气阻力加速度(考虑风的影响)
+ Vector3D dragAcceleration = CalculateDragAcceleration(velocity, windVector);
+
+ // 合成总加速度(制导加速度 + 推力加速度 + 空气阻力加速度)
Vector3D totalAcceleration = GuidanceAcceleration + ThrustAcceleration + dragAcceleration;
- Debug.WriteLine($"导弹 {Id} 的加速度: {totalAcceleration}, 制导加速度: {GuidanceAcceleration}, 推力加速度: {ThrustAcceleration}, 空气阻力加速度: {dragAcceleration}");
+ Console.WriteLine($"导弹 {Id} 的加速度: {totalAcceleration}, 制导加速度: {GuidanceAcceleration}, " +
+ $"推力加速度: {ThrustAcceleration}, 空气阻力加速度(含风影响): {dragAcceleration}");
+
if (totalAcceleration.Magnitude() > Properties.MaxAcceleration)
{
totalAcceleration = totalAcceleration.Normalize() * Properties.MaxAcceleration;
@@ -249,26 +249,65 @@ namespace ThreatSource.Missile
}
///
- /// 计算空气阻力
+ /// 从天气系统获取当前的风速向量
///
- /// 当前速度大小,单位:米/秒
- /// 空气阻力大小,单位:牛顿
+ /// 风速向量,单位:米/秒
+ private Vector3D GetWindVectorFromWeather()
+ {
+ var weather = SimulationManager.CurrentWeather;
+ if (weather == null)
+ return Vector3D.Zero;
+
+ return MotionAlgorithm.CalculateWindVector(weather.WindSpeed, weather.WindDirection);
+ }
+
+ ///
+ /// 计算空气阻力加速度,考虑风的影响
+ ///
+ /// 物体速度向量
+ /// 风速向量
+ /// 空气阻力加速度向量,单位:米/秒²
///
/// 计算公式:
- /// F = 0.5 * Cd * ρ * A * v²
+ /// a = (0.5 * Cd * ρ * A * v²) / m * (-v_rel_norm)
/// 其中:
/// - Cd:阻力系数
/// - ρ:空气密度
/// - A:参考面积
- /// - v:速度
+ /// - v:物体相对于空气的速度
+ /// - m:物体质量
+ /// - v_rel_norm:相对速度的单位向量
///
- private static double CalculateDrag(double speed)
+ private Vector3D CalculateDragAcceleration(Vector3D velocity, Vector3D windVector)
{
- const double dragCoefficient = 0.1; // 减小阻力系数
+ const double dragCoefficient = 0.1; // 阻力系数
const double airDensity = 1.225; // 海平面空气密度,kg/m^3
- const double referenceArea = 0.01; // 减小导弹的参考面积,m^2
-
- return 0.5 * dragCoefficient * airDensity * referenceArea * speed * speed;
+ const double referenceArea = 0.01; // 导弹的参考面积,m^2
+
+ // 计算物体相对于空气的速度
+ Vector3D relativeVelocity = velocity - windVector;
+ double relativeSpeed = relativeVelocity.Magnitude();
+
+ // 如果相对速度接近零,返回零加速度
+ if (relativeSpeed < 0.001)
+ return Vector3D.Zero;
+
+ // 计算空气阻力加速度大小
+ double dragAccelerationMagnitude = 0.5 * dragCoefficient * airDensity * referenceArea * relativeSpeed * relativeSpeed / Properties.Mass;
+
+ // 计算单位向量的各个分量
+ double normX = relativeVelocity.X / relativeSpeed;
+ double normY = relativeVelocity.Y / relativeSpeed;
+ double normZ = relativeVelocity.Z / relativeSpeed;
+
+ // 空气阻力加速度方向与相对速度方向相反(每个分量都取反)
+ Vector3D dragAcceleration = new Vector3D(
+ -normX * dragAccelerationMagnitude,
+ -normY * dragAccelerationMagnitude,
+ -normZ * dragAccelerationMagnitude
+ );
+
+ return dragAcceleration;
}
///
diff --git a/ThreatSource/src/MIssile/LaserSemiActiveGuidedMissile.cs b/ThreatSource/src/MIssile/LaserSemiActiveGuidedMissile.cs
index 3b0db95..9f5a9c0 100644
--- a/ThreatSource/src/MIssile/LaserSemiActiveGuidedMissile.cs
+++ b/ThreatSource/src/MIssile/LaserSemiActiveGuidedMissile.cs
@@ -1,8 +1,6 @@
using ThreatSource.Simulation;
using ThreatSource.Utils;
using ThreatSource.Guidance;
-using ThreatSource.Indicator;
-using ThreatSource.Target;
namespace ThreatSource.Missile
{
@@ -215,32 +213,10 @@ namespace ThreatSource.Missile
{
// 更新制导系统
guidanceSystem.Update(deltaTime, Position, Velocity);
-
- // 根据制导系统的HasGuidance属性设置IsGuidance
- if (guidanceSystem is LaserSemiActiveGuidanceSystem laserGuidance)
- {
- // 只有当四象限探测器锁定目标时,才启用制导
- IsGuidance = laserGuidance.HasGuidance && laserGuidance.IsQuadrantDetectorLocked();
-
- // 打印激光能量和制导加速度
- string guidanceStatus = laserGuidance.GetStatus();
- double accelerationMagnitude = GuidanceAcceleration.Magnitude();
- }
- else
- {
- IsGuidance = false; // 默认情况下禁用制导
- }
-
// 获取制导加速度
- if (IsGuidance)
- {
- GuidanceAcceleration = guidanceSystem.GetGuidanceAcceleration();
- }
- else
- {
- // 如果没有制导,则将制导加速度设置为零向量
- GuidanceAcceleration = Vector3D.Zero;
- }
+ GuidanceAcceleration = guidanceSystem.GetGuidanceAcceleration();
+ // 设置制导状态
+ IsGuidance = guidanceSystem.HasGuidance;
}
///
diff --git a/ThreatSource/src/Sensor/QuadrantDetector.cs b/ThreatSource/src/Sensor/QuadrantDetector.cs
index 5b83ad2..842baef 100644
--- a/ThreatSource/src/Sensor/QuadrantDetector.cs
+++ b/ThreatSource/src/Sensor/QuadrantDetector.cs
@@ -76,6 +76,43 @@ namespace ThreatSource.Sensor
///
public double VerticalError { get; private set; }
+ ///
+ /// 滤波后的水平方向误差
+ ///
+ ///
+ /// 对原始水平误差进行滤波后的值
+ /// 用于减少误差信号的噪声和快速变化
+ ///
+ private double filteredHorizontalError = 0;
+
+ ///
+ /// 滤波后的垂直方向误差
+ ///
+ ///
+ /// 对原始垂直误差进行滤波后的值
+ /// 用于减少误差信号的噪声和快速变化
+ ///
+ private double filteredVerticalError = 0;
+
+ ///
+ /// 误差滤波系数
+ ///
+ ///
+ /// 控制滤波的强度,值越小滤波越强
+ /// 范围:(0,1]
+ /// 值为1时无滤波效果
+ ///
+ private const double errorFilterFactor = 0.15;
+
+ ///
+ /// 误差死区阈值
+ ///
+ ///
+ /// 小于此值的误差将被视为零
+ /// 用于避免对微小误差的过度响应
+ ///
+ private const double errorDeadZone = 0.01;
+
///
/// 获取总接收功率,单位:瓦特
///
@@ -120,6 +157,8 @@ namespace ThreatSource.Sensor
HorizontalError = 0;
VerticalError = 0;
+ filteredHorizontalError = 0;
+ filteredVerticalError = 0;
TotalReceivedPower = 0;
IsTargetLocked = false;
}
@@ -152,6 +191,8 @@ namespace ThreatSource.Sensor
}
HorizontalError = 0;
VerticalError = 0;
+ filteredHorizontalError = 0;
+ filteredVerticalError = 0;
return;
}
@@ -233,23 +274,44 @@ namespace ThreatSource.Sensor
if (TotalReceivedPower > 0)
{
// 计算水平误差
- HorizontalError = ((quadrantSignals[0] + quadrantSignals[3]) -
+ double rawHorizontalError = ((quadrantSignals[0] + quadrantSignals[3]) -
(quadrantSignals[1] + quadrantSignals[2])) /
TotalReceivedPower;
// 计算垂直误差
- VerticalError = ((quadrantSignals[0] + quadrantSignals[1]) -
+ double rawVerticalError = ((quadrantSignals[0] + quadrantSignals[1]) -
(quadrantSignals[2] + quadrantSignals[3])) /
TotalReceivedPower;
// 限制误差范围在[-1, 1]之间
- HorizontalError = Math.Max(-1, Math.Min(1, HorizontalError));
- VerticalError = Math.Max(-1, Math.Min(1, VerticalError));
+ HorizontalError = Math.Max(-1, Math.Min(1, rawHorizontalError));
+ VerticalError = Math.Max(-1, Math.Min(1, rawVerticalError));
+
+ // 应用误差滤波
+ filteredHorizontalError = filteredHorizontalError * (1 - errorFilterFactor) +
+ HorizontalError * errorFilterFactor;
+ filteredVerticalError = filteredVerticalError * (1 - errorFilterFactor) +
+ VerticalError * errorFilterFactor;
+
+ // 应用误差死区
+ if (Math.Abs(filteredHorizontalError) < errorDeadZone)
+ filteredHorizontalError = 0;
+ if (Math.Abs(filteredVerticalError) < errorDeadZone)
+ filteredVerticalError = 0;
+
+ // 使用滤波后的误差替代原始误差
+ HorizontalError = filteredHorizontalError;
+ VerticalError = filteredVerticalError;
+
+ // 增强调试输出,同时显示水平和垂直误差
+ Console.WriteLine($"原始误差: 水平={rawHorizontalError:F6}, 垂直={rawVerticalError:F6}, 滤波后: 水平={HorizontalError:F6}, 垂直={VerticalError:F6}");
}
else
{
HorizontalError = 0;
VerticalError = 0;
+ filteredHorizontalError = 0;
+ filteredVerticalError = 0;
}
}
@@ -260,32 +322,34 @@ namespace ThreatSource.Sensor
/// 灵敏度系数
/// 修正后的目标方向向量
///
- /// 计算过程:
- /// - 根据水平和垂直误差计算修正角度
- /// - 应用修正角度到当前方向
- /// - 返回修正后的方向向量
+ /// 使用通用的正交基构建方法
+ /// 不依赖于特定的坐标系
+ /// 适用于任何飞行姿态
///
public Vector3D GetTargetDirection(Vector3D currentDirection, double sensitivity)
{
- // 如果未锁定目标,返回当前方向
if (!IsTargetLocked)
{
return currentDirection;
}
-
- // 获取当前方向的标准正交基
+
+ // 1. 获取当前方向的单位向量
Vector3D forward = currentDirection.Normalize();
- Vector3D right = Vector3D.CrossProduct(Vector3D.UnitY, forward).Normalize();
+
+ // 2. 构建任意正交基
+ // 选择一个非平行于forward的向量来构建正交基
+ Vector3D temp = Math.Abs(forward.X) < 0.9 ? Vector3D.UnitX : Vector3D.UnitY;
+ Vector3D right = Vector3D.CrossProduct(temp, forward).Normalize();
Vector3D up = Vector3D.CrossProduct(forward, right).Normalize();
- // 根据误差和灵敏度计算修正向量
+ // 3. 在这个局部坐标系中应用误差修正
+ // HorizontalError 对应 right 方向
+ // VerticalError 对应 up 方向
Vector3D correction = right * (HorizontalError * sensitivity) +
up * (VerticalError * sensitivity);
- // 应用修正并归一化
- Vector3D targetDirection = (forward + correction).Normalize();
-
- return targetDirection;
+ // 4. 计算新的方向向量并归一化
+ return (forward + correction).Normalize();
}
///
diff --git a/ThreatSource/src/Simulation/DecoyTarget.cs b/ThreatSource/src/Simulation/DecoyTarget.cs
index 94e78a3..0052d0c 100644
--- a/ThreatSource/src/Simulation/DecoyTarget.cs
+++ b/ThreatSource/src/Simulation/DecoyTarget.cs
@@ -16,6 +16,11 @@ namespace ThreatSource.Simulation
/// 获取或设置诱偏源功率,单位:瓦特
///
public double DecoyPower { get; set; }
+
+ ///
+ /// 获取或设置诱偏激光发散角,单位:弧度
+ ///
+ public double DecoyLaserDivergenceAngle { get; set; }
///
/// 获取或设置反射系数
@@ -30,7 +35,7 @@ namespace ThreatSource.Simulation
///
/// 获取或设置诱偏源位置
///
- public Vector3D SourcePosition { get; set; }
+ public string SourceId { get; set; }
///
/// 获取创建时间
@@ -46,23 +51,25 @@ namespace ThreatSource.Simulation
/// 初始化激光诱偏目标的新实例
///
/// 目标ID
+ /// 诱偏源ID
/// 目标位置
/// 诱偏源功率
+ /// 诱偏激光发散角
/// 反射系数
/// 有效反射面积
/// 生命周期
- /// 诱偏源位置
/// 仿真管理器
- public DecoyTarget(string id, Vector3D position, double decoyPower,
- double reflectionCoefficient, double reflectiveArea, double lifeTime,
- Vector3D sourcePosition, ISimulationManager simulationManager)
+ public DecoyTarget(string id, string sourceId, Vector3D position, double decoyPower,
+ double decoyLaserDivergenceAngle, double reflectionCoefficient, double reflectiveArea, double lifeTime,
+ ISimulationManager simulationManager)
: base(id, position, new Orientation(), 0, simulationManager) // 诱偏目标通常是静止的,速度为0
{
+ SourceId = sourceId;
DecoyPower = decoyPower;
+ DecoyLaserDivergenceAngle = decoyLaserDivergenceAngle;
ReflectionCoefficient = reflectionCoefficient;
ReflectiveArea = reflectiveArea;
LifeTime = lifeTime;
- SourcePosition = sourcePosition;
CreationTime = DateTime.Now;
}
@@ -70,40 +77,11 @@ namespace ThreatSource.Simulation
/// 检查诱偏目标是否仍然活跃
///
/// 如果目标仍然活跃返回true,否则返回false
- public bool IsActive()
+ public bool IsDecoyActive()
{
return (DateTime.Now - CreationTime).TotalSeconds < LifeTime;
}
- ///
- /// 计算在特定位置接收到的反射功率
- ///
- /// 观察者位置
- /// 激光发散角
- /// 计算得到的反射功率,单位:瓦特
- public double CalculateReflectedPower(Vector3D observerPosition, double laserDivergenceAngle)
- {
- double distanceSourceToDecoy = (SourcePosition - Position).Magnitude();
- double distanceDecoyToObserver = (Position - observerPosition).Magnitude();
-
- // 计算诱偏源处的光斑面积
- double spotAreaAtDecoy = Math.PI * Math.Pow(distanceSourceToDecoy * Math.Tan(laserDivergenceAngle), 2);
-
- // 计算诱偏源处的激光功率密度
- double powerDensityAtDecoy = DecoyPower / spotAreaAtDecoy;
-
- // 计算从诱偏源反射的总功率
- double reflectedPower = powerDensityAtDecoy * ReflectiveArea * ReflectionCoefficient;
-
- // 计算反射光在观察者处的扩散面积(假设漫反射)
- double reflectedSpotArea = 2 * Math.PI * Math.Pow(distanceDecoyToObserver, 2);
-
- // 计算观察者接收到的功率
- double receivedPower = reflectedPower / reflectedSpotArea;
-
- return receivedPower;
- }
-
///
/// 更新诱偏目标状态
///
@@ -111,7 +89,7 @@ namespace ThreatSource.Simulation
public override void Update(double deltaTime)
{
// 如果生命周期结束,从仿真中移除
- if (!IsActive())
+ if (!IsDecoyActive())
{
SimulationManager.UnregisterEntity(Id);
}
diff --git a/ThreatSource/src/Simulation/ISimulationManager.cs b/ThreatSource/src/Simulation/ISimulationManager.cs
index f3e7541..560f326 100644
--- a/ThreatSource/src/Simulation/ISimulationManager.cs
+++ b/ThreatSource/src/Simulation/ISimulationManager.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using ThreatSource.Utils;
+using AirTransmission;
namespace ThreatSource.Simulation
{
@@ -100,25 +101,37 @@ namespace ThreatSource.Simulation
}
///
- /// 仿真管理器接口,提供仿真系统的核心功能
+ /// 仿真管理器接口,定义仿真系统的核心功能
///
///
- /// 该接口定义了仿真系统的主要功能,包括:
- /// - 事件系统:用于实体间的通信和状态同步
- /// - 实体管理:负责实体的注册、注销和查询
- /// - 第三方集成:支持与其他仿真环境的对接
+ /// 该接口定义了仿真系统应提供的基本功能:
+ /// - 事件系统:支持发布/订阅模式的事件处理
+ /// - 实体管理:实体的注册、注销和查询
+ /// - 仿真控制:启动、暂停、恢复和停止仿真
+ /// - 第三方集成:支持与外部仿真环境的对接
///
public interface ISimulationManager
{
///
- /// 当前仿真时间
+ /// 获取当前仿真状态
+ ///
+ SimulationState State { get; }
+
+ ///
+ /// 获取当前仿真时间
///
double CurrentTime { get; }
///
- /// 仿真状态
+ /// 获取当前天气系统
///
- SimulationState State { get; }
+ Weather? CurrentWeather { get; }
+
+ ///
+ /// 设置当前天气
+ ///
+ /// 天气条件
+ void SetWeather(Weather weather);
///
/// 启动仿真系统
diff --git a/ThreatSource/src/Simulation/SimulationConfig.cs b/ThreatSource/src/Simulation/SimulationConfig.cs
index 6e115a1..1a68b6a 100644
--- a/ThreatSource/src/Simulation/SimulationConfig.cs
+++ b/ThreatSource/src/Simulation/SimulationConfig.cs
@@ -1,5 +1,12 @@
using System.Runtime.CompilerServices;
using ThreatSource.Utils;
+using System.Collections.Generic; // Added for Dictionary
+using ThreatSource.Missile; // For MissileProperties
+using ThreatSource.Target; // For Target properties if needed
+using ThreatSource.Sensor; // For Sensor configs
+using ThreatSource.Jamming; // For Jammer configs
+using ThreatSource.Indicator; // For Indicator configs
+using AirTransmission; // Added for WeatherType enum
namespace ThreatSource.Simulation
{
@@ -134,24 +141,14 @@ namespace ThreatSource.Simulation
public double JammingResistanceThreshold { get; set; } = 1.0;
///
- /// 获取或设置最小工作波长
+ /// 获取或设置工作波长
///
///
/// 单位:微米
- /// 激光指示器工作的最小波长
+ /// 激光指示器工作的波长
/// 影响激光干扰的匹配判断
///
- public double MinWavelength { get; set; } = 1.0;
-
- ///
- /// 获取或设置最大工作波长
- ///
- ///
- /// 单位:微米
- /// 激光指示器工作的最大波长
- /// 影响激光干扰的匹配判断
- ///
- public double MaxWavelength { get; set; } = 1.1;
+ public double LaserWavelength { get; set; } = 1.06;
}
///
@@ -622,7 +619,10 @@ namespace ThreatSource.Simulation
/// - 反射系数:0.2
/// - 反射面积:1.0平方米
/// - 锁定阈值:1e-12瓦特
- /// - 灵敏度:0.5
+ /// - 灵敏度:0.05
+ /// - 发射系统透过率:0.85
+ /// - 接收系统透过率:0.8
+ /// - 激光波长:1.06微米
///
public class LaserSemiActiveGuidanceConfig
{
@@ -716,9 +716,9 @@ namespace ThreatSource.Simulation
///
/// 定义了四象限探测器对光斑偏移的响应灵敏度
/// 影响制导系统的响应速度和稳定性
- /// 默认值为0.5
+ /// 默认值为0.2
///
- public double SpotOffsetSensitivity { get; set; } = 0.5;
+ public double SpotOffsetSensitivity { get; set; } = 0.05;
///
/// 干扰抗性阈值,单位:瓦特
@@ -730,6 +730,36 @@ namespace ThreatSource.Simulation
///
public double JammingResistanceThreshold { get; set; } = 1e-12;
+ ///
+ /// 发射系统透过率
+ ///
+ ///
+ /// 定义了激光从发射器到外部的能量传输效率
+ /// 范围:[0,1],1表示无损耗
+ /// 默认值为0.85
+ ///
+ public double TransmitterEfficiency { get; set; } = 0.85;
+
+ ///
+ /// 接收系统透过率
+ ///
+ ///
+ /// 定义了接收系统的光学元件传输效率
+ /// 范围:[0,1],1表示无损耗
+ /// 默认值为0.8
+ ///
+ public double ReceiverEfficiency { get; set; } = 0.8;
+
+ ///
+ /// 激光波长,单位:微米
+ ///
+ ///
+ /// 定义了激光的工作波长
+ /// 影响大气透过率和目标反射特性
+ /// 默认值为1.06微米(Nd:YAG激光器)
+ ///
+ public double LaserWavelength { get; set; } = 1.06;
+
///
/// 初始化激光半主动导引配置的新实例
///
@@ -742,7 +772,10 @@ namespace ThreatSource.Simulation
/// - 反射系数:0.2
/// - 反射面积:1.0平方米
/// - 锁定阈值:1e-12瓦特
- /// - 灵敏度:0.5
+ /// - 灵敏度:0.2
+ /// - 发射系统透过率:0.85
+ /// - 接收系统透过率:0.8
+ /// - 激光波长:1.06微米
///
public LaserSemiActiveGuidanceConfig()
{
@@ -1063,6 +1096,17 @@ namespace ThreatSource.Simulation
///
public double JammingResistanceThreshold { get; set; } = 1e-3;
+
+ ///
+ /// 激光波长,单位:纳米
+ ///
+ ///
+ /// 定义了激光的波长
+ /// 影响激光的传输特性和探测性能
+ /// 默认值为1.06纳米
+ ///
+ public double LaserWavelength { get; set; } = 1.06;
+
///
/// 初始化激光驾束制导系统配置的新实例
///
diff --git a/ThreatSource/src/Simulation/SimulationEvents.cs b/ThreatSource/src/Simulation/SimulationEvents.cs
index b66c100..9847aee 100644
--- a/ThreatSource/src/Simulation/SimulationEvents.cs
+++ b/ThreatSource/src/Simulation/SimulationEvents.cs
@@ -52,41 +52,6 @@ namespace ThreatSource.Simulation
public string? TargetId { get; set; }
}
- ///
- /// 激光照射开始事件,表示激光定位器开始照射目标
- ///
- ///
- /// 用于激光半主动导引系统
- /// 触发时机:激光定位器开始照射目标时
- ///
- public class LaserIlluminationStartEvent : SimulationEvent
- {
- ///
- /// 获取或设置激光定位器的ID
- ///
- ///
- /// 标识发出激光的定位器设备
- ///
- public string? LaserDesignatorId { get; set; }
-
- ///
- /// 获取或设置被照射目标的ID
- ///
- ///
- /// 标识被激光照射的目标实体
- ///
- public string? TargetId { get; set; }
-
- ///
- /// 获取或设置激光编码信息
- ///
- ///
- /// 包含激光信号的编码类型和编码值
- /// 用于抗干扰和安全识别
- ///
- public LaserCodeConfig? LaserCodeConfig { get; set; }
- }
-
///
/// 激光照射更新事件,表示激光照射状态的更新
///
@@ -786,54 +751,21 @@ namespace ThreatSource.Simulation
}
///
- /// 诱偏目标创建事件,表示创建了一个新的激光诱偏目标
+ /// 诱偏目标照射事件,表示诱偏目标被照射
///
///
- /// 用于通知系统新的诱偏目标已创建
- /// 触发时机:激光诱偏目标被创建时
+ /// 用于模拟诱偏目标被照射的情况
+ /// 触发时机:诱偏目标被照射时
///
- public class DecoyTargetCreatedEvent : SimulationEvent
+ public class DecoyTargetIlluminationEvent : SimulationEvent
{
///
/// 获取或设置诱偏目标的ID
///
///
- /// 标识新创建的诱偏目标
+ /// 标识被照射的诱偏目标
///
public string? DecoyTargetId { get; set; }
-
- ///
- /// 获取或设置诱偏目标的位置
- ///
- ///
- /// 诱偏目标在三维空间中的位置
- ///
- public Vector3D DecoyPosition { get; set; }
-
- ///
- /// 获取或设置诱偏源的功率
- ///
- ///
- /// 单位:瓦特
- /// 诱偏源的发射功率
- ///
- public double DecoyPower { get; set; }
-
- ///
- /// 获取或设置诱偏源的位置
- ///
- ///
- /// 诱偏发射设备在三维空间中的位置
- ///
- public Vector3D SourcePosition { get; set; }
-
- ///
- /// 获取或设置诱偏目标的生命周期
- ///
- ///
- /// 单位:秒
- /// 诱偏目标的有效存在时间
- ///
- public double LifeTime { get; set; }
}
+
}
diff --git a/ThreatSource/src/Simulation/SimulationManager.cs b/ThreatSource/src/Simulation/SimulationManager.cs
index 9a7fbf3..6a883f8 100644
--- a/ThreatSource/src/Simulation/SimulationManager.cs
+++ b/ThreatSource/src/Simulation/SimulationManager.cs
@@ -2,6 +2,7 @@ using System.Diagnostics;
using ThreatSource.Missile;
using ThreatSource.Target;
using ThreatSource.Utils;
+using AirTransmission;
namespace ThreatSource.Simulation
{
@@ -52,8 +53,6 @@ namespace ThreatSource.Simulation
///
private ISimulationAdapter? _simulationAdapter;
-
-
private SimulationState _state = SimulationState.Stopped;
///
@@ -71,6 +70,16 @@ namespace ThreatSource.Simulation
///
private double _timeStep;
+ ///
+ /// 当前天气系统
+ ///
+ private Weather? _currentWeather;
+
+ ///
+ /// 获取当前天气系统
+ ///
+ public Weather? CurrentWeather => _currentWeather;
+
///
/// 启动仿真系统
///
@@ -167,8 +176,8 @@ namespace ThreatSource.Simulation
var activeTargets = entities.Values.OfType().Where(e => e.IsActive).ToList();
var hitEvents = new List<(Tank tank, BaseMissile missile, double damage)>();
- Console.WriteLine($"activeMissiles: {activeMissiles.Count}");
- Console.WriteLine($"activeTargets: {activeTargets.Count}");
+ Console.WriteLine($"活动导弹数量: {activeMissiles.Count}");
+ Console.WriteLine($"活动目标数量: {activeTargets.Count}");
// 收集所有的命中信息
foreach (var missile in activeMissiles)
@@ -525,5 +534,33 @@ namespace ThreatSource.Simulation
PublishEvent(evt);
}
#endregion
+
+ ///
+ /// 设置当前天气
+ ///
+ /// 天气条件
+ public void SetWeather(Weather weather)
+ {
+ _currentWeather = weather;
+ Console.WriteLine($"已设置天气:{weather.Type}");
+
+ // 通知其他实体天气已变化
+ var evt = new WeatherChangedEvent
+ {
+ NewWeather = weather
+ };
+ PublishEvent(evt);
+ }
+ }
+
+ ///
+ /// 天气变化事件,当天气系统变化时触发
+ ///
+ public class WeatherChangedEvent : SimulationEvent
+ {
+ ///
+ /// 新的天气系统
+ ///
+ public Weather? NewWeather { get; set; }
}
}
\ No newline at end of file
diff --git a/ThreatSource/src/Target/Tank.cs b/ThreatSource/src/Target/Tank.cs
index cfec237..ae1a6b2 100644
--- a/ThreatSource/src/Target/Tank.cs
+++ b/ThreatSource/src/Target/Tank.cs
@@ -22,6 +22,14 @@ namespace ThreatSource.Target
///
public override TargetType Type => TargetType.Tank;
+ ///
+ /// 获取或设置诱偏目标的ID
+ ///
+ ///
+ /// 标识诱偏目标
+ ///
+ public string? DecoyTargetId { get; set; }
+
///
/// 获取或设置诱偏功率,单位:瓦特
///
@@ -76,6 +84,18 @@ namespace ThreatSource.Target
public override void Update(double deltaTime)
{
base.Update(deltaTime);
+ // 发布诱偏目标照射事件
+ if (DecoyTargetId != null)
+ {
+ if(SimulationManager.GetEntityById(DecoyTargetId) is DecoyTarget decoyTarget && decoyTarget.IsDecoyActive())
+ {
+ var illuminationEvent = new DecoyTargetIlluminationEvent
+ {
+ DecoyTargetId = DecoyTargetId
+ };
+ SimulationManager.PublishEvent(illuminationEvent);
+ }
+ }
// TODO: 添加坦克特有的更新逻辑
}
@@ -109,12 +129,13 @@ namespace ThreatSource.Target
// 创建诱偏目标
var decoyTarget = new DecoyTarget(
decoyId,
+ Id,
decoyPosition,
power,
+ DecoyLaserDivergenceAngle,
reflectionCoefficient,
reflectiveArea,
lifetime,
- Position, // 诱偏源位置为坦克位置
SimulationManager
);
@@ -123,17 +144,8 @@ namespace ThreatSource.Target
// 激活诱偏目标
decoyTarget.Activate();
-
- // 发布诱偏目标创建事件
- var createdEvent = new DecoyTargetCreatedEvent
- {
- DecoyTargetId = decoyId,
- DecoyPosition = decoyPosition,
- DecoyPower = power,
- SourcePosition = Position,
- LifeTime = lifetime
- };
- SimulationManager.PublishEvent(createdEvent);
+
+ DecoyTargetId = decoyId;
return decoyId;
}
diff --git a/ThreatSource/src/Utils/AtmosphereDllWrapper.cs b/ThreatSource/src/Utils/AtmosphereDllWrapper.cs
new file mode 100644
index 0000000..10a5d7e
--- /dev/null
+++ b/ThreatSource/src/Utils/AtmosphereDllWrapper.cs
@@ -0,0 +1,157 @@
+using AirTransmission; // 引用 .NET DLL 的命名空间
+using System;
+
+namespace ThreatSource.Utils
+{
+ ///
+ /// 封装对 AirTransmission.dll 中大气透过率计算逻辑的调用
+ ///
+ public class AtmosphereDllWrapper
+ {
+ ///
+ /// 初始化 AtmosphereDllWrapper 类的新实例
+ /// (当前无需特殊初始化)
+ ///
+ public AtmosphereDllWrapper()
+ {
+ // 构造函数为空,因为我们直接调用静态方法
+ }
+
+ ///
+ /// 计算两点之间的大气透过率
+ ///
+ /// 距离(米)
+ /// 电磁波类型
+ /// 波长(单位:微米)
+ /// 天气条件
+ /// 透过率因子(0.0 到 1.0)
+ public static double CalculateTransmittance(double distance, RadiationType radiationType, double wavelength, Weather weather)
+ {
+ try
+ {
+ // 创建WeatherParameters结构体
+ var parameters = new WeatherParameters
+ {
+ Temperature = weather.Temperature,
+ RelativeHumidity = weather.RelativeHumidity,
+ Visibility = weather.Visibility,
+ Pressure = weather.Pressure,
+ Precipitation = weather.Precipitation,
+ CO2Concentration = weather.CO2Concentration,
+ WindSpeed = weather.WindSpeed,
+ WindDirection = weather.WindDirection,
+ WeatherType = (int)weather.Type
+ };
+
+ // 将距离从米转换为公里(库函数期望距离以公里为单位)
+ double distanceInKm = distance / 1000.0;
+
+ // 调用导出方法
+ double transmittance = AtmosphericTransmittanceCalculator.CalculateTransmittanceExport(
+ (int)radiationType,
+ wavelength,
+ distanceInKm, // 使用公里单位
+ parameters);
+
+ Console.WriteLine($"[透过率] 类型: {radiationType}, 波长: {wavelength:F2}um, 距离: {distance:F1}m -> {transmittance:F3}");
+
+ return Math.Clamp(transmittance, 0.0, 1.0);
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"调用AirTransmission计算透过率时出错 (类型: {radiationType}, 波长: {wavelength}um, 距离: {distance}m): {ex.Message}");
+ // 发生错误时返回一个保守的默认值
+ return 0.8;
+ }
+ }
+
+ ///
+ /// 计算激光在大气中的透过率
+ ///
+ /// 传输距离(米)
+ /// 激光波长(微米)
+ /// 天气条件
+ /// 激光的大气透过率(0.0到1.0)
+ ///
+ /// 这是一个便捷方法,专门用于计算激光的大气透过率。
+ /// 内部调用CalculateTransmittance方法,使用RadiationType.Laser作为参数。
+ ///
+ public static double CalculateLaserTransmittance(double distance, double wavelength, Weather weather)
+ {
+ return CalculateTransmittance(distance, RadiationType.Laser, wavelength, weather);
+ }
+
+ ///
+ /// 计算大气湍流影响
+ ///
+ /// 波长(微米)
+ /// 传输距离(米)
+ /// 天气条件
+ /// 传输高度(米)
+ /// 湍流效应(0到1之间的值,1表示无影响,0表示完全衰减)
+ public static double CalculateAtmosphericTurbulence(double wavelength, double distance, Weather weather, double height)
+ {
+ try
+ {
+ // 创建WeatherParameters结构体
+ var parameters = new WeatherParameters
+ {
+ Temperature = weather.Temperature,
+ RelativeHumidity = weather.RelativeHumidity,
+ Visibility = weather.Visibility,
+ Pressure = weather.Pressure,
+ Precipitation = weather.Precipitation,
+ CO2Concentration = weather.CO2Concentration,
+ WindSpeed = weather.WindSpeed,
+ WindDirection = weather.WindDirection,
+ WeatherType = (int)weather.Type
+ };
+
+ // 将距离从米转换为公里(库函数期望距离以公里为单位)
+ double distanceInKm = distance / 1000.0;
+
+ // 调用导出方法
+ double turbulenceEffect = AtmosphericTransmittanceCalculator.CalculateAtmosphericTurbulenceExport(
+ wavelength,
+ distanceInKm, // 使用公里单位
+ parameters,
+ height); // 使用米单位
+
+ Console.WriteLine($"[湍流效应] 波长: {wavelength:F2}um, 距离: {distance:F1}m, 高度: {height:F1}m -> {turbulenceEffect:F3}");
+ return turbulenceEffect;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"计算湍流效应时出错 (波长: {wavelength}um, 距离: {distance}m, 高度: {height}m): {ex.Message}");
+ return 1.0; // 假设无影响
+ }
+ }
+
+ ///
+ /// 计算烟幕透过率
+ ///
+ /// 波长(微米)
+ /// 烟幕浓度(g/m³)
+ /// 烟幕厚度(米)
+ /// 烟幕透过率(0到1之间的值)
+ public static double CalculateSmokeScreenTransmittance(double wavelength, double smokeConcentration, double smokeThickness)
+ {
+ try
+ {
+ // 调用导出方法
+ double smokeTransmittance = AtmosphericTransmittanceCalculator.CalculateSmokeScreenTransmittanceExport(
+ wavelength,
+ smokeConcentration,
+ smokeThickness); // 使用米单位
+
+ Console.WriteLine($"[烟幕透过率] 波长: {wavelength:F2}um, 浓度: {smokeConcentration:F1}g/m³, 厚度: {smokeThickness:F1}m -> {smokeTransmittance:F3}");
+ return smokeTransmittance;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"计算烟幕透过率时出错 (波长: {wavelength}um, 浓度: {smokeConcentration}g/m³, 厚度: {smokeThickness}m): {ex.Message}");
+ return 0.0; // 假设完全衰减
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ThreatSource/src/Utils/LaserCode.cs b/ThreatSource/src/Utils/LaserCode.cs
index a872398..4ef921b 100644
--- a/ThreatSource/src/Utils/LaserCode.cs
+++ b/ThreatSource/src/Utils/LaserCode.cs
@@ -1,5 +1,3 @@
-using System.Collections.Generic;
-
namespace ThreatSource.Utils
{
///
diff --git a/ThreatSource/src/Utils/MotionAlgorithm.cs b/ThreatSource/src/Utils/MotionAlgorithm.cs
index 4ed07bd..d1f3423 100644
--- a/ThreatSource/src/Utils/MotionAlgorithm.cs
+++ b/ThreatSource/src/Utils/MotionAlgorithm.cs
@@ -284,5 +284,29 @@ namespace ThreatSource.Utils
vector.Z + gaussianZ
);
}
+
+ ///
+ /// 根据风速和风向计算风速向量
+ ///
+ /// 风速,单位:米/秒
+ /// 风向,0-360度,0为北方,顺时针方向
+ /// 风速向量,单位:米/秒
+ ///
+ /// 将风速和风向转换为三维风速向量
+ /// 风向是0-360度,0为北方,顺时针方向
+ /// 在坐标系中,北方对应+Z,东方对应+X
+ ///
+ public static Vector3D CalculateWindVector(double windSpeed, double windDirection)
+ {
+ // 风向是0-360度,0为北方,顺时针方向
+ double windDirectionRad = windDirection * Math.PI / 180.0;
+
+ // 在水平面上分解风向
+ // 北方对应+Z,东方对应+X
+ double windX = windSpeed * Math.Sin(windDirectionRad); // 东西分量
+ double windZ = windSpeed * Math.Cos(windDirectionRad); // 南北分量
+
+ return new Vector3D(windX, 0, windZ);
+ }
}
}
diff --git a/VERSION b/VERSION
index d81f1c3..d156ab4 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.2.9
\ No newline at end of file
+0.2.10
\ No newline at end of file
diff --git a/docs/project/develop_log.md b/docs/project/develop_log.md
index 6f3025e..1c94f15 100644
--- a/docs/project/develop_log.md
+++ b/docs/project/develop_log.md
@@ -7,6 +7,34 @@
- 事件描述
- 分析处理
+## 2025-04-09 改进各导弹导弹制导系统的大气透过率计算
+
+- 使用AtmosphereDllWrapper封装的计算函数,实现了激光在大气中传输的透过率精确计算
+- 添加了新的CalculateLaserTransmittance方法,简化对大气透过率的计算
+- 改进了接收功率计算逻辑,考虑了以下因素:
+ - 激光从发射器到目标的大气衰减
+ - 目标反射光从目标到导弹的大气衰减
+ - 发射系统透过率和接收系统透过率
+ - 激光波长对透过率的影响
+ - 增加了红外图像的最小像素限制
+- 模拟效果改进:
+ - 在不同天气条件下的导引性能变化更加符合物理规律
+ - 远距离目标的锁定概率降低,符合实际武器系统特性
+ - 雾天、雨天等恶劣天气条件下制导性能降低,更加真实
+
+## 2025-03-10 优化激光半主动导弹的制导加速度计算
+
+- 降低了比例导引系数从 3 降至 2,使最大加速度从 ±18 降低到 ±12左右
+- 降低了四象限探测器的灵敏度spotOffsetSensitivity,从 0.5 到 0.05
+- 实现了制导加速度平滑处理机制,通过加速度历史值加权平均的方式减少突变
+- 利用四象限探测器误差死区机制(误差阈值0.01),当探测器误差在死区范围内时不产生制导指令
+- 修改后的效果:
+ - 当光斑在四象限探测器中心位置时,制导加速度保持为0
+ - 微小光斑偏移不再引起过度调整
+ - 制导加速度变化更加平滑,减少了能量消耗
+ - 导弹飞行轨迹更加稳定,飞行姿态变化更平滑
+- 系统稳定性得到显著提升,特别是在瞄准目标过程中的稳定性
+
## 2025-03-05 修改各导弹运行中的一些 BUG,修改日志的输出方式
- 修改了日志的输出方式,使用 Debug 和 Trace 输出日志
- 修改了 Vector3D 中归一化和点积的计算,避免因为浮点数的精度问题导致出现NaN错误
diff --git a/docs/project/theory.md b/docs/project/theory.md
index 55aed57..a1ec553 100644
--- a/docs/project/theory.md
+++ b/docs/project/theory.md
@@ -71,3 +71,129 @@ z &= \sin(\alpha)\cos(\beta)
其中:
- α:扫描半径角(与前向轴夹角)
- β:扫描方位角(旋转角度)
+
+# 激光半主动导引头接收功率计算
+
+## 1. 基本原理
+
+激光半主动导引系统工作原理:地面或机载激光指示器照射目标,目标反射激光能量,导弹上的导引头接收反射激光,通过四象限探测器确定目标方位,实现精确打击。
+
+## 2. 激光能量传输模型
+
+激光能量在传输过程中受多种因素影响,包括发散、大气衰减、反射损耗等。激光从发射到被导弹接收分为两个阶段:
+
+### 2.1 发射器到目标阶段
+
+激光功率密度在目标处的计算:
+
+```math
+I_{target} = \frac{P_t \cdot \tau_a(R_1) \cdot \tau_t}{\pi \cdot (R_1 \cdot \tan(\theta/2))^2}
+```
+
+其中:
+- $I_{target}$:目标处的激光功率密度(W/m²)
+- $P_t$:激光发射功率(W)
+- $\tau_a(R_1)$:大气透过率(从发射器到目标)
+- $\tau_t$:发射系统透过率
+- $R_1$:发射器到目标的距离(m)
+- $\theta$:激光发散角(rad)
+
+### 2.2 目标到导弹阶段
+
+目标反射光被导弹接收的功率计算:
+
+```math
+P_r = I_{target} \cdot \rho \cdot A_{target} \cdot \tau_a(R_2) \cdot \tau_r \cdot \frac{A_{receiver}}{2\pi \cdot R_2^2}
+```
+
+其中:
+- $P_r$:导弹接收的功率(W)
+- $\rho$:目标反射系数
+- $A_{target}$:目标有效反射面积(m²)
+- $\tau_a(R_2)$:大气透过率(从目标到导弹)
+- $\tau_r$:接收系统透过率
+- $A_{receiver}$:接收器有效面积(m²)
+- $R_2$:目标到导弹的距离(m)
+
+### 2.3 综合计算公式
+
+综合上述两个阶段,导弹接收功率的完整计算公式为:
+
+```math
+P_r = \frac{P_t \cdot \tau_a(R_1) \cdot \tau_t \cdot \rho \cdot A_{target} \cdot \tau_a(R_2) \cdot \tau_r \cdot A_{receiver}}{2\pi^2 \cdot R_1^2 \cdot R_2^2 \cdot \tan^2(\theta/2)}
+```
+
+## 3. 接收光学系统处理
+
+### 3.1 光学系统聚焦效应
+
+当入射光通过接收光学系统聚焦时,功率密度会增加:
+
+```math
+G_{focus} = \frac{A_{sensor}}{A_{spot}}
+```
+
+其中:
+- $G_{focus}$:聚焦增益
+- $A_{sensor}$:传感器面积
+- $A_{spot}$:聚焦光斑面积
+
+### 3.2 最终接收功率
+
+考虑光学系统效应后的最终接收功率:
+
+```math
+P_{final} = P_r \cdot \min(1, \frac{A_{lens}}{A_{illuminated}}) \cdot G_{focus}
+```
+
+其中:
+- $P_{final}$:最终接收功率(W)
+- $A_{lens}$:接收镜头面积
+- $A_{illuminated}$:入射光照射面积
+- $G_{focus}$:聚焦增益
+
+## 4. 锁定判断
+
+探测器根据接收功率与锁定阈值的比较,判断是否锁定目标:
+
+```math
+\text{目标锁定} = \begin{cases}
+\text{是}, & \text{如果}\ P_{final} \geq P_{threshold} \\
+\text{否}, & \text{如果}\ P_{final} < P_{threshold}
+\end{cases}
+```
+
+其中:
+- $P_{threshold}$:锁定阈值功率(典型值为10⁻¹²W)
+
+## 5. 影响因素分析
+
+### 5.1 距离影响
+接收功率与距离的四次方成反比,是最敏感的影响因素:
+
+```math
+P_r \propto \frac{1}{R_1^2 \cdot R_2^2}
+```
+
+### 5.2 天气条件影响
+不同天气条件下的有效探测距离对比(假设其他条件相同):
+
+| 天气条件 | 相对探测距离 |
+|---------|-------------|
+| 晴朗 | 100% |
+| 轻雾 | 60-80% |
+| 浓雾 | 20-40% |
+| 雨天 | 40-60% |
+| 雪天 | 30-50% |
+
+### 5.3 目标特性影响
+目标反射特性对接收功率的影响:
+
+```math
+P_r \propto \rho \cdot A_{target}
+```
+
+典型目标反射系数:
+- 金属表面:0.2-0.9
+- 涂装表面:0.1-0.3
+- 植被背景:0.1-0.2
diff --git a/tools/ComprehensiveMissileSimulator.cs b/tools/ComprehensiveMissileSimulator.cs
index 31d8e6a..8c9a343 100644
--- a/tools/ComprehensiveMissileSimulator.cs
+++ b/tools/ComprehensiveMissileSimulator.cs
@@ -12,6 +12,7 @@ using ThreatSource.Target;
using ThreatSource.Guidance;
using ThreatSource.Indicator;
using ThreatSource.Data;
+using AirTransmission;
namespace ThreatSource.Tools.MissileSimulation
{
@@ -52,6 +53,9 @@ namespace ThreatSource.Tools.MissileSimulation
///
private void InitializeSimulation()
{
+ // 添加天气
+ AddWeathers();
+
// 添加目标(坦克)
AddTankTarget();
@@ -65,6 +69,19 @@ namespace ThreatSource.Tools.MissileSimulation
// 添加各种传感器和指示器
AddSensorsAndDesignators();
+
+
+ }
+
+ ///
+ /// 添加天气
+ ///
+ private void AddWeathers()
+ {
+ // 创建雨天天气并设置为当前天气
+ var rainWeather = _threatSourceFactory.CreateWeather("sunny");
+ simulationManager.SetWeather(rainWeather);
+ Console.WriteLine("已添加并设置晴天天气环境");
}
///
@@ -83,6 +100,10 @@ namespace ThreatSource.Tools.MissileSimulation
targets[targetId] = target;
simulationManager.RegisterEntity(targetId, target);
Console.WriteLine($"添加目标 {targetId},位置:{launchParams.Position}");
+
+ // 添加诱偏目标
+ Tank tank = (Tank)target;
+ tank.LaunchLaserDecoy(new Vector3D(0, 0, 1), 50, 25, 20);
}
///
@@ -92,8 +113,8 @@ namespace ThreatSource.Tools.MissileSimulation
{
var launchParams = new InitialMotionParameters
{
- Position = new Vector3D(2000, 10, 100),
- Orientation = new Orientation(Math.PI, -0.05, 0),
+ Position = new Vector3D(2000, 1, 100),
+ Orientation = new Orientation(Math.PI, 0.05, 0),
InitialSpeed = 700
};
string missileId = "LSGM_1";
@@ -449,6 +470,19 @@ namespace ThreatSource.Tools.MissileSimulation
///
private void PrintSimulationStatus()
{
+ // 打印当前天气状态
+ var weather = simulationManager.CurrentWeather;
+ if (weather != null)
+ {
+ Console.WriteLine("\n========== 天气状态 ==========");
+ Console.WriteLine($"天气类型: {weather.Type}");
+ Console.WriteLine($"温度: {weather.Temperature}°C");
+ Console.WriteLine($"湿度: {weather.RelativeHumidity}%");
+ Console.WriteLine($"能见度: {weather.Visibility}公里");
+ Console.WriteLine($"风速: {weather.WindSpeed}米/秒");
+ Console.WriteLine($"风向: {weather.WindDirection}°");
+ }
+
// 打印所有活跃导弹的状态
var activeMissiles = simulationManager.GetEntitiesByType()
.Where(m => m.IsActive);
@@ -619,5 +653,26 @@ namespace ThreatSource.Tools.MissileSimulation
Console.WriteLine($"指示器 {GetIndicatorDisplayName(indicator)} 已{(indicator.IsActive ? "激活" : "停用")}");
}
}
+
+ ///
+ /// 切换天气
+ ///
+ /// 天气类型
+ public void SwitchWeather(string weatherType)
+ {
+ // 创建新的天气实例
+ var newWeather = _threatSourceFactory.CreateWeather(weatherType);
+
+ // 设置为当前天气
+ simulationManager.SetWeather(newWeather);
+
+ // 打印天气详情
+ Console.WriteLine($"已切换到 {weatherType} 天气环境");
+ Console.WriteLine($"温度: {newWeather.Temperature}°C");
+ Console.WriteLine($"湿度: {newWeather.RelativeHumidity}%");
+ Console.WriteLine($"能见度: {newWeather.Visibility}公里");
+ Console.WriteLine($"风速: {newWeather.WindSpeed}米/秒");
+ Console.WriteLine($"风向: {newWeather.WindDirection}°");
+ }
}
}
\ No newline at end of file
diff --git a/tools/ThreatSource.Tools.csproj b/tools/ThreatSource.Tools.csproj
index 197e1de..f26d3dd 100644
--- a/tools/ThreatSource.Tools.csproj
+++ b/tools/ThreatSource.Tools.csproj
@@ -9,6 +9,10 @@
+
+ ../ThreatSource/lib/AirTransmission.dll
+ True
+