增加激光目标指示器

This commit is contained in:
Tian jianyong 2024-10-06 14:56:20 +08:00
parent edfead8927
commit e94e94e031
11 changed files with 266 additions and 119 deletions

View File

@ -1,7 +0,0 @@
using ActiveProtect.Models;
public interface ISimulationManager
{
Vector3D GetElementPosition(string elementId);
// 添加其他必要的方法
}

View File

@ -0,0 +1,13 @@
using ActiveProtect.SimulationEnvironment;
namespace ActiveProtect.Models
{
public interface ILaserIlluminatable
{
bool IsIlluminated { get; }
void Illuminate();
// 移除重复的 Illuminate 方法(如果存在)
void StopIllumination();
Vector3D Position { get; }
}
}

56
Models/LaserDesignator.cs Normal file
View File

@ -0,0 +1,56 @@
using ActiveProtect.SimulationEnvironment;
namespace ActiveProtect.Models
{
public class LaserDesignator(string id, LaserDesignatorConfig laserDesignatorConfig, ISimulationManager simulationManager) : SimulationElement(id, laserDesignatorConfig.InitialPosition, new Orientation(), simulationManager)
{
public string TargetId { get; private set; } = laserDesignatorConfig.TargetId;
public bool IsActive { get; private set; } = true;
private const double MaxIlluminationRange = 1000; // 1公里单位
public void ActivateLaser()
{
IsActive = true;
}
public void DeactivateLaser()
{
IsActive = false;
}
public override void Update(double deltaTime)
{
if (IsActive)
{
IlluminateTarget();
}
}
private void IlluminateTarget()
{
var target = SimulationManager.GetEntityById(TargetId) as ILaserIlluminatable;
if (target != null)
{
double distanceToTarget = Vector3D.Distance(Position, target.Position);
if (distanceToTarget <= MaxIlluminationRange)
{
target.Illuminate();
}
else
{
target.StopIllumination();
}
}
}
public override string GetStatus()
{
return $"激光目标指示器 {Id}:\n" +
$" 位置: {Position}\n" +
$" 目标: {TargetId}\n" +
$" 激活状态: {(IsActive ? "" : "")}";
}
}
}

View File

