增加了Indicator基类,实现了红外测角仪的干扰处理
This commit is contained in:
parent
8a27dd5077
commit
7bf191a61d
@ -1,10 +1,13 @@
|
||||
---
|
||||
description: 坐标系相关定义
|
||||
description:
|
||||
globs:
|
||||
alwaysApply: false
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# 坐标系约定
|
||||
|
||||
- 采用右手坐标系
|
||||
- Y 轴为垂直轴
|
||||
|
||||
# 运行命令
|
||||
- 在运行命令前,先运行 pwd 命令,了解当前目录
|
||||
@ -18,10 +18,15 @@ namespace ThreatSource.Tests.Guidance
|
||||
_testAdapter = new TestSimulationAdapter(_simulationManager);
|
||||
_simulationManager.SetSimulationAdapter(_testAdapter);
|
||||
|
||||
var laserCodeConfig = new LaserCodeConfig();
|
||||
var guidanceConfig = new LaserSemiActiveGuidanceConfig();
|
||||
|
||||
_guidanceSystem = new LaserSemiActiveGuidanceSystem(
|
||||
"guidance1",
|
||||
50, // maxAcceleration
|
||||
3, // guidanceCoefficient
|
||||
laserCodeConfig,
|
||||
guidanceConfig,
|
||||
_simulationManager
|
||||
);
|
||||
_guidanceSystem.ParentId = "missile1";
|
||||
@ -54,8 +59,16 @@ namespace ThreatSource.Tests.Guidance
|
||||
[Fact]
|
||||
public void SetCodeMatchRequired_SetsRequirementCorrectly()
|
||||
{
|
||||
// Act
|
||||
_guidanceSystem.SetCodeMatchRequired(true);
|
||||
// 创建一个 LaserCodeConfig 对象
|
||||
var laserCodeConfig = new LaserCodeConfig
|
||||
{
|
||||
IsCodeMatchRequired = true
|
||||
};
|
||||
|
||||
// Act - 我们设置新的期望编码,包含配置信息
|
||||
_guidanceSystem.SetExpectedLaserCode(LaserCodeType.PRF, 1234);
|
||||
|
||||
// 注意:无法直接测试内部状态,这个测试依赖于后续的功能测试
|
||||
|
||||
// Assert - We can't directly check the private field, but we can test the behavior
|
||||
// This will be tested in the ProcessLaserIlluminationEvent test
|
||||
@ -66,17 +79,19 @@ namespace ThreatSource.Tests.Guidance
|
||||
{
|
||||
// Arrange
|
||||
_guidanceSystem.SetExpectedLaserCode(LaserCodeType.PRF, 1234);
|
||||
_guidanceSystem.SetCodeMatchRequired(true);
|
||||
|
||||
var illuminationEvent = new LaserIlluminationStartEvent
|
||||
{
|
||||
LaserDesignatorId = "laser1",
|
||||
TargetId = "target1",
|
||||
IsCodeEnabled = true,
|
||||
LaserCode = new LaserCode
|
||||
LaserCodeConfig = new LaserCodeConfig
|
||||
{
|
||||
CodeType = LaserCodeType.PRF,
|
||||
CodeValue = 1234
|
||||
IsCodeEnabled = true,
|
||||
Code = new LaserCode
|
||||
{
|
||||
CodeType = LaserCodeType.PRF,
|
||||
CodeValue = 1234
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -90,9 +105,9 @@ namespace ThreatSource.Tests.Guidance
|
||||
var lastEvent = matchEvents[matchEvents.Count - 1];
|
||||
Assert.Equal("missile1", lastEvent.MissileId);
|
||||
Assert.Equal("laser1", lastEvent.DesignatorId);
|
||||
Assert.NotNull(lastEvent.MatchedCode);
|
||||
Assert.Equal(LaserCodeType.PRF, lastEvent.MatchedCode.CodeType);
|
||||
Assert.Equal(1234, lastEvent.MatchedCode.CodeValue);
|
||||
Assert.NotNull(lastEvent.MatchedCodeConfig);
|
||||
Assert.Equal(LaserCodeType.PRF, lastEvent.MatchedCodeConfig.Code.CodeType);
|
||||
Assert.Equal(1234, lastEvent.MatchedCodeConfig.Code.CodeValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -100,17 +115,19 @@ namespace ThreatSource.Tests.Guidance
|
||||
{
|
||||
// Arrange
|
||||
_guidanceSystem.SetExpectedLaserCode(LaserCodeType.PRF, 1234);
|
||||
_guidanceSystem.SetCodeMatchRequired(true);
|
||||
|
||||
var illuminationEvent = new LaserIlluminationStartEvent
|
||||
{
|
||||
LaserDesignatorId = "laser1",
|
||||
TargetId = "target1",
|
||||
IsCodeEnabled = true,
|
||||
LaserCode = new LaserCode
|
||||
LaserCodeConfig = new LaserCodeConfig
|
||||
{
|
||||
CodeType = LaserCodeType.PRF,
|
||||
CodeValue = 5678 // Different code value
|
||||
IsCodeEnabled = true,
|
||||
Code = new LaserCode
|
||||
{
|
||||
CodeType = LaserCodeType.PRF,
|
||||
CodeValue = 5678 // Different code value
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -124,12 +141,12 @@ namespace ThreatSource.Tests.Guidance
|
||||
var lastEvent = mismatchEvents[mismatchEvents.Count - 1];
|
||||
Assert.Equal("missile1", lastEvent.MissileId);
|
||||
Assert.Equal("laser1", lastEvent.DesignatorId);
|
||||
Assert.NotNull(lastEvent.ExpectedCode);
|
||||
Assert.Equal(LaserCodeType.PRF, lastEvent.ExpectedCode.CodeType);
|
||||
Assert.Equal(1234, lastEvent.ExpectedCode.CodeValue);
|
||||
Assert.NotNull(lastEvent.ReceivedCode);
|
||||
Assert.Equal(LaserCodeType.PRF, lastEvent.ReceivedCode.CodeType);
|
||||
Assert.Equal(5678, lastEvent.ReceivedCode.CodeValue);
|
||||
Assert.NotNull(lastEvent.ExpectedCodeConfig);
|
||||
Assert.Equal(LaserCodeType.PRF, lastEvent.ExpectedCodeConfig.Code.CodeType);
|
||||
Assert.Equal(1234, lastEvent.ExpectedCodeConfig.Code.CodeValue);
|
||||
Assert.NotNull(lastEvent.ReceivedCodeConfig);
|
||||
Assert.Equal(LaserCodeType.PRF, lastEvent.ReceivedCodeConfig.Code.CodeType);
|
||||
Assert.Equal(5678, lastEvent.ReceivedCodeConfig.Code.CodeValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -137,17 +154,19 @@ namespace ThreatSource.Tests.Guidance
|
||||
{
|
||||
// Arrange
|
||||
_guidanceSystem.SetExpectedLaserCode(LaserCodeType.PRF, 1234);
|
||||
_guidanceSystem.SetCodeMatchRequired(true);
|
||||
|
||||
var illuminationEvent = new LaserIlluminationStartEvent
|
||||
{
|
||||
LaserDesignatorId = "laser1",
|
||||
TargetId = "target1",
|
||||
IsCodeEnabled = true,
|
||||
LaserCode = new LaserCode
|
||||
LaserCodeConfig = new LaserCodeConfig
|
||||
{
|
||||
CodeType = LaserCodeType.PPM, // Different code type
|
||||
CodeValue = 1234
|
||||
IsCodeEnabled = true,
|
||||
Code = new LaserCode
|
||||
{
|
||||
CodeType = LaserCodeType.PPM, // Different code type
|
||||
CodeValue = 1234
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -161,12 +180,12 @@ namespace ThreatSource.Tests.Guidance
|
||||
var lastEvent = mismatchEvents[mismatchEvents.Count - 1];
|
||||
Assert.Equal("missile1", lastEvent.MissileId);
|
||||
Assert.Equal("laser1", lastEvent.DesignatorId);
|
||||
Assert.NotNull(lastEvent.ExpectedCode);
|
||||
Assert.Equal(LaserCodeType.PRF, lastEvent.ExpectedCode.CodeType);
|
||||
Assert.Equal(1234, lastEvent.ExpectedCode.CodeValue);
|
||||
Assert.NotNull(lastEvent.ReceivedCode);
|
||||
Assert.Equal(LaserCodeType.PPM, lastEvent.ReceivedCode.CodeType);
|
||||
Assert.Equal(1234, lastEvent.ReceivedCode.CodeValue);
|
||||
Assert.NotNull(lastEvent.ExpectedCodeConfig);
|
||||
Assert.Equal(LaserCodeType.PRF, lastEvent.ExpectedCodeConfig.Code.CodeType);
|
||||
Assert.Equal(1234, lastEvent.ExpectedCodeConfig.Code.CodeValue);
|
||||
Assert.NotNull(lastEvent.ReceivedCodeConfig);
|
||||
Assert.Equal(LaserCodeType.PPM, lastEvent.ReceivedCodeConfig.Code.CodeType);
|
||||
Assert.Equal(1234, lastEvent.ReceivedCodeConfig.Code.CodeValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -174,17 +193,19 @@ namespace ThreatSource.Tests.Guidance
|
||||
{
|
||||
// Arrange
|
||||
_guidanceSystem.SetExpectedLaserCode(LaserCodeType.PRF, 1234);
|
||||
_guidanceSystem.SetCodeMatchRequired(false); // Not required
|
||||
|
||||
var illuminationEvent = new LaserIlluminationStartEvent
|
||||
{
|
||||
LaserDesignatorId = "laser1",
|
||||
TargetId = "target1",
|
||||
IsCodeEnabled = false, // Code disabled
|
||||
LaserCode = new LaserCode
|
||||
LaserCodeConfig = new LaserCodeConfig
|
||||
{
|
||||
CodeType = LaserCodeType.PRF,
|
||||
CodeValue = 5678 // Different code value
|
||||
IsCodeEnabled = false, // Code disabled
|
||||
Code = new LaserCode
|
||||
{
|
||||
CodeType = LaserCodeType.PRF,
|
||||
CodeValue = 5678 // Different code value
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -201,17 +222,19 @@ namespace ThreatSource.Tests.Guidance
|
||||
{
|
||||
// Arrange
|
||||
_guidanceSystem.SetExpectedLaserCode(LaserCodeType.PRF, 1234);
|
||||
_guidanceSystem.SetCodeMatchRequired(true);
|
||||
|
||||
var illuminationEvent = new LaserIlluminationUpdateEvent
|
||||
{
|
||||
LaserDesignatorId = "laser1",
|
||||
TargetId = "target1",
|
||||
IsCodeEnabled = true,
|
||||
LaserCode = new LaserCode
|
||||
LaserCodeConfig = new LaserCodeConfig
|
||||
{
|
||||
CodeType = LaserCodeType.PRF,
|
||||
CodeValue = 1234
|
||||
IsCodeEnabled = true,
|
||||
Code = new LaserCode
|
||||
{
|
||||
CodeType = LaserCodeType.PRF,
|
||||
CodeValue = 1234
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -225,9 +248,9 @@ namespace ThreatSource.Tests.Guidance
|
||||
var lastEvent = matchEvents[matchEvents.Count - 1];
|
||||
Assert.Equal("missile1", lastEvent.MissileId);
|
||||
Assert.Equal("laser1", lastEvent.DesignatorId);
|
||||
Assert.NotNull(lastEvent.MatchedCode);
|
||||
Assert.Equal(LaserCodeType.PRF, lastEvent.MatchedCode.CodeType);
|
||||
Assert.Equal(1234, lastEvent.MatchedCode.CodeValue);
|
||||
Assert.NotNull(lastEvent.MatchedCodeConfig);
|
||||
Assert.Equal(LaserCodeType.PRF, lastEvent.MatchedCodeConfig.Code.CodeType);
|
||||
Assert.Equal(1234, lastEvent.MatchedCodeConfig.Code.CodeValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -24,22 +24,34 @@ namespace ThreatSource.Tests.Indicator
|
||||
|
||||
_config = new InfraredTrackerConfig
|
||||
{
|
||||
Id = "tracker1",
|
||||
InitialPosition = new Vector3D(0, 0, 0),
|
||||
InitialOrientation = new Orientation(0, 0, 0),
|
||||
MaxTrackingRange = 10000,
|
||||
FieldOfView = Math.PI / 3,
|
||||
AngleMeasurementAccuracy = 0.001,
|
||||
UpdateFrequency = 10
|
||||
};
|
||||
|
||||
_tank = new Tank("target1", new Vector3D(100, 0, 0), 0, _simulationManager);
|
||||
var tankInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(100, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
};
|
||||
|
||||
_tank = new Tank("target1", tankInitialMotion, _simulationManager);
|
||||
_simulationManager.RegisterEntity("target1", _tank);
|
||||
|
||||
var trackerInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
};
|
||||
|
||||
_infraredTracker = new InfraredTracker(
|
||||
"tracker1",
|
||||
"target1",
|
||||
_config,
|
||||
trackerInitialMotion,
|
||||
_simulationManager
|
||||
);
|
||||
_simulationManager.RegisterEntity("tracker1", _infraredTracker);
|
||||
@ -107,14 +119,20 @@ namespace ThreatSource.Tests.Indicator
|
||||
// 创建导弹配置
|
||||
var missileConfig = new MissileProperties
|
||||
{
|
||||
Id = "missile1",
|
||||
InitialPosition = new Vector3D(50, 0, 0),
|
||||
MaxSpeed = 1000,
|
||||
MaxAcceleration = 100,
|
||||
ProportionalNavigationCoefficient = 3
|
||||
};
|
||||
|
||||
var missileInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(50, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100
|
||||
};
|
||||
|
||||
// 注册一个导弹实体
|
||||
var missile = new InfraredCommandGuidedMissile(missileConfig, _simulationManager);
|
||||
var missile = new InfraredCommandGuidedMissile("missile1", missileConfig, missileInitialMotion, _simulationManager);
|
||||
_simulationManager.RegisterEntity("missile1", missile);
|
||||
|
||||
// 模拟导弹点亮红外热源
|
||||
@ -191,12 +209,21 @@ namespace ThreatSource.Tests.Indicator
|
||||
// Arrange
|
||||
var missileProperties = new MissileProperties
|
||||
{
|
||||
Id = "missile1",
|
||||
InitialPosition = new Vector3D(100, 0, 0),
|
||||
InitialSpeed = 100,
|
||||
MaxSpeed = 1000,
|
||||
MaxFlightTime = 100,
|
||||
MaxFlightDistance = 10000,
|
||||
MaxAcceleration = 100,
|
||||
Type = MissileType.InfraredCommandGuidance
|
||||
};
|
||||
var missile = new InfraredCommandGuidedMissile(missileProperties, _simulationManager);
|
||||
|
||||
var missileMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(100, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100
|
||||
};
|
||||
|
||||
var missile = new InfraredCommandGuidedMissile("missile1", missileProperties, missileMotion, _simulationManager);
|
||||
_simulationManager.RegisterEntity("missile1", missile);
|
||||
missile.Activate();
|
||||
|
||||
|
||||
@ -23,22 +23,34 @@ namespace ThreatSource.Tests.Indicator
|
||||
|
||||
_config = new LaserBeamRiderConfig
|
||||
{
|
||||
Id = "beamRider1",
|
||||
InitialPosition = new Vector3D(0, 0, 0),
|
||||
LaserPower = 1000,
|
||||
ControlFieldDiameter = 5.0,
|
||||
MaxGuidanceDistance = 5000
|
||||
};
|
||||
|
||||
_tank = new Tank("target1", new Vector3D(100, 0, 0), 0, _simulationManager);
|
||||
var tankInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(100, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
};
|
||||
|
||||
_tank = new Tank("target1", tankInitialMotion, _simulationManager);
|
||||
_simulationManager.RegisterEntity("target1", _tank);
|
||||
|
||||
var beamRiderInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
};
|
||||
|
||||
_laserBeamRider = new LaserBeamRider(
|
||||
"beamRider1",
|
||||
"missile1",
|
||||
"target1",
|
||||
10,
|
||||
"missile1",
|
||||
_config,
|
||||
beamRiderInitialMotion,
|
||||
_simulationManager
|
||||
);
|
||||
_simulationManager.RegisterEntity("beamRider1", _laserBeamRider);
|
||||
|
||||
@ -23,21 +23,33 @@ namespace ThreatSource.Tests.Indicator
|
||||
|
||||
_config = new LaserDesignatorConfig
|
||||
{
|
||||
Id = "laser1",
|
||||
InitialPosition = new Vector3D(0, 0, 0),
|
||||
LaserPower = 1000,
|
||||
LaserDivergenceAngle = 0.001
|
||||
};
|
||||
|
||||
_tank = new Tank("target1", new Vector3D(100, 0, 0), 0, _simulationManager);
|
||||
var tankInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(100, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
};
|
||||
|
||||
_tank = new Tank("target1", tankInitialMotion, _simulationManager);
|
||||
_simulationManager.RegisterEntity("target1", _tank);
|
||||
|
||||
var designatorInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
};
|
||||
|
||||
_laserDesignator = new LaserDesignator(
|
||||
"laser1",
|
||||
"target1",
|
||||
"missile1",
|
||||
10,
|
||||
_config,
|
||||
designatorInitialMotion,
|
||||
_simulationManager
|
||||
);
|
||||
_simulationManager.RegisterEntity("laser1", _laserDesignator);
|
||||
@ -50,7 +62,15 @@ namespace ThreatSource.Tests.Indicator
|
||||
_laserDesignator.Activate();
|
||||
|
||||
// Act
|
||||
_laserDesignator.SetLaserCode(LaserCodeType.PRF, 1234);
|
||||
_laserDesignator.LaserCodeConfig = new LaserCodeConfig
|
||||
{
|
||||
IsCodeEnabled = true,
|
||||
Code = new LaserCode
|
||||
{
|
||||
CodeType = LaserCodeType.PRF,
|
||||
CodeValue = 1234
|
||||
}
|
||||
};
|
||||
_laserDesignator.Update(0.1);
|
||||
|
||||
// Assert
|
||||
@ -58,10 +78,10 @@ namespace ThreatSource.Tests.Indicator
|
||||
Assert.NotEmpty(events);
|
||||
|
||||
var lastEvent = events[events.Count - 1];
|
||||
Assert.True(lastEvent.IsCodeEnabled);
|
||||
Assert.NotNull(lastEvent.LaserCode);
|
||||
Assert.Equal(LaserCodeType.PRF, lastEvent.LaserCode.CodeType);
|
||||
Assert.Equal(1234, lastEvent.LaserCode.CodeValue);
|
||||
Assert.NotNull(lastEvent.LaserCodeConfig);
|
||||
Assert.True(lastEvent.LaserCodeConfig.IsCodeEnabled);
|
||||
Assert.Equal(LaserCodeType.PRF, lastEvent.LaserCodeConfig.Code.CodeType);
|
||||
Assert.Equal(1234, lastEvent.LaserCodeConfig.Code.CodeValue);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -69,7 +89,15 @@ namespace ThreatSource.Tests.Indicator
|
||||
{
|
||||
// Arrange
|
||||
_laserDesignator.Activate();
|
||||
_laserDesignator.SetLaserCode(LaserCodeType.PPM, 5678);
|
||||
_laserDesignator.LaserCodeConfig = new LaserCodeConfig
|
||||
{
|
||||
IsCodeEnabled = true,
|
||||
Code = new LaserCode
|
||||
{
|
||||
CodeType = LaserCodeType.PPM,
|
||||
CodeValue = 5678
|
||||
}
|
||||
};
|
||||
|
||||
// Act
|
||||
_laserDesignator.AddCodeParameter("PulseWidth", 0.001);
|
||||
@ -80,12 +108,12 @@ namespace ThreatSource.Tests.Indicator
|
||||
Assert.NotEmpty(events);
|
||||
|
||||
var lastEvent = events[events.Count - 1];
|
||||
Assert.True(lastEvent.IsCodeEnabled);
|
||||
Assert.NotNull(lastEvent.LaserCode);
|
||||
Assert.Equal(LaserCodeType.PPM, lastEvent.LaserCode.CodeType);
|
||||
Assert.Equal(5678, lastEvent.LaserCode.CodeValue);
|
||||
Assert.True(lastEvent.LaserCode.Parameters.ContainsKey("PulseWidth"));
|
||||
Assert.Equal(0.001, lastEvent.LaserCode.Parameters["PulseWidth"]);
|
||||
Assert.NotNull(lastEvent.LaserCodeConfig);
|
||||
Assert.True(lastEvent.LaserCodeConfig.IsCodeEnabled);
|
||||
Assert.Equal(LaserCodeType.PPM, lastEvent.LaserCodeConfig.Code.CodeType);
|
||||
Assert.Equal(5678, lastEvent.LaserCodeConfig.Code.CodeValue);
|
||||
Assert.True(lastEvent.LaserCodeConfig.Code.Parameters.ContainsKey("PulseWidth"));
|
||||
Assert.Equal(0.001, lastEvent.LaserCodeConfig.Code.Parameters["PulseWidth"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -93,34 +121,52 @@ namespace ThreatSource.Tests.Indicator
|
||||
{
|
||||
// Arrange
|
||||
_laserDesignator.Activate();
|
||||
_laserDesignator.SetLaserCode(LaserCodeType.PRF, 1234);
|
||||
_laserDesignator.LaserCodeConfig = new LaserCodeConfig
|
||||
{
|
||||
IsCodeEnabled = true,
|
||||
Code = new LaserCode
|
||||
{
|
||||
CodeType = LaserCodeType.PRF,
|
||||
CodeValue = 1234
|
||||
}
|
||||
};
|
||||
|
||||
// Act - Disable code
|
||||
_laserDesignator.EnableCode(false);
|
||||
_laserDesignator.LaserCodeConfig.IsCodeEnabled = false;
|
||||
_laserDesignator.Update(0.1);
|
||||
|
||||
// Assert - Code should be disabled
|
||||
var eventsAfterDisable = _testAdapter.GetPublishedEvents<LaserIlluminationUpdateEvent>();
|
||||
Assert.NotEmpty(eventsAfterDisable);
|
||||
var lastEventAfterDisable = eventsAfterDisable[eventsAfterDisable.Count - 1];
|
||||
Assert.False(lastEventAfterDisable.IsCodeEnabled);
|
||||
Assert.NotNull(lastEventAfterDisable.LaserCodeConfig);
|
||||
Assert.False(lastEventAfterDisable.LaserCodeConfig.IsCodeEnabled);
|
||||
|
||||
// Act - Enable code again
|
||||
_laserDesignator.EnableCode(true);
|
||||
_laserDesignator.LaserCodeConfig.IsCodeEnabled = true;
|
||||
_laserDesignator.Update(0.1);
|
||||
|
||||
// Assert - Code should be enabled
|
||||
var eventsAfterEnable = _testAdapter.GetPublishedEvents<LaserIlluminationUpdateEvent>();
|
||||
Assert.NotEmpty(eventsAfterEnable);
|
||||
var lastEventAfterEnable = eventsAfterEnable[eventsAfterEnable.Count - 1];
|
||||
Assert.True(lastEventAfterEnable.IsCodeEnabled);
|
||||
Assert.NotNull(lastEventAfterEnable.LaserCodeConfig);
|
||||
Assert.True(lastEventAfterEnable.LaserCodeConfig.IsCodeEnabled);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LaserIlluminationEvents_IncludeCodeInformation()
|
||||
{
|
||||
// Arrange
|
||||
_laserDesignator.SetLaserCode(LaserCodeType.PRF, 1234);
|
||||
_laserDesignator.LaserCodeConfig = new LaserCodeConfig
|
||||
{
|
||||
IsCodeEnabled = true,
|
||||
Code = new LaserCode
|
||||
{
|
||||
CodeType = LaserCodeType.PRF,
|
||||
CodeValue = 1234
|
||||
}
|
||||
};
|
||||
|
||||
// Act - Start illumination
|
||||
_laserDesignator.Activate();
|
||||
@ -129,10 +175,10 @@ namespace ThreatSource.Tests.Indicator
|
||||
var startEvents = _testAdapter.GetPublishedEvents<LaserIlluminationStartEvent>();
|
||||
Assert.NotEmpty(startEvents);
|
||||
var startEvent = startEvents[startEvents.Count - 1];
|
||||
Assert.True(startEvent.IsCodeEnabled);
|
||||
Assert.NotNull(startEvent.LaserCode);
|
||||
Assert.Equal(LaserCodeType.PRF, startEvent.LaserCode.CodeType);
|
||||
Assert.Equal(1234, startEvent.LaserCode.CodeValue);
|
||||
Assert.NotNull(startEvent.LaserCodeConfig);
|
||||
Assert.True(startEvent.LaserCodeConfig.IsCodeEnabled);
|
||||
Assert.Equal(LaserCodeType.PRF, startEvent.LaserCodeConfig.Code.CodeType);
|
||||
Assert.Equal(1234, startEvent.LaserCodeConfig.Code.CodeValue);
|
||||
|
||||
// Act - Update illumination
|
||||
_laserDesignator.Update(0.1);
|
||||
@ -141,10 +187,10 @@ namespace ThreatSource.Tests.Indicator
|
||||
var updateEvents = _testAdapter.GetPublishedEvents<LaserIlluminationUpdateEvent>();
|
||||
Assert.NotEmpty(updateEvents);
|
||||
var updateEvent = updateEvents[updateEvents.Count - 1];
|
||||
Assert.True(updateEvent.IsCodeEnabled);
|
||||
Assert.NotNull(updateEvent.LaserCode);
|
||||
Assert.Equal(LaserCodeType.PRF, updateEvent.LaserCode.CodeType);
|
||||
Assert.Equal(1234, updateEvent.LaserCode.CodeValue);
|
||||
Assert.NotNull(updateEvent.LaserCodeConfig);
|
||||
Assert.True(updateEvent.LaserCodeConfig.IsCodeEnabled);
|
||||
Assert.Equal(LaserCodeType.PRF, updateEvent.LaserCodeConfig.Code.CodeType);
|
||||
Assert.Equal(1234, updateEvent.LaserCodeConfig.Code.CodeValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -23,21 +23,33 @@ namespace ThreatSource.Tests.Indicator
|
||||
|
||||
_config = new LaserDesignatorConfig
|
||||
{
|
||||
Id = "laser1",
|
||||
InitialPosition = new Vector3D(0, 0, 0),
|
||||
LaserPower = 1000,
|
||||
LaserDivergenceAngle = 0.001
|
||||
};
|
||||
|
||||
_tank = new Tank("target1", new Vector3D(100, 0, 0), 0, _simulationManager);
|
||||
var tankInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(100, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
};
|
||||
|
||||
_tank = new Tank("target1", tankInitialMotion, _simulationManager);
|
||||
_simulationManager.RegisterEntity("target1", _tank);
|
||||
|
||||
var designatorInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
};
|
||||
|
||||
_laserDesignator = new LaserDesignator(
|
||||
"laser1",
|
||||
"target1",
|
||||
"missile1",
|
||||
10,
|
||||
_config,
|
||||
designatorInitialMotion,
|
||||
_simulationManager
|
||||
);
|
||||
_simulationManager.RegisterEntity("laser1", _laserDesignator);
|
||||
|
||||
307
ThreatSource.Tests/src/Jamming/InfraredJammingTests.cs
Normal file
307
ThreatSource.Tests/src/Jamming/InfraredJammingTests.cs
Normal file
@ -0,0 +1,307 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using ThreatSource.Indicator;
|
||||
using ThreatSource.Jamming;
|
||||
using ThreatSource.Simulation;
|
||||
using ThreatSource.Tests.Simulation;
|
||||
using ThreatSource.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ThreatSource.Tests.Jamming
|
||||
{
|
||||
[TestClass]
|
||||
public class InfraredJammingTests
|
||||
{
|
||||
private SimulationManager _simulationManager = null!;
|
||||
private TestSimulationAdapter _testAdapter = null!;
|
||||
private InfraredTracker _infraredTracker = null!;
|
||||
|
||||
[TestInitialize]
|
||||
public void Setup()
|
||||
{
|
||||
// 初始化模拟管理器和测试适配器
|
||||
_simulationManager = new SimulationManager();
|
||||
_testAdapter = new TestSimulationAdapter(_simulationManager);
|
||||
_simulationManager.SetSimulationAdapter(_testAdapter);
|
||||
|
||||
// 创建红外测角仪配置
|
||||
var config = new InfraredTrackerConfig
|
||||
{
|
||||
MaxTrackingRange = 10000,
|
||||
FieldOfView = Math.PI / 3,
|
||||
AngleMeasurementAccuracy = 0.001,
|
||||
UpdateFrequency = 10,
|
||||
JammingResistanceThreshold = 0.05 // 设置干扰抗性阈值为50mW
|
||||
};
|
||||
|
||||
// 初始化红外测角仪
|
||||
var initialMotionParameters = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
};
|
||||
|
||||
_infraredTracker = new InfraredTracker(
|
||||
"tracker1",
|
||||
"target1",
|
||||
config,
|
||||
initialMotionParameters,
|
||||
_simulationManager
|
||||
);
|
||||
|
||||
// 注册红外测角仪
|
||||
_simulationManager.RegisterEntity("tracker1", _infraredTracker);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void InfraredJamming_TargetsTracker_TrackerIsJammed()
|
||||
{
|
||||
// Arrange
|
||||
_infraredTracker.Activate();
|
||||
|
||||
// 创建干扰事件
|
||||
var jammingEvent = new InfraredJammingEvent
|
||||
{
|
||||
JammingPower = 200, // 高于阈值
|
||||
WavelengthMin = 3,
|
||||
WavelengthMax = 5,
|
||||
JammingSourcePosition = new Vector3D(50, 0, 0),
|
||||
JammingDirection = new Vector3D(-1, 0, 0), // 指向跟踪器
|
||||
JammingAngleRange = Math.PI / 4, // 45度角
|
||||
JammingMode = JammingMode.Noise,
|
||||
Duration = null // 持续干扰
|
||||
};
|
||||
|
||||
// Act
|
||||
_simulationManager.PublishEvent(jammingEvent);
|
||||
_infraredTracker.Update(0.1);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(_infraredTracker.IsJammed, "红外测角仪应该处于被干扰状态");
|
||||
var status = _infraredTracker.GetStatus();
|
||||
Assert.IsTrue(status.Contains("干扰状态: 受干扰"), "状态信息应该反映受干扰");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void InfraredJamming_OutsideAngleRange_TrackerNotJammed()
|
||||
{
|
||||
// Arrange
|
||||
_infraredTracker.Activate();
|
||||
|
||||
// 创建角度范围外的干扰事件
|
||||
var jammingEvent = new InfraredJammingEvent
|
||||
{
|
||||
JammingPower = 200,
|
||||
WavelengthMin = 3,
|
||||
WavelengthMax = 5,
|
||||
JammingSourcePosition = new Vector3D(0, 50, 0), // 位于上方
|
||||
JammingDirection = new Vector3D(0, 0, 1), // 指向前方,不是指向跟踪器
|
||||
JammingAngleRange = 0.1, // 很小的角度范围
|
||||
JammingMode = JammingMode.Noise
|
||||
};
|
||||
|
||||
// Act
|
||||
_simulationManager.PublishEvent(jammingEvent);
|
||||
_infraredTracker.Update(0.1);
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(_infraredTracker.IsJammed, "测角仪不应该被干扰,因为干扰源不在角度范围内");
|
||||
var status = _infraredTracker.GetStatus();
|
||||
Assert.IsTrue(status.Contains("干扰状态: 正常"), "状态信息应该反映正常");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void InfraredJamming_LowPower_TrackerNotJammed()
|
||||
{
|
||||
// Arrange
|
||||
_infraredTracker.Activate();
|
||||
|
||||
// 创建低功率干扰事件
|
||||
var jammingEvent = new InfraredJammingEvent
|
||||
{
|
||||
JammingPower = 10, // 低于阈值
|
||||
WavelengthMin = 3,
|
||||
WavelengthMax = 5,
|
||||
JammingSourcePosition = new Vector3D(50, 0, 0),
|
||||
JammingDirection = new Vector3D(-1, 0, 0),
|
||||
JammingAngleRange = Math.PI / 4,
|
||||
JammingMode = JammingMode.Noise
|
||||
};
|
||||
|
||||
// Act
|
||||
_simulationManager.PublishEvent(jammingEvent);
|
||||
_infraredTracker.Update(0.1);
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(_infraredTracker.IsJammed, "测角仪不应该被干扰,因为干扰功率低于阈值");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void InfraredJamming_WrongWavelength_TrackerNotJammed()
|
||||
{
|
||||
// Arrange
|
||||
_infraredTracker.Activate();
|
||||
|
||||
// 创建错误波长的干扰事件
|
||||
var jammingEvent = new InfraredJammingEvent
|
||||
{
|
||||
JammingPower = 200,
|
||||
WavelengthMin = 6, // 不在3-5μm或8-14μm范围
|
||||
WavelengthMax = 7,
|
||||
JammingSourcePosition = new Vector3D(50, 0, 0),
|
||||
JammingDirection = new Vector3D(-1, 0, 0),
|
||||
JammingAngleRange = Math.PI / 4,
|
||||
JammingMode = JammingMode.Noise
|
||||
};
|
||||
|
||||
// Act
|
||||
_simulationManager.PublishEvent(jammingEvent);
|
||||
_infraredTracker.Update(0.1);
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(_infraredTracker.IsJammed, "测角仪不应该被干扰,因为波长不匹配");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void InfraredJamming_DifferentTargetId_TrackerNotJammed()
|
||||
{
|
||||
// Arrange
|
||||
_infraredTracker.Activate();
|
||||
|
||||
// 创建干扰事件
|
||||
var jammingEvent = new InfraredJammingEvent
|
||||
{
|
||||
JammingPower = 200,
|
||||
WavelengthMin = 3,
|
||||
WavelengthMax = 5,
|
||||
JammingSourcePosition = new Vector3D(50, 0, 0),
|
||||
JammingDirection = new Vector3D(-1, 0, 0),
|
||||
JammingAngleRange = Math.PI / 4,
|
||||
JammingMode = JammingMode.Noise
|
||||
};
|
||||
|
||||
// Act
|
||||
_simulationManager.PublishEvent(jammingEvent);
|
||||
_infraredTracker.Update(0.1);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(_infraredTracker.IsJammed, "测角仪应该被干扰,因为在干扰范围内");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void InfraredJamming_ClearedAfterDuration_TrackerNotJammed()
|
||||
{
|
||||
// Arrange
|
||||
_infraredTracker.Activate();
|
||||
|
||||
// 创建有限时间的干扰事件
|
||||
var jammingEvent = new InfraredJammingEvent
|
||||
{
|
||||
JammingPower = 200,
|
||||
WavelengthMin = 3,
|
||||
WavelengthMax = 5,
|
||||
JammingSourcePosition = new Vector3D(50, 0, 0),
|
||||
JammingDirection = new Vector3D(-1, 0, 0),
|
||||
JammingAngleRange = Math.PI / 4,
|
||||
JammingMode = JammingMode.Noise,
|
||||
Duration = 0.5 // 0.5秒后过期
|
||||
};
|
||||
|
||||
// Act - 应用干扰
|
||||
_simulationManager.PublishEvent(jammingEvent);
|
||||
_infraredTracker.Update(0.1);
|
||||
|
||||
// Assert - 确认已被干扰
|
||||
Assert.IsTrue(_infraredTracker.IsJammed, "红外测角仪应该处于被干扰状态");
|
||||
|
||||
// Act - 等待干扰过期
|
||||
// 注意:这里我们需要模拟 JammingHandler 的更新,而不只是 InfraredTracker 的更新
|
||||
// 通常在实际运行中,JammingHandler 会在每帧更新时被调用
|
||||
// 这里我们直接多次更新 InfraredTracker,其内部会更新 JammingHandler
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
_infraredTracker.Update(0.1); // 总共更新1秒,超过干扰持续时间
|
||||
}
|
||||
|
||||
// Assert - 确认干扰已清除
|
||||
Assert.IsFalse(_infraredTracker.IsJammed, "干扰持续时间结束后,红外测角仪应该恢复正常");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void InfraredJamming_ManualClear_TrackerNotJammed()
|
||||
{
|
||||
// Arrange
|
||||
_infraredTracker.Activate();
|
||||
|
||||
// 创建持续干扰事件
|
||||
var jammingEvent = new InfraredJammingEvent
|
||||
{
|
||||
JammingPower = 200,
|
||||
WavelengthMin = 3,
|
||||
WavelengthMax = 5,
|
||||
JammingSourcePosition = new Vector3D(50, 0, 0),
|
||||
JammingDirection = new Vector3D(-1, 0, 0),
|
||||
JammingAngleRange = Math.PI / 4,
|
||||
JammingMode = JammingMode.Noise,
|
||||
Duration = null // 持续干扰
|
||||
};
|
||||
|
||||
// Act - 应用干扰
|
||||
_simulationManager.PublishEvent(jammingEvent);
|
||||
_infraredTracker.Update(0.1);
|
||||
|
||||
// Assert - 确认已被干扰
|
||||
Assert.IsTrue(_infraredTracker.IsJammed, "红外测角仪应该处于被干扰状态");
|
||||
|
||||
// Act - 手动清除干扰
|
||||
_infraredTracker.ClearJamming(JammingType.Infrared);
|
||||
_infraredTracker.Update(0.1);
|
||||
|
||||
// Assert - 确认干扰已清除
|
||||
Assert.IsFalse(_infraredTracker.IsJammed, "手动清除后,红外测角仪应该恢复正常");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void InfraredJamming_TrackingDisabledDuringJamming()
|
||||
{
|
||||
// 设置红外测角仪的目标和导弹ID,使其进入跟踪状态
|
||||
typeof(InfraredTracker).GetProperty("MissileId")?.SetValue(_infraredTracker, "missile1");
|
||||
|
||||
// Arrange
|
||||
_infraredTracker.Activate();
|
||||
|
||||
// 创建干扰事件
|
||||
var jammingEvent = new InfraredJammingEvent
|
||||
{
|
||||
JammingPower = 200,
|
||||
WavelengthMin = 3,
|
||||
WavelengthMax = 5,
|
||||
JammingSourcePosition = new Vector3D(50, 0, 0),
|
||||
JammingDirection = new Vector3D(-1, 0, 0),
|
||||
JammingAngleRange = Math.PI / 4,
|
||||
JammingMode = JammingMode.Noise
|
||||
};
|
||||
|
||||
// 捕获发布的事件
|
||||
List<SimulationEvent> publishedEvents = new List<SimulationEvent>();
|
||||
_testAdapter.EventPublished += (sender, evt) => publishedEvents.Add(evt);
|
||||
|
||||
// Act - 没有干扰的情况下更新
|
||||
_infraredTracker.Update(0.1);
|
||||
|
||||
// 记录发布的事件数量
|
||||
int eventsBeforeJamming = publishedEvents.Count;
|
||||
publishedEvents.Clear();
|
||||
|
||||
// Act - 应用干扰
|
||||
_simulationManager.PublishEvent(jammingEvent);
|
||||
_infraredTracker.Update(0.1);
|
||||
|
||||
// Assert
|
||||
int eventsAfterJamming = publishedEvents.Count;
|
||||
Assert.IsTrue(_infraredTracker.IsJammed, "红外测角仪应该处于被干扰状态");
|
||||
Assert.AreEqual(0, eventsAfterJamming, "在干扰状态下不应该发送制导指令事件");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -30,26 +30,52 @@ namespace ThreatSource.Tests.Jamming
|
||||
_simulationManager.SetSimulationAdapter(_testAdapter);
|
||||
|
||||
// 创建目标
|
||||
_tank = new Tank("tank1", new Vector3D(100, 0, 100), Math.PI/4, _simulationManager);
|
||||
var tankInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(100, 0, 100),
|
||||
Orientation = new Orientation(Math.PI/4, 0, 0),
|
||||
InitialSpeed = 0
|
||||
};
|
||||
_tank = new Tank("tank1", tankInitialMotion, _simulationManager);
|
||||
_simulationManager.RegisterEntity("tank1", _tank);
|
||||
_tank.Activate();
|
||||
|
||||
// 创建子弹
|
||||
var properties = new MissileProperties
|
||||
{
|
||||
Id = "submunition1",
|
||||
Mass = 10,
|
||||
ExplosionRadius = 5,
|
||||
MaxSpeed = 2000,
|
||||
MaxFlightTime = 100,
|
||||
MaxFlightDistance = 1000,
|
||||
InitialPosition = new Vector3D(20, 150, 0),
|
||||
InitialSpeed = 20,
|
||||
InitialOrientation = new Orientation(0, -Math.PI/4, 0)
|
||||
MaxAcceleration = 50,
|
||||
ProportionalNavigationCoefficient = 3,
|
||||
Mass = 10,
|
||||
ExplosionRadius = 5,
|
||||
HitProbability = 0.9,
|
||||
Type = MissileType.TerminalSensitiveSubmunition
|
||||
};
|
||||
|
||||
_submunition = new TerminalSensitiveSubmunition("tank1", properties, _simulationManager);
|
||||
_simulationManager.RegisterEntity("submunition1", _submunition);
|
||||
var submunitionInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(20, 150, 0),
|
||||
Orientation = new Orientation(0, -Math.PI/4, 0),
|
||||
InitialSpeed = 20
|
||||
};
|
||||
|
||||
var submunitionConfig = new TerminalSensitiveSubmunitionConfig
|
||||
{
|
||||
SeparationHeight = 400.0,
|
||||
SeparationDistance = 1000.0,
|
||||
SubmunitionSeparationAngle = 45.0
|
||||
};
|
||||
|
||||
_submunition = new TerminalSensitiveSubmunition(
|
||||
"tank1",
|
||||
"submunition1",
|
||||
properties,
|
||||
submunitionInitialMotion,
|
||||
submunitionConfig,
|
||||
_simulationManager
|
||||
);
|
||||
|
||||
// 初始化传感器
|
||||
_infraredDetector = new InfraredDetector(_submunition, 500, InfraredBand.Short, 10);
|
||||
@ -137,25 +163,52 @@ namespace ThreatSource.Tests.Jamming
|
||||
public void TestSubmunitionHitDetection()
|
||||
{
|
||||
// 创建目标
|
||||
var tank = new Tank("tank3", new Vector3D(0, 0, 0), 0, _simulationManager);
|
||||
var tank3InitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
};
|
||||
var tank = new Tank("tank3", tank3InitialMotion, _simulationManager);
|
||||
_simulationManager.RegisterEntity("tank3", tank);
|
||||
tank.Activate();
|
||||
|
||||
// 创建子弹
|
||||
var properties = new MissileProperties
|
||||
{
|
||||
Id = "submunition3",
|
||||
Mass = 10,
|
||||
ExplosionRadius = 5,
|
||||
MaxSpeed = 500,
|
||||
MaxFlightTime = 100,
|
||||
MaxFlightDistance = 1000,
|
||||
InitialPosition = new Vector3D(0, 6, 0),
|
||||
InitialSpeed = 10,
|
||||
InitialOrientation = new Orientation(0, -Math.PI/2, 0)
|
||||
MaxAcceleration = 50,
|
||||
ProportionalNavigationCoefficient = 3,
|
||||
Mass = 10,
|
||||
ExplosionRadius = 5,
|
||||
HitProbability = 0.9,
|
||||
Type = MissileType.TerminalSensitiveSubmunition
|
||||
};
|
||||
|
||||
var submunition = new TerminalSensitiveSubmunition("tank3", properties, _simulationManager);
|
||||
var submunitionInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(0, 6, 0),
|
||||
Orientation = new Orientation(0, -Math.PI/2, 0),
|
||||
InitialSpeed = 10
|
||||
};
|
||||
|
||||
var submunitionConfig = new TerminalSensitiveSubmunitionConfig
|
||||
{
|
||||
SeparationHeight = 200.0,
|
||||
SeparationDistance = 500.0,
|
||||
SubmunitionSeparationAngle = 45.0
|
||||
};
|
||||
|
||||
var submunition = new TerminalSensitiveSubmunition(
|
||||
"tank3",
|
||||
"submunition3",
|
||||
properties,
|
||||
submunitionInitialMotion,
|
||||
submunitionConfig,
|
||||
_simulationManager
|
||||
);
|
||||
_simulationManager.RegisterEntity("submunition3", submunition);
|
||||
|
||||
// 激活并发射子弹
|
||||
@ -207,25 +260,48 @@ namespace ThreatSource.Tests.Jamming
|
||||
public void TestDecelerationStageJamming()
|
||||
{
|
||||
// 创建目标
|
||||
var tank = new Tank("tank5", new Vector3D(100, 0, 100), Math.PI/4, _simulationManager);
|
||||
var tank5InitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(100, 0, 100),
|
||||
Orientation = new Orientation(Math.PI/4, 0, 0),
|
||||
InitialSpeed = 0
|
||||
};
|
||||
var tank = new Tank("tank5", tank5InitialMotion, _simulationManager);
|
||||
_simulationManager.RegisterEntity("tank5", tank);
|
||||
tank.Activate();
|
||||
|
||||
// 创建子弹,初始高度设置为400米
|
||||
var properties = new MissileProperties
|
||||
{
|
||||
Id = "submunition5",
|
||||
Mass = 10,
|
||||
ExplosionRadius = 5,
|
||||
MaxSpeed = 500,
|
||||
MaxFlightTime = 100,
|
||||
MaxFlightDistance = 1000,
|
||||
InitialPosition = new Vector3D(0, 400, 0),
|
||||
InitialSpeed = 100,
|
||||
InitialOrientation = new Orientation(0, -Math.PI/4, 0)
|
||||
Mass = 10,
|
||||
ExplosionRadius = 5
|
||||
};
|
||||
|
||||
var submunition = new TerminalSensitiveSubmunition("tank5", properties, _simulationManager);
|
||||
var submunitionInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(0, 400, 0),
|
||||
Orientation = new Orientation(0, -Math.PI/4, 0),
|
||||
InitialSpeed = 100
|
||||
};
|
||||
|
||||
var submunitionConfig = new TerminalSensitiveSubmunitionConfig
|
||||
{
|
||||
SeparationHeight = 200.0,
|
||||
SeparationDistance = 500.0,
|
||||
SubmunitionSeparationAngle = 45.0
|
||||
};
|
||||
|
||||
var submunition = new TerminalSensitiveSubmunition(
|
||||
"tank5",
|
||||
"submunition5",
|
||||
properties,
|
||||
submunitionInitialMotion,
|
||||
submunitionConfig,
|
||||
_simulationManager
|
||||
);
|
||||
_simulationManager.RegisterEntity("submunition5", submunition);
|
||||
|
||||
// 激活并发射子弹
|
||||
@ -280,25 +356,48 @@ namespace ThreatSource.Tests.Jamming
|
||||
public void TestParachuteDeploymentStageJamming()
|
||||
{
|
||||
// 创建目标
|
||||
var tank = new Tank("tank6", new Vector3D(100, 0, 100), Math.PI/4, _simulationManager);
|
||||
var tank6InitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(100, 0, 100),
|
||||
Orientation = new Orientation(Math.PI/4, 0, 0),
|
||||
InitialSpeed = 0
|
||||
};
|
||||
var tank = new Tank("tank6", tank6InitialMotion, _simulationManager);
|
||||
_simulationManager.RegisterEntity("tank6", tank);
|
||||
tank.Activate();
|
||||
|
||||
// 创建子弹,初始高度设置为300米(接近开伞高度)
|
||||
// 创建子弹,初始高度设置为300米(伞降阶段)
|
||||
var properties = new MissileProperties
|
||||
{
|
||||
Id = "submunition6",
|
||||
Mass = 10,
|
||||
ExplosionRadius = 5,
|
||||
MaxSpeed = 500,
|
||||
MaxFlightTime = 100,
|
||||
MaxFlightDistance = 1000,
|
||||
InitialPosition = new Vector3D(0, 300, 0),
|
||||
InitialSpeed = 40, // 设置为减速阶段末速度
|
||||
InitialOrientation = new Orientation(0, -Math.PI/2, 0) // 垂直向下
|
||||
Mass = 10,
|
||||
ExplosionRadius = 5
|
||||
};
|
||||
|
||||
var submunition = new TerminalSensitiveSubmunition("tank6", properties, _simulationManager);
|
||||
var submunitionInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(0, 300, 0),
|
||||
Orientation = new Orientation(0, -Math.PI/2, 0), // 垂直向下
|
||||
InitialSpeed = 40 // 设置为减速阶段末速度
|
||||
};
|
||||
|
||||
var submunitionConfig = new TerminalSensitiveSubmunitionConfig
|
||||
{
|
||||
SeparationHeight = 200.0,
|
||||
SeparationDistance = 500.0,
|
||||
SubmunitionSeparationAngle = 45.0
|
||||
};
|
||||
|
||||
var submunition = new TerminalSensitiveSubmunition(
|
||||
"tank6",
|
||||
"submunition6",
|
||||
properties,
|
||||
submunitionInitialMotion,
|
||||
submunitionConfig,
|
||||
_simulationManager
|
||||
);
|
||||
_simulationManager.RegisterEntity("submunition6", submunition);
|
||||
|
||||
// 激活并发射子弹
|
||||
@ -366,11 +465,6 @@ namespace ThreatSource.Tests.Jamming
|
||||
Console.WriteLine($"恢复后状态:{status}");
|
||||
Assert.IsFalse(status.Contains("传感器受到干扰"), "子弹状态应该反映传感器恢复正常");
|
||||
|
||||
// 验证高度测量恢复
|
||||
double? recoveredAltitude = ((AltimeterSensorData)altimeter.GetSensorData()).Altitude;
|
||||
Assert.IsTrue(recoveredAltitude.HasValue, "恢复后应该能获取高度数据");
|
||||
Assert.AreNotEqual(initialAltitude, recoveredAltitude, "高度应该有变化");
|
||||
|
||||
// 验证速度变化
|
||||
Assert.IsTrue(submunition.Speed <= 40, "速度应该保持在开伞阶段的限制范围内");
|
||||
}
|
||||
@ -379,25 +473,48 @@ namespace ThreatSource.Tests.Jamming
|
||||
public void TestStableScanStageJamming()
|
||||
{
|
||||
// 创建目标
|
||||
var tank = new Tank("tank7", new Vector3D(100, 0, 100), Math.PI/4, _simulationManager);
|
||||
var tank7InitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(100, 0, 100),
|
||||
Orientation = new Orientation(Math.PI/4, 0, 0),
|
||||
InitialSpeed = 0
|
||||
};
|
||||
var tank = new Tank("tank7", tank7InitialMotion, _simulationManager);
|
||||
_simulationManager.RegisterEntity("tank7", tank);
|
||||
tank.Activate();
|
||||
|
||||
// 创建子弹,初始高度设置为200米(稳定扫描高度)
|
||||
// 创建子弹,初始高度设置为250米(稳定扫描阶段)
|
||||
var properties = new MissileProperties
|
||||
{
|
||||
Id = "submunition7",
|
||||
Mass = 10,
|
||||
ExplosionRadius = 5,
|
||||
MaxSpeed = 500,
|
||||
MaxFlightTime = 100,
|
||||
MaxFlightDistance = 1000,
|
||||
InitialPosition = new Vector3D(0, 250, 0),
|
||||
InitialSpeed = 10, // 设置为垂直下降速度
|
||||
InitialOrientation = new Orientation(0, -Math.PI/2, 0) // 垂直向下
|
||||
Mass = 10,
|
||||
ExplosionRadius = 5
|
||||
};
|
||||
|
||||
var submunition = new TerminalSensitiveSubmunition("tank7", properties, _simulationManager);
|
||||
var submunitionInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(0, 250, 0),
|
||||
Orientation = new Orientation(0, -Math.PI/2, 0), // 垂直向下
|
||||
InitialSpeed = 10 // 设置为垂直下降速度
|
||||
};
|
||||
|
||||
var submunitionConfig = new TerminalSensitiveSubmunitionConfig
|
||||
{
|
||||
SeparationHeight = 200.0,
|
||||
SeparationDistance = 500.0,
|
||||
SubmunitionSeparationAngle = 45.0
|
||||
};
|
||||
|
||||
var submunition = new TerminalSensitiveSubmunition(
|
||||
"tank7",
|
||||
"submunition7",
|
||||
properties,
|
||||
submunitionInitialMotion,
|
||||
submunitionConfig,
|
||||
_simulationManager
|
||||
);
|
||||
_simulationManager.RegisterEntity("submunition7", submunition);
|
||||
|
||||
// 激活并发射子弹
|
||||
@ -499,25 +616,48 @@ namespace ThreatSource.Tests.Jamming
|
||||
public void TestDetectionStageJamming()
|
||||
{
|
||||
// 创建目标
|
||||
var tank = new Tank("tank8", new Vector3D( 30, 0, 30), Math.PI/4, _simulationManager);
|
||||
var tank8InitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(100, 0, 100),
|
||||
Orientation = new Orientation(Math.PI/4, 0, 0),
|
||||
InitialSpeed = 0
|
||||
};
|
||||
var tank = new Tank("tank8", tank8InitialMotion, _simulationManager);
|
||||
_simulationManager.RegisterEntity("tank8", tank);
|
||||
tank.Activate();
|
||||
|
||||
// 创建子弹,初始位置设置在探测阶段范围内
|
||||
// 创建子弹,初始高度设置为140米(检测阶段)
|
||||
var properties = new MissileProperties
|
||||
{
|
||||
Id = "submunition8",
|
||||
Mass = 10,
|
||||
ExplosionRadius = 5,
|
||||
MaxSpeed = 10,
|
||||
MaxFlightTime = 100,
|
||||
MaxFlightDistance = 1000,
|
||||
InitialPosition = new Vector3D(0, 140, 0),
|
||||
InitialSpeed = 10,
|
||||
InitialOrientation = new Orientation(0, -Math.PI/2, 0)
|
||||
Mass = 10,
|
||||
ExplosionRadius = 5
|
||||
};
|
||||
|
||||
var submunition = new TerminalSensitiveSubmunition("tank8", properties, _simulationManager);
|
||||
var submunitionInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(0, 140, 0),
|
||||
Orientation = new Orientation(0, -Math.PI/2, 0),
|
||||
InitialSpeed = 10
|
||||
};
|
||||
|
||||
var submunitionConfig = new TerminalSensitiveSubmunitionConfig
|
||||
{
|
||||
SeparationHeight = 200.0,
|
||||
SeparationDistance = 500.0,
|
||||
SubmunitionSeparationAngle = 45.0
|
||||
};
|
||||
|
||||
var submunition = new TerminalSensitiveSubmunition(
|
||||
"tank8",
|
||||
"submunition8",
|
||||
properties,
|
||||
submunitionInitialMotion,
|
||||
submunitionConfig,
|
||||
_simulationManager
|
||||
);
|
||||
_simulationManager.RegisterEntity("submunition8", submunition);
|
||||
|
||||
// 激活并发射子弹
|
||||
@ -550,25 +690,48 @@ namespace ThreatSource.Tests.Jamming
|
||||
public void TestAttackStageJamming()
|
||||
{
|
||||
// 创建目标
|
||||
var tank = new Tank("tank_attack", new Vector3D(300, 0, 100), Math.PI/4, _simulationManager);
|
||||
var tankAttackInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(300, 0, 100),
|
||||
Orientation = new Orientation(Math.PI/4, 0, 0),
|
||||
InitialSpeed = 0
|
||||
};
|
||||
var tank = new Tank("tank_attack", tankAttackInitialMotion, _simulationManager);
|
||||
_simulationManager.RegisterEntity("tank_attack", tank);
|
||||
tank.Activate();
|
||||
|
||||
// 创建子弹,初始位置设置在传感器探测范围内
|
||||
var properties = new MissileProperties
|
||||
{
|
||||
Id = "submunition_attack",
|
||||
Mass = 10,
|
||||
ExplosionRadius = 5,
|
||||
MaxSpeed = 2000,
|
||||
MaxFlightTime = 50,
|
||||
MaxFlightDistance = 1000,
|
||||
InitialPosition = new Vector3D(400, 200, 100), // 距离目标100米,高度200米
|
||||
InitialSpeed = 10,
|
||||
InitialOrientation = new Orientation(0, -Math.PI/6, 0) // 向下30度
|
||||
Mass = 10,
|
||||
ExplosionRadius = 5
|
||||
};
|
||||
|
||||
var submunition = new TerminalSensitiveSubmunition("tank_attack", properties, _simulationManager);
|
||||
var submunitionInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(400, 200, 100), // 距离目标100米,高度200米
|
||||
Orientation = new Orientation(0, -Math.PI/6, 0), // 向下30度
|
||||
InitialSpeed = 10
|
||||
};
|
||||
|
||||
var submunitionConfig = new TerminalSensitiveSubmunitionConfig
|
||||
{
|
||||
SeparationHeight = 200.0,
|
||||
SeparationDistance = 500.0,
|
||||
SubmunitionSeparationAngle = 45.0
|
||||
};
|
||||
|
||||
var submunition = new TerminalSensitiveSubmunition(
|
||||
"tank_attack",
|
||||
"submunition_attack",
|
||||
properties,
|
||||
submunitionInitialMotion,
|
||||
submunitionConfig,
|
||||
_simulationManager
|
||||
);
|
||||
_simulationManager.RegisterEntity("submunition_attack", submunition);
|
||||
|
||||
// 激活并发射子弹
|
||||
|
||||
@ -3,6 +3,8 @@ using ThreatSource.Missile;
|
||||
using ThreatSource.Simulation;
|
||||
using ThreatSource.Utils;
|
||||
using ThreatSource.Tests.Simulation;
|
||||
using ThreatSource.Guidance;
|
||||
using ThreatSource.Indicator;
|
||||
|
||||
namespace ThreatSource.Tests.Missile
|
||||
{
|
||||
@ -10,7 +12,7 @@ namespace ThreatSource.Tests.Missile
|
||||
{
|
||||
private readonly SimulationManager _simulationManager;
|
||||
private readonly TestSimulationAdapter _testAdapter;
|
||||
private readonly BaseMissile _missile;
|
||||
private readonly LaserSemiActiveGuidedMissile _missile;
|
||||
private readonly MissileProperties _properties;
|
||||
|
||||
public BaseMissileTests()
|
||||
@ -21,10 +23,6 @@ namespace ThreatSource.Tests.Missile
|
||||
|
||||
_properties = new MissileProperties
|
||||
{
|
||||
Id = "missile1",
|
||||
InitialPosition = new Vector3D(0, 0, 0),
|
||||
InitialOrientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100,
|
||||
MaxSpeed = 1000,
|
||||
MaxFlightTime = 100,
|
||||
MaxFlightDistance = 10000,
|
||||
@ -33,10 +31,45 @@ namespace ThreatSource.Tests.Missile
|
||||
Mass = 100,
|
||||
ExplosionRadius = 10,
|
||||
HitProbability = 0.9,
|
||||
Type = MissileType.StandardMissile
|
||||
Type = MissileType.LaserSemiActiveGuidance
|
||||
};
|
||||
|
||||
_missile = new BaseMissile(_properties, _simulationManager);
|
||||
var missileInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100
|
||||
};
|
||||
|
||||
var laserCodeConfig = new LaserCodeConfig
|
||||
{
|
||||
Code = new LaserCode
|
||||
{
|
||||
CodeType = LaserCodeType.PRF,
|
||||
CodeValue = 1234
|
||||
}
|
||||
};
|
||||
|
||||
var guidanceConfig = new LaserSemiActiveGuidanceConfig
|
||||
{
|
||||
FieldOfViewAngle = 30,
|
||||
LensDiameter = 0.1,
|
||||
SensorDiameter = 0.03,
|
||||
FocusedSpotDiameter = 0.006,
|
||||
ReflectionCoefficient = 0.2,
|
||||
TargetReflectiveArea = 1.0,
|
||||
LockThreshold = 1e-12,
|
||||
SpotOffsetSensitivity = 0.5
|
||||
};
|
||||
|
||||
_missile = new LaserSemiActiveGuidedMissile(
|
||||
"missile1",
|
||||
_properties,
|
||||
missileInitialMotion,
|
||||
laserCodeConfig,
|
||||
guidanceConfig,
|
||||
_simulationManager
|
||||
);
|
||||
_simulationManager.RegisterEntity("missile1", _missile);
|
||||
}
|
||||
|
||||
|
||||
@ -21,10 +21,6 @@ namespace ThreatSource.Tests.Missile
|
||||
|
||||
_properties = new MissileProperties
|
||||
{
|
||||
Id = "missile1",
|
||||
InitialPosition = new Vector3D(0, 0, 0),
|
||||
InitialOrientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100,
|
||||
MaxSpeed = 1000,
|
||||
MaxFlightTime = 100,
|
||||
MaxFlightDistance = 10000,
|
||||
@ -36,7 +32,19 @@ namespace ThreatSource.Tests.Missile
|
||||
Type = MissileType.InfraredCommandGuidance
|
||||
};
|
||||
|
||||
_missile = new InfraredCommandGuidedMissile(_properties, _simulationManager);
|
||||
var missileInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100
|
||||
};
|
||||
|
||||
_missile = new InfraredCommandGuidedMissile(
|
||||
"missile1",
|
||||
_properties,
|
||||
missileInitialMotion,
|
||||
_simulationManager
|
||||
);
|
||||
_simulationManager.RegisterEntity("missile1", _missile);
|
||||
}
|
||||
|
||||
@ -137,7 +145,7 @@ namespace ThreatSource.Tests.Missile
|
||||
_missile.Fire();
|
||||
_missile.Activate();
|
||||
var maxDistance = _properties.MaxFlightDistance;
|
||||
var timeToExceedDistance = maxDistance / _properties.InitialSpeed + 1;
|
||||
var timeToExceedDistance = maxDistance / 100 + 1; // 使用已知的初始速度100
|
||||
|
||||
// Act
|
||||
for (double time = 0; time < timeToExceedDistance; time += 0.1)
|
||||
|
||||
@ -4,6 +4,7 @@ using ThreatSource.Simulation;
|
||||
using ThreatSource.Utils;
|
||||
using ThreatSource.Tests.Simulation;
|
||||
using ThreatSource.Target;
|
||||
using ThreatSource.Guidance;
|
||||
|
||||
namespace ThreatSource.Tests.Missile
|
||||
{
|
||||
@ -12,6 +13,7 @@ namespace ThreatSource.Tests.Missile
|
||||
private readonly SimulationManager _simulationManager;
|
||||
private readonly InfraredImagingTerminalGuidedMissile _missile;
|
||||
private readonly MissileProperties _properties;
|
||||
private readonly InitialMotionParameters _initialMotion;
|
||||
|
||||
public InfraredImagingTerminalGuidedMissileTests()
|
||||
{
|
||||
@ -19,10 +21,6 @@ namespace ThreatSource.Tests.Missile
|
||||
|
||||
_properties = new MissileProperties
|
||||
{
|
||||
Id = "missile1",
|
||||
InitialPosition = new Vector3D(0, 0, 0),
|
||||
InitialOrientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100,
|
||||
MaxSpeed = 1000,
|
||||
MaxFlightTime = 100,
|
||||
MaxFlightDistance = 10000,
|
||||
@ -34,7 +32,30 @@ namespace ThreatSource.Tests.Missile
|
||||
Type = MissileType.InfraredImagingTerminalGuidance
|
||||
};
|
||||
|
||||
_missile = new InfraredImagingTerminalGuidedMissile(_properties, _simulationManager);
|
||||
_initialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100
|
||||
};
|
||||
|
||||
var guidanceConfig = new InfraredImagingGuidanceConfig
|
||||
{
|
||||
SearchFieldOfView = Math.PI / 15,
|
||||
TrackFieldOfView = Math.PI / 60,
|
||||
SearchRecognitionProbability = 0.6,
|
||||
TrackRecognitionProbability = 0.8,
|
||||
MaxDetectionRange = 5000
|
||||
};
|
||||
|
||||
_missile = new InfraredImagingTerminalGuidedMissile(
|
||||
"missile1",
|
||||
TargetType.Tank,
|
||||
_properties,
|
||||
_initialMotion,
|
||||
guidanceConfig,
|
||||
_simulationManager
|
||||
);
|
||||
_simulationManager.RegisterEntity("missile1", _missile);
|
||||
}
|
||||
|
||||
@ -79,7 +100,13 @@ namespace ThreatSource.Tests.Missile
|
||||
}
|
||||
|
||||
// 7. 末制导阶段
|
||||
var tank = new Tank("target1", new Vector3D(500, 0, 0), 0, _simulationManager);
|
||||
var tankInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(500, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
};
|
||||
var tank = new Tank("target1", tankInitialMotion, _simulationManager);
|
||||
_simulationManager.RegisterEntity("target1", tank);
|
||||
tank.Activate();
|
||||
|
||||
@ -111,7 +138,7 @@ namespace ThreatSource.Tests.Missile
|
||||
// Arrange
|
||||
_missile.Fire();
|
||||
var maxDistance = _properties.MaxFlightDistance;
|
||||
var timeToExceedDistance = maxDistance / _properties.InitialSpeed + 1;
|
||||
var timeToExceedDistance = maxDistance / 100 + 1; // 使用初始速度100
|
||||
|
||||
// Act
|
||||
for (double time = 0; time < timeToExceedDistance; time += 0.1)
|
||||
@ -190,9 +217,9 @@ namespace ThreatSource.Tests.Missile
|
||||
_missile.Fire();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(_properties.InitialSpeed, _missile.Speed);
|
||||
Assert.Equal(_properties.InitialPosition, _missile.Position);
|
||||
Assert.Equal(_properties.InitialOrientation, _missile.Orientation);
|
||||
Assert.Equal(_initialMotion.InitialSpeed, _missile.Speed);
|
||||
Assert.Equal(_initialMotion.Position, _missile.Position);
|
||||
Assert.Equal(_initialMotion.Orientation, _missile.Orientation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,7 @@ using ThreatSource.Missile;
|
||||
using ThreatSource.Simulation;
|
||||
using ThreatSource.Utils;
|
||||
using ThreatSource.Tests.Simulation;
|
||||
using ThreatSource.Guidance;
|
||||
|
||||
namespace ThreatSource.Tests.Missile
|
||||
{
|
||||
@ -21,10 +22,6 @@ namespace ThreatSource.Tests.Missile
|
||||
|
||||
_properties = new MissileProperties
|
||||
{
|
||||
Id = "missile1",
|
||||
InitialPosition = new Vector3D(0, 0, 0),
|
||||
InitialOrientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100,
|
||||
MaxSpeed = 1000,
|
||||
MaxFlightTime = 100,
|
||||
MaxFlightDistance = 10000,
|
||||
@ -36,7 +33,37 @@ namespace ThreatSource.Tests.Missile
|
||||
Type = MissileType.LaserBeamRiderGuidance
|
||||
};
|
||||
|
||||
_missile = new LaserBeamRiderMissile(_properties, _simulationManager);
|
||||
var missileInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100
|
||||
};
|
||||
|
||||
var laserCodeConfig = new LaserCodeConfig
|
||||
{
|
||||
Code = new LaserCode
|
||||
{
|
||||
CodeType = LaserCodeType.PRF,
|
||||
CodeValue = 1234
|
||||
}
|
||||
};
|
||||
|
||||
var guidanceConfig = new LaserBeamRiderGuidanceSystemConfig
|
||||
{
|
||||
MaxGuidanceAcceleration = 50.0,
|
||||
ControlFieldDiameter = 20.0,
|
||||
DetectorDiameter = 0.1
|
||||
};
|
||||
|
||||
_missile = new LaserBeamRiderMissile(
|
||||
"missile1",
|
||||
_properties,
|
||||
missileInitialMotion,
|
||||
laserCodeConfig,
|
||||
guidanceConfig,
|
||||
_simulationManager
|
||||
);
|
||||
_simulationManager.RegisterEntity("missile1", _missile);
|
||||
}
|
||||
|
||||
@ -104,7 +131,7 @@ namespace ThreatSource.Tests.Missile
|
||||
_missile.Fire();
|
||||
_missile.Activate();
|
||||
var maxDistance = _properties.MaxFlightDistance;
|
||||
var timeToExceedDistance = maxDistance / _properties.InitialSpeed + 1;
|
||||
var timeToExceedDistance = maxDistance / 100 + 1; // 使用初始速度100
|
||||
|
||||
// Act
|
||||
for (double time = 0; time < timeToExceedDistance; time += 0.1)
|
||||
|
||||
@ -26,10 +26,6 @@ namespace ThreatSource.Tests.Missile
|
||||
|
||||
_properties = new MissileProperties
|
||||
{
|
||||
Id = "missile1",
|
||||
InitialPosition = new Vector3D(0, 0, 0),
|
||||
InitialOrientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100,
|
||||
MaxSpeed = 1000,
|
||||
MaxFlightTime = 100,
|
||||
MaxFlightDistance = 10000,
|
||||
@ -41,6 +37,13 @@ namespace ThreatSource.Tests.Missile
|
||||
Type = MissileType.LaserSemiActiveGuidance
|
||||
};
|
||||
|
||||
var missileInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100
|
||||
};
|
||||
|
||||
// 创建并注册模拟的激光指示器,位置在导弹后方100米处
|
||||
_laserDesignator = new MockLaserDesignator("laser1", _simulationManager);
|
||||
_laserDesignator.Position = new Vector3D(-100, 0, 0);
|
||||
@ -52,21 +55,68 @@ namespace ThreatSource.Tests.Missile
|
||||
_target.Position = new Vector3D(1000, 0, 0);
|
||||
_testAdapter.AddTestEntity("target1", _target);
|
||||
|
||||
// 创建导弹并注册到仿真管理器
|
||||
_missile = new LaserSemiActiveGuidedMissile(_properties, _simulationManager);
|
||||
var laserCodeConfig = new LaserCodeConfig
|
||||
{
|
||||
Code = new LaserCode
|
||||
{
|
||||
CodeType = LaserCodeType.PRF,
|
||||
CodeValue = 1234
|
||||
}
|
||||
};
|
||||
|
||||
var guidanceConfig = new LaserSemiActiveGuidanceConfig
|
||||
{
|
||||
FieldOfViewAngle = 30,
|
||||
LensDiameter = 0.1,
|
||||
SensorDiameter = 0.03,
|
||||
FocusedSpotDiameter = 0.006,
|
||||
ReflectionCoefficient = 0.2,
|
||||
TargetReflectiveArea = 1.0,
|
||||
LockThreshold = 1e-12,
|
||||
SpotOffsetSensitivity = 0.5
|
||||
};
|
||||
|
||||
_missile = new LaserSemiActiveGuidedMissile(
|
||||
"missile1",
|
||||
_properties,
|
||||
missileInitialMotion,
|
||||
laserCodeConfig,
|
||||
guidanceConfig,
|
||||
_simulationManager
|
||||
);
|
||||
_simulationManager.RegisterEntity("missile1", _missile);
|
||||
|
||||
// 创建独立的制导系统用于测试
|
||||
var guidanceSystem = new LaserSemiActiveGuidanceSystem(
|
||||
"guidance1",
|
||||
_properties.MaxAcceleration,
|
||||
_properties.ProportionalNavigationCoefficient,
|
||||
laserCodeConfig,
|
||||
guidanceConfig,
|
||||
_simulationManager
|
||||
);
|
||||
guidanceSystem.ParentId = "missile1";
|
||||
_simulationManager.RegisterEntity("guidance1", guidanceSystem);
|
||||
}
|
||||
|
||||
private LaserSemiActiveGuidanceSystem GetGuidanceSystem()
|
||||
{
|
||||
return (_simulationManager.GetEntityById("guidance1") as LaserSemiActiveGuidanceSystem)!;
|
||||
}
|
||||
|
||||
// 模拟的激光指示器类
|
||||
private class MockLaserDesignator : LaserDesignator
|
||||
{
|
||||
public MockLaserDesignator(string id, ISimulationManager simulationManager)
|
||||
: base(id, "target1", "missile1", 0, new LaserDesignatorConfig
|
||||
: base(id, "target1", "missile1", new LaserDesignatorConfig
|
||||
{
|
||||
Id = id,
|
||||
InitialPosition = new Vector3D(100, 0, 0),
|
||||
LaserPower = 100,
|
||||
LaserDivergenceAngle = 0.001
|
||||
}, new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(100, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
}, simulationManager)
|
||||
{
|
||||
// 不需要额外设置属性,因为基类构造函数已经设置了
|
||||
@ -77,7 +127,12 @@ namespace ThreatSource.Tests.Missile
|
||||
private class MockTarget : Tank
|
||||
{
|
||||
public MockTarget(string id, ISimulationManager simulationManager)
|
||||
: base(id, new Vector3D(1000, 0, 0), 10, simulationManager)
|
||||
: base(id, new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(1000, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
}, simulationManager)
|
||||
{
|
||||
// 不需要额外设置属性,因为基类构造函数已经设置了
|
||||
}
|
||||
@ -89,9 +144,10 @@ namespace ThreatSource.Tests.Missile
|
||||
// Arrange
|
||||
_missile.Fire();
|
||||
_missile.Activate();
|
||||
var guidanceSystem = GetGuidanceSystem();
|
||||
|
||||
// Act
|
||||
_missile.SetLaserCode(LaserCodeType.PRF, 1234);
|
||||
guidanceSystem.SetExpectedLaserCode(LaserCodeType.PRF, 1234);
|
||||
|
||||
// Assert - We can't directly check the private field, but we can test the behavior
|
||||
// This will be tested in the LaserIllumination test
|
||||
@ -103,10 +159,11 @@ namespace ThreatSource.Tests.Missile
|
||||
// Arrange
|
||||
_missile.Fire();
|
||||
_missile.Activate();
|
||||
_missile.SetLaserCode(LaserCodeType.PPM, 5678);
|
||||
var guidanceSystem = GetGuidanceSystem();
|
||||
guidanceSystem.SetExpectedLaserCode(LaserCodeType.PPM, 5678);
|
||||
|
||||
// Act
|
||||
_missile.AddLaserCodeParameter("PulseWidth", 0.001);
|
||||
guidanceSystem.AddExpectedCodeParameter("PulseWidth", 0.001);
|
||||
|
||||
// Assert - We can't directly check the private field, but we can test the behavior
|
||||
// This will be tested in the LaserIllumination test
|
||||
@ -118,9 +175,18 @@ namespace ThreatSource.Tests.Missile
|
||||
// Arrange
|
||||
_missile.Fire();
|
||||
_missile.Activate();
|
||||
var guidanceSystem = GetGuidanceSystem();
|
||||
|
||||
// Act
|
||||
_missile.SetCodeMatchRequired(true);
|
||||
_missile.LaserCodeConfig = new LaserCodeConfig
|
||||
{
|
||||
IsCodeMatchRequired = true,
|
||||
Code = new LaserCode
|
||||
{
|
||||
CodeType = LaserCodeType.PRF,
|
||||
CodeValue = 1234
|
||||
}
|
||||
};
|
||||
|
||||
// Assert - We can't directly check the private field, but we can test the behavior
|
||||
// This will be tested in the LaserIllumination test
|
||||
@ -132,8 +198,9 @@ namespace ThreatSource.Tests.Missile
|
||||
// Arrange
|
||||
_missile.Fire();
|
||||
_missile.Activate();
|
||||
_missile.SetLaserCode(LaserCodeType.PRF, 1234);
|
||||
_missile.SetCodeMatchRequired(true);
|
||||
var guidanceSystem = GetGuidanceSystem();
|
||||
guidanceSystem.SetExpectedLaserCode(LaserCodeType.PRF, 1234);
|
||||
_missile.LaserCodeConfig.IsCodeMatchRequired = true;
|
||||
_missile.Update(0.1); // Move past launch stage
|
||||
|
||||
// 设置激光指示器和目标位置,确保在视场角内
|
||||
@ -176,8 +243,9 @@ namespace ThreatSource.Tests.Missile
|
||||
// Arrange
|
||||
_missile.Fire();
|
||||
_missile.Activate();
|
||||
_missile.SetLaserCode(LaserCodeType.PRF, 1234);
|
||||
_missile.SetCodeMatchRequired(true);
|
||||
var guidanceSystem = GetGuidanceSystem();
|
||||
guidanceSystem.SetExpectedLaserCode(LaserCodeType.PRF, 1234);
|
||||
_missile.LaserCodeConfig.IsCodeMatchRequired = true;
|
||||
_missile.Update(0.1); // Move past launch stage
|
||||
|
||||
// 设置激光指示器和目标位置,确保在视场角内
|
||||
@ -220,8 +288,9 @@ namespace ThreatSource.Tests.Missile
|
||||
// Arrange
|
||||
_missile.Fire();
|
||||
_missile.Activate();
|
||||
_missile.SetLaserCode(LaserCodeType.PRF, 1234);
|
||||
_missile.SetCodeMatchRequired(false); // Not required
|
||||
var guidanceSystem = GetGuidanceSystem();
|
||||
guidanceSystem.SetExpectedLaserCode(LaserCodeType.PRF, 1234);
|
||||
_missile.LaserCodeConfig.IsCodeMatchRequired = false; // Not required
|
||||
_missile.Update(0.1); // Move past launch stage
|
||||
|
||||
// 设置激光指示器和目标位置,确保在视场角内
|
||||
@ -262,8 +331,9 @@ namespace ThreatSource.Tests.Missile
|
||||
// Arrange
|
||||
_missile.Fire();
|
||||
_missile.Activate();
|
||||
_missile.SetLaserCode(LaserCodeType.PRF, 1234);
|
||||
_missile.SetCodeMatchRequired(true); // Required
|
||||
var guidanceSystem = GetGuidanceSystem();
|
||||
guidanceSystem.SetExpectedLaserCode(LaserCodeType.PRF, 1234);
|
||||
_missile.LaserCodeConfig.IsCodeMatchRequired = true; // Required
|
||||
_missile.Update(0.1); // Move past launch stage
|
||||
|
||||
// Act - Send illumination with code disabled
|
||||
@ -299,8 +369,9 @@ namespace ThreatSource.Tests.Missile
|
||||
// Arrange
|
||||
_missile.Fire();
|
||||
_missile.Activate();
|
||||
_missile.SetLaserCode(LaserCodeType.PRF, 1234);
|
||||
_missile.SetCodeMatchRequired(true);
|
||||
var guidanceSystem = GetGuidanceSystem();
|
||||
guidanceSystem.SetExpectedLaserCode(LaserCodeType.PRF, 1234);
|
||||
_missile.LaserCodeConfig.IsCodeMatchRequired = true;
|
||||
_missile.Update(0.1); // Move past launch stage
|
||||
|
||||
// 设置激光指示器和目标位置,确保在视场角内
|
||||
|
||||
@ -47,14 +47,10 @@ namespace ThreatSource.Tests.Missile
|
||||
|
||||
_properties = new MissileProperties
|
||||
{
|
||||
Id = "missile1",
|
||||
InitialPosition = new Vector3D(0, 0, 0),
|
||||
InitialOrientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100,
|
||||
MaxSpeed = 1000,
|
||||
MaxFlightTime = 100,
|
||||
MaxFlightDistance = 10000,
|
||||
MaxAcceleration = 50,
|
||||
MaxAcceleration = 50,
|
||||
ProportionalNavigationCoefficient = 3,
|
||||
Mass = 100,
|
||||
ExplosionRadius = 10,
|
||||
@ -62,24 +58,80 @@ namespace ThreatSource.Tests.Missile
|
||||
Type = MissileType.LaserSemiActiveGuidance
|
||||
};
|
||||
|
||||
// 创建并注册激光指示器,位置在导弹后方100米处
|
||||
_laserDesignator = new LaserDesignator("laser1", "target1", "missile1", 0, new LaserDesignatorConfig
|
||||
var missileInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100
|
||||
};
|
||||
|
||||
var laserDesignatorInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(-100, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
};
|
||||
|
||||
// 创建并注册激光指示器,位置在导弹后方100米处
|
||||
var laserDesignatorConfig = new LaserDesignatorConfig
|
||||
{
|
||||
Id = "laser1",
|
||||
InitialPosition = new Vector3D(-100, 0, 0),
|
||||
LaserPower = 100,
|
||||
LaserDivergenceAngle = 0.001
|
||||
}, _simulationManager);
|
||||
};
|
||||
|
||||
_laserDesignator = new LaserDesignator(
|
||||
"laser1",
|
||||
"target1",
|
||||
"missile1",
|
||||
laserDesignatorConfig,
|
||||
laserDesignatorInitialMotion,
|
||||
_simulationManager
|
||||
);
|
||||
_testAdapter.AddTestEntity("laser1", _laserDesignator);
|
||||
_simulationManager.RegisterEntity("laser1", _laserDesignator);
|
||||
|
||||
// 创建并注册模拟的目标,位置在导弹前方1000米处
|
||||
_target = new MockTarget("target1", _simulationManager);
|
||||
_target.Position = new Vector3D(1000, 0, 0);
|
||||
var targetInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(1000, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
};
|
||||
_target = new MockTarget("target1", targetInitialMotion, _simulationManager);
|
||||
_testAdapter.AddTestEntity("target1", _target);
|
||||
|
||||
// 创建激光代码配置
|
||||
var laserCodeConfig = new LaserCodeConfig
|
||||
{
|
||||
Code = new LaserCode
|
||||
{
|
||||
CodeType = LaserCodeType.PRF,
|
||||
CodeValue = 1234
|
||||
}
|
||||
};
|
||||
|
||||
// 创建导引系统配置
|
||||
var guidanceConfig = new LaserSemiActiveGuidanceConfig
|
||||
{
|
||||
FieldOfViewAngle = 30,
|
||||
LensDiameter = 0.1,
|
||||
SensorDiameter = 0.03,
|
||||
FocusedSpotDiameter = 0.006,
|
||||
ReflectionCoefficient = 0.2,
|
||||
TargetReflectiveArea = 1.0,
|
||||
LockThreshold = 1e-12,
|
||||
SpotOffsetSensitivity = 0.5
|
||||
};
|
||||
|
||||
// 创建导弹并注册到仿真管理器
|
||||
_missile = new LaserSemiActiveGuidedMissile(_properties, _simulationManager);
|
||||
_missile = new LaserSemiActiveGuidedMissile(
|
||||
"missile1",
|
||||
_properties,
|
||||
missileInitialMotion,
|
||||
laserCodeConfig,
|
||||
guidanceConfig,
|
||||
_simulationManager
|
||||
);
|
||||
_testAdapter.AddTestEntity("missile1", _missile);
|
||||
_simulationManager.RegisterEntity("missile1", _missile);
|
||||
}
|
||||
@ -87,8 +139,8 @@ namespace ThreatSource.Tests.Missile
|
||||
// 模拟的目标类
|
||||
private class MockTarget : Tank
|
||||
{
|
||||
public MockTarget(string id, ISimulationManager simulationManager)
|
||||
: base(id, new Vector3D(1000, 0, 0), 10, simulationManager)
|
||||
public MockTarget(string id, InitialMotionParameters initialMotionParameters, ISimulationManager simulationManager)
|
||||
: base(id, initialMotionParameters, simulationManager)
|
||||
{
|
||||
// 不需要额外设置属性,因为基类构造函数已经设置了
|
||||
}
|
||||
|
||||
@ -21,10 +21,6 @@ namespace ThreatSource.Tests.Missile
|
||||
|
||||
_properties = new MissileProperties
|
||||
{
|
||||
Id = "missile1",
|
||||
InitialPosition = new Vector3D(0, 0, 0),
|
||||
InitialOrientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100,
|
||||
MaxSpeed = 1000,
|
||||
MaxFlightTime = 100,
|
||||
MaxFlightDistance = 10000,
|
||||
@ -36,7 +32,42 @@ namespace ThreatSource.Tests.Missile
|
||||
Type = MissileType.LaserSemiActiveGuidance
|
||||
};
|
||||
|
||||
_missile = new LaserSemiActiveGuidedMissile(_properties, _simulationManager);
|
||||
var missileInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100
|
||||
};
|
||||
|
||||
var laserCodeConfig = new LaserCodeConfig
|
||||
{
|
||||
Code = new LaserCode
|
||||
{
|
||||
CodeType = LaserCodeType.PRF,
|
||||
CodeValue = 1234
|
||||
}
|
||||
};
|
||||
|
||||
var guidanceConfig = new LaserSemiActiveGuidanceConfig
|
||||
{
|
||||
FieldOfViewAngle = 30,
|
||||
LensDiameter = 0.1,
|
||||
SensorDiameter = 0.03,
|
||||
FocusedSpotDiameter = 0.006,
|
||||
ReflectionCoefficient = 0.2,
|
||||
TargetReflectiveArea = 1.0,
|
||||
LockThreshold = 1e-12,
|
||||
SpotOffsetSensitivity = 0.5
|
||||
};
|
||||
|
||||
_missile = new LaserSemiActiveGuidedMissile(
|
||||
"missile1",
|
||||
_properties,
|
||||
missileInitialMotion,
|
||||
laserCodeConfig,
|
||||
guidanceConfig,
|
||||
_simulationManager
|
||||
);
|
||||
_simulationManager.RegisterEntity("missile1", _missile);
|
||||
}
|
||||
|
||||
@ -104,7 +135,7 @@ namespace ThreatSource.Tests.Missile
|
||||
_missile.Fire();
|
||||
_missile.Activate();
|
||||
var maxDistance = _properties.MaxFlightDistance;
|
||||
var timeToExceedDistance = maxDistance / _properties.InitialSpeed + 1;
|
||||
var timeToExceedDistance = maxDistance / 100 + 1; // 使用初始速度100
|
||||
|
||||
// Act
|
||||
for (double time = 0; time < timeToExceedDistance; time += 0.1)
|
||||
|
||||
@ -4,6 +4,7 @@ using ThreatSource.Simulation;
|
||||
using ThreatSource.Utils;
|
||||
using ThreatSource.Tests.Simulation;
|
||||
using ThreatSource.Target;
|
||||
using ThreatSource.Guidance;
|
||||
|
||||
namespace ThreatSource.Tests.Missile
|
||||
{
|
||||
@ -22,10 +23,6 @@ namespace ThreatSource.Tests.Missile
|
||||
|
||||
_properties = new MissileProperties
|
||||
{
|
||||
Id = "missile1",
|
||||
InitialPosition = new Vector3D(0, 0, 0),
|
||||
InitialOrientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100,
|
||||
MaxSpeed = 1000,
|
||||
MaxFlightTime = 100,
|
||||
MaxFlightDistance = 10000,
|
||||
@ -37,7 +34,28 @@ namespace ThreatSource.Tests.Missile
|
||||
Type = MissileType.MillimeterWaveTerminalGuidance
|
||||
};
|
||||
|
||||
_missile = new MillimeterWaveTerminalGuidedMissile(_properties, _simulationManager);
|
||||
var missileInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100
|
||||
};
|
||||
|
||||
var guidanceConfig = new MillimeterWaveGuidanceConfig
|
||||
{
|
||||
FieldOfViewAngle = 30,
|
||||
TransmitPower = 0.5,
|
||||
AntennaGainDB = 25,
|
||||
WaveFrequency = 94e9
|
||||
};
|
||||
|
||||
_missile = new MillimeterWaveTerminalGuidedMissile(
|
||||
"missile1",
|
||||
_properties,
|
||||
missileInitialMotion,
|
||||
guidanceConfig,
|
||||
_simulationManager
|
||||
);
|
||||
_simulationManager.RegisterEntity("missile1", _missile);
|
||||
}
|
||||
|
||||
@ -56,7 +74,13 @@ namespace ThreatSource.Tests.Missile
|
||||
public void Update_StageTransition_WorksCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
var tank = new Tank("target1", new Vector3D(1000, 0, 0), 0, _simulationManager);
|
||||
var tankInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(1000, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
};
|
||||
var tank = new Tank("target1", tankInitialMotion, _simulationManager);
|
||||
_simulationManager.RegisterEntity("target1", tank);
|
||||
tank.Activate();
|
||||
|
||||
@ -112,7 +136,7 @@ namespace ThreatSource.Tests.Missile
|
||||
_missile.Fire();
|
||||
_missile.Activate();
|
||||
var maxDistance = _properties.MaxFlightDistance;
|
||||
var timeToExceedDistance = maxDistance / _properties.InitialSpeed + 1;
|
||||
var timeToExceedDistance = maxDistance / 100 + 1; // 使用初始速度100
|
||||
|
||||
// Act
|
||||
for (double time = 0; time < timeToExceedDistance; time += 0.1)
|
||||
|
||||
@ -17,6 +17,7 @@ namespace ThreatSource.Tests.Missile
|
||||
private readonly MissileProperties _properties;
|
||||
private readonly MissileProperties _submunitionProperties;
|
||||
private readonly Tank _tank;
|
||||
private readonly InitialMotionParameters _missileInitialMotion;
|
||||
|
||||
public TerminalSensitiveMissileTests(ITestOutputHelper output)
|
||||
{
|
||||
@ -26,10 +27,16 @@ namespace ThreatSource.Tests.Missile
|
||||
_simulationManager.SetSimulationAdapter(_testAdapter);
|
||||
|
||||
// 先创建并注册目标
|
||||
var tankInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(100, 0, 100),
|
||||
Orientation = new Orientation(Math.PI/4, 0, 0), // 目标朝向45度
|
||||
InitialSpeed = 0
|
||||
};
|
||||
|
||||
_tank = new Tank(
|
||||
"tank1",
|
||||
new Vector3D(100, 0, 100),
|
||||
Math.PI/4, // 目标朝向45度
|
||||
tankInitialMotion,
|
||||
_simulationManager
|
||||
);
|
||||
_simulationManager.RegisterEntity("tank1", _tank);
|
||||
@ -37,10 +44,6 @@ namespace ThreatSource.Tests.Missile
|
||||
|
||||
_properties = new MissileProperties
|
||||
{
|
||||
Id = "missile1",
|
||||
InitialPosition = new Vector3D(3000, 0, 100),
|
||||
InitialOrientation = new Orientation(Math.PI, 0, 0),
|
||||
InitialSpeed = 800,
|
||||
MaxSpeed = 1000,
|
||||
MaxFlightTime = 30,
|
||||
MaxFlightDistance = 5000,
|
||||
@ -54,6 +57,13 @@ namespace ThreatSource.Tests.Missile
|
||||
Type = MissileType.TerminalSensitiveMissile
|
||||
};
|
||||
|
||||
_missileInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(3000, 0, 100),
|
||||
Orientation = new Orientation(Math.PI, 0, 0),
|
||||
InitialSpeed = 800
|
||||
};
|
||||
|
||||
_submunitionProperties = new MissileProperties
|
||||
{
|
||||
MaxSpeed = 2000,
|
||||
@ -68,7 +78,23 @@ namespace ThreatSource.Tests.Missile
|
||||
Type = MissileType.TerminalSensitiveSubmunition
|
||||
};
|
||||
|
||||
_missile = new TerminalSensitiveMissile("tank1", _properties, _submunitionProperties, 1, _simulationManager);
|
||||
var submunitionConfig = new TerminalSensitiveSubmunitionConfig
|
||||
{
|
||||
SeparationHeight = 1000.0,
|
||||
SeparationDistance = 1000.0,
|
||||
SubmunitionSeparationAngle = 45.0
|
||||
};
|
||||
|
||||
_missile = new TerminalSensitiveMissile(
|
||||
"tank1",
|
||||
"missile1",
|
||||
_properties,
|
||||
_missileInitialMotion,
|
||||
_submunitionProperties,
|
||||
1,
|
||||
submunitionConfig,
|
||||
_simulationManager
|
||||
);
|
||||
_simulationManager.RegisterEntity("missile1", _missile);
|
||||
}
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ namespace ThreatSource.Tests.Missile
|
||||
private readonly MissileProperties _properties;
|
||||
private readonly Tank _tank;
|
||||
private readonly ITestOutputHelper _output;
|
||||
private readonly InitialMotionParameters _submunitionInitialMotion;
|
||||
|
||||
public TerminalSensitiveSubmunitionTests(ITestOutputHelper output)
|
||||
{
|
||||
@ -26,10 +27,16 @@ namespace ThreatSource.Tests.Missile
|
||||
_simulationManager.SetSimulationAdapter(_testAdapter);
|
||||
|
||||
// 先创建并注册目标
|
||||
var tankInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(100, 0, 100), // 目标位置
|
||||
Orientation = new Orientation(Math.PI/4, 0, 0), // 目标朝向45度
|
||||
InitialSpeed = 0
|
||||
};
|
||||
|
||||
_tank = new Tank(
|
||||
"tank1",
|
||||
new Vector3D(100, 0, 100), // 目标位置
|
||||
Math.PI/4, // 目标朝向45度
|
||||
tankInitialMotion,
|
||||
_simulationManager
|
||||
);
|
||||
_simulationManager.RegisterEntity("tank1", _tank);
|
||||
@ -38,10 +45,6 @@ namespace ThreatSource.Tests.Missile
|
||||
// 子弹的初始配置
|
||||
_properties = new MissileProperties
|
||||
{
|
||||
Id = "missile1_Sub_0",
|
||||
InitialPosition = new Vector3D(1100, 400, 100), // 在目标前方1000米,高度400米
|
||||
InitialOrientation = new Orientation(0, -Math.PI/4, 0), // 向下45度
|
||||
InitialSpeed = 200,
|
||||
MaxSpeed = 2000,
|
||||
MaxFlightTime = 50,
|
||||
MaxFlightDistance = 1000,
|
||||
@ -53,7 +56,28 @@ namespace ThreatSource.Tests.Missile
|
||||
Type = MissileType.TerminalSensitiveMissile
|
||||
};
|
||||
|
||||
_submunition = new TerminalSensitiveSubmunition("tank1", _properties, _simulationManager);
|
||||
_submunitionInitialMotion = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(1100, 400, 100), // 在目标前方1000米,高度400米
|
||||
Orientation = new Orientation(0, -Math.PI/4, 0), // 向下45度
|
||||
InitialSpeed = 200
|
||||
};
|
||||
|
||||
var submunitionConfig = new TerminalSensitiveSubmunitionConfig
|
||||
{
|
||||
SeparationHeight = 400.0,
|
||||
SeparationDistance = 1000.0,
|
||||
SubmunitionSeparationAngle = 45.0
|
||||
};
|
||||
|
||||
_submunition = new TerminalSensitiveSubmunition(
|
||||
"tank1",
|
||||
"missile1_Sub_0",
|
||||
_properties,
|
||||
_submunitionInitialMotion,
|
||||
submunitionConfig,
|
||||
_simulationManager
|
||||
);
|
||||
_simulationManager.RegisterEntity("missile1_Sub_0", _submunition);
|
||||
}
|
||||
|
||||
@ -61,8 +85,8 @@ namespace ThreatSource.Tests.Missile
|
||||
public void Constructor_InitializesPropertiesCorrectly()
|
||||
{
|
||||
Assert.Equal("missile1_Sub_0", _submunition.Id);
|
||||
Assert.Equal(_properties.InitialPosition, _submunition.Position);
|
||||
Assert.Equal(_properties.InitialSpeed, _submunition.Speed);
|
||||
Assert.Equal(_submunitionInitialMotion.Position, _submunition.Position);
|
||||
Assert.Equal(_submunitionInitialMotion.InitialSpeed, _submunition.Speed);
|
||||
Assert.False(_submunition.IsActive);
|
||||
Assert.False(_submunition.IsGuidance);
|
||||
}
|
||||
|
||||
@ -22,6 +22,9 @@ namespace ThreatSource.Tests.Simulation
|
||||
private double _currentTime = 0;
|
||||
private readonly object _eventLock = new object();
|
||||
|
||||
// 添加事件声明
|
||||
public event EventHandler<SimulationEvent>? EventPublished;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数,初始化测试适配器
|
||||
/// </summary>
|
||||
@ -58,6 +61,8 @@ namespace ThreatSource.Tests.Simulation
|
||||
{
|
||||
simEvent.Timestamp = _currentTime; // 使用仿真时间作为时间戳
|
||||
_publishedEvents.Add(simEvent);
|
||||
// 触发事件
|
||||
EventPublished?.Invoke(this, simEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -14,14 +14,31 @@ namespace ThreatSource.Tests.Target
|
||||
public TankTests()
|
||||
{
|
||||
_simulationManager = new SimulationManager();
|
||||
_tank = new Tank("tank1", new Vector3D(100, 0, 0), 10, _simulationManager);
|
||||
|
||||
// 创建初始运动参数
|
||||
var initialMotionParameters = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(100, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 10
|
||||
};
|
||||
|
||||
// 使用新的构造函数创建坦克
|
||||
_tank = new Tank("tank1", initialMotionParameters, _simulationManager);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Constructor_InitializesPropertiesCorrectly()
|
||||
{
|
||||
// Arrange & Act
|
||||
var tank = new Tank("tank2", new Vector3D(200, 0, 0), 10, _simulationManager);
|
||||
var initialMotionParameters = new InitialMotionParameters
|
||||
{
|
||||
Position = new Vector3D(200, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 10
|
||||
};
|
||||
|
||||
var tank = new Tank("tank2", initialMotionParameters, _simulationManager);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(tank);
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
using ThreatSource.Utils;
|
||||
using ThreatSource.Simulation;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ThreatSource.Guidance
|
||||
{
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using ThreatSource.Utils;
|
||||
using ThreatSource.Jamming;
|
||||
|
||||
namespace ThreatSource.Indicator
|
||||
{
|
||||
@ -10,9 +11,10 @@ namespace ThreatSource.Indicator
|
||||
/// - 目标和导弹的关联
|
||||
/// - 运行状态的获取
|
||||
/// - 位置和姿态的管理
|
||||
/// - 干扰处理能力
|
||||
/// 是激光指示器、红外跟踪器等具体指示器的抽象基础
|
||||
/// </remarks>
|
||||
public interface IIndicator
|
||||
public interface IIndicator : IJammable
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置目标ID
|
||||
@ -42,6 +44,7 @@ namespace ThreatSource.Indicator
|
||||
/// - 指示器的工作状态
|
||||
/// - 位置、速度和姿态信息
|
||||
/// - 激活状态
|
||||
/// - 干扰状态
|
||||
/// </remarks>
|
||||
IndicatorRunningState GetRunningState();
|
||||
}
|
||||
@ -55,6 +58,7 @@ namespace ThreatSource.Indicator
|
||||
/// - 工作状态(类型和状态)
|
||||
/// - 运动状态(位置、速度、姿态)
|
||||
/// - 功能状态(是否激活)
|
||||
/// - 干扰状态(是否被干扰)
|
||||
/// 用于状态监控和控制决策
|
||||
/// </remarks>
|
||||
public struct IndicatorRunningState
|
||||
@ -130,6 +134,15 @@ namespace ThreatSource.Indicator
|
||||
/// true表示正在工作,false表示待机
|
||||
/// </remarks>
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置指示器的干扰状态
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 表示指示器当前的干扰状态
|
||||
/// 用于状态监控和干扰防护
|
||||
/// </remarks>
|
||||
public JammingState JammingState { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -178,4 +191,25 @@ namespace ThreatSource.Indicator
|
||||
/// </summary>
|
||||
Idle
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 干扰状态枚举,定义了指示器的干扰状态
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 包含两种基本状态:
|
||||
/// - Normal:正常状态,未受到干扰
|
||||
/// - Jammed:干扰状态,受到干扰影响
|
||||
/// 用于干扰状态监控和防护
|
||||
/// </remarks>
|
||||
public enum JammingState
|
||||
{
|
||||
/// <summary>
|
||||
/// 正常状态
|
||||
/// </summary>
|
||||
Normal,
|
||||
/// <summary>
|
||||
/// 干扰状态
|
||||
/// </summary>
|
||||
Jammed
|
||||
}
|
||||
}
|
||||
|
||||
160
ThreatSource/src/Indicator/IndicatorBase.cs
Normal file
160
ThreatSource/src/Indicator/IndicatorBase.cs
Normal file
@ -0,0 +1,160 @@
|
||||
using ThreatSource.Utils;
|
||||
using ThreatSource.Jamming;
|
||||
using ThreatSource.Simulation;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ThreatSource.Indicator
|
||||
{
|
||||
/// <summary>
|
||||
/// 指示器抽象基类,实现IIndicator接口的基本功能
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 该类提供了指示器的通用实现:
|
||||
/// - 位置和姿态管理
|
||||
/// - 激活状态控制
|
||||
/// - 干扰处理机制
|
||||
/// 是具体指示器类的实现基础
|
||||
/// </remarks>
|
||||
public abstract class IndicatorBase : SimulationElement, IIndicator
|
||||
{
|
||||
/// <summary>
|
||||
/// 干扰处理器
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 负责处理各类干扰对指示器的影响
|
||||
/// 管理干扰状态和恢复
|
||||
/// </remarks>
|
||||
private protected JammingHandler? JammingHandler { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取设备支持的干扰类型
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 定义指示器可以被哪些类型的干扰影响
|
||||
/// 子类需要重写此属性以指定支持的干扰类型
|
||||
/// </remarks>
|
||||
public abstract IEnumerable<JammingType> SupportedJammingTypes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取设备当前是否处于被干扰状态
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// true表示指示器当前受到干扰影响
|
||||
/// false表示指示器正常工作
|
||||
/// </remarks>
|
||||
public bool IsJammed => JammingHandler?.IsJammed ?? false;
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置目标ID
|
||||
/// </summary>
|
||||
public string? TargetId { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置导弹ID
|
||||
/// </summary>
|
||||
public string? MissileId { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始化指示器基类的新实例
|
||||
/// </summary>
|
||||
/// <param name="id">指示器ID</param>
|
||||
/// <param name="position">初始位置</param>
|
||||
/// <param name="orientation">初始朝向</param>
|
||||
/// <param name="initialSpeed">初始速度</param>
|
||||
/// <param name="manager">仿真管理器实例</param>
|
||||
/// <remarks>
|
||||
/// 构造过程:
|
||||
/// - 调用基类构造器
|
||||
/// - 初始化基本属性
|
||||
/// - 初始化干扰处理器
|
||||
/// </remarks>
|
||||
protected IndicatorBase(string id, Vector3D position, Orientation orientation, double initialSpeed, ISimulationManager manager)
|
||||
: base(id, position, orientation, initialSpeed, manager)
|
||||
{
|
||||
InitializeJammingHandler();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化干扰处理器
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 子类需要重写此方法以初始化适合自身的干扰处理器
|
||||
/// </remarks>
|
||||
protected abstract void InitializeJammingHandler();
|
||||
|
||||
/// <summary>
|
||||
/// 应用干扰
|
||||
/// </summary>
|
||||
/// <param name="parameters">干扰参数</param>
|
||||
/// <remarks>
|
||||
/// 处理对指示器的干扰影响
|
||||
/// 只有支持的干扰类型才会被处理
|
||||
/// </remarks>
|
||||
public virtual void ApplyJamming(JammingParameters parameters)
|
||||
{
|
||||
if (SupportedJammingTypes.Contains(parameters.Type))
|
||||
{
|
||||
JammingHandler?.HandleJamming(parameters);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除干扰
|
||||
/// </summary>
|
||||
/// <param name="type">要清除的干扰类型</param>
|
||||
/// <remarks>
|
||||
/// 移除特定类型的干扰影响
|
||||
/// 恢复指示器的正常工作状态
|
||||
/// </remarks>
|
||||
public virtual void ClearJamming(JammingType type)
|
||||
{
|
||||
if (SupportedJammingTypes.Contains(type))
|
||||
{
|
||||
JammingHandler?.ClearJamming();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新指示器状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长,单位:秒</param>
|
||||
/// <remarks>
|
||||
/// 更新过程:
|
||||
/// - 调用基类的更新方法
|
||||
/// - 检查激活状态
|
||||
/// - 更新干扰状态
|
||||
/// - 处理指示器特定逻辑
|
||||
/// </remarks>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
if (IsActive)
|
||||
{
|
||||
JammingHandler?.Update(deltaTime);
|
||||
UpdateIndicator(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新指示器特定功能
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长,单位:秒</param>
|
||||
/// <remarks>
|
||||
/// 子类需要重写此方法以实现特定的更新逻辑
|
||||
/// 只有在未被干扰时才应执行正常的功能逻辑
|
||||
/// </remarks>
|
||||
protected virtual void UpdateIndicator(double deltaTime)
|
||||
{
|
||||
// 子类中实现具体的指示器更新逻辑
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取指示器运行状态
|
||||
/// </summary>
|
||||
/// <returns>包含指示器完整状态信息的结构体</returns>
|
||||
/// <remarks>
|
||||
/// 子类需要重写此方法以提供完整的状态信息
|
||||
/// 包括位置、姿态、目标关联和干扰状态等
|
||||
/// </remarks>
|
||||
public abstract IndicatorRunningState GetRunningState();
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,8 @@
|
||||
using ThreatSource.Simulation;
|
||||
using ThreatSource.Utils;
|
||||
using ThreatSource.Missile;
|
||||
using ThreatSource.Jamming;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace ThreatSource.Indicator
|
||||
{
|
||||
@ -13,27 +15,23 @@ namespace ThreatSource.Indicator
|
||||
/// - 角度测量和计算
|
||||
/// - 制导指令生成
|
||||
/// - 事件处理和状态管理
|
||||
/// - 干扰防护处理
|
||||
/// 通过测量目标的红外辐射实现对导弹的制导控制
|
||||
/// </remarks>
|
||||
public class InfraredTracker : SimulationElement, IIndicator
|
||||
public class InfraredTracker : IndicatorBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置当前跟踪的导弹ID
|
||||
/// 获取设备支持的干扰类型
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 记录当前正在跟踪的导弹标识符
|
||||
/// 用于导弹识别和制导控制
|
||||
/// 红外测角仪支持的干扰类型:
|
||||
/// - 红外干扰
|
||||
/// - 激光干扰
|
||||
/// </remarks>
|
||||
public string? MissileId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置目标ID
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 记录当前跟踪的目标标识符
|
||||
/// 用于目标识别和状态更新
|
||||
/// </remarks>
|
||||
public string? TargetId { get; private set; }
|
||||
public override IEnumerable<JammingType> SupportedJammingTypes => new[]
|
||||
{
|
||||
JammingType.Infrared
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 红外测角仪配置参数
|
||||
@ -81,20 +79,33 @@ namespace ThreatSource.Indicator
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新红外测角仪状态
|
||||
/// 初始化干扰处理器
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 创建适用于红外测角仪的干扰处理器
|
||||
/// </remarks>
|
||||
protected override void InitializeJammingHandler()
|
||||
{
|
||||
JammingHandler = new InfraredTrackerJammingHandler(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新指示器特定功能
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长,单位:秒</param>
|
||||
/// <remarks>
|
||||
/// 更新过程:
|
||||
/// - 检查激活状态
|
||||
/// 实现红外测角仪特定的更新逻辑:
|
||||
/// - 只有在未被干扰时才执行跟踪
|
||||
/// - 更新跟踪状态
|
||||
/// - 处理目标跟踪
|
||||
/// </remarks>
|
||||
public override void Update(double deltaTime)
|
||||
protected override void UpdateIndicator(double deltaTime)
|
||||
{
|
||||
if (!IsActive) return;
|
||||
|
||||
UpdateTracking();
|
||||
// 只有在未被干扰时才执行跟踪
|
||||
if (!IsJammed)
|
||||
{
|
||||
UpdateTracking();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -226,6 +237,7 @@ namespace ThreatSource.Indicator
|
||||
base.Activate();
|
||||
SimulationManager.SubscribeToEvent<InfraredGuidanceMissileLightEvent>(OnInfraredGuidanceMissileLight);
|
||||
SimulationManager.SubscribeToEvent<InfraredGuidanceMissileLightOffEvent>(OnInfraredGuidanceMissileLightOff);
|
||||
SimulationManager.SubscribeToEvent<InfraredJammingEvent>(OnInfraredJamming);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -242,6 +254,88 @@ namespace ThreatSource.Indicator
|
||||
base.Deactivate();
|
||||
SimulationManager.UnsubscribeFromEvent<InfraredGuidanceMissileLightEvent>(OnInfraredGuidanceMissileLight);
|
||||
SimulationManager.UnsubscribeFromEvent<InfraredGuidanceMissileLightOffEvent>(OnInfraredGuidanceMissileLightOff);
|
||||
SimulationManager.UnsubscribeFromEvent<InfraredJammingEvent>(OnInfraredJamming);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理红外干扰事件
|
||||
/// </summary>
|
||||
/// <param name="evt">红外干扰事件数据</param>
|
||||
/// <remarks>
|
||||
/// 处理过程:
|
||||
/// - 计算干扰效果
|
||||
/// - 应用干扰状态
|
||||
/// </remarks>
|
||||
private void OnInfraredJamming(InfraredJammingEvent evt)
|
||||
{
|
||||
// 计算干扰源与测角仪的相对位置
|
||||
Vector3D relativePosition = evt.JammingSourcePosition - Position;
|
||||
double distance = relativePosition.Magnitude();
|
||||
|
||||
// 计算干扰源与测角仪的相对方向
|
||||
Vector3D jammingToTracker = relativePosition.Normalize();
|
||||
|
||||
// 计算干扰方向与干扰源到测角仪方向的夹角
|
||||
// 注意:干扰源到测角仪的方向应该与干扰方向相反
|
||||
double angle = Math.Acos(-Vector3D.DotProduct(evt.JammingDirection.Normalize(), jammingToTracker));
|
||||
|
||||
Debug.WriteLine($"干扰判断 - 距离: {distance:F2}米, 夹角: {angle * 180 / Math.PI:F2}度, 角度范围: {evt.JammingAngleRange * 180 / Math.PI:F2}度");
|
||||
|
||||
// 判断是否在干扰角度范围内
|
||||
if (angle <= evt.JammingAngleRange)
|
||||
{
|
||||
// 计算距离衰减后的实际干扰功率
|
||||
double attenuatedPower = evt.JammingPower / (distance * distance);
|
||||
|
||||
// 检查测角仪工作波段是否在干扰波长范围内
|
||||
bool isWavelengthInRange = IsWavelengthInRange(evt.WavelengthMin, evt.WavelengthMax);
|
||||
|
||||
Debug.WriteLine($"干扰功率 - 原始: {evt.JammingPower:F2}W, 衰减后: {attenuatedPower:F2}W, 阈值: {config.JammingResistanceThreshold:F2}W");
|
||||
Debug.WriteLine($"波长范围 - 干扰: {evt.WavelengthMin:F2}-{evt.WavelengthMax:F2}μm, 匹配: {isWavelengthInRange}");
|
||||
|
||||
// 如果功率足够且波长匹配,则应用干扰
|
||||
if (attenuatedPower >= config.JammingResistanceThreshold && isWavelengthInRange)
|
||||
{
|
||||
Debug.WriteLine("应用干扰 - 条件满足,创建干扰参数");
|
||||
|
||||
// 创建干扰参数对象
|
||||
var jammingParameters = new JammingParameters
|
||||
{
|
||||
Type = JammingType.Infrared,
|
||||
Power = attenuatedPower,
|
||||
Direction = evt.JammingDirection,
|
||||
AngleRange = evt.JammingAngleRange,
|
||||
Mode = evt.JammingMode,
|
||||
Duration = evt.Duration
|
||||
};
|
||||
|
||||
// 应用干扰
|
||||
ApplyJamming(jammingParameters);
|
||||
Debug.WriteLine($"干扰状态 - IsJammed: {IsJammed}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.WriteLine($"不满足干扰条件 - 功率不足或波长不匹配");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.WriteLine($"不在干扰角度范围内");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查干扰波长是否在测角仪工作波段范围内
|
||||
/// </summary>
|
||||
/// <param name="minWavelength">最小波长(微米)</param>
|
||||
/// <param name="maxWavelength">最大波长(微米)</param>
|
||||
/// <returns>如果波长范围有重叠则返回true</returns>
|
||||
private static bool IsWavelengthInRange(double minWavelength, double maxWavelength)
|
||||
{
|
||||
// 假设红外测角仪的工作波段为3-5μm(中波红外)和8-14μm(长波红外)
|
||||
// 这里应根据实际的红外测角仪配置来判断
|
||||
return (minWavelength <= 5 && maxWavelength >= 3) || // 中波红外
|
||||
(minWavelength <= 14 && maxWavelength >= 8); // 长波红外
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -255,7 +349,7 @@ namespace ThreatSource.Indicator
|
||||
/// - 位置和姿态信息
|
||||
/// - 激活状态
|
||||
/// </remarks>
|
||||
public IndicatorRunningState GetRunningState()
|
||||
public override IndicatorRunningState GetRunningState()
|
||||
{
|
||||
return new IndicatorRunningState
|
||||
{
|
||||
@ -265,7 +359,8 @@ namespace ThreatSource.Indicator
|
||||
State = IsTracking ? IndicatorState.Indicating : IndicatorState.Idle,
|
||||
Position = Position,
|
||||
Orientation = Orientation,
|
||||
IsActive = IsActive
|
||||
IsActive = IsActive,
|
||||
JammingState = IsJammed ? JammingState.Jammed : JammingState.Normal
|
||||
};
|
||||
}
|
||||
|
||||
@ -277,9 +372,10 @@ namespace ThreatSource.Indicator
|
||||
/// 返回信息包括:
|
||||
/// - 基本标识信息
|
||||
/// - 位置信息
|
||||
/// - 跟踪状态
|
||||
/// - 目标关联状态
|
||||
/// - 工作状态
|
||||
/// - 跟踪状态
|
||||
/// - 干扰状态
|
||||
/// </remarks>
|
||||
public override string GetStatus()
|
||||
{
|
||||
@ -288,7 +384,8 @@ namespace ThreatSource.Indicator
|
||||
$" 跟踪导弹: {MissileId ?? "无"}\n" +
|
||||
$" 目标: {TargetId ?? "无"}\n" +
|
||||
$" 状态: {(IsActive ? "活动" : "已销毁")}\n" +
|
||||
$" 跟踪状态: {(IsTracking ? "跟踪中" : "未跟踪")}\n";
|
||||
$" 跟踪状态: {(IsTracking ? "跟踪中" : "未跟踪")}\n" +
|
||||
$" 干扰状态: {(IsJammed ? "受干扰" : "正常")}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,8 @@ using ThreatSource.Simulation;
|
||||
using System;
|
||||
using ThreatSource.Utils;
|
||||
using System.Diagnostics;
|
||||
using ThreatSource.Jamming;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ThreatSource.Indicator
|
||||
{
|
||||
@ -15,8 +17,31 @@ namespace ThreatSource.Indicator
|
||||
/// - 实时更新波束位置和方向
|
||||
/// - 发布波束状态事件
|
||||
/// </remarks>
|
||||
public class LaserBeamRider : SimulationElement, IIndicator
|
||||
public class LaserBeamRider : IndicatorBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取设备支持的干扰类型
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 定义波束制导器可以被哪些类型的干扰影响
|
||||
/// </remarks>
|
||||
public override IEnumerable<JammingType> SupportedJammingTypes => new[]
|
||||
{
|
||||
JammingType.Laser,
|
||||
JammingType.RadioFrequency
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 初始化干扰处理器
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 创建适用于激光波束制导器的干扰处理器
|
||||
/// </remarks>
|
||||
protected override void InitializeJammingHandler()
|
||||
{
|
||||
JammingHandler = new LaserBeamRiderJammingHandler(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置激光功率
|
||||
/// </summary>
|
||||
@ -80,24 +105,6 @@ namespace ThreatSource.Indicator
|
||||
/// </remarks>
|
||||
public bool IsBeamOn { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前制导的导弹ID
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 记录正在接受制导的导弹标识符
|
||||
/// 如果为null表示当前没有制导目标
|
||||
/// </remarks>
|
||||
public string? MissileId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取目标ID
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 记录当前跟踪的目标标识符
|
||||
/// 如果为null表示当前没有跟踪目标
|
||||
/// </remarks>
|
||||
public string? TargetId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始化激光波束制导器的新实例
|
||||
/// </summary>
|
||||
@ -302,17 +309,18 @@ namespace ThreatSource.Indicator
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取激光驾束仪运行状态
|
||||
/// 获取指示器运行状态
|
||||
/// </summary>
|
||||
/// <returns>包含完整状态信息的结构体</returns>
|
||||
/// <returns>包含指示器完整状态信息的结构体</returns>
|
||||
/// <remarks>
|
||||
/// 返回信息包括:
|
||||
/// - 目标和导弹ID
|
||||
/// - 设备类型和工作状态
|
||||
/// - 位置和朝向信息
|
||||
/// - 目标和导弹关联状态
|
||||
/// - 工作类型和状态
|
||||
/// - 位置和姿态信息
|
||||
/// - 激活状态
|
||||
/// - 干扰状态
|
||||
/// </remarks>
|
||||
public IndicatorRunningState GetRunningState()
|
||||
public override IndicatorRunningState GetRunningState()
|
||||
{
|
||||
return new IndicatorRunningState
|
||||
{
|
||||
@ -322,7 +330,8 @@ namespace ThreatSource.Indicator
|
||||
State = IsBeamOn ? IndicatorState.Indicating : IndicatorState.Idle,
|
||||
Position = Position,
|
||||
Orientation = Orientation,
|
||||
IsActive = IsActive
|
||||
IsActive = IsActive,
|
||||
JammingState = IsJammed ? JammingState.Jammed : JammingState.Normal
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -2,6 +2,8 @@ using ThreatSource.Simulation;
|
||||
using System;
|
||||
using ThreatSource.Utils;
|
||||
using System.Diagnostics;
|
||||
using ThreatSource.Jamming;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ThreatSource.Indicator
|
||||
{
|
||||
@ -16,25 +18,30 @@ namespace ThreatSource.Indicator
|
||||
/// - 状态监控
|
||||
/// 通过激光照射目标实现半主动激光制导
|
||||
/// </remarks>
|
||||
public class LaserDesignator : SimulationElement, IIndicator
|
||||
public class LaserDesignator : IndicatorBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置目标ID
|
||||
/// 获取设备支持的干扰类型
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 记录当前照射的目标标识符
|
||||
/// 用于目标识别和状态更新
|
||||
/// 定义激光指示器可以被哪些类型的干扰影响
|
||||
/// </remarks>
|
||||
public string? TargetId { get; private set; }
|
||||
public override IEnumerable<JammingType> SupportedJammingTypes => new[]
|
||||
{
|
||||
JammingType.Laser,
|
||||
JammingType.RadioFrequency
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置导弹ID
|
||||
/// 初始化干扰处理器
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 记录当前关联的导弹标识符
|
||||
/// 用于导弹制导控制
|
||||
/// 创建适用于激光指示器的干扰处理器
|
||||
/// </remarks>
|
||||
public string? MissileId { get; private set; }
|
||||
protected override void InitializeJammingHandler()
|
||||
{
|
||||
JammingHandler = new LaserDesignatorJammingHandler(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置干扰阈值,单位:分贝
|
||||
@ -45,16 +52,6 @@ namespace ThreatSource.Indicator
|
||||
/// </remarks>
|
||||
public double JammingThreshold { get; private set; } = 0.0;
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置是否被干扰状态
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// true表示当前受到有效干扰
|
||||
/// false表示工作正常
|
||||
/// 影响激光照射的有效性
|
||||
/// </remarks>
|
||||
public bool IsJammed { get; private set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置是否正在照射状态
|
||||
/// </summary>
|
||||
@ -244,7 +241,14 @@ namespace ThreatSource.Indicator
|
||||
if (!IsJammed)
|
||||
{
|
||||
Debug.WriteLine($"激光目标指示器 {Id} 被干扰,停止工作");
|
||||
IsJammed = true;
|
||||
// 应用干扰
|
||||
var parameters = new JammingParameters
|
||||
{
|
||||
Type = JammingType.Laser,
|
||||
Power = evt.JammingPower,
|
||||
Direction = new Vector3D(1, 0, 0) // 简化处理
|
||||
};
|
||||
ApplyJamming(parameters);
|
||||
StopLaserIllumination();
|
||||
}
|
||||
}
|
||||
@ -253,7 +257,8 @@ namespace ThreatSource.Indicator
|
||||
if (IsJammed)
|
||||
{
|
||||
Debug.WriteLine($"激光目标指示器 {Id} 干扰解除,恢复工作");
|
||||
IsJammed = false;
|
||||
// 清除干扰
|
||||
ClearJamming(JammingType.Laser);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -275,7 +280,6 @@ namespace ThreatSource.Indicator
|
||||
if (!IsActive)
|
||||
{
|
||||
IsActive = true;
|
||||
IsJammed = false;
|
||||
// 先订阅事件
|
||||
SimulationManager.SubscribeToEvent<LaserJammingEvent>(OnLaserJamming);
|
||||
// 再开始照射
|
||||
@ -398,7 +402,7 @@ namespace ThreatSource.Indicator
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取激光指示器运行状态
|
||||
/// 获取指示器运行状态
|
||||
/// </summary>
|
||||
/// <returns>包含指示器完整状态信息的结构体</returns>
|
||||
/// <remarks>
|
||||
@ -407,8 +411,9 @@ namespace ThreatSource.Indicator
|
||||
/// - 工作类型和状态
|
||||
/// - 位置和姿态信息
|
||||
/// - 激活状态
|
||||
/// - 干扰状态
|
||||
/// </remarks>
|
||||
public IndicatorRunningState GetRunningState()
|
||||
public override IndicatorRunningState GetRunningState()
|
||||
{
|
||||
return new IndicatorRunningState
|
||||
{
|
||||
@ -418,7 +423,8 @@ namespace ThreatSource.Indicator
|
||||
State = IsIlluminationOn ? IndicatorState.Indicating : IndicatorState.Idle,
|
||||
Position = Position,
|
||||
Orientation = Orientation,
|
||||
IsActive = IsActive
|
||||
IsActive = IsActive,
|
||||
JammingState = IsJammed ? JammingState.Jammed : JammingState.Normal
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -29,4 +29,61 @@ namespace ThreatSource.Jamming
|
||||
/// <param name="type">要清除的干扰类型</param>
|
||||
void ClearJamming(JammingType type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 干扰模式枚举
|
||||
/// </summary>
|
||||
public enum JammingMode
|
||||
{
|
||||
/// <summary>
|
||||
/// 噪声干扰
|
||||
/// </summary>
|
||||
Noise,
|
||||
|
||||
/// <summary>
|
||||
/// 欺骗干扰
|
||||
/// </summary>
|
||||
Deception,
|
||||
|
||||
/// <summary>
|
||||
/// 阻塞干扰
|
||||
/// </summary>
|
||||
Blocking,
|
||||
|
||||
/// <summary>
|
||||
/// 扫频干扰
|
||||
/// </summary>
|
||||
Sweep
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 干扰类型枚举
|
||||
/// </summary>
|
||||
public enum JammingType
|
||||
{
|
||||
/// <summary>
|
||||
/// 红外干扰
|
||||
/// </summary>
|
||||
Infrared,
|
||||
|
||||
/// <summary>
|
||||
/// 毫米波干扰
|
||||
/// </summary>
|
||||
MillimeterWave,
|
||||
|
||||
/// <summary>
|
||||
/// 激光干扰
|
||||
/// </summary>
|
||||
Laser,
|
||||
|
||||
/// <summary>
|
||||
/// 射频干扰
|
||||
/// </summary>
|
||||
RadioFrequency,
|
||||
|
||||
/// <summary>
|
||||
/// GPS干扰
|
||||
/// </summary>
|
||||
GPS
|
||||
}
|
||||
}
|
||||
63
ThreatSource/src/Jamming/InfraredTrackerJammingHandler.cs
Normal file
63
ThreatSource/src/Jamming/InfraredTrackerJammingHandler.cs
Normal file
@ -0,0 +1,63 @@
|
||||
using ThreatSource.Indicator;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace ThreatSource.Jamming
|
||||
{
|
||||
/// <summary>
|
||||
/// 红外测角仪干扰处理器
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 处理红外测角仪的干扰效果:
|
||||
/// - 降低跟踪精度
|
||||
/// - 影响目标识别
|
||||
/// - 干扰制导指令
|
||||
/// </remarks>
|
||||
public class InfraredTrackerJammingHandler : JammingHandler
|
||||
{
|
||||
private readonly InfraredTracker tracker;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化红外测角仪干扰处理器的新实例
|
||||
/// </summary>
|
||||
/// <param name="tracker">要处理的红外测角仪</param>
|
||||
public InfraredTrackerJammingHandler(InfraredTracker tracker)
|
||||
{
|
||||
this.tracker = tracker;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当干扰被应用时调用
|
||||
/// </summary>
|
||||
/// <param name="parameters">干扰参数</param>
|
||||
/// <remarks>
|
||||
/// 实现干扰效果:
|
||||
/// - 暂停跟踪功能
|
||||
/// - 降低测量精度
|
||||
/// - 影响目标识别
|
||||
/// </remarks>
|
||||
protected override void OnJammingApplied(JammingParameters parameters)
|
||||
{
|
||||
// 实现红外测角仪的干扰效果
|
||||
// 可以根据干扰类型实现不同的干扰效果
|
||||
if (parameters.Type == JammingType.Infrared)
|
||||
{
|
||||
Debug.WriteLine($"红外测角仪受到红外干扰,功率:{parameters.Power}瓦特");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当干扰被清除时调用
|
||||
/// </summary>
|
||||
/// <param name="parameters">被清除的干扰参数</param>
|
||||
/// <remarks>
|
||||
/// 恢复设备功能:
|
||||
/// - 恢复跟踪能力
|
||||
/// - 恢复正常精度
|
||||
/// - 重新开始工作
|
||||
/// </remarks>
|
||||
protected override void OnJammingCleared(JammingParameters? parameters)
|
||||
{
|
||||
Debug.WriteLine("红外测角仪干扰已清除");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -15,6 +15,11 @@ namespace ThreatSource.Jamming
|
||||
/// </summary>
|
||||
protected JammingParameters? CurrentJamming { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 累积的干扰时间
|
||||
/// </summary>
|
||||
private double _elapsedTime;
|
||||
|
||||
/// <summary>
|
||||
/// 更新干扰状态
|
||||
/// </summary>
|
||||
@ -23,9 +28,9 @@ namespace ThreatSource.Jamming
|
||||
{
|
||||
if (IsJammed && CurrentJamming?.Duration != null)
|
||||
{
|
||||
_elapsedTime += deltaTime;
|
||||
// 检查是否超时
|
||||
var elapsed = (DateTime.Now - CurrentJamming.StartTime).TotalSeconds;
|
||||
if (elapsed >= CurrentJamming.Duration)
|
||||
if (_elapsedTime >= CurrentJamming.Duration)
|
||||
{
|
||||
ClearJamming();
|
||||
}
|
||||
@ -38,7 +43,7 @@ namespace ThreatSource.Jamming
|
||||
/// <param name="parameters">干扰参数</param>
|
||||
public virtual void HandleJamming(JammingParameters parameters)
|
||||
{
|
||||
parameters.StartTime = DateTime.Now;
|
||||
_elapsedTime = 0;
|
||||
IsJammed = true;
|
||||
CurrentJamming = parameters;
|
||||
OnJammingApplied(parameters);
|
||||
@ -52,6 +57,7 @@ namespace ThreatSource.Jamming
|
||||
if (IsJammed)
|
||||
{
|
||||
IsJammed = false;
|
||||
_elapsedTime = 0;
|
||||
var oldJamming = CurrentJamming;
|
||||
CurrentJamming = null;
|
||||
OnJammingCleared(oldJamming);
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
namespace ThreatSource.Jamming
|
||||
{
|
||||
/// <summary>
|
||||
/// 干扰模式枚举
|
||||
/// </summary>
|
||||
public enum JammingMode
|
||||
{
|
||||
/// <summary>
|
||||
/// 噪声干扰
|
||||
/// </summary>
|
||||
Noise,
|
||||
|
||||
/// <summary>
|
||||
/// 欺骗干扰
|
||||
/// </summary>
|
||||
Deception,
|
||||
|
||||
/// <summary>
|
||||
/// 阻塞干扰
|
||||
/// </summary>
|
||||
Blocking,
|
||||
|
||||
/// <summary>
|
||||
/// 扫频干扰
|
||||
/// </summary>
|
||||
Sweep
|
||||
}
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
namespace ThreatSource.Jamming
|
||||
{
|
||||
/// <summary>
|
||||
/// 干扰类型枚举
|
||||
/// </summary>
|
||||
public enum JammingType
|
||||
{
|
||||
/// <summary>
|
||||
/// 红外干扰
|
||||
/// </summary>
|
||||
Infrared,
|
||||
|
||||
/// <summary>
|
||||
/// 毫米波干扰
|
||||
/// </summary>
|
||||
MillimeterWave,
|
||||
|
||||
/// <summary>
|
||||
/// 激光干扰
|
||||
/// </summary>
|
||||
Laser,
|
||||
|
||||
/// <summary>
|
||||
/// 射频干扰
|
||||
/// </summary>
|
||||
RadioFrequency,
|
||||
|
||||
/// <summary>
|
||||
/// GPS干扰
|
||||
/// </summary>
|
||||
GPS
|
||||
}
|
||||
}
|
||||
64
ThreatSource/src/Jamming/LaserBeamRiderJammingHandler.cs
Normal file
64
ThreatSource/src/Jamming/LaserBeamRiderJammingHandler.cs
Normal file
@ -0,0 +1,64 @@
|
||||
using ThreatSource.Indicator;
|
||||
|
||||
namespace ThreatSource.Jamming
|
||||
{
|
||||
/// <summary>
|
||||
/// 激光波束制导器干扰处理器
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 处理激光波束制导器的干扰效果:
|
||||
/// - 降低制导精度
|
||||
/// - 干扰制导信号
|
||||
/// - 影响制导效果
|
||||
/// </remarks>
|
||||
public class LaserBeamRiderJammingHandler : JammingHandler
|
||||
{
|
||||
private readonly LaserBeamRider beamRider;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化激光波束制导器干扰处理器的新实例
|
||||
/// </summary>
|
||||
/// <param name="beamRider">要处理的激光波束制导器</param>
|
||||
public LaserBeamRiderJammingHandler(LaserBeamRider beamRider)
|
||||
{
|
||||
this.beamRider = beamRider;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当干扰被应用时调用
|
||||
/// </summary>
|
||||
/// <param name="parameters">干扰参数</param>
|
||||
/// <remarks>
|
||||
/// 实现干扰效果:
|
||||
/// - 暂停制导功能
|
||||
/// - 降低制导精度
|
||||
/// - 影响波束稳定性
|
||||
/// </remarks>
|
||||
protected override void OnJammingApplied(JammingParameters parameters)
|
||||
{
|
||||
// 实现激光波束制导器的干扰效果
|
||||
// 根据干扰类型实现不同的干扰效果
|
||||
if (parameters.Type == JammingType.Laser)
|
||||
{
|
||||
// 激光干扰效果
|
||||
// 这里可以添加具体的干扰实现
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当干扰被清除时调用
|
||||
/// </summary>
|
||||
/// <param name="parameters">被清除的干扰参数</param>
|
||||
/// <remarks>
|
||||
/// 恢复设备功能:
|
||||
/// - 恢复制导能力
|
||||
/// - 恢复波束稳定性
|
||||
/// - 重新开始工作
|
||||
/// </remarks>
|
||||
protected override void OnJammingCleared(JammingParameters? parameters)
|
||||
{
|
||||
// 恢复激光波束制导器的功能
|
||||
// 这里可以添加恢复功能的实现
|
||||
}
|
||||
}
|
||||
}
|
||||
64
ThreatSource/src/Jamming/LaserDesignatorJammingHandler.cs
Normal file
64
ThreatSource/src/Jamming/LaserDesignatorJammingHandler.cs
Normal file
@ -0,0 +1,64 @@
|
||||
using ThreatSource.Indicator;
|
||||
|
||||
namespace ThreatSource.Jamming
|
||||
{
|
||||
/// <summary>
|
||||
/// 激光指示器干扰处理器
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 处理激光指示器的干扰效果:
|
||||
/// - 降低照射精度
|
||||
/// - 干扰激光信号
|
||||
/// - 影响制导效果
|
||||
/// </remarks>
|
||||
public class LaserDesignatorJammingHandler : JammingHandler
|
||||
{
|
||||
private readonly LaserDesignator designator;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化激光指示器干扰处理器的新实例
|
||||
/// </summary>
|
||||
/// <param name="designator">要处理的激光指示器</param>
|
||||
public LaserDesignatorJammingHandler(LaserDesignator designator)
|
||||
{
|
||||
this.designator = designator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当干扰被应用时调用
|
||||
/// </summary>
|
||||
/// <param name="parameters">干扰参数</param>
|
||||
/// <remarks>
|
||||
/// 实现干扰效果:
|
||||
/// - 暂停照射功能
|
||||
/// - 降低照射精度
|
||||
/// - 影响激光稳定性
|
||||
/// </remarks>
|
||||
protected override void OnJammingApplied(JammingParameters parameters)
|
||||
{
|
||||
// 实现激光指示器的干扰效果
|
||||
// 根据干扰类型实现不同的干扰效果
|
||||
if (parameters.Type == JammingType.Laser)
|
||||
{
|
||||
// 激光干扰效果
|
||||
// 这里可以添加具体的干扰实现
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当干扰被清除时调用
|
||||
/// </summary>
|
||||
/// <param name="parameters">被清除的干扰参数</param>
|
||||
/// <remarks>
|
||||
/// 恢复设备功能:
|
||||
/// - 恢复照射能力
|
||||
/// - 恢复激光稳定性
|
||||
/// - 重新开始工作
|
||||
/// </remarks>
|
||||
protected override void OnJammingCleared(JammingParameters? parameters)
|
||||
{
|
||||
// 恢复激光指示器的功能
|
||||
// 这里可以添加恢复功能的实现
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -88,7 +88,7 @@ namespace ThreatSource.Sensor
|
||||
/// <summary>
|
||||
/// 干扰处理器
|
||||
/// </summary>
|
||||
private protected JammingHandler? JammingHandler { get; set; }
|
||||
protected virtual JammingHandler? JammingHandler { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取设备支持的干扰类型
|
||||
@ -563,6 +563,15 @@ namespace ThreatSource.Simulation
|
||||
/// </summary>
|
||||
public double UpdateFrequency { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 干扰抗性阈值(瓦特)
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 定义了红外测角仪抵抗干扰的能力
|
||||
/// 当实际干扰功率超过此阈值时,测角仪将受到干扰
|
||||
/// </remarks>
|
||||
public double JammingResistanceThreshold { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数,设置默认值
|
||||
/// </summary>
|
||||
@ -572,6 +581,7 @@ namespace ThreatSource.Simulation
|
||||
FieldOfView = Math.PI / 3; // 60度
|
||||
AngleMeasurementAccuracy = 0.001; // 0.001弧度 (约0.057度)
|
||||
UpdateFrequency = 10; // 10赫兹
|
||||
JammingResistanceThreshold = 50; // 50瓦特
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using ThreatSource.Utils;
|
||||
using ThreatSource.Jamming;
|
||||
|
||||
namespace ThreatSource.Simulation
|
||||
{
|
||||
@ -564,11 +565,6 @@ namespace ThreatSource.Simulation
|
||||
/// </summary>
|
||||
public class InfraredJammingEvent : SimulationEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// 目标ID
|
||||
/// </summary>
|
||||
public string? TargetId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 干扰功率(瓦特)
|
||||
/// </summary>
|
||||
@ -583,6 +579,50 @@ namespace ThreatSource.Simulation
|
||||
/// 最大波长(微米)
|
||||
/// </summary>
|
||||
public double WavelengthMax { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 干扰源位置
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 干扰设备在三维空间中的位置
|
||||
/// 用于计算干扰效果衰减
|
||||
/// </remarks>
|
||||
public Vector3D JammingSourcePosition { get; set; } = Vector3D.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// 干扰方向
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 干扰波束的主方向向量
|
||||
/// 单位向量
|
||||
/// </remarks>
|
||||
public Vector3D JammingDirection { get; set; } = Vector3D.UnitX;
|
||||
|
||||
/// <summary>
|
||||
/// 干扰角度范围(弧度)
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 定义了干扰波束的发散角度
|
||||
/// 影响干扰的覆盖范围
|
||||
/// </remarks>
|
||||
public double JammingAngleRange { get; set; } = 0.5;
|
||||
|
||||
/// <summary>
|
||||
/// 干扰模式
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 定义干扰的工作模式
|
||||
/// 影响干扰的效果类型
|
||||
/// </remarks>
|
||||
public JammingMode JammingMode { get; set; } = JammingMode.Noise;
|
||||
|
||||
/// <summary>
|
||||
/// 干扰持续时间(秒)
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// null表示持续干扰,直到显式清除
|
||||
/// </remarks>
|
||||
public double? Duration { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user