Board index FlightGear Support Flying

RNAV with KNS80 trouble (SOLVED)

Controlling your aircraft, using the autopilot etc.

Re: RNAV with KNS80 trouble (NOT SO - PARTIALLY SOLVED)

Postby jogois » Tue Sep 04, 2018 9:28 pm

UPDATE--- having pasted the "alias" option into the KNS80.nas (inside the mode 2 and 3 conditions so it is triggered only by RNAV modes) the result is the same, but now I think that the blinking of the CDI needle DOESN'T have to do with the animation rate (increasing it would solve the visual issue but only aparently), but to the persistence of the "/instrumentation/nav/radials/whatever-values" in spite of the alias (or listener) option:

If we browse the internal properties once the aliases are passed from kns-80/rnav, we can se that "/instrumentation/kns-80/rnav/actual-deg, reciprocal-radial-deg, and heading-needle-deflection" also blink between the "legitimate" nav values and the passed ones from itself.

Now I see that the solution resides on how to make nav to omit its legitimate values while the RNAV modes are selected, UPDATED-->>or to add a new animation tag inside ki206.xml that points to /instrumetation/kns-80/rnav/whatever-needed-values ONLY when RNAV modes are active. I'll see.

Note: by saying in my previous post that the CDI needle now points to our waypoint, I mean it points to our selected course that in turn would be the course we have chosen to fly direct to our waypoint in our flightplan (according to the KNS80 Pilot's Guide).

Again, any ideas?

More next time.

Jogois
jogois
 
Posts: 25
Joined: Thu Dec 25, 2008 5:41 pm
Location: Europe
OS: Ubuntu-Mate 18.04

Re: RNAV with KNS80 trouble (NOT SO - PARTIALLY SOLVED)

Postby jogois » Thu Sep 06, 2018 10:27 am

The experiment continues, and I think we are getting closer to the solution.

This time I tested the "listeners" option in the KNS80.nas file, and although it produces the same result as the "alias" option mentioned above (being this time the relevant values in /nav/radials the ones that blinked, or better said, the ones that flashed between the "legitimate" nav values and the ones passed from /kns-80/rnav) it led me to understand that the problem had to do with the refreshing time of the updateRNAV function in the KNS80.nas. Checking the forum I found this post dated back from 2009:

https://forum.flightgear.org/viewtopic.php?f=4&t=5623&start=0&st=0&sk=t&sd=a

From that I started to think that tweaking the settimer in the KNS80.nas would solve the blinking-flashing CDI needle, and it did just by following the suggestion in that post. The problem for the CDI needle to work without flashing is there, in the settimer. However, if we change it for good the flashing frequency of the DSP numbers in the KNS80 panel is also modified (we don't want that). The solution comes either by modifying the settimer and tweaking the flashing time of the DSP numbers for these to keep their 1/2 second flashing time, or by using a new settimer to control the listeners inside the KNS80.nas. I keep on trying.

Other thing, just in case anyone is thinking why this (me) flightgear fan is taking so much effort in modifying something that seemed to work: what I'm trying to get is that the KNS80 in FG is as close as possible to the experiences posted in:

https://www.pilotsofamerica.com/community/threads/how-to-fly-direct-w-kns80.14391/

Right now, there is no way to get it since it is hidden behind the GPS.

More next time.

Jogois
Last edited by jogois on Sun Sep 09, 2018 8:43 pm, edited 1 time in total.
jogois
 
Posts: 25
Joined: Thu Dec 25, 2008 5:41 pm
Location: Europe
OS: Ubuntu-Mate 18.04

Re: RNAV with KNS80 trouble (NOT SO - PARTIALLY SOLVED)

Postby WoodSTokk » Sat Sep 08, 2018 3:36 am

jogois wrote in Tue Sep 04, 2018 9:28 pm:If we browse the internal properties once the aliases are passed from kns-80/rnav, we can se that "/instrumentation/kns-80/rnav/actual-deg, reciprocal-radial-deg, and heading-needle-deflection" also blink between the "legitimate" nav values and the passed ones from itself.


This is because the values will be updated from the core. If you also write to this properties, the values become jumpy.

jogois wrote in Tue Sep 04, 2018 9:28 pm:Now I see that the solution resides on how to make nav to omit its legitimate values while the RNAV modes are selected,

No.
jogois wrote in Tue Sep 04, 2018 9:28 pm:UPDATED-->>or to add a new animation tag inside ki206.xml that points to /instrumetation/kns-80/rnav/whatever-needed-values ONLY when RNAV modes are active. I'll see.

Add a new property for the CDI needle and update your nas (or write a filter) that feed the right value to the new property acording to the setting of the AP.
As example look at the instrument filters of the Citation II. I have filters for all mechanical needles to avoid needle jumps while switching inputs.
https://sourceforge.net/p/flightgear/fgaddon/HEAD/tree/trunk/Aircraft/Citation/Models/Instruments/instrument-filters.xml
WoodSTokk
 
Posts: 1077
Joined: Tue Oct 17, 2017 3:30 pm
Location: Milky Way/Sol/Earth/Europe
Callsign: SX-W57
IRC name: WoodSTokk
Version: 2020.4.0
OS: Debian Bullseye

Re: RNAV with KNS80 trouble (NOT SO - PARTIALLY SOLVED)

Postby jogois » Sun Sep 09, 2018 9:23 pm

Thank you very much for answering.

As you can see in my post following the one you quote, I refer to the refreshing frequency of the updateRNAV function as a possible solution for the problem. By changing that frequency I finally got the CDI needle animation to be smooth.

Also, the issue of the display digit flashing time was solved by separating the relevant part of the "update" function at the end of the KNS80.nas file and including it into a new one with its own "settimer". Appending this new function to the signal ("setlistener("/sim/signals/fdm-initialized" ...) at the end of the file solves de flashing digit issue.

Below I include the code of my first version of the KNS80.nas for testing purposes (copy it to a file and name it KNS80.nas, then place it in the kns80 folder in the tree of Patten's Aerostar). I have documented my modifications clearly, so they can be easily seen. I would apreciate if anyone test the file (if so, first make sure to set the "slaved-to-gps" to false in the kns80.xml as I mentioned in one of my previous posts).

As you can see from the comments in the included KNS80.nas code, for the moment the to-from flag is not usable in RNAV modes. I'm considering to solve the problem either by writing new code for the to-nav flag to work inside a condition executed only if modes 2 ans 3 are active, or by slaving the dme/indicated-distance-nm to that value passed from rnav. I'll see.

Again, thank you very much for your advice. I'll definitely take a look at the instrument filters of the Citation II.


Jogois


Below is the code for the new KNS80.nas (for testing functionality):

Code: Select all
####    King KNS-80 Integrated Navigation System   ####
####    Syd Adams    ####
####    Ron Jensen   ####
####
####   Must be included in the Set file to run the KNS80 radio
####
#### Nav Modes  0 = VOR ; 1 = VOR/PAR ; 2 = RNAV/ENR ; 3 = RNAV/APR ;
####

################################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
################################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#
#THIS VERSION OF THE ORIGINAL FILE HAS BEEN MODIFIED BY JOGOIS. THE AIM OF THIS VERSION IS TO
#MAKE THE KNS80 IN FLIGHTGEAR TO BE GPS INDEPENDENT. ALL REFERENCES TO THE GPS IN THE
#ORIGINAL FILE HAVE BEEN COMMENTED OUT (THEY ARE KEEPT AS COMMENTS JUST FOR TRACKING THE
#CHANGES MADE TO THE ORIGINAL FILE). CONSEQUENTLY THE "slaved-to-gps" PROPERTY IN kns80.xml
#MUST BE SET TO FALSE.
#
#THE FUNCTIONALITY OF THE KNS80 HAS BEEN GOT BY USING "alias" IN NASAL ("setlistener" WAS ALSO
#CONSIDERED AND TESTED, AND ALTHOUGH THIS OPTION WORKED AS WELL, WAS NOT FINALLY CHOSEN).
#THE MODIFICATIONS MADE ARE CONTAINED BETWEEN DOUBLE "####>>>>" LINES FOR CLARITY.
#
#THIS IS VERSION 1.1 OF THE FILE (SOME CORRECTIONS TO THE COMMENTS). THERE ARE STILL MODIFICATIONS TO BE DONE
# (i.e.: THE TO-FROM FLAG IS NOT RELIABLE YET IN RNAV MODES SINCE BEFORE IT DEPENDED ON THE GPS).
#USE ONLY FOR TESTING FUNCTIONALITY OF THE KNS80 WITHOUT DEPENDING ON THE GPS.
#
#IN CASE YOU WANT TO TEST IT MAKE SURE YOU BACK UP THE ORIGINAL KNS80.nas AND kns80.xml
#FILES SO YOU CAN UNDO THE CHANGES.
#
#SEPTEMBER 9, 2018  BY JOGOIS
#
#########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

var KNS80 = {
    new : func(prop){
        var m = { parents : [KNS80]};
      m.wpt_freq=[];
      m.wpt_radial=[];
      m.wpt_distance=[];
        m.volume_adjust =0;
      m.nav_selected = "instrumentation/nav/frequencies/selected-mhz";
      m.dme_selected = "instrumentation/dme/frequencies/selected-mhz";
      m.display_num = 0;
      m.use_num = 0;
      m.flasher = 0;
      
      m.kns80 = props.globals.initNode(prop);
      m.serviceable = m.kns80.initNode("serviceable",1,"BOOL");
      m.data_mode = m.kns80.initNode("data-mode",0,"DOUBLE");
        m.nav_mode = m.kns80.initNode("nav-mode",0,"DOUBLE");
        m.dme_hold = m.kns80.initNode("dme-hold",0,"BOOL");
      m.dsp_flash = m.kns80.initNode("flash",0,"BOOL");
      m.display = m.kns80.initNode("display",0,"DOUBLE");
      m.use = m.kns80.initNode("use",0,"DOUBLE");

      append(m.wpt_freq,m.kns80.initNode("wpt[0]/frequency",115.80,"DOUBLE"));
      append(m.wpt_freq,m.kns80.initNode("wpt[1]/frequency",111.70,"DOUBLE"));
      append(m.wpt_freq,m.kns80.initNode("wpt[2]/frequency",116.80,"DOUBLE"));
      append(m.wpt_freq,m.kns80.initNode("wpt[3]/frequency",113.90,"DOUBLE"));

      append(m.wpt_radial,m.kns80.initNode("wpt[0]/radial",280.0,"DOUBLE"));
      append(m.wpt_radial,m.kns80.initNode("wpt[1]/radial",280.0,"DOUBLE"));
      append(m.wpt_radial,m.kns80.initNode("wpt[2]/radial",029.0,"DOUBLE"));
      append(m.wpt_radial,m.kns80.initNode("wpt[3]/radial",029.0,"DOUBLE"));

      append(m.wpt_distance,m.kns80.initNode("wpt[0]/distance",0,"DOUBLE"));
      append(m.wpt_distance,m.kns80.initNode("wpt[1]/distance",0,"DOUBLE"));
      append(m.wpt_distance,m.kns80.initNode("wpt[2]/distance",0,"DOUBLE"));
      append(m.wpt_distance,m.kns80.initNode("wpt[3]/distance",0,"DOUBLE"));

        m.displayed_distance = m.kns80.initNode("displayed-distance",m.wpt_distance[0].getValue(),"DOUBLE");
        m.displayed_frequency = m.kns80.initNode("displayed-frequency",m.wpt_freq[0].getValue(),"DOUBLE");
        m.displayed_radial = m.kns80.initNode("displayed-radial",m.wpt_radial[0].getValue(),"DOUBLE");

      m.NAV=props.globals.initNode("instrumentation/nav");
      m.NAV1 = m.NAV.initNode("frequencies/selected-mhz");
      m.NAV1_RADIAL = m.NAV.initNode("radials/selected-deg");
      m.NAV1_ACTUAL = m.NAV.initNode("radials/actual-deg");
      m.NAV1_TO_FLAG = m.NAV.initNode("to-flag");
      m.NAV1_FROM_FLAG = m.NAV.initNode("from-flag");
      m.NAV1_HEADING_NEEDLE_DEFLECTION = m.NAV.initNode("heading-needle-deflection");
      m.NAV1_IN_RANGE = m.NAV.initNode("in-range");
      m.NAV1_distance = m.NAV.initNode("distance");

######################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
######################>>>>>>>>>>>>>>>>>>>>>>>>>>THE LINE BELOW WAS ADDED SINCE IT IS NEEDED

        m.NAV1_RECIPROCAL = m.NAV.initNode("radials/reciprocal-radial-deg");

######################>>>>>>>>>>>>>>>>>>>>>>>>>>>THE LINE ABOVE WAS ADDED SINCE IT IS NEEDED
######################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>      

        m.NAV_volume = m.NAV.initNode("volume",0.2,"DOUBLE");


########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINES BELOW COMMENTED OUT

#      m.CDI_NEEDLE = props.globals.initNode("/instrumentation/gps/cdi-deflection");
#      m.TO_FLAG    = props.globals.initNode("/instrumentation/gps/to-flag");
#      m.FROM_FLAG  = props.globals.initNode("/instrumentation/gps/from-flag");

########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINES ABOVE COMMENTED OUT
########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

      m.RNAV = m.kns80.initNode("rnav");
      m.RNAV_deflection = m.RNAV.initNode("heading-needle-deflection",0,"DOUBLE");
      m.RNAV_distance = m.RNAV.initNode("indicated-distance-nm",0,"DOUBLE");
      m.RNAV_reciprocal = m.RNAV.initNode("reciprocal-radial-deg",0,"DOUBLE");
      m.RNAV_actual_deg = m.RNAV.initNode("actual-deg",0,"DOUBLE");
       
      m.DME_mhz = props.globals.initNode("instrumentation/dme/frequencies/selected-mhz",0,"DOUBLE");
      m.DME_src = props.globals.initNode("instrumentation/dme/frequencies/source",m.nav_selected,"STRING");
      m.DME_dist = props.globals.initNode("instrumentation/dme/indicated-distance-nm",0,"DOUBLE");
      return m;
    },

#### volume adjust ####

volume : func(vlm){
      var vol = me.NAV_volume.getValue();
      vol += vlm;
      if(vol > 1.0)vol = 1.0;
      if(vol < 0.0){
         vol = 0.0;
         me.serviceable.setBoolValue(0);
         setprop("/instrumentation/nav/serviceable",0);
         setprop("/instrumentation/dme/serviceable",0);
      }
      if(vol > 0.0){
         me.serviceable.setBoolValue(1);
         setprop("/instrumentation/nav/serviceable",1);
         setprop("/instrumentation/dme/serviceable",1);
      }
      me.NAV_volume.setValue(vol);
    },

#### dme hold ####

DME_hold : func{
   var hold = me.dme_hold.getValue();
    hold= 1- hold;
   me.dme_hold.setValue(hold);
   if(hold==1){
        me.DME_mhz.setValue(me.NAV1.getValue());
        me.DME_src.setValue(me.dme_selected);
    }else{
        me.DME_mhz.setValue(0);
        me.DME_src.setValue(me.nav_selected);
        }
    },

#### display button ####

display_btn : func{
   me.display_num +=1;
   if(me.display_num>3)me.display_num=0;
   me.displayed_frequency.setValue(me.wpt_freq[me.display_num].getValue());
    me.displayed_distance.setValue(me.wpt_distance[me.display_num].getValue());
    me.displayed_radial.setValue(me.wpt_radial[me.display_num].getValue());
    me.data_mode.setValue(0);
    if(me.use_num == me.display_num){
        me.flasher=0;
      }else{
      me.flasher=1;
        }
   me.display.setValue(me.display_num);
    },


#### use button ####

use_btn : func{
   me.use_num = me.display_num;
    me.flasher=0;
    me.data_mode.setValue(0);
    me.use.setValue(me.use_num);
   me.NAV1.setValue(me.wpt_freq[me.display_num].getValue());
    },

#### data button ####

data_btn : func{
   var data = me.data_mode.getValue();
    data +=1;
   if(data > 2) data = 0;
    me.data_mode.setValue(data);
    },

#### data adjust ####

   data_adjust : func(dtadj){
    var dmode = me.data_mode.getValue();
    var num = dtadj;
    dtadj=0;
    if(dmode == 0){
        if(num == -1 or num ==1){num = num *0.05;}else{num = num *0.10;}
        var newfreq = me.displayed_frequency.getValue();
        newfreq += num;
        if(newfreq > 118.95){newfreq -= 11.00;}
        if(newfreq < 108.00){newfreq += 11.00;}
        me.displayed_frequency.setValue(newfreq);
      me.wpt_freq[me.display_num].setValue(newfreq);
       if(me.use_num == me.display_num)me.NAV1.setValue(newfreq);
    }elsif(dmode == 1){
        var newrad = me.displayed_radial.getValue();
        newrad += num;
        if(newrad > 359){newrad -= 360;}
        if(newrad < 0){newrad += 360;}
        me.displayed_radial.setValue(newrad);
      me.wpt_radial[me.display_num].setValue(newrad);
    }elsif(dmode == 2){
        var newdist = me.displayed_distance.getValue();
        if(num == -1 or num ==1 ){num = num *0.1;}
        newdist += num;
        if(newdist > 99){newdist -= 100;}
        if(newdist < 0){newdist += 100;}
        me.displayed_distance.setValue(newdist);
      me.wpt_distance[me.display_num].setValue(newdist);
    }
},

#### update RNAV ####

# Properties
# outputs
# distance, radial from VOR Station
# rho, theta: distance and radial for phantom station
# range, bearing: distance and radial from phantom station
#### Nav Modes  0 = VOR ; 1 = VOR/PAR ; 2 = RNAV/ENR ; 3 = RNAV/APR ;

updateRNAV : func{

   if(!me.NAV1_IN_RANGE.getValue()) {
        return;
    }
   var mode = me.nav_mode.getValue() or 0;
    var distance=me.DME_dist.getValue() or 0;
    var selected_radial = me.NAV1_RADIAL.getValue() or 0;
    var radial = me.NAV1_ACTUAL.getValue() or 0;
    var rho = me.wpt_distance[me.use_num].getValue();
    var theta = me.wpt_radial[me.use_num].getValue();
    var fangle = 0;
    var needle_deflection = 0;
    var from_flag=1;
    var to_flag  =0;
   
    var x1 = distance * math.cos( radial*D2R );
    var y1 = distance * math.sin( radial*D2R );
    var x2 = rho * math.cos( theta*D2R );
    var y2 = rho * math.sin( theta*D2R );

    var range = math.sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) );
    var bearing = math.atan2 (( y1-y2), (x1-x2))*R2D;

    if(bearing < 0) bearing += 360;
    var abearing = bearing > 180 ? bearing - 180 : bearing + 180;

    if( mode == 0){
        needle_deflection = (me.NAV1_HEADING_NEEDLE_DEFLECTION.getValue());
        range = distance;
    }
    if ( mode == 1){
        fangle = math.abs(selected_radial - radial);
        needle_deflection = math.sin((selected_radial - radial) * D2R) * distance * 2;
        range = distance;
    }
    if ( mode == 2){
       fangle = math.abs(selected_radial - bearing);
       needle_deflection = math.sin((selected_radial - bearing) * D2R) * range * 2;
    }

    if ( mode == 3){
        fangle = math.abs(selected_radial - bearing);
        needle_deflection = math.sin((selected_radial - bearing) * D2R) * range * 8;
    }


#####################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>NOTE BELOW:
#THE "alias" OPTION HAS BEEN USED TO PASS THE VALUES GENERATED IN KNS-80 RNAV MODES TO THE
#MAIN NAV SYSTEM. THIS WAY THE NAV GOVERNED DEVICES (HSI'S CDI NEEDLE IN THIS CASE) ARE
#"SLAVED" TO THE RNAV VALUES SO WE CAN MAKE USE OF THE CDI NEEDLE AS IN NAV MODE TO FLY TO
#THE WAYPOINTS WITHOUT GPS, WHICH IS CLOSER TO THE REAL THING. THE OPTION HAS BEEN INCLUDED
#INSIDE A CONDITION THAT IS EXECUTED ONLY IF RNAV MODES (MODES 2 and 3) ARE ACTIVE. ACCORDINGLY
#AN "unalias" HAS BEEN INCLUDED AND IT IS EXECUTED EVERYTIME THE VOR OR VOR/PAR MODES ARE
#ACTIVE (MODES 0 AND 1).



    if (( mode == 2) or (mode == 3))  {
    props.globals.getNode("/instrumentation/nav/radials/actual-deg").alias("/instrumentation/kns-80/rnav/actual-deg");
    props.globals.getNode("/instrumentation/nav/radials/reciprocal-radial-deg").alias("/instrumentation/kns-80/rnav/reciprocal-radial-deg");
    props.globals.getNode("/instrumentation/nav/heading-needle-deflection").alias("/instrumentation/kns-80/rnav/heading-needle-deflection");
    }

    if (( mode == 0) or (mode == 1))  {
    props.globals.getNode("/instrumentation/nav/radials/actual-deg").unalias("/instrumentation/kns-80/rnav/actual-deg");
    props.globals.getNode("/instrumentation/nav/radials/reciprocal-radial-deg").unalias("/instrumentation/kns-80/rnav/reciprocal-radial-deg");
    props.globals.getNode("/instrumentation/nav/heading-needle-deflection").unalias("/instrumentation/kns-80/rnav/heading-needle-deflection");
    }

########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINES ABOVE ADDED
#########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>

    if ( needle_deflection >  10) needle_deflection = 10;
    if ( needle_deflection < -10) needle_deflection =-10;
    if (fangle < 90 or fangle >270){
        from_flag=1;
        to_flag  =0;
    } else {
        from_flag=0;
        to_flag  =1;
    }

#####################
    me.RNAV_deflection.setValue(needle_deflection);

########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
########################>>>>>>>>>>>>>>>>>>LINES BELOW COMMENTED OUT SINCE THEY ARE GPS DEPENDANT.

#    me.CDI_NEEDLE.setDoubleValue(needle_deflection);
#    me.TO_FLAG.setDoubleValue(to_flag);
#    me.FROM_FLAG.setDoubleValue(from_flag);

########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINES ABOVE COMMENTED OUT
########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    me.RNAV_distance.setValue(range);
    me.RNAV_reciprocal.setValue(abearing);
    me.RNAV_actual_deg.setValue(bearing);
   }

};

###########################################

var kns80 = KNS80.new("instrumentation/kns-80");

setlistener("/sim/signals/fdm-initialized", func {
      update();


#####################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINE BELOW ADDED TO INCLUDE
#THE "flashstatus" FUNCTION INTO THE SIGNAL ABOVE.

        flashstatus();

########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINE ABOVE ADDED
#########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

   });

var update = func {
   kns80.updateRNAV();


##########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
##########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> NOTE:
#THE PART OF THE FUNCTION THAT CORRESPONDS TO THE FLASHING OF THE DISPLAY DIGIT HAS BEEN SEPARATED INTO
#ANOTHER FUNCTION ("flashstatus" - the chosen name is self explanatory) THAT HAS BEEN INCLUDED IN THE
#SIGNAL ("setlistener") ABOVE TO MAKE ITS REFRESHING FREQUENCY INDEPENDENT OF THE ONE AFFECTING THE
#FUNCTION "update". THE DEFINITION OF THE FUNCTION "flashstatus" AND ITS "settimer" ARE AT THE BOTTOM OF THIS FILE.


##########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
##########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>NOTE BELOW:
#THE VALUE CHOSEN FOR THE "update" settimer MAY BE SYSTEM DEPENDANT. IN MY PERSONAL CASE IT IS THE VALUE
#THAT BEST DISPLAYS THE CDI NEEDLE IN RNAV MODES. ITS VALUE CORRESPONDS ROUGHLY TO 60Hz THAT, AGAIN IN
#MY PERSONAL CASE, IS THE SAME AS THE REFRESHING FREQUENCY OF MY MONITOR. START WITH THIS VALUE AND THEN
#YOU CAN MODIFY IT IF YOU WISH.

settimer(update,0.015);

};


#####################################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#####################################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINE BELOW ADDED

    var flashstatus = func {

########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINE ABOVE ADDED
#########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#NOTE: BELOW IS THE PORTION OF THE ORIGINAL "update" FUNCTION THAT HAS BEEN SEPARATED. SEE NOTE ABOVE.

      var fl = kns80.dsp_flash.getValue();
   
      if(kns80.flasher){
         kns80.dsp_flash.setValue(1-fl);
      }else{
         kns80.dsp_flash.setValue(1);
      };

#####################################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#####################################>>>>>>>>>>>>>>>>>>>>>>>LINES BELOW ADDED. SEE NOTE ABOVE.

    settimer(flashstatus, 0.5);

    };

#####################################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINES ABOVE ADDED
#####################################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
jogois
 
Posts: 25
Joined: Thu Dec 25, 2008 5:41 pm
Location: Europe
OS: Ubuntu-Mate 18.04

Re: RNAV with KNS80 trouble (NOT SO - PARTIALLY SOLVED)

Postby jogois » Fri Sep 14, 2018 6:56 pm

Well, finally got the to-from flags to be usable in RNAV modes. I include the code for the new KNS80.nas with the new modifications made to the original file. Those modifications are pointed out as comments in the code.

There is a lot to be done though: the HOLD button doesn't quite behave as described in the KNS80 Pilot's Guide because, as stated in the MOONEY AIRCRAFT CORPORATION AFM SUPPLEMENT FOR MODELS M20C, M20J, M20K, M20L, M20M ON THE KNS-80 RNAV SYSTEM (http://www.mooney201.de/files/KNS-80---C-J-K-L-M.pdf), it should be a two position pushbutton. That would explain the differences from the described functionality and the one in FG's. I must say that I haven't modified the DME_hold function inside the KNS80.nas (yet!), it is as it was.

One of the next tasks I assign to myself will be to recode the DME_hold function so we get it to work as per the Pilot's Guide. Besides I will try to make the CDI to be "FLAGGED" if the conditions listed in the above mentioned Mooney Aircraft Corporation's AFM Supplement are fulfilled (point 4.2.2.11, page 7 of 9 ).

Jogois

Bellow is the code for the KNS80.nas:

Code: Select all
####    King KNS-80 Integrated Navigation System   ####
####    Syd Adams    ####
####    Ron Jensen   ####
####
####   Must be included in the Set file to run the KNS80 radio
####
#### Nav Modes  0 = VOR ; 1 = VOR/PAR ; 2 = RNAV/ENR ; 3 = RNAV/APR ;
####

################################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
################################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>COMMENTS BELOW ADDED
#
#THIS VERSION OF THE ORIGINAL FILE HAS BEEN MODIFIED BY JOGOIS. THE AIM OF THIS VERSION IS TO
#MAKE THE KNS80 IN FLIGHTGEAR TO BE GPS INDEPENDENT. ALL REFERENCES TO THE GPS IN THE ORIGINAL FILE HAVE
#BEEN COMMENTED OUT (THEY ARE KEPT AS COMMENTS JUST FOR TRACKING THE CHANGES MADE TO THE ORIGINAL FILE).
#CONSEQUENTLY THE "slaved-to-gps" PROPERTY IN kns80.xml HAS BEEN SET TO FALSE (TO 0).
#
#THE FUNCTIONALITY OF THE KNS80 HAS BEEN GOT BY USING "alias" PROPERTY IN NASAL ("setlistener" WAS ALSO
#CONSIDERED AND TESTED, AND ALTHOUGH THIS OPTION WORKED AS WELL, WAS NOT FINALLY CHOSEN).
#
#THE MODIFICATIONS TO THE ORIGINAL FILE ARE CONTAINED BETWEEN DOUBLE LINES OF "###>>>>>>>": SOME ARE
#MARKED AS "...COMMENTED OUT" AND OTHERS AS "...ADDED" TO CLEARLY IDENTIFY THE MODIFICATIONS DONE.
#
#
#THIS IS VERSION 1.3 OF THE FILE. BESIDES DE CDI NEEDLE, NOW THE TO-FROM FLAG IS WORKING FOR THE RNAV
#MODES ALTHOUGH THERE ARE STILL MODIFICATIONS TO BE DONE. USE ONLY FOR TESTING FUNCTIONALITY OF THE KNS80
#WITHOUT DEPENDING ON THE GPS.
#
#IN CASE YOU WANT TO TEST IT MAKE SURE YOU BACK UP THE ORIGINAL KNS80.nas AND kns80.xml FILES SO YOU CAN
#UNDO THE CHANGES.
#
#SEPTEMBER 2018  BY JOGOIS
#
############################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>COMMENTS ABOVE ADDED
#########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

var KNS80 = {
    new : func(prop){
        var m = { parents : [KNS80]};
      m.wpt_freq=[];
      m.wpt_radial=[];
      m.wpt_distance=[];
                m.volume_adjust =0;
      m.nav_selected = "instrumentation/nav/frequencies/selected-mhz";
      m.dme_selected = "instrumentation/dme/frequencies/selected-mhz";
      m.display_num = 0;
      m.use_num = 0;
      m.flasher = 0;
      
      m.kns80 = props.globals.initNode(prop);
      m.serviceable = m.kns80.initNode("serviceable",1,"BOOL");
      m.data_mode = m.kns80.initNode("data-mode",0,"DOUBLE");
                m.nav_mode = m.kns80.initNode("nav-mode",0,"DOUBLE");
                m.dme_hold = m.kns80.initNode("dme-hold",0,"BOOL");
      m.dsp_flash = m.kns80.initNode("flash",0,"BOOL");
      m.display = m.kns80.initNode("display",0,"DOUBLE");
      m.use = m.kns80.initNode("use",0,"DOUBLE");


########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINES BELOW ADDED (V1.3)
#THE FOLLOWING TWO NEW PROPERTIES (NAMES ARE SELF-EXPLANATORY) ARE DEFINED FOR THE KNS-80 RNAV:
        m.to_flagrnav = m.kns80.initNode("to-flag-kns-80",0,"BOOL");
   m.from_flagrnav = m.kns80.initNode("from-flag-kns-80",1,"BOOL");
########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINES ABOVE ADDED (V1.3)
########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


      append(m.wpt_freq,m.kns80.initNode("wpt[0]/frequency",115.80,"DOUBLE"));
      append(m.wpt_freq,m.kns80.initNode("wpt[1]/frequency",111.70,"DOUBLE"));
      append(m.wpt_freq,m.kns80.initNode("wpt[2]/frequency",116.80,"DOUBLE"));
      append(m.wpt_freq,m.kns80.initNode("wpt[3]/frequency",113.90,"DOUBLE"));

      append(m.wpt_radial,m.kns80.initNode("wpt[0]/radial",280.0,"DOUBLE"));
      append(m.wpt_radial,m.kns80.initNode("wpt[1]/radial",280.0,"DOUBLE"));
      append(m.wpt_radial,m.kns80.initNode("wpt[2]/radial",029.0,"DOUBLE"));
      append(m.wpt_radial,m.kns80.initNode("wpt[3]/radial",029.0,"DOUBLE"));

      append(m.wpt_distance,m.kns80.initNode("wpt[0]/distance",0,"DOUBLE"));
      append(m.wpt_distance,m.kns80.initNode("wpt[1]/distance",0,"DOUBLE"));
      append(m.wpt_distance,m.kns80.initNode("wpt[2]/distance",0,"DOUBLE"));
      append(m.wpt_distance,m.kns80.initNode("wpt[3]/distance",0,"DOUBLE"));

        m.displayed_distance = m.kns80.initNode("displayed-distance",m.wpt_distance[0].getValue(),"DOUBLE");
        m.displayed_frequency = m.kns80.initNode("displayed-frequency",m.wpt_freq[0].getValue(),"DOUBLE");
        m.displayed_radial = m.kns80.initNode("displayed-radial",m.wpt_radial[0].getValue(),"DOUBLE");

      m.NAV=props.globals.initNode("instrumentation/nav");
      m.NAV1 = m.NAV.initNode("frequencies/selected-mhz");
      m.NAV1_RADIAL = m.NAV.initNode("radials/selected-deg");
      m.NAV1_ACTUAL = m.NAV.initNode("radials/actual-deg");
      m.NAV1_TO_FLAG = m.NAV.initNode("to-flag");
      m.NAV1_FROM_FLAG = m.NAV.initNode("from-flag");
      m.NAV1_HEADING_NEEDLE_DEFLECTION = m.NAV.initNode("heading-needle-deflection");
      m.NAV1_IN_RANGE = m.NAV.initNode("in-range");
      m.NAV1_distance = m.NAV.initNode("distance");

######################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
######################>>>>>>>>>>>LINE BELOW ADDED IN PREVIOUS (1 AND 1.2) VERSIONS, BUT NOT NEEDED

#        m.NAV1_RECIPROCAL = m.NAV.initNode("radials/reciprocal-radial-deg");

######################>>>>>>>>>>>LINE ABOVE ADDED IN PREVIOUS (1 AND 1.2) VERSIONS, BUT NOT NEEDED
######################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>      

        m.NAV_volume = m.NAV.initNode("volume",0.2,"DOUBLE");


########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINES BELOW COMMENTED OUT

#      m.CDI_NEEDLE = props.globals.initNode("/instrumentation/gps/cdi-deflection");
#      m.TO_FLAG    = props.globals.initNode("/instrumentation/gps/to-flag");
#      m.FROM_FLAG  = props.globals.initNode("/instrumentation/gps/from-flag");


########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINES ABOVE COMMENTED OUT
########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

      m.RNAV = m.kns80.initNode("rnav");
      m.RNAV_deflection = m.RNAV.initNode("heading-needle-deflection",0,"DOUBLE");
      m.RNAV_distance = m.RNAV.initNode("indicated-distance-nm",0,"DOUBLE");
      m.RNAV_reciprocal = m.RNAV.initNode("reciprocal-radial-deg",0,"DOUBLE");
      m.RNAV_actual_deg = m.RNAV.initNode("actual-deg",0,"DOUBLE");


      m.DME_mhz = props.globals.initNode("instrumentation/dme/frequencies/selected-mhz",0,"DOUBLE");
      m.DME_src = props.globals.initNode("instrumentation/dme/frequencies/source",m.nav_selected,"STRING");
      m.DME_dist = props.globals.initNode("instrumentation/dme/indicated-distance-nm",0,"DOUBLE");
      return m;
    },

#### volume adjust ####

volume : func(vlm){
      var vol = me.NAV_volume.getValue();
      vol += vlm;
      if(vol > 1.0)vol = 1.0;
      if(vol < 0.0){
         vol = 0.0;
         me.serviceable.setBoolValue(0);
         setprop("/instrumentation/nav/serviceable",0);
         setprop("/instrumentation/dme/serviceable",0);
      }
      if(vol > 0.0){
         me.serviceable.setBoolValue(1);
         setprop("/instrumentation/nav/serviceable",1);
         setprop("/instrumentation/dme/serviceable",1);
      }
      me.NAV_volume.setValue(vol);
    },

#### dme hold ####

DME_hold : func{
   var hold = me.dme_hold.getValue();
    hold= 1- hold;
   me.dme_hold.setValue(hold);
   if(hold==1){
        me.DME_mhz.setValue(me.NAV1.getValue());
        me.DME_src.setValue(me.dme_selected);
    }else{
        me.DME_mhz.setValue(0);
        me.DME_src.setValue(me.nav_selected);
        }
    },

#### display button ####

display_btn : func{
   me.display_num +=1;
   if(me.display_num>3)me.display_num=0;
   me.displayed_frequency.setValue(me.wpt_freq[me.display_num].getValue());
    me.displayed_distance.setValue(me.wpt_distance[me.display_num].getValue());
    me.displayed_radial.setValue(me.wpt_radial[me.display_num].getValue());
    me.data_mode.setValue(0);
    if(me.use_num == me.display_num){
        me.flasher=0;
      }else{
      me.flasher=1;
        }
   me.display.setValue(me.display_num);
    },


#### use button ####

use_btn : func{
   me.use_num = me.display_num;
    me.flasher=0;
    me.data_mode.setValue(0);
    me.use.setValue(me.use_num);
   me.NAV1.setValue(me.wpt_freq[me.display_num].getValue());
    },

#### data button ####

data_btn : func{
   var data = me.data_mode.getValue();
    data +=1;
   if(data > 2) data = 0;
    me.data_mode.setValue(data);
    },

#### data adjust ####

   data_adjust : func(dtadj){
    var dmode = me.data_mode.getValue();
    var num = dtadj;
    dtadj=0;
    if(dmode == 0){
        if(num == -1 or num ==1){num = num *0.05;}else{num = num *0.10;}
        var newfreq = me.displayed_frequency.getValue();
        newfreq += num;
        if(newfreq > 118.95){newfreq -= 11.00;}
        if(newfreq < 108.00){newfreq += 11.00;}
        me.displayed_frequency.setValue(newfreq);
      me.wpt_freq[me.display_num].setValue(newfreq);
       if(me.use_num == me.display_num)me.NAV1.setValue(newfreq);
    }elsif(dmode == 1){
        var newrad = me.displayed_radial.getValue();
        newrad += num;
        if(newrad > 359){newrad -= 360;}
        if(newrad < 0){newrad += 360;}
        me.displayed_radial.setValue(newrad);
      me.wpt_radial[me.display_num].setValue(newrad);
    }elsif(dmode == 2){
        var newdist = me.displayed_distance.getValue();
        if(num == -1 or num ==1 ){num = num *0.1;}
        newdist += num;
        if(newdist > 99){newdist -= 100;}
        if(newdist < 0){newdist += 100;}
        me.displayed_distance.setValue(newdist);
      me.wpt_distance[me.display_num].setValue(newdist);
    }
},


#### update RNAV ####

# Properties
# outputs
# distance, radial from VOR Station
# rho, theta: distance and radial for phantom station
# range, bearing: distance and radial from phantom station
#### Nav Modes  0 = VOR ; 1 = VOR/PAR ; 2 = RNAV/ENR ; 3 = RNAV/APR ;

updateRNAV : func{

   if(!me.NAV1_IN_RANGE.getValue()) {
        return;
    }
   var mode = me.nav_mode.getValue() or 0;
    var distance=me.DME_dist.getValue() or 0;
    var selected_radial = me.NAV1_RADIAL.getValue() or 0;
    var radial = me.NAV1_ACTUAL.getValue() or 0;
    var rho = me.wpt_distance[me.use_num].getValue();
    var theta = me.wpt_radial[me.use_num].getValue();
    var fangle = 0;
    var needle_deflection = 0;
    var from_flag=1;
    var to_flag  =0;

    var x1 = distance * math.cos( radial*D2R );
    var y1 = distance * math.sin( radial*D2R );
    var x2 = rho * math.cos( theta*D2R );
    var y2 = rho * math.sin( theta*D2R );

    var range = math.sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) );
    var bearing = math.atan2 (( y1-y2), (x1-x2))*R2D;

    if(bearing < 0) bearing += 360;
    var abearing = bearing > 180 ? bearing - 180 : bearing + 180;

    if( mode == 0){
        needle_deflection = (me.NAV1_HEADING_NEEDLE_DEFLECTION.getValue());
        range = distance;
    }
    if ( mode == 1){
        fangle = math.abs(selected_radial - radial);
        needle_deflection = math.sin((selected_radial - radial) * D2R) * distance * 2;
        range = distance;
    }
    if ( mode == 2){
       fangle = math.abs(selected_radial - bearing);
       needle_deflection = math.sin((selected_radial - bearing) * D2R) * range * 2;
    }

    if ( mode == 3){
        fangle = math.abs(selected_radial - bearing);
        needle_deflection = math.sin((selected_radial - bearing) * D2R) * range * 8;
    }


#####################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINES BELOW ADDED
#THE "alias" OPTION HAS BEEN USED TO PASS THE VALUES GENERATED IN KNS-80 RNAV MODES TO THE MAIN NAV
#SYSTEM. THIS WAY THE NAV GOVERNED DEVICES (HSI'S CDI NEEDLE IN THIS CASE) ARE "SLAVED" TO THE RNAV
#VALUES SO WE CAN MAKE USE OF THE CDI NEEDLE AS IN NAV MODE. WE CAN FLY THE NEEDLE TO OUR WAYPOINTS
#WITHOUT GPS WHICH IS CLOSER TO THE REAL THING. THE OPTION HAS BEEN INCLUDED INSIDE A CONDITION THAT IS
#EXECUTED ONLY IF RNAV MODES (MODES 2 and 3) ARE ACTIVE, ACCORDINGLY AN "unalias" HAS BEEN SET THAT
#IS EXECUTED OTHERWISE.



    if (( mode == 2) or (mode == 3))  {
    props.globals.getNode("/instrumentation/nav/radials/actual-deg").alias("/instrumentation/kns-80/rnav/actual-deg");
    props.globals.getNode("/instrumentation/nav/radials/reciprocal-radial-deg").alias("/instrumentation/kns-80/rnav/reciprocal-radial-deg");
    props.globals.getNode("/instrumentation/nav/heading-needle-deflection").alias("/instrumentation/kns-80/rnav/heading-needle-deflection");
#    }                                                                  --->>>  NOW USE ELSE INSTEAD OF TWO SEPARATE IF'S --V1.3
#    if (( mode == 0) or (mode == 1))  {    --->>>  NOW USE ELSE INSTEAD OF TWO SEPARATE IF'S --V1.3
    }else{
    props.globals.getNode("/instrumentation/nav/radials/actual-deg").unalias("/instrumentation/kns-80/rnav/actual-deg");
    props.globals.getNode("/instrumentation/nav/radials/reciprocal-radial-deg").unalias("/instrumentation/kns-80/rnav/reciprocal-radial-deg");
    props.globals.getNode("/instrumentation/nav/heading-needle-deflection").unalias("/instrumentation/kns-80/rnav/heading-needle-deflection");
    }


########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINES ABOVE ADDED
#########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    if ( needle_deflection >  10) needle_deflection = 10;
    if ( needle_deflection < -10) needle_deflection =-10;
    if (fangle < 90 or fangle >270){
        from_flag =1;
        to_flag  = 0;
    } else {
        from_flag=0;
        to_flag  =1;
    }

##########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
##########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINES BELLOW ADDED (V1.3)
#TO PASS THE VALUES FROM THE ABOVE EXPRESSION TO THE NEW PROPERTIES SO RNAV GETS
#THE TO-FROM FLAG VALUES THAT CAN BE PASSED TO THE MAIN NAV SYSTEM LATER ON. SEE BELLOW.
me.from_flagrnav.setValue(from_flag);
me.to_flagrnav.setValue(to_flag);

##########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINES ABOVE ADDED V1.3
#############################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


    me.RNAV_deflection.setValue(needle_deflection);

########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINES BELOW COMMENTED OUT

#    me.CDI_NEEDLE.setDoubleValue(needle_deflection);
#    me.TO_FLAG.setDoubleValue(to_flag);
#    me.FROM_FLAG.setDoubleValue(from_flag);

########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINES ABOVE COMMENTED OUT
########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


##########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
##########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINES BELLOW ADDED (V1.3)
#AGAIN, "alias" HAS BEEN USED TO PASS THE VALUES OF THE TWO NEW PROPERTIES FROM KNS-80 TO THE MAIN NAV
#SYSTEM SO THE CDI IS USABLE WITH A WORKING TO-FROM FLAG INDICATOR FOR THE RNAV MODES (2 AND 3).

    if((mode==2) or (mode==3)) {
    props.globals.getNode("/instrumentation/nav/to-flag").alias("/instrumentation/kns-80/to-flag-kns-80");
    props.globals.getNode("/instrumentation/nav/from-flag").alias("/instrumentation/kns-80/from-flag-kns-80");
    }else{
    props.globals.getNode("/instrumentation/nav/to-flag").unalias("/instrumentation/kns-80/to-flag-kns-80");
    props.globals.getNode("/instrumentation/nav/from-flag").unalias("/instrumentation/kns-80/from-flag-kns-80");
    }

##########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINES ABOVE ADDED (V1.3)
#############################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


    me.RNAV_distance.setValue(range);
    me.RNAV_reciprocal.setValue(abearing);
    me.RNAV_actual_deg.setValue(bearing);
   }

};

##################################

var kns80 = KNS80.new("instrumentation/kns-80");

setlistener("/sim/signals/fdm-initialized", func {
      update();


#####################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINE BELOW ADDED.
#SEE NOTES BELOW

        flashstatus();

########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINE ABOVE ADDED
#########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

   });

var update = func {
   kns80.updateRNAV();


##########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
##########################>>>>>>>>>>>>>>>>>>>>>>>>>>>LINES BELOW COMMENTED OUT.
#NOTE: THIS IS THE PART OF THE FUNCTION THAT CONTROLS THE DISPLAY DIGIT FLASHING STATUS:

#   var fl = kns80.dsp_flash.getValue();
   
#   if(kns80.flasher){
#      kns80.dsp_flash.setValue(1-fl);
#   }else{
#      kns80.dsp_flash.setValue(1);
#   };

##########################>>>>>>>>>>>>>>>>>>>>>>>>>>>LINES ABOVE COMMENTED OUT
##########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>NOTE:
#THE PART OF THE FUNCTION THAT CORRESPONDS TO THE FLASHING OF THE DISPLAY DIGIT
#HAS BEEN SEPARATED INTO ANOTHER FUNCTION ("flashstatus" - the chosen name is self-
#explanatory) THAT HAS BEEN INCLUDED IN THE SIGNAL ("setlistener") ABOVE TO MAKE
#IT'S REFRESHING FREQUENCY INDEPENDENT OF THE ONE AFFECTING THE FUNCTION "update".
#THE DEFINITION OF THE FUNCTION "flashstatus" AND IT'S "settimer" ARE AT THE BOTTOM
#OF THIS FILE.

#THE VALUE CHOSEN FOR THE "update" settimer MAY BE SYSTEM DEPENDANT. IN MY
#PERSONAL CASE IT IS THE VALUE THAT BEST DISPLAYS THE CDI NEEDLE IN RNAV MODES.
#ITS VALUE CORRESPONDS ROUGHLY TO 60Hz, THAT AGAIN, IN MY PERSONAL CASE IS THE
#SAME AS THE REFRESHING FREQUENCY OF MY MONITOR. START WITH THIS VALUE AND THEN
#YOU CAN MODIFY IT IF YOU DON'T GET A SMOOTH ANIMATION OF THE NEEDLE.

settimer(update,0.015);

};


#####################################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#####################################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINE BELOW ADDED
#THIS IS THE NEW FUNCTION TO CONTROL THE STATUS OF THE DISPLAY DIGIT FLASHING.

    var flashstatus = func {

########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LINE ABOVE ADDED
#########################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#NOTE: THIS IS THE PORTION OF THE ORIGINAL "update" FUNCTION THAT HAS BEEN SEPARATED.



      var fl = kns80.dsp_flash.getValue();
   
      if(kns80.flasher){
         kns80.dsp_flash.setValue(1-fl);
      }else{
         kns80.dsp_flash.setValue(1);
      };

#####################################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#####################################>>>>>>>>>>>>>>>>>>>>LINES BELOW ADDED.SEE NOTE ABOVE.

    settimer(flashstatus, 0.5);

    };

#####################################>>>>>>>>>>>>>>>>>>>>>>>>>>>LINES ABOVE ADDED
#####################################>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
jogois
 
Posts: 25
Joined: Thu Dec 25, 2008 5:41 pm
Location: Europe
OS: Ubuntu-Mate 18.04

Re: RNAV with KNS80 trouble (NOT SO - PARTIALLY SOLVED)

Postby jogois » Sat Feb 29, 2020 6:20 pm

If you have reached this thread, you definitely should check this one by WoodSTokk: Bendix/King KNS 80 (Areal Navigation) rebuild

His is a really "different approach" by using properties instead of Nasal.

jogois
jogois
 
Posts: 25
Joined: Thu Dec 25, 2008 5:41 pm
Location: Europe
OS: Ubuntu-Mate 18.04

Re: RNAV with KNS80 trouble (DONE)

Postby jogois » Sun Jul 25, 2021 12:23 pm

Hi there.

If you are reading this you probably know from my previous posts on this subject that I was modifying the KNS80.nas file included in the Patten's Aerostar 700 to make its KING'S KNS-80 work closer to the real one.

At the time I started my mod I was using Patten’s Aerostar-700-04-05_2016 version which used the KNS80.nas originally coded by Syd Adams and Ron Jensen, and the kns80.xml by Syd Adams. These are the files that as for today (I'm using FG2020.4) are also included in the fgdata/Aircraft/Instruments-3d/kns80 folder, which is the kns80 used by the original Syd Adams' Aerostar. However, now the Aerostar in Patten's hangar is the Aerostar-700-28-05_2021 (may 28, 2021) version which includes the newly coded kns80.nas by clm76 of the PAF Team. It solves some problems with the autopilot, and includes WoodSTock's KNS80 rebuild, but after having tried it I found that the RNAV modes in the new kns80 don't work properly (by the KNS80 Pilot's Guide).

The problem is that, although it apparently works since the needle points to the corresponding selected waypoint location, it makes the OBS knob unusable when the RNAV modes are selected, besides there is no change in the CDI/HSI or DME when using HOLD function while in RNAV modes which is against what we can read on the KNS80 Pilot's Guide. According to it, we can see:

a) on point 11., just under "Take of and fly to waypoint 1", it is written that "Before take off, check to be sure that RNV/ENR is still the active mode,"..."You have determined you want to fly a 112º course to the first waypoint, so you place 112º under the lubber line on your CDI (using the OBS knob on the CDI) and fly to center the needle"

