增加激光目标指示器

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 bool IsLaserDetected { get; private set; } = false;
private const double LaserLockDistance = 1000; // 1公里单位
// 激光半主动制导导弹的特殊属性
public bool IsLaserLocked { get; private set; } = false;
public LaserSemiActiveGuidedMissile(
string id,
Vector3D position,
Orientation orientation,
double initialSpeed,
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)
MissileConfig missileConfig,
ISimulationManager simulationManager)
: base(id, missileConfig, simulationManager)
{
Type = MissileType.SemiActiveLaserGuidance;
}
@ -33,20 +24,51 @@ namespace ActiveProtect.Models
{
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()
{
// 这里实现激光锁定逻辑
// 例如,根据距离和其他因素来决定是否锁定目标
IsLaserLocked = DistanceToTarget < DistanceParams.TerminalGuidanceDistance;
// 如果检测到激光,则锁定目标
IsLaserLocked = IsLaserDetected;
if (IsLaserLocked)
{
// 根据激光照射的光斑进行导引
// 这里可以添加更精确的导引逻辑
AdjustTrajectoryBasedOnLaserGuidance();
}
}
private void AdjustTrajectoryBasedOnLaserGuidance()
{
// 实现基于激光导引的轨迹调整
// 这里可以添加更复杂的导引算法
}
public override string GetStatus()
{
return base.GetStatus().Replace("导弹", "激光半主动制导导弹") +
$"\n 激光检测: {(IsLaserDetected ? "" : "")}" +
$"\n 激光锁定: {(IsLaserLocked ? "" : "")}";
}
}

View File

@ -79,8 +79,6 @@ namespace ActiveProtect.Models
private Vector3D LastTargetPosition;
private const double N = 3; // 比例导引系数
private readonly ISimulationManager _simulationManager;
public double ThrustAcceleration { get; protected set; }
public double EngineBurnTime { get; protected set; }
public double MaxEngineBurnTime { get; protected set; }
@ -89,32 +87,27 @@ namespace ActiveProtect.Models
public double ProportionalNavigationCoefficient { get; set; }
public Missile(string id, Vector3D position, Orientation orientation, double initialSpeed, 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)
public Missile(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
: base(id, missileConfig.InitialPosition, missileConfig.InitialOrientation, simulationManager)
{
Speed = initialSpeed;
MaxSpeed = maxSpeed;
TargetId = targetId;
MaxFlightTime = maxFlightTime;
MaxFlightDistance = maxFlightDistance;
DistanceParams = distanceParams;
StageConfig = stageConfig;
Speed = missileConfig.InitialSpeed;
MaxSpeed = missileConfig.MaxSpeed;
MaxFlightTime = missileConfig.MaxFlightTime;
MaxFlightDistance = missileConfig.MaxFlightDistance;
DistanceParams = missileConfig.DistanceParams;
StageConfig = missileConfig.StageConfig;
IsActive = true;
FlightTime = 0;
FlightDistance = 0;
_simulationManager = simulationManager;
ThrustAcceleration = thrustAcceleration;
SimulationManager = simulationManager;
ThrustAcceleration = missileConfig.ThrustAcceleration;
EngineBurnTime = 0;
MaxEngineBurnTime = maxEngineBurnTime;
MaxAcceleration = maxAcceleration;
Vector3D horizontalDirection = new Vector3D(orientation.ToVector().X, 0, orientation.ToVector().Z).Normalize();
Velocity = horizontalDirection * initialSpeed;
MaxEngineBurnTime = missileConfig.MaxEngineBurnTime;
MaxAcceleration = missileConfig.MaxAcceleration;
ProportionalNavigationCoefficient = missileConfig.ProportionalNavigationCoefficient;
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 :
@ -125,8 +118,7 @@ namespace ActiveProtect.Models
Console.WriteLine($"导弹 {Id} 的初始阶: {CurrentStage}");
LastTargetPosition = position; // 初始化 LastTargetPosition
ProportionalNavigationCoefficient = proportionalNavigationCoefficient;
LastTargetPosition = Position; // 初始化 LastTargetPosition
}
public override void Update(double deltaTime)
@ -160,7 +152,7 @@ namespace ActiveProtect.Models
FlightTime += deltaTime;
FlightDistance += Speed * deltaTime;
UpdateDistanceToTarget(Vector3D.Distance(Position, _simulationManager.GetElementPosition(TargetId)));
UpdateDistanceToTarget(Vector3D.Distance(Position, SimulationManager.GetElementPosition(TargetId)));
// 首先检查是否命中目标
if (CheckHit())
@ -200,7 +192,7 @@ namespace ActiveProtect.Models
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 LOSRate = (targetPosition - LastTargetPosition) / deltaTime - velocity;
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
{
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 bool IsActive { get; private set; } = true;
public double MaxSpeed { get; private set; } = maxSpeed;
public double MaxArmor { get; private set; } = maxArmor;
public double Armor { get; private set; } = maxArmor;
public double CurrentArmor { get; private set; } = maxArmor;
public double Speed { get; set; } = 0;
public bool IsActive { get; private set; } = false;
public double MaxSpeed { get; private set; } = 0;
public double MaxArmor { get; private set; } = 0;
public double Armor { get; private set; } = 0;
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.X += Speed * Math.Cos(Orientation.Yaw) * Math.Cos(Orientation.Pitch) * deltaTime;
Position.Y += Speed * Math.Sin(Orientation.Pitch) * deltaTime;
Position.Z += Speed * Math.Sin(Orientation.Yaw) * Math.Cos(Orientation.Pitch) * deltaTime;
Position = tankConfig.InitialPosition;
Orientation = tankConfig.InitialOrientation;
Speed = tankConfig.InitialSpeed;
IsActive = true;
MaxSpeed = tankConfig.MaxSpeed;
MaxArmor = tankConfig.MaxArmor;
Armor = tankConfig.MaxArmor;
CurrentArmor = tankConfig.MaxArmor;
IsIlluminated = false;
SimulationManager = simulationManager;
}
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()
{
return $"坦克 {Id}:\n" +
$" 位置: X={Position.X:F2}, Y={Position.Y:F2}, Z={Position.Z:F2}\n" +
$" 装甲: {CurrentArmor:F2}";
return base.GetStatus() +
$"\n 速度: {Speed}" +
$"\n 最大速度: {MaxSpeed}" +
$"\n 装甲: {CurrentArmor}/{MaxArmor}" +
$"\n 状态: {(IsActive ? "" : "")}" +
$"\n 激光照射: {(IsIlluminated ? "" : "")}";
}
}
}