@ -4,27 +4,18 @@ namespace ActiveProtect.Models
{ {
public class LaserSemiActiveGuidedMissile : Missile public class LaserSemiActiveGuidedMissile : Missile
{ {
// 添加新的属性
public bool IsLaserDetected { get; private set; } = false;
private const double LaserLockDistance = 1000; // 1公里单位
// 激光半主动制导导弹的特殊属性 // 激光半主动制导导弹的特殊属性
public bool IsLaserLocked { get; private set; } = false; public bool IsLaserLocked { get; private set; } = false;
public LaserSemiActiveGuidedMissile( public LaserSemiActiveGuidedMissile(
string id, string id,
Vector3D position, MissileConfig missileConfig,
Orientation orientation, ISimulationManager simulationManager)
double initialSpeed, : base(id, missileConfig, simulationManager)
double maxSpeed,
string targetId,
double maxFlightTime,
double maxFlightDistance,
MissileDistanceParams distanceParams,
FlightStageConfig stageConfig,
ISimulationManager simulationManager,
double thrustAcceleration,
double maxEngineBurnTime,
double maxAcceleration,
double proportionalNavigationCoefficient)
: base(id, position, orientation, initialSpeed, maxSpeed, targetId, maxFlightTime, maxFlightDistance,
distanceParams, stageConfig, simulationManager, thrustAcceleration, maxEngineBurnTime, maxAcceleration, proportionalNavigationCoefficient)
{ {
Type = MissileType.SemiActiveLaserGuidance; Type = MissileType.SemiActiveLaserGuidance;
} }
@ -33,20 +24,51 @@ namespace ActiveProtect.Models
{ {
base.Update(deltaTime); base.Update(deltaTime);
// 激光半主动制导导弹的特殊更新逻辑 // 更新激光检测和锁定逻辑
UpdateLaserLock(); UpdateLaserDetection();
if (IsLaserDetected)
{
UpdateLaserLock();
}
}
private void UpdateLaserDetection()
{
// 检查是否有激光照射目标
var target = SimulationManager.GetEntityById(TargetId) as ILaserIlluminatable;
if (target != null)
{
IsLaserDetected = target.IsIlluminated && DistanceToTarget <= LaserLockDistance;
}
else
{
IsLaserDetected = false;
}
} }
private void UpdateLaserLock() private void UpdateLaserLock()
{ {
// 这里实现激光锁定逻辑 // 如果检测到激光,则锁定目标
// 例如,根据距离和其他因素来决定是否锁定目标 IsLaserLocked = IsLaserDetected;
IsLaserLocked = DistanceToTarget < DistanceParams.TerminalGuidanceDistance;
if (IsLaserLocked)
{
// 根据激光照射的光斑进行导引
// 这里可以添加更精确的导引逻辑
AdjustTrajectoryBasedOnLaserGuidance();
}
}
private void AdjustTrajectoryBasedOnLaserGuidance()
{
// 实现基于激光导引的轨迹调整
// 这里可以添加更复杂的导引算法
} }
public override string GetStatus() public override string GetStatus()
{ {
return base.GetStatus().Replace("导弹", "激光半主动制导导弹") + return base.GetStatus().Replace("导弹", "激光半主动制导导弹") +
$"\n 激光检测: {(IsLaserDetected ? "" : "")}" +
$"\n 激光锁定: {(IsLaserLocked ? "" : "")}"; $"\n 激光锁定: {(IsLaserLocked ? "" : "")}";
} }
} }

View File

@ -79,8 +79,6 @@ namespace ActiveProtect.Models
private Vector3D LastTargetPosition; private Vector3D LastTargetPosition;
private const double N = 3; // 比例导引系数 private const double N = 3; // 比例导引系数
private readonly ISimulationManager _simulationManager;
public double ThrustAcceleration { get; protected set; } public double ThrustAcceleration { get; protected set; }
public double EngineBurnTime { get; protected set; } public double EngineBurnTime { get; protected set; }
public double MaxEngineBurnTime { get; protected set; } public double MaxEngineBurnTime { get; protected set; }
@ -89,32 +87,27 @@ namespace ActiveProtect.Models
public double ProportionalNavigationCoefficient { get; set; } public double ProportionalNavigationCoefficient { get; set; }
public Missile(string id, Vector3D position, Orientation orientation, double initialSpeed, double maxSpeed, public Missile(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
string targetId, double maxFlightTime, double maxFlightDistance, : base(id, missileConfig.InitialPosition, missileConfig.InitialOrientation, simulationManager)
MissileDistanceParams distanceParams,
FlightStageConfig stageConfig,
ISimulationManager simulationManager,
double thrustAcceleration, double maxEngineBurnTime, double maxAcceleration,
double proportionalNavigationCoefficient)
: base(id, position, orientation)
{ {
Speed = initialSpeed; Speed = missileConfig.InitialSpeed;
MaxSpeed = maxSpeed; MaxSpeed = missileConfig.MaxSpeed;
TargetId = targetId; MaxFlightTime = missileConfig.MaxFlightTime;
MaxFlightTime = maxFlightTime; MaxFlightDistance = missileConfig.MaxFlightDistance;
MaxFlightDistance = maxFlightDistance; DistanceParams = missileConfig.DistanceParams;
DistanceParams = distanceParams; StageConfig = missileConfig.StageConfig;
StageConfig = stageConfig;
IsActive = true; IsActive = true;
FlightTime = 0; FlightTime = 0;
FlightDistance = 0; FlightDistance = 0;
_simulationManager = simulationManager; SimulationManager = simulationManager;
ThrustAcceleration = thrustAcceleration; ThrustAcceleration = missileConfig.ThrustAcceleration;
EngineBurnTime = 0; EngineBurnTime = 0;
MaxEngineBurnTime = maxEngineBurnTime; MaxEngineBurnTime = missileConfig.MaxEngineBurnTime;
MaxAcceleration = maxAcceleration; MaxAcceleration = missileConfig.MaxAcceleration;
Vector3D horizontalDirection = new Vector3D(orientation.ToVector().X, 0, orientation.ToVector().Z).Normalize(); ProportionalNavigationCoefficient = missileConfig.ProportionalNavigationCoefficient;
Velocity = horizontalDirection * initialSpeed; TargetId = $"Tank_{missileConfig.TargetIndex + 1}";
Vector3D horizontalDirection = new Vector3D(Orientation.ToVector().X, 0, Orientation.ToVector().Z).Normalize();
Velocity = horizontalDirection * missileConfig.InitialSpeed;
// 设置初始阶段 // 设置初始阶段
CurrentStage = StageConfig.EnableLaunch ? FlightStage.Launch : CurrentStage = StageConfig.EnableLaunch ? FlightStage.Launch :
@ -125,8 +118,7 @@ namespace ActiveProtect.Models
Console.WriteLine($"导弹 {Id} 的初始阶: {CurrentStage}"); Console.WriteLine($"导弹 {Id} 的初始阶: {CurrentStage}");
LastTargetPosition = position; // 初始化 LastTargetPosition LastTargetPosition = Position; // 初始化 LastTargetPosition
ProportionalNavigationCoefficient = proportionalNavigationCoefficient;
} }
public override void Update(double deltaTime) public override void Update(double deltaTime)
@ -160,7 +152,7 @@ namespace ActiveProtect.Models
FlightTime += deltaTime; FlightTime += deltaTime;
FlightDistance += Speed * deltaTime; FlightDistance += Speed * deltaTime;
UpdateDistanceToTarget(Vector3D.Distance(Position, _simulationManager.GetElementPosition(TargetId))); UpdateDistanceToTarget(Vector3D.Distance(Position, SimulationManager.GetElementPosition(TargetId)));
// 首先检查是否命中目标 // 首先检查是否命中目标
if (CheckHit()) if (CheckHit())
@ -200,7 +192,7 @@ namespace ActiveProtect.Models
private (Vector3D, Vector3D) CalculateDerivatives(Vector3D position, Vector3D velocity, double deltaTime) private (Vector3D, Vector3D) CalculateDerivatives(Vector3D position, Vector3D velocity, double deltaTime)
{ {
Vector3D targetPosition = _simulationManager.GetElementPosition(TargetId); Vector3D targetPosition = SimulationManager.GetElementPosition(TargetId);
Vector3D LOS = targetPosition - position; Vector3D LOS = targetPosition - position;
Vector3D LOSRate = (targetPosition - LastTargetPosition) / deltaTime - velocity; Vector3D LOSRate = (targetPosition - LastTargetPosition) / deltaTime - velocity;
Vector3D guidanceAcceleration = Vector3D.CrossProduct(Vector3D.CrossProduct(LOS, LOSRate), LOS).Normalize() Vector3D guidanceAcceleration = Vector3D.CrossProduct(Vector3D.CrossProduct(LOS, LOSRate), LOS).Normalize()
@ -306,10 +298,4 @@ namespace ActiveProtect.Models
} }
} }
public struct MissileDistanceParams(double terminalGuidanceDistance, double attackDistance, double explosionDistance)
{
public double TerminalGuidanceDistance { get; set; } = terminalGuidanceDistance;
public double AttackDistance { get; set; } = attackDistance;
public double ExplosionDistance { get; set; } = explosionDistance;
}
} }

