Jump to content

Using MOOSE to Calculate/Communicate Relative Positions/Heading


Recommended Posts

Posted

I'm working on a simple script, but it has a complicated piece I can see value in learning for applications. Here's what I'm trying to do:

 

1) Calculate the distance between two group objects

 

2) Determine the bearing from one to the other

 

3) Translate this in a way that it can all be communicated in a message constructor (some "GetXxxx()" methods can't immediately, such as GetVec2())

 

Am I chasing another month-long mystery or is this doable?

 

Thanks!

The State Military (MAG 13)

 

[sIGPIC][/sIGPIC]



 

SHEEP WE-01

AV-8B BuNo 164553

VMA-214

Col J. “Poe” Rasmussen

http://www.statelyfe.com

 

Specs: Gigabyte Z390 Pro Wifi; i9-9900K; EVGA 2080 Ti Black; 32GB Corsair Vengeance LPX DDR4; Samsung 970 EVO Series M.2 SSD; WIN10; ASUS VG248QE; CV-1 and Index



Modules: A-10C; AV8B; CA; FC3; F-5; F-14; F-18; F-86; HAWK; L-39; P-51; UH1H; NTTR; Normandy; Persian Gulf

Posted (edited)

No idea on how to do it with MOOSE, anyway it's easy enough with normal DCS lua functions.

 

function choose_your_function_name() 
local group_1_pos = Group.getByName('group_1'):getUnits()[1]:getPoint()
local group_2_pos = Group.getByName('group_2'):getUnits()[1]:getPoint()
local distance = ((group_1_pos.x - group_2_pos.x)^2 + (group_1_pos.z - group_2_pos.z)^2)^0.5
local bearing_vector = {
	x = group_2_pos.x - group_1_pos.x, 
	y = group_2_pos.y - group_1_pos.y, 
	z = group_2_pos.z - group_1_pos.z
	}
local bearing_rad = math.atan2(bearing_vector.z, bearing_vector.x)
if bearing_rad < 0 then
		bearing_rad = bearing_rad + (2 * math.pi) 
	end
   local bearing = math.deg(bearing_rad)
trigger.action.outText('enemy group bearing '..bearing..'° at '..distance, 10)
end

choose_your_function_name() 

 

Please note that:

  • the bearing value is true bearing, as in the F-10 map. add/subtract local magnetic variation if you want to
  • distance is 2D and in meters. divide by 1852 for nm
  • all values are not rounded

 

Have fun!

Edited by catt42
Posted

Thank you Catt. I think I understand what's happening in this. I'm not too familiar with regular LUA scripting for DCS—though I keep trying to learn.

 

Each group will only have one unit. Is it still necessary to have the getUnits()[1] in there? Just curious.

 

Thanks again. This is great.

The State Military (MAG 13)

 

[sIGPIC][/sIGPIC]



 

SHEEP WE-01

AV-8B BuNo 164553

VMA-214

Col J. “Poe” Rasmussen

http://www.statelyfe.com

 

Specs: Gigabyte Z390 Pro Wifi; i9-9900K; EVGA 2080 Ti Black; 32GB Corsair Vengeance LPX DDR4; Samsung 970 EVO Series M.2 SSD; WIN10; ASUS VG248QE; CV-1 and Index



Modules: A-10C; AV8B; CA; FC3; F-5; F-14; F-18; F-86; HAWK; L-39; P-51; UH1H; NTTR; Normandy; Persian Gulf

Posted

Yes, it is. getPoint requires an unit object to work, if you think about it the position of a group is formation dependant, while the position of an unit is a point.

getUnits()[1] will select the group leader, even if it's a one-unit group

Posted

Understood. Thanks for clarifying.

The State Military (MAG 13)

 

[sIGPIC][/sIGPIC]



 

SHEEP WE-01

AV-8B BuNo 164553

VMA-214

Col J. “Poe” Rasmussen

http://www.statelyfe.com

 

Specs: Gigabyte Z390 Pro Wifi; i9-9900K; EVGA 2080 Ti Black; 32GB Corsair Vengeance LPX DDR4; Samsung 970 EVO Series M.2 SSD; WIN10; ASUS VG248QE; CV-1 and Index



Modules: A-10C; AV8B; CA; FC3; F-5; F-14; F-18; F-86; HAWK; L-39; P-51; UH1H; NTTR; Normandy; Persian Gulf

Posted (edited)

Here is MOOSE script that reports range and bearing once by message when range reaches 14000 meters then stops the check schedule:

 

 

From_Grp = UNIT:FindByName( "B17" )   -- Instantiate groups of interest
To_Grp = GROUP:FindByName( "P51" )

SCHEDULER:New( nil, --  Scheduler optional
 function()

     To_GrpCoord = To_Grp:GetCoordinate()  -- Get To_Grp group coordinate
     From_GrpCoord = From_Grp:GetCoordinate()     -- Convert Vec3 to Coordinate
     To_GrpDist = From_GrpCoord:Get2DDistance( To_GrpCoord )  -- Returns distance in meters   

   if To_GrpDist <= 14000 then  -- Optional message conditions. 14000 ~ 7.2 NM 

     To_GrpVector = From_GrpCoord:GetDirectionVec3( To_GrpCoord )  --Returns vector in Vec3 to To_Grp
     To_GrpBearing = From_GrpCoord:GetAngleRadians( To_GrpVector ) -- Returns bearing Bomber to To_Grp
     To_GrpBR = From_GrpCoord:GetBRText( To_GrpBearing, To_GrpDist, _SETTINGS:SetImperial() )  -- Returns bearing, distance text
     WelcomeMsg = "Colt 1, Springfield 3. Visual, bearing ".. To_GrpBR

     MessageTo_Grp = MESSAGE:New( WelcomeMsg, 15, nil ):ToAll()
     Scheduler:Stop()
   end
               
   end, {}, 1, 1  -- Freq must be high to get accurate BR message
 )

Edited by Habu_69
  • Like 1
  • 1 year later...
Posted

Thanks for the insight! I have changed it to get bearing and distance to and from two different zones. Here's the code:

function choose_your_function_name() 
 --local group_1_pos = Group.getByName('group_1'):getUnits()[1]:getPoint()--from
 --local group_2_pos = Group.getByName('group_2'):getUnits()[1]:getPoint()--to
 
 local group_1_pos = trigger.misc.getZone("zone1").point--zone from
 local group_2_pos = trigger.misc.getZone("zone2").point--zone to
 
 local distance = ((group_1_pos.x - group_2_pos.x)^2 + (group_1_pos.z - group_2_pos.z)^2)^0.5--distance in meters
 local bearing_vector = {
   x = group_2_pos.x - group_1_pos.x, 
   y = group_2_pos.y - group_1_pos.y, 
   z = group_2_pos.z - group_1_pos.z
   }--magic math for the bearing
 local bearing_rad = math.atan2(bearing_vector.z, bearing_vector.x)
 if bearing_rad < 0 then
     bearing_rad = bearing_rad + (2 * math.pi) 
   end--end of magic math
 local bearing = math.deg(bearing_rad)--this is the bearing
 --trigger.action.outText('enemy group bearing '..bearing..'° at '..distance, 10)--original last line of code
 actualBearing = string.format("%.0f",bearing)--remove the decimals from the bearing
 actualBearing = string.format("%03d",actualBearing)--make the bearing always 3 digits. ads a '0' or '00'
 --math for kilometers with no decimals
 actualDistanceKm = distance/1000
 actualDistanceKm = string.format("%.0f",actualDistanceKm)
 --math for nautical miles with no decimals
 actualDistanceNm = distance/1852
 actualDistanceNm = string.format("%.0f",actualDistanceNm)
 --the message sent
 trigger.action.outText('enemy group bearing '.. actualBearing .. '/' .. actualDistanceNm .. ' nm || ' .. actualBearing.. '/' ..actualDistanceKm..' km', 10)
end

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...