View File

@ -77,7 +77,7 @@ namespace ActiveProtect
},
// 新增激光半主动制导导弹配置
new() {
InitialPosition = new Vector3D(2000, 150, 100),
InitialPosition = new Vector3D(1500, 150, 100),
InitialOrientation = new Orientation(Math.PI, -0.12, 0),
InitialSpeed = 700,
MaxSpeed = 800,
@ -93,6 +93,14 @@ namespace ActiveProtect
Type = MissileType.SemiActiveLaserGuidance
}
],
LaserDesignatorConfigs =
[
new LaserDesignatorConfig
{
InitialPosition = new Vector3D(500, 50, 100),
TargetId = "Tank_1"
}
],
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<MissileConfig> MissileConfigs { get; set; }
public List<LaserDesignatorConfig> LaserDesignatorConfigs { get; set; }
public double SimulationTimeStep { get; set; }
public SimulationConfig()
{
TankConfigs = [];
MissileConfigs = [];
LaserDesignatorConfigs = [];
SimulationTimeStep = 0.1; // 默认时间步长为0.1秒
}
}
@ -44,15 +46,14 @@ namespace ActiveProtect.SimulationEnvironment
public double ProportionalNavigationCoefficient { get; set; }
public Missile.FlightStageConfig StageConfig { get; set; }
public MissileDistanceParams DistanceParams { get; set; }
public MissileType Type { get; set; }
// 新增属性
public double ThrustAcceleration { get; set; }
public double MaxEngineBurnTime { get; set; }
public MissileType Type { get; set; }
public MissileConfig()
{
InitialPosition = new Vector3D(0, 0, 0); // 初始位
InitialPosition = new Vector3D(0, 0, 0); // 初始位<EFBFBD><EFBFBD>
InitialOrientation = new Orientation(0, 0, 0); // 初始方向
InitialSpeed = 0; // 初始速度
MaxSpeed = 0; // 最大速度
@ -68,4 +69,23 @@ namespace ActiveProtect.SimulationEnvironment
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
{
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 Vector3D Position { get; set; } = position;
public Orientation Orientation { get; set; } = orientation;
public ISimulationManager SimulationManager { get; set; } = simulationManager;
public abstract void Update(double deltaTime);

View File

@ -27,14 +27,7 @@ namespace ActiveProtect.SimulationEnvironment
for (int i = 0; i < config.TankConfigs.Count; i++)
{
var tankConfig = config.TankConfigs[i];
Elements.Add(new Tank(
$"Tank_{i + 1}",
tankConfig.InitialPosition,
tankConfig.InitialOrientation,
tankConfig.InitialSpeed,
tankConfig.MaxSpeed,
tankConfig.MaxArmor
));
Elements.Add(new Tank($"Tank_{i + 1}", tankConfig, this));
}
// 创建导弹(修改这部分)
@ -45,41 +38,24 @@ namespace ActiveProtect.SimulationEnvironment
{
MissileType.SemiActiveLaserGuidance => new LaserSemiActiveGuidedMissile(
$"LSGM_{i + 1}",
missileConfig.InitialPosition,
missileConfig.InitialOrientation,
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
missileConfig,
this
),
_ => new Missile(
$"NM_{i + 1}",
missileConfig.InitialPosition,
missileConfig.InitialOrientation,
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
missileConfig,
this
),
};
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()
@ -130,5 +106,10 @@ namespace ActiveProtect.SimulationEnvironment
}
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");
}
}
}