View File

@ -2,22 +2,29 @@ using ActiveProtect.SimulationEnvironment;
namespace ActiveProtect.Models namespace ActiveProtect.Models
{ {
public class Tank(string id, Vector3D position, Orientation orientation, double initialSpeed, double maxSpeed, double maxArmor) : SimulationElement(id, position, orientation) public class Tank : SimulationElement, ILaserIlluminatable
{ {
public double Speed { get; set; } = initialSpeed; public double Speed { get; set; } = 0;
public bool IsActive { get; private set; } = true; public bool IsActive { get; private set; } = false;
public double MaxSpeed { get; private set; } = maxSpeed; public double MaxSpeed { get; private set; } = 0;
public double MaxArmor { get; private set; } = maxArmor; public double MaxArmor { get; private set; } = 0;
public double Armor { get; private set; } = maxArmor; public double Armor { get; private set; } = 0;
public double CurrentArmor { get; private set; } = maxArmor; public double CurrentArmor { get; private set; } = 0;
public bool IsIlluminated { get; private set; } = false;
public override void Update(double deltaTime) public Tank(string id, TankConfig tankConfig, ISimulationManager simulationManager)
: base(id, tankConfig.InitialPosition, tankConfig.InitialOrientation, simulationManager)
{ {
if (!IsActive) return; Position = tankConfig.InitialPosition;
Orientation = tankConfig.InitialOrientation;
Position.X += Speed * Math.Cos(Orientation.Yaw) * Math.Cos(Orientation.Pitch) * deltaTime; Speed = tankConfig.InitialSpeed;
Position.Y += Speed * Math.Sin(Orientation.Pitch) * deltaTime; IsActive = true;
Position.Z += Speed * Math.Sin(Orientation.Yaw) * Math.Cos(Orientation.Pitch) * deltaTime; MaxSpeed = tankConfig.MaxSpeed;
MaxArmor = tankConfig.MaxArmor;
Armor = tankConfig.MaxArmor;
CurrentArmor = tankConfig.MaxArmor;
IsIlluminated = false;
SimulationManager = simulationManager;
} }
public void TakeDamage(double damage) public void TakeDamage(double damage)
@ -30,11 +37,59 @@ namespace ActiveProtect.Models
} }
} }
public void Illuminate()
{
IsIlluminated = true;
}
public void StopIllumination()
{
IsIlluminated = false;
}
public override void Update(double deltaTime)
{
// 移除对基类抽象方法的调用
// 实现坦克特定的更新逻辑
UpdatePosition(deltaTime);
UpdateArmor();
CheckIlluminationStatus();
}
private void UpdatePosition(double deltaTime)
{
// 根据速度更新坦克位置
Vector3D direction = Orientation.ToVector();
Vector3D movement = direction * Speed * deltaTime;
Position += movement;
}
private void UpdateArmor()
{
// 可能的装甲恢复逻辑
if (CurrentArmor < MaxArmor)
{
CurrentArmor = Math.Min(CurrentArmor + 10, MaxArmor);
}
}
private void CheckIlluminationStatus()
{
// 检查激光照射状态,可能会影响坦克的其他属性
if (IsIlluminated)
{
// 实现被激光照射时的效果
}
}
public override string GetStatus() public override string GetStatus()
{ {
return $"坦克 {Id}:\n" + return base.GetStatus() +
$" 位置: X={Position.X:F2}, Y={Position.Y:F2}, Z={Position.Z:F2}\n" + $"\n 速度: {Speed}" +
$" 装甲: {CurrentArmor:F2}"; $"\n 最大速度: {MaxSpeed}" +
$"\n 装甲: {CurrentArmor}/{MaxArmor}" +
$"\n 状态: {(IsActive ? "" : "")}" +
$"\n 激光照射: {(IsIlluminated ? "" : "")}";
} }
} }
} }

