init
This commit is contained in:
894
processors/ripr_agents/aifl/aifl_processor.old.txt
Normal file
894
processors/ripr_agents/aifl/aifl_processor.old.txt
Normal file
@@ -0,0 +1,894 @@
|
||||
# ****************************************************************************
|
||||
# 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.
|
||||
# ****************************************************************************
|
||||
|
||||
|
||||
#with a commander:
|
||||
#bids on "zone" and "flank" jobs
|
||||
#creates "pursue-target" and "pursue-point" jobs
|
||||
#does not perform any jobs
|
||||
#without a commander:
|
||||
#creates "pursue-target" jobs from threats in it's tracklist
|
||||
#does not perform any jobs
|
||||
|
||||
|
||||
include_once processors/ripr_agents/common/common_platform_script.txt
|
||||
|
||||
|
||||
processor AIFL-thinker WSF_AIFL_PROCESSOR
|
||||
|
||||
#script_debug_writes off
|
||||
|
||||
#debug
|
||||
script_debug_writes on
|
||||
|
||||
update_interval 3.0 sec
|
||||
|
||||
script_variables
|
||||
|
||||
bool windowToggle = false;
|
||||
WsfDraw draw = WsfDraw();
|
||||
|
||||
bool mDrawFlankLines = false;
|
||||
|
||||
Array<string> mEscortNames = Array<string>();
|
||||
string mEscortName = "";
|
||||
double mEscortProtectRange = 1E8;
|
||||
string mEscortZoneName = "";
|
||||
// We need to keep references to all the jobs we create so they don't get
|
||||
// garbage collected when they go out of scope
|
||||
Map<string, WsfRIPRJob> mTrackJobMap = Map<string, WsfRIPRJob>();
|
||||
Map<int, WsfGeoPoint> mFlankJobIdToFlankPointMap = Map<int, WsfGeoPoint>();
|
||||
int maxJobWinnersForPursueTrack = 1;
|
||||
int maxJobWinnersForWeaponUplink = 1;
|
||||
double cPursuePointPriority = 0.00001;
|
||||
double cFlankPointPriority = 25000.0;
|
||||
double cPursueTargetPriority = 10000.0;
|
||||
//bool fastAndDirtyBidding = false;
|
||||
bool fastAndDirtyBidding = true;
|
||||
|
||||
double cFlankWeighting = 100000.0;
|
||||
|
||||
string cPreferredFlank = "auto"; //or "left" or "right"
|
||||
|
||||
int cMaxPeersToComeAlong = 1000;
|
||||
|
||||
WsfRIPRJob mCurrentJob;
|
||||
WsfRIPRJob mLastJob;
|
||||
double mJobStickiness = 1.0;
|
||||
Array<string> mZoneNames = Array<string>(); #dlc
|
||||
|
||||
bool mUseThreatTypeEngageZones = true;
|
||||
Map<string, string> ThreatTypeEngageZone = Map<string, string>();
|
||||
ThreatTypeEngageZone["unknown"] = "";
|
||||
ThreatTypeEngageZone["uav"] = "";
|
||||
ThreatTypeEngageZone["sam"] = "";
|
||||
ThreatTypeEngageZone["ship"] = "";
|
||||
ThreatTypeEngageZone["awacs"] = "";
|
||||
ThreatTypeEngageZone["bomber"] = "";
|
||||
ThreatTypeEngageZone["jammer"] = "";
|
||||
ThreatTypeEngageZone["fighter"] = "";
|
||||
ThreatTypeEngageZone["missile"] = "";
|
||||
ThreatTypeEngageZone["missile_fast"] = "";
|
||||
|
||||
##extern string DeterminePlatformCategory(WsfPlatform);
|
||||
# string catg = DeterminePlatformCategory(target);
|
||||
# WsfGeoPoint WsfPlatform.Location()
|
||||
# bool WsfGeoPoint.WithinZone(string aZoneName) #Return true if the point is within the global zone.
|
||||
|
||||
end_script_variables
|
||||
|
||||
|
||||
|
||||
script bool CreateGuidanceJobFor(WsfPlatform activeWeapon, WsfTrack target)
|
||||
string uniqueName = activeWeapon.Name() + "_uplink";
|
||||
if ( ! mTrackJobMap.Exists(uniqueName) )
|
||||
{
|
||||
double jobPriority = cPursueTargetPriority * 3.0;
|
||||
WsfRIPRJob temp = WsfRIPRJob.Create( PROCESSOR,
|
||||
"weapon_uplink",
|
||||
uniqueName,
|
||||
jobPriority,
|
||||
maxJobWinnersForWeaponUplink);
|
||||
|
||||
temp.SetData("weaponPlatformIndex", activeWeapon.Index());
|
||||
temp.SetData("targetPlatformIndex", target.TargetIndex());
|
||||
temp.SetData("targetTrackName", target.TargetName());
|
||||
|
||||
AddJob(temp);
|
||||
mTrackJobMap.Set(uniqueName, temp);
|
||||
string NewComment = "AIFL - new job: " + temp.Name() + " - " + temp.GetDescription();
|
||||
PLATFORM.Comment(NewComment);
|
||||
//writeln_d("--- ", PLATFORM.Name(), " job change, ADD: ", uniqueName );
|
||||
writeln_d(NewComment);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d("Guidance job already exists: ", uniqueName);
|
||||
return false;
|
||||
}
|
||||
end_script
|
||||
|
||||
|
||||
|
||||
script void CreateJobsIndependently()
|
||||
|
||||
WsfLocalTrackList localTracks = PLATFORM.MasterTrackList();
|
||||
Map<string, int> updatedTracks = Map<string, int>();
|
||||
|
||||
WsfPlatform escortPlatform = WsfSimulation.FindPlatform( mEscortName );
|
||||
|
||||
writeln_d(" Flight Lead, Considering Num Tracks: ", localTracks.Count() );
|
||||
|
||||
foreach (WsfTrack x in localTracks)
|
||||
{
|
||||
//writeln_d(" Considering: ", x.TargetName());
|
||||
WsfTrackId tid = x.TrackId();
|
||||
writeln_d(" Considering: ", tid.Name(), ".", tid.Number(), " -> ", x.TargetName());
|
||||
updatedTracks.Set(x.TargetName(), 0);
|
||||
|
||||
// if the track is not a foe or is damaged, we'll ignore it
|
||||
if (!(x.IsValid())) // || !x.IFF_Foe())// || x.TargetDamaged() > 0)
|
||||
{
|
||||
writeln_d("!!! Need to remove track: ", !(x.IsValid()), ", ", !x.IFF_Foe(), ", ", x.TargetDamaged() > 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
#extern string DetermineTrackCategory(WsfTrack);
|
||||
string category = DetermineTrackCategory(x);
|
||||
|
||||
if (category == "unknown")
|
||||
{
|
||||
writeln_d(" - Unknown type: ", x.TargetName(), " - ", x.TargetType() );
|
||||
continue;
|
||||
}
|
||||
if (ThreatTypeEngageZone.Exists(category) && ThreatTypeEngageZone[category].Length()>0)
|
||||
{
|
||||
writeln_d(PLATFORM.Name(), " checking target ", x.TargetName(), " in zone ", ThreatTypeEngageZone[category]);
|
||||
if ( ! x.CurrentLocation().WithinZone(ThreatTypeEngageZone[category]))
|
||||
{
|
||||
writeln_d("aifl ", PLATFORM.Name(),", target ", x.TargetName(), " outside of category ", category," zone ", ThreatTypeEngageZone[category], ". not considering for a job.");
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d("aifl ", PLATFORM.Name(),", target ", x.TargetName(), " inside category ", category," zone ", ThreatTypeEngageZone[category], ". updating job!!!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d(PLATFORM.Name(), " no zone to check for category ", category);
|
||||
}
|
||||
|
||||
updatedTracks.Set(x.TargetName(), 1);
|
||||
if ( ! mTrackJobMap.Exists(x.TargetName()) )
|
||||
{
|
||||
double jobPriority = cPursueTargetPriority;
|
||||
if( escortPlatform.IsValid() )
|
||||
{
|
||||
jobPriority = cPursueTargetPriority / (1 + x.SlantRangeTo( escortPlatform ) );
|
||||
}
|
||||
|
||||
WsfRIPRJob temp = WsfRIPRJob.Create( PROCESSOR,
|
||||
"pursue-target",
|
||||
"pursue-target-" + x.TargetName(),
|
||||
jobPriority,
|
||||
maxJobWinnersForPursueTrack);
|
||||
|
||||
writeln_d(" - Setting targetTrack, name: ", x.TargetName());
|
||||
temp.SetData("targetTrack", x);
|
||||
temp.SetData("targetTrackName", x.TargetName());
|
||||
writeln_d(" - Adding job");
|
||||
AddJob(temp);
|
||||
mTrackJobMap.Set(x.TargetName(), temp);
|
||||
|
||||
//writeln_d(" - Creating job pursue-target-", x.TargetName());
|
||||
writeln_d("--- ", PLATFORM.Name(), " job change, ADD: ", x.TargetName() );
|
||||
|
||||
string NewComment = "AIFL - new job: " + temp.Name() + " - " + temp.GetDescription();
|
||||
PLATFORM.Comment(NewComment);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( escortPlatform.IsValid() )
|
||||
{
|
||||
double jobPriority = cPursueTargetPriority / (1 + x.SlantRangeTo( escortPlatform ) );
|
||||
WsfRIPRJob updateJob = mTrackJobMap.Get( x.TargetName() );
|
||||
updateJob.Priority( jobPriority );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Array<WsfRIPRJob> jobs = GetJobs();
|
||||
foreach (WsfRIPRJob x in jobs)
|
||||
{
|
||||
Map<string, Object>tempData = x.GetData();
|
||||
string name = (string)tempData["targetTrackName"];
|
||||
|
||||
if (updatedTracks[name] == 0)
|
||||
{
|
||||
if (mTrackJobMap[name].IsValid())
|
||||
{
|
||||
//writeln_d(" - Removing non-updated track: ", name);
|
||||
string temp = write_str("--- ", PLATFORM.Name(), " job change, REMOVE: ", mTrackJobMap[name].Name());
|
||||
writeln_d(temp);
|
||||
PLATFORM.Comment(temp);
|
||||
RemoveJob(mTrackJobMap[name]);
|
||||
mTrackJobMap.Erase(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
writeln_d(" - mTrackJobMap.Size() = ", mTrackJobMap.Size());
|
||||
|
||||
end_script
|
||||
|
||||
|
||||
|
||||
query_bid
|
||||
if (PLATFORM.Subordinates().Count() <= 0)
|
||||
{
|
||||
return -MATH.DOUBLE_MAX();
|
||||
}
|
||||
//only bid on jobs that air platforms can perform
|
||||
if (1 != ((int)JOB.GetData("for_air")))
|
||||
{
|
||||
writeln_d("aifl, job NOT for air!");
|
||||
return -MATH.DOUBLE_MAX();
|
||||
}
|
||||
Map<string, Object> jobData = JOB.GetData();
|
||||
//determine the job type & bid appropriately
|
||||
if( JOB.Name() == "zone" )
|
||||
{
|
||||
double maxBid = -MATH.DOUBLE_MAX();
|
||||
//iterate over all targets in the zone cluster
|
||||
//find out what my subordinates would bid on each of these targets
|
||||
//return the best bid from my subordinate on one target as my own bid on the whole cluster of targets
|
||||
WsfRIPRJob tempJob = WsfRIPRJob.Create(PROCESSOR,"pursue-target","job description",1.0,1);
|
||||
Array<string> targetNames = (Array<string>)JOB.GetData("ZoneThreatNameArray");
|
||||
writeln_d("job ", JOB.GetDescription(), " -> number of target names considering: ", targetNames.Size());
|
||||
foreach(string targetName in targetNames)
|
||||
{
|
||||
tempJob.SetData("targetTrackName", targetName);
|
||||
if (fastAndDirtyBidding)
|
||||
{
|
||||
Array<WsfRIPRProcessor> subs = GetRIPRSubordinateProcessors();
|
||||
if (subs.Size() > 0)
|
||||
{
|
||||
WsfRIPRProcessor sub = subs.Get(0);
|
||||
maxBid = sub.QueryBid(tempJob);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
//by default this expands through job-pass-through agents to get all bids
|
||||
double curBid = QuerySubordinatesMaxBid(tempJob);
|
||||
|
||||
#######
|
||||
WsfPlatform target = WsfSimulation.FindPlatform(targetName);
|
||||
if (target.IsValid())
|
||||
{
|
||||
#extern string DeterminePlatformCategory(WsfPlatform);
|
||||
string category = DeterminePlatformCategory(target);
|
||||
if (ThreatTypeEngageZone.Exists(category) && ThreatTypeEngageZone[category].Length()>0)
|
||||
{
|
||||
if ( ! target.Location().WithinZone(ThreatTypeEngageZone[category]))
|
||||
{
|
||||
curBid = -MATH.DOUBLE_MAX();
|
||||
writeln_d("aifl ", PLATFORM.Name(),", target ", targetName, " outside of category ", category," zone ", ThreatTypeEngageZone[category], ". bid = -DOUBLE_MAX.");
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d("aifl ", PLATFORM.Name(),", target ", targetName, " inside category ", category," zone ", ThreatTypeEngageZone[category], ". bid as usual!!!");
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( string aZone in mZoneNames)
|
||||
{
|
||||
if ( !target.WithinZoneOf(PLATFORM, aZone) )
|
||||
{
|
||||
curBid = -MATH.DOUBLE_MAX();
|
||||
writeln_d("ai flight lead, target ", targetName, " outside of defined zone ", aZone, " curBid from subordinate set to -DOUBLE_MAX.");
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d("ai flight lead, target ", targetName, " inside of defined zone ", aZone, " curBid unchanged.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#######
|
||||
# Escorts only bid on targets within a certain radius of the escorted platform
|
||||
#WsfPlatform escortPlatform = WsfSimulation.FindPlatform(mEscortName);
|
||||
#if ( escortPlatform.IsValid() && target.IsValid() )
|
||||
#{
|
||||
# if ( escortPlatform.SlantRangeTo(target)>mEscortProtectRange )
|
||||
# {
|
||||
# curBid = -MATH.DOUBLE_MAX();
|
||||
# writeln(" Target outside escort protect range" );
|
||||
# }
|
||||
#}
|
||||
|
||||
#######
|
||||
# Escorts only bid on targets within a zone on the escorted platform
|
||||
if ( mEscortZoneName != "" )
|
||||
{
|
||||
WsfPlatform escortPlatform = WsfSimulation.FindPlatform(mEscortName);
|
||||
if ( escortPlatform.IsValid() && target.IsValid() )
|
||||
{
|
||||
#writeln_d("$$$3", " ", target.WithinZoneOf(escortPlatform, mEscortZoneName), " ", escortPlatform.SlantRangeTo(target)*(1/MATH.M_PER_NM()));
|
||||
writeln_d(" slantrange from protected platform ", escortPlatform.Name(), " and target ", target.Name(), " is ", escortPlatform.SlantRangeTo(target)*(1/MATH.M_PER_NM()), " nmi");
|
||||
if ( !target.WithinZoneOf(escortPlatform, mEscortZoneName) )
|
||||
{
|
||||
curBid = -MATH.DOUBLE_MAX();
|
||||
writeln_d(" target not within protected platform zone");
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d(" target is within protected platform zone");
|
||||
}
|
||||
}
|
||||
}
|
||||
writeln_d("ai flight lead, max bid on ", targetName," from subordinates: ", curBid);
|
||||
if (curBid > maxBid)
|
||||
{
|
||||
maxBid = curBid;
|
||||
}
|
||||
}
|
||||
}
|
||||
return maxBid;
|
||||
}
|
||||
else if( JOB.Name() == "flank" )
|
||||
{
|
||||
|
||||
//first determine if this squadron is already in a flank position
|
||||
|
||||
#string zoneName = (string)jobData.Get("FlankZoneName");
|
||||
####string FlankZoneName = JOB.Name();
|
||||
#string FlankZoneName = zoneName;
|
||||
#WsfPlatform zoneOwner = JOB.GetAssigner().Platform();
|
||||
#//writeln_d("@@@ num subs: ", PLATFORM.Subordinates().Count());
|
||||
#Array<string> zoneNames = zoneOwner.ZoneNames();
|
||||
#foreach( string zName in zoneNames)
|
||||
#{
|
||||
# writeln(zoneOwner.Name(), " has zone: ", zName);
|
||||
#}
|
||||
|
||||
#### put this part in the script that performs the job, not bids on the job
|
||||
#foreach( WsfPlatform sub in PLATFORM.Subordinates() )
|
||||
#{
|
||||
# if( sub.WithinZoneOf( zoneOwner, FlankZoneName ) )
|
||||
# {
|
||||
# ### writeln_d( "@@@ aifl subordinate ", sub.Name(), " inside flank zone: ", FlankZoneName );
|
||||
# ### //mark job as complete (progress == 1.0)
|
||||
# ### JOB.SetProgress( PROCESSOR, 1.0 );
|
||||
# return -MATH.DOUBLE_MAX();
|
||||
# }
|
||||
#}
|
||||
|
||||
WsfGeoPoint zonePoint = (WsfGeoPoint)JOB.GetData("ZonePoint");
|
||||
double zoneBearing = (double) JOB.GetData("ZoneBearing");
|
||||
WsfZone flankZone = (WsfZone) JOB.GetData("FlankZone");
|
||||
|
||||
if (mDrawFlankLines)
|
||||
{
|
||||
//writeln("flank zone point: ", zonePoint.ToString(), ", bearing (rad): ", zoneBearing*MATH.RAD_PER_DEG());
|
||||
flankZone.DebugDrawZone(zonePoint, zoneBearing*MATH.RAD_PER_DEG());
|
||||
}
|
||||
|
||||
#foreach( WsfPlatform sub in PLATFORM.Subordinates() )
|
||||
#{
|
||||
# if (flankZone.PointIsInside(sub.Location(), zonePoint, zoneBearing*MATH.RAD_PER_DEG(), 0.0))
|
||||
# {
|
||||
# #mark the job as complete elsewhere, probably where it would be performed
|
||||
# return -MATH.DOUBLE_MAX();
|
||||
# }
|
||||
#}
|
||||
|
||||
//determine which side to flank on, based on subordinate that is closest to flank point
|
||||
//find closest subordinate & then calculate relative geometry
|
||||
#writeln_d("@@@ aiFL - commander flank job ", JOB.GetId() ," for zone: ", zoneName );
|
||||
WsfGeoPoint fPoint = (WsfGeoPoint)jobData.Get("ZonePoint");
|
||||
double flankDistance = (double)jobData.Get( "FlankDistance" );
|
||||
WsfPlatform ClosestFlanker;
|
||||
|
||||
###writeln("cluster: bearing=", clusterBearingTrue, ", distance=", flankDistance);
|
||||
|
||||
if( fPoint.IsValid() )
|
||||
{
|
||||
|
||||
if (mDrawFlankLines) //draw flank point of interest (target we are flanking), white dot
|
||||
{
|
||||
draw.BeginPoints();
|
||||
draw.SetColor(1.0, 1.0, 1.0);
|
||||
draw.Vertex(fPoint);
|
||||
draw.End();
|
||||
}
|
||||
|
||||
#writeln("cluster ZonePoint is valid!");
|
||||
double MinRange = MATH.DOUBLE_MAX();
|
||||
double NumSubordinates = (double)(PLATFORM.Subordinates().Count());
|
||||
foreach (WsfPlatform sub in PLATFORM.Subordinates())
|
||||
{
|
||||
double range = sub.SlantRangeTo( fPoint );
|
||||
#writeln("sub ", sub.Name(), " slant range to cluster point: ", range);
|
||||
if( range < MinRange )
|
||||
{
|
||||
MinRange = range;
|
||||
ClosestFlanker = sub;
|
||||
}
|
||||
}
|
||||
|
||||
bool clusterBearingValid = (bool)jobData.Get( "ZoneBearingValid" );
|
||||
double tempBearing = (double)jobData.Get( "ZoneBearing" );
|
||||
###double clusterBearingTrue = MATH.NormalizeAngle0_360( (double)jobData.Get( "ZoneBearing" ) );
|
||||
double clusterBearingTrue = 0.0;
|
||||
if (clusterBearingValid)
|
||||
{
|
||||
#writeln("cluster bearing valid, bearing: ", tempBearing);
|
||||
|
||||
### cluster heading is with reference to east (instead of north), so subtract 90 degrees
|
||||
|
||||
|
||||
#clusterBearingTrue = MATH.NormalizeAngle0_360( tempBearing - 90.0 );
|
||||
clusterBearingTrue = MATH.NormalizeAngle0_360( tempBearing );
|
||||
|
||||
|
||||
WsfGeoPoint bPoint = WsfGeoPoint(fPoint);
|
||||
bPoint.Extrapolate( clusterBearingTrue, flankDistance );
|
||||
|
||||
if (mDrawFlankLines) //draw red-orange line to represent heading of target's flight
|
||||
{
|
||||
draw.BeginLines();
|
||||
draw.SetColor(1.0, 0.3, 0.1);
|
||||
draw.Vertex(fPoint);
|
||||
draw.Vertex(bPoint);
|
||||
draw.End();
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln("cluster bearing invalid, bearing: ", tempBearing);
|
||||
//assume cluster is flying straight at me, flank to side I'm already oriented towards
|
||||
clusterBearingTrue = ClosestFlanker.TrueBearingTo( fPoint ) - 180.0;
|
||||
}
|
||||
|
||||
//don't need to normalize it here, the next line catches it
|
||||
double angle = ClosestFlanker.TrueBearingTo( fPoint ) - 180.0;
|
||||
double relativeFlankBearing = MATH.NormalizeAngle0_360( angle - clusterBearingTrue );
|
||||
double flankAngle = 90.0;
|
||||
if( relativeFlankBearing > 180.0 )
|
||||
{
|
||||
flankAngle = 270.0;
|
||||
}
|
||||
|
||||
if (cPreferredFlank == "left")
|
||||
{
|
||||
flankAngle = 90.0;
|
||||
}
|
||||
else if(cPreferredFlank == "right")
|
||||
{
|
||||
flankAngle = 270.0;
|
||||
}
|
||||
|
||||
double flankBearing = MATH.NormalizeAngle0_360( clusterBearingTrue + flankAngle );
|
||||
|
||||
#writeln("angle: ", angle, ", relativeFlankBearing: ", relativeFlankBearing, ", cluster: bearing=", flankBearing, ", minRange=", MinRange);
|
||||
|
||||
WsfGeoPoint ePoint = WsfGeoPoint(fPoint);
|
||||
ePoint.Extrapolate( flankBearing, flankDistance );
|
||||
|
||||
if (mDrawFlankLines) //draw green line to the flank point, and to the side we are flying towards
|
||||
{
|
||||
|
||||
draw.BeginLines();
|
||||
draw.SetColor(0.1, 1.0, 0.4);
|
||||
draw.Vertex(fPoint);
|
||||
draw.Vertex(ePoint);
|
||||
draw.Vertex(fPoint);
|
||||
draw.Vertex(ClosestFlanker);
|
||||
draw.End();
|
||||
}
|
||||
|
||||
//save off the flank point, in case we win this job
|
||||
mFlankJobIdToFlankPointMap.Set( JOB.GetId(), ePoint );
|
||||
|
||||
//find the range to the place we will fly so as to flank the target
|
||||
MinRange = ClosestFlanker.SlantRangeTo( ePoint );
|
||||
|
||||
###double JobBidValue = NumSubordinates / MATH.Sqrt(MinRange);
|
||||
double JobBidValue = NumSubordinates * flankDistance / MinRange;
|
||||
JobBidValue = JobBidValue + cFlankWeighting;
|
||||
#writeln_d("!!! Bid for flanking job: ", JOB.Name(), ", bid: ", JobBidValue );
|
||||
return JobBidValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d("!!! Invalid point in flank job");
|
||||
}
|
||||
}
|
||||
//can't make a bid, return max negative
|
||||
return -MATH.DOUBLE_MAX();
|
||||
end_query_bid
|
||||
|
||||
|
||||
|
||||
|
||||
script void CreateJobsFromCommander()
|
||||
|
||||
//writeln_d("!!! Creating jobs from commanders jobs!" );
|
||||
|
||||
Array<WsfRIPRJob> jobs = GetRIPRCommanderProcessor().GetJobs();
|
||||
|
||||
writeln_d(PLATFORM.Name(), " jobs.Size() = ", jobs.Size());
|
||||
|
||||
foreach (WsfRIPRJob aJob in jobs)
|
||||
{
|
||||
if( aJob.IsValid() )
|
||||
{
|
||||
double bidValue = QueryBid(aJob);
|
||||
|
||||
writeln_d(PLATFORM.Name(), " bid on job ", aJob.GetDescription(), " == ", bidValue, ", priority = ", aJob.GetPriority());
|
||||
|
||||
if (bidValue == -MATH.DOUBLE_MAX())
|
||||
{
|
||||
if (aJob.GetProgress( PROCESSOR) < 1.0)
|
||||
{
|
||||
aJob.UnbidJob( PROCESSOR );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
aJob.BidJob( PROCESSOR, bidValue );
|
||||
}
|
||||
|
||||
# aJob.SetProgress( PROCESSOR, 1.0 );
|
||||
# GetRIPRCommanderProcessor().RemoveJob(aJob)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// now check the board to see what we've won!
|
||||
mCurrentJob = GetRIPRCommanderProcessor().GetJobFor(TIME_NOW, PROCESSOR);
|
||||
|
||||
if( mCurrentJob.IsValid() )
|
||||
{
|
||||
if( (!mLastJob.IsValid()) || mCurrentJob.GetId() != mLastJob.GetId() )
|
||||
{
|
||||
string NewComment = "AIFL - Won new job: " + mCurrentJob.Name() + " - " + mCurrentJob.GetDescription();
|
||||
PLATFORM.Comment(NewComment);
|
||||
}
|
||||
mLastJob = mCurrentJob;
|
||||
|
||||
if( mCurrentJob.Name() == "zone" )
|
||||
{
|
||||
Map<string, int> updatedTracks = Map<string, int>();
|
||||
Array<string> targetNames = (Array<string>)mCurrentJob.GetData("ZoneThreatNameArray");
|
||||
writeln_d(PLATFORM.Name(), " targetNames.Size() = ", targetNames.Size());
|
||||
WsfGeoPoint point;
|
||||
|
||||
#WsfCluster cluster = WsfCluster.Create();
|
||||
|
||||
foreach(string targetName in targetNames)
|
||||
{
|
||||
WsfPlatform target = WsfSimulation.FindPlatform(targetName);
|
||||
if (target.IsValid())
|
||||
{
|
||||
#extern string DeterminePlatformCategory(WsfPlatform);
|
||||
string category = DeterminePlatformCategory(target);
|
||||
if (ThreatTypeEngageZone.Exists(category) && ThreatTypeEngageZone[category].Length()>0)
|
||||
{
|
||||
if ( ! target.Location().WithinZone(ThreatTypeEngageZone[category]))
|
||||
{
|
||||
#make sure no job exists for him
|
||||
continue;
|
||||
}
|
||||
}
|
||||
updatedTracks.Set( targetName, 1 );
|
||||
|
||||
#cluster.Add(target.MakeTrack());
|
||||
|
||||
#save any target's location, to send along extra subordinates later
|
||||
point = target.Location();
|
||||
|
||||
if (!mTrackJobMap.Exists(targetName))
|
||||
{
|
||||
WsfRIPRJob temp = WsfRIPRJob.Create( PROCESSOR,
|
||||
"pursue-target",
|
||||
"pursue-target-" + targetName,
|
||||
cPursueTargetPriority,
|
||||
maxJobWinnersForPursueTrack);
|
||||
temp.SetData("targetTrackName", targetName);
|
||||
AddJob(temp);
|
||||
mTrackJobMap.Set(targetName, temp);
|
||||
writeln_d("--- ", PLATFORM.Name(), " job change, ADD: ", targetName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Array<WsfRIPRProcessor> subs = GetRIPRSubordinateProcessors();
|
||||
int NumSubordinates = subs.Size();
|
||||
string zName = (string)mCurrentJob.GetData("ZoneName");
|
||||
|
||||
//create a pursue-point job that allows for enough winners to send the whole squadron
|
||||
//this is useful in case some subordinates don't have a track for some of the threats
|
||||
//or if there are less threats than there are subordinates, so the whole squadron will be sent
|
||||
|
||||
//writeln_d("!!! Not enough tracks inside zone for all subordinates! Using default zone point too!" );
|
||||
|
||||
#if (cluster.Count()>0)
|
||||
if (point.IsValid())
|
||||
{
|
||||
updatedTracks.Set( zName, 1 );
|
||||
#WsfGeoPoint point = (WsfGeoPoint)mCurrentJob.GetData("ZonePoint");
|
||||
#WsfGeoPoint realPoint = cluster.MeanLocation();
|
||||
|
||||
if( ! mTrackJobMap.Exists( zName ) )
|
||||
{
|
||||
if (NumSubordinates > cMaxPeersToComeAlong)
|
||||
{
|
||||
NumSubordinates = cMaxPeersToComeAlong;
|
||||
}
|
||||
if (NumSubordinates > 0)
|
||||
{
|
||||
//set max job winners to number of subordinates (so all can proceed into zone)
|
||||
WsfRIPRJob temp = WsfRIPRJob.Create( PROCESSOR,
|
||||
"pursue-point",
|
||||
"pursue-point-" + zName,
|
||||
cPursuePointPriority,
|
||||
NumSubordinates);
|
||||
temp.SetData( "targetTrackName", zName ); //hack for now, so other code here works
|
||||
temp.SetData( "targetPoint", point );
|
||||
#temp.SetData( "targetPoint", realPoint );
|
||||
#writeln(PLATFORM.Name(), " using cluster point: ", realPoint.ToString());
|
||||
AddJob(temp);
|
||||
mTrackJobMap.Set( zName, temp );
|
||||
writeln_d("--- ", PLATFORM.Name(), " job change, ADD: ", zName );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//update the job?
|
||||
mTrackJobMap.Get( zName ).SetData( "targetPoint" , point );
|
||||
#mTrackJobMap.Get( zName ).SetData( "targetPoint" , realPoint );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln(PLATFORM.Name(), " has no valid targets, not creating pursue-point job either!");
|
||||
}
|
||||
|
||||
Array<WsfRIPRJob> jobs = GetJobs();
|
||||
foreach (WsfRIPRJob x in jobs)
|
||||
{
|
||||
string name = (string)x.GetData("targetTrackName");
|
||||
if (updatedTracks.Get(name) != 1)
|
||||
{
|
||||
writeln_d("--- ", PLATFORM.Name(), " job change, REMOVE: ", name);
|
||||
RemoveJob(mTrackJobMap[name]);
|
||||
mTrackJobMap.Erase(name);
|
||||
}
|
||||
}
|
||||
|
||||
#writeln(PLATFORM.Name(), " final line in zone job processing!");
|
||||
|
||||
}
|
||||
else if( mCurrentJob.Name() == "flank" )
|
||||
{
|
||||
writeln_d(" Flight Lead, Won job for flank ", mCurrentJob.Name() );
|
||||
|
||||
|
||||
#//see if any subordinates are in the flank zone, if they are... flanking is done
|
||||
####string FlankZoneName = mCurrentJob.Name();
|
||||
#string FlankZoneName = (string)(mCurrentJob.GetData().Get("FlankZoneName"));
|
||||
#writeln_d( "@@@ aifl flank zone: ", FlankZoneName );
|
||||
#WsfPlatform zoneOwner = mCurrentJob.GetAssigner().Platform();
|
||||
#writeln("@@@ aifl flank zone owner: ", zoneOwner.Name());
|
||||
|
||||
|
||||
WsfGeoPoint zonePoint = (WsfGeoPoint)mCurrentJob.GetData("ZonePoint");
|
||||
double zoneBearing = (double) mCurrentJob.GetData("ZoneBearing");
|
||||
WsfZone flankZone = (WsfZone) mCurrentJob.GetData("FlankZone");
|
||||
|
||||
foreach( WsfPlatform sub in PLATFORM.Subordinates() )
|
||||
{
|
||||
if (flankZone.PointIsInside(sub.Location(), zonePoint, zoneBearing*MATH.RAD_PER_DEG(), 0.0))
|
||||
{
|
||||
writeln_d( "@@@ aifl subordinate ", sub.Name(), " inside flank zone!");
|
||||
mCurrentJob.SetProgress( PROCESSOR, 1.0 ); #mark the job as complete
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WsfGeoPoint point = mFlankJobIdToFlankPointMap.Get( mCurrentJob.GetId() );
|
||||
int NumSubordinates = PLATFORM.Subordinates().Count();
|
||||
|
||||
#foreach( WsfPlatform sub in PLATFORM.Subordinates() )
|
||||
#{
|
||||
# if( sub.GroundRangeTo(point) < 1500 )
|
||||
# {
|
||||
# writeln_d( "@@@ aifl subordinate ", sub.Name(), " close to flank point!");
|
||||
# mCurrentJob.SetProgress( PROCESSOR, 1.0 );
|
||||
# #mCurrentJob.UnbidJob( PROCESSOR );
|
||||
# return;
|
||||
# }
|
||||
# else
|
||||
# {
|
||||
# writeln_d( "@@@ aifl subordinate ", sub.Name(), " NOT close to flank point!");
|
||||
# }
|
||||
#}
|
||||
|
||||
|
||||
##string zName = (string)mCurrentJob.GetData("ZoneName");
|
||||
string zName = (string)mCurrentJob.GetData("FlankZoneName");
|
||||
|
||||
//if flank job doesn't exist yet, create it
|
||||
if( ! mTrackJobMap.Exists( zName ) )
|
||||
{
|
||||
if (NumSubordinates > cMaxPeersToComeAlong)
|
||||
{
|
||||
NumSubordinates = cMaxPeersToComeAlong;
|
||||
}
|
||||
if (NumSubordinates > 0)
|
||||
{
|
||||
//set max job winners to number of subordinates (so all can proceed into zone)
|
||||
WsfRIPRJob temp = WsfRIPRJob.Create( PROCESSOR,
|
||||
"pursue-point",
|
||||
"pursue-point-" + zName,
|
||||
cFlankPointPriority,
|
||||
NumSubordinates);
|
||||
temp.SetData( "targetTrackName", zName ); //hack for now, so other code here works
|
||||
temp.SetData( "targetPoint", point );
|
||||
AddJob(temp);
|
||||
mTrackJobMap.Set( zName, temp );
|
||||
writeln_d("--- ", PLATFORM.Name(), " job change, ADD: ", zName );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mTrackJobMap.Get( zName ).SetData( "targetPoint" , point );
|
||||
writeln_d(" aiFL - updated flank pursue-point job ", zName, ", ( ", point.Latitude(), ", ", point.Longitude(), " )" );
|
||||
}
|
||||
|
||||
//remove all jobs that aren't involved with flanking
|
||||
Array<WsfRIPRJob> jobs = GetJobs();
|
||||
foreach (WsfRIPRJob x in jobs)
|
||||
{
|
||||
Map<string, Object>jobData = x.GetData();
|
||||
string name = (string)jobData.Get("targetTrackName");
|
||||
if ( name != zName )
|
||||
{
|
||||
//writeln_d(" - Removing job not related to flanking, target: ", name);
|
||||
writeln_d("--- ", PLATFORM.Name(), " job change, REMOVE: ", name);
|
||||
RemoveJob(mTrackJobMap[name]);
|
||||
mTrackJobMap.Erase(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln("ERROR: UNRECOGNIZED JOB TYPE: ", mCurrentJob.Name(), " !!!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d("--- mCurrentJob NOT VALID!!!!! Removing all my aifl jobs.");
|
||||
Array<WsfRIPRJob> jobs = GetJobs();
|
||||
foreach (WsfRIPRJob x in jobs)
|
||||
{
|
||||
Map<string, Object>jobData = x.GetData();
|
||||
string name = (string)jobData.Get("targetTrackName");
|
||||
writeln_d("--- ", PLATFORM.Name(), " job change, REMOVE: ", name);
|
||||
RemoveJob(mTrackJobMap[name]);
|
||||
mTrackJobMap.Erase(name);
|
||||
}
|
||||
}
|
||||
|
||||
#writeln(PLATFORM.Name(), " final line in CreateJobsFromCommander method!");
|
||||
|
||||
end_script
|
||||
|
||||
|
||||
|
||||
on_initialize2
|
||||
draw.SetPointSize(5);
|
||||
draw.SetDuration(PROCESSOR.UpdateInterval()); //try it here, after the processor is setup
|
||||
end_on_initialize2
|
||||
|
||||
|
||||
on_initialize
|
||||
|
||||
SetJobAllocationMode(0); #spread (Default -- every subordinate is given the highest priority job that he has the highest bid for. If there are more subordinates than jobs, some subordinates will be left idle. )
|
||||
#SetJobAllocationMode(1); #greedy (Every subordinate is given the job he bids highest on with the highest priority, without regard for the maximum number of winners that the job allows. Every subordinate will get a job. (Disregards Job Stickiness value) )
|
||||
#SetJobAllocationMode(2); #coverthengreedy (Like spread, but remaining unassigned subordinates will be given the job they bid highest on with the highest priority, even if that results in the job having more winners that the maximum specified. )
|
||||
#SetJobAllocationMode(3); #coverthenspread (Like spread, but remaining unassigned subordinates will be spread out over the pool of jobs with no job getting two extra winners before all jobs have one extra winner. )
|
||||
#SetJobAllocationMode(4); #strictpriority (Like spread, awards the highest priority job to the highest bidder regardless of the bidder's highest overall bid. )
|
||||
|
||||
#SetJobStickiness(mJobStickiness);
|
||||
|
||||
Array<WsfZone> zoneList = PLATFORM.Zones();
|
||||
foreach (WsfZone z in zoneList)
|
||||
{
|
||||
mZoneNames.PushBack(z.Name());
|
||||
}
|
||||
foreach( string x in mZoneNames )
|
||||
{
|
||||
writeln_d("~~~ Flight Lead ", PLATFORM.Name(), " now monitoring retrieved zone: ", x );
|
||||
}
|
||||
|
||||
if( mZoneNames.Size() == 0 )
|
||||
{
|
||||
writeln_d( "~~~ Flight Lead ", PLATFORM.Name(), " has no zone defined." );
|
||||
}
|
||||
|
||||
end_on_initialize
|
||||
|
||||
|
||||
|
||||
on_update
|
||||
|
||||
/*
|
||||
if (windowToggle)
|
||||
{
|
||||
SetJobWindowOpen(true);
|
||||
SetBidWindowOpen(false);
|
||||
windowToggle = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetJobWindowOpen(false);
|
||||
SetBidWindowOpen(true);
|
||||
windowToggle = true;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
#######
|
||||
mEscortName = "";
|
||||
if ( !mEscortNames.Empty() )
|
||||
{
|
||||
foreach ( string sEscortName in mEscortNames )
|
||||
{
|
||||
if ( WsfSimulation.FindPlatform(sEscortName).IsValid() )
|
||||
{
|
||||
mEscortName = sEscortName;
|
||||
#writeln("$$$2", " ", PLATFORM.Name(), " ", mEscortName);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
#{
|
||||
# mEscortNames.Erase(mEscortName);
|
||||
#}
|
||||
}
|
||||
}
|
||||
|
||||
if ( mEscortName != "" ) writeln_d("~~~ Flight Lead ", PLATFORM.Name(), " is assigned to escort ", mEscortName);
|
||||
|
||||
double duration = 0.0;
|
||||
double lStartTime = GetWallClockTime();
|
||||
writeln_d("--- aifl_update Platform: ", PLATFORM.Name(), ", Time: ", TIME_NOW);
|
||||
if (GetRIPRCommanderProcessor().IsValid())
|
||||
{
|
||||
writeln_d("...CreateJobsFromCommander()");
|
||||
CreateJobsFromCommander();
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d("...CreateJobsIndependently()");
|
||||
CreateJobsIndependently();
|
||||
}
|
||||
duration = GetWallClockTime() - lStartTime;
|
||||
writeln_d("--- on_update Platform: ", PLATFORM.Name(), ", Process Time: ", duration);
|
||||
end_on_update
|
||||
|
||||
|
||||
end_processor
|
||||
281
processors/ripr_agents/aifl/aifl_processor.txt
Normal file
281
processors/ripr_agents/aifl/aifl_processor.txt
Normal file
@@ -0,0 +1,281 @@
|
||||
# ****************************************************************************
|
||||
# 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 processors/ripr_agents/common/common_platform_script.txt
|
||||
|
||||
include_once processors/ripr_agents/aiai/behavior_bid_on_jobs.txt
|
||||
include_once processors/ripr_agents/aifl/behavior_interpret_zone_jobs.txt
|
||||
include_once processors/ripr_agents/aifl/behavior_create_target_jobs_self.txt
|
||||
include_once processors/ripr_agents/aifl/behavior_interpret_flank_jobs.txt
|
||||
include_once processors/ripr_agents/aifl/behavior_create_point_job.txt
|
||||
include_once processors/ripr_agents/aifl/behavior_create_cap-routes.txt
|
||||
#include_once processors/ripr_agents/aifl/behavior_create_sar_jobs.txt
|
||||
include_once processors/ripr_agents/aifl/behavior_manage-pincer.txt
|
||||
include_once processors/ripr_agents/aifl/behavior_manage-uplinks.txt
|
||||
include_once processors/ripr_agents/aiai/behavior_debug_job_board.txt
|
||||
include_once processors/ripr_agents/aifl/behavior_toggle_windows.txt
|
||||
|
||||
|
||||
processor AIFL-thinker WSF_RIPR_PROCESSOR
|
||||
|
||||
script_debug_writes off
|
||||
update_interval 3.0 sec
|
||||
|
||||
script_variables
|
||||
bool windowToggle = false;
|
||||
// We need to keep references to all the jobs we create so they don't get
|
||||
// garbage collected when they go out of scope
|
||||
int maxJobWinnersForWeaponUplink = 1;
|
||||
double cPursuePointPriority = 0.00001;
|
||||
double cFlankPointPriority = 25000.0;
|
||||
double cPursueTargetPriority = 10000.0;
|
||||
double cPincerPriority = 10000.0;
|
||||
WsfRIPRJob mCurrentJob;
|
||||
WsfRIPRJob mLastJob;
|
||||
double mJobStickiness = 1.25;
|
||||
int mJobAllocationMode = 3;
|
||||
bool mFastAndDirtyBidding = false;
|
||||
Map<string, string> ThreatTypeEngageZone = Map<string, string>();
|
||||
string cPreferredFlank = "auto"; //or "left" or "right"
|
||||
Map<int, WsfGeoPoint> mFlankJobIdToFlankPointMap = Map<int, WsfGeoPoint>();
|
||||
|
||||
end_script_variables
|
||||
|
||||
|
||||
behavior_tree
|
||||
behavior_node bid_on_jobs
|
||||
behavior_node toggle_windows
|
||||
selector
|
||||
behavior_node interpret_zone_jobs
|
||||
behavior_node create_target_jobs_self
|
||||
end_selector
|
||||
behavior_node create_point_job
|
||||
behavior_node create_cap-routes
|
||||
#behavior_node create_sar_jobs
|
||||
#behavior_node interpret_flank_jobs
|
||||
behavior_node manage-uplinks
|
||||
behavior_node manage-pincer
|
||||
#behavior_node debug_job_board
|
||||
end_behavior_tree
|
||||
|
||||
##deprecated
|
||||
#query_bid
|
||||
# return -MATH.DOUBLE_MAX();
|
||||
#end_query_bid
|
||||
|
||||
on_initialize
|
||||
# job allocation mode enumerations:
|
||||
# 0 --> spread (Default -- every subordinate is given the highest priority job that he has the highest bid for. If there are more subordinates than jobs, some subordinates will be left idle. )
|
||||
# 1 --> greedy (Every subordinate is given the job he bids highest on with the highest priority, without regard for the maximum number of winners that the job allows. Every subordinate will get a job. (Disregards Job Stickiness value) )
|
||||
# 2 --> coverthengreedy (Like spread, but remaining unassigned subordinates will be given the job they bid highest on with the highest priority, even if that results in the job having more winners that the maximum specified. )
|
||||
# 3 --> coverthenspread (Like spread, but remaining unassigned subordinates will be spread out over the pool of jobs with no job getting two extra winners before all jobs have one extra winner. )
|
||||
# 4 --> strictpriority (Like spread, awards the highest priority job to the highest bidder regardless of the bidder's highest overall bid. )
|
||||
PROCESSOR.SetJobAllocationMode(mJobAllocationMode);
|
||||
PROCESSOR.SetJobStickiness(mJobStickiness);
|
||||
end_on_initialize
|
||||
|
||||
|
||||
|
||||
query_bid_type zone
|
||||
|
||||
if (PLATFORM.Subordinates().Count() <= 0 || PROCESSOR.GetRIPRSubordinateProcessors().Size() <= 0)
|
||||
{
|
||||
writeln_d("behavior interpret_zone_jobs: not enough subordinates");
|
||||
return -MATH.DOUBLE_MAX();
|
||||
}
|
||||
########################################################################
|
||||
## bid on the cluster is based on subordinate bids on their members
|
||||
########################################################################
|
||||
WsfRIPRJob tempJob = WsfRIPRJob.Create(PROCESSOR,"pursue-target","job description",1.0,1);
|
||||
Array<string> targetNames = (Array<string>)JOB.GetData("ZoneThreatNameArray");
|
||||
writeln_d("job ", JOB.GetDescription(), " -> number of target names considering: ", targetNames.Size());
|
||||
double maxBid = -MATH.DOUBLE_MAX();
|
||||
|
||||
foreach(string targetName in targetNames)
|
||||
{
|
||||
bool inZone = true;
|
||||
WsfPlatform target = WsfSimulation.FindPlatform(targetName);
|
||||
if (target.IsValid())
|
||||
{
|
||||
#extern string DeterminePlatformCategory(WsfPlatform);
|
||||
string category = DeterminePlatformCategory(target);
|
||||
if (ThreatTypeEngageZone.Exists(category) && ThreatTypeEngageZone[category].Length()>0)
|
||||
{
|
||||
if ( ! target.Location().WithinZone(ThreatTypeEngageZone[category]))
|
||||
{
|
||||
inZone = false;
|
||||
writeln_d("aifl ", PLATFORM.Name(),", target ", targetName, " outside of category ", category," zone ", ThreatTypeEngageZone[category], ". bid = -DOUBLE_MAX.");
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d("aifl ", PLATFORM.Name(),", target ", targetName, " inside category ", category," zone ", ThreatTypeEngageZone[category], ". bid as usual!!!");
|
||||
}
|
||||
}
|
||||
foreach ( string aZone in PLATFORM.ZoneNames())
|
||||
{
|
||||
if ( !target.WithinZoneOf(PLATFORM, aZone) )
|
||||
{
|
||||
inZone = false;
|
||||
writeln_d("ai flight lead, target ", targetName, " outside of defined zone ", aZone, " curBid from subordinate set to -DOUBLE_MAX.");
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d("ai flight lead, target ", targetName, " inside of defined zone ", aZone, " curBid unchanged.");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (inZone == true)
|
||||
{
|
||||
tempJob.SetData("targetTrackName", targetName);
|
||||
if (mFastAndDirtyBidding)
|
||||
{
|
||||
maxBid = PROCESSOR.GetRIPRSubordinateProcessors().Get(0).QueryBid(tempJob);
|
||||
writeln_d("ai flight lead, fast dirty bid on ", JOB.Description()," = ", maxBid);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
//by default this expands through job-pass-through agents to get all bids
|
||||
double curBid = PROCESSOR.QuerySubordinatesMaxBid(tempJob);
|
||||
|
||||
writeln_d("ai flight lead, max bid on ", targetName," from subordinates: ", curBid);
|
||||
if (curBid > maxBid)
|
||||
{
|
||||
maxBid = curBid;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
maxBid = -MATH.DOUBLE_MAX();
|
||||
}
|
||||
}
|
||||
return maxBid;
|
||||
|
||||
end_query_bid_type
|
||||
|
||||
|
||||
|
||||
query_bid_type flank
|
||||
|
||||
if (PLATFORM.Subordinates().Count() <= 0)
|
||||
{
|
||||
writeln_d("no subordinates to carry out flank job");
|
||||
return -MATH.DOUBLE_MAX();
|
||||
}
|
||||
|
||||
WsfGeoPoint zonePoint = (WsfGeoPoint)JOB.GetData("ZonePoint");
|
||||
double zoneBearing = (double) JOB.GetData("ZoneBearing");
|
||||
WsfZone flankZone = (WsfZone) JOB.GetData("FlankZone");
|
||||
double flankDist = (double) JOB.GetData("FlankDistance");
|
||||
bool bearingValid = (bool) JOB.GetData("ZoneBearingValid");
|
||||
|
||||
//determine which side to flank on, based on subordinate that is closest to flank point
|
||||
//find closest subordinate & then calculate relative geometry
|
||||
|
||||
WsfPlatform ClosestFlanker;
|
||||
|
||||
if( zonePoint.IsValid() )
|
||||
{
|
||||
double MinRange = MATH.DOUBLE_MAX();
|
||||
double NumSubordinates = (double)(PLATFORM.Subordinates().Count());
|
||||
foreach (WsfPlatform sub in PLATFORM.Subordinates())
|
||||
{
|
||||
double range = sub.SlantRangeTo( zonePoint );
|
||||
if( range < MinRange )
|
||||
{
|
||||
MinRange = range;
|
||||
ClosestFlanker = sub;
|
||||
}
|
||||
}
|
||||
if (!ClosestFlanker.IsValid())
|
||||
{
|
||||
writeln_d("!!! no valid subordinates to compare to flank point!");
|
||||
return -MATH.DOUBLE_MAX();
|
||||
}
|
||||
|
||||
double clusterBearingTrue = 0.0;
|
||||
if (bearingValid)
|
||||
{
|
||||
//cluster heading is with reference to east (instead of north), so subtract 90 degrees
|
||||
#clusterBearingTrue = MATH.NormalizeAngle0_360( zoneBearing - 90.0 );
|
||||
clusterBearingTrue = MATH.NormalizeAngle0_360( zoneBearing );
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d("cluster bearing invalid, bearing: ", zoneBearing);
|
||||
//assume cluster is flying straight at me, flank to side I'm already oriented towards
|
||||
clusterBearingTrue = ClosestFlanker.TrueBearingTo( zonePoint ) - 180.0;
|
||||
}
|
||||
|
||||
//don't need to normalize it here, the next line catches it
|
||||
double angle = ClosestFlanker.TrueBearingTo( zonePoint ) - 180.0;
|
||||
double relativeFlankBearing = MATH.NormalizeAngle0_360( angle - clusterBearingTrue );
|
||||
double flankAngle = 90.0;
|
||||
if( relativeFlankBearing > 180.0 )
|
||||
{
|
||||
flankAngle = 270.0;
|
||||
}
|
||||
|
||||
if (cPreferredFlank == "left")
|
||||
{
|
||||
flankAngle = 90.0;
|
||||
}
|
||||
else if(cPreferredFlank == "right")
|
||||
{
|
||||
flankAngle = 270.0;
|
||||
}
|
||||
|
||||
double flankBearing = MATH.NormalizeAngle0_360( clusterBearingTrue + flankAngle );
|
||||
WsfGeoPoint ePoint = WsfGeoPoint(zonePoint);
|
||||
ePoint.Extrapolate( flankBearing, flankDist );
|
||||
|
||||
//save off the flank point, in case we win this job
|
||||
mFlankJobIdToFlankPointMap.Set( JOB.GetId(), ePoint );
|
||||
|
||||
//find the range to the place we will fly so as to flank the target
|
||||
MinRange = ClosestFlanker.SlantRangeTo( ePoint );
|
||||
|
||||
double JobBidValue = 100000 + NumSubordinates * flankDist / MinRange;
|
||||
return JobBidValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d("!!! Invalid point in flank job");
|
||||
return -MATH.DOUBLE_MAX();
|
||||
}
|
||||
|
||||
end_query_bid_type
|
||||
|
||||
|
||||
on_update
|
||||
|
||||
writeln_d("--- aifl_update Platform: ", PLATFORM.Name(), ", Time: ", TIME_NOW);
|
||||
|
||||
WsfRIPRProcessor commander = PROCESSOR.GetRIPRCommanderProcessor();
|
||||
if (commander.IsValid())
|
||||
{
|
||||
// print any job changes, so check the board to see what we've won
|
||||
mCurrentJob = commander.GetJobFor(TIME_NOW, PROCESSOR);
|
||||
if( mCurrentJob.IsValid() )
|
||||
{
|
||||
if( (!mLastJob.IsValid()) || mCurrentJob.GetId() != mLastJob.GetId() )
|
||||
{
|
||||
string NewComment = "AIFL - Won new job: " + mCurrentJob.Name() + " - " + mCurrentJob.GetDescription();
|
||||
PLATFORM.Comment(NewComment);
|
||||
}
|
||||
mLastJob = mCurrentJob;
|
||||
}
|
||||
}
|
||||
|
||||
end_on_update
|
||||
|
||||
|
||||
end_processor
|
||||
@@ -0,0 +1,33 @@
|
||||
# ****************************************************************************
|
||||
# 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 adjust_priority_for_escort
|
||||
|
||||
precondition
|
||||
return true;
|
||||
end_precondition
|
||||
|
||||
execute
|
||||
#extern string mEscortName;
|
||||
WsfPlatform escortPlatform = WsfSimulation.FindPlatform( mEscortName );
|
||||
if( escortPlatform.IsValid() )
|
||||
{
|
||||
|
||||
#extern double cPursueTargetPriority;
|
||||
Array<WsfRIPRJob> jobs = PROCESSOR.GetJobs();
|
||||
foreach (WsfRIPRJob x in jobs)
|
||||
{
|
||||
double jobPriority = cPursueTargetPriority / (1 + x.SlantRangeTo( escortPlatform ) );
|
||||
x.Priority( jobPriority );
|
||||
}
|
||||
}
|
||||
end_execute
|
||||
|
||||
end_behavior
|
||||
66
processors/ripr_agents/aifl/behavior_create_cap-routes.txt
Normal file
66
processors/ripr_agents/aifl/behavior_create_cap-routes.txt
Normal file
@@ -0,0 +1,66 @@
|
||||
# ****************************************************************************
|
||||
# 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 create_cap-routes
|
||||
|
||||
script_debug_writes off
|
||||
|
||||
script_variables
|
||||
Array<Map<string, Object>> mCapRoutes = Array<Map<string, Object>>();
|
||||
#mCapRoutes[0] = Map<string, Object>();
|
||||
#mCapRoutes[0].Set("route name", "GOALIE_CAP_CCW_ORBIT");
|
||||
#mCapRoutes[0].Set("location", WsfGeoPoint.Construct(12.60313, 117.37702, 40000));
|
||||
#mCapRoutes[0].Set("heading", 140.0);
|
||||
#mCapRoutes[0].Set("priority", 1000.0);
|
||||
#mCapRoutes[0].Set("max winners", 1);
|
||||
#mCapRoutes[0].Set("fez_zone", "lane_2");
|
||||
end_script_variables
|
||||
|
||||
on_init
|
||||
if (PROCESSOR.IsA_TypeOf("WSF_RIPR_PROCESSOR"))
|
||||
{
|
||||
foreach( Map<string, Object> map in mCapRoutes)
|
||||
{
|
||||
//create a "cap-route" job
|
||||
string routeName = (string) map["route name"];
|
||||
WsfGeoPoint location = (WsfGeoPoint)map["location"];
|
||||
double heading = (double) map["heading"];
|
||||
double priority = (double) map["priority"];
|
||||
int maxWinners = (int) map["max winners"];
|
||||
string zoneName = (string) map["fez_zone"];
|
||||
string unique_desc = write_str("cap-route_", routeName, "_", location.Latitude(), "_", location.Longitude());
|
||||
writeln_d("CREATING CAP ROUTE JOB: ", unique_desc);
|
||||
WsfRIPRJob temp = WsfRIPRJob.Create( ((WsfRIPRProcessor)PROCESSOR), "cap-route", unique_desc, priority, maxWinners );
|
||||
temp.SetData( "location", location );
|
||||
temp.SetData( "heading", heading );
|
||||
temp.SetData( "route name", routeName );
|
||||
temp.SetData( "for_air", 1 );
|
||||
temp.SetData( "fez_zone", zoneName);
|
||||
((WsfRIPRProcessor)PROCESSOR).AddJob(temp);
|
||||
}
|
||||
}
|
||||
end_on_init
|
||||
|
||||
precondition
|
||||
writeln_d("precondition create_cap-routes");
|
||||
if (!PROCESSOR.IsA_TypeOf("WSF_RIPR_PROCESSOR"))
|
||||
{
|
||||
return Failure("behavior not attached to a RIPR processor!");
|
||||
} //((WsfRIPRProcessor)PROCESSOR)
|
||||
return false;
|
||||
end_precondition
|
||||
|
||||
execute
|
||||
writeln_d("executing create_cap-routes");
|
||||
end_execute
|
||||
|
||||
end_behavior
|
||||
|
||||
125
processors/ripr_agents/aifl/behavior_create_point_job.txt
Normal file
125
processors/ripr_agents/aifl/behavior_create_point_job.txt
Normal file
@@ -0,0 +1,125 @@
|
||||
# ****************************************************************************
|
||||
# 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 create_point_job
|
||||
|
||||
script_debug_writes off
|
||||
|
||||
script_variables
|
||||
int maxJobWinnersForPursueTrack = 1;
|
||||
string pointJobName = "-1";
|
||||
end_script_variables
|
||||
|
||||
|
||||
on_init
|
||||
//nothing here yet
|
||||
end_on_init
|
||||
|
||||
|
||||
precondition
|
||||
writeln_d("precondition create_point_job");
|
||||
|
||||
if (!PROCESSOR.IsA_TypeOf("WSF_RIPR_PROCESSOR"))
|
||||
{
|
||||
return Failure("behavior not attached to a RIPR processor!");
|
||||
}
|
||||
|
||||
WsfRIPRProcessor commander = ((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor();
|
||||
if (!commander.IsValid())
|
||||
{
|
||||
return Failure("Agent does not have a commander to get jobs from!");
|
||||
}
|
||||
int NumSubordinates = ((WsfRIPRProcessor)PROCESSOR).GetRIPRSubordinateProcessors().Size();
|
||||
if (NumSubordinates <= 0)
|
||||
{
|
||||
return Failure("Agent has no subordinates to send to a point!");
|
||||
}
|
||||
return true;
|
||||
end_precondition
|
||||
|
||||
|
||||
execute
|
||||
writeln_d("executing create_point_job");
|
||||
|
||||
// now check the board to see what we've won!
|
||||
WsfRIPRJob currentJob = ((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor().GetJobFor(TIME_NOW, ((WsfRIPRProcessor)PROCESSOR));
|
||||
|
||||
if( currentJob.IsValid() && currentJob.Name() == "zone" )
|
||||
{
|
||||
//create a pursue-point job that allows for enough winners to send the whole squadron
|
||||
//this is useful in case some subordinates don't have a track for some of the threats
|
||||
//or if there are less threats than there are subordinates, so the whole squadron will be sent
|
||||
|
||||
string zName = (string)currentJob.GetData("ZoneName");
|
||||
WsfGeoPoint point = (WsfGeoPoint)currentJob.GetData("ZonePoint");
|
||||
if (point.IsValid())
|
||||
{
|
||||
string newPointJobName = "pursue-point-" + zName;
|
||||
WsfRIPRJob pointJob = ((WsfRIPRProcessor)PROCESSOR).GetJobByData("pointName", newPointJobName);
|
||||
if( !pointJob.IsValid() )
|
||||
{
|
||||
extern double cPursuePointPriority;
|
||||
//set max job winners to number of subordinates (so all can proceed into zone)
|
||||
int NumSubordinates = ((WsfRIPRProcessor)PROCESSOR).GetRIPRSubordinateProcessors().Size();
|
||||
pointJob = WsfRIPRJob.Create( ((WsfRIPRProcessor)PROCESSOR),
|
||||
"pursue-point",
|
||||
newPointJobName,
|
||||
cPursuePointPriority,
|
||||
NumSubordinates);
|
||||
pointJob.SetData( "targetTrackName", zName ); //hack for now, so other code here works
|
||||
pointJob.SetData( "targetPoint", point );
|
||||
pointJob.SetData( "pointName", newPointJobName );
|
||||
((WsfRIPRProcessor)PROCESSOR).AddJob(pointJob);
|
||||
writeln_d("--- ", PLATFORM.Name(), " job change, ADD: pursue-point-", zName );
|
||||
}
|
||||
else
|
||||
{
|
||||
//update the job?
|
||||
pointJob.SetData( "targetPoint" , point );
|
||||
pointJob.SetData( "targetTrackName" , zName );
|
||||
}
|
||||
if (pointJobName != newPointJobName)
|
||||
{
|
||||
//remove old point job
|
||||
WsfRIPRJob prevPointJob = ((WsfRIPRProcessor)PROCESSOR).GetJobByData("pointName", pointJobName);
|
||||
if (prevPointJob.IsValid())
|
||||
{
|
||||
writeln_d("--- ", PLATFORM.Name(), " job change, REMOVE: ", pointJobName);
|
||||
((WsfRIPRProcessor)PROCESSOR).RemoveJob(prevPointJob);
|
||||
}
|
||||
pointJobName = newPointJobName;
|
||||
}
|
||||
return; //step out of the behavior at this point, otherwise remove the job
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln(PLATFORM.Name(), " has no valid zone point, not creating pursue-point job!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d(PLATFORM.Name(), " does not have a valid zone job for a point!");
|
||||
|
||||
//remove old point job
|
||||
WsfRIPRJob prevPointJob = ((WsfRIPRProcessor)PROCESSOR).GetJobByData("pointName", pointJobName);
|
||||
writeln_d("--- ", PLATFORM.Name(), " job change, REMOVE: ", pointJobName);
|
||||
pointJobName = "-1";
|
||||
if (prevPointJob.IsValid())
|
||||
{
|
||||
writeln_d("--- ", PLATFORM.Name(), " job change, REMOVE: ", pointJobName);
|
||||
((WsfRIPRProcessor)PROCESSOR).RemoveJob(prevPointJob);
|
||||
}
|
||||
}
|
||||
|
||||
end_execute
|
||||
|
||||
end_behavior
|
||||
|
||||
127
processors/ripr_agents/aifl/behavior_create_target_jobs_self.txt
Normal file
127
processors/ripr_agents/aifl/behavior_create_target_jobs_self.txt
Normal file
@@ -0,0 +1,127 @@
|
||||
# ****************************************************************************
|
||||
# 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 create_target_jobs_self
|
||||
|
||||
script_debug_writes off
|
||||
|
||||
|
||||
script_variables
|
||||
WsfRIPRJob mMyJob;
|
||||
int maxJobWinnersForPursueTrack = 1;
|
||||
end_script_variables
|
||||
|
||||
|
||||
on_init
|
||||
|
||||
end_on_init
|
||||
|
||||
|
||||
precondition
|
||||
writeln_d("precondition create_target_jobs_self");
|
||||
|
||||
writeln_d("precondition radar-control");
|
||||
if (!PROCESSOR.IsA_TypeOf("WSF_RIPR_PROCESSOR"))
|
||||
{
|
||||
return Failure("behavior not attached to a RIPR processor!");
|
||||
}
|
||||
|
||||
//this behavior should probably always run, because it
|
||||
//removes stale jobs from old tracks that have gone away
|
||||
|
||||
return true;
|
||||
end_precondition
|
||||
|
||||
|
||||
execute
|
||||
writeln_d("executing create_target_jobs_self");
|
||||
|
||||
WsfLocalTrackList localTracks = PLATFORM.MasterTrackList();
|
||||
Map<string, int> updatedTracks = Map<string, int>();
|
||||
|
||||
writeln_d(" Flight Lead, Considering Num Tracks: ", localTracks.Count() );
|
||||
|
||||
foreach (WsfTrack x in localTracks)
|
||||
{
|
||||
// if the track is not a foe or is damaged, we'll ignore it
|
||||
if (!(x.IsValid()))
|
||||
{
|
||||
writeln_d("!!! Need to remove track: not valid!");
|
||||
continue;
|
||||
}
|
||||
|
||||
WsfTrackId tid = x.TrackId();
|
||||
writeln_d(" Considering: ", tid.Name(), ".", tid.Number(), " -> ", x.TargetName());
|
||||
updatedTracks.Set(x.TargetName(), 0);
|
||||
|
||||
if (x.IFF_Friend())
|
||||
{
|
||||
writeln_d("!!! Need to remove track: IFF FRIEND!");
|
||||
continue;
|
||||
}
|
||||
if (x.SideValid() && x.Side() == PLATFORM.Side())
|
||||
{
|
||||
writeln_d("!!! Need to remove track: SAME SIDE!");
|
||||
continue;
|
||||
}
|
||||
|
||||
#extern string DetermineTrackCategory(WsfTrack);
|
||||
string category = DetermineTrackCategory(x);
|
||||
|
||||
if (category == "unknown")
|
||||
{
|
||||
writeln_d(" - Unknown type: ", x.TargetName(), " - ", x.TargetType() );
|
||||
continue;
|
||||
}
|
||||
|
||||
updatedTracks.Set(x.TargetName(), 1);
|
||||
|
||||
WsfRIPRJob job = ((WsfRIPRProcessor)PROCESSOR).GetJobByData("targetTrackName", x.TargetName());
|
||||
if (job.IsValid())
|
||||
{
|
||||
//update the already existing job
|
||||
job.SetData("targetLocation", x.CurrentLocation());
|
||||
}
|
||||
else
|
||||
{
|
||||
//create a job for this track
|
||||
extern double cPursueTargetPriority;
|
||||
WsfRIPRJob temp = WsfRIPRJob.Create( ((WsfRIPRProcessor)PROCESSOR),
|
||||
"pursue-target",
|
||||
"pursue-target-" + x.TargetName(),
|
||||
cPursueTargetPriority,
|
||||
maxJobWinnersForPursueTrack);
|
||||
temp.SetData("targetTrack", x);
|
||||
temp.SetData("targetTrackName", x.TargetName());
|
||||
temp.SetData("targetLocation", x.CurrentLocation());
|
||||
writeln_d(" - Adding job");
|
||||
((WsfRIPRProcessor)PROCESSOR).AddJob(temp);
|
||||
writeln_d("--- ", PLATFORM.Name(), " job change, ADD: ", temp.GetDescription() );
|
||||
PLATFORM.Comment(write_str("AIFL - new job: ", temp.GetDescription()));
|
||||
}
|
||||
}
|
||||
|
||||
Array<WsfRIPRJob> jobs = ((WsfRIPRProcessor)PROCESSOR).GetJobs();
|
||||
foreach (WsfRIPRJob x in jobs)
|
||||
{
|
||||
string name = (string)x.GetData("targetTrackName");
|
||||
if (updatedTracks[name] == 0 && x.Name() == "pursue-target")
|
||||
{
|
||||
string temp = write_str("--- ", PLATFORM.Name(), " job change, REMOVE: ", x.GetDescription());
|
||||
writeln_d(temp);
|
||||
PLATFORM.Comment(temp);
|
||||
((WsfRIPRProcessor)PROCESSOR).RemoveJob(x);
|
||||
}
|
||||
}
|
||||
|
||||
end_execute
|
||||
|
||||
end_behavior
|
||||
173
processors/ripr_agents/aifl/behavior_interpret_flank_jobs.txt
Normal file
173
processors/ripr_agents/aifl/behavior_interpret_flank_jobs.txt
Normal file
@@ -0,0 +1,173 @@
|
||||
# ****************************************************************************
|
||||
# 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 interpret_flank_jobs
|
||||
|
||||
script_debug_writes off
|
||||
|
||||
script_variables
|
||||
WsfDraw draw = WsfDraw();
|
||||
bool mDrawFlankLines = false;
|
||||
WsfRIPRJob mMyJob;
|
||||
end_script_variables
|
||||
|
||||
|
||||
on_init
|
||||
draw.SetLineSize(2);
|
||||
draw.SetColor(1.0, 0.0, 1.0); //purple
|
||||
end_on_init
|
||||
|
||||
|
||||
precondition
|
||||
|
||||
if (!PROCESSOR.IsA_TypeOf("WSF_RIPR_PROCESSOR"))
|
||||
{
|
||||
return Failure("behavior not attached to a RIPR processor!");
|
||||
}
|
||||
|
||||
writeln_d("precondition interpret_flank_jobs");
|
||||
draw.SetDuration(PROCESSOR.UpdateInterval());
|
||||
WsfRIPRProcessor commander = ((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor();
|
||||
if (commander.IsValid())
|
||||
{
|
||||
mMyJob = commander.GetJobFor(TIME_NOW, ((WsfRIPRProcessor)PROCESSOR));
|
||||
if (mMyJob.IsValid() && mMyJob.Name() == "flank")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//remove any jobs this behavior created
|
||||
Array<WsfRIPRJob> jobs = ((WsfRIPRProcessor)PROCESSOR).GetJobs();
|
||||
foreach (WsfRIPRJob job in jobs)
|
||||
{
|
||||
if (job.IsValid() && job.Data().Exists("flankPointName"))
|
||||
{
|
||||
//its a valid flank point job created by this behavior, remove it
|
||||
((WsfRIPRProcessor)PROCESSOR).RemoveJob(job);
|
||||
}
|
||||
}
|
||||
|
||||
extern Map<int, WsfGeoPoint> mFlankJobIdToFlankPointMap;
|
||||
mFlankJobIdToFlankPointMap.Clear();
|
||||
|
||||
return Failure("Agent does not have a flank job!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failure("Agent does not have a commander!");
|
||||
}
|
||||
end_precondition
|
||||
|
||||
|
||||
execute
|
||||
writeln_d("executing interpret_flank_jobs");
|
||||
|
||||
WsfGeoPoint zonePoint = (WsfGeoPoint)mMyJob.GetData("ZonePoint");
|
||||
double zoneBearing = (double) mMyJob.GetData("ZoneBearing");
|
||||
bool bearingValid = (bool) mMyJob.GetData("ZoneBearingValid");
|
||||
WsfZone flankZone = (WsfZone) mMyJob.GetData("FlankZone");
|
||||
double flankDist = (double) mMyJob.GetData("FlankDistance");
|
||||
string zoneName = (string) mMyJob.GetData("ZoneName");
|
||||
|
||||
#extern Map<int, WsfGeoPoint> mFlankJobIdToFlankPointMap;
|
||||
WsfGeoPoint flankPoint = mFlankJobIdToFlankPointMap.Get( mMyJob.GetId() );
|
||||
|
||||
if (mDrawFlankLines)
|
||||
{
|
||||
//draw the outline of the flank zone
|
||||
flankZone.DebugDrawZone(zonePoint, zoneBearing*MATH.RAD_PER_DEG());
|
||||
|
||||
//draw flank point of interest (target we are flanking), white dot
|
||||
draw.BeginPoints();
|
||||
draw.SetColor(1.0, 1.0, 1.0);
|
||||
draw.Vertex(zonePoint);
|
||||
draw.End();
|
||||
|
||||
if (bearingValid)
|
||||
{
|
||||
//cluster heading is with reference to east (instead of north), so subtract 90 degrees
|
||||
#doulbe clusterBearingTrue = MATH.NormalizeAngle0_360( zoneBearing - 90.0 );
|
||||
double clusterBearingTrue = MATH.NormalizeAngle0_360( zoneBearing );
|
||||
|
||||
WsfGeoPoint bPoint = WsfGeoPoint(zonePoint);
|
||||
bPoint.Extrapolate( clusterBearingTrue, flankDist );
|
||||
|
||||
//draw red-orange line to represent heading of target's flight
|
||||
draw.BeginLines();
|
||||
draw.SetColor(1.0, 0.3, 0.1);
|
||||
draw.Vertex(zonePoint);
|
||||
draw.Vertex(bPoint);
|
||||
draw.End();
|
||||
}
|
||||
|
||||
//draw green line to the flank point (the side we are flying towards)
|
||||
draw.BeginLines();
|
||||
draw.SetColor(0.1, 1.0, 0.4);
|
||||
draw.Vertex(zonePoint);
|
||||
draw.Vertex(flankPoint);
|
||||
draw.End();
|
||||
}
|
||||
|
||||
//see if any subordinates are in the flank zone, if they are... flanking is done
|
||||
foreach( WsfPlatform sub in PLATFORM.Subordinates() )
|
||||
{
|
||||
if (flankZone.PointIsInside(sub.Location(), zonePoint, zoneBearing*MATH.RAD_PER_DEG(), 0.0))
|
||||
{
|
||||
writeln_d( "@@@ aifl subordinate ", sub.Name(), " inside flank zone!");
|
||||
mMyJob.SetProgress( ((WsfRIPRProcessor)PROCESSOR), 1.0 ); #mark the job as complete
|
||||
}
|
||||
}
|
||||
|
||||
int NumSubordinates = PLATFORM.Subordinates().Count();
|
||||
|
||||
//if flank job doesn't exist yet, create it
|
||||
WsfRIPRJob job = ((WsfRIPRProcessor)PROCESSOR).GetJobByData("flankPointName", zoneName);
|
||||
if( ! job.IsValid() )
|
||||
{
|
||||
if (NumSubordinates > 0)
|
||||
{
|
||||
extern double cFlankPointPriority;
|
||||
//set max job winners to number of subordinates (so all can proceed into zone)
|
||||
WsfRIPRJob temp = WsfRIPRJob.Create( ((WsfRIPRProcessor)PROCESSOR),
|
||||
"pursue-point",
|
||||
"pursue-point-" + zoneName,
|
||||
cFlankPointPriority,
|
||||
NumSubordinates);
|
||||
temp.SetData( "targetTrackName", zoneName ); //hack for now, so other code here works
|
||||
temp.SetData( "targetPoint", flankPoint );
|
||||
temp.SetData( "flankPointName", zoneName );
|
||||
((WsfRIPRProcessor)PROCESSOR).AddJob(temp);
|
||||
writeln_d("--- ", PLATFORM.Name(), " job change, ADD: ", zoneName );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
job.SetData( "targetPoint" , flankPoint );
|
||||
writeln_d(" aiFL - updated flank pursue-point job ", zoneName, ", ( ", flankPoint.Latitude(), ", ", flankPoint.Longitude(), " )" );
|
||||
}
|
||||
|
||||
//remove all jobs that aren't involved with flanking
|
||||
Array<WsfRIPRJob> jobs = ((WsfRIPRProcessor)PROCESSOR).GetJobs();
|
||||
foreach (WsfRIPRJob x in jobs)
|
||||
{
|
||||
string name = (string)x.GetData("targetTrackName");
|
||||
if ( name != zoneName )
|
||||
{
|
||||
writeln_d("--- ", PLATFORM.Name(), " job change, REMOVE: ", name);
|
||||
((WsfRIPRProcessor)PROCESSOR).RemoveJob(x);
|
||||
}
|
||||
}
|
||||
|
||||
end_execute
|
||||
|
||||
end_behavior
|
||||
119
processors/ripr_agents/aifl/behavior_interpret_zone_jobs.txt
Normal file
119
processors/ripr_agents/aifl/behavior_interpret_zone_jobs.txt
Normal file
@@ -0,0 +1,119 @@
|
||||
# ****************************************************************************
|
||||
# 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 behavior will be the only one in an agents tree that bids on "zone" jobs (compiler error otherwise)
|
||||
//this behavior should be the only one in an agents tree that creates "pursue-target" jobs when it runs (unexplained behavior otherwise)
|
||||
//in other words... if other behaviors also create "pursue-target" jobs, they should all be under a selector node, so only 1 runs on any update
|
||||
|
||||
|
||||
behavior interpret_zone_jobs
|
||||
|
||||
script_debug_writes off
|
||||
|
||||
|
||||
script_variables
|
||||
int maxJobWinnersForPursueTrack = 1;
|
||||
WsfRIPRJob mCurrentJob;
|
||||
end_script_variables
|
||||
|
||||
|
||||
on_init
|
||||
//nothing here yet
|
||||
end_on_init
|
||||
|
||||
|
||||
precondition
|
||||
writeln_d("precondition interpret_zone_jobs");
|
||||
|
||||
if (!PROCESSOR.IsA_TypeOf("WSF_RIPR_PROCESSOR"))
|
||||
{
|
||||
return Failure("behavior not attached to a RIPR processor!");
|
||||
}
|
||||
|
||||
if (((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor().IsValid())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failure("Agent does not have a commander to get jobs from!");
|
||||
}
|
||||
end_precondition
|
||||
|
||||
|
||||
|
||||
execute
|
||||
writeln_d(PLATFORM.Name(), " executing interpret_zone_jobs, T=", TIME_NOW);
|
||||
|
||||
// now check the board to see what we've won!
|
||||
Map<string, int> updatedTracks = Map<string, int>();
|
||||
WsfRIPRProcessor commander = ((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor();
|
||||
|
||||
if (commander.IsJobWindowOpen())
|
||||
{
|
||||
//we can get a new job for ourselves here
|
||||
mCurrentJob = commander.GetJobFor(TIME_NOW, ((WsfRIPRProcessor)PROCESSOR));
|
||||
}
|
||||
else if (commander.IsBidWindowOpen())
|
||||
{
|
||||
//we dont update our own job board until here
|
||||
if( mCurrentJob.IsValid() && mCurrentJob.Name() == "zone" )
|
||||
{
|
||||
Array<string> targetNames = (Array<string>)mCurrentJob.GetData("ZoneThreatNameArray");
|
||||
writeln_d(PLATFORM.Name(), " targetNames.Size() = ", targetNames.Size());
|
||||
foreach(string targetName in targetNames)
|
||||
{
|
||||
WsfPlatform target = WsfSimulation.FindPlatform(targetName);
|
||||
if (target.IsValid())
|
||||
{
|
||||
updatedTracks.Set( targetName, 1 );
|
||||
|
||||
WsfRIPRJob job = ((WsfRIPRProcessor)PROCESSOR).GetJobByData("targetTrackName", targetName);
|
||||
if (job.IsValid())
|
||||
{
|
||||
//just update it, it already exists
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
extern double cPursueTargetPriority;
|
||||
WsfRIPRJob temp = WsfRIPRJob.Create(((WsfRIPRProcessor)PROCESSOR),
|
||||
"pursue-target",
|
||||
"pursue-target-" + targetName,
|
||||
cPursueTargetPriority,
|
||||
maxJobWinnersForPursueTrack);
|
||||
temp.SetData("targetTrackName", targetName);
|
||||
((WsfRIPRProcessor)PROCESSOR).AddJob(temp);
|
||||
writeln_d("--- ", PLATFORM.Name(), " job change, ADD: ", targetName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d("--- currentJob not a valid zone job!!!!! Removing all my aifl jobs.");
|
||||
}
|
||||
|
||||
Array<WsfRIPRJob> jobs = ((WsfRIPRProcessor)PROCESSOR).GetJobs();
|
||||
foreach (WsfRIPRJob x in jobs)
|
||||
{
|
||||
string name = (string)x.GetData("targetTrackName");
|
||||
if (updatedTracks.Get(name) != 1 && x.Name() == "pursue-target")
|
||||
{
|
||||
writeln_d("--- ", PLATFORM.Name(), " job change, REMOVE: ", name);
|
||||
((WsfRIPRProcessor)PROCESSOR).RemoveJob(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end_execute
|
||||
|
||||
end_behavior
|
||||
342
processors/ripr_agents/aifl/behavior_manage-pincer.txt
Normal file
342
processors/ripr_agents/aifl/behavior_manage-pincer.txt
Normal file
@@ -0,0 +1,342 @@
|
||||
# ****************************************************************************
|
||||
# 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 manage-pincer
|
||||
|
||||
script_debug_writes off
|
||||
|
||||
script_variables
|
||||
|
||||
//for debugging
|
||||
bool mDrawClusters = false;
|
||||
|
||||
//parameters used to determine if a pincer is appropriate
|
||||
bool mRequireActiveWeapons = false; //if true, weapons must be in flight before pincer performed
|
||||
double mMaxSeparationAngle = 120.0; //degrees (pincer done if we've flanked by this much)
|
||||
int mNumSubsInvolved = 2; //not necessary to be an even number
|
||||
double mThresholdDistance = 160 * 1852; //160nm
|
||||
//clustering is performed to make sure the group of threats we are pincering against are grouped tightly together
|
||||
//if more than one group exist, the 2nd, 3rd, etc... groups have to be far enough away so that they aren't a
|
||||
//concern for the pincer maneuver (i.e. we wont head into them by separating around the target group)
|
||||
string mClusterMethod = "HTREEMAX"; //also valid: K_MEANS, H_TREE_MIN
|
||||
double mClusterDistanceLimit = 20*1852; //20nm - how close the group members have to be together
|
||||
double mMinDistanceRatio = 1.15; //other groups have to be 15% farther away than target group
|
||||
|
||||
// parameters useful for those performing the pincer
|
||||
bool mCross = false;
|
||||
string mCapZoneName = ""; //useful to specify the name of zone in which we ignore the threat's
|
||||
//orientation, because they are capping while in the zone
|
||||
|
||||
// script variables, used by methods below, do not change, not for user edit
|
||||
Array<WsfTrack> mTrackArray = Array<WsfTrack>();
|
||||
Array<string> mTargetNames = Array<string>();
|
||||
WsfDraw mDraw = WsfDraw();
|
||||
double mMeanBearing = 0;
|
||||
bool mMeanBearingValid = false;
|
||||
WsfClusterManager mClusterManager;
|
||||
WsfRIPRJob mPincerJob;
|
||||
WsfGeoPoint mMeanPoint;
|
||||
WsfGeoPoint mSubPoint;
|
||||
end_script_variables
|
||||
|
||||
|
||||
on_init
|
||||
mClusterManager = WsfClusterManager.Create(); // creates a cluster manager owned by this script
|
||||
mClusterManager.SetClusterMethod(mClusterMethod); // default is: "K_MEANS"
|
||||
mClusterManager.SetDistanceFunction("POSITION_VELOCITY"); // default is: "POSITION_ONLY"
|
||||
mClusterManager.SetDistanceLimit(mClusterDistanceLimit) ;
|
||||
end_on_init
|
||||
|
||||
## utility method used to draw lines around tracks in a cluster ## lines are drawn according to the convex hull of the cluster members
|
||||
script void draw_cluster_hull(WsfCluster cluster)
|
||||
Array<WsfGeoPoint> pts = cluster.ConvexHull();
|
||||
if (pts.Size() <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
WsfGeoPoint first = pts.Get(0);
|
||||
mDraw.SetColor(1.0,0.5,0.0); //orange?
|
||||
mDraw.SetLineStyle("solid");
|
||||
mDraw.SetLineSize(2);
|
||||
mDraw.BeginPolyline();
|
||||
for (int j = 0; j < pts.Size(); j = j + 1 )
|
||||
{
|
||||
WsfGeoPoint pt = pts.Get(j);
|
||||
mDraw.Vertex(pt);
|
||||
}
|
||||
mDraw.Vertex(first);
|
||||
mDraw.End();
|
||||
if (cluster.BearingValid())
|
||||
{
|
||||
double bearing = cluster.Bearing();
|
||||
WsfGeoPoint pt = cluster.MeanLocation();
|
||||
mDraw.SetColor(1.0,1.0,1.0); //white?
|
||||
mDraw.BeginLines();
|
||||
mDraw.Vertex(pt); pt.Extrapolate(cluster.Bearing(), 92600); //50 nautical miles
|
||||
mDraw.Vertex(pt);
|
||||
mDraw.End();
|
||||
}
|
||||
end_script
|
||||
|
||||
script WsfGeoPoint MeanLocation(Array<WsfPlatform> plats)
|
||||
Vec3 mean = Vec3.Construct(0, 0, 0);
|
||||
if (plats.Size() > 0)
|
||||
{
|
||||
double scale = 1.0/((double)plats.Size());
|
||||
foreach(WsfPlatform plat in plats)
|
||||
{
|
||||
Vec3 temp = plat.LocationWCS();
|
||||
temp.Scale(scale);
|
||||
mean = Vec3.Add(mean, temp);
|
||||
}
|
||||
}
|
||||
return WsfGeoPoint.ConstructWCS(mean);
|
||||
end_script
|
||||
|
||||
script WsfGeoPoint SubordinatesMeanLocation()
|
||||
return MeanLocation(((WsfRIPRProcessor)PROCESSOR).SubordinatePlatforms());
|
||||
end_script
|
||||
|
||||
script void RemovePincerJob()
|
||||
if(mPincerJob.IsValid())
|
||||
{
|
||||
//remove job from board
|
||||
WsfRIPRJob fake;
|
||||
writeln_d(PLATFORM.Name(), " job change, REMOVE: ", mPincerJob.GetDescription());
|
||||
PLATFORM.Comment(write_str("REMOVE job: ", mPincerJob.GetDescription()));
|
||||
((WsfRIPRProcessor)PROCESSOR).RemoveJob(mPincerJob);
|
||||
mPincerJob = fake;
|
||||
}
|
||||
end_script
|
||||
|
||||
|
||||
|
||||
precondition
|
||||
|
||||
#writeln_d("precondition manage-pincer");
|
||||
if (!PROCESSOR.IsA_TypeOf("WSF_RIPR_PROCESSOR"))
|
||||
{
|
||||
return Failure("behavior not attached to a RIPR processor!");
|
||||
} //((WsfRIPRProcessor)PROCESSOR)
|
||||
|
||||
if (((WsfRIPRProcessor)PROCESSOR).SubordinateProcessors().Size() < mNumSubsInvolved)
|
||||
{
|
||||
RemovePincerJob();
|
||||
writeln_d("not enough subordinates");
|
||||
return Failure("not enough subordinates");
|
||||
}
|
||||
|
||||
if (mRequireActiveWeapons)
|
||||
{
|
||||
int weaponCount = 0;
|
||||
Array<WsfRIPRProcessor> subs = ((WsfRIPRProcessor)PROCESSOR).SubordinateProcessors();
|
||||
foreach(WsfRIPRProcessor proc in subs)
|
||||
{
|
||||
weaponCount = weaponCount + proc.WeaponsActive();
|
||||
}
|
||||
if (weaponCount <= 0)
|
||||
{
|
||||
RemovePincerJob();
|
||||
writeln_d("no active weapons, no pincer yet");
|
||||
return Failure("no active weapons, no pincer yet");
|
||||
}
|
||||
}
|
||||
|
||||
mSubPoint = SubordinatesMeanLocation();
|
||||
|
||||
#extern bool TestTrackCategory(WsfTrack, string);
|
||||
mTrackArray.Clear();
|
||||
mTargetNames.Clear();
|
||||
foreach (WsfLocalTrack track in PLATFORM.MasterTrackList())
|
||||
{
|
||||
if ( (track.IFF_Friend()) ||
|
||||
(track.SideValid() && track.Side() == PLATFORM.Side()) ||
|
||||
(! track. LocationValid() ) ||
|
||||
(track.SlantRangeTo(mSubPoint) > mThresholdDistance) ||
|
||||
(TestTrackCategory(track, "unknown")) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
track.SetBearing( track.Heading() ); #useful for the cluster processing
|
||||
mTrackArray.PushBack(track);
|
||||
mTargetNames.PushBack(track.TargetName());
|
||||
}
|
||||
|
||||
if (mTrackArray.Size() > 0)
|
||||
{
|
||||
mClusterManager.UpdateClusters(TIME_NOW,mTrackArray);
|
||||
if (mDrawClusters == true)
|
||||
{
|
||||
for (int i = 0; i < mClusterManager.Count(); i = i + 1 )
|
||||
{
|
||||
draw_cluster_hull(mClusterManager.Entry(i));
|
||||
}
|
||||
}
|
||||
|
||||
if (mClusterManager.Count() > 1)
|
||||
{
|
||||
//check distances
|
||||
double near = MATH.DOUBLE_MAX();
|
||||
double near2 = MATH.DOUBLE_MAX();
|
||||
|
||||
for (int i = 0; i < mClusterManager.Count(); i = i + 1 )
|
||||
{
|
||||
double dist = mClusterManager.Entry(i).MeanLocation().SlantRangeTo(mSubPoint);
|
||||
if (dist < near)
|
||||
{
|
||||
if (near < near2)
|
||||
{
|
||||
near2 = near;
|
||||
}
|
||||
near = dist;
|
||||
}
|
||||
else if (dist < near2)
|
||||
{
|
||||
near2 = dist;
|
||||
}
|
||||
}
|
||||
|
||||
double ratio = near2/near;
|
||||
if (ratio < mMinDistanceRatio)
|
||||
{
|
||||
RemovePincerJob();
|
||||
writeln_d("threats too spread out!");
|
||||
return Failure("threats too spread out!");
|
||||
}
|
||||
}
|
||||
|
||||
WsfCluster cluster = mClusterManager.Entry(0);
|
||||
mMeanPoint = cluster.MeanLocation();
|
||||
mMeanBearingValid = cluster.BearingValid();
|
||||
mMeanBearing = cluster.Bearing();
|
||||
}
|
||||
else //no threats to pincer against, exit out
|
||||
{
|
||||
RemovePincerJob();
|
||||
writeln_d("no threats to pincer against yet!");
|
||||
return Failure("no threats to pincer against yet!");
|
||||
}
|
||||
|
||||
//check separation of all subordinates
|
||||
//only relavent if not currently in phase 2 (dragging & chasing)
|
||||
int dragging = 0;
|
||||
if(mPincerJob.IsValid())
|
||||
{
|
||||
dragging = (int)mPincerJob.GetData("left_drag") + (int)mPincerJob.GetData("right_drag");
|
||||
}
|
||||
if (dragging == 0)
|
||||
{
|
||||
Array<WsfPlatform> subs = ((WsfRIPRProcessor)PROCESSOR).SubordinatePlatforms();
|
||||
WsfGeoPoint subMean = MeanLocation(subs);
|
||||
double standard = mMeanPoint.TrueBearingTo(subMean);
|
||||
double min = 361;
|
||||
double max = -361;
|
||||
foreach(WsfPlatform p in subs)
|
||||
{
|
||||
double b = MATH.NormalizeAngleMinus180_180(mMeanPoint.TrueBearingTo(p.Location()) - standard);
|
||||
min = MATH.Min(min, b);
|
||||
max = MATH.Max(max, b);
|
||||
}
|
||||
double diff = max - min;
|
||||
if (diff >= mMaxSeparationAngle)
|
||||
{
|
||||
RemovePincerJob();
|
||||
writeln_d("pincer complete, targets flanked!");
|
||||
return Failure("pincer complete, targets flanked!");
|
||||
}
|
||||
}
|
||||
|
||||
mDraw.SetDuration(PROCESSOR.UpdateInterval());
|
||||
return true;
|
||||
end_precondition
|
||||
|
||||
|
||||
|
||||
execute
|
||||
writeln_d("executing manage-pincer, T=", TIME_NOW);
|
||||
//first find the group of target(s) we are going to perform the pincer against
|
||||
//generate a list of their names and get their mean location
|
||||
Array<WsfRIPRProcessor> subs = ((WsfRIPRProcessor)PROCESSOR).SubordinateProcessors();
|
||||
int N = subs.Size();
|
||||
if (mPincerJob.IsValid())
|
||||
{
|
||||
//pincer job already created! just update it
|
||||
mPincerJob.SetData("ZoneThreatNameArray", mTargetNames);
|
||||
mPincerJob.SetData("ZonePoint", mMeanPoint);
|
||||
mPincerJob.SetData("ZoneBearingValid", mMeanBearingValid);
|
||||
mPincerJob.SetData("ZoneBearing", mMeanBearing);
|
||||
mPincerJob.SetData("all_on_cap", 0);
|
||||
|
||||
if (mCapZoneName != "" && mPincerJob.IsValid())
|
||||
{
|
||||
bool allOnCap = true;
|
||||
foreach(WsfTrack t in mTrackArray)
|
||||
{
|
||||
if ( ! t.ReportedLocation().WithinZone(mCapZoneName))
|
||||
{
|
||||
allOnCap = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (allOnCap)
|
||||
{
|
||||
mPincerJob.SetData("all_on_cap", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//create a pincer job for this flight group
|
||||
string desc = write_str("pincer-", mNumSubsInvolved);
|
||||
extern double cPincerPriority;
|
||||
mPincerJob = WsfRIPRJob.Create( ((WsfRIPRProcessor)PROCESSOR), //creator
|
||||
"pincer", //name
|
||||
desc, //description
|
||||
cPincerPriority * mNumSubsInvolved, //priority (must be enough to break even with "mNumSubsInvolved" jobs of another type
|
||||
mNumSubsInvolved); //max winnners
|
||||
mPincerJob.SetData("ZoneThreatNameArray", mTargetNames);
|
||||
mPincerJob.SetData("ZonePoint", mMeanPoint);
|
||||
mPincerJob.SetData("ZoneBearingValid", mMeanBearingValid);
|
||||
mPincerJob.SetData("ZoneBearing", mMeanBearing);
|
||||
mPincerJob.SetData("left_drag", 0);
|
||||
mPincerJob.SetData("rightdrag", 0);
|
||||
mPincerJob.SetData("all_on_cap", 0);
|
||||
mPincerJob.SetWinnersMin(mNumSubsInvolved);
|
||||
//setup the left & right flyers
|
||||
double avgBearing = mMeanPoint.TrueBearingTo(mSubPoint);
|
||||
foreach(WsfRIPRProcessor proc in subs)
|
||||
{
|
||||
//Vec3 temp = proc.Platform().LocationWCS();
|
||||
double bearing = mMeanPoint.TrueBearingTo(proc.Platform().Location());
|
||||
double relAngle = MATH.NormalizeAngleMinus180_180(bearing-avgBearing);
|
||||
if (mCross)
|
||||
{
|
||||
relAngle = -1 * relAngle;
|
||||
}
|
||||
if (relAngle < 0)
|
||||
{
|
||||
mPincerJob.SetData(proc.Platform().Name(), "right");
|
||||
}
|
||||
else
|
||||
{
|
||||
mPincerJob.SetData(proc.Platform().Name(), "left");
|
||||
}
|
||||
}
|
||||
((WsfRIPRProcessor)PROCESSOR).AddJob(mPincerJob);
|
||||
writeln_d("--- ", PLATFORM.Name(), " job change, ADD: ", mPincerJob.GetDescription() );
|
||||
PLATFORM.Comment(write_str("ADD job: ", mPincerJob.GetDescription()));
|
||||
# foreach(string tgt in mTargetNames)
|
||||
# {
|
||||
# PLATFORM.Comment(tgt);
|
||||
# }
|
||||
}
|
||||
end_execute
|
||||
|
||||
end_behavior
|
||||
58
processors/ripr_agents/aifl/behavior_manage-uplinks.txt
Normal file
58
processors/ripr_agents/aifl/behavior_manage-uplinks.txt
Normal file
@@ -0,0 +1,58 @@
|
||||
# ****************************************************************************
|
||||
# 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.
|
||||
# ****************************************************************************
|
||||
|
||||
|
||||
##############################################################################
|
||||
### assumes exists: #extern WsfTrack GetTrackByName(WsfPlatform, string);
|
||||
##############################################################################
|
||||
|
||||
behavior manage-uplinks
|
||||
|
||||
script_debug_writes off
|
||||
|
||||
script_variables
|
||||
//agent constants
|
||||
end_script_variables
|
||||
|
||||
precondition
|
||||
writeln_d("precondition manage-uplinks");
|
||||
if (!PROCESSOR.IsA_TypeOf("WSF_RIPR_PROCESSOR"))
|
||||
{
|
||||
return Failure("behavior not attached to a RIPR processor!");
|
||||
} //((WsfRIPRProcessor)PROCESSOR)
|
||||
return true;
|
||||
end_precondition
|
||||
|
||||
#on_init
|
||||
#end_on_init
|
||||
|
||||
execute
|
||||
writeln_d("executing manage-uplinks");
|
||||
Array<WsfRIPRJob> jobs = ((WsfRIPRProcessor)PROCESSOR).GetJobs();
|
||||
foreach (WsfRIPRJob job in jobs)
|
||||
{
|
||||
if (job.Name() == "weapon_uplink")
|
||||
{
|
||||
int weaponPlatformIndex = (int)job.GetData("weaponPlatformIndex");
|
||||
int targetPlatformIndex = (int)job.GetData("targetPlatformIndex");
|
||||
WsfPlatform weaponPlatform = WsfSimulation.FindPlatform(weaponPlatformIndex);
|
||||
WsfPlatform targetPlatform = WsfSimulation.FindPlatform(targetPlatformIndex);
|
||||
if (!weaponPlatform.IsValid() || !targetPlatform.IsValid())
|
||||
{
|
||||
//either the weapon is gone or the target is gone, so the uplink is no longer needed, remove the job
|
||||
string msg = write_str("weapon or target for ", job.GetDescription(), " is gone, remove job");
|
||||
writeln_d(msg);
|
||||
PLATFORM.Comment(msg);
|
||||
((WsfRIPRProcessor)PROCESSOR).RemoveJob(job);
|
||||
}
|
||||
}
|
||||
}
|
||||
end_execute
|
||||
|
||||
end_behavior
|
||||
66
processors/ripr_agents/aifl/behavior_toggle_windows.txt
Normal file
66
processors/ripr_agents/aifl/behavior_toggle_windows.txt
Normal file
@@ -0,0 +1,66 @@
|
||||
# ****************************************************************************
|
||||
# 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 toggle_windows
|
||||
|
||||
script_debug_writes off
|
||||
|
||||
|
||||
script_variables
|
||||
int mToggleAfterThisManyUpdates = 1;
|
||||
int mToggleCounter;
|
||||
end_script_variables
|
||||
|
||||
|
||||
on_init
|
||||
mToggleCounter = mToggleAfterThisManyUpdates;
|
||||
end_on_init
|
||||
|
||||
|
||||
precondition
|
||||
writeln_d("precondition toggle_windows");
|
||||
if (!PROCESSOR.IsA_TypeOf("WSF_RIPR_PROCESSOR"))
|
||||
{
|
||||
return Failure("behavior not attached to a RIPR processor!");
|
||||
} //((WsfRIPRProcessor)PROCESSOR)
|
||||
//this behavior should probably always run, windows can always be toggled
|
||||
return true;
|
||||
end_precondition
|
||||
|
||||
|
||||
execute
|
||||
writeln_d("executing toggle_windows");
|
||||
|
||||
if (mToggleCounter <=0)
|
||||
{
|
||||
mToggleCounter = mToggleAfterThisManyUpdates;
|
||||
|
||||
if (((WsfRIPRProcessor)PROCESSOR).IsJobWindowOpen())
|
||||
{
|
||||
((WsfRIPRProcessor)PROCESSOR).SetJobWindowOpen(false);
|
||||
((WsfRIPRProcessor)PROCESSOR).SetBidWindowOpen(true);
|
||||
writeln_d(PLATFORM.Name(), " job window closed / bid window opened, time=", TIME_NOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
((WsfRIPRProcessor)PROCESSOR).SetJobWindowOpen(true);
|
||||
((WsfRIPRProcessor)PROCESSOR).SetBidWindowOpen(false);
|
||||
writeln_d(PLATFORM.Name(), " job window opened / bid window closed, time=", TIME_NOW);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mToggleCounter = mToggleCounter - 1;
|
||||
}
|
||||
|
||||
end_execute
|
||||
|
||||
end_behavior
|
||||
Reference in New Issue
Block a user