b) on point 12., just under "Waypoint passage", it is written that "You are now passing over waypoint 1"..."Your flight plan calls for a course of 132º direct from waypoint 1 to Memphis, so you use your OBS knob to place 132º under the lubber line, fly to center the needle and continue your flight …",

c) when using the HOLD function while in RNAV modes or in VOR/PAR (in non ILS frequency) the CDI/HSI should be flagged, and the DME should show dashed lines (they would be unusable in that case).

So being back to FG world, I decided to finish my mod of the original KNS80.nas (again the one by Syd Adams and Ron Jensen) to make it work as per the KNS80 Pilot's Guide. Finally I have added some code to the DME_hold function so that when the HOLD button is depressed and the HLD annunciator is on, if the frequency is rechanneled to an already stored one the HLD will cancel as described in point 16. of the "Tune an ILS frequency without losing DME" section of the Pilot's guide. I've done this by placing a listener inside the (hold==1) condition of the DME_hold function so that it only triggers when selecting new frequencies that affect to the ACTIVE waypoint. The key here is “If you should mistakenly try to use the HOLD function in RNAV modes, as soon as the frequency is changed” as said in the KNS80 Pilot’s Guide, or “rechanneled” as per the MOONEY AIRCRAFT CORPORATION KNS80 RNAV SYSTEM SUPPLEMENT (I posted the links to this documents in previous posts).