View File

@ -77,7 +77,7 @@ namespace ActiveProtect
}, },
// 新增激光半主动制导导弹配置 // 新增激光半主动制导导弹配置
new() { new() {
InitialPosition = new Vector3D(2000, 150, 100), InitialPosition = new Vector3D(1500, 150, 100),
InitialOrientation = new Orientation(Math.PI, -0.12, 0), InitialOrientation = new Orientation(Math.PI, -0.12, 0),
InitialSpeed = 700, InitialSpeed = 700,
MaxSpeed = 800, MaxSpeed = 800,
@ -93,6 +93,14 @@ namespace ActiveProtect
Type = MissileType.SemiActiveLaserGuidance Type = MissileType.SemiActiveLaserGuidance
} }
], ],
LaserDesignatorConfigs =
[
new LaserDesignatorConfig
{
InitialPosition = new Vector3D(500, 50, 100),
TargetId = "Tank_1"
}
],
SimulationTimeStep = 0.05 SimulationTimeStep = 0.05
}; };

View File

@ -0,0 +1,12 @@
using ActiveProtect.Models;
using ActiveProtect.SimulationEnvironment;
namespace ActiveProtect.SimulationEnvironment
{
public interface ISimulationManager
{
Vector3D GetElementPosition(string elementId);
SimulationElement GetEntityById(string id);
}
}

