Experiment - Controlling Lockon from another application using lua - ED Forums
 


Notices

Reply
 
Thread Tools Display Modes
Old 01-15-2008, 09:05 PM   #1
Joe Kurr
Member
 
Joe Kurr's Avatar
 
Join Date: Nov 2004
Location: Almere, The Netherlands
Posts: 634
Reputation power: 24
Joe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of light
Default Experiment - Controlling Lockon from another application using lua

I first got this idea when we started work on our cockpit project, but at that time, I only knew how to export stuff from lockon via the export.lua script.
After studying the lua language a little, and searching the net, I found out that it is also possible to use export.lua as an import script

To try this out, I created a small program to run on my PDA, which functions like TouchBuddy in a way, but much simpler (at the moment, it has only six non-programmable buttons).
It communicates with the PC via a TCP socket, using port 10309.

On the PC, I was first planning to create a small server, which would translate the commands it received from the PDA into keystrokes for Lockon.
But since Lockon has the LoSetCommand() function in the export.lua script, I wondered if it would be possible to create the server using a lua script.

After some tests, I had a perfectly working server script, which handled all my commands, but it was running outside of Lockon, and since it used an endless loop, this might be a problem.

Time to learn coroutines

After a couple of hours of programming and testing, I finally managed to create a script, which runs inside Lockon, and listens on TCP port 10309 for incoming commands.
It then translates the received commands into the numeric command codes listed at the end of the export.lua script, and calls the LoSetCommand() function.

By using this script, I can now control my aircraft from any type of application, even via a script from a web browser

As I'm still in the early stages of learning lua, maybe some of you can comment on my script to make it better.

Here's the lua script:

Code:
---------------------------------------------------------------------------------------------------
-- TCP Listener script for controlling Lockon from an external program                           --
-- Author: Bas 'Joe Kurr' Weijers                                                                --
---------------------------------------------------------------------------------------------------

dofile "lua.lua"

-- Listener settings
-- By default, the listener binds to port 10309 on all local network interfaces
local host     = "*"
local port     = 10309

-- Command list
-- Send these commands from your application to execute the corresponding functions in Lockon
-- The numbers here correspond to the commands at the end of the original export.lua script
local commands = { 
  view_cockpit         = 7,   view_external        = 8,
  view_flyby           = 9,   view_ground_units    = 10,
  view_civilians       = 11,  view_chase           = 12,
  view_navy            = 13,  view_air_combat      = 14,
  view_theater         = 15,  view_airfield        = 16,

  chat_allies          = 50,  chat_common          = 57,

  acs_altitude_toggle  = 59,  acs_autopilot_toggle = 62,
  acs_thrust_toggle    = 63,

  mech_gear_toggle     = 68,  mech_hook_toggle     = 69,
  mech_wings_toggle    = 70,  mech_canopy_toggle   = 71,
  mech_flaps_toggle    = 72,  mech_flaps_down      = 145,
  mech_flaps_up        = 146, mech_airbrake_toggle = 73,
  mech_airbrake_open   = 147, mech_airbrake_close  = 148,
  mech_wheelbrakes_on  = 74,  mech_wheelbrakes_off = 75,
  mech_chute           = 76,

  refuel_on            = 79,  refuel_off           = 80,
  refuel_probe_toggle  = 155,

  mode_nav             = 105, mode_bvr             = 106,
  mode_vs              = 107, mode_bore            = 108,
  mode_helmet          = 109, mode_fio             = 110,
  mode_ground          = 111, mode_grid            = 112,
  
  kobra                = 121,
  
  engines_both_start   = 309, engines_both_stop    = 310,
  engines_left_start   = 311, engines_left_stop    = 312,
  engines_right_start  = 313, engines_right_stop   = 314,

  master_power_toggle  = 315,

  lights_toggle        = 175,

  jettison_weapons     = 82,  jettison_fueltanks   = 178,
  
  radar_toggle         = 86,
  eos_toggle           = 87
}

Coroutines     = Coroutines or {}
CoroutineIndex = CoroutineIndex or 0

