init
This commit is contained in:
995
processors/ripr_agents/aiss/aiss_processor.txt
Normal file
995
processors/ripr_agents/aiss/aiss_processor.txt
Normal file
@@ -0,0 +1,995 @@
|
||||
# ****************************************************************************
|
||||
# CUI
|
||||
#
|
||||
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
|
||||
#
|
||||
# The use, dissemination or disclosure of data in this file is subject to
|
||||
# limitation or restriction. See accompanying README and LICENSE for details.
|
||||
# ****************************************************************************
|
||||
|
||||
|
||||
#always requires a commander
|
||||
#bids on & performs "pursue-target" jobs
|
||||
#does not create any jobs
|
||||
|
||||
|
||||
include_once processors/ripr_agents/common/common_platform_script.txt
|
||||
include_once weapons/sam/sam_launch_computer.txt
|
||||
|
||||
|
||||
processor AISS-thinker WSF_RIPR_PROCESSOR
|
||||
|
||||
#debug
|
||||
#script_debug_writes on
|
||||
script_debug_writes off
|
||||
|
||||
update_interval 1.0 sec
|
||||
|
||||
script_variables
|
||||
|
||||
int mMaxJobChannels = 1;
|
||||
int mSalvoSize = 2;
|
||||
string mTargetTrackingSensor = "ttr";
|
||||
string mTTSensorMode = "TRACK";
|
||||
string mAcqSensorMode = "ACQUIRE";
|
||||
string mAcquisitionSensorType = "ACQ_RADAR";
|
||||
string mAcquisitionCategory = "ACQUISITION";
|
||||
string mTaskManagerName = "task_mgr";
|
||||
string mWeaponNameOnSubordinates = "sam";
|
||||
|
||||
string mEnvelopeName_Outer = "full_kinematic";
|
||||
string mEnvelopeName_Inner = "quarter_kinematic";
|
||||
|
||||
double mAcquireTimeout = 15.0; //seconds
|
||||
double mTrackingTimeout = 15.0; //seconds
|
||||
double mRelativeOffsetLimit = 90.0; //degrees
|
||||
double mRelativeHeadingLimit = 90.0; //degrees
|
||||
double mTrackerAngleAdjustLimit = 0.0; //degrees (more if target radar can rotate)
|
||||
|
||||
double mDeadZoneRange = 1852; //arbitrary: in meters (1852 meters == 1 nautical mile)
|
||||
//go silent when threats are in the "dead zone" inner circle
|
||||
double mNeededAcquisitionTrackQuality = 0.75;
|
||||
double mNeededTargetingTrackQuality = 0.95;
|
||||
|
||||
string mAcqTrkTaskStr = "AcqTrk";
|
||||
string mCueTaskStr = "Cue";
|
||||
|
||||
Map<string, double> mStateDurations = Map<string, double>(); //the minimum time of evaluation for each state
|
||||
mStateDurations.Set( "DETECTED", 1.0 ); //arbitrary: seconds
|
||||
mStateDurations.Set( "TRY_ACQUIRE", 1.0 ); //arbitrary: seconds
|
||||
mStateDurations.Set( "ACQUIRE", 1.0 ); //arbitrary: seconds
|
||||
mStateDurations.Set( "TRY_TRACK", 1.0 ); //arbitrary: seconds
|
||||
mStateDurations.Set( "TRACK", 1.0 ); //arbitrary: seconds
|
||||
mStateDurations.Set( "TRY_FIRE", 1.0 ); //arbitrary: seconds
|
||||
mStateDurations.Set( "FIRE", 1.0 ); //arbitrary: seconds
|
||||
mStateDurations.Set( "WEAPONS_ACTIVE", 1.0 ); //arbitrary: seconds
|
||||
|
||||
Map<int, string> mJobCurrentState = Map<int, string>(); //keeps each jobs current engagement state
|
||||
Map<int, double> mJobStateTimes = Map<int, double>(); //records when each job entered its current state
|
||||
|
||||
WsfTrack mLastCuedTrack; // stores the last cued track
|
||||
Map<WsfTrackId, double> mLastCueStartTime = Map<WsfTrackId, double>(); // records the last time a pedestal cue was envoked
|
||||
|
||||
Array<int> mChannelJobs = Array<int>(); //array index is job channel, array value is job id
|
||||
Array<WsfTrackId> mChannelTracks = Array<WsfTrackId>(); //array index is job channel, array value is trackId
|
||||
int mCurrentBiddingChannel = -1;
|
||||
|
||||
WsfDraw draw = WsfDraw();
|
||||
end_script_variables
|
||||
|
||||
on_initialize
|
||||
|
||||
SetNumJobChannels( mMaxJobChannels );
|
||||
writeln_d("AISS on_init - Starting multi channel guy ", PLATFORM.Name(), " with ", GetNumJobChannels(), " total job channels" );
|
||||
|
||||
for (int i = 0; i < GetNumJobChannels(); i = i + 1)
|
||||
{
|
||||
mChannelJobs.PushBack( -1 );
|
||||
|
||||
WsfTrackId tempTrackId = WsfTrackId();
|
||||
mChannelTracks.PushBack( tempTrackId );
|
||||
}
|
||||
end_on_initialize
|
||||
|
||||
// ----------------------------------------
|
||||
// return the task manager object
|
||||
script WsfTaskManager GetTaskManager()
|
||||
static WsfTaskManager taskMgr;
|
||||
if( !taskMgr.IsValid() )
|
||||
{
|
||||
taskMgr = (WsfTaskManager)PLATFORM.Processor(mTaskManagerName);
|
||||
}
|
||||
return taskMgr;
|
||||
end_script
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Get the track object to from the corresponding job
|
||||
script WsfTrack GetJobsTrack(WsfRIPRJob aJob)
|
||||
|
||||
string name = (string)aJob.GetData("targetTrackName");
|
||||
#extern WsfTrack GetTrackByName(WsfPlatform, string);
|
||||
WsfTrack track = GetTrackByName(PLATFORM, name);
|
||||
return track;
|
||||
end_script
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Change the current state
|
||||
script bool TransitionEngagementState(int aJobId, string aDesiredState)
|
||||
string currentState = mJobCurrentState.Get(aJobId);
|
||||
|
||||
double duration = TIME_NOW - mJobStateTimes.Get(aJobId);
|
||||
double required = mStateDurations.Get(currentState);
|
||||
if (duration < required)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
mJobCurrentState.Set(aJobId, aDesiredState);
|
||||
mJobStateTimes.Set(aJobId, TIME_NOW);
|
||||
|
||||
string comment = "Job " + (string)aJobId + ", " + PLATFORM.Name() + " transition -> " + aDesiredState;
|
||||
PLATFORM.Comment(comment);
|
||||
writeln_d(comment, ", TIME = ", TIME_NOW);
|
||||
|
||||
return true;
|
||||
end_script
|
||||
|
||||
// ----------------------------------------
|
||||
// Return the track quality from sensor tracks associated with the given track
|
||||
script double SensorTrackQuality(WsfTrack track)
|
||||
|
||||
if( !track.IsValid() )
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
WsfLocalTrack finalTrack;
|
||||
WsfLocalTrackList localTrackList = PLATFORM.MasterTrackList();
|
||||
if( localTrackList.Count() > 0 )
|
||||
{
|
||||
finalTrack = localTrackList.FindTrack( track.TrackId() );
|
||||
}
|
||||
|
||||
if( finalTrack.IsValid() )
|
||||
{
|
||||
double quality = 0.0;
|
||||
for (int trackIndex = 0; trackIndex < finalTrack.RawTrackCount(); trackIndex = trackIndex + 1)
|
||||
{
|
||||
WsfTrack rawTrack = finalTrack.RawTrack(trackIndex);
|
||||
double rtQuality = rawTrack.TrackQuality();
|
||||
|
||||
// Indirect reports will be assigned a maximum quality of 0.5
|
||||
if (rawTrack.SensorType() == "")
|
||||
{
|
||||
rtQuality = MATH.Min(0.5, rtQuality);
|
||||
}
|
||||
|
||||
quality = MATH.Max(quality, rtQuality);
|
||||
}
|
||||
|
||||
return quality;
|
||||
}
|
||||
|
||||
return track.TrackQuality();
|
||||
end_script
|
||||
|
||||
// ----------------------------------------
|
||||
// Returns true if altitude data is known.
|
||||
script bool AltitudeKnown(WsfTrack target) // height data is available
|
||||
return (target.LocationValid() || target.ElevationValid());
|
||||
end_script
|
||||
|
||||
// ----------------------------------------
|
||||
// Returns true if intercept results are known
|
||||
// (i.e. weapons have terminated for this TRACK)
|
||||
script bool InterceptResultsKnown(WsfTrack target)
|
||||
return (GetTaskManager().TimeSinceWeaponLastTerminatedFor(target.TrackId()) > 0.0);
|
||||
end_script
|
||||
|
||||
// ----------------------------------------
|
||||
// Return 'true' if the target is in the 'dead-zone'
|
||||
script bool InDeadZone( WsfTrack track )
|
||||
return ( PLATFORM.SlantRangeTo(track) < mDeadZoneRange );
|
||||
end_script
|
||||
|
||||
// ----------------------------------------
|
||||
// Returns true if the given track is inside the given intercept envelope using the launch computer.
|
||||
script bool InInterceptEnvelopeOf( WsfTrack track, string aEnvelopeName )
|
||||
#extern bool SAM_LaunchComputer(WsfTrack, WsfPlatform, string, double);
|
||||
|
||||
return SAM_LaunchComputer(track, PLATFORM, aEnvelopeName, 0.0);
|
||||
end_script
|
||||
|
||||
// ----------------------------------------
|
||||
// returns true if the given track has a bearing in the direction of the platform
|
||||
script bool TrackIsBearingTowardPlatform( WsfTrack target )
|
||||
|
||||
// writeln_d( "AISS TrackIsBearingTowardPlatform() - track=", target.TargetName(), " | bearing=", target.RelativeBearingTo(PLATFORM) );
|
||||
return ( target.RelativeBearingTo(PLATFORM) < 90.0 &&
|
||||
target.RelativeBearingTo(PLATFORM) > -90.0 );
|
||||
|
||||
end_script
|
||||
|
||||
// ----------------------------------------
|
||||
// returns true if the given track is inside an appropriate envelope
|
||||
script bool IsInEnvelope( WsfTrack target )
|
||||
if( GetTaskManager().HaveFiredAt( target.TrackId() ) )
|
||||
{
|
||||
writeln_d( "AISS IsInEnvelope() - target=", target.TargetName(), " | InnerEnvelope=", mEnvelopeName_Inner );
|
||||
return ( GetTaskManager().TimeSinceWeaponLastTerminatedFor( target.TrackId() ) > 0.0 &&
|
||||
InInterceptEnvelopeOf( target, mEnvelopeName_Inner ) );
|
||||
}
|
||||
|
||||
writeln_d( "AISS IsInEnvelope() - target=", target.TargetName(), " | OuterEnvelope=", mEnvelopeName_Outer, " | Range=", PLATFORM.SlantRangeTo(target) );
|
||||
return InInterceptEnvelopeOf( target, mEnvelopeName_Outer );
|
||||
end_script
|
||||
|
||||
// ----------------------------------------
|
||||
// returns true if the given platform is within the multiple target zone specified on the sensor
|
||||
script bool WithinMultipleTargetZone(WsfPlatform aPlatform, WsfTrack target)
|
||||
|
||||
if (! aPlatform.IsValid())
|
||||
{
|
||||
writeln_d("***** WARNING: Null platform in WithinMultipleTargetZone");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = target.WithinZoneOf(aPlatform, "multiple_target_zone", mTargetTrackingSensor);
|
||||
writeln_d("AISS WithinMultipleTargetZone() - aPlatform=", aPlatform.Name(), " | target=", target.TargetName(), " | result=", result );
|
||||
return result;
|
||||
end_script
|
||||
|
||||
// ----------------------------------------
|
||||
// Platform type specific WithinZoneOf logic
|
||||
script bool WithinZoneOf(string aZone, WsfTrack target)
|
||||
bool result = false;
|
||||
|
||||
WsfPlatform subPlatform;
|
||||
foreach( WsfPlatform sub in PLATFORM.Subordinates() )
|
||||
{
|
||||
WsfSensor sensor = sub.Sensor(mTargetTrackingSensor);
|
||||
if ( sensor.IsValid() )
|
||||
{
|
||||
subPlatform = sub;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( subPlatform.IsValid() && GetNumJobChannels() > 1 ) // can engage multiple targets
|
||||
{
|
||||
result = WithinMultipleTargetZone(subPlatform, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Multiple targets not supported - just check to see if within the supplied zone.
|
||||
result = InInterceptEnvelopeOf(target, aZone);
|
||||
}
|
||||
|
||||
writeln_d("AISS WithinZoneOf() - subPlatform=", subPlatform.Name(), " | aZone=", aZone, " | target=", target.TargetName(), " | jobchannels=", GetNumJobChannels(), " | result=", result );
|
||||
return result;
|
||||
end_script
|
||||
|
||||
// ----------------------------------------
|
||||
// Determine the number of available weapons.
|
||||
script int WeaponsAvailable()
|
||||
int quantity = 0;
|
||||
foreach (WsfPlatform sub in PLATFORM.Subordinates())
|
||||
{
|
||||
WsfWeapon weapon = sub.Weapon(mWeaponNameOnSubordinates);
|
||||
if (weapon.IsTurnedOn())
|
||||
{
|
||||
quantity = quantity + weapon.QuantityRemaining();
|
||||
}
|
||||
}
|
||||
return quantity;
|
||||
end_script
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Determine the number of active weapons
|
||||
script int NumWeaponsActive(WsfTrack aTrack)
|
||||
return GetTaskManager().WeaponsActiveFor(aTrack.TrackId());
|
||||
end_script
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// turn on all subordinate sensors
|
||||
script void ActivateSensors()
|
||||
{
|
||||
for (int entry = 0; entry < PLATFORM.SensorCount(); entry = entry + 1)
|
||||
{
|
||||
//writeln_d( "AISS ActivateSensors() - attempting to activate ", PLATFORM.SensorEntry(entry).Name() );
|
||||
if( !PLATFORM.SensorEntry(entry).IsTurnedOn() )
|
||||
{
|
||||
if( PLATFORM.SensorEntry(entry).TurnOn() )
|
||||
{
|
||||
writeln_d( "AISS ActivateSensors() - ", PLATFORM.SensorEntry(entry).Name(), " activated." );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now activate subordinate subordinate sensors
|
||||
foreach( WsfPlatform sub in PLATFORM.Subordinates() )
|
||||
{
|
||||
for (int entry = 0; entry < sub.SensorCount(); entry = entry + 1)
|
||||
{
|
||||
//writeln_d( "AISS ActivateSensors() - attempting to activate ", sub.SensorEntry(entry).Name() );
|
||||
if( !sub.SensorEntry(entry).IsTurnedOn() )
|
||||
{
|
||||
if( sub.SensorEntry(entry).TurnOn() )
|
||||
{
|
||||
writeln_d( "AISS ActivateSensors() - ", sub.SensorEntry(entry).Name(), " activated." );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end_script
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// turn off all subordinate sensors
|
||||
script void DeactivateSensors()
|
||||
{
|
||||
for (int entry = 0; entry < PLATFORM.SensorCount(); entry = entry + 1)
|
||||
{
|
||||
writeln_d( "AISS DeactivateSensors() - attempting to deactivate ", PLATFORM.SensorEntry(entry).Name() );
|
||||
if( PLATFORM.SensorEntry(entry).IsTurnedOn() )
|
||||
{
|
||||
if( PLATFORM.SensorEntry(entry).TurnOff() )
|
||||
{
|
||||
writeln_d( "AISS DeactivateSensors() - ", PLATFORM.SensorEntry(entry).Name(), " deactivated." );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now deactivate subordinate subordinate sensors
|
||||
foreach( WsfPlatform sub in PLATFORM.Subordinates() )
|
||||
{
|
||||
for (int entry = 0; entry < sub.SensorCount(); entry = entry + 1)
|
||||
{
|
||||
writeln_d( "AISS DeactivateSensors() - attempting to deactivate ", sub.SensorEntry(entry).Name() );
|
||||
if( sub.SensorEntry(entry).IsTurnedOn() )
|
||||
{
|
||||
if( sub.SensorEntry(entry).TurnOff() )
|
||||
{
|
||||
writeln_d( "AISS DeactivateSensors() - ", sub.SensorEntry(entry).Name(), " deactivated." );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end_script
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// cancel tasks and stop tracking on the given track
|
||||
script void CancelTaskOnTrack( WsfTrackId trackId, string taskStr )
|
||||
|
||||
if( !trackId.IsValid() )
|
||||
{
|
||||
writeln_d( "AISS CancelTaskOnTrack() - invalid TrackId" );
|
||||
return;
|
||||
}
|
||||
|
||||
foreach( WsfPlatform sub in PLATFORM.Subordinates() )
|
||||
{
|
||||
// cancel tasks
|
||||
if( ( GetTaskManager().TasksAssignedTo(sub, trackId, taskStr) ) > 0 )
|
||||
{
|
||||
if( GetTaskManager().CancelTask(trackId, taskStr) )
|
||||
{
|
||||
writeln_d( "AISS CancelTaskOnTrack() - cancel task ", taskStr, " on ", sub.Name() );
|
||||
}
|
||||
}
|
||||
}
|
||||
end_script
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Update the pedestal cue (if possible).
|
||||
script void UpdatePedestalCue(WsfSensor aSensor, WsfTrack target)
|
||||
// Don't allow the pedestal to be re-cued if it is actively being used.
|
||||
|
||||
if ( aSensor.IsValid() && target.IsValid() )
|
||||
{
|
||||
writeln_d( "AISS UpdatePedestalCue() - TasksAssigned=", GetTaskManager().TasksAssignedTo(aSensor.Platform(), mCueTaskStr),
|
||||
" | RequestCount=", aSensor.ActiveRequestCount() );
|
||||
if( GetTaskManager().TasksAssignedTo(aSensor.Platform(), mCueTaskStr) == 0 &&
|
||||
(aSensor.ActiveRequestCount() == 0) )
|
||||
{
|
||||
writeln_d( "AISS UpdatePedestalCue() - Bearing=", target.RelativeBearingTo(PLATFORM),
|
||||
" | !InDeadZone?=", !InDeadZone(target),
|
||||
" | InEnvelope?=", InInterceptEnvelopeOf(target, "engagement_zone") );
|
||||
WsfPlatform sub = aSensor.Platform();
|
||||
if ( TrackIsBearingTowardPlatform(target) &&
|
||||
!InDeadZone(target) &&
|
||||
InInterceptEnvelopeOf(target, "engagement_zone") )
|
||||
{
|
||||
// Indicate this task has this pedestal
|
||||
GetTaskManager().AssignTask( target, mCueTaskStr, aSensor.Platform() );
|
||||
//aSensor.CueToTrack( target );
|
||||
aSensor.SetYaw( PLATFORM.RelativeBearingTo(target) );
|
||||
|
||||
mLastCuedTrack = target;
|
||||
mLastCueStartTime[target.TrackId()] = TIME_NOW;
|
||||
|
||||
PLATFORM.SetAuxData("ENGAGED", true); // For RED_SAM_MOVEMENT
|
||||
|
||||
writeln_d("***** T=", TIME_NOW, " Cue pedestal ", sub.Name(), " to ", target.TargetName(),
|
||||
" R=", sub.SlantRangeTo(target),
|
||||
", RelBrg=", aSensor.Yaw(), " deg", ", AbsBrg=", sub.TrueBearingTo(target), " deg");
|
||||
|
||||
/*
|
||||
// draw a line in the new facing direction
|
||||
WsfGeoPoint look = PLATFORM.Location();
|
||||
|
||||
look.Offset( sub.TrueBearingTo(target), 120000, 0, 0 );
|
||||
|
||||
writeln_d("AISS UpdatePedestalCue() - PLATFORM.Location()=", PLATFORM.Location().X(), "::", PLATFORM.Location().Y(), "::", PLATFORM.Location().Z(), " | ", PLATFORM.Location().ToString() );
|
||||
writeln_d("AISS UpdatePedestalCue() - target.CurrentLocation()=", target.CurrentLocation().X(), "::", target.CurrentLocation().Y(), "::", target.CurrentLocation().Z(), " | ", target.CurrentLocation().ToString() );
|
||||
writeln_d("AISS UpdatePedestalCue() - look=", look.X(), "::", look.Y(), "::", look.Z(), " | ", look.ToString() );
|
||||
|
||||
draw.Reset();
|
||||
draw.BeginLines();
|
||||
draw.SetLineStyle("dash_dot2");
|
||||
draw.SetLineSize(20);
|
||||
draw.SetColor(0.0,1.0,0.0);
|
||||
draw.Vertex(PLATFORM.Location());
|
||||
draw.Vertex(look);
|
||||
draw.End();
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
end_script
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Release the pedestal if appropriate.
|
||||
script void ReleasePedestal()
|
||||
|
||||
if( !mLastCuedTrack.IsValid() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
writeln_d( "AISS ReleasePedestal() - TasksAssigned=", GetTaskManager().TasksAssignedFor( mLastCuedTrack.TrackId(), mCueTaskStr), " | mLastCuedTrack=", mLastCuedTrack.TargetName() );
|
||||
if ( GetTaskManager().TasksAssignedFor( mLastCuedTrack.TrackId(), mCueTaskStr) != 0 )
|
||||
{
|
||||
// This track has the pedestal. Determine if it should be released.
|
||||
WsfPlatform sub = GetTaskManager().AssigneeForTask(mLastCuedTrack.TrackId(), mCueTaskStr);
|
||||
if (sub.IsValid())
|
||||
{
|
||||
double timeSinceLastCueStart = TIME_NOW - mLastCueStartTime[mLastCuedTrack.TrackId()];
|
||||
|
||||
WsfSensor sensor = sub.Sensor(mTargetTrackingSensor);
|
||||
|
||||
writeln_d( "AISS ReleasePedestal() - sensor=", sensor.Name(),
|
||||
" | RequestCount=", sensor.ActiveRequestCount(),
|
||||
" | timeSinceLastCueStart=", timeSinceLastCueStart );
|
||||
if ( sensor.IsValid() &&
|
||||
(sensor.ActiveRequestCount() == 0) && // No active search, acq or trk requests
|
||||
(timeSinceLastCueStart > 30.0))
|
||||
{
|
||||
|
||||
writeln_d( "AISS ReleasePedestal() - BelievedDead?=", mLastCuedTrack.BelievedDead(),
|
||||
" | !WMTZ=", !WithinMultipleTargetZone(sub, mLastCuedTrack) );
|
||||
if ( mLastCuedTrack.BelievedDead() || (!WithinMultipleTargetZone(sub, mLastCuedTrack)) )
|
||||
{
|
||||
GetTaskManager().CancelTask(mLastCuedTrack.TrackId(), mCueTaskStr);
|
||||
//sensor.ClearCueing();
|
||||
|
||||
writeln_d("***** T=", TIME_NOW, " Release pedestal ", sub.Name(), " from ", mLastCuedTrack.TargetName());
|
||||
writeln_d(" TSE=", timeSinceLastCueStart, " InMTZ=", WithinMultipleTargetZone(sub, mLastCuedTrack));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end_script
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Release resources (sensor, pedestal) that have been assigned to the target.
|
||||
script void ReleaseResources(WsfTrack track)
|
||||
writeln_d( "AISS ReleaseResources() - track=", track.TargetName() );
|
||||
CancelTaskOnTrack( track.TrackId(), mAcqTrkTaskStr );
|
||||
ReleasePedestal();
|
||||
end_script
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// try to Acquire the given target
|
||||
script bool TryAcquire( WsfTrack target )
|
||||
writeln_d("AISS TryAcquire() - target=", target.TargetName() );
|
||||
|
||||
foreach (WsfPlatform sub in PLATFORM.Subordinates())
|
||||
{
|
||||
WsfSensor sensor = sub.Sensor(mTargetTrackingSensor);
|
||||
if (! sensor.IsValid()) continue;
|
||||
|
||||
UpdatePedestalCue(sensor, target);
|
||||
|
||||
writeln_d( " - sensor=", sensor.Name(), " | RequestCount(Acquire)=", sensor.ActiveRequestCount(mAcqSensorMode), " | MaxRequestCount(Acquire)=", sensor.MaximumRequestCount(mAcqSensorMode) );
|
||||
writeln_d( " - sensor=", sensor.Name(), " | RequestCount(Track)=", sensor.ActiveRequestCount(mTTSensorMode), " | MaxRequestCount(Track)=", sensor.MaximumRequestCount(mTTSensorMode) );
|
||||
|
||||
// Check number of requests for acquisition.
|
||||
if ( sensor.ActiveRequestCount(mAcqSensorMode) >= sensor.MaximumRequestCount(mAcqSensorMode) )
|
||||
{
|
||||
writeln_d(" - sensor has too many requests in ", mAcqSensorMode, " mode" );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check number of requests for track.
|
||||
if ( sensor.ActiveRequestCount(mTTSensorMode) >= sensor.MaximumRequestCount(mTTSensorMode) )
|
||||
{
|
||||
writeln_d(" - sensor has too many requests in ", mTTSensorMode, " mode" );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( WithinZoneOf("engagement_zone", target) && IsInEnvelope(target) )
|
||||
{
|
||||
// Acquire the target
|
||||
if ( GetTaskManager().StartTracking(target, mAcqTrkTaskStr, sensor.Name(), mAcqSensorMode, sub) )
|
||||
{
|
||||
writeln_d(" - Start Acquiring Target" );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d( " - sensor tried but FAILED to start Acquiring" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d( " - target is NOT in envelope" );
|
||||
}
|
||||
}
|
||||
|
||||
writeln_d( " - unable to Acquire target" );
|
||||
return false;
|
||||
end_script
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Try to track the given target
|
||||
script bool TryTrack(WsfTrack target)
|
||||
writeln_d("AISS TryTrack() - target=", target.TargetName() );
|
||||
|
||||
if ( WeaponsAvailable() == 0 )
|
||||
{
|
||||
writeln_d("AISS TryTrack() - Bingo on Ammo" );
|
||||
return false; // no weapons available
|
||||
}
|
||||
|
||||
foreach (WsfPlatform sub in PLATFORM.Subordinates())
|
||||
{
|
||||
WsfSensor sensor = sub.Sensor(mTargetTrackingSensor);
|
||||
if (! sensor.IsValid())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
writeln_d( " - sensor=", sensor.Name(), " | RequestCount(Track)=", sensor.ActiveRequestCount(mTTSensorMode), " | MaxRequestCount(Track)=", sensor.MaximumRequestCount(mTTSensorMode) );
|
||||
|
||||
if (sensor.ActiveRequestCount(mTTSensorMode) >= sensor.MaximumRequestCount(mTTSensorMode))
|
||||
{
|
||||
writeln_d(" - sensor has too many requests in ", mTTSensorMode, " mode" );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( WithinZoneOf("engagement_zone", target) && !InDeadZone(target) )
|
||||
{
|
||||
if( IsInEnvelope(target) &&
|
||||
TrackIsBearingTowardPlatform(target) )
|
||||
{
|
||||
// Track the target
|
||||
if ( GetTaskManager().StartTracking(target, mAcqTrkTaskStr, sensor.Name(), mTTSensorMode, sub) )
|
||||
{
|
||||
writeln_d(" - Start Tracking Target" );
|
||||
|
||||
writeln_d( " - sensor=", sensor.Name(), " | RequestCount(Acquire)=", sensor.ActiveRequestCount(mAcqSensorMode), " | MaxRequestCount(Acquire)=", sensor.MaximumRequestCount(mAcqSensorMode) );
|
||||
writeln_d( " - sensor=", sensor.Name(), " | RequestCount(Track)=", sensor.ActiveRequestCount(mTTSensorMode), " | MaxRequestCount(Track)=", sensor.MaximumRequestCount(mTTSensorMode) );
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d( " - sensor tried but FAILED to start tracking" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d( " - target is NOT in envelope" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d( " - target is in Dead Zone" );
|
||||
}
|
||||
}
|
||||
|
||||
writeln_d( " - unable to Track target" );
|
||||
return false;
|
||||
end_script
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// launch a weapon at the target, the weapon must be:
|
||||
// - available and turned on
|
||||
// - have sufficient rounds
|
||||
// - have a target not already being fired on
|
||||
script bool LaunchWeaponAt(WsfTrack target)
|
||||
|
||||
writeln_d("AISS LaunchWeaponAt() - attempting to launch weapon at ", target.TargetName());
|
||||
foreach (WsfPlatform sub in PLATFORM.Subordinates())
|
||||
{
|
||||
WsfWeapon weapon = sub.Weapon(mWeaponNameOnSubordinates);
|
||||
if (weapon.IsValid())
|
||||
{
|
||||
writeln_d( "AISS LaunchWeaponAt() - ", PLATFORM.Name(), ".LaunchWeaponAt() - weapon=", weapon.Name(),
|
||||
" | WeaponOn=", weapon.IsTurnedOn(),
|
||||
" | TimeSinceFired=", weapon.TimeSinceLastFired(),
|
||||
" | QuantityRemaining=", weapon.QuantityRemaining() );
|
||||
|
||||
if ( weapon.IsTurnedOn() &&
|
||||
weapon.QuantityRemaining() >= mSalvoSize &&
|
||||
(GetTaskManager().TasksAssignedTo( sub, "", weapon.Name() )) == 0 )
|
||||
{
|
||||
if ( GetTaskManager().Fire(target, "Shoot", weapon.Name(), mSalvoSize, sub) )
|
||||
{
|
||||
writeln_d("*** T=", TIME_NOW, " ",PLATFORM.Name()," -> ", sub.Name(), " FIRING ON ", target.TargetName(), "!!!");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
end_script
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Can the target be self-engaged
|
||||
script void ProcessEngagement(WsfRIPRJob aJob, int currChannel)
|
||||
|
||||
if (!aJob.IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WsfTrack jobTrack = GetJobsTrack(aJob);
|
||||
if (!jobTrack.IsValid() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int jobID = aJob.GetId();
|
||||
string jobState = mJobCurrentState.Get(jobID);
|
||||
|
||||
writeln_d( "AISS ProcessEngagement() - platform=", PLATFORM.Name(), " | jobState=", jobState, " | jobTrack=", jobTrack.TargetName() );
|
||||
if( jobTrack.BelievedDead() )
|
||||
{
|
||||
writeln_d( "AISS ProcessEngagement() - track, ", jobTrack.TargetName(), " is believed dead." );
|
||||
|
||||
aJob.SetProgress( PROCESSOR, currChannel, 1.0 );
|
||||
|
||||
ReleaseResources(jobTrack);
|
||||
PLATFORM.SetAuxData("FIRING", false);
|
||||
return;
|
||||
}
|
||||
|
||||
if( !AltitudeKnown(jobTrack) )
|
||||
{
|
||||
writeln_d( "AISS ProcessEngagement() - track, ", jobTrack.TargetName(), " unknown altitude." );
|
||||
|
||||
ReleaseResources(jobTrack);
|
||||
PLATFORM.SetAuxData("FIRING", false);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
if( !WithinZoneOf("engagement_zone", jobTrack) )
|
||||
{
|
||||
writeln_d( "AISS ProcessEngagement() - track, ", jobTrack.TargetName(), " is out of engagement zone." );
|
||||
|
||||
ReleaseResources(jobTrack);
|
||||
PLATFORM.SetAuxData("FIRING", false);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
if (jobState == "DETECTED")
|
||||
{
|
||||
PLATFORM.SetAuxData("FIRING", false);
|
||||
ReleasePedestal();
|
||||
|
||||
//if threat is one to be tracked & fired on, try to acquire it
|
||||
if ( jobTrack.IFF_Foe() )
|
||||
{
|
||||
TransitionEngagementState(jobID, "TRY_ACQUIRE");
|
||||
}
|
||||
}
|
||||
else if (jobState == "TRY_ACQUIRE")
|
||||
{
|
||||
ReleasePedestal();
|
||||
|
||||
if( TryAcquire(jobTrack) )
|
||||
{
|
||||
//turned on an acquisition radar, make transition
|
||||
TransitionEngagementState(jobID, "ACQUIRE");
|
||||
}
|
||||
}
|
||||
else if (jobState == "ACQUIRE")
|
||||
{
|
||||
// look for an acquisition track of sufficient quality
|
||||
writeln_d( "AISS ProcessEngagement() - SensorTrackQuality()=", SensorTrackQuality(jobTrack), " | mNeededAcquisitionTrackQuality=", mNeededAcquisitionTrackQuality );
|
||||
if ( SensorTrackQuality(jobTrack) >= mNeededAcquisitionTrackQuality )
|
||||
{
|
||||
TransitionEngagementState(jobID, "TRY_TRACK");
|
||||
|
||||
ReleaseResources(jobTrack);
|
||||
return;
|
||||
}
|
||||
|
||||
double timeInAcquireState = TIME_NOW - mJobStateTimes[jobID];
|
||||
if( timeInAcquireState > mAcquireTimeout )
|
||||
{
|
||||
writeln_d( "AISS ProcessEngagement() - ACQUIRE TIMEOUT: timeInAcquireState=", timeInAcquireState );
|
||||
TransitionEngagementState(jobID, "TRY_ACQUIRE");
|
||||
|
||||
ReleaseResources(jobTrack);
|
||||
}
|
||||
}
|
||||
else if (jobState == "TRY_TRACK")
|
||||
{
|
||||
if( TryTrack( jobTrack ) )
|
||||
{
|
||||
TransitionEngagementState(jobID, "TRACK");
|
||||
}
|
||||
}
|
||||
else if (jobState == "TRACK")
|
||||
{
|
||||
//look for this target track of sufficient quality
|
||||
writeln_d( "AISS ProcessEngagement() - SensorTrackQuality()=", SensorTrackQuality(jobTrack), " | mNeededTargetingTrackQuality=", mNeededTargetingTrackQuality );
|
||||
if ( SensorTrackQuality(jobTrack) >= mNeededTargetingTrackQuality )
|
||||
{
|
||||
//found it & its good for firing on (target quality)
|
||||
TransitionEngagementState(jobID, "TRY_FIRE");
|
||||
return;
|
||||
}
|
||||
|
||||
double timeInTrackState = TIME_NOW - mJobStateTimes[jobID];
|
||||
if( timeInTrackState > mTrackingTimeout )
|
||||
{
|
||||
writeln_d( "AISS ProcessEngagement() - TRACK TIMEOUT: timeInTrackState=", timeInTrackState );
|
||||
TransitionEngagementState(jobID, "TRY_ACQUIRE");
|
||||
|
||||
ReleaseResources(jobTrack);
|
||||
}
|
||||
}
|
||||
else if (jobState == "TRY_FIRE")
|
||||
{
|
||||
|
||||
if( TrackIsBearingTowardPlatform(jobTrack) &&
|
||||
!InDeadZone(jobTrack) &&
|
||||
WithinZoneOf("full_kinematic", jobTrack) )
|
||||
{
|
||||
TransitionEngagementState(jobID, "FIRE");
|
||||
}
|
||||
|
||||
// break off if we are no longer tracking
|
||||
if( SensorTrackQuality(jobTrack) < mNeededTargetingTrackQuality )
|
||||
{
|
||||
TransitionEngagementState(jobID, "TRY_ACQUIRE");
|
||||
|
||||
ReleaseResources(jobTrack);
|
||||
}
|
||||
}
|
||||
else if (jobState == "FIRE")
|
||||
{
|
||||
writeln_d( "AISS ProcessEngagement() - IsInEnvelope()=", IsInEnvelope(jobTrack), " | NumWeaponsActive()=", NumWeaponsActive(jobTrack) );
|
||||
if ( IsInEnvelope( jobTrack ) && NumWeaponsActive( jobTrack ) < 1 )
|
||||
{
|
||||
if( LaunchWeaponAt(jobTrack) )
|
||||
{
|
||||
PLATFORM.SetAuxData("HAVE_FIRED", true);
|
||||
PLATFORM.SetAuxData("FIRING", true);
|
||||
TransitionEngagementState(jobID, "WEAPONS_ACTIVE");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (jobState == "WEAPONS_ACTIVE")
|
||||
{
|
||||
// check if we should fire again
|
||||
if( NumWeaponsActive( jobTrack ) < 1 )
|
||||
{
|
||||
PLATFORM.SetAuxData("FIRING", false);
|
||||
TransitionEngagementState(jobID, "TRY_FIRE");
|
||||
}
|
||||
}
|
||||
|
||||
end_script
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Perform the given job
|
||||
script void DoJob(WsfRIPRJob aJob, int aChannel)
|
||||
writeln_d( "AISS DoJob() - platform=", PLATFORM.Name(), " | job=", aJob.GetDescription(), " | aChannel=", aChannel );
|
||||
if (aJob.IsValid())
|
||||
{
|
||||
WsfTrack track = GetJobsTrack(aJob);
|
||||
|
||||
if (!track.IsValid())
|
||||
{
|
||||
writeln_d( " track invalid" );
|
||||
return;
|
||||
}
|
||||
|
||||
draw.BeginLines();
|
||||
draw.SetLineStyle("dashed");
|
||||
draw.SetLineSize(30);
|
||||
draw.SetDuration(1.0);
|
||||
draw.SetColor(1.0,0.0,0.0);
|
||||
draw.Vertex(track.CurrentLocation());
|
||||
draw.Vertex(PLATFORM.Location());
|
||||
draw.End();
|
||||
|
||||
if (mChannelJobs.Get(aChannel) != aJob.GetId()) //write a line to output if the job changed
|
||||
{
|
||||
writeln_d( " Job Change: ", PLATFORM.Name(), " channel ", aChannel, " new job(", aJob.GetId(), "): ", aJob.GetDescription(), " new track: ", track.TrackId().ToString());
|
||||
writeln_d( " aChannel=", aChannel, " | mChannelJobs.Size()=", mChannelJobs.Size(), " | mChannelTracks.Size()=", mChannelTracks.Size() );
|
||||
|
||||
#extern WsfTrack GetTrackById(WsfPlatform, WsfTrackId);
|
||||
WsfTrack oldTrack = GetTrackById( PLATFORM, mChannelTracks.Get(aChannel) );
|
||||
if( oldTrack.IsValid() )
|
||||
{
|
||||
ReleaseResources(oldTrack);
|
||||
}
|
||||
|
||||
// store the new job data
|
||||
mChannelJobs.Set(aChannel, aJob.GetId());
|
||||
mChannelTracks.Set(aChannel, track.TrackId());
|
||||
|
||||
//transition job to DETECTED
|
||||
TransitionEngagementState( aJob.GetId(), "DETECTED");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d( " job invalid" );
|
||||
}
|
||||
end_script
|
||||
|
||||
on_update
|
||||
writeln_d( "AISS on_update - ", PLATFORM.Name(), " GetNumJobChannels()=", GetNumJobChannels() );
|
||||
|
||||
WsfRIPRProcessor cmdr = GetRIPRCommanderProcessor();
|
||||
if (!cmdr.IsValid())
|
||||
{
|
||||
writeln_d("AISS on_update - Invalid commander for platform, ", PLATFORM.Name() );
|
||||
return;
|
||||
}
|
||||
|
||||
Array<WsfRIPRJob> jobs = cmdr.GetJobs();
|
||||
|
||||
// if there are no jobs, turn off all sensors
|
||||
if( jobs.Size() < 1 )
|
||||
{
|
||||
DeactivateSensors();
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d( "AISS on_update - Bid and Do jobs" );
|
||||
ActivateSensors();
|
||||
|
||||
writeln_d( " - Jobs up for bid" );
|
||||
foreach (WsfRIPRJob debugJob in jobs)
|
||||
{
|
||||
writeln_d(" ~ ", debugJob.GetDescription() );
|
||||
}
|
||||
|
||||
for (int jobChannel = 0; jobChannel < GetNumJobChannels(); jobChannel = jobChannel + 1)
|
||||
{
|
||||
// bid on each job from our commander
|
||||
foreach (WsfRIPRJob aJob in jobs)
|
||||
{
|
||||
mCurrentBiddingChannel = jobChannel;
|
||||
double bidVal = QueryBid(aJob);
|
||||
if( bidVal > 0 )
|
||||
{
|
||||
// scale down bid value as channels increase
|
||||
//bidVal = bidVal * MATH.Pow(0.97,(double)jobChannel);
|
||||
aJob.BidJob(PROCESSOR, jobChannel, bidVal);
|
||||
}
|
||||
}
|
||||
|
||||
writeln_d( "AISS on_update - ", cmdr.Name(), ".GetJobFor(", TIME_NOW, ", ", PLATFORM.Name(), ".", PROCESSOR.Name(), ", ", jobChannel, ")" );
|
||||
WsfRIPRJob jobWon = cmdr.GetJobFor(TIME_NOW, PROCESSOR, jobChannel);
|
||||
if( jobWon.IsValid() )
|
||||
{
|
||||
DoJob(jobWon, jobChannel);
|
||||
ProcessEngagement(jobWon, jobChannel);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d( "AISS on_update - no job assigned for channel, ", jobChannel );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mCurrentBiddingChannel = -1;
|
||||
|
||||
//extra debug stuff
|
||||
|
||||
// draw the current facing direction of the platform
|
||||
WsfLocalTrackList localTracks = PLATFORM.MasterTrackList();
|
||||
writeln_d( "AISS on_update - multi channel guy ",PLATFORM.Name()," track count: ",localTracks.Count());
|
||||
writeln_d( "AISS on_update - multi channel guy ",PLATFORM.Name()," job count: ",jobs.Size());
|
||||
writeln_d( "AISS on_update - ", PLATFORM.Name(), " GetNumJobChannels()=", GetNumJobChannels() );
|
||||
end_on_update
|
||||
|
||||
query_bid_type pursue-target
|
||||
|
||||
if (!JOB.IsValid())
|
||||
{
|
||||
writeln_d("AISS query_bid - job not valid for platform", PLATFORM.Name() );
|
||||
return -MATH.DOUBLE_MAX();
|
||||
}
|
||||
|
||||
WsfTrack track = GetJobsTrack(JOB);
|
||||
if (!track.IsValid())
|
||||
{
|
||||
writeln_d("AISS query_bid - track not valid for job: ", JOB.Name(), " - ", JOB.GetDescription(), " on platform: ", PLATFORM.Name() );
|
||||
return -MATH.DOUBLE_MAX();
|
||||
}
|
||||
|
||||
if( track.BelievedDead() )
|
||||
{
|
||||
writeln_d("AISS query_bid - track is believed dead: ", JOB.Name(), " - ", JOB.GetDescription(), " on platform: ", PLATFORM.Name() );
|
||||
return -MATH.DOUBLE_MAX();
|
||||
}
|
||||
|
||||
if( !TrackIsBearingTowardPlatform(track) )
|
||||
{
|
||||
writeln_d("AISS query_bid - track bearing is away from platform: ", JOB.Name(), " - ", JOB.GetDescription(), " on platform: ", PLATFORM.Name() );
|
||||
return -MATH.DOUBLE_MAX();
|
||||
}
|
||||
|
||||
writeln_d( "AISS query_bid - JOB=", JOB.GetDescription(), " | PLATFORM=", PLATFORM.Name(), " | TRACK=", track.TargetName(), " | mCurrentBiddingChannel=", mCurrentBiddingChannel );
|
||||
|
||||
// don't bid on the job if the other channel already won it
|
||||
if( mCurrentBiddingChannel > -1 )
|
||||
{
|
||||
for( int currChannel=0; currChannel<GetNumJobChannels(); currChannel = currChannel + 1 )
|
||||
{
|
||||
if( currChannel != mCurrentBiddingChannel )
|
||||
{
|
||||
WsfRIPRProcessor cmdr = GetRIPRCommanderProcessor();
|
||||
if( cmdr.IsValid() )
|
||||
{
|
||||
WsfRIPRJob channelJob = cmdr.GetJobFor(TIME_NOW, PROCESSOR, currChannel);
|
||||
if( channelJob.IsValid() )
|
||||
{
|
||||
int JobId = channelJob.GetId();
|
||||
if( JobId == JOB.GetId() )
|
||||
{
|
||||
writeln_d( " - channel ", currChannel, " has already won this job" );
|
||||
return -MATH.DOUBLE_MAX();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
writeln_d( " - SlantRangeTo(", track.TargetName(), ")=", PLATFORM.SlantRangeTo(track),
|
||||
" | platformLoc=", PLATFORM.Location().X(), ":", PLATFORM.Location().Y(), ":", PLATFORM.Location().Z(),
|
||||
" | trackLoc=", track.CurrentLocation().X(), ":", track.CurrentLocation().Y(), ":", track.CurrentLocation().Z() );
|
||||
if ( InInterceptEnvelopeOf(track, "engagement_zone") ) // tracking range is the max
|
||||
{
|
||||
// bid max on jobs that we have fired on
|
||||
if( NumWeaponsActive( track ) > 0 )
|
||||
{
|
||||
writeln_d( " - platform: ", PLATFORM.Name(), " has no active weapons." );
|
||||
return MATH.DOUBLE_MAX();
|
||||
}
|
||||
|
||||
//bids based on range to the job's track
|
||||
double JobBidValue = 1.0 / PLATFORM.SlantRangeTo(track);
|
||||
writeln_d(" - platform: ", PLATFORM.Name(), " bidding: ", JobBidValue, " on job: ", JOB.Name(), " - ", JOB.GetDescription() );
|
||||
return JobBidValue;
|
||||
}
|
||||
|
||||
writeln_d(" - platform: ", PLATFORM.Name(), " out of range of track ", track.TargetName() );
|
||||
return -MATH.DOUBLE_MAX();
|
||||
end_query_bid_type
|
||||
|
||||
end_processor
|
||||
Reference in New Issue
Block a user