Therefore, the listener has to point to "instrumentation/nav/frequencies/selected-mhz", and when using the frequency knob the listener’s function is executed only if (hold==1). The function sets the var "hold" to 0 when the "selected-mhz" from NAV (NAV1) and the DME are the same, otherwise HLD will remain ON. In other words, now, as per the Pilot's Guide, "Hold (HLD) annunciation occurs only when VOR/ILS and DME frequencies are different".

The above will happen no matter which waypoint we have in use. If we do, as in the Pilot's guide, reselect the frequency to the value we hold to retain the DME for using with a non DME ILS, the HOLD function will end and the HLD annunciator will cancel. In the same manner, if we retain a frequency in one of the four waypoints to hold DME info, and we changed from that waypoint to another of the other three to find other VOR or ILS, if we reselect the retained frequency in any of the other waypoins, as long as we make it active, the HOLD function will end -since it is common for the four channels, and the HLD annunciator will cancel as well.

To make the condition work the frequencies have to be rounded first using the sprintf() function with "%.2f" to round to the two decimal figures shown on the KNS80 display, otherwise there is no way to compare the frequencies from DME and NAV1 in a reliable way since they are floating point numbers (with up to 13 decimal figures). My first thought was to use the round() function, but from the Nasal library/math wiki it is suggested to use sprintf() instead.

