Page 1 of 1

Staggered CAPs

Posted: Thu Jan 02, 2020 3:00 pm
by SeaQueen
From time to time, the existing CAP planner is insufficient because of the need to follow a specific schedule rather than just filling CAPs on an "as needed" basis. I've been working on a LUA-based solution.

I began by creating two CAPs, using the same CAP area but with different mission starting times. This got the airplanes up at the right times. In this case they are "East CAP" and "East CAP (Second Shift)." Their mission start times are one hour apart. For precision, I calculated their required mission start times on scenario load:

Code: Select all

 -- US base guids
 hickamAfb = 'gwkw9v-0hlsepaaej1ro'
 
 -- F-22 constants
 f22CruiseSpeed = 480 -- knots
 
 -- important times
 
 time0000Z = os.time{year=2020, month=1, day=1, hour=0}
 time0100Z = os.time{year=2020, month=1, day=1, hour=1}
 time0200Z = os.time{year=2020, month=1, day=1, hour=2}
 time0300Z = os.time{year=2020, month=1, day=1, hour=3}
 time0400Z = os.time{year=2020, month=1, day=1, hour=4}
 time0500Z = os.time{year=2020, month=1, day=1, hour=5}
 time0600Z = os.time{year=2020, month=1, day=1, hour=6}
 time0700Z = os.time{year=2020, month=1, day=1, hour=7}
 time0800Z = os.time{year=2020, month=1, day=1, hour=8}
 
 timeline = {time0000Z, time0100Z, time0200Z, time0300Z, time0400Z,  time0500Z, time0600Z, time0700Z, time0800Z }
 -- important distance calculations
 capEastMarker = ScenEdit_GetReferencePoint( {side='USA', name='CAP East Marker' } )
 capWestMarker = ScenEdit_GetReferencePoint( {side='USA', name='CAP West Marker' } )
 
 hickamToCAPEastDistance = Tool_Range(hickamAfb, {latitude=capEastMarker.latitude, longitude=capEastMarker.longitude})
 hickamToCAPWestDistance = Tool_Range(hickamAfb, {latitude=capWestMarker.latitude, longitude=capWestMarker.longitude})
 

Code: Select all

 -- important time calculations and constants / conversion factors
 oneSecond = 1
 oneMinute = 60 * oneSecond 
 thirtyMinutes = 30 * oneMinute
 halfHour = thirtyMinutes
 oneHour = 2 * halfHour
 
 hickamToCAPEastF22Time = hickamToCAPEastDistance / f22CruiseSpeed * oneHour
 hickamToCAPWestF22Time = hickamToCAPWestDistance / f22CruiseSpeed * oneHour
 
 --missions and mission start times
 capEastMission = ScenEdit_GetMission('USA', 'CAP East')
 capEastSecondShiftMission = ScenEdit_GetMission('USA', 'CAP East (Second Shift)')
 capWestMission = ScenEdit_GetMission('USA', 'CAP West')
 
 capEastFirstShiftCheckInTime =time0100Z
 capWestFirstShiftCheckInTime = time0100Z
 
 capEastMissionStartTime = capEastFirstShiftCheckInTime - hickamToCAPEastF22Time
 capWestMissionStartTime = capWestFirstShiftCheckInTime - hickamToCAPWestF22Time 
 

Code: Select all

 ScenEdit_SetMission('USA', capEastMission.guid , {starttime= os.date("%m/%d/%Y %I:%M:%S %p", capEastMissionStartTime )})
 ScenEdit_SetMission('USA', capWestMission.guid, {starttime = os.date("%m/%d/%Y %I:%M:%S %p", capWestMissionStartTime )})
 
 capEastSecondShiftCheckInTime =time0200Z
 capWestSecondShiftCheckInTime = time0200Z
 
 capEastMissionSecondShiftStartTime = capEastSecondShiftCheckInTime - hickamToCAPEastF22Time
 
 ScenEdit_SetMission('USA', capEastSecondShiftMission.guid , {starttime= os.date("%m/%d/%Y %I:%M:%S %p", capEastMissionSecondShiftStartTime )})
 

Next I created two data structures for storing the relevant CAP information:

