KNS80.nas 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. #### King KNS-80 Integrated Navigation System ####
  2. #### Syd Adams ####
  3. #### Ron Jensen ####
  4. ####
  5. #### Must be included in the Set file to run the KNS80 radio
  6. ####
  7. #### Nav Modes 0 = VOR ; 1 = VOR/PAR ; 2 = RNAV/ENR ; 3 = RNAV/APR ;
  8. ####
  9. var KNS80 = {
  10. new : func(prop){
  11. var m = { parents : [KNS80]};
  12. m.wpt_freq=[];
  13. m.wpt_radial=[];
  14. m.wpt_distance=[];
  15. m.volume_adjust =0;
  16. m.nav_selected = "instrumentation/nav/frequencies/selected-mhz";
  17. m.dme_selected = "instrumentation/dme/frequencies/selected-mhz";
  18. m.display_num = 0;
  19. m.use_num = 0;
  20. m.flasher = 0;
  21. m.kns80 = props.globals.initNode(prop);
  22. m.serviceable = m.kns80.initNode("serviceable",1,"BOOL");
  23. m.data_mode = m.kns80.initNode("data-mode",0,"DOUBLE");
  24. m.nav_mode = m.kns80.initNode("nav-mode",0,"DOUBLE");
  25. m.dme_hold = m.kns80.initNode("dme-hold",0,"BOOL");
  26. m.dsp_flash = m.kns80.initNode("flash",0,"BOOL");
  27. m.display = m.kns80.initNode("display",0,"DOUBLE");
  28. m.use = m.kns80.initNode("use",0,"DOUBLE");
  29. append(m.wpt_freq,m.kns80.initNode("wpt[0]/frequency",115.80,"DOUBLE"));
  30. append(m.wpt_freq,m.kns80.initNode("wpt[1]/frequency",111.70,"DOUBLE"));
  31. append(m.wpt_freq,m.kns80.initNode("wpt[2]/frequency",116.80,"DOUBLE"));
  32. append(m.wpt_freq,m.kns80.initNode("wpt[3]/frequency",113.90,"DOUBLE"));
  33. append(m.wpt_radial,m.kns80.initNode("wpt[0]/radial",280.0,"DOUBLE"));
  34. append(m.wpt_radial,m.kns80.initNode("wpt[1]/radial",280.0,"DOUBLE"));
  35. append(m.wpt_radial,m.kns80.initNode("wpt[2]/radial",029.0,"DOUBLE"));
  36. append(m.wpt_radial,m.kns80.initNode("wpt[3]/radial",029.0,"DOUBLE"));
  37. append(m.wpt_distance,m.kns80.initNode("wpt[0]/distance",0,"DOUBLE"));
  38. append(m.wpt_distance,m.kns80.initNode("wpt[1]/distance",0,"DOUBLE"));
  39. append(m.wpt_distance,m.kns80.initNode("wpt[2]/distance",0,"DOUBLE"));
  40. append(m.wpt_distance,m.kns80.initNode("wpt[3]/distance",0,"DOUBLE"));
  41. m.displayed_distance = m.kns80.initNode("displayed-distance",m.wpt_distance[0].getValue(),"DOUBLE");
  42. m.displayed_frequency = m.kns80.initNode("displayed-frequency",m.wpt_freq[0].getValue(),"DOUBLE");
  43. m.displayed_radial = m.kns80.initNode("displayed-radial",m.wpt_radial[0].getValue(),"DOUBLE");
  44. m.NAV=props.globals.initNode("instrumentation/nav");
  45. m.NAV1 = m.NAV.initNode("frequencies/selected-mhz");
  46. m.NAV1_RADIAL = m.NAV.initNode("radials/selected-deg");
  47. m.NAV1_ACTUAL = m.NAV.initNode("radials/actual-deg");
  48. m.NAV1_TO_FLAG = m.NAV.initNode("to-flag");
  49. m.NAV1_FROM_FLAG = m.NAV.initNode("from-flag");
  50. m.NAV1_HEADING_NEEDLE_DEFLECTION = m.NAV.initNode("heading-needle-deflection");
  51. m.NAV1_IN_RANGE = m.NAV.initNode("in-range");
  52. m.NAV1_distance = m.NAV.initNode("distance");
  53. m.NAV_volume = m.NAV.initNode("volume",0.2,"DOUBLE");
  54. m.CDI_NEEDLE = props.globals.initNode("/instrumentation/gps/cdi-deflection");
  55. m.TO_FLAG = props.globals.initNode("/instrumentation/gps/to-flag");
  56. m.FROM_FLAG = props.globals.initNode("/instrumentation/gps/from-flag");
  57. m.RNAV = m.kns80.initNode("rnav");
  58. m.RNAV_deflection = m.RNAV.initNode("heading-needle-deflection",0,"DOUBLE");
  59. m.RNAV_distance = m.RNAV.initNode("indicated-distance-nm",0,"DOUBLE");
  60. m.RNAV_reciprocal = m.RNAV.initNode("reciprocal-radial-deg",0,"DOUBLE");
  61. m.RNAV_actual_deg = m.RNAV.initNode("actual-deg",0,"DOUBLE");
  62. m.DME_mhz = props.globals.initNode("instrumentation/dme/frequencies/selected-mhz",0,"DOUBLE");
  63. m.DME_src = props.globals.initNode("instrumentation/dme/frequencies/source",m.nav_selected,"STRING");
  64. m.DME_dist = props.globals.initNode("instrumentation/dme/indicated-distance-nm",0,"DOUBLE");
  65. return m;
  66. },
  67. #### volume adjust ####
  68. volume : func(vlm){
  69. var vol = me.NAV_volume.getValue();
  70. vol += vlm;
  71. if(vol > 1.0)vol = 1.0;
  72. if(vol < 0.0){
  73. vol = 0.0;
  74. me.serviceable.setBoolValue(0);
  75. setprop("/instrumentation/nav/serviceable",0);
  76. setprop("/instrumentation/dme/serviceable",0);
  77. }
  78. if(vol > 0.0){
  79. me.serviceable.setBoolValue(1);
  80. setprop("/instrumentation/nav/serviceable",1);
  81. setprop("/instrumentation/dme/serviceable",1);
  82. }
  83. me.NAV_volume.setValue(vol);
  84. },
  85. #### dme hold ####
  86. DME_hold : func{
  87. var hold = me.dme_hold.getValue();
  88. hold= 1- hold;
  89. me.dme_hold.setValue(hold);
  90. if(hold==1){
  91. me.DME_mhz.setValue(me.NAV1.getValue());
  92. me.DME_src.setValue(me.dme_selected);
  93. }else{
  94. me.DME_mhz.setValue(0);
  95. me.DME_src.setValue(me.nav_selected);
  96. }
  97. },
  98. #### display button ####
  99. display_btn : func{
  100. me.display_num +=1;
  101. if(me.display_num>3)me.display_num=0;
  102. me.displayed_frequency.setValue(me.wpt_freq[me.display_num].getValue());
  103. me.displayed_distance.setValue(me.wpt_distance[me.display_num].getValue());
  104. me.displayed_radial.setValue(me.wpt_radial[me.display_num].getValue());
  105. me.data_mode.setValue(0);
  106. if(me.use_num == me.display_num){
  107. me.flasher=0;
  108. }else{
  109. me.flasher=1;
  110. }
  111. me.display.setValue(me.display_num);
  112. },
  113. #### use button ####
  114. use_btn : func{
  115. me.use_num = me.display_num;
  116. me.flasher=0;
  117. me.data_mode.setValue(0);
  118. me.use.setValue(me.use_num);
  119. me.NAV1.setValue(me.wpt_freq[me.display_num].getValue());
  120. },
  121. #### data button ####
  122. data_btn : func{
  123. var data = me.data_mode.getValue();
  124. data +=1;
  125. if(data > 2) data = 0;
  126. me.data_mode.setValue(data);
  127. },
  128. #### data adjust ####
  129. data_adjust : func(dtadj){
  130. var dmode = me.data_mode.getValue();
  131. var num = dtadj;
  132. dtadj=0;
  133. if(dmode == 0){
  134. if(num == -1 or num ==1){num = num *0.05;}else{num = num *0.10;}
  135. var newfreq = me.displayed_frequency.getValue();
  136. newfreq += num;
  137. if(newfreq > 118.95){newfreq -= 11.00;}
  138. if(newfreq < 108.00){newfreq += 11.00;}
  139. me.displayed_frequency.setValue(newfreq);
  140. me.wpt_freq[me.display_num].setValue(newfreq);
  141. if(me.use_num == me.display_num)me.NAV1.setValue(newfreq);
  142. }elsif(dmode == 1){
  143. var newrad = me.displayed_radial.getValue();
  144. newrad += num;
  145. if(newrad > 359){newrad -= 360;}
  146. if(newrad < 0){newrad += 360;}
  147. me.displayed_radial.setValue(newrad);
  148. me.wpt_radial[me.display_num].setValue(newrad);
  149. }elsif(dmode == 2){
  150. var newdist = me.displayed_distance.getValue();
  151. if(num == -1 or num ==1 ){num = num *0.1;}
  152. newdist += num;
  153. if(newdist > 99){newdist -= 100;}
  154. if(newdist < 0){newdist += 100;}
  155. me.displayed_distance.setValue(newdist);
  156. me.wpt_distance[me.display_num].setValue(newdist);
  157. }
  158. },
  159. #### update RNAV ####
  160. # Properties
  161. # outputs
  162. # distance, radial from VOR Station
  163. # rho, theta: distance and radial for phantom station
  164. # range, bearing: distance and radial from phantom station
  165. #### Nav Modes 0 = VOR ; 1 = VOR/PAR ; 2 = RNAV/ENR ; 3 = RNAV/APR ;
  166. updateRNAV : func{
  167. if(!me.NAV1_IN_RANGE.getValue()) {
  168. return;
  169. }
  170. var mode = me.nav_mode.getValue() or 0;
  171. var distance=me.DME_dist.getValue() or 0;
  172. var selected_radial = me.NAV1_RADIAL.getValue() or 0;
  173. var radial = me.NAV1_ACTUAL.getValue() or 0;
  174. var rho = me.wpt_distance[me.use_num].getValue();
  175. var theta = me.wpt_radial[me.use_num].getValue();
  176. var fangle = 0;
  177. var needle_deflection = 0;
  178. var from_flag=1;
  179. var to_flag =0;
  180. var x1 = distance * math.cos( radial*D2R );
  181. var y1 = distance * math.sin( radial*D2R );
  182. var x2 = rho * math.cos( theta*D2R );
  183. var y2 = rho * math.sin( theta*D2R );
  184. var range = math.sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) );
  185. var bearing = math.atan2 (( y1-y2), (x1-x2))*R2D;
  186. if(bearing < 0) bearing += 360;
  187. var abearing = bearing > 180 ? bearing - 180 : bearing + 180;
  188. if( mode == 0){
  189. needle_deflection = (me.NAV1_HEADING_NEEDLE_DEFLECTION.getValue());
  190. range = distance;
  191. }
  192. if ( mode == 1){
  193. fangle = math.abs(selected_radial - radial);
  194. needle_deflection = math.sin((selected_radial - radial) * D2R) * distance * 2;
  195. }
  196. if ( mode == 2){
  197. fangle = math.abs(selected_radial - bearing);
  198. needle_deflection = math.sin((selected_radial - bearing) * D2R) * range * 2;
  199. }
  200. if ( mode == 3){
  201. fangle = math.abs(selected_radial - bearing);
  202. needle_deflection = math.sin((selected_radial - bearing) * D2R) * range * 8;
  203. }
  204. if ( needle_deflection > 10) needle_deflection = 10;
  205. if ( needle_deflection < -10) needle_deflection =-10;
  206. if (fangle < 90 or fangle >270){
  207. from_flag=1;
  208. to_flag =0;
  209. } else {
  210. from_flag=0;
  211. to_flag =1;
  212. }
  213. me.RNAV_deflection.setValue(needle_deflection);
  214. me.CDI_NEEDLE.setDoubleValue(needle_deflection);
  215. me.TO_FLAG.setDoubleValue(to_flag);
  216. me.FROM_FLAG.setDoubleValue(from_flag);
  217. me.RNAV_distance.setValue(range);
  218. me.RNAV_reciprocal.setValue(abearing);
  219. me.RNAV_actual_deg.setValue(bearing);
  220. }
  221. };
  222. ###########################################
  223. var kns80 = KNS80.new("instrumentation/kns-80");
  224. setlistener("/sim/signals/fdm-initialized", func {
  225. update();
  226. });
  227. var update = func {
  228. kns80.updateRNAV();
  229. var fl = kns80.dsp_flash.getValue();
  230. if(kns80.flasher){
  231. kns80.dsp_flash.setValue(1-fl);
  232. }else{
  233. kns80.dsp_flash.setValue(1);
  234. };
  235. settimer(update,0.5);
  236. };