Also, as per the Pilot's guide, now the HOLD function will only work if VOR or VOR/PAR (with a ILS frequency) are selected, otherwise the DME will be unusable (showing dashed lines), and the CDI (or HSI) will be flagged. Take into account that this behavior is also described in the MOONEY AIRCRAFT CORPORATION KNS80 RNAV SYSTEM SUPPLEMENT, when it is said that the VOR PAR, RNV ENR, and RNV APR are “Flagged if the VOR is rechanneled with the DME HOLD button depressed”.

However, it is NOT all true for VOR PAR mode and to correctly model it we need to recheck the KNS80 Pilot's Guide: in the MOONEY AIRCRAFT CORPORATION KNS80 RNAV SYSTEM SUPPLEMENT it is said that in VOR PAR mode the CDI will be "Flagged if the VOR is rechanneled with the DME HOLD button depressed" (point 2. of section 4.2.2.11 - COURSE DEVIATION INDICATOR), but in the Pilot's guide it is clear that this flagged situation will NOT occur if an ILS frequency is selected. I've modeled that also inside the (hold==1) condition of the DME_hold function.

I haven’t seen a KNS80 working in real life, but I assumed that if we depress the HOLD button while in RNAV modes, and by the flagged CDI, and the dashed DME we realize of our mistake and cancel the HOLD function, the CDI and the DME will be serviceable again. That’s why I placed another listener inside the “else if” pointing to “instrumentation/kns-80/dme-hold”. Without it, if we had the HLD annunciator ON in RNAV modes, and cancel it by depressing the button again, the only way to regain the CDI and DME functionality was to use the frequency knob to get out of our desired frequency and then back to it (because everything is inside the listener pointing to "instrumentation/nav/frequencies/selected-mhz"), which doesn't seem logical during flight. If anyone knows the way the KNS80 works in such a case in real life, please comment so it can be re-fixed.

