# **************************************************************************** # 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. # **************************************************************************** #this should be used to evade a threatening enemy when you have an energy advantage behavior unload 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 double mLastProcTime = -1.0; double mLastClimbRate = 0.0; end_script_variables script bool RanLastTick() if ((TIME_NOW-mLastProcTime) < 1.5*PROCESSOR.UpdateInterval()) { return true; } else return false; end_script precondition writeln("precondition unload"); //see if I have the energy advantage against my threat #extern WsfTrack mBiggestThreat; if (mBiggestThreat.IsValid()) { double modifier = 1.0; if (RanLastTick()) { modifier = 1.10; } //otherwise, IF we have an energy advantage, get out -> unload ###double altDiff = PLATFORM.RelativeAltitudeOf(mBiggestThreat); #positive value means track is higher than you double altDiff = mBiggestThreat.Altitude() - PLATFORM.Altitude()*modifier; #positive value means track is higher than you double velDiff = mBiggestThreat.Speed() - PLATFORM.Speed()*modifier; #positive value means track is faster than you double altEnergy = MATH.Sqrt(2*MATH.Fabs(altDiff)*cGRAVITY_ACCEL); #convert potential energy into kinetic energy (mass excluded -> just convert to velocity) if (altDiff<0) { altEnergy = -altEnergy; } if ((velDiff + altEnergy) < 0) # if I have an energy advantage, unload { mLastProcTime = TIME_NOW; return true; } else { writeln(" do not unload, no energy advantage!"); } } mLastProcTime = -1.0; return false; end_precondition execute writeln("executing unload"); //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 (!RanLastTick()) { mLastClimbRate = 0.0; } double climbRate = mLastClimbRate - (cGRAVITY_ACCEL * PROCESSOR.UpdateInterval()); mLastClimbRate = climbRate; PLATFORM.GoToSpeed(cMAX_SPEED); PLATFORM.TurnToHeading(evadeHeading); PLATFORM.GoToAltitude(cDIVE_ALTITUDE, climbRate); #PLATFORM.Comment("unload"); PLATFORM.Comment(write_str("unload to heading: ", evadeHeading)); } end_execute end_behavior