完善了烟幕弹的干扰机制,在激光半主动导弹中生效。

This commit is contained in:
Tian jianyong 2025-04-16 16:37:50 +08:00
parent 4640aa36f8
commit 3d635f6180
40 changed files with 152 additions and 868 deletions

View File

@ -1,13 +0,0 @@
{
"name": {
"zh": "红外测角仪-001",
"en": "IR Tracker-001"
},
"type": "InfraredTracker",
"infraredTrackerConfig": {
"maxTrackingRange": 10000.0,
"fieldOfView": 0.2,
"angleMeasurementAccuracy": 0.001,
"updateFrequency": 10.0
}
}

View File

@ -1,18 +0,0 @@
{
"name": {
"zh": "激光驾束仪-001",
"en": "Laser Beam Rider-001"
},
"type": "LaserBeamRider",
"beamRiderConfig": {
"laserPower": 1000,
"laserWavelength": 1.06,
"controlFieldDiameter": 6.0,
"laserCodeConfig": {
"code": {
"codeType": "PRF",
"codeValue": 1010
}
}
}
}

View File

@ -1,18 +0,0 @@
{
"name": {
"zh": "前视激光指示器-001",
"en": "Forward Looking Laser Designator-001"
},
"type": "LaserDesignator",
"designatorConfig": {
"laserPower": 5000,
"laserWavelength": 1.06,
"laserDivergenceAngle": 0.0003,
"laserCodeConfig": {
"code": {
"codeType": "PRF",
"codeValue": 1010
}
}
}
}

View File

@ -1,14 +0,0 @@
{
"name": {
"zh": "激光诱偏目标",
"en": "Laser Decoy"
},
"type": "LaserDecoy",
"LaserDecoyConfig": {
"decoyPower": 25.0,
"decoyLaserDivergenceAngle": 0.001,
"reflectiveArea": 1.2,
"reflectionCoefficient": 0.8,
"lifeTime": 60.0
}
}

View File

@ -1,18 +0,0 @@
{
"name": {
"zh": "周边烟幕弹",
"en": "Surround Smoke Grenade"
},
"type": "SmokeGrenade",
"SmokeGrenadeConfig": {
"smokeType": "Wall",
"concentration": 0.2,
"duration": 60.0,
"wallWidth": 50.0,
"wallHeight": 10.0,
"cloudDiameter": 0.0,
"thickness": 5.0,
"formationDelay": 1.5,
"expansionRate": 5.0
}
}

View File

@ -1,18 +0,0 @@
{
"name": {
"zh": "顶部烟幕弹",
"en": "Top Smoke Grenade"
},
"type": "SmokeGrenade",
"SmokeGrenadeConfig": {
"smokeType": "Cloud",
"concentration": 0.2,
"duration": 60.0,
"wallWidth": 0.0,
"wallHeight": 0.0,
"cloudDiameter": 20.0,
"thickness": 5.0,
"formationDelay": 1.5,
"expansionRate": 5.0
}
}

View File

@ -1,27 +0,0 @@
{
"name": {
"zh": "红外指令导引导弹-001",
"en": "IR Command Guided Missile-001"
},
"type": "InfraredCommandGuidance",
"properties": {
"maxSpeed": 300.0,
"maxFlightTime": 60.0,
"maxFlightDistance": 5000.0,
"maxAcceleration": 100.0,
"proportionalNavigationCoefficient": 3.0,
"launchAcceleration": 100.0,
"maxEngineBurnTime": 0.1,
"cruiseTime": 5.0,
"mass": 23.5,
"explosionRadius": 5.0,
"hitProbability": 0.9,
"selfDestructHeight": 0.0,
"trackerSensitivity": null,
"commandLatency": null,
"irSignature": null
},
"infraredCommandGuidanceConfig": {
"jammingResistanceThreshold": 1e-3
}
}

View File

@ -1,34 +0,0 @@
{
"name": {
"zh": "红外成像末制导导弹-001",
"en": "IR Imaging Terminal Guided Missile-001"
},
"type": "InfraredImagingTerminalGuidance",
"properties": {
"maxSpeed": 250.0,
"maxFlightTime": 60.0,
"maxFlightDistance": 5000.0,
"maxAcceleration": 100.0,
"proportionalNavigationCoefficient": 3.0,
"launchAcceleration": 100.0,
"maxEngineBurnTime": 0.1,
"cruiseTime": 5.0,
"mass": 25.0,
"explosionRadius": 5.5,
"hitProbability": 0.9,
"selfDestructHeight": 0.0
},
"infraredImagingGuidanceConfig": {
"maxDetectionRange": 1000,
"searchFieldOfView": 0.209,
"trackFieldOfView": 0.052,
"imageWidth": 640,
"imageHeight": 512,
"backgroundIntensity": 0.01,
"searchRecognitionProbability": 0.6,
"trackRecognitionProbability": 0.8,
"targetLostTolerance": 0.2,
"lockConfirmationTime": 0.3,
"jammingResistanceThreshold": 1e-3
}
}

View File