View File

@ -6,12 +6,14 @@ namespace ActiveProtect.SimulationEnvironment
{ {
public List<TankConfig> TankConfigs { get; set; } public List<TankConfig> TankConfigs { get; set; }
public List<MissileConfig> MissileConfigs { get; set; } public List<MissileConfig> MissileConfigs { get; set; }
public List<LaserDesignatorConfig> LaserDesignatorConfigs { get; set; }
public double SimulationTimeStep { get; set; } public double SimulationTimeStep { get; set; }
public SimulationConfig() public SimulationConfig()
{ {
TankConfigs = []; TankConfigs = [];
MissileConfigs = []; MissileConfigs = [];
LaserDesignatorConfigs = [];
SimulationTimeStep = 0.1; // 默认时间步长为0.1秒 SimulationTimeStep = 0.1; // 默认时间步长为0.1秒
} }
} }
@ -44,15 +46,14 @@ namespace ActiveProtect.SimulationEnvironment
public double ProportionalNavigationCoefficient { get; set; } public double ProportionalNavigationCoefficient { get; set; }
public Missile.FlightStageConfig StageConfig { get; set; } public Missile.FlightStageConfig StageConfig { get; set; }
public MissileDistanceParams DistanceParams { get; set; } public MissileDistanceParams DistanceParams { get; set; }
public MissileType Type { get; set; }
// 新增属性
public double ThrustAcceleration { get; set; } public double ThrustAcceleration { get; set; }
public double MaxEngineBurnTime { get; set; } public double MaxEngineBurnTime { get; set; }
public MissileType Type { get; set; }
public MissileConfig() public MissileConfig()
{ {
InitialPosition = new Vector3D(0, 0, 0); // 初始位 InitialPosition = new Vector3D(0, 0, 0); // 初始位<EFBFBD><EFBFBD>
InitialOrientation = new Orientation(0, 0, 0); // 初始方向 InitialOrientation = new Orientation(0, 0, 0); // 初始方向
InitialSpeed = 0; // 初始速度 InitialSpeed = 0; // 初始速度
MaxSpeed = 0; // 最大速度 MaxSpeed = 0; // 最大速度
@ -68,4 +69,23 @@ namespace ActiveProtect.SimulationEnvironment
Type = MissileType.StandardMissile; // 导弹类型 Type = MissileType.StandardMissile; // 导弹类型
} }
} }
public class LaserDesignatorConfig
{
public Vector3D InitialPosition { get; set; }
public string TargetId { get; set; }
public LaserDesignatorConfig()
{
InitialPosition = new Vector3D(0, 0, 0);
TargetId = "";
}
}
public struct MissileDistanceParams(double terminalGuidanceDistance, double attackDistance, double explosionDistance)
{
public double TerminalGuidanceDistance { get; set; } = terminalGuidanceDistance;
public double AttackDistance { get; set; } = attackDistance;
public double ExplosionDistance { get; set; } = explosionDistance;
}
} }

View File