local serverRunning = 0
local origStart     = LuaExportStart
local origStop      = LuaExportStop

function run_server()
  local socket = require("socket")

  local sck = socket.try(socket.bind(host, port))

  if (sck ~= nil) then
    addr, prt = socket.try(sck:getsockname())

    logtofile("Listener started")
    while (serverRunning == 1) do
      socket.try(sck:settimeout(0.01))
      conn, err = sck:accept()
      if conn ~= nil then
        msg, err = conn:receive()
        conn:close()
        if (msg == "END") then
          stop_server = 1
        else
	 logtofile("Received: " .. msg .. " --> " .. commands[msg])
         LoSetCommand(commands[msg])
        end -- if
      end -- if
      coroutine.yield()
    end -- while
    sck:close()
    logtofile("Listener stopped")
  end -- if
end -- function

function start_server()
  logtofile("Starting listener")
  serverRunning = 1
  CoroutineIndex = CoroutineIndex + 1
  Coroutines[CoroutineIndex] = coroutine.create(run_server)
  LoCreateCoroutineActivity(CoroutineIndex, 0.0, 0.1)
end

function stop_server()
  logtofile("Stopping listener")
  serverRunning = 0
end
  
function CoroutineResume(index, tCurrent)
	coroutine.resume(Coroutines[index], tCurrent)
	return coroutine.status(Coroutines[index]) ~= "dead"
end

function LuaExportStart()
  origStart()
  local file = io.open("./Temp/commander.log", "w")
  if file then
	  io.output(file)
  end
  start_server()
end

function LuaExportStop()
  logtofile("End")
  stop_server()
  origStop()
end

function logtofile(message)
	io.write(message .. "\n")
end
---------------------------------------------------------------------------------------------------
-- End of lockon-commander.lua                                                                   --
---------------------------------------------------------------------------------------------------
The sending application makes a connection each time a button is pressed, sends the corresponding command, and closes the connection again.
If this doesn't happen, the lua script will wait until the connection is closed before continuing, thus effectively pause the mission in Lockon.

Question to the devs:

I found that there is a function to toggle the gear up and down (command 68 ), but are there also separate commands for lowering and raising the gear?
I found that there are separate commands for the airbrake and flaps.
__________________
Dutch Flanker Display Team | LLTM 2010 Tiger Spirit Award

Last edited by Joe Kurr; 01-21-2008 at 10:47 PM. Reason: Changed title to better fit the content
Joe Kurr is offline   Reply With Quote
Old 01-16-2008, 02:55 AM   #2
A.S+
Posting Rights Revoked
 
A.S's Avatar
 
Join Date: Jan 2006
Posts: 1,346
Reputation power: 0
A.S is a name known to allA.S is a name known to allA.S is a name known to allA.S is a name known to allA.S is a name known to allA.S is a name known to allA.S is a name known to allA.S is a name known to allA.S is a name known to allA.S is a name known to allA.S is a name known to all
Default

ohoh..i knew it.....saaaaabooooootageeee they will infiltrate my controls hehe

good job
A.S is offline   Reply With Quote
Old 01-21-2008, 10:34 PM   #3
Joe Kurr
Member
 
Joe Kurr's Avatar
 
Join Date: Nov 2004
Location: Almere, The Netherlands
Posts: 634
Reputation power: 24
Joe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of light
Default

I built a simple touch-buddy like application on my PDA, to test the possibilities of the script I posted earlier.
I haven't put any energy in making a nice interface, it's just a series of tabs with a bunch of buttons on them, but it works very well
There is a slight delay when I push a button on my PDA, which is partly due to the lua script posted above only listening once every 0.1 seconds.

The whole application can be set up using a simple xml file, making it very easy to add tabs and buttons.

Here are some 'screenshots' of the first test:




The next step will be to try exporting flight data to the PDA, and rendering it there.
__________________
Dutch Flanker Display Team | LLTM 2010 Tiger Spirit Award
Joe Kurr is offline   Reply With Quote
Old 01-22-2008, 08:06 AM   #4
JaNk0
Senior Member
 