@ -1,41 +0,0 @@
{
"name": {
"zh": "红箭-10",
"en": "HJ-10"
},
"type": "LaserBeamRiderGuidance",
"properties": {
"maxSpeed": 300.0,
"maxFlightTime": 60.0,
"maxFlightDistance": 5000.0,
"maxAcceleration": 100.0,
"proportionalNavigationCoefficient": 3.0,
"launchAcceleration": 100.0,
"maxEngineBurnTime": 0.1,
"cruiseTime": 5.0,
"mass": 24.5,
"explosionRadius": 5.0,
"hitProbability": 0.9,
"selfDestructHeight": 0.0,
"laserCodeConfig": {
"code": {
"codeType": "PRF",
"codeValue": 1010
},
"IsCodeEnabled": true,
"IsCodeMatchRequired": true
}
},
"LaserBeamRiderGuidanceConfig": {
"minDetectablePower": 1e-10,
"detectorDiameter": 0.03,
"controlFieldDiameter": 20.0,
"proportionalGain": 30.0,
"integralGain": 0.05,
"derivativeGain": 5.0,
"nonlinearGain": 0.5,
"maxGuidanceAcceleration": 50.0,
"lowPassFilterCoefficient": 0.2,
"jammingResistanceThreshold": 1e-3
}
}

View File

@ -1,27 +0,0 @@
{
"name": {
"zh": "科尔内特",
"en": "Kornet"
},
"type": "LaserBeamRiderGuidance",
"properties": {
"maxSpeed": 300.0,
"maxFlightTime": 70.0,
"maxFlightDistance": 5500.0,
"maxAcceleration": 110.0,
"proportionalNavigationCoefficient": 3.0,
"launchAcceleration": 100.0,
"maxEngineBurnTime": 12.0,
"cruiseTime": 5.0,
"mass": 27.0,
"explosionRadius": 5.5,
"hitProbability": 0.9,
"selfDestructHeight": 10.0,
"laserCodeConfig": {
"code": {
"codeType": "PRF",
"codeValue": 1100
}
}
}
}

View File

@ -1,27 +0,0 @@
{
"name": {
"zh": "陶式导弹",
"en": "TOW"
},
"type": "LaserBeamRiderGuidance",
"properties": {
"maxSpeed": 278.0,
"maxFlightTime": 65.0,
"maxFlightDistance": 4500.0,
"maxAcceleration": 100.0,
"proportionalNavigationCoefficient": 3.0,
"launchAcceleration": 100.0,
"maxEngineBurnTime": 10.0,
"cruiseTime": 5.0,
"mass": 22.6,
"explosionRadius": 5.0,
"hitProbability": 0.9,
"selfDestructHeight": 10.0,
"laserCodeConfig": {
"code": {
"codeType": "PRF",
"codeValue": 1110
}
}
}
}

View File

@ -1,43 +0,0 @@
{
"name": {
"zh": "激光半主动制导导弹-001",
"en": "Laser Semi-Active Guidance Missile-001"
},
"type": "LaserSemiActiveGuidance",
"properties": {
"maxSpeed": 800.0,
"maxFlightTime": 60.0,
"maxFlightDistance": 4000.0,
"maxAcceleration": 50.0,
"proportionalNavigationCoefficient": 2.0,
"launchAcceleration": 100.0,
"maxEngineBurnTime": 0.1,
"cruiseTime": 5.0,
"mass": 22.0,
"explosionRadius": 5.0,
"hitProbability": 0.9,
"selfDestructHeight": 0.0,
"laserCodeConfig": {
"code": {
"codeType": "PRF",
"codeValue": 1010
},
"IsCodeEnabled": true,
"IsCodeMatchRequired": true
}
},
"laserSemiActiveGuidanceConfig": {
"fieldOfViewAngle": 30.0,
"lensDiameter": 0.1,
"sensorDiameter": 0.03,
"focusedSpotDiameter": 0.006,
"reflectionCoefficient": 0.2,
"targetReflectiveArea": 1.0,
"lockThreshold": 1e-12,
"spotOffsetSensitivity": 0.05,
"jammingResistanceThreshold": 1e-3,
"transmitterEfficiency": 0.85,
"receiverEfficiency": 0.8,
"laserWavelength": 1.06
}
}

View File

@ -1,56 +0,0 @@
{
"name": {
"zh": "毫米波末制导导弹-001",
"en": "Millimeter Wave Terminal Guided Missile-001"
},
"type": "MillimeterWaveTerminalGuidance",
"properties": {
"maxSpeed": 250.0,
"maxFlightTime": 60.0,
"maxFlightDistance": 8000.0,
"maxAcceleration": 100.0,
"proportionalNavigationCoefficient": 3.0,
"launchAcceleration": 100.0,
"maxEngineBurnTime": 0.1,
"cruiseTime": 4.0,
"mass": 28.0,
"explosionRadius": 5.0,
"hitProbability": 0.9,
"selfDestructHeight": 0.0
},
"millimeterWaveGuidanceConfig": {
"maxDetectionRange": 5000.0,
"fieldOfViewAngle": 45.0,
"targetRecognitionProbability": 0.95,
"waveFrequency": 94e9,
"pulseDuration": 1e-6,
"searchBeamWidth": 4.0,
"trackBeamWidth": 2.0,
"lockBeamWidth": 1.0,
"scanAngularSpeedDeg": 360.0,
"scanRadiusGrowthRateDeg": 22.5,
"recognitionSNRThreshold": -25.0,
"lockSNRThreshold": -10.0,
"targetLostTolerance": 0.2,
"lockConfirmationTime": 0.3,
"pulseRepetitionFrequency": 1e-4,
"transmitPower": 0.3,
"dopplerVelocityResolution": 1.0,
"maxMeasurableVelocity": 1000.0,
"antennaGainDB": 23.0,
"noiseFigureDB": 7.0,
"systemLossDB": 6.0,
"monopulseSensitivity": 1,
"yawControlEffectiveness": 120.0,
"pitchControlEffectiveness": 150.0,
"jammingResistanceThreshold": 1e-3
}
}