I’ve been searching for videos about the KNS80 to see if it is as I assumed, but I haven’t found anything of use. Although not from a real aircraft, the only video I’ve found of some interest, because it explains the HOLD function of the KNS80, is this one:

“Distance_Measuring_Equipment_DME__Using_Frequency_Hold__Setting_Waypoints__Transponder”

At the end of this post I include the code for the modified KNS80.nas and kns80.xml files, so they can directly substitute the ones inside the kns80 folder in fgdata/Aircraft/Instruments-3d to be used by the original Syd Adams' Aerostar. A copy of the fixed kns80 folder from fgdata can also be placed, as previously, inside the Models/Instruments folder of Patten’s Aerostar-700 04-05_2016 version. However, the same procedure will not work for the new Patten's Aerostar, nor for some of the helijah’s airplanes (Ryan Navion, Velocity XL, etc for example) or the EC-145 of Melchior Franz (and others) -to mention some aircraft that I use- that still use the KNS80 slaved to the GPS. Simply placing a copy of the kns80 folder from fgdata/Aircraft/Instruments-3d/kns80 (already with my fixed KNS80.nas and kns80.xml) won’t make the KNS80 work in those aircraft. So don’t do it!

Some definitions of those aircraft would need to be recoded for them to be able to use the kns80 in fgdata as the original Syd Adams' Aerostar does.

To finish, I have to apologize for the over-commented KNS80.nas of my previous posts, but it has been really useful for me to finish the mod after all this time. The new file has been cleaned off so to check what modifications I did to the original one, please refer to my previous posts on this topic. I don't comment any of the new mods in the new KNS80.nas since I've already done here, and by comparison with the DME_hold section of the original file all are very obvious.

The code for the fixed KNS80.nas:

Code: Select all
####    King KNS-80 Integrated Navigation System   ####
####    Syd Adams    ####
####    Ron Jensen   ####
####
####    Must be included in the Set file to run the KNS80 radio
####
#### Nav Modes  0 = VOR ; 1 = VOR/PAR ; 2 = RNAV/ENR ; 3 = RNAV/APR ;
####
###############################################################
####
####    Joseba K. Gorbea-Isusi (jogois)- HOLD & GPS independent fix.
####
####    Version 1.4 July 2021
####