JaNk0's Avatar
 
Join Date: Apr 2005
Location: Sweden
Posts: 1,560
Reputation power: 27
JaNk0 is a glorious beacon of lightJaNk0 is a glorious beacon of lightJaNk0 is a glorious beacon of lightJaNk0 is a glorious beacon of lightJaNk0 is a glorious beacon of lightJaNk0 is a glorious beacon of lightJaNk0 is a glorious beacon of lightJaNk0 is a glorious beacon of lightJaNk0 is a glorious beacon of lightJaNk0 is a glorious beacon of lightJaNk0 is a glorious beacon of light
Send a message via MSN to JaNk0
Default

That's really cool !
__________________
JaNk0 is offline   Reply With Quote
Old 01-23-2008, 09:10 AM   #5
Lecreole
Junior Member
 
Join Date: Jan 2008
Posts: 5
Reputation power: 0
Lecreole is an unknown quantity at this point
Default

Quote:
Originally Posted by Joe Kurr View Post
Question to the devs:

I found that there is a function to toggle the gear up and down (command 68 ), but are there also separate commands for lowering and raising the gear?
This gear up and down command is 430 and 431 .
Look part of my code to not block lockon for receive data:

-- Creation de coroutines pour LOSIOC
Coroutines = {} -- Tables des coroutines
function CoroutineResume(index, tCurrent)
coroutine.resume(Coroutines[index], tCurrent)
return coroutine.status(Coroutines[index]) ~= "dead"
end
--
function LOSIOCModelTimer(t)
local tNext = t
LOSIOC:StarLOSIOC()
while LOSIOC.InitOK do
if LoGetPlayerPlaneId() then
LOSIOC:ReceptionData()
LOSIOC:SendData()
else
LOSIOC.Retab = true
end
tNext = coroutine.yield()
end
end
-- Declaration des coroutines
Coroutines[1] = coroutine.create(LOSIOCModelTimer)
LoCreateCoroutineActivity(1, 0, 0.05)

you can't create server, you can create client to communicate,
for first connexion set : socket.try(sck:settimeout(4000)); delay for wait connexion with your pocket PC
when connection is OK : socket.try(sck:settimeout(0)); no wait, for no block LOCKON.

Excuse me for my bad english, I'm french.

Last edited by Lecreole; 01-23-2008 at 10:04 AM.
Lecreole is offline   Reply With Quote
Old 01-23-2008, 12:47 PM   #6
Joe Kurr
Member
 
Joe Kurr's Avatar
 
Join Date: Nov 2004
Location: Almere, The Netherlands
Posts: 634
Reputation power: 24
Joe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of light
Default

Quote:
Originally Posted by Lecreole View Post
This gear up and down command is 430 and 431 .
Look part of my code to not block lockon for receive data:

-- Creation de coroutines pour LOSIOC
Coroutines = {} -- Tables des coroutines
function CoroutineResume(index, tCurrent)
coroutine.resume(Coroutines[index], tCurrent)
return coroutine.status(Coroutines[index]) ~= "dead"
end
--
function LOSIOCModelTimer(t)
local tNext = t
LOSIOC:StarLOSIOC()
while LOSIOC.InitOK do
if LoGetPlayerPlaneId() then
LOSIOC:ReceptionData()
LOSIOC:SendData()
else
LOSIOC.Retab = true
end
tNext = coroutine.yield()
end
end
-- Declaration des coroutines
Coroutines[1] = coroutine.create(LOSIOCModelTimer)
LoCreateCoroutineActivity(1, 0, 0.05)

you can't create server, you can create client to communicate,
for first connexion set : socket.try(sck:settimeout(4000)); delay for wait connexion with your pocket PC
when connection is OK : socket.try(sck:settimeout(0)); no wait, for no block LOCKON.

