# **************************************************************************** # 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