Hi there guys and girls,
I am trying to create an atmospheric autopilot from an MFD. I was glad to read that it is possible to create a LUA script based MFD using the Script MFD examples.
I've "borrowed" the aap code from the base orbiter package (with some alterations by Mogeley - http://orbiter-forum.com/project.php?issueid=254) and I have modified and created various new autopilots using this as a template.
Now trying to put this into an MFD is proving difficult. My problem is that I would like to open a user input box for the speed/heading/altitude when you want to switch that part of the autopilot on. I am starting with the speed since this is quickest to test.
The problem is that the MFD script doesn't seem to like the proc.wait_input command being used unless it is performed as a background function (proc.bg). The problem is that my variable does not seem to get assigned with the user input.
Maybe I can explain another way. If I have a function which I run as a background function, and this includes in the first line the proc.wait_input command, then none of the subsequent commands from within that function are actioned.
I am trying different ways to get this to work and I know that the speed hold code works if I supply it with a number from within the code, but getting the user to input a number via an input doesn't seem to be straightforward.
I guess a workaround would be to use the attitudercs method of changing a value up and down with different MFD buttons to select the speed required, but an input box would be better for me.
Any help would be appreciated. Here is my code so you can hopefully see what I mean (it is not the most beautiful and optimised piece of code ever so be gentle!):
Thanks for any help :thumbup:
I am trying to create an atmospheric autopilot from an MFD. I was glad to read that it is possible to create a LUA script based MFD using the Script MFD examples.
I've "borrowed" the aap code from the base orbiter package (with some alterations by Mogeley - http://orbiter-forum.com/project.php?issueid=254) and I have modified and created various new autopilots using this as a template.
Now trying to put this into an MFD is proving difficult. My problem is that I would like to open a user input box for the speed/heading/altitude when you want to switch that part of the autopilot on. I am starting with the speed since this is quickest to test.
The problem is that the MFD script doesn't seem to like the proc.wait_input command being used unless it is performed as a background function (proc.bg). The problem is that my variable does not seem to get assigned with the user input.
Maybe I can explain another way. If I have a function which I run as a background function, and this includes in the first line the proc.wait_input command, then none of the subsequent commands from within that function are actioned.
I am trying different ways to get this to work and I know that the speed hold code works if I supply it with a number from within the code, but getting the user to input a number via an input doesn't seem to be straightforward.
I guess a workaround would be to use the attitudercs method of changing a value up and down with different MFD buttons to select the speed required, but an input box would be better for me.
Any help would be appreciated. Here is my code so you can hopefully see what I mean (it is not the most beautiful and optimised piece of code ever so be gentle!):
Code:
--[[
Name = AutoPilot
Script = AP.cfg
Key = 0x16 ; 'U'
Persist = vessel
END_PARSE
--]]
-- global reference to vessel associated with MFD
vi = vessel.get_focusinterface()
actionstr = ''
actionstr2 = ''
spdapeng = false
tgtspd = nil
ap = {}
ap.spdinp = nil
ap.spd = nil
-- the list of button labels
btn_label = {'100','KIL','SPD','','','','','','','CLR'}
-- table of button menu entries
btn_menu = {
{l1='Set 100% Main Thrust',sel='a'},
{l1='Kill Main Thrust',sel='b'},
{l1='Maintain Speed',sel='f'},
{l1=''},
{l1=''},
{l1=''},
{l1=''},
{l1=''},
{l1=''},
{l1='Clear Screen',sel='c'}
}
-- callback function: button label for button 'bt' (>= 0)
function buttonlabel(bt)
if bt < 12 then
return btn_label[bt+1]
end
return nil
end
-- callback function: button menu entries
function buttonmenu()
return btn_menu,10
end
-- callback function: update display
function update(skp)
ch,cw = skp:get_charsize()
mfd:set_title(skp,'AutoPilot MFD')
skp:text(cw*5,ch*10,actionstr,#actionstr)
skp:text(cw*8,ch*13,actionstr2,#actionstr2)
return true
end
-- respond to button presses
function consumebutton(bt,event)
if bt==0 then
if event%PANEL_MOUSE.LBPRESSED == PANEL_MOUSE.LBDOWN then
button1_func()
end
return true
elseif bt==1 then
if event%PANEL_MOUSE.LBPRESSED == PANEL_MOUSE.LBDOWN then
button2_func()
end
return true
elseif bt==2 then
if event%PANEL_MOUSE.LBPRESSED == PANEL_MOUSE.LBDOWN then
button3_func()
end
return true
elseif bt==9 then
if event%PANEL_MOUSE.LBPRESSED == PANEL_MOUSE.LBDOWN then
button9_func()
end
return true
else
-- just for fun, let's trap unassigned buttons as well
if event%PANEL_MOUSE.LBPRESSED == PANEL_MOUSE.LBDOWN then
button_inv_func()
end
return true
end
end
-- dummy action for button 1
function button1_func()
if spdapeng == false then
actionstr = 'AP Main Thrust 100%'
vi:set_thrustergrouplevel(THGROUP.MAIN,1)
mfd:invalidate_display()
end
end
-- dummy action for button 2
function button2_func()
if spdapeng == false then
actionstr = 'AP Main Thrust 0%'
vi:set_thrustergrouplevel(THGROUP.MAIN,0)
mfd:invalidate_display()
end
end
-- dummy action for button 3
function button3_func()
if spdapeng == false then
spdapeng = true
ap.spdinp = proc.bg(spdinput)
elseif spdapeng == true then
spdapeng = false
proc.kill(ap.spd)
proc.kill(ap.spdinp)
tgtspd = nil
actionstr = 'AP Speed OFF'
mfd:invalidate_display()
end
end
function spdinput()
tgtspd = proc.wait_input('AP Tgt Speed (m/s)')
end
-- dummy action for button 9
function button9_func()
actionstr = ''
mfd:invalidate_display()
end
-- dummy action for invalid buttons
function button_inv_func()
actionstr = "Don't press that button again"
mfd:invalidate_display()
end
function prestep(simt,simtd,mjd)
spd0 = vi:get_airspeed()
end
function poststep(simt,simtd,mjd)
time = round(oapi.get_simtime(),0)
actionstr2 = time..' sec sim time'
if spdapeng == true then
spd_ap(tgtspd)
end
end
function spd_ap(tgtspd)
if tgtspd ~= nil then
actionstr = 'AP Speed Hold ON: '..tgtspd..' m/s'
alpha = 1
beta = 1
dt = oapi.get_simstep()
spd = vi:get_airspeed()
acc = (spd - spd0) / dt
spd0 = spd
dspd = tgtspd - spd
dthrott = (dspd * alpha - acc * beta) * dt
thrott = vi:get_thrustergrouplevel(THGROUP.MAIN)
vi:set_thrustergrouplevel(THGROUP.MAIN,thrott+dthrott)
end
end
function round(num , idp)
local mult = 10^(idp or 0)
return math.floor(num * mult + 0.5) / mult
end