# **************************************************************************** # 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. # **************************************************************************** // converted BRAWLER v7.5 alt35.f // Replicates the 1v1 Defensive Maneuver 3,5,3,1 alternative behavior // Defensive left break turn // Operates on nearest perceived threat to generate maneuver alternative include_once BrawlerScriptUtil.txt behavior alt3531_break_left script_debug_writes off script_variables WsfQuantumTaskerProcessor processor; WsfBrawlerPlatform brawlerPlatform; //**********************************************************************// //** debugging parameters **// //**********************************************************************// bool mDrawSteering = false; //**********************************************************************// //** alternative parameters **// //**********************************************************************// // Flag used to enable/disable this alternative bool mAlternative3531Enabled = true; bool mCheckRange = true; bool mCheckBoresight = true; bool mCheckClosingSpeed = true; // Alternative ID int ilevel = 3; int kalt = 5; int icall = 3; int lcall = 1; // Maneuver Alternative flight values Vec3 mDir0; double mGMX = 1.0; double mSpd0 = 3.0; // ALSO NEED: // randomization to simulate imperfect desision making, valsig, read from MIND file, typically ~0.01 // Production rule bias, used in socring of alternative //**********************************************************************// //********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********// //**********************************************************************// WsfDraw mDraw = WsfDraw(); double mLastTime = 0.0; end_script_variables on_init if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR")) { processor = (WsfQuantumTaskerProcessor)PROCESSOR; } brawlerPlatform = (WsfBrawlerPlatform)PLATFORM; end_on_init precondition #writeln_d(PLATFORM.Name(), " precondition behavior_alt3531_break_left, T=", TIME_NOW); ### Evaluate conditions that would prevent behavior alternative from running if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR")) { return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR"); } if (!mAlternative3531Enabled) { return Failure("behavior alternative not enabled"); } WsfTaskList tasks = processor.TasksReceivedOfType("WEAPON"); if(tasks.Count() <= 0) { return Failure("no weapon (hostile) tasks!"); } WsfTask targetTask = tasks.Entry(0); WsfLocalTrack hostile = PLATFORM.MasterTrackList().Find(targetTask.LocalTrackId()); if (!hostile.IsValid()) { return Failure("no hostile track!"); } //TODO - change this script so it doesn't use a truth method? if (hostile.TargetKilled()) { return Failure("hostile was destroyed!"); } // alt35.f line 184 - 188 # if(rngun(iac)*ftnmi .gt. 2.) go to 205 # if(obang(iac,me) .gt. hafpi) go to 205 # if(obang(me,iac).gt.hafpi) go to 232 # if(rngrun(iac) .gt. 0.) go to 205 # if(rngun(iac)-rngrun(iac)*2. .gt. 3000.) go to 205 //if the predicted range (rngun) between me and threat greater then 2 nautical miles, skip double projectionTime = TIME_NOW + brawlerPlatform.ProjectedTimeDelta(); WsfGeoPoint projectedHostileLocation = hostile.LocationAtTime(projectionTime); double rangeToHostile = PLATFORM.SlantRangeTo(projectedHostileLocation); if (mCheckRange == true && rangeToHostile > 2.0 * Math.M_PER_NM()) { string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " nearest hostile further than 2 nautical miles"); writeln_d(msg); return Failure(msg); } //if the off-bore angle between threat and me is greater than pi/2, skip if (mCheckBoresight == true && brawlerPlatform.OffBoresightAngle(hostile.Target(), PLATFORM) > Math.PI_OVER_2()) { string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " Boresight angle between hostile and me greater than Pi/2"); writeln_d(msg); return Failure(msg); } //if the off-bore angle between me and the threat is less than pi/2 check more conditions if (mCheckBoresight == true && brawlerPlatform.OffBoresightAngle(PLATFORM, hostile.Target()) < Math.PI_OVER_2()) { //if the predicted range rate (rngrun) of the threat is greater then zero, skip if (mCheckClosingSpeed == true && PLATFORM.ClosingSpeedOf(hostile) > 0) { string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " Hostile is not closing"); writeln_d(msg); return Failure(msg); } //if the predicted range minus the range rate * 2 is greater than 3000, skip if (mCheckRange == true && rangeToHostile * Math.FT_PER_M() - (PLATFORM.ClosingSpeedOf(hostile) * 3.28084 * 2.0) > 3000.0) { string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " Hostile further than 3000 ft within 2 seconds"); writeln_d(msg); return Failure(msg); } } // ALL CONDITIONS PASS ### Generate Maneuver Alternative // alt35.f line 189 - 201 #232 continue # call xmit(3,dxp(1,me,iac),dir0) # call vxfrmc(rwep,dir0,dir0,1) # dir0(1) = 0. # call vxfrmc(rwep,dir0,dir0,2) # if(-xp(3,me).lt.5000.) dir0(3) = amin1(0.,dir0(3)) # call vnorm(dir0,dir0) # gmx = gmxin+(2.-gmxin)*ramp(1.,rngun(iac)*ftnmi,2.) # iactn = 4 # lenalt = lactn(iactn) # altdsc = altpk(3,5,icall,1,iacidt(iac),0) # spd0 = 3. # spdmod = thrttl mDir0 = RelativePositionNED(PLATFORM.Location(), projectedHostileLocation); mDir0 = brawlerPlatform.ConvertNEDtoWind(mDir0); mDir0.SetX(0.0); mDir0 = brawlerPlatform.ConvertWindtoNED(mDir0); if (PLATFORM.Altitude() < 5000.0 * Math.M_PER_FT()) { mDir0.SetZ( Math.Min(0.0, mDir0.Z()) ); } mDir0.Normalize(); mGMX = brawlerPlatform.MaxAvailableGs() + (2.0 - brawlerPlatform.MaxAvailableGs()) * ramp(1.0, rangeToHostile * Math.M_PER_NM(), 2.0); mSpd0 = 3.0; ### Evaluate (Score) Maneuver Alternative double alternativeScore = brawlerPlatform.EvaluateVectorWithThrottle(mDir0, mGMX, mSpd0, ilevel, kalt, icall, lcall); ### Return Maneuver Alternative Score return alternativeScore; end_precondition execute writeln_d(PLATFORM.Name(), " executing behavior_alt3531_break_left, T=", TIME_NOW); // Fly this alternative brawlerPlatform.FlyVectorWithThrottle(mDir0, mGMX, mSpd0); # if (mDrawSteering == true) # { # mDraw.SetLayer("behavior_pursue_target"); # mDraw.SetDuration(processor.UpdateInterval()); # mDraw.SetColor(1.0, 0.5, 0.0); # mDraw.SetLineSize(1); # mDraw.BeginLines(); # mDraw.Vertex(PLATFORM.Location()); # mDraw.Vertex(mTargetPoint); # mDraw.End(); # } # # string msg = write_str("pursue-target: ", targetTrack.TargetName(), " at speed ", (string)mTargetSpeed); # writeln_d(" T=", TIME_NOW, " ", PLATFORM.Name(), " ", msg); # FlyTarget( PLATFORM, mTargetPoint, mTargetSpeed); end_execute end_behavior