# **************************************************************************** # 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 commander: #bids on "zone" jobs #creates "pursue-target" jobs #does not perform any jobs #without commander: #creates "pursue-target" jobs from threats in tracklist processor AISC-thinker WSF_RIPR_PROCESSOR #debug #script_debug_writes on script_debug_writes off update_interval 5.0 seconds script_variables Map mTargetNameJobIdMap = Map(); Map mJobIdTargetNameMap = Map(); int mMaxJobWinners = 1; int mNumJobChannels = 3; end_script_variables on_initialize //SetJobAllocationMode(2); SetNumJobChannels(mNumJobChannels); SetJobStickiness(1.0); end_on_initialize on_update writeln_d( "AISC on_update" ); #extern WsfTrack GetTrackByName(WsfPlatform, string); //this agent acts slightly different if it has a commander //it bids on its commander's jobs based on other bids from its subordinates Map updatedJobs = Map(); if( GetRIPRCommanderProcessor().IsValid() ) { writeln_d(" ", PLATFORM.Name(), " update with commander."); Array jobs = GetRIPRCommanderProcessor().GetJobs(); //this agent is special, he'll use a different channel to bid on each of his commander's jobs //this is done so that he can potentially win each and every job writeln_d("AISC update - number of jobs to bid on: ", jobs.Size()); //bid on all the commander's jobs foreach (WsfRIPRJob aJob in jobs) { for( int channel = 0; channel < GetNumJobChannels(); channel = channel + 1 ) { double bidValue = QueryBid(aJob); if( bidValue > -MATH.DOUBLE_MAX() ) { //bidValue = bidValue * MATH.Pow(0.97,(double)channel); aJob.BidJob( PROCESSOR, channel, bidValue ); writeln_d( "AISC update - channel ", channel, " bid ", bidValue, " on job ", aJob.GetDescription() ); } } } //find out which jobs this agent has won, and create/update local jobs based on them Map updatedTargetJobs = Map(); for (int i = 0; i < GetNumJobChannels(); i = i+1 ) { WsfRIPRJob aJob = GetRIPRCommanderProcessor().GetJobFor(TIME_NOW, PROCESSOR, i); if (aJob.IsValid()) { // we won this job, remove all other bids from our other channels for( int otherChannel = 0; otherChannel < GetNumJobChannels(); otherChannel = otherChannel + 1 ) { if( otherChannel != i ) { aJob.UnbidJob( PROCESSOR, otherChannel ); } } string NewComment = "AISC update - channel " + (string)i + " won job: " + aJob.GetDescription(); PLATFORM.Comment(NewComment); writeln_d( NewComment ); //break up each job of many targets into single-target jobs #extern WsfTrack GetTrackByName(WsfPlatform, string); Array arr = (Array)aJob.GetData("ZoneThreatNameArray"); foreach (string targetName in arr) { // if the track doesnt exist or is dead, dont create or update a job for it WsfTrack target = GetTrackByName(PLATFORM, targetName); if( !target.IsValid() || target.BelievedDead() ) { continue; } if (mTargetNameJobIdMap.Exists(targetName)) { //job exists, just update it //not much updating done here, could probably leave this out, just a stub for now int jobId = mTargetNameJobIdMap.Get(targetName); WsfRIPRJob eJob = GetJobById(jobId); double currentPriority = 1.0; eJob.Priority(currentPriority); } else { //job doesn't exist yet, create it //make sure there is a job on this agent's board for this target double Priority = 1.0 / PLATFORM.SlantRangeTo( GetTrackByName(PLATFORM, targetName) ); // base priority on distance? WsfRIPRJob temp = WsfRIPRJob.Create( PROCESSOR, "pursue-target", "pursue-target-" + targetName, Priority, mMaxJobWinners ); temp.SetData("targetTrackName", targetName); mTargetNameJobIdMap.Set(targetName, temp.GetId()); AddJob(temp); } //either way the job was updated or created, record that fact updatedJobs.Set(targetName,1 ); } } } } else { //no ripr commander was found for this agent //continue to function as if he doesn't exist or is dead //simply create jobs for each threat we know about //this agent considers itself the highest level commander for any of it's subordinates writeln_d(" ", PLATFORM.Name(), " update WITHOUT commander, stand-alone."); WsfLocalTrackList localTracks = PLATFORM.MasterTrackList(); //writeln_d("AISC update - ",PLATFORM.Name()," track count: ",localTracks.Count()); foreach (WsfTrack track in localTracks) { if ( mTargetNameJobIdMap.Exists( track.TargetName() ) ) { //update existing job double currentPriority = 1.0; int jobId = mTargetNameJobIdMap.Get(track.TargetName()); WsfRIPRJob job = GetJobById(jobId); job.Priority( currentPriority ); job.SetData("TrackId", track.TrackId() ); //redundant, this shouldn't change anything job.SetData("targetTrackName", track.TargetName()); //redundant, this shouldn't change anything if (track.WithinZoneOf(PLATFORM,"MEZ")) { job.SetData( "for_air", 0 ); job.SetData( "for_ground", 1 ); } else if (track.WithinZoneOf(PLATFORM,"FEZ")) { job.SetData( "for_air", 1 ); job.SetData( "for_ground", 0 ); } else { job.SetData( "for_air", 1 ); job.SetData( "for_ground", 1 ); } } else { //create new job double initialPriority = 1.0; WsfRIPRJob temp; temp = temp.Create( PROCESSOR, "pursue-target", "pursue-target-" + track.TargetName(), initialPriority, mMaxJobWinners ); //temp.SetData("TrackId", track.TrackId() ); temp.SetData("targetTrackName", track.TargetName()); if ( track.WithinZoneOf(PLATFORM,"MEZ") ) { temp.SetData( "for_air", 0 ); temp.SetData( "for_ground", 1 ); } else if ( track.WithinZoneOf(PLATFORM,"FEZ") ) { temp.SetData( "for_air", 1 ); temp.SetData( "for_ground", 0 ); } else { temp.SetData( "for_air", 1 ); temp.SetData( "for_ground", 1 ); } AddJob(temp); mTargetNameJobIdMap.Set(track.TargetName(), temp.GetId()); mJobIdTargetNameMap.Set(temp.GetId(), track.TargetName()); writeln_d("~~~ ", PLATFORM.Name(), " job change, ADD: ", temp.Name() ); //double bidValue = QueryBid(temp); //writeln_d("QueryBid(job) returned: ", bidValue); } //either way the job was updated or created, record that fact updatedJobs.Set( track.TargetName(), 1 ); } } //now make sure the right jobs are removed DeleteCompletedJobs(); //this agent might have created jobs depending on other jobs from its commander //or the targets for previous jobs might not exist anymore //remove any jobs that are for non-existent tracks Array jobs = GetJobs(); foreach (WsfRIPRJob x in jobs) { string name = (string)x.GetData("targetTrackName"); if (updatedJobs[name] != 1) { int jid = x.GetId(); writeln_d("--- ", PLATFORM.Name(), " job change, REMOVE: ", x.GetDescription()); string tName = mJobIdTargetNameMap[jid]; //this should match the job's data: "targetTrackName" mTargetNameJobIdMap.Erase(name); mJobIdTargetNameMap.Erase(jid); RemoveJob(x); } } writeln_d( "AISC update - ", PLATFORM.Name(), " job count: ", jobs.Size() ); end_on_update query_bid_type pursue-target if (!JOB.IsValid()) { writeln_d("aisc query_bid, job invalid!!"); return -MATH.DOUBLE_MAX(); } //only bid on jobs that ground platforms can perform if (((int)JOB.GetData("for_ground")) != 1) { writeln_d("aisc query_bid, job NOT for ground!"); return -MATH.DOUBLE_MAX(); } return QuerySubordinatesMaxBid(JOB); end_query_bid_type query_bid_type zone if (!JOB.IsValid()) { writeln_d("aisc query_bid, job invalid!!"); return -MATH.DOUBLE_MAX(); } //only bid on jobs that ground platforms can perform if (((int)JOB.GetData("for_ground")) != 1) { writeln_d("aisc query_bid, job NOT for ground!"); return -MATH.DOUBLE_MAX(); } double current_bid = 0; writeln_d("aisc query_bid, bidding on ", JOB.Name(), ", desc: ", JOB.GetDescription()); 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-zone", "pursue-" + JOB.GetDescription(), 1.0, mMaxJobWinners); if( !tempJob.IsValid() ) { writeln_d( "AISC query_bid - job, pursue-zone, could not be created" ); return -MATH.DOUBLE_MAX(); } Array targetNames = (Array)JOB.GetData("ZoneThreatNameArray"); foreach(string targetName in targetNames) { tempJob.SetData("targetTrackName", targetName); //by default this expands through job-pass-through agents to get all bids double curBid = QuerySubordinatesMaxBid(tempJob); writeln_d("aisc query_bid, max bid on ", targetName," from subordinates: ", curBid); if (curBid > maxBid) { maxBid = curBid; } } return maxBid; end_query_bid_type end_processor