var KNS80 = {
    new : func(prop){
        var m = { parents : [KNS80]};
      m.wpt_freq=[];
      m.wpt_radial=[];
      m.wpt_distance=[];
      m.volume_adjust =0;
      m.nav_selected = "instrumentation/nav/frequencies/selected-mhz";
      m.dme_selected = "instrumentation/dme/frequencies/selected-mhz";
      m.display_num = 0;
      m.use_num = 0;
      m.flasher = 0;

      m.kns80 = props.globals.initNode(prop);
      m.serviceable = m.kns80.initNode("serviceable",1,"BOOL");
      m.data_mode = m.kns80.initNode("data-mode",0,"DOUBLE");
      m.nav_mode = m.kns80.initNode("nav-mode",0,"DOUBLE");
      m.dme_hold = m.kns80.initNode("dme-hold",0,"BOOL");
      m.dsp_flash = m.kns80.initNode("flash",0,"BOOL");
      m.display = m.kns80.initNode("display",0,"DOUBLE");
      m.use = m.kns80.initNode("use",0,"DOUBLE");

      m.to_flagrnav = m.kns80.initNode("to-flag-kns-80",0,"BOOL");
      m.from_flagrnav = m.kns80.initNode("from-flag-kns-80",1,"BOOL");
     

      append(m.wpt_freq,m.kns80.initNode("wpt[0]/frequency",115.80,"DOUBLE"));
      append(m.wpt_freq,m.kns80.initNode("wpt[1]/frequency",111.70,"DOUBLE"));
      append(m.wpt_freq,m.kns80.initNode("wpt[2]/frequency",116.80,"DOUBLE"));
      append(m.wpt_freq,m.kns80.initNode("wpt[3]/frequency",113.90,"DOUBLE"));

      append(m.wpt_radial,m.kns80.initNode("wpt[0]/radial",280.0,"DOUBLE"));
      append(m.wpt_radial,m.kns80.initNode("wpt[1]/radial",280.0,"DOUBLE"));
      append(m.wpt_radial,m.kns80.initNode("wpt[2]/radial",029.0,"DOUBLE"));
      append(m.wpt_radial,m.kns80.initNode("wpt[3]/radial",029.0,"DOUBLE"));

      append(m.wpt_distance,m.kns80.initNode("wpt[0]/distance",0,"DOUBLE"));
      append(m.wpt_distance,m.kns80.initNode("wpt[1]/distance",0,"DOUBLE"));
      append(m.wpt_distance,m.kns80.initNode("wpt[2]/distance",0,"DOUBLE"));
      append(m.wpt_distance,m.kns80.initNode("wpt[3]/distance",0,"DOUBLE"));

      m.displayed_distance = m.kns80.initNode("displayed-distance",m.wpt_distance[0].getValue(),"DOUBLE");
      m.displayed_frequency = m.kns80.initNode("displayed-frequency",m.wpt_freq[0].getValue(),"DOUBLE");
      m.displayed_radial = m.kns80.initNode("displayed-radial",m.wpt_radial[0].getValue(),"DOUBLE");

      m.NAV=props.globals.initNode("instrumentation/nav");
      m.NAV1 = m.NAV.initNode("frequencies/selected-mhz");
      m.NAV1_RADIAL = m.NAV.initNode("radials/selected-deg");
      m.NAV1_ACTUAL = m.NAV.initNode("radials/actual-deg");
      m.NAV1_TO_FLAG = m.NAV.initNode("to-flag");
      m.NAV1_FROM_FLAG = m.NAV.initNode("from-flag");
      m.NAV1_HEADING_NEEDLE_DEFLECTION = m.NAV.initNode("heading-needle-deflection");
      m.NAV1_IN_RANGE = m.NAV.initNode("in-range");
      m.NAV1_distance = m.NAV.initNode("distance");

      m.NAV_volume = m.NAV.initNode("volume",0.2,"DOUBLE");

      m.RNAV = m.kns80.initNode("rnav");
      m.RNAV_deflection = m.RNAV.initNode("heading-needle-deflection",0,"DOUBLE");
      m.RNAV_distance = m.RNAV.initNode("indicated-distance-nm",0,"DOUBLE");
      m.RNAV_reciprocal = m.RNAV.initNode("reciprocal-radial-deg",0,"DOUBLE");
      m.RNAV_actual_deg = m.RNAV.initNode("actual-deg",0,"DOUBLE");

      m.DME_mhz = props.globals.initNode("instrumentation/dme/frequencies/selected-mhz",0,"DOUBLE");
      m.DME_src = props.globals.initNode("instrumentation/dme/frequencies/source",m.nav_selected,"STRING");
      m.DME_dist = props.globals.initNode("instrumentation/dme/indicated-distance-nm",0,"DOUBLE");
     
     
     
      return m;
    },

#### volume adjust ####

volume : func(vlm){
      var vol = me.NAV_volume.getValue();
      vol += vlm;
      if(vol > 1.0)vol = 1.0;
      if(vol < 0.0){
         vol = 0.0;
         me.serviceable.setBoolValue(0);
         setprop("/instrumentation/nav/serviceable",0);
         setprop("/instrumentation/dme/serviceable",0);
      }
      if(vol > 0.0){
         me.serviceable.setBoolValue(1);
         setprop("/instrumentation/nav/serviceable",1);
         setprop("/instrumentation/dme/serviceable",1);
      }
      me.NAV_volume.setValue(vol);
    },

#### dme hold ####

DME_hold : func{
   var hold = me.dme_hold.getValue();
   hold= 1- hold;
   me.dme_hold.setValue(hold);
   
   
         if(hold==1){
          
            me.DME_mhz.setValue(me.NAV1.getValue());
            me.DME_src.setValue(me.dme_selected);
            setlistener("instrumentation/nav/frequencies/selected-mhz",func {
               
              if(sprintf("%.2f",me.NAV1.getValue())==sprintf("%.2f",me.DME_mhz.getValue())){
               me.dme_hold.setBoolValue(0);
               me.DME_mhz.setValue(0);
               me.DME_src.setValue(me.nav_selected);
               }
              
            var mode_for_dme_hld = getprop("instrumentation/kns-80/nav-mode");
            var VOR_has_ILS=getprop("instrumentation/nav/frequencies/is-localizer-frequency");
            
               if(me.dme_hold.getValue()==1 and !VOR_has_ILS and mode_for_dme_hld==1){   
               setprop("instrumentation/dme/serviceable","false");
               setprop("instrumentation/nav/serviceable","false");
               }else if(me.dme_hold.getValue()==1 and (mode_for_dme_hld==2 or mode_for_dme_hld==3)){
               setprop("instrumentation/dme/serviceable","false");
               setprop("instrumentation/nav/serviceable","false");       
               }else if(me.dme_hold.getValue()==0){setlistener("instrumentation/kns-80/dme-hold",func{
                  setprop("instrumentation/dme/serviceable","true");
                  setprop("instrumentation/nav/serviceable","true");
                  });
               }else{
                  setprop("instrumentation/dme/serviceable","true");
                  setprop("instrumentation/nav/serviceable","true");
               }
                     
             });
             
          }else{

            me.DME_mhz.setValue(0);
            me.DME_src.setValue(me.nav_selected);           
         }              
   },

#### display button ####

display_btn : func{

   me.display_num +=1;
   if(me.display_num>3) me.display_num=0;
   me.displayed_frequency.setValue(me.wpt_freq[me.display_num].getValue());
    me.displayed_distance.setValue(me.wpt_distance[me.display_num].getValue());
    me.displayed_radial.setValue(me.wpt_radial[me.display_num].getValue());
    me.data_mode.setValue(0);
    if(me.use_num == me.display_num){
        me.flasher=0;
      }else{
      me.flasher=1;
        }
   me.display.setValue(me.display_num);
    },


#### use button ####

use_btn : func{
   me.use_num = me.display_num;
    me.flasher=0;
    me.data_mode.setValue(0);
    me.use.setValue(me.use_num);
   me.NAV1.setValue(me.wpt_freq[me.display_num].getValue());
    },

#### data button ####

data_btn : func{
   var data = me.data_mode.getValue();
    data +=1;
   if(data > 2) data = 0;
    me.data_mode.setValue(data);
    },

#### data adjust ####

   data_adjust : func(dtadj){
    var dmode = me.data_mode.getValue();
    var num = dtadj;
    dtadj=0;
    if(dmode == 0){
        if(num == -1 or num ==1){num = num *0.05;}else{num = num *0.10;}
        var newfreq = me.displayed_frequency.getValue();
        newfreq += num;
        if(newfreq > 118.95){newfreq -= 11.00;}
        if(newfreq < 108.00){newfreq += 11.00;}
        me.displayed_frequency.setValue(newfreq);
      me.wpt_freq[me.display_num].setValue(newfreq);
       if(me.use_num == me.display_num)me.NAV1.setValue(newfreq);
    }elsif(dmode == 1){
        var newrad = me.displayed_radial.getValue();
        newrad += num;
        if(newrad > 359){newrad -= 360;}
        if(newrad < 0){newrad += 360;}
        me.displayed_radial.setValue(newrad);
      me.wpt_radial[me.display_num].setValue(newrad);
    }elsif(dmode == 2){
        var newdist = me.displayed_distance.getValue();
        if(num == -1 or num ==1 ){num = num *0.1;}
        newdist += num;
        if(newdist > 99){newdist -= 100;}
        if(newdist < 0){newdist += 100;}
        me.displayed_distance.setValue(newdist);
      me.wpt_distance[me.display_num].setValue(newdist);
    }
},


#### update RNAV ####

# Properties
# outputs
# distance, radial from VOR Station
# rho, theta: distance and radial for phantom station
# range, bearing: distance and radial from phantom station
#### Nav Modes  0 = VOR ; 1 = VOR/PAR ; 2 = RNAV/ENR ; 3 = RNAV/APR ;

updateRNAV : func{

   if(!me.NAV1_IN_RANGE.getValue()) {
        return;
    }
   var mode = me.nav_mode.getValue() or 0;
    var distance=me.DME_dist.getValue() or 0;
    var selected_radial = me.NAV1_RADIAL.getValue() or 0;
    var radial = me.NAV1_ACTUAL.getValue() or 0;
    var rho = me.wpt_distance[me.use_num].getValue();
    var theta = me.wpt_radial[me.use_num].getValue();
    var fangle = 0;
    var needle_deflection = 0;
    var from_flag=1;
    var to_flag  =0;

    var x1 = distance * math.cos( radial*D2R );
    var y1 = distance * math.sin( radial*D2R );
    var x2 = rho * math.cos( theta*D2R );
    var y2 = rho * math.sin( theta*D2R );

    var range = math.sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) );
    var bearing = math.atan2 (( y1-y2), (x1-x2))*R2D;

    if(bearing < 0) bearing += 360;
    var abearing = bearing > 180 ? bearing - 180 : bearing + 180;

    if( mode == 0){
        needle_deflection = (me.NAV1_HEADING_NEEDLE_DEFLECTION.getValue());
        range = distance;
    }
    if ( mode == 1){
        fangle = math.abs(selected_radial - radial);
        needle_deflection = math.sin((selected_radial - radial) * D2R) * distance * 2;
        range = distance;
    }
    if ( mode == 2){
       fangle = math.abs(selected_radial - bearing);
       needle_deflection = math.sin((selected_radial - bearing) * D2R) * range * 2;
    }

    if ( mode == 3){
        fangle = math.abs(selected_radial - bearing);
        needle_deflection = math.sin((selected_radial - bearing) * D2R) * range * 8;
    }

    if (( mode == 2) or (mode == 3))  {
    props.globals.getNode("/instrumentation/nav/radials/actual-deg").alias("/instrumentation/kns-80/rnav/actual-deg");
    props.globals.getNode("/instrumentation/nav/radials/reciprocal-radial-deg").alias("/instrumentation/kns-80/rnav/reciprocal-radial-deg");
    props.globals.getNode("/instrumentation/nav/heading-needle-deflection").alias("/instrumentation/kns-80/rnav/heading-needle-deflection");

    }else{
    props.globals.getNode("/instrumentation/nav/radials/actual-deg").unalias("/instrumentation/kns-80/rnav/actual-deg");
    props.globals.getNode("/instrumentation/nav/radials/reciprocal-radial-deg").unalias("/instrumentation/kns-80/rnav/reciprocal-radial-deg");
    props.globals.getNode("/instrumentation/nav/heading-needle-deflection").unalias("/instrumentation/kns-80/rnav/heading-needle-deflection");
    }

    if ( needle_deflection >  10) needle_deflection = 10;
    if ( needle_deflection < -10) needle_deflection =-10;
    if (fangle < 90 or fangle >270){
        from_flag =1;
        to_flag  = 0;
    } else {
        from_flag=0;
        to_flag  =1;
    }

   me.from_flagrnav.setValue(from_flag);
   me.to_flagrnav.setValue(to_flag);

   me.RNAV_deflection.setValue(needle_deflection);

    if((mode==2) or (mode==3)) {
    props.globals.getNode("/instrumentation/nav/to-flag").alias("/instrumentation/kns-80/to-flag-kns-80");
    props.globals.getNode("/instrumentation/nav/from-flag").alias("/instrumentation/kns-80/from-flag-kns-80");
    }else{
    props.globals.getNode("/instrumentation/nav/to-flag").unalias("/instrumentation/kns-80/to-flag-kns-80");
    props.globals.getNode("/instrumentation/nav/from-flag").unalias("/instrumentation/kns-80/from-flag-kns-80");
    }

    me.RNAV_distance.setValue(range);
    me.RNAV_reciprocal.setValue(abearing);
    me.RNAV_actual_deg.setValue(bearing);
   }

};

