# **************************************************************************** # 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. # **************************************************************************** include_once weapon_defs.txt behavior engage_on_timeline script_debug_writes off script_variables //**********************************************************************// //** platform / agent specific shooting parameters **// //**********************************************************************// #bool mCoopEngageOne = false; #bool mCoopEngageOneFlightOnly = false; # double mDegradedFiringAngle = 55.0; //negative if not valid # double mDegradedPercentRange = 0.50; //range constraint if past degraded firing angle # //specify orientation limits for shooting # double mMaxFiringRollAngle = 10.0; //dont shoot if rolled more/less than this # double mMaxFiringPitchAngle = 15.0; //dont shoot if pitched more than this # double mMinFiringPitchAngle = -10.0; //dont shoot if pitched less than this //**********************************************************************// //** threat specific shooting parameters **// //**********************************************************************// //require different track qualities to fire on different kinds of threats # double DefaultRequiredTrackQuality = 0.49; # Map ThreatTypeRequiredTrackQuality = Map(); # ThreatTypeRequiredTrackQuality["bomber"] = 0.49; # ThreatTypeRequiredTrackQuality["fighter"] = 0.49; //fire off different salvos at different types of threats # int DefaultAirSalvo = 1; # int DefaultGndSalvo = 1; # Map ThreatTypeSalvo = Map(); # ThreatTypeSalvo["sam"] = 2; # ThreatTypeSalvo["ship"] = 2; # ThreatTypeSalvo["bomber"] = 2; # ThreatTypeSalvo["fighter"] = 1; # ThreatTypeSalvo["FIRE_CONTROL"] = 1; # ThreatTypeSalvo["primary_target"] = 2; # ThreatTypeSalvo["secondary_target"] = 2; //**********************************************************************// //** weapon + threat specific shooting parameters **// //**********************************************************************// //specify an Rmax based on which weapon used and which threat engaged double DefaultPercentRangeMax = 0.80; // don't launch unless within this percent of Rmax double DefaultPercentRangeMin = 1.20; // don't launch unless beyond this percent of Rmin Map> WeaponThreatRmaxMap = Map>(); WeaponThreatRmaxMap["base_weapon"] = Map(); WeaponThreatRmaxMap["base_weapon"].Set("fighter", 0.80); end_script_variables # script int GetSalvoForThreat(WsfTrack track) # #writeln_d("checking salvo size for category: ", category); # #WsfPlatform plat = WsfSimulation.FindPlatform( track.TargetIndex() ); # WsfPlatform plat = WsfSimulation.FindPlatform( track.TargetName() ); # if (plat.IsValid()) # { # foreach( string aCategory : int salvo in ThreatTypeSalvo ) # { # if( plat.CategoryMemberOf( aCategory ) ) # { # writeln_d("salvo for type ", aCategory, " = ", salvo); # return salvo; # } # } # } # #extern string GetTargetDomain(WsfTrack); # string sTargetDomain = GetTargetDomain(track); # if ( (sTargetDomain == "LAND") || (sTargetDomain == "SURFACE") ) # { # return DefaultGndSalvo; # } # return DefaultAirSalvo; # end_script # script double GetRequiredTrackQualityForThreat(WsfTrack threat) # writeln_d("checking required TQ for track: ", threat.TargetName()); # WsfPlatform plat = WsfSimulation.FindPlatform( threat.TargetName() ); # if (plat.IsValid()) # { # foreach( string aCategory : double quality in ThreatTypeRequiredTrackQuality ) # { # if( plat.CategoryMemberOf( aCategory ) ) # { # writeln_d("TQ for type ", aCategory, " = ", quality); # return quality; # } # } # } # return DefaultRequiredTrackQuality; # end_script script double GetLaunchPercentRangeMaxOnThreat(string weaponName, WsfTrack threat) WsfPlatform plat = WsfSimulation.FindPlatform( threat.TargetName() ); if (plat.IsValid()) { if (WeaponThreatRmaxMap.Exists(weaponName)) { Map categoryRangeMap = WeaponThreatRmaxMap.Get(weaponName); foreach (string aCategory : double percent in categoryRangeMap) { if( plat.CategoryMemberOf( aCategory ) ) { return percent; } } } } return DefaultPercentRangeMax; end_script #on_init #end_on_init precondition #writeln_d("precondition engage-target"); if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR")) { writeln_d("behavior engage... not on quantum tasker processor"); return Failure("behavior not attached to a quantum tasker processor!"); } # todo - try using a state machine to setup the shot ?? # double pitch = PLATFORM.Pitch(); # if (MATH.Fabs(PLATFORM.Roll()) > mMaxFiringRollAngle || # pitch > mMaxFiringPitchAngle || # pitch < mMinFiringPitchAngle) # { # string msgStr = write_str(" ", PLATFORM.Name(), " orientation too far off to fire! (roll or pitch)"); # writeln_d(msgStr); # //PLATFORM.Comment(msgStr); # return Failure(msgStr); # } WsfQuantumTaskerProcessor proc = (WsfQuantumTaskerProcessor)PROCESSOR; # WsfTaskList tasks = proc.TasksReceivedOfType("WEAPON"); # if (tasks.Count() > 0) # { # writeln_d("behavior engage precondition passes!"); # return true; # } # writeln_d("no weapon task target to shoot at!"); if (GetTimelineTask(proc).IsValid()) { writeln_d("behavior engage precondition passes!"); return true; } writeln_d("no timeline task to engage!"); return Failure("no timeline task to engage!"); end_precondition execute writeln_d(PLATFORM.Name(), " executing engage-target, T=", TIME_NOW); #extern WsfTrack GetTrackByName(WsfPlatform, string); #check all possible targets on all channels ######################################################################## ### fire on any pursue-target jobs we are assigned to ######################################################################## WsfQuantumTaskerProcessor proc = (WsfQuantumTaskerProcessor)PROCESSOR; WsfTask timeline = GetTimelineTask(proc); if (timeline.IsValid() && timeline.AuxDataExists("targets")) { Array targets = (Array)timeline.AuxDataObject("targets"); foreach (WsfTrack target in targets) { if (!target.IsValid()) { continue; } #do we need master track? WsfLocalTrack masterTarget = GetMasterTrackByName(PLATFORM, target.TargetName()); if (!masterTarget.IsValid()) { continue; } # if (mCoopEngageOne == false) # { # WsfLocalTrack targetLocalTrack = (WsfLocalTrack)targetTrack; # if (targetLocalTrack.IsValid()) # { # if(!targetLocalTrack.ContributorOf(PLATFORM) && # !targetLocalTrack.IsPredefined()) # { # writeln_d(" FAIL: Not able to coop engage! ", PLATFORM.Name(), " targeting ",targetTrack.TargetName(), ". NumContributors: ", targetLocalTrack.NumContributors() ); # return; # } # } # } # # writeln_d (" targetTrack.TrackQuality == ", targetTrack.TrackQuality()); # if (targetTrack.TrackQuality() < GetRequiredTrackQualityForThreat(targetTrack)) # { # writeln_d(" FAIL: track quality not good enough to fire on target"); # return; # } if ((PLATFORM.WeaponsPendingFor(masterTarget.TrackId()) + PLATFORM.WeaponsActiveFor(masterTarget.TrackId())) > 0) { writeln_d("already have weapons assigned for target: ", masterTarget.TargetName()); continue; } WsfWeapon weapon; bool weaponUsable = false; #first weapon found will be used for (int i=0; i < PLATFORM.WeaponCount(); i+=1) { weapon = PLATFORM.WeaponEntry(i); writeln_d("checking if weapon ", weapon.Name(), " is usable."); if (WeaponCapableAvailableAgainstThreat(weapon, masterTarget) && InRangeToFire(PLATFORM, weapon, masterTarget, GetLaunchPercentRangeMaxOnThreat(weapon.Name(), masterTarget), DefaultPercentRangeMin)) { weaponUsable = true; break; } } if (weaponUsable == false) { writeln_d("no usable weapon found!"); continue; } #int salvoCount = GetSalvoForThreat(targetTrack); #writeln_d(" salvo count for ", targetTrack, " is: ", salvoCount); int salvoCount = 1; bool launched = false; if (weapon.IsTurnedOn()) { writeln_d(" Attempting launch at ", masterTarget.TargetName()); # if (salvoCount > 1) # { # writeln_d("FIRING SALVO AT ", masterTarget.TargetName()); # launched = weapon.FireSalvo(masterTarget, salvoCount); # } # else # { # writeln_d("FIRING AT ", masterTarget.TargetName()); # launched = weapon.Fire(masterTarget); # } launched = weapon.FireSalvo(masterTarget, salvoCount); } writeln_d(" launched == ", launched, ", weapon: ", weapon.Name()); if(launched == false) { writeln_d(" ", PLATFORM.Name(), " could NOT fire at track: ", masterTarget.TargetName(), " at time: ", TIME_NOW); } } } end_execute end_behavior