View File

@ -1,51 +0,0 @@
{
"name": {
"zh": "末敏导弹-001",
"en": "Terminal Sensitive Missile-001"
},
"type": "TerminalSensitiveMissile",
"properties": {
"maxSpeed": 1000.0,
"maxFlightTime": 100.0,
"maxFlightDistance": 5000.0,
"maxAcceleration": 200.0,
"proportionalNavigationCoefficient": 3.0,
"launchAcceleration": 100.0,
"maxEngineBurnTime": 0.1,
"cruiseTime": 5.0,
"mass": 50.0,
"explosionRadius": 5.0,
"selfDestructHeight": 0.0
},
"submunitionProperties": {
"maxSpeed": 2000.0,
"maxFlightTime": 60.0,
"maxFlightDistance": 2000.0,
"maxAcceleration": 300.0,
"proportionalNavigationCoefficient": 4.0,
"launchAcceleration": 10.0,
"maxEngineBurnTime": 0.1,
"mass": 10.0,
"explosionRadius": 5.0,
"hitProbability": 0.9,
"selfDestructHeight": 20.0
},
"submunitionCount": 1,
"submunitionConfig": {
"separationHeight": 1000.0,
"separationDistance": 1000.0,
"submunitionSeparationAngle": 45.0,
"separationRange": 50.0,
"decelerationAcceleration": 250.0,
"decelerationEndSpeed": 50.0,
"parachuteDeploymentHeight": 400.0,
"parachuteDeceleration": 140.0,
"stableScanHeight": 200.0,
"verticalDeclineSpeed": 10.0,
"spiralRotationSpeed": 25.13,
"scanAngle": 30.0,
"targetDetectionDistance": 150.0,
"selfDestructHeight": 20.0,
"attackSpeed": 200.0
}
}

View File

@ -1,32 +0,0 @@
{
"name": {
"zh": "激光告警接收机-001",
"en": "Laser Warning Receiver-001"
},
"type": "LaserWarner",
"properties": {
"detectionRange": 5000.0,
"wavelengthRange": {
"min": 0.4,
"max": 1.7
},
"fieldOfView": 360.0,
"responseTime": 0.001,
"sensitivity": -60.0,
"angularResolution": 7.5,
"falseAlarmRate": 1e-6,
"detectionProbability": 0.95,
"spectralBands": [
{
"name": "Band1",
"minWavelength": 0.4,
"maxWavelength": 0.7
},
{
"name": "Band2",
"minWavelength": 0.7,
"maxWavelength": 1.7
}
]
}
}

View File

@ -1,34 +0,0 @@
{
"name": {
"zh": "装甲运兵车-001",
"en": "Armored Personnel Carrier-001"
},
"type": "APC",
"mass": 25000.0,
"length": 7.0,
"width": 3.2,
"height": 2.8,
"maxSpeed": 80.0,
"armorThickness": 400.0,
"radarCrossSection": 12.0,
"infraredRadiationIntensity": 2000.0,
"ultravioletRadiationIntensity": 12.0,
"millimeterWaveRadiationIntensity": 8.0,
"millimeterWaveRadiationTemperature": 350.0,
"laserReflectivity": 0.25,
"thermalPattern": {
"description": "3x3 matrix representing side view temperature distribution (°C)",
"static": [
[35, 40, 65],
[30, 35, 70],
[40, 40, 45]
],
"moving": [
[40, 45, 70],
[35, 40, 75],
[50, 50, 55]
]
}
}

View File

@ -1,34 +0,0 @@
{
"name": {
"zh": "武装直升机-001",
"en": "Attack Helicopter-001"
},
"type": "Helicopter",
"mass": 10000.0,
"length": 17.0,
"width": 3.0,
"height": 4.5,
"maxSpeed": 280.0,
"armorThickness": 150.0,
"radarCrossSection": 8.0,
"infraredRadiationIntensity": 3000.0,
"ultravioletRadiationIntensity": 20.0,
"millimeterWaveRadiationIntensity": 6.0,
"millimeterWaveRadiationTemperature": 450.0,
"laserReflectivity": 0.2,
"thermalPattern": {
"description": "3x3 matrix representing side view temperature distribution (°C)",
"static": [
[85, 110, 80],
[35, 45, 40],
[30, 35, 30]
],
"moving": [
[90, 115, 85],
[40, 50, 45],
[35, 40, 35]
]
}
}

View File