##################################

var kns80 = KNS80.new("instrumentation/kns-80");

setlistener("/sim/signals/fdm-initialized", func {
      update();

      flashstatus();

   });

var update = func {
   kns80.updateRNAV();


settimer(update,0.015);

};


    var flashstatus = func {

      var fl = kns80.dsp_flash.getValue();

      if(kns80.flasher){
         kns80.dsp_flash.setValue(1-fl);
      }else{
         kns80.dsp_flash.setValue(1);
      };

    settimer(flashstatus, 0.5);

    };




The code for its accompanying kns80.xml:

Code: Select all
<?xml version="1.0"?>
<!-- KNS 80
Bendix/King VOR/LOC/GS/DME/RVAV Integrated NAV System
Syd Adams

Joseba K. Gorbea-Isusi (jogois) - HOLD & GPS independent fix.

July 2021
 -->

<PropertyList>

    <path>kns80.ac</path>

    <animation>
        <type>material</type>
        <object-name>VOR.btn</object-name>
        <object-name>RNAV.btn</object-name>
        <object-name>HOLD.btn</object-name>
        <object-name>USE.btn</object-name>
        <object-name>DSP.btn</object-name>
        <object-name>DATA.btn</object-name>
        <object-name>KNS80.volume</object-name>
        <object-name>KNS80.freq</object-name>
        <object-name>KNS80.freq1</object-name>
        <emission>
        <red>0.028</red>
            <green>0.014</green>
            <blue>0.007</blue>
            <factor-prop>systems/electrical/outputs/instrument-lights</factor-prop>
        </emission>
    </animation>

    <animation>
        <name>dme-on</name>
        <object-name>nm.101</object-name>
        <object-name>nm.102</object-name>
        <object-name>nm.103</object-name>
        <object-name>kt.101</object-name>
        <object-name>kt.102</object-name>
        <object-name>kt.103</object-name>
        <object-name>min.101</object-name>
        <object-name>min.102</object-name>
    </animation>

    <animation>
        <name>illumination</name>
        <object-name>annun.nm</object-name>
        <object-name>use.digit</object-name>
    </animation>

    <animation>
        <name>frequencies</name>
        <object-name>navfreq.101</object-name>
        <object-name>navfreq.102</object-name>
        <object-name>navfreq.103</object-name>
        <object-name>navfreq.104</object-name>
        <object-name>navfreq.105</object-name>
        <object-name>freq.annun</object-name>
    </animation>

    <animation>
        <name>radials</name>
        <object-name>radial.101</object-name>
        <object-name>radial.102</object-name>
        <object-name>radial.103</object-name>
        <object-name>radial.104</object-name>
        <object-name>radial.annun</object-name>
    </animation>

    <animation>
        <name>distance</name>
        <object-name>dist.101</object-name>
        <object-name>dist.102</object-name>
        <object-name>dist.103</object-name>
        <object-name>dist.annun</object-name>
    </animation>

    <animation>
        <type>select</type>
        <object-name>illumination</object-name>
        <condition>
            <and>
                <property>instrumentation/kns-80/serviceable</property>
                <greater-than>
                    <property>systems/electrical/outputs/KNS80</property>
                    <value>1</value>
                </greater-than>
            </and>
        </condition>
    </animation>

    <animation>
        <type>select</type>
        <object-name>display.digit</object-name>
        <condition>
            <and>
                <greater-than>
                    <property>systems/electrical/outputs/KNS80</property>
                    <value>1</value>
                </greater-than>
                <property>instrumentation/kns-80/flash</property>
         </and>
        </condition>
    </animation>


    <animation>
        <type>select</type>
        <object-name>frequencies</object-name>
        <condition>
            <and>
                <property>instrumentation/kns-80/serviceable</property>
                <equals>
                    <property>instrumentation/kns-80/data-mode</property>
                    <value>0</value>
                </equals>
                <greater-than>
                    <property>systems/electrical/outputs/KNS80</property>
                    <value>1</value>
                </greater-than>
            </and>
        </condition>
    </animation>

    <animation>
        <type>select</type>
        <object-name>radials</object-name>
        <condition>
            <and>
                <property>instrumentation/kns-80/serviceable</property>
                <equals>
                    <property>instrumentation/kns-80/data-mode</property>
                    <value>1</value>
                </equals>
                <greater-than>
                    <property>systems/electrical/outputs/KNS80</property>
                    <value>1</value>
                </greater-than>
            </and>
        </condition>
    </animation>

    <animation>
        <type>select</type>
        <object-name>distance</object-name>
        <condition>
            <and>
                <property>instrumentation/kns-80/serviceable</property>
                <equals>
                    <property>instrumentation/kns-80/data-mode</property>
                    <value>2</value>
                </equals>
                <greater-than>
                    <property>systems/electrical/outputs/KNS80</property>
                    <value>1</value>
                </greater-than>
            </and>
        </condition>
    </animation>


    <animation>
        <type>select</type>
        <object-name>dme.invalid</object-name>
        <condition>
            <and>
                <property>instrumentation/kns-80/serviceable</property>
                <not>
                    <property>instrumentation/dme/in-range</property>
                </not>
                <greater-than>
                    <property>systems/electrical/outputs/KNS80</property>
                    <value>1</value>
                </greater-than>
            </and>
        </condition>
    </animation>

    <animation>
        <type>select</type>
        <object-name>dme-on</object-name>
        <condition>
            <and>
                <property>instrumentation/kns-80/serviceable</property>
                <property>instrumentation/dme/in-range</property>
                <greater-than>
                    <property>systems/electrical/outputs/KNS80</property>
                    <value>1</value>
                </greater-than>
            </and>
        </condition>
    </animation>

    <animation>
        <type>select</type>
        <object-name>vor.annun</object-name>
        <condition>
            <and>
                <property>instrumentation/kns-80/serviceable</property>
                <equals>
                    <property>instrumentation/kns-80/nav-mode</property>
                    <value>0</value>
                </equals>
                <greater-than>
                    <property>systems/electrical/outputs/KNS80</property>
                    <value>1</value>
                </greater-than>
            </and>
        </condition>
    </animation>

    <animation>
        <type>select</type>
        <object-name>par.annun</object-name>
        <condition>
            <and>
                <property>instrumentation/kns-80/serviceable</property>
                <equals>
                    <property>instrumentation/kns-80/nav-mode</property>
                    <value>1</value>
                </equals>
                <greater-than>
                    <property>systems/electrical/outputs/KNS80</property>
                    <value>1</value>
                </greater-than>
            </and>
        </condition>
    </animation>

    <animation>
        <type>select</type>
        <object-name>enr.annun</object-name>
        <condition>
            <and>
                <property>instrumentation/kns-80/serviceable</property>
                <equals>
                    <property>instrumentation/kns-80/nav-mode</property>
                    <value>2</value>
                </equals>
                <greater-than>
                    <property>systems/electrical/outputs/KNS80</property>
                    <value>1</value>
                </greater-than>
            </and>
        </condition>
    </animation>

    <animation>
        <type>select</type>
        <object-name>apr.annun</object-name>
        <condition>
            <and>
                <property>instrumentation/kns-80/serviceable</property>
                <equals>
                    <property>instrumentation/kns-80/nav-mode</property>
                    <value>3</value>
                </equals>
                <greater-than>
                    <property>systems/electrical/outputs/KNS80</property>
                    <value>1</value>
                </greater-than>
            </and>
        </condition>
    </animation>

    <animation>
        <type>select</type>
        <object-name>hld.annun</object-name>
        <condition>
            <and>
                <property>instrumentation/kns-80/serviceable</property>
                <property>instrumentation/kns-80/dme-hold</property>
                <greater-than>
                    <property>systems/electrical/outputs/KNS80</property>
                    <value>1</value>
                </greater-than>
            </and>
        </condition>
    </animation>

    <animation>
        <type>select</type>
        <object-name>ils.annun</object-name>
        <condition>
            <and>
                <property>instrumentation/kns-80/serviceable</property>
                <property>instrumentation/nav/has-gs</property>
                <property>instrumentation/nav/in-range</property>
                <greater-than>
                    <property>systems/electrical/outputs/KNS80</property>
                    <value>1</value>
                </greater-than>
            </and>
        </condition>
    </animation>

    <animation>
        <type>rotate</type>
        <object-name>KNS80.volume</object-name>
        <property>instrumentation/nav/volume</property>
        <interpolation>
            <entry><ind>0</ind><dep>0</dep></entry>
            <entry><ind>1.0</ind><dep>300</dep></entry>
        </interpolation>
        <center>
            <x-m> 0.00260 </x-m>
            <y-m> 0.04010 </y-m>
            <z-m> -0.0279 </z-m>
        </center>
        <axis>
            <x>-1</x>
            <y>0</y>
            <z>0</z>
        </axis>
    </animation>

    <animation>
        <type>translate</type>
        <object-name>KNS80.volume</object-name>
        <property>instrumentation/nav/ident</property>
        <factor>0.005</factor>
        <center>
            <x-m> 0.00260 </x-m>
            <y-m> 0.04010 </y-m>
            <z-m> -0.0279 </z-m>
        </center>
        <axis>
            <x>1</x>
            <y>0</y>
            <z>0</z>
        </axis>
    </animation>

<!--    Frequency   -->

    <animation>
        <type>textranslate</type>
        <object-name>navfreq.101</object-name>
        <property>instrumentation/kns-80/displayed-frequency</property>
        <factor>0.001</factor>
        <step>100</step>
      <bias>0.005</bias>
        <axis>
            <x>1</x>
            <y>0</y>
            <z>0</z>
        </axis>
    </animation>

    <animation>
        <type>textranslate</type>
        <object-name>navfreq.102</object-name>
        <property>instrumentation/kns-80/displayed-frequency</property>
        <factor>0.01</factor>
        <step>10</step>
      <bias>0.005</bias>
        <axis>
            <x>1</x>
            <y>0</y>
            <z>0</z>
        </axis>
    </animation>

    <animation>
        <type>textranslate</type>
        <object-name>navfreq.103</object-name>
        <property>instrumentation/kns-80/displayed-frequency</property>
        <factor>0.1</factor>
        <step>1</step>
      <bias>0.005</bias>
        <axis>
            <x>1</x>
            <y>0</y>
            <z>0</z>
        </axis>
    </animation>

    <animation>
        <type>textranslate</type>
        <object-name>navfreq.104</object-name>
        <property>instrumentation/kns-80/displayed-frequency</property>
        <factor>1.0</factor>
        <step>0.1</step>
      <bias>0.005</bias>
        <axis>
            <x>1</x>
            <y>0</y>
            <z>0</z>
        </axis>
    </animation>

    <animation>
        <type>textranslate</type>
        <object-name>navfreq.105</object-name>
        <property>instrumentation/kns-80/displayed-frequency</property>
        <factor>10.0</factor>
        <step>0.01</step>
      <bias>0.005</bias>
        <axis>
            <x>1</x>
            <y>0</y>
            <z>0</z>
        </axis>
    </animation>

