init
This commit is contained in:
398
processors/timeline_agents/common_timeline_scripts.txt
Normal file
398
processors/timeline_agents/common_timeline_scripts.txt
Normal file
@@ -0,0 +1,398 @@
|
||||
# ****************************************************************************
|
||||
# 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.
|
||||
# ****************************************************************************
|
||||
|
||||
script WsfLocalTrack GetMasterTrackByName(WsfPlatform aPlatform, string trackName)
|
||||
WsfLocalTrackList trackList = aPlatform.MasterTrackList();
|
||||
foreach (WsfLocalTrack track in trackList)
|
||||
{
|
||||
if (track.TargetName() == trackName)
|
||||
{
|
||||
return track;
|
||||
}
|
||||
}
|
||||
WsfLocalTrack x; # since we can't return null
|
||||
return x;
|
||||
end_script
|
||||
|
||||
|
||||
# aSpeed in meters per second, current platform speed
|
||||
# aMaxG in units of gravity (1g equivalent to 9.8 m/s^2)
|
||||
# adjust to min of 2 G if less is passed in
|
||||
script double TurnRadius(double aSpeed, double aMaxG)
|
||||
#RadialAccel = Speed^2/Radius
|
||||
double RadialAccel = aMaxG * Earth.ACCEL_OF_GRAVITY();
|
||||
if (aMaxG < 2.0)
|
||||
{
|
||||
RadialAccel = 2.0 * Earth.ACCEL_OF_GRAVITY();
|
||||
}
|
||||
double turnRadius = aSpeed * aSpeed / RadialAccel;
|
||||
return turnRadius;
|
||||
end_script
|
||||
|
||||
|
||||
#maxG in units of gravity (1g equivalent to 9.8 m/s^2)
|
||||
#adjust to min of 2 G if less is passed in
|
||||
script double TimeToTurnAndFace(WsfTrack turner, WsfGeoPoint targetPoint, double maxG)
|
||||
if (!turner.IsValid())
|
||||
{
|
||||
return MATH.DOUBLE_MAX();
|
||||
}
|
||||
double TurnAzimuth = MATH.Fabs(turner.RelativeBearingTo(targetPoint));
|
||||
double Speed = turner.Speed();
|
||||
double Radius = TurnRadius(Speed, maxG);
|
||||
double TurningCircleCircumference = 2.0 * MATH.PI() * Radius;
|
||||
double TurningArc = (TurnAzimuth/360)*TurningCircleCircumference;
|
||||
double TimeToTurn = TurningArc / Speed;
|
||||
return TimeToTurn;
|
||||
end_script
|
||||
|
||||
script double DistanceClosedDuringTurn(double turnAngle, double turnRadius)
|
||||
#lock the turn angle into [0,180]
|
||||
turnAngle = MATH.Fabs(MATH.NormalizeAngleMinus180_180(turnAngle));
|
||||
#a max turn (from relative bearing 180 back to 0 means we didn't close any distance at all
|
||||
#plot closing speed as a function of relative angle
|
||||
#this gives you a cosine curve from 0 to 180 with an amplitude of speed
|
||||
#use calculus for integrating the cosine curve from the relative angle the turner starts at back to zero
|
||||
#if solving for total area under curve, you break up an integral whenever it crosses the X axis
|
||||
#in our case, we don't want total area, we want positive area (positive closing speed)
|
||||
#so integrating cosine from [0,angle] where angle <= 180, we dont have to break it up into multiple integrals
|
||||
#integral of cosine is sin
|
||||
#showing -sin(0) for completeness when integrating
|
||||
double scale = MATH.Sin(turnAngle) - MATH.Sin(0);
|
||||
double distanceClosed = scale * turnRadius;
|
||||
return distanceClosed;
|
||||
end_script
|
||||
|
||||
script bool TurnAngleTimeAndDistance(double angle, double speed, double maxG, Array<double> TimeAndDistance)
|
||||
if (!TimeAndDistance.IsValid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
angle = MATH.Fabs(MATH.NormalizeAngleMinus180_180(angle));
|
||||
double Radius = TurnRadius(speed, maxG);
|
||||
double TurningCircleCircumference = 2.0 * MATH.PI() * Radius;
|
||||
double TurningArc = (angle/360)*TurningCircleCircumference;
|
||||
double TimeToTurn = TurningArc / speed;
|
||||
double DistanceClosed = DistanceClosedDuringTurn(angle, Radius);
|
||||
TimeAndDistance.Clear();
|
||||
TimeAndDistance.PushBack(TimeToTurn);
|
||||
TimeAndDistance.PushBack(DistanceClosed);
|
||||
return true;
|
||||
end_script
|
||||
|
||||
|
||||
#maxG in units of gravity (1g equivalent to 9.8 m/s^2)
|
||||
#adjust to min of 2 G if less is passed in
|
||||
script bool TurnTimeAndDistance(WsfTrack turner, WsfGeoPoint targetPoint, double maxG, Array<double> TimeAndDistance)
|
||||
if (!turner.IsValid() || !targetPoint.IsValid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
double angle = MATH.Fabs(turner.RelativeBearingTo(targetPoint));
|
||||
return TurnAngleTimeAndDistance(angle, turner.Speed(), maxG, TimeAndDistance);
|
||||
end_script
|
||||
|
||||
|
||||
script double TimeToTurnFrom(WsfPlatform plat, double speed, WsfTrack threat, double maxG)
|
||||
double runAwayTurn = 180 - MATH.Fabs(plat.RelativeBearingTo(threat));
|
||||
double radius = TurnRadius(speed, maxG);
|
||||
double turnCircle = 2.0 * MATH.PI() * radius;
|
||||
double turnArc = (runAwayTurn/360)*turnCircle;
|
||||
double turnTime = turnArc / speed;
|
||||
return turnTime;
|
||||
end_script
|
||||
|
||||
# Calculate how long it taks a platform to turn the specified angle
|
||||
# at specified speed (m/s) and max G
|
||||
script double TimeToTurn(double angle, double speed, double maxG)
|
||||
double radius = TurnRadius(speed, maxG);
|
||||
double turnCircle = 2.0 * MATH.PI() * radius;
|
||||
double turnArc = (angle/360)*turnCircle;
|
||||
double turnTime = turnArc / speed;
|
||||
return turnTime;
|
||||
end_script
|
||||
|
||||
#assumes current speed maintained
|
||||
script double TimeToReachPoint(WsfTrack traveler, WsfGeoPoint targetPoint, double maxG)
|
||||
if (!traveler.IsValid())
|
||||
{
|
||||
return MATH.DOUBLE_MAX();
|
||||
}
|
||||
double Speed = traveler.Speed();
|
||||
if (Speed <= 0.0)
|
||||
{
|
||||
return MATH.DOUBLE_MAX();
|
||||
}
|
||||
Array<double> vals = Array<double>();
|
||||
TurnTimeAndDistance(traveler, targetPoint, maxG, vals);
|
||||
double TurnTime = vals[0];
|
||||
double DistClosed = vals[1];
|
||||
double TravelLegDist = traveler.GroundRangeTo(targetPoint) - DistClosed;
|
||||
double TravelLegTime = TravelLegDist / traveler.Speed();
|
||||
double TimeToReach = TurnTime + TravelLegTime;
|
||||
return TimeToReach;
|
||||
end_script
|
||||
|
||||
|
||||
#bubble sort
|
||||
script void SortTracksByValue(Array<WsfTrack> tracks, Array<double> values)
|
||||
if(tracks.Size() != values.Size())
|
||||
return;
|
||||
bool swapped = true;
|
||||
int j = 0;
|
||||
WsfTrack tempTrack;
|
||||
double tempValue;
|
||||
while (swapped)
|
||||
{
|
||||
swapped = false;
|
||||
j += 1;
|
||||
for (int i=0; i<(values.Size())-j; i+=1)
|
||||
{
|
||||
if (values[i] > values[i+1])
|
||||
{
|
||||
tempValue = values[i]; tempTrack = tracks[i];
|
||||
values[i] = values[i+1]; tracks[i] = tracks[i+1];
|
||||
values[i+1] = tempValue; tracks[i+1] = tempTrack;
|
||||
swapped = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
end_script
|
||||
|
||||
script void SortLocalTracksByValue(Array<WsfLocalTrack> tracks, Array<double> values)
|
||||
if(tracks.Size() != values.Size())
|
||||
return;
|
||||
bool swapped = true;
|
||||
int j = 0;
|
||||
WsfLocalTrack tempTrack;
|
||||
double tempValue;
|
||||
while (swapped)
|
||||
{
|
||||
swapped = false;
|
||||
j += 1;
|
||||
for (int i=0; i<(values.Size())-j; i+=1)
|
||||
{
|
||||
if (values[i] > values[i+1])
|
||||
{
|
||||
tempValue = values[i]; tempTrack = tracks[i];
|
||||
values[i] = values[i+1]; tracks[i] = tracks[i+1];
|
||||
values[i+1] = tempValue; tracks[i+1] = tempTrack;
|
||||
swapped = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
end_script
|
||||
|
||||
script WsfGeoPoint GetAssetCentroid(Array<WsfAssetPerception> ASSETS)
|
||||
if (ASSETS.Size() <= 0)
|
||||
{
|
||||
return WsfGeoPoint.Construct(0,0,0);
|
||||
}
|
||||
double coeff = 1.0/((double)ASSETS.Size());
|
||||
Vec3 wcs = Vec3.Construct(0,0,0);
|
||||
foreach (WsfAssetPerception p in ASSETS)
|
||||
{
|
||||
Vec3 vec = p.Location().LocationWCS();
|
||||
vec.Scale(coeff);
|
||||
wcs = Vec3.Add(wcs, vec);
|
||||
}
|
||||
return WsfGeoPoint.ConstructWCS(wcs);
|
||||
end_script
|
||||
|
||||
script WsfTask GetTimeLineTask(WsfQuantumTaskerProcessor proc)
|
||||
WsfTaskList taskList = proc.TasksReceivedOfType("TIMELINE");
|
||||
if (taskList.Count() > 0)
|
||||
{
|
||||
return taskList.Entry(0);
|
||||
}
|
||||
WsfTask retTask; #dummy task
|
||||
return retTask;
|
||||
end_script
|
||||
|
||||
script double GetTimeLineTaskValueForKey(WsfTask timeline, string aKeyVal)
|
||||
if (timeline.IsValid())
|
||||
{
|
||||
if (timeline.AuxDataExists(aKeyVal))
|
||||
{
|
||||
return timeline.AuxDataDouble(aKeyVal);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeln_d(aKeyVal, " not found in ", timeline.TaskType() );
|
||||
}
|
||||
}
|
||||
return -1.0;
|
||||
end_script
|
||||
|
||||
script double GetTimeLineValueForKey(WsfQuantumTaskerProcessor proc, string aKeyVal)
|
||||
WsfTask timeline = GetTimeLineTask(proc);
|
||||
return GetTimeLineTaskValueForKey(timeline, aKeyVal);
|
||||
end_script
|
||||
|
||||
script WsfTrack GetTimeLineTaskTargetTrack(WsfPlatform plat, WsfTask timeline)
|
||||
WsfTrack t; #stub track
|
||||
if (timeline.IsValid())
|
||||
{
|
||||
if (timeline.AuxDataExists("targets"))
|
||||
{
|
||||
Array<WsfTrack> trkList = (Array<WsfTrack>)timeline.AuxDataObject("targets");
|
||||
foreach (WsfTrack trk in trkList)
|
||||
{
|
||||
if (trk.IsValid())
|
||||
{
|
||||
#see if the track can be found in local track list, if so return the distance
|
||||
WsfLocalTrack myTrack = GetMasterTrackByName(plat, trk.TargetName());
|
||||
if (myTrack.IsValid())
|
||||
{
|
||||
return myTrack;
|
||||
}
|
||||
#if the task assigned track isn't a track on the current platform, use the information given
|
||||
else
|
||||
{
|
||||
return trk;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return t;
|
||||
end_script
|
||||
|
||||
script WsfTrack GetTimeLineTargetTrack(WsfPlatform plat, WsfQuantumTaskerProcessor proc)
|
||||
WsfTask timeline = GetTimeLineTask(proc);
|
||||
return GetTimeLineTaskTargetTrack(plat, timeline);
|
||||
end_script
|
||||
|
||||
script Array<WsfTrack> GetTimeLineTaskTargets(WsfTask timeline)
|
||||
Array<WsfTrack> targets;
|
||||
if (timeline.IsValid() && timeline.AuxDataExists("targets"))
|
||||
{
|
||||
targets = (Array<WsfTrack>)timeline.AuxDataObject("targets");
|
||||
}
|
||||
else
|
||||
{
|
||||
targets = Array<WsfTrack>();
|
||||
}
|
||||
return targets;
|
||||
end_script
|
||||
|
||||
script Array<WsfTrack> GetTimeLineTargets(WsfQuantumTaskerProcessor proc)
|
||||
WsfTask timeline = GetTimeLineTask(proc);
|
||||
return GetTimeLineTaskTargets(timeline);
|
||||
end_script
|
||||
|
||||
script WsfTrack GetNearestTimeLineTaskTarget(WsfPlatform plat, WsfTask timeline)
|
||||
WsfTrack nearestTrack; #empty at first
|
||||
Array<WsfTrack> trkList = GetTimeLineTaskTargets(timeline);
|
||||
double nearest = MATH.DOUBLE_MAX();
|
||||
foreach (WsfTrack trk in trkList)
|
||||
{
|
||||
if (trk.IsValid())
|
||||
{
|
||||
double dist = plat.GroundRangeTo(trk.CurrentLocation());
|
||||
if (dist < nearest)
|
||||
{
|
||||
nearest = dist;
|
||||
nearestTrack = trk;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nearestTrack;
|
||||
end_script
|
||||
|
||||
script WsfTrack GetNearestTimeLineTarget(WsfPlatform plat, WsfQuantumTaskerProcessor proc)
|
||||
WsfTask timeline = GetTimeLineTask(proc);
|
||||
return GetNearestTimeLineTaskTarget(plat, timeline);
|
||||
end_script
|
||||
|
||||
script WsfLocalTrack GetNearestTimeLineTaskLocalTarget(WsfPlatform plat, WsfTask timeline)
|
||||
WsfLocalTrack nearestLocalTrack; #empty at first
|
||||
Array<WsfTrack> trkList = GetTimeLineTaskTargets(timeline);
|
||||
double nearest = MATH.DOUBLE_MAX();
|
||||
foreach (WsfTrack trk in trkList)
|
||||
{
|
||||
WsfLocalTrack lt = GetMasterTrackByName(plat,trk.TargetName());
|
||||
if (lt.IsValid())
|
||||
{
|
||||
double dist = plat.GroundRangeTo(lt.CurrentLocation());
|
||||
|
||||
if (dist < nearest)
|
||||
{
|
||||
nearest = dist;
|
||||
nearestLocalTrack = lt;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nearestLocalTrack;
|
||||
end_script
|
||||
|
||||
|
||||
script Array<WsfLocalTrack> GetTimeLineTaskLocalTargets(WsfPlatform plat, WsfTask timeline)
|
||||
Array<WsfTrack> targets = GetTimeLineTaskTargets(timeline);
|
||||
Array<WsfLocalTrack> localTargets = Array<WsfLocalTrack>();
|
||||
foreach(WsfTrack t in targets)
|
||||
{
|
||||
WsfLocalTrack lt = GetMasterTrackByName(plat, t.TargetName());
|
||||
if (lt.IsValid())
|
||||
{
|
||||
localTargets.PushBack(lt);
|
||||
}
|
||||
}
|
||||
return localTargets;
|
||||
end_script
|
||||
|
||||
script Array<WsfLocalTrack> GetTimeLineLocalTargets(WsfPlatform plat, WsfQuantumTaskerProcessor proc)
|
||||
WsfTask timeline = GetTimeLineTask(proc);
|
||||
return GetTimeLineTaskLocalTargets(plat, timeline);
|
||||
end_script
|
||||
|
||||
|
||||
script bool FiredOn(WsfPlatform shooter, WsfLocalTrack target, bool checkPeers)
|
||||
if ((shooter.WeaponsPendingFor(target.TrackId()) + shooter.WeaponsActiveFor(target.TrackId())) > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (checkPeers)
|
||||
{
|
||||
foreach(WsfPlatform peer in shooter.Peers())
|
||||
{
|
||||
WsfLocalTrack peerTrack = GetMasterTrackByName(peer,target.TargetName());
|
||||
if (peerTrack.IsValid())
|
||||
{
|
||||
if ((peer.WeaponsPendingFor(peerTrack.TrackId()) + peer.WeaponsActiveFor(peerTrack.TrackId())) > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
end_script
|
||||
|
||||
|
||||
script double GetTargetDistance(WsfPlatform plat, WsfQuantumTaskerProcessor proc)
|
||||
WsfTrack targetTrack = GetNearestTimeLineTarget(plat, proc);
|
||||
|
||||
if (targetTrack.IsValid())
|
||||
{
|
||||
# if (targetTrack.Target().IsValid() && PLATFORM.IsValid())
|
||||
# {
|
||||
# draw.SetLineStyle("solid");
|
||||
# draw.BeginLines();
|
||||
# draw.SetColor(1.0, 0.0, 1.0);
|
||||
# draw.Vertex(PLATFORM);
|
||||
# draw.Vertex(targetTrack.Target());
|
||||
# draw.End();
|
||||
# }
|
||||
|
||||
double dist = plat.GroundRangeTo(targetTrack.CurrentLocation());
|
||||
return dist;
|
||||
}
|
||||
return -1;
|
||||
end_script
|
||||
Reference in New Issue
Block a user