Files
lab1/processors/quantum_agents/aigci/gci_quantum_tasker.txt

207 lines
8.9 KiB
Plaintext
Raw Normal View History

2025-09-12 15:20:28 +08:00
# ****************************************************************************
# 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.
# ****************************************************************************
processor GCI_QUANTUM_TASKER WSF_QUANTUM_TASKER_PROCESSOR
update_interval 10.0 sec
script_variables
##########################################################################
## user parameters, change these at will
##########################################################################
bool mDrawClusters = false;
bool mRequireTasking = false;
int mMaxTaskPerformers = 1;
string mClusterMethod = "H_TREE_MAX"; //valid: K_MEANS, H_TREE_MIN, H_TREE_MAX
string mDistanceFunction = "POSITION_VELOCITY"; //valid: POSITION_VELOCITY, POSITION_ONLY, 2D_POSITION
double mClusterDistanceLimit = 50*1852; // ~50 nautical miles
int mNumClusters = -1; //not used unless positive (over-rides distance limit)
double mClusterJobPriority = 1; //if set to zero or less, then number of cluster occupants will be the priority
##########################################################################
## script variables, used by methods below, do not change
##########################################################################
WsfDraw draw = WsfDraw();
WsfClusterManager cManager;
end_script_variables
on_initialize
cManager = WsfClusterManager.Create(); // creates a cluster manager owned by this script
cManager.SetClusterMethod(mClusterMethod);
cManager.SetDistanceLimit(mClusterDistanceLimit);
if (mNumClusters > 0)
{
cManager.SetNumClustersToCreate(mNumClusters);
}
else
{
cManager.SetDistanceFunction(mDistanceFunction);
}
end_on_initialize
############################################################################
## 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);
draw.SetDuration(PROCESSOR.UpdateInterval());
draw.SetColor(1.0,0.5,0.0); //orange?
draw.SetLineStyle("solid");
draw.SetLineSize(2);
draw.BeginPolyline();
for (int j = 0; j < pts.Size(); j = j + 1 )
{
WsfGeoPoint pt = pts.Get(j);
draw.Vertex(pt);
}
draw.Vertex(first);
draw.End();
end_script
script Array<WsfQuantumTask> GciCommanderTaskGeneration (Array<WsfLocalTrack> TRACKS, Array<WsfAssetPerception> ASSETS )
//create weapon tasks for enemy track groups (clusters)
Array<WsfQuantumTask> tasks = Array<WsfQuantumTask>();
writeln_d(PLATFORM.Name(), " executing GciCommanderTaskGeneration(), T=", TIME_NOW);
##########################################################################
## update the cluster manager with the current master track list
##########################################################################
WsfLocalTrackList localTracks = PLATFORM.MasterTrackList();
Array<WsfTrack> trackArray = Array<WsfTrack>();
foreach (WsfLocalTrack lt in localTracks)
{
if (mRequireTasking == true && TasksReceivedForTarget(lt.TrackId()).Count() <= 0)
{
continue;
}
if (lt.IsValid() && (!lt.SideValid() || lt.Side() != PLATFORM.Side()))
{
lt.SetBearing( lt.Heading() ); #useful for the cluster processing
trackArray.PushBack(lt);
}
}
cManager.UpdateClusters(TIME_NOW,trackArray);
##########################################################################
## generate a task for each clusters
##########################################################################
int NumClusters = cManager.Count();
for (int i = 0; i < NumClusters; i = i + 1 )
{
WsfCluster cluster = cManager.Entry(i);
int clusterId = cluster.Id();
if (mDrawClusters == true)
{
draw_cluster_hull(cluster);
}
if( cluster.Count() > 0 )
{
double ClusterPriority = mClusterJobPriority;
if (ClusterPriority <= 0)
{
ClusterPriority = (double)cluster.Count();
}
WsfQuantumTask qt = WsfQuantumTask.Construct(ClusterPriority, "CLUSTER", cluster.Entry(0)); //include a track with the task
qt.SetTaskType("CLUSTER");
qt.UniqueId(cluster.Id());
qt.SetAuxData( "clusterIndex", i ); //for evaluation below
//TODO local tracks in the quantum task???
qt.SetAuxData( "maxPerformers", mMaxTaskPerformers );
qt.SetAuxData( "clusterId", cluster.Id() );
qt.SetAuxData( "ClusterMeanPoint", WsfGeoPoint(cluster.MeanLocation()) );
qt.SetAuxData( "ClusterBearing", cluster.Bearing() );
qt.SetAuxData( "ClusterBearingValid", cluster.BearingValid() );
qt.SetAuxData( "ClusterNumMembers", cluster.Count() );
Array<string> arr = Array<string>();
for (int i = 0; i < cluster.Count(); i = i + 1 )
{
arr.PushBack(cluster.Entry(i).TargetName());
writeln_d("job cluster member: ", cluster.Entry(i).TargetName());
}
qt.SetAuxData( "ClusterMemberNames", arr );
tasks.PushBack(qt);
writeln_d("cluster task generated for: ", cluster.Id());
}
}
return tasks;
end_script
script double GciCommanderEvaluation ( WsfQuantumTask TASK, WsfAssetPerception ASSET)
//simplistic evaluation for now
//TODO : iterate over all perceived assets that are subordinates of this lead and...
// evaluate each entry separately & make a composite value
writeln_d("evaluating ", ASSET.Name(), " and task type ", TASK.TaskType());
if (ASSET.Type() == "FLIGHT_LEAD")
{
WsfPlatform lead = WsfSimulation.FindPlatform(ASSET.Index());
if (lead.IsValid())
{
writeln_d("calculating value");
WsfGeoPoint subCentroid = lead.SubordinatesCentroid(); //cheating, TODO: use asset perception
int clusterIndex = TASK.AuxDataInt("clusterIndex");
WsfCluster cluster = cManager.Entry(clusterIndex);
double dist = cluster.MeanLocation().GroundRangeTo(subCentroid);
#double count = (double)lead.Subordinates().Count();
//count available weapons
double weaponCount = 0;
Array<WsfAssetPerception> assets = PLATFORM.PerceivedAssets();
WsfPlatformList subs = lead.Subordinates();
foreach(WsfPlatform sub in subs)
{
foreach (WsfAssetPerception asset in assets)
{
if (asset.Index()==sub.Index())
{
for (int j=0; j<asset.SystemCount(); j+=1)
{
if (asset.SystemKind(j) == "weapon")
{
weaponCount += asset.SystemQuantityRemaining(j);
}
}
break;
}
}
}
writeln_d("T=", TIME_NOW, ", ", lead.Name(), " evaluation: ", (weaponCount/dist));
#return (count/dist);
return (weaponCount/dist);
}
}
return 0.0;
end_script
#show_task_messages
script_debug_writes off
update_interval 10.0 sec
reallocation_strategy dynamic
generator custom GciCommanderTaskGeneration
evaluator custom GciCommanderEvaluation
allocator optimal_profit
#allocator_extra_tasks optimal_profit
#allocator greedy_isolated
#allocator_extra_tasks greedy_isolated
end_processor