298 lines
8.2 KiB
Plaintext
298 lines
8.2 KiB
Plaintext
|
|
# File generated by Wizard 2.9.0 on Dec 22, 2024.
|
||
|
|
processor airControl WSF_SCRIPT_PROCESSOR
|
||
|
|
|
||
|
|
update_interval 10 sec
|
||
|
|
|
||
|
|
script_variables
|
||
|
|
string zNameOrPoint = "tw";
|
||
|
|
string zType = "polygon";
|
||
|
|
WsfTrackList tl = PLATFORM.MasterRawTrackList();
|
||
|
|
double Radius = 50000;
|
||
|
|
bool isOver = false;
|
||
|
|
double LLR = 175000;
|
||
|
|
double LR = 100000;
|
||
|
|
double MR = 50000;
|
||
|
|
double SR = 30000;
|
||
|
|
double a = 10000000;
|
||
|
|
bool laststate = false;
|
||
|
|
bool finish = false;
|
||
|
|
double startaTime = 0;
|
||
|
|
double lastTime = 30;
|
||
|
|
WsfWeapon aa_mrm = PLATFORM.Weapon("aa_mrm"); //
|
||
|
|
WsfTrack currentTarget; //
|
||
|
|
end_script_variables
|
||
|
|
|
||
|
|
//
|
||
|
|
//@ flyPolygonalZone
|
||
|
|
//
|
||
|
|
script void flyPolygonalZone(string zName)
|
||
|
|
WsfZone zone = zone.FindZone(zName);
|
||
|
|
PLATFORM.GoToSpeed(1000,999);
|
||
|
|
PLATFORM.GoToLocation(zone.Location());
|
||
|
|
end_script
|
||
|
|
|
||
|
|
//
|
||
|
|
//@ flyCircleZone
|
||
|
|
//
|
||
|
|
script void flyCircleZone(string zPoint)
|
||
|
|
WsfGeoPoint p = p.Construct(zPoint);
|
||
|
|
PLATFORM.GoToSpeed(1000,999);
|
||
|
|
PLATFORM.GoToLocation(p);
|
||
|
|
end_script
|
||
|
|
|
||
|
|
//
|
||
|
|
//@ fly the zone
|
||
|
|
//
|
||
|
|
script void flyZone(string zNameOrPoint,string zType)
|
||
|
|
if(zType == "polygon")
|
||
|
|
{
|
||
|
|
flyPolygonalZone(zNameOrPoint);
|
||
|
|
}
|
||
|
|
else if(zType == "circle")
|
||
|
|
{
|
||
|
|
flyCircleZone(zNameOrPoint);
|
||
|
|
}
|
||
|
|
end_script
|
||
|
|
|
||
|
|
//
|
||
|
|
//@ isInZone
|
||
|
|
//
|
||
|
|
script bool isInZone(string zNameOrPoint,string zType)
|
||
|
|
if(zType == "polygon")
|
||
|
|
{
|
||
|
|
WsfZone zone = zone.FindZone(zNameOrPoint);
|
||
|
|
return (PLATFORM.GroundRangeTo(zone.Location())<=100);
|
||
|
|
}
|
||
|
|
else if(zType == "circle")
|
||
|
|
{
|
||
|
|
WsfGeoPoint p = p.Construct(zNameOrPoint);
|
||
|
|
return (PLATFORM.GroundRangeTo(p) < 1000);
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
end_script
|
||
|
|
|
||
|
|
|
||
|
|
// Calculate the distance to the nearest enemy target and return that target's Track
|
||
|
|
script WsfTrack GetClosestEnemy()
|
||
|
|
PLATFORM->closestTrack = WsfTrack();
|
||
|
|
// Initialize an empty WsfTrack object
|
||
|
|
double minDistance = 9999999.0; // Set an extremely large initial distance
|
||
|
|
|
||
|
|
// Iterate through all targets to find the nearest enemy
|
||
|
|
for (int i = 0; i < PLATFORM.MasterTrackList().Count(); i = i + 1)
|
||
|
|
{
|
||
|
|
WsfTrack tempTrack = PLATFORM.MasterTrackList().TrackEntry(i); // Get the target
|
||
|
|
|
||
|
|
if (tempTrack.IsValid() && tempTrack.BelievedAlive()) // If the target is valid
|
||
|
|
{
|
||
|
|
double distanceToTarget = PLATFORM.GroundRangeTo(tempTrack); // Calculate the ground distance from the current platform to the target
|
||
|
|
|
||
|
|
if (distanceToTarget < minDistance) // If this target is closer
|
||
|
|
{
|
||
|
|
minDistance = distanceToTarget; // Update the minimum distance
|
||
|
|
PLATFORM->closestTrack = tempTrack; // Update the nearest target
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return PLATFORM->closestTrack; // Return the nearest target
|
||
|
|
end_script
|
||
|
|
|
||
|
|
# script bool isHaveTarget()
|
||
|
|
# return(PLATFORM.MasterTrackList().Count() > 0);
|
||
|
|
# end_script
|
||
|
|
|
||
|
|
//
|
||
|
|
//@ bounds Patrol
|
||
|
|
//
|
||
|
|
script void airPolygonPatrol(string zNameOrPoint)
|
||
|
|
WsfZone zone = zone.FindZone(zNameOrPoint);
|
||
|
|
Array<WsfGeoPoint> boundsPoints = zone.PolyPoints();
|
||
|
|
WsfRoute route;
|
||
|
|
WsfRoute r1 = route.Create("lx");
|
||
|
|
foreach(WsfGeoPoint vertex in boundsPoints)
|
||
|
|
{
|
||
|
|
vertex.SetAltitudeHAE(10000);
|
||
|
|
r1.Append(vertex,1500);
|
||
|
|
}
|
||
|
|
r1.Waypoint(0).SetLabel("start");
|
||
|
|
r1.Waypoint(r1.Size() - 1).SetGoToLabel("start");
|
||
|
|
PLATFORM.FollowRoute(r1);
|
||
|
|
isOver =true;
|
||
|
|
end_script
|
||
|
|
|
||
|
|
//
|
||
|
|
//@ generateCirclePoints
|
||
|
|
//
|
||
|
|
script Array<WsfGeoPoint> generateCirclePoints(string Center , double radius)
|
||
|
|
WsfGeoPoint center= WsfGeoPoint.Construct(Center);
|
||
|
|
Array<WsfGeoPoint>circlePoints={};
|
||
|
|
double earthRadius =6371000.0;
|
||
|
|
double angularDistance =radius /earthRadius;
|
||
|
|
Array<double>angles ={0.0,120,240};
|
||
|
|
foreach(double angle in angles)
|
||
|
|
{
|
||
|
|
double latCenter=center.Latitude()* MATH.PI()/ 180.0;
|
||
|
|
double loncenter= center.Longitude()* MATH.PI()/ 180.0;
|
||
|
|
double lat= MATH.ASin(MATH.Sin(latCenter)
|
||
|
|
* MATH.Cos(angularDistance)
|
||
|
|
+ MATH.Cos(latCenter)
|
||
|
|
* MATH.Sin(angularDistance)
|
||
|
|
* MATH.Cos(angle));
|
||
|
|
|
||
|
|
double lon = loncenter +MATH.ATan2(MATH.Sin(angle)
|
||
|
|
* MATH.Sin(angularDistance)
|
||
|
|
* MATH.Cos(latCenter)
|
||
|
|
, MATH.Cos(angularDistance)
|
||
|
|
- MATH.Sin(latCenter)
|
||
|
|
* MATH.Sin(lat));
|
||
|
|
circlePoints.PushBack(WsfGeoPoint.Construct(lat*180.0/MATH.PI() , lon *180.0 / MATH.PI(),5000));
|
||
|
|
}
|
||
|
|
return circlePoints;
|
||
|
|
end_script
|
||
|
|
|
||
|
|
//
|
||
|
|
//@ circle execute
|
||
|
|
//
|
||
|
|
script void executeCircularPatrol(string zNameOrPoint)
|
||
|
|
Array<WsfGeoPoint> circlePoints = generateCirclePoints(zNameOrPoint,Radius);
|
||
|
|
WsfRoute route;
|
||
|
|
WsfRoute r1= route.Create("lx");
|
||
|
|
foreach(WsfGeoPoint vertex in circlePoints)
|
||
|
|
{
|
||
|
|
vertex.SetAltitudeHAE(10000);
|
||
|
|
r1.Append(vertex,1500);
|
||
|
|
}
|
||
|
|
|
||
|
|
r1.Waypoint(0).SetLabel("start");
|
||
|
|
r1 .Waypoint(r1.Size()-1).SetGoToLabel("start");
|
||
|
|
PLATFORM.FollowRoute(r1);
|
||
|
|
# r1.Print();
|
||
|
|
isOver =true;
|
||
|
|
end_script
|
||
|
|
|
||
|
|
//
|
||
|
|
//@ execute patrol
|
||
|
|
//
|
||
|
|
script void executePatrol(string zNameOrPoint,string zType)
|
||
|
|
if(zType == "polygon")
|
||
|
|
{
|
||
|
|
airPolygonPatrol(zNameOrPoint);
|
||
|
|
}
|
||
|
|
else if(zType == "circle" )
|
||
|
|
{
|
||
|
|
executeCircularPatrol(zNameOrPoint);
|
||
|
|
}
|
||
|
|
end_script
|
||
|
|
|
||
|
|
//
|
||
|
|
//@ isDecectedTarget
|
||
|
|
//
|
||
|
|
script bool isDecectedTarget()
|
||
|
|
return(PLATFORM.MasterTrackList().Count() > 0 &&
|
||
|
|
aa_mrm.QuantityRemaining() > 0
|
||
|
|
# PLATFORM->closestTrack.IsValid()
|
||
|
|
);
|
||
|
|
end_script
|
||
|
|
|
||
|
|
//
|
||
|
|
//
|
||
|
|
//@ finishIntercept
|
||
|
|
//
|
||
|
|
script bool finishIntercept()
|
||
|
|
bool finished = false;
|
||
|
|
WsfTrack closestTarget = GetClosestEnemy();
|
||
|
|
if (closestTarget.IsNull() || closestTarget.BelievedDead())
|
||
|
|
{
|
||
|
|
writeln("Target is destroyed or not valid.");
|
||
|
|
finished = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
double currentTime = TIME_NOW;
|
||
|
|
if (currentTime - startaTime >= lastTime)
|
||
|
|
{
|
||
|
|
writeln("Task timeout.");
|
||
|
|
finished = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
return finished;
|
||
|
|
end_script
|
||
|
|
|
||
|
|
|
||
|
|
//
|
||
|
|
//@ ON aa_intercept
|
||
|
|
//
|
||
|
|
script void trunOnIntercept()
|
||
|
|
WsfProcessor launchComputer = PLATFORM.Processor("intercept");
|
||
|
|
if (! launchComputer.IsTurnedOn())
|
||
|
|
{
|
||
|
|
writeln("Starting attack at T=", TIME_NOW);
|
||
|
|
launchComputer.TurnOn();
|
||
|
|
}
|
||
|
|
end_script
|
||
|
|
|
||
|
|
//
|
||
|
|
//@ OFF aa_intercept
|
||
|
|
//
|
||
|
|
script void trunOffIntercept()
|
||
|
|
WsfProcessor launchComputer = PLATFORM.Processor("intercept");
|
||
|
|
if (! launchComputer.IsTurnedOff())
|
||
|
|
{
|
||
|
|
writeln("Stoping attack at T=", TIME_NOW);
|
||
|
|
launchComputer.TurnOff();
|
||
|
|
}
|
||
|
|
end_script
|
||
|
|
|
||
|
|
/////////////////////execute//////////////////////////
|
||
|
|
execute at_time 2 sec relative
|
||
|
|
writeln("start before PROCESSOR.SetState(MOVER)");
|
||
|
|
PROCESSOR.SetState("MOVER");
|
||
|
|
end_execute
|
||
|
|
/////////////////////state////////////////////////
|
||
|
|
state MOVER
|
||
|
|
on_entry
|
||
|
|
flyZone(zNameOrPoint,zType);
|
||
|
|
end_on_entry
|
||
|
|
|
||
|
|
next_state PATROL
|
||
|
|
return isInZone(zNameOrPoint,zType);
|
||
|
|
end_next_state
|
||
|
|
|
||
|
|
next_state HIT
|
||
|
|
return isDecectedTarget();
|
||
|
|
end_next_state
|
||
|
|
|
||
|
|
on_exit
|
||
|
|
GetClosestEnemy();
|
||
|
|
end_on_exit
|
||
|
|
end_state
|
||
|
|
|
||
|
|
state PATROL
|
||
|
|
on_entry
|
||
|
|
executePatrol(zNameOrPoint,zType);
|
||
|
|
end_on_entry
|
||
|
|
|
||
|
|
next_state HIT
|
||
|
|
return isDecectedTarget();
|
||
|
|
end_next_state
|
||
|
|
|
||
|
|
on_exit
|
||
|
|
GetClosestEnemy();
|
||
|
|
end_on_exit
|
||
|
|
end_state
|
||
|
|
|
||
|
|
state HIT
|
||
|
|
on_entry
|
||
|
|
trunOnIntercept();
|
||
|
|
end_on_entry
|
||
|
|
|
||
|
|
next_state PATROL
|
||
|
|
return (!isDecectedTarget());
|
||
|
|
end_next_state
|
||
|
|
|
||
|
|
on_exit
|
||
|
|
trunOffIntercept();
|
||
|
|
end_on_exit
|
||
|
|
end_state
|
||
|
|
|
||
|
|
end_processor
|