CDI needle tuning on Generic HSI KI525A MSFS

Help creating logic scripts for Air Manager Instruments

Moderators: russ, Ralph

Message
Author
blokovchan
Posts: 32
Joined: Tue Jul 26, 2022 6:13 am

CDI needle tuning on Generic HSI KI525A MSFS

#1 Post by blokovchan »

Hello guys
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
Zajeta-slika.jpg

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
Last edited by blokovchan on Thu Jul 28, 2022 6:33 am, edited 2 times in total.

blokovchan
Posts: 32
Joined: Tue Jul 26, 2022 6:13 am

Re: CDI needle tuning on Generic HSI KI525A MSFS

#2 Post by blokovchan »

Update: glide slope indicator in the ils approach also isn't working, so I need support also on that...

User avatar
Ralph
Posts: 7924
Joined: Tue Oct 27, 2015 7:02 pm
Location: De Steeg
Contact:

Re: CDI needle tuning on Generic HSI KI525A MSFS

#3 Post by Ralph »

The CDI needle is an issue in FS2020, the value for GPS is incorrect. You have to multiply the value for GPS, you can see this in the Garmin GI 106A/B CDI.
This is something that Microsoft / Asobo has to fix.

This instrument is made by @JackZ I believe. I'm still not sure if he wants to look at it or if we should.

JackZ
Posts: 2267
Joined: Mon Feb 22, 2016 1:02 pm

Re: CDI needle tuning on Generic HSI KI525A MSFS

#4 Post by JackZ »

Yeah, kinda starting to be tired of complaints about a gauge I worked on more than 6 (six!) years ago, a day where MSFS was not even a dream…
Lots of complaints, but as far as I recall no one ever said “thanks”.

This one is about a specific addon that might interfere as well, and I don’t use MSFS for my personal use.

So let me be clear: I don’t develop gauges for everybody’s pleasure but if and when I fell the need for my personal purpose.
If a gauge fits my personal goal, that’s it.

I am okay in publishing the said gauge on the store afterwards for other to use, but I feel absolutely no constraints about maintaining this gauge, nor adapting the said gauge for another’s people specific need or request. Especially considering what I said about people taking that work for granted, even for free.

So here basically, people went on modifying my code and now are asking for help? Thank you, but no thank you. My plate is already full.
IF and WHEN the need arise for myself I’ll have a look at it, but that’s a big IF.
My YouTube Chanel on the A320 (Real SOPs by an Airline Pilot IRL):
https://www.youtube.com/playlist?list=P ... 0Q6SBASRqJ

User avatar
Ralph
Posts: 7924
Joined: Tue Oct 27, 2015 7:02 pm
Location: De Steeg
Contact:

Re: CDI needle tuning on Generic HSI KI525A MSFS

#5 Post by Ralph »

The question was if you want us to do it or if you want to do it yourself. There has been a lot of discussion about people editing someone else's instruments, therefore I'm asking if it is okay for us to fix these issues.
I'm not saying that you have to do it.

JackZ
Posts: 2267
Joined: Mon Feb 22, 2016 1:02 pm

Re: CDI needle tuning on Generic HSI KI525A MSFS

#6 Post by JackZ »

@Ralph, my ranting was obviously not directed towards you.
I am pretty busy with other projects ATM and as said I don’t even really understand what the problem, so go ahead if you do!
My YouTube Chanel on the A320 (Real SOPs by an Airline Pilot IRL):
https://www.youtube.com/playlist?list=P ... 0Q6SBASRqJ

User avatar
Ralph
Posts: 7924
Joined: Tue Oct 27, 2015 7:02 pm
Location: De Steeg
Contact:

Re: CDI needle tuning on Generic HSI KI525A MSFS

#7 Post by Ralph »

Thanks! I'll give the script a rework with animations and such.

blokovchan
Posts: 32
Joined: Tue Jul 26, 2022 6:13 am

Re: CDI needle tuning on Generic HSI KI525A MSFS

#8 Post by blokovchan »

@JackZ :
I wasn't suggesting, that you should fix the code for hsi. I was asking for tips, from the community, on how can I do it by myself. I managed to fix the code so that the heading dial is working and that the heading flag isn't displayed to early (JustFLight Pa28 voltage quickly drops below 10 volts, if the engine is not running, and so on), by myself. Other stuff is to advanced for me at the moment. I just bought Air Manager the previous week and I'm not a programer, so I could quickly learn lua... :)

@Ralph : I apologize for similar repeating questions and request. We have a similar discussion on how the instruments are updated in that other topic. :)
Could you please mention here, when you will rework script, because I have a local clone of the instrument with the changes mentioned above, and my instrument won't update automagically when you will publish changes...

User avatar
Ralph
Posts: 7924
Joined: Tue Oct 27, 2015 7:02 pm
Location: De Steeg
Contact:

Re: CDI needle tuning on Generic HSI KI525A MSFS

#9 Post by Ralph »

I'm going to work on it today. Probably done by the end of the day.

blokovchan
Posts: 32
Joined: Tue Jul 26, 2022 6:13 am

Re: CDI needle tuning on Generic HSI KI525A MSFS

#10 Post by blokovchan »

@Ralph : Thanks.
I should say this. Imo one the most imprtant criteria, for judging the quality of sotware, is quality of supprt, especially in a world of flightsim, where, because of complexity and quantity of the components, a lot of things dont work out of the box. :D
Well, after a good week of using Air Manager, I dare to say that AM, scores here very highly... ;)

Post Reply