Hoping someone can help unlock a mystery for me.
I've got an annunciator instrument I built which 100% works as expected. In an effort to better organize it, and in preparation to transition to LEDs instead of images, I split related functions out of the main script and created library files. For instance, there are functions specific to alerts for the engine/fuel system; they have all been moved to the engine.lua script.
My mystery revolves around when functions in the library scripts are executed, and how they utilize global variables. Prior to initializing a library file, I fill a variable called plane, which holds various reference data. When I run the instrument, I'm getting errors (attempt to index a nil value, attempt to compare number with nil). The location of the errors are where the library scripts refer to the plane variable. I am also getting errors when I try to reference an image variable that I set prior to initializing the library file. In this latter case, I tried moving the _init statements to the end of the function that loads images, but I still get the error.
Key parts of the logic.lua script:
Code: Select all
-- Define dimensions and location of each light area
dx =
{5,5,5,5,5,5,5,136,136,136,136,136,136,136,270,270,270,270,270,270,270,400,400,400,400,400,400,400,530,530,530,530,530,530,530,660,660,660,660,660,660,660,790,790,790,790,790,790,790}
dy = {14,74,141,207,274,339,405,14,74,141,207,274,339,405,14,74,141,207,274,339,405,14,74,141,207,274,339,405,14,74,141,207,274,339,405,14,74,141,207,274,339,405}
dw = {132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132}
dh = {67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67}
aircraft = {
["M20T"] = {
["vac_press"] = {4.3, 5.2},
["fuel_press"] = {25, 550},
["oil_press"] = {3400, 550},
["throttle"] = 10,
["flap"] = 55,
["alerts"] = {1,2,3,5,6,7,10,11,12,13,14,15,16,17,19,21,24,26,27,28,29,30,31,34,35,38,40,41,42},
["retract"] = true,
}
-- other aircraft omitted for brevity
}
-- To facilitate value access, prepare a variable that will be filled with the appropriate aircraft values
plane = {}
function load_images()
-- Load the lights, but keep them off
if plane.engines == 1 then
img_anun_off = img_add("exp_annun_single_off.png", 0, 0, 800, 480, "stretch")
else
img_anun_off = img_add("exp_annun_multi_off.png", 0, 0, 800, 480, "stretch")
end
img_lit = {}
img_dis = {}
-- Prepare the lighted alerts
for i = 1, 42 do
if plane.engines == 1 then
img_lit[i] = img_add("exp_annun_single.png", 0, 0, 800, 480)
else
img_lit[i] = img_add("exp_annun_multi.png", 0, 0, 800, 480)
end
viewport_rect(img_lit[i], dx[i], dy[i], dw[i], dh[i])
visible(img_lit[i], false)
-- Load the blocking image for alerts that don't apply to the aircraft
if not has_value(i) then
img_dis[i] = img_add("exp_annun_disabled.png", 0, 0, 800, 480)
viewport_rect(img_dis[i], dx[i], dy[i], dw[i], dh[i])
visible(img_dis[i], true)
end
end
end
function has_value(value)
-- Facilitates loading of working vs. disabled annunciator alert images
for i, val in ipairs(plane.alerts) do
if val == value then
return true
end
end
return false
end
function set_aircraft(atc_model, engines, type, center_cap)
model = atc_model
plane = aircraft[model]
if plane == nil then
plane = aircraft["Undefined"]
end
if type == 0 then
plane.type = "piston"
elseif type == 1 then
plane.type = "jet"
elseif type == 5 then
plane.type = "turboprop"
else
plane.type = "unsupported"
end
plane.engines = math.floor(engines)
plane.c_fuel_cap = center_cap
-- Prepare display
load_images()
-- Initialize all systems
electric_init()
engine_init()
switch_init()
mechanical_init()
gear_init()
light_init()
end
fsx_variable_subscribe("ATC MODEL", "String",
"NUMBER OF ENGINES", "Number",
"ENGINE TYPE", "Enum",
"FUEL TANK CENTER CAPACITY", "Gallons", set_aircraft)
Code: Select all
function engine_init()
end
function engine_liteup(fuelpress, oilpress, fuel_level, suction, feathered, autofeather, fire, xfeed)
visible(img_lit[1], fuelpress[1] == 1 or fuelpress[1] == nil)
visible(img_lit[2], oilpress[1] == 1 or oilpress[1] == nil)
visible(img_lit[4], fire == 1)
visible(img_lit[8], fuelpress[2] == 1 or fuelpress[2] == nil)
visible(img_lit[9], oilpress[2] == 1 or oilpress[2] == nil)
visible(img_lit[10], suction == 1)
visible(img_lit[15], fuel_level[1] == 1)
visible(img_lit[22], fuel_level[2] == 1)
visible(img_lit[18], autofeather == 1)
visible(img_lit[29], fuel_level[3] == 1)
visible(img_lit[32], feathered[1] == 1)
visible(img_lit[36], xfeed == 1)
visible(img_lit[39], feathered[2] == 1)
end
function fuel_oil_pressure(type, pressure1, pressure2, rpm1, rpm2)
-- omitted for brevity
end
function annunciate_engine(fuelpress1, fuelpress2, oilpress1, oilpress2,
prop_rpm1, prop_rpm2, n1_rpm1, n1_rpm2,
c_percent, l_percent, r_percent,
fire1, fire2, xfeed, fuel_flow,
suction, feather1, feather2, autofeather1, autofeather2)
if plane.type == "piston" or plane.type == "turboprop" then
rpm1 = prop_rpm1
rpm2 = prop_rpm2
elseif plane.type == "jet" then
rpm1 = n1_rpm1
rpm2 = n1_rpm2
end
-- Fuel Pressure
fuelpress = fuel_oil_pressure("fuel", fuelpress1, fuelpress2, rpm1, rpm2)
-- Oil Pressure
oilpress = fuel_oil_pressure("oil", oilpress1, oilpress2, rpm1, rpm2)
-- Fuel Quantity
-- Alarm at <10%
fuel_level = {0, 0, 0}
fuel_level[1] = fif(l_percent < 10, 1, 0)
fuel_level[3] = fif(r_percent < 10, 1, 0)
if plane.c_fuel_cap > 0 then
fuel_level[2] = fif(c_percent < 10, 1, 0)
end
-- filling other variables here, omitted for brevity --
--[...]
-- using the variables next --
if power() and startup == false then engine_liteup(fuelpress, oilpress, fuel_level, suction, {pitch1, pitch2}, autofeather, fire, xfeed) end
end
fsx_variable_subscribe(
"GENERAL ENG FUEL PRESSURE:1", "Psi",
"GENERAL ENG FUEL PRESSURE:2", "Psi",
"GENERAL ENG OIL PRESSURE:1", "Psf",
"GENERAL ENG OIL PRESSURE:2", "Psf",
"PROP RPM:1", "Rpm",
"PROP RPM:2", "Rpm",
"ENG N1 RPM:1", "Rpm",
"ENG N1 RPM:2", "Rpm",
"FUEL TANK CENTER LEVEL", "Percent",
"FUEL TANK LEFT MAIN LEVEL", "Percent",
"FUEL TANK RIGHT MAIN LEVEL", "Percent",
"ENGINE ON FIRE:1", "Bool",
"ENGINE ON FIRE:2", "Bool",
"FUEL CROSS FEED", "Enum",
"RECIP ENG FUEL TANK SELECTOR:1", "Enum",
"SUCTION PRESSURE", "inHg",
"PROP BETA:1", "Radians",
"PROP BETA:2", "Radians",
"PROP AUTO FEATHER ARMED:1", "Bool",
"PROP AUTO FEATHER ARMED:2", "Bool",
annunciate_engine
)
Any guidance here would be appreciated.
-Bryan