# **************************************************************************** # 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. # **************************************************************************** #creates and updates "zone" jobs #does not bid on any jobs #does not perform any jobs processor AISOC-thinker WSF_RIPR_PROCESSOR update_interval 5.0 seconds #script_debug_writes on #script_debug_writes off debug script_variables WsfClusterManager cManager; int mMaxJobWinners = 1; int mLastNumClusters = 0; bool mDrawClusters = true; WsfDraw mDraw = WsfDraw(); Map mClusterNameJobIdMap = Map(); end_script_variables on_initialize //SetJobAllocationMode(2); cManager = WsfClusterManager.Create(); //creates a cluster manager owned by this script cManager.SetClusterMethod("H_TREE_MAX"); //default is: "K_MEANS" cManager.SetDistanceFunction("POSITION_VELOCITY"); //default is: "POSITION_ONLY" //cManager.SetDistanceLimit(92600); //default is: 100 meters, set to ~50 nautical miles cManager.SetDistanceLimit(46300); //default is: 100 meters, set to ~25 nautical miles mDraw.SetColor(1.0,0.5,0.0); //orange? mDraw.SetLineStyle("solid"); mDraw.SetLineSize(2); mDraw.SetDuration(5); end_on_initialize script void draw_cluster_hull(WsfCluster cluster) Array pts = cluster.ConvexHull(); //writeln_d(" ~~~ SOC cluster convex hull pts: ", pts.Size()); if (pts.Size() <= 0) { return; } WsfGeoPoint first = pts.Get(0); mDraw.BeginPolyline(); for (int j = 0; j < pts.Size(); j = j + 1 ) { WsfGeoPoint pt = pts.Get(j); mDraw.Vertex(pt); //writeln_d(" ~~~ SOC cluster convex hull pt ", j+1, ": ", pt.Latitude(), ", ", pt.Longitude()); } mDraw.Vertex(first); mDraw.End(); end_script on_update //writeln_d(" ~~~ SOC tracklist count: ", localTracks.Count()); WsfLocalTrackList localTracks = PLATFORM.MasterTrackList(); cManager.UpdateClusters(TIME_NOW,localTracks); int NumClusters = cManager.Count(); for (int i = 0; i < NumClusters; i = i + 1 ) { WsfCluster cluster = cManager.Entry(i); string ClusterName = PLATFORM.Name() + "_" + (string)i; //create a zone that bounds this cluster, with some padding //anybody can call up this zone by name to check if a threat is inside it //no need to have a zone on the platform: deprecated! //cluster.UpdatePlatformZone(PLATFORM,ClusterName,(5.0/60.0)); //5 minutes (1/12th of a degree) if (mDrawClusters == true) { draw_cluster_hull(cluster); } WsfGeoPoint clusterPoint = cluster.MeanLocation(); double clusterBearing = cluster.Bearing(); bool clusterBearingValid = cluster.BearingValid(); //writeln_d("~~~ SOC - cluster ", ClusterName, ", BEARING ", clusterBearing, " bearing valid: ", clusterBearingValid ); int numThreats = cluster.Count(); double ClusterPriority = (double)numThreats; if( numThreats > 0 ) { if( mClusterNameJobIdMap.Exists( ClusterName ) ) { //writeln_d("~~~ SOC, updating job for cluster: ", ClusterName); //job exists for zone with threats, update job priority int jobId = mClusterNameJobIdMap.Get( ClusterName ); WsfRIPRJob temp = GetJobById( jobId ); //job priority could have changed, set it temp.Priority( ClusterPriority ); temp.SetData( "ZonePoint", clusterPoint ); temp.SetData( "ZoneBearing", clusterBearing ); temp.SetData( "ZoneBearingValid", clusterBearingValid ); //number of threats inside zone could have changed, set it temp.SetData( "ZoneNumThreats", numThreats ); bool anyInsideMEZ = false; Array arr = Array(); for (int i = 0; i < numThreats; i = i + 1 ) { WsfTrack threat = cluster.Entry(i); arr.PushBack(threat.TargetName()); if (threat.WithinZoneOf(PLATFORM,"MEZ")) { anyInsideMEZ = true; writeln_d("~~~ SOC, threat inside MEZ"); // dlc } } // dlc bool anyInsideFEZ = false; // Array arr = Array(); for (int i = 0; i < numThreats; i = i + 1 ) { WsfTrack threat = cluster.Entry(i); arr.PushBack(threat.TargetName()); if (threat.WithinZoneOf(PLATFORM,"FEZ")) { anyInsideFEZ = true; writeln_d("~~~ SOC, threat inside FEZ"); } } /* temp.SetData( "ZoneThreatNameArray", arr ); if (anyInsideMEZ) { temp.SetData( "for_air", 0 ); temp.SetData( "for_ground", 1 ); } else { temp.SetData( "for_air", 1 ); temp.SetData( "for_ground", 0 ); } */ temp.SetData( "ZoneThreatNameArray", arr ); if (anyInsideMEZ) { temp.SetData( "for_air", 0 ); temp.SetData( "for_ground", 1 ); } else if (anyInsideFEZ) { temp.SetData( "for_air", 1 ); temp.SetData( "for_ground", 0 ); } else { temp.SetData( "for_air", 0 ); temp.SetData( "for_ground", 0 ); } // cld } else { //zone just became hot, job not created yet, create one WsfRIPRJob temp = WsfRIPRJob.Create( PROCESSOR, "zone", "zone-" + ClusterName, ClusterPriority, mMaxJobWinners ); temp.SetData( "ZoneName", ClusterName ); temp.SetData( "ZonePoint", clusterPoint ); temp.SetData( "ZoneBearing", clusterBearing ); temp.SetData( "ZoneBearingValid", clusterBearingValid ); temp.SetData( "ZoneNumThreats", numThreats ); Array arr = Array(); for (int i = 0; i < numThreats; i = i + 1 ) { arr.PushBack(cluster.Entry(i).TargetName()); } temp.SetData( "ZoneThreatNameArray", arr ); AddJob(temp); mClusterNameJobIdMap.Set( ClusterName, temp.GetId() ); //writeln_d("~~~ SOC, creating job for cluster: ", ClusterName); writeln_d("~~~ ", PLATFORM.Name(), " job change, ADD: ", temp.Name() ); string NewComment = "SOC - " + PLATFORM.Name() + " job change, ADD: " + (temp.Name()); PLATFORM.Comment(NewComment); } } else { //no threats in cluster, make sure job for cluster doesn't exist or is deleted if( mClusterNameJobIdMap.Exists( ClusterName ) ) { //writeln_d("~~~ SOC, removing job for empty cluster: ", ClusterName); int jobId = mClusterNameJobIdMap.Get(ClusterName); writeln_d("~~~ ", PLATFORM.Name(), " job change, REMOVE: ", GetJobById(jobId).Name() ); string NewComment = "SOC - " + PLATFORM.Name() + " job change, REMOVE: " + (GetJobById(jobId).Name()); PLATFORM.Comment(NewComment); RemoveJob( GetJobById(jobId) ); //mClusterNameJobIdMap.Erase( ClusterName ); mClusterNameJobIdMap.Remove( ClusterName ); } } } //remove any additional clusters for( int j = NumClusters; j < mLastNumClusters; j = j+1 ) { string ClusterName = PLATFORM.Name() + "_" + (string)j; if( mClusterNameJobIdMap.Exists( ClusterName ) ) { //writeln_d("~~~ SOC, removing job for empty cluster: ", ClusterName); int jobId = mClusterNameJobIdMap.Get(ClusterName); writeln_d("~~~ ", PLATFORM.Name(), " job change, REMOVE: ", GetJobById(jobId).Name() ); string NewComment = "SOC - " + PLATFORM.Name() + " job change, REMOVE: " + (GetJobById(jobId).Name()); PLATFORM.Comment(NewComment); RemoveJob( GetJobById(jobId) ); //mClusterNameJobIdMap.Erase( ClusterName ); mClusterNameJobIdMap.Remove( ClusterName ); } } mLastNumClusters = NumClusters; end_on_update end_processor