Jump to content

Using MOOSE to Calculate/Communicate Relative Positions/Heading


rassy7

Recommended Posts

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

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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
Link to comment
Share on other sites

  • 1 year later...

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

Link to comment
Share on other sites

  • Recently Browsing   0 members

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