859 lines
27 KiB
Plaintext
859 lines
27 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.
|
||
|
|
# ****************************************************************************
|
||
|
|
|
||
|
|
|
||
|
|
#always requires a commander
|
||
|
|
#bids on & performs "jam-target" jobs
|
||
|
|
#does not create any jobs
|
||
|
|
#attempts to jam the target
|
||
|
|
#assumes jammers aren't destroyed
|
||
|
|
|
||
|
|
|
||
|
|
include_once ../common/common_platform_script.txt
|
||
|
|
|
||
|
|
processor AIJAM-thinker WSF_RIPR_PROCESSOR
|
||
|
|
|
||
|
|
#debug
|
||
|
|
#script_debug_writes on
|
||
|
|
|
||
|
|
//1 Hz update
|
||
|
|
//update_interval 0.5 sec
|
||
|
|
update_interval 1.0 sec
|
||
|
|
|
||
|
|
//num_job_channels 3 // very important for bidding on and receiving multiple jobs, this is the
|
||
|
|
// // number of targets the jammer can engage (jam) simultaneously
|
||
|
|
// // depends on number of jamming arrays, will be updated on_initialize
|
||
|
|
|
||
|
|
script_variables
|
||
|
|
|
||
|
|
string mTaskManagerName = "task_mgr";
|
||
|
|
WsfTaskManager mTaskMgr;
|
||
|
|
|
||
|
|
int CHANNEL = 0;
|
||
|
|
|
||
|
|
double rangeBiddingScale = 2.0;
|
||
|
|
double targetPriorityBidScale = 4.1;
|
||
|
|
double bandPriorityBidScale = 1.0;
|
||
|
|
double powerBidScale = 5.3;
|
||
|
|
|
||
|
|
//Map<int, string> mJobCurrentState = Map<int, string>(); //keeps each jobs current engagement state
|
||
|
|
//Map<int, double> mJobStateTimes = Map<int, double>(); //records when each job entered its current state
|
||
|
|
|
||
|
|
WsfTrackId emptyTrackId = WsfTrackId();
|
||
|
|
Array<WsfTrackId> mChannelTargets = Array<WsfTrackId>(); //array index is job channel, array value is target track id (from job that channel is performing)
|
||
|
|
|
||
|
|
///////////////////////////////////////////////////////////////////////////
|
||
|
|
// mChannelJammers and mChannelBeams are to be used in conjunction with one another
|
||
|
|
// mChannelJammers stores that channel's jammer weapon
|
||
|
|
// mChannelBeams stores that channel's jammer's beam to be used
|
||
|
|
//
|
||
|
|
//array index is channel, value is jamming weapons name
|
||
|
|
Array<string> mChannelJammers = Array<string>();
|
||
|
|
//array index is channel, value is jamming weapons beam
|
||
|
|
Array<int> mChannelBeams = Array<int>();
|
||
|
|
//array index is channel, value is jamming weapons pod (category)
|
||
|
|
Array<string> mChannelPods = Array<string>();
|
||
|
|
//map key is jammer weapons pod (category), value is array of channels that use the pod
|
||
|
|
Map< string, Array<int> > mPodToChannels = Map< string, Array<int> >();
|
||
|
|
|
||
|
|
//map key is pod of interest, value is related pod
|
||
|
|
Map< string, string> mPodToPod = Map< string, string>();
|
||
|
|
///////////////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
double RESOURCE_ROLL_ANGLE = 75.0; // degrees
|
||
|
|
double DISTANCE_3D = 500000.0; // meters
|
||
|
|
|
||
|
|
double SPOT_SIZE_DEFAULT = 5000000.0; // hz
|
||
|
|
|
||
|
|
//double TRACK_PURGE_INTERVAL = 10.0; //seconds
|
||
|
|
|
||
|
|
string JAM_TASK_STR = "Jam";
|
||
|
|
|
||
|
|
//string techniqueCountFile = "DRFM_Technique_Count.txt";
|
||
|
|
//FileIO techFile = FileIO();
|
||
|
|
|
||
|
|
// If USE_PRIORITY_LIST is 'true' then the priority lists is used to get the specified
|
||
|
|
// jammer types to be used for the given target type/name of interest. If one is not found
|
||
|
|
// and USE_BAND_BREAKS is also 'true' then the band breaks will be searched and used also.
|
||
|
|
|
||
|
|
//bool USE_PRIORITY_LIST = true;
|
||
|
|
//bool USE_BAND_BREAKS = false;
|
||
|
|
|
||
|
|
bool USE_PRIORITY_LIST = false;
|
||
|
|
bool USE_BAND_BREAKS = true;
|
||
|
|
|
||
|
|
// used when time modulation is done with a beam and more than one target is given to that beam
|
||
|
|
//each beam can have a few spots (or time slots)
|
||
|
|
//bool ADD_SPOTS_FIRST = true; # "true" does time commutation before splitting the arrays.
|
||
|
|
|
||
|
|
// If set to true when a new assignment comes in and cannot be allocated to a jammer in the
|
||
|
|
// priority list, the dropping of lower priority tracks for the given jammer group (category)
|
||
|
|
// will begin and with each cancellation of the assignmnet will be tried again until it can be
|
||
|
|
// assigned or all assignments with a lower priority are cancelled.
|
||
|
|
// WARNING: this may cause some weird effects as assignments can be dropped and other
|
||
|
|
// ones re-assigned in their place later, plus some other strange things.
|
||
|
|
//bool ALLOW_RE_QUEUEING = true;
|
||
|
|
|
||
|
|
//Map< string, Array< double > > BANDLIST = Map< string, Array< double > >();
|
||
|
|
|
||
|
|
// Radar Sensor type to jammer spot size mapping
|
||
|
|
Map< string, double > mSpotSize = Map< string, double >();
|
||
|
|
|
||
|
|
// Map of the target type/name to the preferred band(s)
|
||
|
|
Map< string, Array< string > > mTargetBandList = Map< string, Array< string > >();
|
||
|
|
|
||
|
|
Map< string, int > mPriorityList = Map< string, int >();
|
||
|
|
|
||
|
|
// Radar Sensor Type to jammer technique mapping (note mapping integer based for now).
|
||
|
|
Map< string, int > mTechniqueId = Map< string, int >();
|
||
|
|
|
||
|
|
double time1 = 0.0;
|
||
|
|
double time2 = 0.0;
|
||
|
|
double time3 = 0.0;
|
||
|
|
double time4 = 0.0;
|
||
|
|
|
||
|
|
end_script_variables
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
// ----------------------------------------
|
||
|
|
// return the task manager object
|
||
|
|
script WsfTaskManager GetTaskManager()
|
||
|
|
static WsfTaskManager taskMgr;
|
||
|
|
if( !taskMgr.IsValid() )
|
||
|
|
{
|
||
|
|
taskMgr = (WsfTaskManager)PLATFORM.Processor(mTaskManagerName);
|
||
|
|
}
|
||
|
|
return taskMgr;
|
||
|
|
end_script
|
||
|
|
|
||
|
|
// -------------------------------------------------------------------------
|
||
|
|
script void SetThreatDataItem(string aThreatString, Array< string > aBands, double aSpotSize, int aTechniqueId, int aPriority)
|
||
|
|
mTargetBandList[aThreatString] = aBands;
|
||
|
|
mSpotSize[aThreatString] = aSpotSize;
|
||
|
|
mTechniqueId[aThreatString] = aTechniqueId;
|
||
|
|
mPriorityList[aThreatString] = aPriority;
|
||
|
|
end_script
|
||
|
|
|
||
|
|
|
||
|
|
include platforms/soj_threat_data.txt
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
// -------------------------------------------------------------------------
|
||
|
|
script void SetBandList(string aBandTypeName, double aLowFreq, double aUpperFreq)
|
||
|
|
Array< double > Bands = Array< double >();
|
||
|
|
Bands.PushBack(aLowFreq);
|
||
|
|
Bands.PushBack(aUpperFreq);
|
||
|
|
BANDLIST[aBandTypeName] = Bands;
|
||
|
|
end_script
|
||
|
|
*/
|
||
|
|
|
||
|
|
|
||
|
|
// -------------------------------------------------------------------------
|
||
|
|
// A sensor detected a threat so determine the spot size to use to jam the threat.
|
||
|
|
script double SpotSize(WsfTrack aTrack)
|
||
|
|
double spotSize = SPOT_SIZE_DEFAULT;
|
||
|
|
|
||
|
|
if (mSpotSize.Exists(aTrack.TargetName()))
|
||
|
|
{
|
||
|
|
spotSize = mSpotSize[aTrack.TargetName()];
|
||
|
|
}
|
||
|
|
else if (mSpotSize.Exists(aTrack.TargetType()))
|
||
|
|
{
|
||
|
|
spotSize = mSpotSize[aTrack.TargetType()];
|
||
|
|
}
|
||
|
|
return spotSize;
|
||
|
|
end_script
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
script int TargetPriority(WsfTrack aTrack)
|
||
|
|
int priority = 0;
|
||
|
|
if (mPriorityList.Exists(aTrack.TargetName()))
|
||
|
|
{
|
||
|
|
priority = mPriorityList[aTrack.TargetName()];
|
||
|
|
}
|
||
|
|
else if (mPriorityList.Exists(aTrack.TargetType()))
|
||
|
|
{
|
||
|
|
priority = mPriorityList[aTrack.TargetType()];
|
||
|
|
}
|
||
|
|
return priority;
|
||
|
|
end_script
|
||
|
|
|
||
|
|
|
||
|
|
script int BandPriority(string aJammerType, WsfTrack aTrack)
|
||
|
|
int priority = 0;
|
||
|
|
Array<string> jammerTypes = Array<string>();
|
||
|
|
|
||
|
|
if (mTargetBandList.Exists(aTrack.TargetName()))
|
||
|
|
{
|
||
|
|
jammerTypes = mTargetBandList[aTrack.TargetName()];
|
||
|
|
}
|
||
|
|
else if (mTargetBandList.Exists(aTrack.TargetType()))
|
||
|
|
{
|
||
|
|
jammerTypes = mTargetBandList[aTrack.TargetType()];
|
||
|
|
}
|
||
|
|
|
||
|
|
int N = jammerTypes.Size();
|
||
|
|
int i = 0;
|
||
|
|
for (i=0; i<N; i = i + 1)
|
||
|
|
{
|
||
|
|
if (jammerTypes[i] == aJammerType)
|
||
|
|
{
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return (N-i);
|
||
|
|
end_script
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
// -------------------------------------------------------------------------
|
||
|
|
// Script to determine the appropriate technique to use based on target type
|
||
|
|
script string TechniqueType(WsfTrack aTrack)
|
||
|
|
string techniqueType = "noise_jamming"; // default technique
|
||
|
|
if (aTrack.IsValid())
|
||
|
|
{
|
||
|
|
if (aTrack.TargetType() == "EW_RADAR")
|
||
|
|
{
|
||
|
|
techniqueType = "false_targets";
|
||
|
|
}
|
||
|
|
else if (aTrack.TargetType() == "ACQ_RADAR")
|
||
|
|
{
|
||
|
|
techniqueType = "random_pulse_jamming";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return techniqueType ;
|
||
|
|
end_script
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
// -------------------------------------------------------------------------
|
||
|
|
// Script to determine the appropriate jammer type(s)
|
||
|
|
|
||
|
|
script bool IsJammerBandCapable(WsfWeapon aJammer, WsfTrack aTrack)
|
||
|
|
string aJammerType = aJammer.Type();
|
||
|
|
if (USE_PRIORITY_LIST)
|
||
|
|
{
|
||
|
|
string lookup = "nothing nada nein";
|
||
|
|
if (mTargetBandList.Exists(aTrack.TargetName()))
|
||
|
|
{
|
||
|
|
lookup = aTrack.TargetName();
|
||
|
|
}
|
||
|
|
else if (mTargetBandList.Exists(aTrack.TargetType()))
|
||
|
|
{
|
||
|
|
lookup = aTrack.TargetType();
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
writeln_d("target ", aTrack.TargetName(), " ", aTrack.TargetType(), " has no matches with ", aJammerType);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
foreach(string jType in mTargetBandList[lookup])
|
||
|
|
{
|
||
|
|
if (aJammerType == jType)
|
||
|
|
{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (aTrack.FrequencyValid() && USE_BAND_BREAKS)
|
||
|
|
{
|
||
|
|
writeln_d("track for ", aTrack.TargetName(), " has frequency ", aTrack.Frequency());
|
||
|
|
if (aJammer.WithinFrequencyBand(aTrack.Frequency()))
|
||
|
|
{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
// if (BANDLIST.Exists(aJammerType))
|
||
|
|
// {
|
||
|
|
// Array< double > Freq = BANDLIST.Get(aJammerType);
|
||
|
|
// if ((aTrack.Frequency() > Freq[0]) &&
|
||
|
|
// (aTrack.Frequency() < Freq[1]))
|
||
|
|
// {
|
||
|
|
// return true;
|
||
|
|
// }
|
||
|
|
// }
|
||
|
|
|
||
|
|
}
|
||
|
|
writeln_d("target ", aTrack.TargetName(), " ", aTrack.TargetType(), " has no matches with ", aJammerType);
|
||
|
|
return false;
|
||
|
|
end_script
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
script WsfTrack GetJobsTrack(WsfRIPRJob aJob)
|
||
|
|
|
||
|
|
string name = (string)aJob.GetData("targetTrackName");
|
||
|
|
|
||
|
|
//WsfTrack jobsTrack = PLATFORM.MasterTrackList().Find(name);
|
||
|
|
//return jobsTrack;
|
||
|
|
|
||
|
|
#extern WsfTrack GetTrackByName(WsfPlatform, string);
|
||
|
|
WsfTrack track = GetTrackByName(PLATFORM, name);
|
||
|
|
return track;
|
||
|
|
|
||
|
|
end_script
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
script double CalculateJamTargetBidValue( WsfTrack aTrack, string aJammerName)
|
||
|
|
|
||
|
|
WsfWeapon jammer = PLATFORM.Weapon(aJammerName);
|
||
|
|
if (!jammer.IsValid())
|
||
|
|
{
|
||
|
|
writeln_d("no bid, jammer not found: ", aJammerName);
|
||
|
|
return -MATH.DOUBLE_MAX();
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!PLATFORM.WithinFieldOfView(aTrack, aJammerName))
|
||
|
|
{
|
||
|
|
writeln_d("target track outside of jammers field of view, no bid! ", aTrack.TargetName(),
|
||
|
|
" outside FOV of ", aJammerName);
|
||
|
|
return -MATH.DOUBLE_MAX();
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!IsJammerBandCapable(jammer, aTrack))
|
||
|
|
{
|
||
|
|
writeln_d("jammer of this type is not band capable for target, no bid! ", aJammerName,
|
||
|
|
" has no bands for ", aTrack.TargetName());
|
||
|
|
return -MATH.DOUBLE_MAX();
|
||
|
|
}
|
||
|
|
|
||
|
|
############################################################################
|
||
|
|
##should we hold off on this test? we've already checked frequency
|
||
|
|
##so effectively, this just checks if any spots are available
|
||
|
|
#if (!jammer.CanJam(aTrack.Frequency()))
|
||
|
|
#{
|
||
|
|
# writeln_d("jammer already full, no more jamming requests please, no bid!");
|
||
|
|
# return -MATH.DOUBLE_MAX();
|
||
|
|
#}
|
||
|
|
############################################################################
|
||
|
|
|
||
|
|
############################################################################
|
||
|
|
##should we hold off on this test? we might let the job board make assignments
|
||
|
|
##and not worry so much about pods and beam counts
|
||
|
|
##the job board should dynamically reassign jamming targets when necessary or optimal
|
||
|
|
#if (CanAssign(jammer, 1))
|
||
|
|
#{
|
||
|
|
# writeln_d("jammer failed frequency availability check, no bid.");
|
||
|
|
# return -MATH.DOUBLE_MAX();
|
||
|
|
#}
|
||
|
|
############################################################################
|
||
|
|
|
||
|
|
double JobBidValue = 0.0;
|
||
|
|
|
||
|
|
#add value based on range to target
|
||
|
|
JobBidValue = JobBidValue + rangeBiddingScale * 100.0 / MATH.Sqrt(PLATFORM.SlantRangeTo(aTrack));
|
||
|
|
|
||
|
|
#add value based on target priority from mission data load
|
||
|
|
JobBidValue = JobBidValue + targetPriorityBidScale * TargetPriority(aTrack);
|
||
|
|
|
||
|
|
#add value based on band ordering from mission data load
|
||
|
|
JobBidValue = JobBidValue + bandPriorityBidScale * BandPriority(jammer.Type(), aTrack);
|
||
|
|
|
||
|
|
#add value based on power the jammer is able to put on target
|
||
|
|
#JobBidValue = JobBidValue + powerBidScale * JammerPower(jammer,aTrack);
|
||
|
|
|
||
|
|
return JobBidValue;
|
||
|
|
|
||
|
|
end_script
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
query_bid_type jam-target
|
||
|
|
|
||
|
|
if (!JOB.IsValid())
|
||
|
|
{
|
||
|
|
writeln_d("job not valid, can not process, no bid!");
|
||
|
|
return -MATH.DOUBLE_MAX();
|
||
|
|
}
|
||
|
|
|
||
|
|
if (mChannelJammers.Size() <= 0)
|
||
|
|
{
|
||
|
|
writeln_d("no jammer weapons found, impossible, no bid!");
|
||
|
|
return -MATH.DOUBLE_MAX();
|
||
|
|
}
|
||
|
|
|
||
|
|
WsfTrack track = GetJobsTrack(JOB);
|
||
|
|
if (!track.IsValid())
|
||
|
|
{
|
||
|
|
writeln_d("track not valid for job: ", JOB.Name(), " - ", JOB.GetDescription(), ", no bid.");
|
||
|
|
return -MATH.DOUBLE_MAX();
|
||
|
|
}
|
||
|
|
|
||
|
|
string jammerName = mChannelJammers.Get(CHANNEL);
|
||
|
|
if(!jammerName.IsValid())
|
||
|
|
{
|
||
|
|
jammerName = mChannelJammers.Get(0);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (MATH.Fabs(PLATFORM.Roll()) >= RESOURCE_ROLL_ANGLE)
|
||
|
|
{
|
||
|
|
writeln_d("platform is rolled beyond the resource limit!");
|
||
|
|
return -MATH.DOUBLE_MAX();
|
||
|
|
}
|
||
|
|
|
||
|
|
if (PLATFORM.SlantRangeTo(track) >= DISTANCE_3D)
|
||
|
|
{
|
||
|
|
writeln_d("jamming target is too far away!");
|
||
|
|
return -MATH.DOUBLE_MAX();
|
||
|
|
}
|
||
|
|
|
||
|
|
double jobBidValue = CalculateJamTargetBidValue( track, jammerName);
|
||
|
|
return jobBidValue;
|
||
|
|
|
||
|
|
end_query_bid_type
|
||
|
|
|
||
|
|
|
||
|
|
script bool DoStartJamming(int aChannel, WsfTrack aTarget)
|
||
|
|
|
||
|
|
string comment = "start jamming: " + aTarget.TrackId().ToString();
|
||
|
|
PLATFORM.Comment(comment);
|
||
|
|
|
||
|
|
string jammerName = mChannelJammers.Get(aChannel);
|
||
|
|
WsfWeapon jammer = PLATFORM.Weapon(jammerName);
|
||
|
|
int beam = mChannelBeams.Get(aChannel);
|
||
|
|
|
||
|
|
if (jammer.IsValid() && aTarget.FrequencyValid())
|
||
|
|
{
|
||
|
|
#should already have passed these checks, when bidding
|
||
|
|
#if (jammer.CanJam(aTarget.Frequency(), TechniqueType(aTarget)) && (CanAssign(jammer, 1)))
|
||
|
|
#{
|
||
|
|
|
||
|
|
int beamNumber = beam;
|
||
|
|
|
||
|
|
mTaskMgr = GetTaskManager();
|
||
|
|
if (!mTaskMgr.IsValid())
|
||
|
|
{
|
||
|
|
writeln("ERROR: invalid task manager for jamming control!");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
//StartJamming(TRACK, "Jam", jammer, TRACK.Frequency(), 5.e6, TechniqueType());
|
||
|
|
|
||
|
|
if (mTaskMgr.StartJamming(aTarget, JAM_TASK_STR, jammer, aTarget.Frequency(),
|
||
|
|
SpotSize(aTarget), beamNumber, TechniqueType(aTarget)))
|
||
|
|
{
|
||
|
|
writeln("T=", TIME_NOW, " START JAMMING: ", jammer.Name(), " : ",
|
||
|
|
PLATFORM.Name(), " - ", aTarget.TargetName(), " : ", aTarget.TargetType(),
|
||
|
|
" ", aTarget.Frequency(), " : ", SpotSize(aTarget), " : ", TechniqueType(aTarget),
|
||
|
|
" Beam: ", beamNumber, " Assignments: ", jammer.ActiveRequestCount());
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
writeln("CANT START JAMMING: ", jammer.Name(), ":", PLATFORM.Name(), " - ",
|
||
|
|
aTarget.TargetName(), ":", aTarget.TargetType(), " ", aTarget.Frequency(),
|
||
|
|
":", SpotSize(aTarget), ":", TechniqueType(aTarget), " RequestCount=",
|
||
|
|
jammer.ActiveRequestCount(), ":", jammer.MaximumRequestCount());
|
||
|
|
}
|
||
|
|
|
||
|
|
#}
|
||
|
|
#else if (jammer.ActiveRequestCount() < jammer.MaximumRequestCount())
|
||
|
|
|
||
|
|
if (jammer.ActiveRequestCount() < jammer.MaximumRequestCount())
|
||
|
|
{
|
||
|
|
writeln("CANT JAM THE TARGET: ", jammer.Name(), ":", PLATFORM.Name(),
|
||
|
|
" - ", aTarget.TargetName(), ":", aTarget.TargetType(), " ",
|
||
|
|
aTarget.Frequency(), ":", SpotSize(aTarget), ":", TechniqueType(aTarget),
|
||
|
|
" RequestCount=", jammer.ActiveRequestCount(), ":", jammer.MaximumRequestCount());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
end_script
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
script bool DoStopJamming( int aChannel, WsfTrackId aTargetId )
|
||
|
|
|
||
|
|
string comment = "stop jamming: " + aTargetId.ToString();
|
||
|
|
PLATFORM.Comment(comment);
|
||
|
|
|
||
|
|
string jammerName = mChannelJammers.Get(aChannel);
|
||
|
|
int beam = mChannelBeams.Get(aChannel);
|
||
|
|
WsfWeapon jammer = PLATFORM.Weapon(jammerName);
|
||
|
|
|
||
|
|
if (jammer.IsValid())
|
||
|
|
{
|
||
|
|
WsfTrack track = PLATFORM.MasterTrackList().Find(aTargetId);
|
||
|
|
|
||
|
|
mTaskMgr = GetTaskManager();
|
||
|
|
if (!mTaskMgr.IsValid())
|
||
|
|
{
|
||
|
|
writeln("ERROR: invalid task manager for jamming control!");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
//this should return a task list with one or none tasks in it
|
||
|
|
WsfTaskList taskList = mTaskMgr.AssignedTaskList(aTargetId, JAM_TASK_STR);
|
||
|
|
|
||
|
|
foreach (WsfTask task in taskList)
|
||
|
|
{
|
||
|
|
if (!task.IsValid())
|
||
|
|
{
|
||
|
|
writeln("do stop jamming: task invalid!");
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
if (task.ResourceName() == jammerName)
|
||
|
|
{
|
||
|
|
double freq = task.ResourceFrequency();
|
||
|
|
double bw = task.ResourceBandwidth();
|
||
|
|
|
||
|
|
//if (mTaskMgr.StopJamming(aTargetId, JAM_TASK_STR, jammerName, freq, bw))
|
||
|
|
|
||
|
|
if (mTaskMgr.StopJamming(aTargetId, JAM_TASK_STR, jammerName, freq, bw, beam))
|
||
|
|
{
|
||
|
|
//do stuff?
|
||
|
|
writeln("T=", TIME_NOW, " STOP JAMMING: ", jammerName, " : ",PLATFORM.Name(),
|
||
|
|
" - ", track.TargetName(), " : ", track.TargetType(), " ", freq, " Hz, ", bw, " Hz");
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
writeln("T=", TIME_NOW, " CANT STOP JAMMING: ", jammerName, ":", PLATFORM.Name(), " - ",
|
||
|
|
track.TargetName(), ":", track.TargetType(), " ", freq, " Hz, ", bw, " Hz");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return true;
|
||
|
|
end_script
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
script void DoJob(WsfRIPRJob aJob, int aChannel)
|
||
|
|
|
||
|
|
# double timeMark1 = GetWallClockTime();
|
||
|
|
# double timeMark2 = timeMark1;
|
||
|
|
|
||
|
|
|
||
|
|
WsfTrack track;
|
||
|
|
if (aJob.IsValid())
|
||
|
|
{
|
||
|
|
track = GetJobsTrack(aJob);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
//stop performing previous jamming job
|
||
|
|
if (mChannelTargets.Size() > aChannel)
|
||
|
|
{
|
||
|
|
WsfTrackId oldTargetId = mChannelTargets.Get(aChannel);
|
||
|
|
if (oldTargetId != emptyTrackId)
|
||
|
|
{
|
||
|
|
if (DoStopJamming(aChannel, oldTargetId))
|
||
|
|
{
|
||
|
|
mChannelTargets.Set(aChannel, emptyTrackId);
|
||
|
|
writeln("successfully stopped jamming old target");
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
writeln("error: still jamming old target, will try to stop next update!");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
//string comment = "doing job: " + aJob.GetDescription();
|
||
|
|
//PLATFORM.Comment(comment);
|
||
|
|
|
||
|
|
WsfTrackId previousTargetId = mChannelTargets.Get(aChannel);
|
||
|
|
string jammerName = mChannelJammers.Get(aChannel);
|
||
|
|
int beam = mChannelBeams.Get(aChannel);
|
||
|
|
bool targetChanged = (!track.IsValid() || (track.TrackId() != previousTargetId));
|
||
|
|
|
||
|
|
// if this channel had a previous target, and the new target is different
|
||
|
|
// (or invalid, and thus different), then stop jamming the previous target
|
||
|
|
// and make room for the new one
|
||
|
|
if ( targetChanged && (previousTargetId != emptyTrackId) )
|
||
|
|
{
|
||
|
|
if (DoStopJamming(aChannel, previousTargetId))
|
||
|
|
{
|
||
|
|
mChannelTargets.Set(aChannel, emptyTrackId);
|
||
|
|
previousTargetId = mChannelTargets.Get(aChannel);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
//if the new target is valid & different, and the previous target has stopped being jammed, then
|
||
|
|
//start jamming the new target
|
||
|
|
if (track.IsValid() && targetChanged && (previousTargetId == emptyTrackId))
|
||
|
|
{
|
||
|
|
if (DoStartJamming(aChannel, track))
|
||
|
|
{
|
||
|
|
mChannelTargets.Set(aChannel, track.TrackId());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
end_script
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
script void final_initialize()
|
||
|
|
|
||
|
|
WsfWeapon jammer;
|
||
|
|
int numWeapons = PLATFORM.WeaponCount();
|
||
|
|
|
||
|
|
for (int j = 0; j < numWeapons; j = j + 1)
|
||
|
|
{
|
||
|
|
jammer = PLATFORM.WeaponEntry(j);
|
||
|
|
if (jammer.IsValid())
|
||
|
|
{
|
||
|
|
string jammerPod = "none";
|
||
|
|
if ( jammer.CategoryMemberOf("left_front_pod" ))
|
||
|
|
{
|
||
|
|
jammerPod = "left_front_pod";
|
||
|
|
}
|
||
|
|
else if (jammer.CategoryMemberOf("left_rear_pod" ))
|
||
|
|
{
|
||
|
|
jammerPod = "left_rear_pod";
|
||
|
|
}
|
||
|
|
else if (jammer.CategoryMemberOf("right_front_pod"))
|
||
|
|
{
|
||
|
|
jammerPod = "right_front_pod";
|
||
|
|
}
|
||
|
|
else if (jammer.CategoryMemberOf("right_rear_pod" ))
|
||
|
|
{
|
||
|
|
jammerPod = "right_rear_pod";
|
||
|
|
}
|
||
|
|
else if (jammer.CategoryMemberOf("left_pod_lbt" ))
|
||
|
|
{
|
||
|
|
jammerPod = "left_pod_lbt";
|
||
|
|
}
|
||
|
|
else if (jammer.CategoryMemberOf("right_pod_lbt" ))
|
||
|
|
{
|
||
|
|
jammerPod = "right_pod_lbt";
|
||
|
|
}
|
||
|
|
|
||
|
|
string jType = jammer.Type();
|
||
|
|
if (jType == "SOJ_VHF_JAMMER" ||
|
||
|
|
jType == "SOJ_SBAND_JAMMER" ||
|
||
|
|
jType == "SOJ_XBAND_JAMMER" )
|
||
|
|
{
|
||
|
|
//map these N beams with the next N channels
|
||
|
|
int numBeams = jammer.MaximumBeams();
|
||
|
|
for (int k = 1; k <= numBeams; k = k + 1)
|
||
|
|
{
|
||
|
|
mChannelBeams.PushBack(k); //this next channel is to use beam k...
|
||
|
|
mChannelJammers.PushBack(jammer.Name()); //...of this jammer
|
||
|
|
mChannelPods.PushBack(jammerPod); //...on this pod
|
||
|
|
|
||
|
|
Array<int> channels = Array<int>();
|
||
|
|
if (mPodToChannels.Exists(jammerPod))
|
||
|
|
{
|
||
|
|
channels = mPodToChannels.Get(jammerPod);
|
||
|
|
}
|
||
|
|
int currentChannel = mChannelBeams.Size() - 1; //channels use zero-based indexing
|
||
|
|
channels.PushBack(currentChannel);
|
||
|
|
mPodToChannels[jammerPod] = channels;
|
||
|
|
}
|
||
|
|
if (numBeams <= 0)
|
||
|
|
{
|
||
|
|
writeln("*** WARNING: no beams on Jammer: ", jammer.Name());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
writeln("*** WARNING: Jammer type: ", jType,
|
||
|
|
" not recognized. Couldn\'t map jammer weapon beams to channels.");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
writeln("*** WARNING: Jammer weapon entry not valid: ", j);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (numWeapons <= 0)
|
||
|
|
{
|
||
|
|
writeln("*** WARNING: no weapons!!!");
|
||
|
|
}
|
||
|
|
|
||
|
|
SetNumJobChannels( mChannelJammers.Size() );
|
||
|
|
string comment = "num job channels: " + (string)GetNumJobChannels();
|
||
|
|
PLATFORM.Comment(comment);
|
||
|
|
|
||
|
|
writeln_d("channels: ", GetNumJobChannels(), " pods arr: ", mChannelPods.Size(),
|
||
|
|
" jammers arr: ", mChannelJammers.Size(), " beams arr: ", mChannelBeams.Size());
|
||
|
|
|
||
|
|
int N = GetNumJobChannels();
|
||
|
|
for (int i = 0; i < N; i = i + 1)
|
||
|
|
{
|
||
|
|
string channelDescription = "channel " + (string)i + ", pod: " + mChannelPods[i] +
|
||
|
|
", jammer: " + mChannelJammers[i] + ", beam: " + (string)mChannelBeams[i];
|
||
|
|
writeln_d(channelDescription);
|
||
|
|
PLATFORM.Comment(channelDescription);
|
||
|
|
}
|
||
|
|
|
||
|
|
writeln("Starting multi channel jammer agent for ", PLATFORM.Name());
|
||
|
|
for (int i = 0; i < GetNumJobChannels(); i = i + 1)
|
||
|
|
{
|
||
|
|
mChannelTargets.Set(i, emptyTrackId);
|
||
|
|
}
|
||
|
|
|
||
|
|
end_script
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
on_initialize
|
||
|
|
|
||
|
|
//writeln("aijam_processor on initialize");
|
||
|
|
|
||
|
|
mTaskMgr = GetTaskManager();
|
||
|
|
if (!mTaskMgr.IsValid())
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
ExecuteScriptAtTime(TIME_NOW + 0.01, "final_initialize");
|
||
|
|
|
||
|
|
ExecuteScript("LoadThreatData");
|
||
|
|
|
||
|
|
//writeln("aijam_processor end on initialize");
|
||
|
|
|
||
|
|
end_on_initialize
|
||
|
|
|
||
|
|
|
||
|
|
script void UnBidAllJobsAllChannels(WsfRIPRProcessor commander)
|
||
|
|
for (int i = 0; i < GetNumJobChannels(); i = i + 1)
|
||
|
|
{
|
||
|
|
commander.ClearBidsFor(PROCESSOR, i);
|
||
|
|
}
|
||
|
|
end_script
|
||
|
|
|
||
|
|
script void UnBidOneJobAllChannels(WsfRIPRJob aJob)
|
||
|
|
for (int i = 0; i < GetNumJobChannels(); i = i + 1)
|
||
|
|
{
|
||
|
|
aJob.UnbidJob(PROCESSOR, i);
|
||
|
|
}
|
||
|
|
end_script
|
||
|
|
|
||
|
|
|
||
|
|
on_update
|
||
|
|
|
||
|
|
double duration = 0.0;
|
||
|
|
double lStartTime = GetWallClockTime();
|
||
|
|
|
||
|
|
string comment = "num tracks: " + (string)PLATFORM.MasterTrackList().Count();
|
||
|
|
//PLATFORM.Comment(comment);
|
||
|
|
|
||
|
|
WsfRIPRProcessor cmdr = GetRIPRCommanderProcessor();
|
||
|
|
if (!cmdr.IsValid())
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
Array<WsfRIPRJob> jobs = cmdr.GetJobs();
|
||
|
|
|
||
|
|
comment = "num jobs: " + (string)jobs.Size();
|
||
|
|
//PLATFORM.Comment(comment);
|
||
|
|
|
||
|
|
writeln_d("--- on_update Platform: ", PLATFORM.Name(), ", num jobs: ", jobs.Size(),
|
||
|
|
", num channels: ", GetNumJobChannels());
|
||
|
|
|
||
|
|
time1 = 0.0;
|
||
|
|
time2 = 0.0;
|
||
|
|
time3 = 0.0;
|
||
|
|
time4 = 0.0;
|
||
|
|
|
||
|
|
//do pruning at the highest level possible, check for jammers and the roll angle first
|
||
|
|
|
||
|
|
if (mChannelJammers.Size() <= 0)
|
||
|
|
{
|
||
|
|
writeln_d("no recognized jammer weapons on platform!");
|
||
|
|
UnBidAllJobsAllChannels(cmdr); //unbid job on all channels
|
||
|
|
jobs.Clear(); //remove jobs from array, so no bids are attempted
|
||
|
|
}
|
||
|
|
|
||
|
|
if (MATH.Fabs(PLATFORM.Roll()) >= RESOURCE_ROLL_ANGLE)
|
||
|
|
{
|
||
|
|
writeln_d("platform is rolled beyond the resource limit!");
|
||
|
|
UnBidAllJobsAllChannels(cmdr); //unbid job on all channels
|
||
|
|
jobs.Clear(); //remove jobs from array, so no bids are attempted
|
||
|
|
}
|
||
|
|
|
||
|
|
//bid on each job from our commander
|
||
|
|
foreach (WsfRIPRJob aJob in jobs)
|
||
|
|
{
|
||
|
|
if(aJob.IsValid() && aJob.Name() == "jam-target")
|
||
|
|
{
|
||
|
|
double BID = -MATH.DOUBLE_MAX();
|
||
|
|
WsfTrack track = GetJobsTrack(aJob);
|
||
|
|
if (track.IsValid())
|
||
|
|
{
|
||
|
|
if (PLATFORM.SlantRangeTo(track) >= DISTANCE_3D)
|
||
|
|
{
|
||
|
|
writeln_d("jamming target is too far away: ", track.TargetName());
|
||
|
|
UnBidOneJobAllChannels(aJob); //unbid job on all channels
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
string lastJammer = "";
|
||
|
|
for (CHANNEL = 0; CHANNEL < GetNumJobChannels(); CHANNEL = CHANNEL + 1)
|
||
|
|
{
|
||
|
|
string curJammer = mChannelJammers[CHANNEL];
|
||
|
|
//if its the same jammer weapon, bid the same, two beams aren't different
|
||
|
|
if (curJammer == lastJammer)
|
||
|
|
{
|
||
|
|
BID = BID; //same bid for this beam as last beam (same jammer)
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
//BID = QueryBid(aJob);
|
||
|
|
BID = CalculateJamTargetBidValue( track, curJammer);
|
||
|
|
lastJammer = curJammer; //update last jammer to calculate bid
|
||
|
|
}
|
||
|
|
aJob.BidJob(PROCESSOR, CHANNEL, BID);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
writeln_d("track not valid for job: ", aJob.Name(), " - ", aJob.GetDescription(), ", no bid.");
|
||
|
|
UnBidOneJobAllChannels(aJob); //unbid job on all channels
|
||
|
|
}
|
||
|
|
|
||
|
|
comment = "one bid was: " + (string)BID;
|
||
|
|
writeln_d(comment);
|
||
|
|
//PLATFORM.Comment(comment);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
double midTime = GetWallClockTime();
|
||
|
|
|
||
|
|
//iterate over the channels (beams) for each pod
|
||
|
|
//take the most important jobs for that pod (greedy) and then clear the
|
||
|
|
//bids for other channels (beams) when the power is gone (spent on other beams)
|
||
|
|
|
||
|
|
for (int i = 0; i < GetNumJobChannels(); i = i + 1)
|
||
|
|
{
|
||
|
|
WsfRIPRJob job = cmdr.GetJobFor(TIME_NOW, PROCESSOR, i);
|
||
|
|
DoJob(job, i);
|
||
|
|
}
|
||
|
|
|
||
|
|
//extra debug stuff
|
||
|
|
//WsfLocalTrackList localTracks = PLATFORM.MasterTrackList();
|
||
|
|
//writeln("multi channel guy ",PLATFORM.Name()," track count: ",localTracks.Count());
|
||
|
|
//writeln("multi channel guy ",PLATFORM.Name()," job count: ",jobs.Size());
|
||
|
|
|
||
|
|
double endTime = GetWallClockTime();
|
||
|
|
//writeln("--- on_update Platform: ", PLATFORM.Name(), ", Bidding Time: ", (midTime - lStartTime));
|
||
|
|
//writeln("--- on_update Platform: ", PLATFORM.Name(), ", Do Job Time: ", (endTime - midTime));
|
||
|
|
//writeln("--- on_update Platform: ", PLATFORM.Name(), ", Whole Time: ", (endTime - lStartTime));
|
||
|
|
|
||
|
|
end_on_update
|
||
|
|
|
||
|
|
|
||
|
|
end_processor
|