178 lines
5.6 KiB
Plaintext
178 lines
5.6 KiB
Plaintext
|
|
# ****************************************************************************
|
||
|
|
# CUI
|
||
|
|
#
|
||
|
|
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
|
||
|
|
#
|
||
|
|
# The use, dissemination or disclosure of data in this file is subject to
|
||
|
|
# limitation or restriction. See accompanying README and LICENSE for details.
|
||
|
|
# ****************************************************************************
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
behavior disengage
|
||
|
|
|
||
|
|
script_debug_writes off
|
||
|
|
|
||
|
|
script_variables
|
||
|
|
double cDIVE_ALTITUDE = 304.8; # 1000 feet
|
||
|
|
double cDEFAULT_SPEED = 200.0; # m/s
|
||
|
|
double cMAX_SPEED = 9999999999.99; # m/s
|
||
|
|
double cGRAVITY_ACCEL = 9.80665; # 1 G
|
||
|
|
double cDEFAULT_ACCEL = (cGRAVITY_ACCEL * 7.5); # m/s^2 ~7.5 Gs
|
||
|
|
double cANGLE_TOLERANCE = 45.0; # degrees
|
||
|
|
bool drawEscape = false;
|
||
|
|
WsfDraw draw = WsfDraw();
|
||
|
|
end_script_variables
|
||
|
|
|
||
|
|
|
||
|
|
on_init
|
||
|
|
draw.SetLineSize(2);
|
||
|
|
draw.SetColor(1.0, 0.0, 1.0); //purple
|
||
|
|
end_on_init
|
||
|
|
|
||
|
|
|
||
|
|
script bool IsFlightAsset(WsfPlatform aPlat)
|
||
|
|
if (aPlat.Mover().IsA_TypeOf("WSF_AIR_MOVER" ) ||
|
||
|
|
aPlat.Mover().IsA_TypeOf("WSF_6DOF_MOVER") )
|
||
|
|
{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
else if (aPlat.MakeTrack().AirDomain())
|
||
|
|
{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
else if((aPlat.Altitude() > 152.4) && (aPlat.Speed() > 51.44) ) // ~500 feet alt, ~100 knots speed
|
||
|
|
{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
end_script
|
||
|
|
|
||
|
|
|
||
|
|
script bool IsWeapon(WsfTrack aTrack)
|
||
|
|
if (aTrack.Target().IsValid() && aTrack.Target().WeaponEngagement().IsValid())
|
||
|
|
{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
end_script
|
||
|
|
|
||
|
|
|
||
|
|
precondition
|
||
|
|
writeln("precondition disengage");
|
||
|
|
|
||
|
|
//check track list or threat processor for any threats
|
||
|
|
extern double mVisualRange;
|
||
|
|
double totalThreatsWVR = 0.0;
|
||
|
|
foreach (WsfLocalTrack t in PLATFORM.MasterTrackList())
|
||
|
|
{
|
||
|
|
if (!t.SideValid() || t.Side() != PLATFORM.Side())
|
||
|
|
{
|
||
|
|
if ((!IsWeapon(t)) && (PLATFORM.SlantRangeTo(t) < mVisualRange))
|
||
|
|
{
|
||
|
|
writeln_d(" is threat: ", t.TargetName());
|
||
|
|
totalThreatsWVR = totalThreatsWVR + 1.0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
double assetCount = 0.0;
|
||
|
|
WsfRIPRProcessor cmdr = PROCESSOR.GetRIPRCommanderProcessor(); # get the flight lead
|
||
|
|
if (cmdr.IsValid())
|
||
|
|
{
|
||
|
|
WsfRIPRProcessor cmdr2 = cmdr.GetRIPRCommanderProcessor(); # check for gci
|
||
|
|
if (cmdr2.IsValid())
|
||
|
|
{
|
||
|
|
foreach (WsfPlatform aifl in cmdr2.Platform().Subordinates())
|
||
|
|
{
|
||
|
|
foreach (WsfPlatform aiai in aifl.Subordinates())
|
||
|
|
{
|
||
|
|
if (IsFlightAsset(aiai) && PLATFORM.SlantRangeTo(aiai) < mVisualRange)
|
||
|
|
{
|
||
|
|
writeln_d(" is asset: ", aiai.Name());
|
||
|
|
assetCount = assetCount + 1.0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
foreach (WsfPlatform aiai in cmdr.Platform().Subordinates())
|
||
|
|
{
|
||
|
|
if (IsFlightAsset(aiai) && PLATFORM.SlantRangeTo(aiai) < mVisualRange)
|
||
|
|
{
|
||
|
|
writeln_d(" is asset: ", aiai.Name());
|
||
|
|
assetCount = assetCount + 1.0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
extern double mEngagementAggressiveness;
|
||
|
|
double requiredAggressiveness = totalThreatsWVR / (totalThreatsWVR + assetCount);
|
||
|
|
|
||
|
|
writeln_d(" required aggress for disengage: ", requiredAggressiveness, " mine: ", mEngagementAggressiveness);
|
||
|
|
|
||
|
|
if (mEngagementAggressiveness < requiredAggressiveness)
|
||
|
|
{
|
||
|
|
draw.SetDuration(PROCESSOR.UpdateInterval());
|
||
|
|
return true; //disengage
|
||
|
|
}
|
||
|
|
|
||
|
|
//check if there are any threats that I need to evade
|
||
|
|
//if there are & I have an energy advantage (altitude &/or speed), then extend the escape & unload
|
||
|
|
|
||
|
|
//???
|
||
|
|
//???
|
||
|
|
//???
|
||
|
|
|
||
|
|
return false;
|
||
|
|
end_precondition
|
||
|
|
|
||
|
|
|
||
|
|
execute
|
||
|
|
writeln("executing disengage.");
|
||
|
|
PLATFORM.Comment("disengage");
|
||
|
|
|
||
|
|
#double bestheading = 0.0; //compute this as away from all threats
|
||
|
|
#PLATFORM.TurnToHeading(bestheading);
|
||
|
|
|
||
|
|
//calculate an average heading to incoming platforms weighted by distance
|
||
|
|
double y = 0;
|
||
|
|
double x = 0;
|
||
|
|
foreach (WsfLocalTrack t in PLATFORM.MasterTrackList())
|
||
|
|
{
|
||
|
|
if (t.IsValid() && (!t.SideValid() || t.Side() != PLATFORM.Side()))
|
||
|
|
{
|
||
|
|
double distMod = 1 / PLATFORM.SlantRangeTo(t);
|
||
|
|
double bearingMod = MATH.NormalizeAngle0_360(PLATFORM.TrueBearingTo(t));
|
||
|
|
x = x + MATH.Sin(bearingMod) * distMod;
|
||
|
|
y = y + MATH.Cos(bearingMod) * distMod;
|
||
|
|
writeln_d(" Incoming ", t.TargetName(), " at distance: ", 1 / distMod, ", bearing: ", bearingMod);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (x!=0 || y!=0) //if there is something to run from
|
||
|
|
{
|
||
|
|
double evadeHeading = MATH.NormalizeAngle0_360(MATH.ATan2(x, y) - 180);
|
||
|
|
writeln_d(" x: ", x, ", y: ", y, ", evade at: ", evadeHeading);
|
||
|
|
|
||
|
|
extern bool FlyHold (WsfPlatform, double, double, double);
|
||
|
|
FlyHold( PLATFORM, evadeHeading, cDIVE_ALTITUDE, cMAX_SPEED);
|
||
|
|
|
||
|
|
if (drawEscape == true)
|
||
|
|
{
|
||
|
|
WsfGeoPoint pt = PLATFORM.Location();
|
||
|
|
pt.Extrapolate(evadeHeading, 1852 * 10); //draw line in direction of egress, for 10 nautical miles
|
||
|
|
draw.BeginLines();
|
||
|
|
draw.Vertex(PLATFORM.Location());
|
||
|
|
draw.Vertex(pt);
|
||
|
|
draw.End();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
end_execute
|
||
|
|
|
||
|
|
end_behavior
|
||
|
|
|