-------------------------------------------------------------------------------------------------------------------------------
-- DCS Export Functions for use with XSimulator SimTools motion control software
-- For SXF-100 Motion System and g-Seat-II Motion System. 
-- Based on original Export.lua from value1.
-- Version 0.07 
-- Author: BrassEm
-- 04/01/2020
-- Take telemetry from DCS and converts it to suitable data for Simtools.
-- Many thanks to [FSF]Ian, Frusheen(RiftFlyer), Asticher(vJaBoG32), Dirty, Andrey Filin from ED, FlyPT,
-- yobuddy and value1 from XSimulator.
-- It is assumed at this time that the g seat command is coming raw directly from the "accelerometers" in the aircraft.
-- SFX-100 forces are Roll, Pitch, Heave and Surge.
-- g-Seat-II forces in flight are Heave, Surge, Sway and Roll.
-- ground lurching is added in to augment ground handling.
-- Added output delay on start up to allow aircraft to settle for 4 seconds and avoid violent lurching.
-------------------------------------------------------------------------------------------------------------------------------

-- Aircraft Names and Observations.
-- --------------------------------
-- C-101EB
-- F-15C
-- F-5E-3
-- F-86F
-- FA-18C_hornet
-- Hawk
-- L-39C
-- L-39ZA
-- M-2000C
-- MiG-15bis
-- MiG-21Bis
-- MiG-29A
-- MiG-29S
-- Su-25
-- Su-25T
-- Su-27
-- Su-33
-- J-11A
-- AV8BNA
-- A-10A
-- A-10C
-- AJS37
-- Bf-109K-4 
-- FW-190D9
-- P-51D
-- TF-51D
-- SpitfireLFMkIX
-- SpitfireLFMkIXCW


-- Globals declared here
PI = math.pi			-- 3.1415926535897932384626433832795028841971693993751
HPI = PI/2				-- Radians in 90Â°
PI2 = PI*2				-- Radians in 360Â°
r2d = 180/PI			-- Radians to Degrees
told = 0.0			-- Last Time function called

Myfunction =