@ -2,11 +2,12 @@ using ActiveProtect.Models;
namespace ActiveProtect.SimulationEnvironment namespace ActiveProtect.SimulationEnvironment
{ {
public abstract class SimulationElement(string id, Vector3D position, Orientation orientation) public abstract class SimulationElement(string id, Vector3D position, Orientation orientation, ISimulationManager simulationManager)
{ {
public string Id { get; set; } = id; public string Id { get; set; } = id;
public Vector3D Position { get; set; } = position; public Vector3D Position { get; set; } = position;
public Orientation Orientation { get; set; } = orientation; public Orientation Orientation { get; set; } = orientation;
public ISimulationManager SimulationManager { get; set; } = simulationManager;
public abstract void Update(double deltaTime); public abstract void Update(double deltaTime);

View File

@ -27,14 +27,7 @@ namespace ActiveProtect.SimulationEnvironment
for (int i = 0; i < config.TankConfigs.Count; i++) for (int i = 0; i < config.TankConfigs.Count; i++)
{ {
var tankConfig = config.TankConfigs[i]; var tankConfig = config.TankConfigs[i];
Elements.Add(new Tank( Elements.Add(new Tank($"Tank_{i + 1}", tankConfig, this));
$"Tank_{i + 1}",
tankConfig.InitialPosition,
tankConfig.InitialOrientation,
tankConfig.InitialSpeed,
tankConfig.MaxSpeed,
tankConfig.MaxArmor
));
} }
// 创建导弹(修改这部分) // 创建导弹(修改这部分)
@ -45,41 +38,24 @@ namespace ActiveProtect.SimulationEnvironment
{ {
MissileType.SemiActiveLaserGuidance => new LaserSemiActiveGuidedMissile( MissileType.SemiActiveLaserGuidance => new LaserSemiActiveGuidedMissile(
$"LSGM_{i + 1}", $"LSGM_{i + 1}",
missileConfig.InitialPosition, missileConfig,
missileConfig.InitialOrientation, this
missileConfig.InitialSpeed,
missileConfig.MaxSpeed,
$"Tank_{missileConfig.TargetIndex + 1}",
missileConfig.MaxFlightTime,
missileConfig.MaxFlightDistance,
missileConfig.DistanceParams,
missileConfig.StageConfig,
this,
missileConfig.ThrustAcceleration,
missileConfig.MaxEngineBurnTime,
missileConfig.MaxAcceleration,
missileConfig.ProportionalNavigationCoefficient
), ),
_ => new Missile( _ => new Missile(
$"NM_{i + 1}", $"NM_{i + 1}",
missileConfig.InitialPosition, missileConfig,
missileConfig.InitialOrientation, this
missileConfig.InitialSpeed,
missileConfig.MaxSpeed,
$"Tank_{missileConfig.TargetIndex + 1}",
missileConfig.MaxFlightTime,
missileConfig.MaxFlightDistance,
missileConfig.DistanceParams,
missileConfig.StageConfig,
this,
missileConfig.ThrustAcceleration,
missileConfig.MaxEngineBurnTime,
missileConfig.MaxAcceleration,
missileConfig.ProportionalNavigationCoefficient
), ),
}; };
Elements.Add(missile); Elements.Add(missile);
} }
// 创建激光目标指示器
for (int i = 0; i < config.LaserDesignatorConfigs.Count; i++)
{
var laserDesignatorConfig = config.LaserDesignatorConfigs[i];
Elements.Add(new LaserDesignator($"LD_{i + 1}", laserDesignatorConfig, this));
}
} }
public void Update() public void Update()
@ -130,5 +106,10 @@ namespace ActiveProtect.SimulationEnvironment
} }
throw new ArgumentException($"Element with id {elementId} not found"); throw new ArgumentException($"Element with id {elementId} not found");
} }
public SimulationElement GetEntityById(string id)
{
return Elements.FirstOrDefault(e => e.Id == id) ?? throw new InvalidOperationException($"Entity with id {id} not found");
}
} }
} }