Code: Select all

 -- build array of all fighters
 
 f22id = 2201
 
 fighters = {}
 
 base = ScenEdit_GetUnit( {guid=hickamAfb} )
 aircraftAtBase = base.embarkedUnits.Aircraft
 
 for i, a in ipairs(aircraftAtBase) do
     u = ScenEdit_GetUnit( {guid=a} )
     if (u.dbid == f22id) then 
         fighters[#fighters + 1] = u.guid
     end
 end
 

Code: Select all

 -- build control structures for fighters
 fighterStatus = {}
 
 -- assign the first 8 fighters to capEast
 
 for i, a in ipairs(capEastMission.unitlist) do 
        fighterStatus[ a ] = {
             mission = capEastMission.guid,
             tanker = tankerCapEastMission.guid,
             timeForNextHookup = time0200Z,
            timeForNextOnStation = time0200Z  + oneHour
     }
 end
 
 for i, a in ipairs(capEastSecondShiftMission.unitlist) do 
     fighterStatus[ a ] =  {
         mission = capEastMission.guid,
         tanker = tankerCapEastMission.guid,
         timeForNextHookup = time0300Z,
         timeForNextOnStation = time0300Z  + oneHour
     }
 end
 

Finally, I wrote a little snippet of code to run every 15 minutes:

Code: Select all

 currentTime = ScenEdit_CurrentTime() + 5*oneHour -- five hours behind for some unclear reason *bug work around?*
 
 for i, f in ipairs(fighters) do
     if (fighterStatus[ f ] ~= nil) then
         if ( currentTime >= fighterStatus[ f ].timeForNextHookup ) then
             u = ScenEdit_GetUnit({ guid=f })
             if( u.mission.guid ~= fighterStatus.tanker ) then
                 ScenEdit_AssignUnitToMission( f, fighterStatus[ f ].tanker )
                 fighterStatus[ f ].timeForNextHookup = fighterStatus[ f ].timeForNextHookup + 2 * oneHour  -- two hours, time for tanking + capping
 --                fighterStatus[ f ].timeForNextOnStation =  fighterStatus[ f ].timeForNextOnStation + oneHour
             end
         elseif ( currentTime >= fighterStatus[ f ].timeForNextOnStation ) then
             u = ScenEdit_GetUnit({ guid=f })
             if( u.mission.guid ~= fighterStatus.tanker ) then
                 ScenEdit_AssignUnitToMission( f, fighterStatus[ f ].mission )
 --                fighterStatus[ f ].timeForNextHookup = fighterStatus[ f ].timeForNextHookup + oneHour
                 fighterStatus[ f ].timeForNextOnStation =  fighterStatus[ f ].timeForNextOnStation + 2* oneHour --  two hours, time for tanking + capping
             end
         end
     end
 end
 

There's a little bit of extraneous code in there I don't need. I'll try to clean it up later.

RE: Staggared CAPs

Posted: Tue Jan 14, 2020 5:12 pm
by tiag
"currentTime = ScenEdit_CurrentTime() + 5*oneHour -- five hours behind for some unclear reason *bug work around?*"

The problem is related to the ZULU and LOCAL time. The function ScenEdit_CurrentTime() gives you the Local time, while missions use ZULU time.
Your signature say you live in USA, on the east coast, capital of USA....GMT-5=ZULU-5.....so it makes sense.

This is definitely a bug, since your code as written above will not work correctly for another guy in another time zone.

RE: Staggared CAPs

Posted: Sat Jan 18, 2020 6:58 am
by tiag
Is there any chance to correct that ZULU/LOCAl time behavior? This constrains quite a lot if one wants to export a code for other users in other time zones.

RE: Staggared CAPs

Posted: Tue Jul 21, 2020 3:32 pm
by SeaQueen
Is there any chance to correct that ZULU/LOCAl time behavior? This constrains quite a lot if one wants to export a code for other users in other time zones.

That would have to be a bug fix, because I was under the impression that the ScenEdit_CurrentTime() returned the scenario time in ZULU. ZULU is universal, you should be able to convert it into whatever you want.

RE: Staggared CAPs

Posted: Wed Jul 22, 2020 2:13 am
by Rory Noonan
There's a function to return each of Zulu
https://commandlua.github.io/#ScenEdit_CurrentTime
and Lima (local)
https://commandlua.github.io/#ScenEdit_CurrentLocalTime

Zulu / ScenEdit_CurrentTime is returned as a timestamp (i.e. number of seconds since / before 1/1/1970)
Lima / ScenEdit_CurrentLocalTime is returned as hh:mm:ss

Let us know in tech support if there are issues with these or if you need other tools to accomplish your desired task [:)]

RE: Staggared CAPs

Posted: Wed Jul 22, 2020 9:49 am
by SeaQueen
Doh! Thanks! :-)

Wait... doesn't local time require a position? Or is that the system local time? If I'm shooting ballistic missiles from North Dakota local is whatever it is out there in the middle of nowhere, and the target would have a different local time. How does it pick a time zone?