Jump to content

Set unit's heading, or add waypoint with Direction/Distance?


Recommended Posts

Posted

Hey guys.

Is it possible to create a waypoint for a group at a particular direction/distance?

I've got a script that is determining the direction I'd like the group to move, but I can't figure out create a vec2/3 with a given direction and distance from a point (the unit in question)

Posted

Its trigonometry. At the basics you just need to take an angle, use math.sin/math.cos on the angle, multiply by distance and add it to a reference point. Keep in mind the az in this code is in radians, so you might need to convert it.

local vec = mist.vec.sub(z1.point, z2.point)
local az = mist.utils.getDir(vec, z1.point, true)
local new = {}
new.x = mist.utils.deepCopy(mist.utils.round((math.sin(az) * dist) + point.x))
new.y = mist.utils.deepCopy(mist.utils.round((math.cos(az) * dist) + point.z))

 

Also something with this code seems to be wrong, but I'm not entirely sure why. Its one of those "it works, but I'm not entirely sure why" sort of things. Basically using a handy calculator and knowing how the coordinates in DCS works the usage of sin/cos should be swapped. Either way, you can always experiment with it to get what you need out of it.

The right man in the wrong place makes all the difference in the world.

Current Projects:  Grayflag ServerScripting Wiki

Useful Links: Mission Scripting Tools MIST-(GitHub) MIST-(Thread)

 SLMOD, Wiki wishlist, Mission Editing Wiki!, Mission Building Forum

Posted

Hey Grimes, I'm starting to sound like a broken record, but thanks, Grimes. lol

 

On my broken record theme: I'm a bit confused here.

 

Let me show you what I've got so far, and the context might help.

I found on the forums somewhere (and can't find again) some code to output text of the wind direction, and haven't removed that bit yet.

The Idea is basically to have the unit ('unit1' in this case) turn into the wind, so I set the distance at 100 meters to soak up his steering error.

function get_wind(unit1)
local BRA = nil
local wind = nil
if Unit.getByName(unit1) then
local pos1 = Unit.getByName(unit1):getPosition().p
if pos1 ~= nil then
	wind = atmosphere.getWind(pos1)
	local dir = math.atan2(wind.z, wind.x) * 180 / math.pi
	if dir < 0 then
		dir = 360 + dir
		
	end
	group1 = Unit.getGroup((Unit.getByName(unit1)))
		--grime's code
		local new = {}
		new.x = mist.utils.deepCopy(mist.utils.round((math.sin(dir) * 100) + pos1.x))
		new.y = mist.utils.deepCopy(mist.utils.round((math.cos(dir) * 100) + pos1.z))
		--send that to unit
		local path = {} 
		path[#path + 1] = mist.ground.buildWP(pos1, 'Diamond', 10)
		path[#path + 1] = mist.ground.buildWP(new, 'Diamond', 10)
		mist.goRoute(group1 ,path)
	BRA = dir
end
end
BRA = string.format("Wind: %d, y: %d,", BRA, wind.y)

return BRA
end
trigger.action.outText(get_wind('unit1'), 2)

 

What I end up with is inconsistent results. Sometimes it's off just a few degrees, but sometimes it's off 90 or even 180 degrees from the intended course.

I also tried setting the dir in your code to a constant, and the pos1 to constant for debugging, and found no answers.

I'm sure you're code works, I'm just missing something.

Posted

Heh, so it totally should be x = math.cos whatever and y = math.sin whatever. I have no clue how I accidentally reversed it and it still works as intended. :music_whistling:

 

Attached is a sample mission where I draw a line via mark points every 10km at a given angle.

 

So with the above sin/cos mixed up it would offset it by 90 degrees. However the angle needs to be in radians. It looks like you are converting dir to degrees.

draw_path_on_angle.miz

The right man in the wrong place makes all the difference in the world.

Current Projects:  Grayflag ServerScripting Wiki

Useful Links: Mission Scripting Tools MIST-(GitHub) MIST-(Thread)

 SLMOD, Wiki wishlist, Mission Editing Wiki!, Mission Building Forum

  • 3 months later...
Posted

How did you end up with the script? I see this a great way to point CV against 25kts headwind and set the speed accordingly.

Posted (edited)

A few things you have to note regarding the degrees and trigonometric functions:

- The zero of a trigonometric unit circle is at 3 o'clock while the compass bearing zero is at 12 o'clock position

- The degrees in the unit circle grow counter-clockwise while in compass they grow clockwise

- You have to be careful with the sign of the sin/cos/tan functions and the degrees because these functions are periodic. For example sin(0) = sin(Pi) and tan(Pi/4) = tan(5Pi/4).

- The getWind function does not seem to work if the vec3 elevation is set to 0

- The new offset waypoint should be far enough from the initial position

 

You can do the math in different ways, but below is a working code (based on the above posts) that changes the carrier heading and matches the actual wind + ship movement speed to 25 knots, or minimum of 5 knots if the wind is over 20 knots. Note that I did not yet check the difference between magnetic and true headings since I don't remember how the editor and triggers handle them. Other than that, the script is working and the carrier is realigning by itself.

 

function carrier_realign(carrier_unit)
local BRA = nil -- compass bearing in degrees
local wind = nil
local desired_wind = 25 -- desired wind over the deck in knots
local min_velocity = 5 -- minimum carrier velocity in knots

if Unit.getByName(carrier_unit) then
	
	local pos1 = Unit.getByName(carrier_unit):getPosition().p

	if pos1 ~= nil then
		pos1.y = 200
		wind = atmosphere.getWind(pos1)

		local dir = math.atan2(wind.z, wind.x) + math.pi / 2
		
		if dir < 0 then
			dir = dir + 2 * math.pi
		end		
		
		local abs_wind_velocity = math.sqrt((wind.z)^2 + (wind.x)^2)
		local cruise_speed = nil

		if abs_wind_velocity > (desired_wind - min_velocity) * 0.51444 then -- 1 knot = 0.51444 m/s
			cruise_speed = 0.51444 * min_velocity
		else
			cruise_speed = 0.51444 * (desired_wind - abs_wind_velocity)
		end

		group1 = Unit.getGroup((Unit.getByName(carrier_unit)))
		--grime's code
		local new = {}
		new.x = mist.utils.deepCopy(mist.utils.round((math.cos(dir+math.pi/2) * 10000) + pos1.x))
		new.y = mist.utils.deepCopy(mist.utils.round((math.sin(dir+math.pi/2) * 10000) + pos1.z))
		--send that to unit
		local path = {} 
		path[#path + 1] = mist.ground.buildWP(pos1, 'Diamond', cruise_speed)
		path[#path + 1] = mist.ground.buildWP(new, 'Diamond', cruise_speed)
		mist.goRoute(group1 ,path)
		
	end
end

return BRA

end

carrier_realign('unit1')

Edited by Firaga
  • Recently Browsing   0 members

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