@ -1,34 +0,0 @@
{
"name": {
"zh": "主战坦克-001",
"en": "Main Battle Tank-001"
},
"type": "Tank",
"properties": {
"mass": 50000.0,
"length": 10.0,
"width": 3.5,
"height": 2.4,
"maxSpeed": 70.0,
"armorThickness": 800.0,
"radarCrossSection": 15.0,
"infraredRadiationIntensity": 2500.0,
"ultravioletRadiationIntensity": 15.0,
"millimeterWaveRadiationIntensity": 10.0,
"millimeterWaveRadiationTemperature": 400.0,
"laserReflectivity": 0.3,
"thermalPattern": {
"description": "3x3 matrix representing side view temperature distribution (°C)",
"static": [
[40, 45, 80],
[35, 40, 90],
[50, 50, 60]
],
"moving": [
[45, 50, 85],
[40, 45, 95],
[65, 65, 75]
]
}
}
}

View File

@ -1,15 +0,0 @@
{
"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
}

View File

@ -1,15 +0,0 @@
{
"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
}

View File

@ -1,15 +0,0 @@
{
"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
}

View File

@ -1,15 +0,0 @@
{
"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
}

View File

@ -1,15 +0,0 @@
{
"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
}

View File

@ -1,15 +0,0 @@
{
"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
}

View File

@ -1,15 +0,0 @@
{
"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
}

View File

@ -1,15 +0,0 @@
{
"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
}

View File

@ -1,15 +0,0 @@
{
"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
}

View File

@ -1,15 +0,0 @@
{
"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
}

View File

@ -1,15 +0,0 @@
{
"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
}

View File

@ -33,7 +33,7 @@
"focusedSpotDiameter": 0.006,
"reflectionCoefficient": 0.2,
"targetReflectiveArea": 1.0,
"lockThreshold": 1e-12,
"lockThreshold": 1e-10,
"spotOffsetSensitivity": 0.05,
"jammingResistanceThreshold": 1e-3,
"transmitterEfficiency": 0.85,

View File

@ -15,7 +15,10 @@ namespace ThreatSource.Data
/// </remarks>
public class ThreatSourceDataManager
{
private static readonly string DATA_PATH = "../ThreatSource/data";
/// <summary>
/// 默认数据目录路径
/// </summary>
private static readonly string DATA_PATH = "../data";
private static readonly JsonSerializerOptions _jsonOptions = new()
{
PropertyNameCaseInsensitive = true,
@ -25,12 +28,12 @@ namespace ThreatSource.Data
new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)
}
};
private readonly Dictionary<string, MissileData> _missiles = new();
private readonly Dictionary<string, IndicatorData> _indicators = new();
private readonly Dictionary<string, SensorData> _sensors = new();
private readonly Dictionary<string, EquipmentData> _targets = new();
private readonly Dictionary<string, WeatherData> _weathers = new();
private readonly Dictionary<string, JammerData> _jammers = new();
private readonly Dictionary<string, MissileData> _missiles = [];
private readonly Dictionary<string, IndicatorData> _indicators = [];
private readonly Dictionary<string, SensorData> _sensors = [];
private readonly Dictionary<string, EquipmentData> _targets = [];
private readonly Dictionary<string, WeatherData> _weathers = [];
private readonly Dictionary<string, JammerData> _jammers = [];
/// <summary>
/// 初始化威胁源数据管理器
/// </summary>

View File

@ -36,6 +36,11 @@ namespace ThreatSource.Guidance
/// </summary>
public bool IsJammed => _jammingComponent.IsJammed;
/// <summary>
/// 设置或获取设备当前是否处于硬干扰状态
/// </summary>
protected bool IsHardJammed { get; private set; } = false;
/// <summary>
/// 获取或设置父实体ID
/// </summary>
@ -233,10 +238,13 @@ namespace ThreatSource.Guidance
protected virtual void HandleJammingApplied(JammingParameters parameters)
{
// 子类可以重写此方法以实现特定的干扰响应
Console.WriteLine($"导引系统受到{parameters.Type}类型干扰,功率:{parameters.Power}W");
// 干扰应用后,设置无有效制导
HasGuidance = false;
// 默认:非烟幕干扰是硬干扰
if (parameters.Type != JammingType.SmokeScreen)
{
this.IsHardJammed = true;
this.HasGuidance = false; // 硬干扰立即停止制导
Trace.WriteLine($"[{this.GetType().Name}] 硬干扰已应用: {parameters.Type}");
}
}
/// <summary>
@ -246,12 +254,27 @@ namespace ThreatSource.Guidance
protected virtual void HandleJammingCleared(JammingType type)
{
// 子类可以重写此方法以实现干扰清除后的特定行为
Console.WriteLine($"导引系统{type}类型干扰已清除");
// 干扰清除后恢复制导状态
// 注意:实际制导能力需要根据当前情况确定,此处默认为恢复
HasGuidance = true;
if (type != JammingType.SmokeScreen)
{
// 尝试清除硬干扰标志。如果还有其他硬干扰,组件状态可能仍反映,
// 或者后续 ApplyJamming 会再次设置 IsHardJammed。
// 简化处理:清除任何硬干扰时都清除标志。
this.IsHardJammed = false;
Trace.WriteLine($"[{this.GetType().Name}] 硬干扰已清除: {type}");
}
// 子类需要重写此方法来处理 SmokeScreen 清除。
// 检查整体干扰状态
if (!this._jammingComponent.IsJammed)
{
this.IsHardJammed = false; // 确保清除
this.HasGuidance = true; // 恢复制导
Trace.WriteLine($"[{this.GetType().Name}] 所有干扰已清除。");
}
// 如果 _jammingComponent 仍然 IsJammed (因为可能有烟幕)
// HasGuidance 的最终状态由 Update 决定。
}
/// <summary>
/// 初始化干扰阈值和支持的干扰类型
/// </summary>