Excuse me for my bad english, I'm french.
So if I understand correctly, you're creating a TCP client in lockon, which reacts to commands pushed to it from a server (e.g. my PDA)?
__________________
Dutch Flanker Display Team | LLTM 2010 Tiger Spirit Award
Joe Kurr is offline   Reply With Quote
Old 01-23-2008, 02:47 PM   #7
DarkWanderer
Senior Member
 
DarkWanderer's Avatar
 
Join Date: Sep 2006
Location: Moscow region
Posts: 1,400
Reputation power: 26
DarkWanderer is a glorious beacon of lightDarkWanderer is a glorious beacon of lightDarkWanderer is a glorious beacon of lightDarkWanderer is a glorious beacon of lightDarkWanderer is a glorious beacon of lightDarkWanderer is a glorious beacon of lightDarkWanderer is a glorious beacon of lightDarkWanderer is a glorious beacon of lightDarkWanderer is a glorious beacon of lightDarkWanderer is a glorious beacon of lightDarkWanderer is a glorious beacon of light
Send a message via ICQ to DarkWanderer
Default

Quote:
So if I understand correctly, you're creating a TCP client in lockon, which reacts to commands pushed to it from a server (e.g. my PDA)?
His example is about making the data receiving a co-routine, effectively making it to be executed as another thread.

About getting information from Lock On you can talk with Mnemonic, the creator of LO Virtual Panel. He already looks for making the export on PDA. If you could cooperate - it will be very useful for both the products (or the product? )

I propose to create two applications: a universal multi-threaded "server", which should be "connected" to the game and various "clients" - for sending commands, for displaying data, etc. This will eliminate the problem with pausing.
__________________
You want the best? Here i am...

Last edited by DarkWanderer; 01-23-2008 at 03:05 PM.
DarkWanderer is offline   Reply With Quote
Old 01-24-2008, 09:16 AM   #8
Lecreole
Junior Member
 
Join Date: Jan 2008
Posts: 5
Reputation power: 0
Lecreole is an unknown quantity at this point
Default

Quote:
Originally Posted by Joe Kurr View Post
So if I understand correctly, you're creating a TCP client in lockon, which reacts to commands pushed to it from a server (e.g. my PDA)?
Yes, i use sioc as server to receive commands.
I use IOCP protocol for this.
What language you're use for create PDA program Vc++, c# or other?
Lecreole is offline   Reply With Quote
Old 01-24-2008, 09:29 AM   #9
Lecreole
Junior Member
 
Join Date: Jan 2008
Posts: 5
Reputation power: 0
Lecreole is an unknown quantity at this point
Default

Quote:
Originally Posted by DarkWanderer View Post
I propose to create two applications: a universal multi-threaded "server", which should be "connected" to the game and various "clients" - for sending commands, for displaying data, etc. This will eliminate the problem with pausing.
It's a good idea, it's my actually project C#. but, each clients don't use the same communication protocol
Lecreole is offline   Reply With Quote
Old 01-24-2008, 04:44 PM   #10
Joe Kurr
Member
 
Joe Kurr's Avatar
 
Join Date: Nov 2004
Location: Almere, The Netherlands
Posts: 634
Reputation power: 24
Joe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of lightJoe Kurr is a glorious beacon of light
Default

Thanks for the responses, I'll give sioc a go, and see where I'll end up
I'm using VB.NET 2005 to build my application.
__________________
Dutch Flanker Display Team | LLTM 2010 Tiger Spirit Award
Joe Kurr is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Controlling your AI wingman Ven Missions and Campaigns 3 05-16-2007 04:20 PM
Application for a BS beta tester HRZ Lock On: Flaming Cliffs 1 & 2 15 10-27-2006 11:47 PM
LockOn Experiment: Maximum Image Quality (7900GTX) NEODARK Lock On: Flaming Cliffs 1 & 2 23 04-10-2006 07:13 PM
What does this error mean? LOCK ON: lockon.exe - Application emenance Lock On: Flaming Cliffs 1 & 2 16 03-20-2005 06:53 AM

All times are GMT. The time now is 05:07 PM. vBulletin Skin by ForumMonkeys. Powered by vBulletin®.
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.