{
Start=function(self)

    -- Output file to check values.
	default_output_file = io.open("./Export.log", "w") 
	
	package.path = package.path..";.\\LuaSocket\\?.lua"
	package.cpath = package.cpath..";.\\LuaSocket\\?.dll"
	socket = require("socket")

	my_init = socket.protect(function()
		-- export telemetry to SimTools
		-- Setup comms for export telemetry to SimTools. Set host1 to your second PC IP.
		-- host1 = host1 or "19.190.26.5" -- Set to 127.0.0.1 for single PC or xxx.xxx.xxx.xxx for two PC's (Set to your 2nd PC IP)
		host1 = "19.190.26.5" 	-- Mine in this case. Change it to yours.
		port1 = "41230"			
		c = socket.udp ( )
		c:settimeout ( 0 )
		c:setpeername ( host1, port1 )

	end)
	my_init()
end,


AfterNextFrame=function(self)

	local t = LoGetModelTime()
	local timedif = 0.0
	
	timedif = t-told  -- Get frame duration

	-- Aircraft name
	local myInfo = LoGetSelfData()
	local CurrentAircraft = myInfo.Name
	-- Add additional telemetry values for testing purposes
	local altRad = LoGetAltitudeAboveGroundLevel()
	local TAS = LoGetTrueAirSpeed()  -- (args - 0, results - 1 (m/s))

	-- g Forces
	local accel = LoGetAccelerationUnits()  	-- (args - 0, results - 1 (g)) The g-Force.
	
	-- From Frusheen
	local vel_v = LoGetVectorVelocity() -- (1 m/s), vel_v.x, vel_v.y, vel_v.z  
	local vel_r = LoGetAngularVelocity() -- (radians per second), vel_r.x, vel_r.y, vel_r.z	= HUD Velocity Vector
	
	-- From FlyPT
	local GearMid = LoGetAircraftDrawArgumentValue(1)   -- Front/Rear landing gear (0 to 1)
	local GearTurn = LoGetAircraftDrawArgumentValue(2)  -- Turning landing gear (0 to 1)
	local GearLeft = LoGetAircraftDrawArgumentValue(4)  -- Left landing gear (0 to 1)
	local GearRight = LoGetAircraftDrawArgumentValue(6) -- Right landing gear (0 to 1)	
	
	-- Output to SimTools
	local yaw = vel_r.y			-- Pitch > #2 in Sim Tools 	- Tuning Center Output. beta plugin. Sway on ground. WAS PITCH
	local roll = vel_r.x		-- Roll > #1 in Sim Tools 	- Tuning Center Output. gamma plugin. Roll on ground.
	local pitch = vel_r.z		-- Yaw > #4 in Sim Tools 	- Tuning Center Output. alpha plugin. Pitch on ground. WAS YAW
	local surge = accel.x		-- Surge > #6 in Sim Tools 	- Tuning Center Output. Surge plugin .
	local heave = accel.y		-- Heave > #3 in Sim Tools 	- Tuning Center Output. Heave plugin.
	local sway = accel.z		-- Sway > #5 in Sim Tools 	- Tuning Center Output. Sway plugin.
	local gsHeave = heave		-- Extra 1 > #7 in Sim Tools - Tuning Center Output. g-seat Heave. Was Aircraft slip. Not used.
	local gsSway = sway			-- Extra 2 > #8 in Sim Tools - Tuning Center Output. g-seat Sway. Was Aircraft lurching while on ground in roll.
	local gsSurge = surge		-- Extra 3 > #9 in Sim Tools - Tuning Center Output. g-seat Surge.  Was Aircraft lurching while on ground in pitch.
	-- Test velocity only
	local bump_surge = vel_v.x	-- Test variable. Surge bump.
	local bump_heave = vel_v.y	-- Test variable. Vertical bump.
	local bump_sway = vel_v.z	-- Test variable. Side bump.
	local lurch_scalar = 1.00	-- Ground bumpiness Scalar
								
	
	-- Convert Rates from radians into degrees.
	pitch = pitch*r2d
	roll = roll*r2d
	yaw = yaw*r2d
	
	pitch_lurch = pitch
	-- roll_lurch = roll
	sway_lurch = yaw
	
	-- Normalise Heave
	heave = heave-1	
	
	-- SimTools FORCES
	-- Roll
	-- Pitch
	-- Heave
	-- Yaw
	-- Sway
	-- Surge
	-- Extra1 - gsHeave - pitch_lurch
	-- Extra2 - gsSway - roll_lurch
	-- Extra3 - gsSurge - sway_lurch 

	-- Add Aircraft lurching while on the ground.
	-- PROP aircraft have violent high g lurching.
	if CurrentAircraft == "SpitfireLFMkIX" then
		lurch_scalar = 0.2
	elseif CurrentAircraft == "SpitfireLFMkIXCW" then
			lurch_scalar = 0.2
	elseif CurrentAircraft == "P-51D" then
			lurch_scalar = 0.2
	elseif CurrentAircraft == "TF-51D" then
			lurch_scalar = 0.2
	elseif CurrentAircraft == "Bf-109K-4" then
			lurch_scalar = 0.1
	elseif CurrentAircraft == "FW-190D9" then
			lurch_scalar = 0.2
	elseif CurrentAircraft == "Yak-52" then
			lurch_scalar = 0.2
		else
			lurch_scalar = 6 -- changed from 1 to 2
			roll_scalar = 0.5 --Sway to roll.
			heave_scalar = 1.25 -- Heave on ground. 2.0
	end
	-- Add modified Lurch Code Here...
	-- ################################
	-- Blank code. Uncomment for no amplified lurch
	if (GearMid+GearLeft+GearRight) > 0 then
		-- Do On Ground lurch calculations
			pitch_lurch = pitch_lurch*lurch_scalar
			if TAS <= 15 then
				pitch = pitch_lurch
			else
				pitch_lurch = 0
			end
			-- roll_lurch = roll_lurch*lurch_scalar 
			sway_lurch = yaw*roll_scalar
			roll =  sway_lurch
			heave = heave*heave_scalar
		else
		-- Null out Ground Lurch if in Air
		pitch_lurch = 0
		-- roll_lurch = 0
		sway_lurch = 0
	end

	TAS=(TAS/1) -- for graphing purposes

	if t >= 4.0 then
	-- Output Telemetry to Export.log file for testing purposes. 
	default_output_file:write(string.format("AIRCRAFT: %s t: %.3f td: %.3f ALTRAD: %.2f TAS: %.1f PITCH: %.2f ROLL: %.2f YAW: %.2f SURGE: %.3f HEAVE: %.3f SWAY: %.3f gsHeave: %.2f gsSway: %.3f gsSurge: %.3f PITCH_LURCH: %.3f SWAY_LURCH: %.3f GEARMID: %.3f GEARLEFT: %.3f GEARRIGHT: %.3f BUMP_SURGE: %.3f BUMP_HEAVE: %.3f BUMP_SWAY: %.3f \n", CurrentAircraft, t, timedif, altRad/10, TAS, pitch, roll, yaw, surge, heave, sway, gsHeave, gsSway, gsSurge, pitch_lurch, sway_lurch, GearMid, GearLeft, GearRight, bump_surge, bump_heave, bump_sway))	
	

	my_send = socket.protect(function()
		if c then
			socket.try(c:send(string.format("%.4f; %.4f; %.4f; %.4f; %.4f; %.4f; %.4f; %.4f; %.4f;\n", pitch, roll, yaw, surge, heave, sway, gsHeave, sway_lurch, pitch_lurch)))
		end
	end)
	end
	told = t
	my_send()

end,


Stop=function(self)
	my_close = socket.protect(function()
		if c then
			c:close()
		end
	end)
	my_close()
end
}


-- =============
-- Overload
-- =============

-- Works once just before mission start.
do
	local PrevLuaExportStart=LuaExportStart
	LuaExportStart=function()
		Myfunction:Start()
		if PrevLuaExportStart then
			PrevLuaExportStart()
		end
	end
end

-- Works just after every simulation frame.
do
	local PrevLuaExportAfterNextFrame=LuaExportAfterNextFrame
	LuaExportAfterNextFrame=function()
		Myfunction:AfterNextFrame()
		if PrevLuaExportAfterNextFrame then
			PrevLuaExportAfterNextFrame()
		end
	end
end

-- Works once just after mission stop.
do
	local PrevLuaExportStop=LuaExportStop
	LuaExportStop=function()
		Myfunction:Stop()
		if PrevLuaExportStop then
			PrevLuaExportStop()
		end
	end
	-- Close the output file
	if default_output_file then
		default_output_file:close()
		default_output_file = nil
	end
end

