This week I started using AM. In generic HSI I added support for dial functions for MSFS (fs2020_event("VOR1_OBI_DEC"))) and I change that the heading flag appears after Voltage drops below 5V. But CDI needle (course deviation) should move more (see screenshot). I figured out that the needle is managed in line 218 and onward, but I don't know how to change the code, so the course deviation needle would move more. Could you please also tell me suggestions on how to manage the glide slope indicator, if I will have to tweak that?
Sim is MSFS and plane is JustFlight Piper Arrow turbo IY.
Thanks for help and suggestions.
Screenshot:
https://ibb.co/Qk9xRb2
Code: Select all
---------------------------------------------------------------
-- BENDIX/KING CROWN SILVER KING SERIE
-- KI525A HSI (ELECTRICAL)
-- version 1.30 Fixed incorrect G/S display bug in XPlane
--
-- J. ZAHAR 04/2016
-- based on original codeby MacnFly (Thanks Mac!)
-- Modeled using the user manual of the real instrument
-- DC instrument
-- includes failure flags when power OFF
-- FSX and Xplane version
---------------------------------------------------------------
---------------------------------------------------------------
-- DISPLAY VARIABLES SECTION --
-- Set to True or False according to taste --
---------------------------------------------------------------
fsx_source_prop = user_prop_add_enum("HSI source", "NAV1,NAV2,HSI", "HSI", "Choose the HSI source FSX and Prepar3D.")
local FSX_HSI_source = 2
if user_prop_get(fsx_source_prop) == "NAV1" then
FSX_HSI_source = 0
elseif user_prop_get(fsx_source_prop) == "NAV2" then
FSX_HSI_source = 1
elseif user_prop_get(fsx_source_prop) == "HSI" then
FSX_HSI_source = 2
end
display_frame_prop = user_prop_add_boolean("Shows the frame", true, "Show the frame of the bezel")
local display_frame = true -- displays the rectangular frame
display_frame = user_prop_get(display_frame_prop)
display_screws_prop = user_prop_add_boolean("Shows the Screws", true, "Show the screws")
local display_screws = user_prop_get(display_screws_prop) -- displays the mounting screws
gyro_spinup_duration_prop = user_prop_add_integer("Gyro Spinup Duration(msec)", 1000, 30000, 15000, "Tme (in msec) before elec gyro is at full speed when master switch has been switched ON (default 10-15 sec)")
local gyro_spinup_duration = 15000 -- time (in msec) before elec gyro is at full speed when master switch has been switched ON (default 10-15 sec)
gyro_spinup_duration=user_prop_get(gyro_spinup_duration_prop)
---------------------------------------------------------------
-- END OF DISPLAY VARIABLES SECTION --
-- DO NOT MODIFIY CODE PAST THIS POINT !!! --
---------------------------------------------------------------
-- Global variables
local is_failed = false
local gbl_cur_hdef = 0
local gbl_cur_vdef = 119
local gbl_cur_bearing = 0
local gbl_target_hdef = 0
local gbl_target_vdef = 20
local gbl_target_bearing = 0
local gbl_factor1 = 0.25
local gbl_factor2 = 0.25
local gbl_factor3 = 0.3
-- DIAL FUNCTIONS --
function new_obs(obsset)
if obsset == -1 then
if FSX_HSI_source==0 then --NAV1
xpl_command("sim/radios/obs1_down")
fsx_event("VOR1_OBI_DEC")
fs2020_event("VOR1_OBI_DEC")
end
if FSX_HSI_source==1 then -- NAV2
xpl_command("sim/radios/obs2_down")
fsx_event("VOR2_OBI_DEC")
fs2020_event("VOR2_OBI_DEC")
end
if FSX_HSI_source==2 then -- GPS
xpl_command("sim/radios/obs1_down")
fsx_event("VOR1_OBI_DEC")
fs2020_event("VOR1_OBI_DEC")
end
elseif obsset == 1 then
if FSX_HSI_source==0 then
xpl_command("sim/radios/obs1_up")
fsx_event("VOR1_OBI_INC")
fs2020_event("VOR1_OBI_INC")
end
if FSX_HSI_source==1 then
xpl_command("sim/radios/obs2_up")
fsx_event("VOR2_OBI_INC")
fs2020_event("VOR2_OBI_INC")
end
if FSX_HSI_source==2 then
xpl_command("sim/radios/obs1_up")
fsx_event("VOR1_OBI_INC")
fs2020_event("VOR1_OBI_INC")
end
end
end
function new_heading(headingset)
if headingset == -1 then
xpl_command("sim/autopilot/heading_down")
fsx_event("HEADING_BUG_DEC")
fs2020_event("HEADING_BUG_DEC")
elseif headingset == 1 then
xpl_command("sim/autopilot/heading_up")
fsx_event("HEADING_BUG_INC")
fs2020_event("HEADING_BUG_INC")
end
end
-- GRAPHICS --
if display_frame then
img_add_fullscreen("HSI_background frame.png")
end
img_add_fullscreen("HSI_background.png")
img_rose = img_add_fullscreen("HSI_compas rose.png")
img_bug = img_add_fullscreen("HSI_headingbug.png")
img_neddle = img_add_fullscreen("HSI_Needle arrow.png")
img_center_to = img_add_fullscreen("HSI_to flag.png")
img_center_from = img_add_fullscreen("HSI_from flag.png")
img_center = img_add_fullscreen("HSI_loc scale.png")
img_center_neddle = img_add_fullscreen("HSI_Needle center.png")
img_hdg_flag = img_add_fullscreen("HSI_flag HDG right.png", "visible:false")
img_nav_flag = img_add_fullscreen("HSI_flag NAV left.png", "visible:false")
img_add_fullscreen("HSI_inner bezel.png")
img_glideslope_markers = img_add_fullscreen("HSI_ILS bugs.png")--,0,-100,512,512)
img_add_fullscreen("HSI_inner bezel2.png")
img_add_fullscreen("HSI_Bezel ext.png")
if display_screws==true then
img_add_fullscreen("HSI_screws.png")
end
-- FUNCTIONS --
function removes_HDG_flag() -- removes NAV flag after gyro_spinup_duration
visible(img_hdg_flag, false)
end
function PT_hsi(heading,source,crs,nav1hdef,nav2hdef,gpshdef,nav1vdef,nav2vdef,
gpsvdef,nav1display,nav2display, nav1glideslopeflag, nav2glideslopeflag, headingbug, nav1_fromto, nav2_fromto, gps_fromto, failed, bus_volts)
-- GS Flag
if nav1glideslopeflag == 1 or nav2glideslopeflag == 1 then
glideslopeflag = 1
end
-- HDG flag
if failed == 1 or bus_volts[1] < 5 then --partial panel failure or master switch is off or main electrical bus is off
visible(img_hdg_flag, true)-- show HDG flag immediately
visible(img_nav_flag, true )
is_failed = true --instrument is off
else -- power is on
if is_failed == true then -- gauge powering up? we start a timer to let the gyro spinning before removing the flag
if not timer_running(gyro_startup_timer) then -- if timer is already started do nothing
gyro_startup_timer = timer_start(gyro_spinup_duration, nil, removes_HDG_flag) --wait for gyro_spinup_duration before removing flag
end
is_failed=false
end
end
if is_failed then --instrument is powered off
nav1display = 0
nav2display = 0
nav1hdef = 0
nav1vdef = 0
nav1_fromto = 0
nav2hdef = 0
nav2vdef = 0
nav2_fromto = 0
gpshdef = 0
gpsvdef = 0
gps_fromto = 0
glideslopeflag = 1
gbl_target_bearing = gbl_cur_bearing
end
-- global variables setting before calling of timer_callback()
gbl_target_bearing = -heading + crs
gbl_target_bug = headingbug
-- Rotate compas card
rotate(img_rose, -heading)
-- Rotate heading bug
rotate(img_bug, headingbug - heading)
rotate(img_center, gbl_target_bearing)
rotate(img_center_to, gbl_target_bearing)
rotate(img_center_from, gbl_target_bearing)
if source == 0 then -- NAV1
gbl_target_hdef = nav1hdef
gbl_target_vdef = nav1vdef
end
if source == 1 then -- NAV2
gbl_target_hdef = nav2hdef
gbl_target_vdef = nav2vdef
end
if source == 2 then -- GPS
gbl_target_hdef = gpshdef
gbl_target_vdef = gpsvdef
end
-- flags to/from
to = ((source == 0 and nav1_fromto == 1) or (source == 1 and nav2_fromto == 1) or (source == 2 and gps_fromto == 1))
from = ((source == 0 and nav1_fromto == 2) or (source == 1 and nav2_fromto == 2) or (source == 2 and gps_fromto == 2))
visible(img_center_to, to)
visible(img_center_from, from)
-- GS bugs
if glideslopeflag == 1 then -- GS signal not received
gbl_target_vdef = -3.5 -- Sends the bugs out of view
end
-- NAV flag when no valid VOR or localizer
visible(img_nav_flag, (source == 0 and nav1display == 0) or (source == 1 and nav2display == 0))
end
-- function to slowly move CDI center needle to current CDI deviation --
-- Thanks Ralph and Corjan for the trick! --
function timer_callback()
-- CDI needle
rotate(img_neddle, gbl_cur_bearing)
rotate(img_center_neddle, gbl_cur_bearing)
-- Calculation of center CDI needle position in pixels according to current needle bearing (actually bearing=course-heading)
navhdef = var_cap(gbl_cur_hdef, -4, 2.5) --horizontal deflection of CDI needle in ° (-2.5,2.5°)
dh = navhdef * math.cos((gbl_cur_bearing)* math.pi / 180) * 41 -- 41 : distance in pixels between 2 dots
dv = navhdef * math.sin((gbl_cur_bearing) * math.pi / 180) * 41
--Move center CDI needle
move(img_center_neddle, dh, dv, nil, nil)
--Move GS needle
navvdef = var_cap(gbl_cur_vdef, -4, 4)--vertical deflection of GS bugs in °
dm = (navvdef * 41) -- 40 : distance in pixels between 2 vertical dots
move(img_glideslope_markers, nil, dm , nil, nil)
--Calculation of current CDI deflection in ° with respect to target deflection position
-- currrent position is decreased/increased by "gbl_factor" every function call until reaching target position within 0.001 degrees
raw_diff = (gbl_target_hdef - gbl_cur_hdef) -- compute the delta of position
diff = fif(raw_diff,raw_diff,(raw_diff)*-1) -- chooses the sign of delta
gbl_cur_hdef = fif(math.abs(diff) < 0.001, gbl_target_hdef, gbl_cur_hdef + (diff * gbl_factor1) )-- chooses the greatest value
--Calculation of current GS deflection in ° with respect to target deflection position
raw_diff = (gbl_target_vdef - gbl_cur_vdef)
diff = fif(raw_diff,raw_diff, (raw_diff) * -1)
gbl_cur_vdef = fif(math.abs(diff) < 0.001, gbl_target_vdef, gbl_cur_vdef + (diff * gbl_factor2) )
gbl_cur_bearing = gbl_target_bearing
end
-- function to adapt FSX parameters to Xplane function
function PT_hsi_FSX(heading, obs, vertical, horizontal, nav_fromto, has_glide, headingbug, partial_panel, bus_volts)
if partial_panel == 1 then
fail = 1
else
fail = 0
end
glideslope = fif(has_glide, 0, 1) -- from FSX boolean to integer (Xplane style) 0= glideslope (no flag), 1= no g/s (flag, g/s needle off view)
vertical = 2 / 119 * vertical -- GS range from -119 to + 119 in FSX
horizontal = 2 / 127 * horizontal -- CDI range from -127 to + 127 in FSX
PT_hsi(heading, 0, obs, horizontal, 0, 0, vertical, 0, 0, nav_fromto, 0, glideslope, glideslope, headingbug, nav_fromto, 0, 0, fail, {bus_volts})
end
-- DIAL ADD --
dial_OBS = dial_add("dialhsi.png", 18, 368, 85, 85, 5, new_obs)
hw_dial_add("OBS heading", 5, new_obs)
dial_BUG = dial_add("headingbug.png", 409, 368, 85, 85, 5, new_heading)
hw_dial_add("Autopilot heading", 5, new_heading)
dial_click_rotate(dial_OBS, 5)
dial_click_rotate(dial_BUG, 5)
if FSX_HSI_source == 0 then -- NAV1 (default)
fsx_variable_subscribe("HEADING INDICATOR", "Degrees", --"PLANE HEADING DEGREES GYRO", "Degrees",
"NAV OBS:1", "Degrees",
"NAV GSI:1", "Number",
"NAV CDI:1", "Number",
"NAV TOFROM:1", "Enum",
"NAV HAS GLIDE SLOPE:1", "Bool",
"AUTOPILOT HEADING LOCK DIR", "Degrees",
"PARTIAL PANEL ELECTRICAL", "Enum", -- failure of electrical bus
"ELECTRICAL MAIN BUS VOLTAGE","Volts", PT_hsi_FSX)-- master switch
fs2020_variable_subscribe("HEADING INDICATOR", "Degrees", --"PLANE HEADING DEGREES GYRO", "Degrees",
"NAV OBS:1", "Degrees",
"NAV GSI:1", "Number",
"NAV CDI:1", "Number",
"NAV TOFROM:1", "Enum",
"NAV HAS GLIDE SLOPE:1", "Bool",
"AUTOPILOT HEADING LOCK DIR", "Degrees",
"PARTIAL PANEL ELECTRICAL", "Enum", -- failure of electrical bus
"ELECTRICAL MAIN BUS VOLTAGE","Volts", PT_hsi_FSX)-- master switch
end
if FSX_HSI_source == 1 then -- NAV2
fsx_variable_subscribe("HEADING INDICATOR", "Degrees", --"PLANE HEADING DEGREES GYRO", "Degrees",
"NAV OBS:2", "Degrees",
"NAV GSI:2", "Number",
"NAV CDI:2", "Number",
"NAV TOFROM:2", "Enum",
"NAV HAS GLIDE SLOPE:2", "Bool",
"AUTOPILOT HEADING LOCK DIR", "Degrees",
"PARTIAL PANEL ELECTRICAL", "Enum", -- failure of electrical bus
"ELECTRICAL MAIN BUS VOLTAGE","Volts", PT_hsi_FSX)-- master switch
fs2020_variable_subscribe("PLANE HEADING DEGREES MAGNETIC", "Degrees", --"PLANE HEADING DEGREES GYRO", "Degrees",
"NAV OBS:2", "Degrees",
"NAV GSI:2", "Number",
"NAV CDI:2", "Number",
"NAV TOFROM:2", "Enum",
"NAV HAS GLIDE SLOPE:2", "Bool",
"AUTOPILOT HEADING LOCK DIR", "Degrees",
"PARTIAL PANEL ELECTRICAL", "Enum", -- failure of electrical bus
"ELECTRICAL MAIN BUS VOLTAGE","Volts", PT_hsi_FSX)-- master switch
end
if FSX_HSI_source == 2 then -- GPS
fsx_variable_subscribe("HEADING INDICATOR", "Degrees",--"PLANE HEADING DEGREES GYRO", "Degrees",
"NAV OBS:1", "Degrees",
"HSI GSI NEEDLE", "Number",
"HSI CDI NEEDLE", "Number",
"HSI TF FLAGS", "Enum",
"HSI GSI NEEDLE VALID", "Bool",
"AUTOPILOT HEADING LOCK DIR", "Degrees",
"PARTIAL PANEL ELECTRICAL", "Enum",-- failure of electrical bus
"ELECTRICAL MAIN BUS VOLTAGE","Volts",PT_hsi_FSX)-- master switch
fs2020_variable_subscribe("PLANE HEADING DEGREES MAGNETIC", "Degrees",--"PLANE HEADING DEGREES GYRO", "Degrees",
"NAV OBS:1", "Degrees",
"HSI GSI NEEDLE", "Number",
"HSI CDI NEEDLE", "Number",
"HSI TF FLAGS", "Enum",
"HSI GSI NEEDLE VALID", "Bool",
"AUTOPILOT HEADING LOCK DIR", "Degrees",
"PARTIAL PANEL ELECTRICAL", "Enum",-- failure of electrical bus
"ELECTRICAL MAIN BUS VOLTAGE","Volts",PT_hsi_FSX)-- master switch
end
xpl_dataref_subscribe("sim/cockpit/gyros/psi_ind_elec_pilot_degm", "FLOAT",-- electrical, not vacuum
"sim/cockpit2/radios/actuators/HSI_source_select_pilot", "INT",
"sim/cockpit2/radios/actuators/hsi_obs_deg_mag_pilot", "FLOAT",
"sim/cockpit/radios/nav1_hdef_dot", "FLOAT",
"sim/cockpit/radios/nav2_hdef_dot", "FLOAT",
"sim/cockpit/radios/gps_hdef_dot", "FLOAT",
"sim/cockpit/radios/nav1_vdef_dot", "FLOAT",
"sim/cockpit/radios/nav2_vdef_dot", "FLOAT",
"sim/cockpit/radios/gps_vdef_dot", "FLOAT",
"sim/cockpit2/radios/indicators/nav1_display_horizontal", "INT",
"sim/cockpit2/radios/indicators/nav2_display_horizontal", "INT",
"sim/cockpit2/radios/indicators/nav1_flag_glideslope","INT",
"sim/cockpit2/radios/indicators/nav2_flag_glideslope","INT",
"sim/cockpit2/autopilot/heading_dial_deg_mag_pilot", "FLOAT",
"sim/cockpit/radios/nav1_fromto", "INT",
"sim/cockpit/radios/nav2_fromto", "INT",
"sim/cockpit/radios/gps_fromto", "INT",
"sim/operations/failures/rel_esys","INT", -- failure of main bus
"sim/cockpit2/electrical/bus_volts", "FLOAT[6]", PT_hsi) -- master switch on
-- Timers
timer_start(0, 50,timer_callback) -- moves the CDI needle every 0.05 second by calling the timer_callback() function