<!--    Radials     -->

    <animation>
        <type>textranslate</type>
        <object-name>radial.101</object-name>
        <property>instrumentation/kns-80/displayed-radial</property>
        <factor>0.001</factor>
        <step>100</step>
        <axis>
            <x>1</x>
            <y>0</y>
            <z>0</z>
        </axis>
    </animation>

    <animation>
        <type>textranslate</type>
        <object-name>radial.102</object-name>
        <property>instrumentation/kns-80/displayed-radial</property>
        <factor>0.01</factor>
        <step>10</step>
        <axis>
            <x>1</x>
            <y>0</y>
            <z>0</z>
        </axis>
    </animation>

    <animation>
        <type>textranslate</type>
        <object-name>radial.103</object-name>
        <property>instrumentation/kns-80/displayed-radial</property>
        <factor>0.1</factor>
        <step>1</step>
        <axis>
            <x>1</x>
            <y>0</y>
            <z>0</z>
        </axis>
    </animation>

    <!--    Distance    -->

    <animation>
        <type>textranslate</type>
        <object-name>dist.101</object-name>
        <property>instrumentation/kns-80/displayed-distance</property>
        <factor>0.01</factor>
        <step>10</step>
        <bias>0.005</bias>
        <axis>
            <x>1</x>
            <y>0</y>
            <z>0</z>
        </axis>
    </animation>

    <animation>
        <type>textranslate</type>
        <object-name>dist.102</object-name>
        <property>instrumentation/kns-80/displayed-distance</property>
        <factor>0.1</factor>
        <bias>0.005</bias>
        <step>1</step>
        <axis>
            <x>1</x>
            <y>0</y>
            <z>0</z>
        </axis>
    </animation>

    <animation>
        <type>textranslate</type>
        <object-name>dist.103</object-name>
        <property>instrumentation/kns-80/displayed-distance</property>
        <factor>1.0</factor>
        <step>0.1</step>
        <bias>0.005</bias>
        <axis>
            <x>1</x>
            <y>0</y>
            <z>0</z>
        </axis>
    </animation>

<!--    DME     -->

    <animation>
        <type>textranslate</type>
        <object-name>nm.101</object-name>
        <property>instrumentation/kns-80/rnav/indicated-distance-nm</property>
        <factor>0.01</factor>
        <step>10</step>
        <bias>0.05</bias>
        <axis>
            <x>1</x>
            <y>0</y>
            <z>0</z>
        </axis>
    </animation>

    <animation>
        <type>textranslate</type>
        <object-name>nm.102</object-name>
        <property>instrumentation/kns-80/rnav/indicated-distance-nm</property>
        <factor>0.1</factor>
        <step>1</step>
        <bias>0.05</bias>
        <axis>
            <x>1</x>
            <y>0</y>
            <z>0</z>
        </axis>
    </animation>

    <animation>
        <type>textranslate</type>
        <object-name>nm.103</object-name>
        <property>instrumentation/kns-80/rnav/indicated-distance-nm</property>
        <factor>1.0</factor>
        <step>0.1</step>
        <bias>0.05</bias>
        <axis>
            <x>1</x>
            <y>0</y>
            <z>0</z>
        </axis>
    </animation>

    <animation>
        <type>textranslate</type>
        <object-name>kt.101</object-name>
        <property>instrumentation/dme/indicated-ground-speed-kt</property>
        <factor>0.001</factor>
        <step>100</step>
        <axis>
            <x>1</x>
            <y>0</y>
            <z>0</z>
        </axis>
    </animation>

    <animation>
        <type>textranslate</type>
        <object-name>kt.102</object-name>
        <property>instrumentation/dme/indicated-ground-speed-kt</property>
        <factor>0.01</factor>
        <step>10</step>
        <axis>
            <x>1</x>
            <y>0</y>
            <z>0</z>
        </axis>
    </animation>

    <animation>
        <type>textranslate</type>
        <object-name>kt.103</object-name>
        <property>instrumentation/dme/indicated-ground-speed-kt</property>
        <factor>0.1</factor>
        <step>1</step>
        <axis>
            <x>1</x>
            <y>0</y>
            <z>0</z>
        </axis>
    </animation>

    <animation>
        <type>textranslate</type>
        <object-name>min.101</object-name>
        <property>instrumentation/dme/indicated-time-min</property>
        <factor>0.01</factor>
        <step>10</step>
        <axis>
            <x>1</x>
            <y>0</y>
            <z>0</z>
        </axis>
    </animation>

    <animation>
        <type>textranslate</type>
        <object-name>min.102</object-name>
        <property>instrumentation/dme/indicated-time-min</property>
        <factor>0.1</factor>
        <step>1</step>
        <axis>
            <x>1</x>
            <y>0</y>
            <z>0</z>
        </axis>
    </animation>

<!--    USED / DISPLAYED WAYPOINTS      -->

    <animation>
        <type>textranslate</type>
        <object-name>use.digit</object-name>
        <property>instrumentation/kns-80/use</property>
        <factor>0.1</factor>
        <step>1</step>
        <axis>
            <x>1</x>
            <y>0</y>
            <z>0</z>
        </axis>
    </animation>

    <animation>
        <type>textranslate</type>
        <object-name>display.digit</object-name>
        <property>instrumentation/kns-80/display</property>
        <factor>0.1</factor>
        <step>1</step>
        <axis>
            <x>1</x>
            <y>0</y>
            <z>0</z>
        </axis>
    </animation>

<!--    OSG hotspots    -->

   <animation>
        <type>pick</type>
        <object-name>KNS80.volume</object-name>
        <action>
            <button>0</button>
            <repeatable>true</repeatable>
         <interval-sec>0.1</interval-sec>
            <binding>
            <condition>
               <not>
                  <property>devices/status/keyboard/shift</property>
               </not>
            </condition>
            <command>nasal</command>
            <script>systems.kns80.volume(0.05)</script>
         </binding>
            <binding>
            <condition>
               <property>devices/status/keyboard/shift</property>
            </condition>
            <command>property-toggle</command>
            <property>instrumentation/nav/ident</property>
         </binding>
        </action>
    </animation>

    <animation>
        <type>pick</type>
        <object-name>KNS80.volume</object-name>
        <action>
            <button>1</button>
            <repeatable>true</repeatable>
         <interval-sec>0.1</interval-sec>
            <binding>
            <command>nasal</command>
            <script>systems.kns80.volume(-0.05)</script>
        </binding>
        </action>
    </animation>

    <animation>
        <type>pick</type>
        <object-name>KNS80.volume</object-name>
        <action>
            <button>3</button>
            <binding>
            <command>nasal</command>
            <script>systems.kns80.volume(0.05)</script>
        </binding>
        </action>
         <hovered>
            <binding>
                <command>set-tooltip</command>
                <tooltip-id>KNS80-Vol</tooltip-id>
                <label>Volume: %3d%%</label>
                <property>instrumentation/nav/volume</property>
                <mapping>percent</mapping>
            </binding>
        </hovered>
    </animation>

    <animation>
        <type>pick</type>
        <object-name>KNS80.volume</object-name>
        <action>
            <button>4</button>
            <binding>
            <command>nasal</command>
            <script>systems.kns80.volume(-0.05)</script>
        </binding>
        </action>
    </animation>

    <animation>
        <type>pick</type>
        <object-name>KNS80.freq1</object-name>
        <action>
            <button>0</button>
            <repeatable>true</repeatable>
            <interval-sec>0.2</interval-sec>
            <binding>
            <command>nasal</command>
            <script>systems.kns80.data_adjust(1)</script>
            </binding>
        </action>
    </animation>

    <animation>
        <type>pick</type>
        <object-name>KNS80.freq1</object-name>
        <action>
            <button>1</button>
            <repeatable>true</repeatable>
            <interval-sec>0.2</interval-sec>
            <binding>
            <command>nasal</command>
            <script>systems.kns80.data_adjust(-1)</script>
            </binding>
        </action>
    </animation>

    <animation>
        <type>pick</type>
        <object-name>KNS80.freq1</object-name>
        <action>
            <button>3</button>
            <binding>
            <command>nasal</command>
            <script>systems.kns80.data_adjust(1)</script>
            </binding>
        </action>
    </animation>

    <animation>
        <type>pick</type>
        <object-name>KNS80.freq1</object-name>
        <action>
            <button>4</button>
            <binding>
            <command>nasal</command>
            <script>systems.kns80.data_adjust(-1)</script>
            </binding>
        </action>
    </animation>

    <animation>
        <type>pick</type>
        <object-name>KNS80.freq</object-name>
        <action>
            <button>0</button>
            <repeatable>true</repeatable>
            <interval-sec>0.2</interval-sec>
            <binding>
            <command>nasal</command>
            <script>systems.kns80.data_adjust(10)</script>
            </binding>
        </action>
    </animation>

    <animation>
        <type>pick</type>
        <object-name>KNS80.freq</object-name>
        <action>
            <button>1</button>
            <repeatable>true</repeatable>
            <interval-sec>0.2</interval-sec>
            <binding>
            <command>nasal</command>
            <script>systems.kns80.data_adjust(-10)</script>
            </binding>
        </action>
    </animation>

    <animation>
        <type>pick</type>
        <object-name>KNS80.freq</object-name>
        <action>
            <button>3</button>
            <binding>
            <command>nasal</command>
            <script>systems.kns80.data_adjust(10)</script>
            </binding>
        </action>
    </animation>

    <animation>
        <type>pick</type>
        <object-name>KNS80.freq</object-name>
        <action>
            <button>4</button>
            <binding>
            <command>nasal</command>
            <script>systems.kns80.data_adjust(-10)</script>
            </binding>
        </action>
    </animation>

    <animation>
        <type>pick</type>
        <object-name>HOLD.btn</object-name>
        <action>
            <button>0</button>
            <repeatable>false</repeatable>
            <binding>
            <command>nasal</command>
            <script>systems.kns80.DME_hold();</script>
            </binding>
        </action>
    </animation>

    <animation>
        <type>pick</type>
        <object-name>USE.btn</object-name>
        <action>
            <button>0</button>
            <binding>
            <command>nasal</command>
            <script>systems.kns80.use_btn();</script>
         </binding>
        </action>
    </animation>

    <animation>
        <type>pick</type>
        <object-name>DSP.btn</object-name>
        <action>
            <button>0</button>
            <binding>
            <command>nasal</command>
            <script>systems.kns80.display_btn();</script>
         </binding>
        </action>
    </animation>

    <animation>
        <type>pick</type>
        <object-name>DATA.btn</object-name>
        <action>
            <button>0</button>
            <binding>
            <command>nasal</command>
            <script>systems.kns80.data_btn()</script>
            </binding>
        </action>
    </animation>

    <animation>
        <type>pick</type>
        <object-name>VOR.btn</object-name>
        <action>
            <button>0</button>
            <repeatable>false</repeatable>
            <binding>
                <command>nasal</command>
                <script>
                var test = getprop("/instrumentation/kns-80/nav-mode");
                if(test != 0){
                    setprop("/instrumentation/kns-80/nav-mode",0);
                    setprop("/instrumentation/nav/slaved-to-gps", 0);
                }else{
                    setprop("/instrumentation/kns-80/nav-mode",1);
                    setprop("/instrumentation/nav/slaved-to-gps", 0);
                }
                </script>
            </binding>
        </action>
    </animation>

    <animation>
        <type>pick</type>
        <object-name>RNAV.btn</object-name>
        <action>
            <button>0</button>
            <repeatable>false</repeatable>
            <binding>
                <command>nasal</command>
                <script>
                var test = getprop("/instrumentation/kns-80/nav-mode");
                if(test != 2){
                    setprop("/instrumentation/kns-80/nav-mode",2);
                }else{
                    setprop("/instrumentation/kns-80/nav-mode",3);
                    setprop("/instrumentation/nav/slaved-to-gps", 0);
                }
                </script>
            </binding>
        </action>
    </animation>

</PropertyList>


Done.

jogois.
jogois
 
Posts: 25
Joined: Thu Dec 25, 2008 5:41 pm
Location: Europe
OS: Ubuntu-Mate 18.04

Previous

Return to Flying

Who is online

Users browsing this forum: No registered users and 4 guests