View File

@ -112,6 +112,11 @@ namespace ThreatSource.Guidance
/// </remarks>
private const double AccelerationSmoothingFactor = 0.5;
/// <summary>
/// 烟幕衰减
/// </summary>
private double SmokeAttenuation { get; set; } = 1.0;
/// <summary>
/// 激光目标列表,包括真实目标和诱偏目标
/// </summary>
@ -311,14 +316,14 @@ namespace ThreatSource.Guidance
// 使用JammableComponent进行干扰判断
ApplyJamming(parameters);
// 如果被干扰,切换到搜索模式
if (IsJammed)
// 如果被干扰,切换到搜索模式
if (IsHardJammed)
{
// 清除目标信息
TargetPosition = Vector3D.Zero;
LaserIlluminationOn = false;
// 记录干扰信息
Trace.WriteLine($"激光半主动制导系统被干扰 - 功率: {evt.JammingPower}W, 位置: {evt.JammingSourcePosition}, 方向: {evt.JammingDirection}");
Trace.WriteLine($"激光半主动制导系统被干扰 - 功率: {evt.JammingPower}W, 位置: {evt.JammingSourcePosition}, 方向: {evt.JammingDirection}");
}
}
@ -331,15 +336,14 @@ namespace ThreatSource.Guidance
if (evt != null && evt.SmokeGrenadeId != null)
{
// 获取烟幕弹的配置
var smokeGrenade = SimulationManager.GetEntityById(evt.SmokeGrenadeId) as SmokeGrenade;
if (smokeGrenade != null)
if (SimulationManager.GetEntityById(evt.SmokeGrenadeId) is SmokeGrenade smokeGrenade)
{
var config = smokeGrenade.config;
// 创建干扰参数
var parameters = new JammingParameters
{
Type = JammingType.SmokeScreen,
JammerId = smokeGrenade.Id,
SourcePosition = smokeGrenade.Position,
Direction = smokeGrenade.Orientation.ToVector(),
AngleRange = config.SmokeType == SmokeScreenType.Wall ? Math.PI : Math.PI * 2, // 墙状烟幕为半球形覆盖,云状为全方位
@ -352,12 +356,6 @@ namespace ThreatSource.Guidance
// 使用JammableComponent进行干扰判断
ApplyJamming(parameters);
// 如果被干扰,记录信息
if (IsJammed)
{
Debug.WriteLine($"激光半主动制导系统被烟幕干扰 - 浓度: {config.Concentration}g/m³, 位置: {smokeGrenade.Position}, 类型: {config.SmokeType}");
}
}
}
}
@ -368,48 +366,25 @@ namespace ThreatSource.Guidance
/// <param name="parameters">干扰参数</param>
protected override void HandleJammingApplied(JammingParameters parameters)
{
base.HandleJammingApplied(parameters);
if (parameters.Type == JammingType.Laser)
{
Debug.WriteLine($"激光半主动制导系统受到激光干扰,功率:{parameters.Power}瓦特");
// 确保基类的处理逻辑被调用设置HasGuidance = false
base.HandleJammingApplied(parameters);
// 在强干扰下切换到搜索模式
{
// 在硬干扰下切换到搜索模式
if (LaserIlluminationOn)
{
LaserIlluminationOn = false;
HasGuidance = false;
PreviousGuidanceAcceleration = Vector3D.Zero; // 重置历史加速度
}
}
else if (parameters.Type == JammingType.SmokeScreen)
{
Debug.WriteLine($"激光半主动制导系统受到烟幕干扰,浓度:{parameters.SmokeConcentration}g/m³");
// 确保基类的处理逻辑被调用设置HasGuidance = false
base.HandleJammingApplied(parameters);
// 在烟幕干扰下,降低激光功率并可能失去锁定
if (LaserIlluminationOn)
if (SimulationManager.GetEntityById(parameters.JammerId) is SmokeGrenade smokeGrenade)
{
// 烟幕会显著衰减激光功率
double attenuationFactor = CalculateSmokeAttenuation(parameters);
ReceivedLaserPower *= attenuationFactor;
// 如果功率降低到阈值以下,失去锁定
if (ReceivedLaserPower < config.LockThreshold)
// 计算烟幕衰减
if (LaserIlluminationOn)
{
Debug.WriteLine($"激光半主动制导系统因烟幕干扰失去锁定,接收功率降至:{ReceivedLaserPower:E}W");
LaserIlluminationOn = false;
HasGuidance = false;
PreviousGuidanceAcceleration = Vector3D.Zero; // 重置历史加速度
}
else
{
Debug.WriteLine($"激光半主动制导系统受烟幕影响,接收功率降至:{ReceivedLaserPower:E}W但仍保持锁定");
// 更新光斑偏移(烟幕可能导致光斑偏移)
Vector2D spotOffset = CalculateSpotOffset();
// 重新处理激光信号
quadrantDetector.ProcessLaserSignal(ReceivedLaserPower, spotOffset);
SmokeAttenuation = smokeGrenade.GetSmokeTransmittanceOnLine(Position, TargetPosition, config.LaserWavelength);
}
}
}
@ -421,18 +396,7 @@ namespace ThreatSource.Guidance
/// <param name="type">被清除的干扰类型</param>
protected override void HandleJammingCleared(JammingType type)
{
if (type == JammingType.Laser)
{
Debug.WriteLine("激光半主动制导系统激光干扰已清除");
// 确保基类的处理逻辑被调用
base.HandleJammingCleared(type);
}
else if (type == JammingType.SmokeScreen)
{
Debug.WriteLine("激光半主动制导系统烟幕干扰已清除");
// 确保基类的处理逻辑被调用
base.HandleJammingCleared(type);
}
base.HandleJammingCleared(type);
}
/// <summary>
@ -444,30 +408,21 @@ namespace ThreatSource.Guidance
public override void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity)
{
base.Update(deltaTime, missilePosition, missileVelocity);
// 处理接收到的所有激光信号
ProcessLaserTargets();
if (!IsJammed)
{
// 处理接收到的所有激光信号
ProcessLaserTargets();
if (LaserIlluminationOn && !IsHardJammed)
{
// 更新制导状态
HasGuidance = quadrantDetector.IsTargetLocked;
if (LaserIlluminationOn)
if (HasGuidance)
{
// 更新制导状态
HasGuidance = quadrantDetector.IsTargetLocked;
if (HasGuidance)
{
CalculateGuidanceAcceleration(deltaTime);
}
else
{
GuidanceAcceleration = Vector3D.Zero;
PreviousGuidanceAcceleration = Vector3D.Zero; // 重置历史加速度
}
CalculateGuidanceAcceleration(deltaTime);
}
else
{
HasGuidance = false;
GuidanceAcceleration = Vector3D.Zero;
PreviousGuidanceAcceleration = Vector3D.Zero; // 重置历史加速度
}
@ -514,7 +469,6 @@ namespace ThreatSource.Guidance
}
double receivedPower = 0;
Console.WriteLine($"处理激光信号: 目标ID: {target.Target.Id}, 目标位置: {target.Target.Position}, 目标角度偏差: {angleDeviation:F2}弧度, 视野范围: {config.FieldOfViewAngleInRadians:F2}弧度");
if (target.Target is LaserDecoy decoy)
{
// 计算接收功率
@ -530,11 +484,10 @@ namespace ThreatSource.Guidance
// 累加功率
ReceivedLaserPower += receivedPower;
Console.WriteLine($"处理激光信号: 总功率={ReceivedLaserPower:E}W");
// 加权位置
weightedPosition += target.Target.Position * receivedPower;
Console.WriteLine($"处理激光信号: 加权位置={weightedPosition}");
Console.WriteLine($"处理激光信号: 累加功率={ReceivedLaserPower:E}W, 加权位置={weightedPosition}");
}
// 如果总功率为0表示没有在视野范围内的激光源
@ -583,15 +536,16 @@ namespace ThreatSource.Guidance
double atmosphericTransmittanceToTarget = 1.0;
double atmosphericTransmittanceToMissile = 1.0;
// 考虑烟幕衰减,计算大气透过率
if(SimulationManager.CurrentWeather != null)
{
atmosphericTransmittanceToTarget = AtmosphereDllWrapper.CalculateTransmittance(
atmosphericTransmittanceToTarget = SmokeAttenuation * AtmosphereDllWrapper.CalculateTransmittance(
distanceDesignatorToTarget,
RadiationType.Laser,
config.LaserWavelength,
SimulationManager.CurrentWeather);
atmosphericTransmittanceToMissile = AtmosphereDllWrapper.CalculateTransmittance(
atmosphericTransmittanceToMissile = SmokeAttenuation * AtmosphereDllWrapper.CalculateTransmittance(
distanceMissileToTarget,
RadiationType.Laser,
config.LaserWavelength,

View File

@ -94,62 +94,14 @@ namespace ThreatSource.Jammable
/// <returns>如果干扰有效返回true否则返回false</returns>
public bool IsJammingEffective(JammingParameters parameters)
{
// 检查是否支持该干扰类型
if (!_jammingThresholds.TryGetValue(parameters.Type, out double threshold))
{
return false; // 不支持的干扰类型
}
// 处理烟幕干扰
if (parameters.Type == JammingType.SmokeScreen)
{
if (!parameters.SmokeConcentration.HasValue) return false;
// 获取设备位置
Vector3D smokeDevicePosition = _owner._positionProvider();
// 检查设备是否在烟幕范围内
bool inSmokeRange = false;
if (parameters.SmokeType == SmokeScreenType.Cloud)
{
// 对于云状烟幕,检查是否在半径范围内
double distanceToSmoke = (smokeDevicePosition - parameters.SourcePosition).Magnitude();
double smokeRadius = parameters.SmokeThickness.HasValue ? parameters.SmokeThickness.Value / 2 : 10.0;
inSmokeRange = distanceToSmoke <= smokeRadius;
}
else // SmokeScreenType.Wall
{
// 对于墙状烟幕,需要更复杂的计算
Vector3D smokeRelativePos = smokeDevicePosition - parameters.SourcePosition;
Vector3D smokeWallNormal = parameters.Direction.Normalize();
// 1. 检查高度范围
if (Math.Abs(smokeRelativePos.Y) <= 5.0) // 烟幕墙高10米上下5米
{
// 2. 计算到墙面的距离
double distToSmokeWall = Math.Abs(Vector3D.DotProduct(smokeRelativePos, smokeWallNormal));
if (distToSmokeWall <= 2.5) // 烟幕墙厚5米前后2.5米
{
// 3. 计算沿墙面的距离
Vector3D smokeWallDirection = Vector3D.CrossProduct(smokeWallNormal, Vector3D.UnitY).Normalize();
double distAlongSmokeWall = Math.Abs(Vector3D.DotProduct(smokeRelativePos, smokeWallDirection));
double smokeWallWidth = parameters.SmokeThickness.HasValue ? parameters.SmokeThickness.Value : 50.0;
inSmokeRange = distAlongSmokeWall <= smokeWallWidth / 2;
}
}
}
if (!inSmokeRange) return false;
// 现实合理的最小有效浓度为0.05 g/m³
// 0.05 g/m³ 是能明显影响视线和激光透过率的最低浓度
const double MIN_EFFECTIVE_CONCENTRATION = 0.05;
// 考虑阈值设置,阈值表示设备对烟幕的抗性,即能够"穿透"的最大浓度
// 阈值越高,设备越能在浓烟中工作
return parameters.SmokeConcentration.Value >= Math.Max(MIN_EFFECTIVE_CONCENTRATION, threshold);
}
// 烟幕干扰总是有效
if(parameters.Type == JammingType.SmokeScreen) return true;
// 处理普通干扰
// 计算干扰源与设备之间的矢量
@ -350,6 +302,10 @@ namespace ThreatSource.Jammable
{
_jammingProcessor.HandleJamming(parameters);
}
else
{
Console.WriteLine($"[可干扰组件] 不支持的干扰类型: {parameters.Type}");
}
}
/// <summary>

View File

@ -130,6 +130,8 @@ namespace ThreatSource.Jammer
/// <param name="deltaTime">时间步长,单位:秒</param>
public override void Update(double deltaTime)
{
Console.WriteLine($"[干扰器] 更新干扰器状态: 干扰器ID={Id}, 是否激活={IsActive}, 是否干扰={IsJamming}, 当前参数={CurrentParameters}");
if (!IsActive || !IsJamming || CurrentParameters == null)
{
return;

View File

@ -12,6 +12,11 @@ namespace ThreatSource.Jammer
/// </summary>
public JammingType Type { get; set; }
/// <summary>
/// 干扰源ID
/// </summary>
public string JammerId { get; set; } = "";
/// <summary>
/// 干扰功率,单位:瓦特
/// </summary>

View File

@ -79,6 +79,7 @@ namespace ThreatSource.Jammer
return new JammingParameters
{
Type = JammingType.SmokeScreen,
JammerId = Id,
Power = 0, // 烟幕不需要功率参数
Direction = Orientation.ToVector(),
SourcePosition = Position,
@ -143,8 +144,7 @@ namespace ThreatSource.Jammer
CurrentParameters.SmokeWallHeight = config.WallHeight + expansionAmount;
CurrentParameters.SmokeDiameter = null;
}
// 发布烟幕状态更新事件
// 发布烟幕状态更新事件
PublishSmokeEvent();
// 检查是否需要停止烟幕效果
@ -206,7 +206,27 @@ namespace ThreatSource.Jammer
};
PublishEvent(evt);
}
/// <summary>
/// 计算观察者到目标的视线穿过烟雾的透射率
/// </summary>
/// <param name="observerPosition">观察者位置</param>
/// <param name="targetPosition">目标位置</param>
/// <param name="wavelength">激光波长</param>
/// <returns>透射率范围0-10表示完全衰减1表示无衰减</returns>
public double GetSmokeTransmittanceOnLine(Vector3D observerPosition, Vector3D targetPosition, double wavelength)
{
Console.WriteLine($"[烟幕透过率计算] 观察者位置={observerPosition}, 目标位置={targetPosition}, 波长={wavelength}");
if (IsActive && IsJamming && CurrentParameters != null)
{
double concentration = CurrentParameters.SmokeConcentration ?? config.Concentration;
double thickness = GetSmokeThicknessOnLine(observerPosition, targetPosition);
return AtmosphereDllWrapper.CalculateSmokeScreenTransmittance(wavelength, concentration, thickness);
}
// 如果烟幕未激活或未开启干扰返回1表示完全透射
return 1;
}
/// <summary>
/// 计算观察者到目标的视线穿过烟雾的厚度
/// </summary>

View File

@ -111,6 +111,7 @@ namespace ThreatSource.Simulation
evt.SenderId = Id;
evt.Timestamp = DateTime.UtcNow.Ticks;
SimulationManager.PublishEvent(evt);
Console.WriteLine($"[仿真元素] 发布事件: 事件类型={evt.GetType().Name}, 发送者ID={evt.SenderId}, 时间戳={evt.Timestamp}");
}
/// <summary>

View File

@ -12,6 +12,7 @@
- 增加了激光诱偏目标的干扰功能
- 把烟幕弹和激光诱偏都统一到Jammer架构中
- 修改了装备的接口把ISpectralCharacteristics接口移除
- 修改了威胁源数据管理器,增加了数据目录路径,在用户使用 dll 库时要指定DataManager 的数据目录路径
## 2025-04-10 增加了 Jammer 架构,实现了烟幕弹逻辑

View File

@ -40,7 +40,7 @@ namespace ThreatSource.Tools.MissileSimulation
public ComprehensiveMissileSimulator()
{
simulationManager = new SimulationManager();
_dataManager = new ThreatSourceDataManager();
_dataManager = new ThreatSourceDataManager("../ThreatSource/data");
_threatSourceFactory = new ThreatSourceFactory(_dataManager, simulationManager);
missiles = new Dictionary<string, BaseMissile>();
targets = new Dictionary<string, SimulationElement>();
@ -121,9 +121,12 @@ namespace ThreatSource.Tools.MissileSimulation
};
string laserDecoyId = "LDY_1";
var laserDecoy = _threatSourceFactory.CreateJammer(laserDecoyId, "laser_decoy", motionParameters, "Tank_1") as LaserDecoy;
simulationManager.RegisterEntity(laserDecoyId, laserDecoy);
jammers[laserDecoyId] = laserDecoy as BaseJammer;
Console.WriteLine($"注册激光诱偏目标 {laserDecoyId}");
if (laserDecoy != null)
{
simulationManager.RegisterEntity(laserDecoyId, laserDecoy);
jammers[laserDecoyId] = laserDecoy as BaseJammer;
Console.WriteLine($"注册激光诱偏目标 {laserDecoyId}");
}
}
/// <summary>
@ -133,15 +136,18 @@ namespace ThreatSource.Tools.MissileSimulation
{
var motionParameters = new MotionParameters
{
Position = new Vector3D(100, 0, 0),
Orientation = new Orientation(Math.PI, 0, 0),
Position = new Vector3D(100, 5, 0),
Orientation = Orientation.FromVector(Vector3D.UnitX),
InitialSpeed = 0.0
};
string smokeGrenadeId = "SG_1";
var smokeGrenade = _threatSourceFactory.CreateJammer(smokeGrenadeId, "surround", motionParameters, "Tank_1");
simulationManager.RegisterEntity(smokeGrenadeId, smokeGrenade);
jammers[smokeGrenadeId] = smokeGrenade as BaseJammer;
Console.WriteLine($"注册烟幕弹 {smokeGrenadeId}");
if (smokeGrenade != null)
{
simulationManager.RegisterEntity(smokeGrenadeId, smokeGrenade);
jammers[smokeGrenadeId] = smokeGrenade as BaseJammer;
Console.WriteLine($"注册烟幕弹 {smokeGrenadeId}");
}
}
/// <summary>
@ -151,8 +157,8 @@ namespace ThreatSource.Tools.MissileSimulation
{
var motionParameters = new MotionParameters
{
Position = new Vector3D(2000, 1, 100),
Orientation = new Orientation(Math.PI, 0.05, 0),
Position = new Vector3D(2000, 1, 0),
Orientation = new Orientation(Math.PI, 0.01, 0),
InitialSpeed = 700
};
string missileId = "LSGM_1";
@ -359,10 +365,15 @@ namespace ThreatSource.Tools.MissileSimulation
indicators["LD_1"].Activate();
}
Console.WriteLine($"干扰器数量 {jammers.Count}");
if (jammers.ContainsKey("LDY_1"))
// if (jammers.ContainsKey("LDY_1"))
// {
// jammers["LDY_1"].Activate();
// Console.WriteLine($"激活激光诱偏目标 {jammers["LDY_1"].Id}");
// }
if (jammers.ContainsKey("SG_1"))
{
jammers["LDY_1"].Activate();
Console.WriteLine($"激活激光诱偏目标 {jammers["LDY_1"].Id}");
jammers["SG_1"].Activate();
Console.WriteLine($"激活烟幕弹 {jammers["SG_1"].Id}");
}
break;
case "LBRM_1": // 激光驾束制导导弹
@ -399,6 +410,18 @@ namespace ThreatSource.Tools.MissileSimulation
SourcePosition = position
};
switch (type)
{
case JammingType.SmokeScreen:
jammingParams.JammerId = "SG_1";
jammers["SG_1"].Activate();
break;
case JammingType.Decoy:
jammingParams.JammerId = "LDY_1";
jammers["LDY_1"].Activate();
break;
}
foreach (var missile in missiles.Values)
{
if (missile is BaseMissile actualMissile)