777:T/D property name change
[fg:toms-fgdata.git] / Aircraft / 777 / Nasal / AFDS.nas
1 #############################################################################
2 # 777 Autopilot Flight Director System
3 # Syd Adams
4 #
5 # speed modes: THR,THR REF, IDLE,HOLD,SPD;
6 # roll modes : TO/GA,HDG SEL,HDG HOLD, LNAV,LOC,ROLLOUT,TRK SEL, TRK HOLD,ATT;
7 # pitch modes: TO/GA,ALT,V/S,VNAV PTH,VNAV SPD,VNAV ALT,G/S,FLARE,FLCH SPD,FPA;
8 # FPA range  : -9.9 ~ 9.9 degrees
9 # VS range   : -8000 ~ 6000
10 # ALT range  : 0 ~ 50,000
11 # KIAS range : 100 ~ 399
12 # MACH range : 0.40 ~ 0.95
13 #
14 #############################################################################
15
16 #Usage : var afds = AFDS.new();
17
18 var copilot = func(msg) { setprop("sim/messages/copilot",msg);}
19
20 var AFDS = {
21         new : func{
22                 var m = {parents:[AFDS]};
23
24                 m.spd_list=["","THR","THR REF","HOLD","IDLE","SPD"];
25
26                 m.roll_list=["","HDG SEL","HDG HOLD","LNAV","LOC","ROLLOUT",
27                 "TRK SEL","TRK HOLD","ATT","TO/GA"];
28
29                 m.pitch_list=["","ALT","V/S","VNAV PTH","VNAV SPD",
30                 "VNAV ALT","G/S","FLARE","FLCH SPD","FPA","TO/GA"];
31
32                 m.step=0;
33                 m.descent_step=0;
34                 m.heading_change_rate = 0;
35                 m.optimal_alt = 0;
36                 m.intervention_alt = 0;
37                 m.altitude_restriction = -9999.99;
38                 m.altitude_alert_from_out = 0;
39                 m.altitude_alert_from_in = 0;
40                 m.top_of_descent = 0;
41                 m.vorient = 0;
42
43                 m.heading_reference=props.globals.initNode("systems/navigation/hdgref/reference",0,"BOOL");
44                 m.crab_angle=props.globals.initNode("orientation/crab-angle", 0, "DOUBLE");
45                 m.crab_angle_total=props.globals.initNode("orientation/crab-angle-total", 0, "DOUBLE");
46                 m.rwy_align_limit=props.globals.initNode("orientation/rwy-align-limit", 0, "DOUBLE");
47                 m.AFDS_node = props.globals.getNode("instrumentation/afds",1);
48                 m.AFDS_inputs = m.AFDS_node.getNode("inputs",1);
49                 m.AFDS_apmodes = m.AFDS_node.getNode("ap-modes",1);
50                 m.AFDS_settings = m.AFDS_node.getNode("settings",1);
51                 m.AP_settings = props.globals.getNode("autopilot/settings",1);
52
53                 m.AP = m.AFDS_inputs.initNode("AP",0,"BOOL");
54                 m.AP_disengaged = m.AFDS_inputs.initNode("AP-disengage",0,"BOOL");
55                 m.AP_passive = props.globals.initNode("autopilot/locks/passive-mode",1,"BOOL");
56                 m.AP_pitch_engaged = props.globals.initNode("autopilot/locks/pitch-engaged",1,"BOOL");
57                 m.AP_roll_engaged = props.globals.initNode("autopilot/locks/roll-engaged",1,"BOOL");
58
59                 m.FMC = props.globals.getNode("autopilot/route-manager", 1);
60                 m.FMC_cruise_alt = m.FMC.initNode("cruise/altitude-ft",10000,"DOUBLE");
61                 m.FMC_cruise_ias = m.FMC.initNode("cruise/speed-kts",320,"DOUBLE");
62                 m.FMC_cruise_mach = m.FMC.initNode("cruise/speed-mach",0.840,"DOUBLE");
63                 m.FMC_descent_ias = m.FMC.initNode("descent/speed-kts",280,"DOUBLE");
64                 m.FMC_descent_mach = m.FMC.initNode("descent/speed-mach",0.780,"DOUBLE");
65                 m.FMC_active = m.FMC.initNode("active",0,"BOOL");
66                 m.FMC_current_wp = m.FMC.initNode("current-wp",0,"INT");
67                 m.FMC_destination_ils = m.FMC.initNode("destination-ils",0,"BOOL");
68                 m.FMC_landing_rwy_elevation = m.FMC.initNode("landing-rwy-elevation",0,"DOUBLE");
69
70                 m.FD = m.AFDS_inputs.initNode("FD",0,"BOOL");
71                 m.at1 = m.AFDS_inputs.initNode("at-armed[0]",0,"BOOL");
72                 m.at2 = m.AFDS_inputs.initNode("at-armed[1]",0,"BOOL");
73                 m.alt_knob = m.AFDS_inputs.initNode("alt-knob",0,"BOOL");
74                 m.autothrottle_mode = m.AFDS_inputs.initNode("autothrottle-index",0,"INT");
75                 m.lateral_mode = m.AFDS_inputs.initNode("lateral-index",0,"INT");
76                 m.vertical_mode = m.AFDS_inputs.initNode("vertical-index",0,"INT");
77                 m.gs_armed = m.AFDS_inputs.initNode("gs-armed",0,"BOOL");
78                 m.loc_armed = m.AFDS_inputs.initNode("loc-armed",0,"BOOL");
79                 m.vor_armed = m.AFDS_inputs.initNode("vor-armed",0,"BOOL");
80                 m.lnav_armed = m.AFDS_inputs.initNode("lnav-armed",0,"BOOL");
81                 m.vnav_armed = m.AFDS_inputs.initNode("vnav-armed",0,"BOOL");
82                 m.rollout_armed = m.AFDS_inputs.initNode("rollout-armed",0,"BOOL");
83                 m.flare_armed = m.AFDS_inputs.initNode("flare-armed",0,"BOOL");
84                 m.ias_mach_selected = m.AFDS_inputs.initNode("ias-mach-selected",0,"BOOL");
85                 m.hdg_trk_selected = m.AFDS_inputs.initNode("hdg-trk-selected",0,"BOOL");
86                 m.vs_fpa_selected = m.AFDS_inputs.initNode("vs-fpa-selected",0,"BOOL");
87                 m.bank_switch = m.AFDS_inputs.initNode("bank-limit-switch",0,"INT");
88                 m.vnav_path_mode = m.AFDS_inputs.initNode("vnav-path-mode",0,"INT");
89                 m.vnav_mcp_reset = m.AFDS_inputs.initNode("vnav-mcp-reset",0,"BOOL");
90                 m.vnav_descent = m.AFDS_inputs.initNode("vnav-descent",0,"BOOL");
91                 m.climb_continuous = m.AFDS_inputs.initNode("climb-continuous",0,"BOOL");
92                 m.indicated_vs_fpm = m.AFDS_inputs.initNode("indicated-vs-fpm",0,"DOUBLE");
93                 m.estimated_time_arrival = m.AFDS_inputs.initNode("estimated-time-arrival",0,"INT");
94                 m.remaining_distance = m.AFDS_inputs.initNode("remaining-distance",0,"DOUBLE");
95                 m.reference_deg = m.AFDS_inputs.initNode("reference-deg",0,"DOUBLE");
96
97                 m.ias_setting = m.AP_settings.initNode("target-speed-kt",200);# 100 - 399 #
98                 m.mach_setting = m.AP_settings.initNode("target-speed-mach",0.40);# 0.40 - 0.95 #
99                 m.vs_setting = m.AP_settings.initNode("vertical-speed-fpm",0); # -8000 to +6000 #
100                 m.hdg_setting = m.AP_settings.initNode("heading-bug-deg",360,"INT"); # 1 to 360
101                 m.hdg_setting_last = m.AP_settings.initNode("heading-bug-last",360,"INT"); # 1 to 360
102                 m.hdg_setting_active = m.AP_settings.initNode("heading-bug-active",0,"BOOL");
103                 m.fpa_setting = m.AP_settings.initNode("flight-path-angle",0); # -9.9 to 9.9 #
104                 m.alt_setting = m.AP_settings.initNode("counter-set-altitude-ft",10000,"DOUBLE");
105                 m.alt_setting_FL = m.AP_settings.initNode("counter-set-altitude-FL",10,"INT");
106                 m.alt_setting_100 = m.AP_settings.initNode("counter-set-altitude-100",000,"INT");
107                 m.target_alt = m.AP_settings.initNode("actual-target-altitude-ft",10000,"DOUBLE");
108                 m.radio_alt_ind = m.AP_settings.initNode("radio-altimeter-indication",000,"INT");
109                 m.pfd_mach_ind = m.AP_settings.initNode("pfd-mach-indication",000,"INT");
110                 m.pfd_mach_target = m.AP_settings.initNode("pfd-mach-target-indication",000,"INT");
111                 m.auto_brake_setting = m.AP_settings.initNode("autobrake",0.000,"DOUBLE");
112                 m.flare_constant_setting = m.AP_settings.initNode("flare-constant",0.000,"DOUBLE");
113                 m.thrust_lmt = m.AP_settings.initNode("thrust-lmt",1,"DOUBLE");
114                 m.flight_idle = m.AP_settings.initNode("flight-idle",0,"DOUBLE");
115
116                 m.vs_display = m.AFDS_settings.initNode("vs-display",0);
117                 m.fpa_display = m.AFDS_settings.initNode("fpa-display",0);
118                 m.bank_min = m.AFDS_settings.initNode("bank-min",-25);
119                 m.bank_max = m.AFDS_settings.initNode("bank-max",25);
120                 m.pitch_min = m.AFDS_settings.initNode("pitch-min",-10);
121                 m.pitch_max = m.AFDS_settings.initNode("pitch-max",15);
122                 m.auto_popup = m.AFDS_settings.initNode("auto-pop-up",0,"BOOL");
123                 m.heading = m.AFDS_settings.initNode("heading",360,"INT");
124                 m.manual_intervention = m.AFDS_settings.initNode("manual-intervention",0,"BOOL");
125
126                 m.AP_roll_mode = m.AFDS_apmodes.initNode("roll-mode","TO/GA");
127                 m.AP_roll_arm = m.AFDS_apmodes.initNode("roll-mode-arm"," ");
128                 m.AP_pitch_mode = m.AFDS_apmodes.initNode("pitch-mode","TO/GA");
129                 m.AP_pitch_arm = m.AFDS_apmodes.initNode("pitch-mode-arm"," ");
130                 m.AP_speed_mode = m.AFDS_apmodes.initNode("speed-mode","");
131                 m.AP_annun = m.AFDS_apmodes.initNode("mode-annunciator"," ");
132
133                 m.APl = setlistener(m.AP, func m.setAP(),0,0);
134                 m.APdisl = setlistener(m.AP_disengaged, func m.setAP(),0,0);
135                 m.Lbank = setlistener(m.bank_switch, func m.setbank(),0,0);
136                 m.LTMode = setlistener(m.autothrottle_mode, func m.updateATMode(),0,0);
137                 m.WpChanged = setlistener(m.FMC.getNode("wp/id",1), func m.wpChanged(),0,0);
138                 m.RmDisabled = setlistener(m.FMC.getNode("active",1), func m.wpChanged(),0,0);
139         
140         
141         m.NDSymbols = props.globals.getNode("autopilot/route-manager/vnav", 1);
142                 setprop("autopilot/internal/waypoint-bearing-error-deg", 0);
143                 return m;
144         },
145
146 ####  Inputs   ####
147 ###################
148         input : func(mode,btn)
149         {
150                 if(getprop("systems/electrical/outputs/avionics"))
151                 {
152                         var current_alt = getprop("instrumentation/altimeter/indicated-altitude-ft");
153                         if(mode==0)
154                         {
155                                 # horizontal AP controls
156                                 if(btn == 1)            # Heading Sel button
157                                 {
158                                         if(getprop("position/gear-agl-ft") < 50)
159                                         {
160                                                 btn = me.lateral_mode.getValue();
161                                         }
162                                 }
163                                 elsif(btn == 2)         # Heading Hold button
164                                 {
165                                         # set target to current heading
166                                         var tgtHdg = me.heading.getValue();
167                                         me.hdg_setting.setValue(tgtHdg);
168                                         if(getprop("position/gear-agl-ft") < 50)
169                                         {
170                                                 btn = me.lateral_mode.getValue();
171                                         }
172                                         else
173                                         {
174                                                 if(me.hdg_trk_selected.getValue())
175                                                 {
176                                                         btn = 6;    # TRK SEL
177                                                 }
178                                                 else
179                                                 {
180                                                         btn = 1;    # HDG SEL
181                                                 }
182                                         }
183                                 }
184                                 elsif(btn==3)           # LNAV button
185                                 {
186                                         if(!me.FMC_active.getValue() or
187                                                 me.FMC_current_wp.getValue()<0 or
188                                                 (getprop("autopilot/route-manager/wp/id")==""))
189                                         {
190                                                 # Oops, route manager isn't active. Keep current mode.
191                                                 btn = me.lateral_mode.getValue();
192                                                 copilot("Captain, LNAV doesn't engage. We forgot to program or activate the route manager!");
193                                         }
194                                         else
195                                         {
196                                                 if(me.lateral_mode.getValue() == 3)             # Current mode is LNAV
197                                                 {
198                                                         # set target to current heading
199                                                         var tgtHdg = me.heading.getValue();
200                                                         me.hdg_setting.setValue(tgtHdg);
201                                                         btn = 1;        # Heading sel
202                                                 }
203                                                 elsif(me.lnav_armed.getValue())
204                                                 {       # LNAV armed then disarm
205                                                         me.lnav_armed.setValue(0);
206                                                         btn = me.lateral_mode.getValue();
207                                                 }
208                                                 else
209                                                 {       # LNAV arm
210                                                         me.lnav_armed.setValue(1);
211                                                         btn = me.lateral_mode.getValue();
212                                                 }
213                                         }
214                                 }
215                                 me.lateral_mode.setValue(btn);
216                         }
217                         elsif(mode==1)
218                         {
219                                 # vertical AP controls
220                                 if (btn==1)
221                                 {
222                                         # hold current altitude
223                                         if(me.AP.getValue() or me.FD.getValue())
224                                         {
225                                                 var alt = int((current_alt+50)/100)*100;
226                                                 me.target_alt.setValue(alt);
227                                                 me.autothrottle_mode.setValue(5);       # A/T SPD
228                                         }
229                                         else
230                                         {
231                                                 btn = 0;
232                                         }
233                                 }
234                                 if(btn==2)
235                                 {
236                                         # hold current vertical speed
237                                         var vs = getprop("instrumentation/inst-vertical-speed-indicator/indicated-speed-fpm");
238                                         vs = int(vs/100)*100;
239                                         if (vs<-8000) vs = -8000;
240                                         if (vs>6000) vs = 6000;
241                                         me.vs_setting.setValue(vs);
242                                         if(vs == 0)
243                                         {
244                                                 me.target_alt.setValue(current_alt);
245                                         }
246                                         else
247                                         {
248                                                 me.target_alt.setValue(me.alt_setting.getValue());
249                                         }
250                                         me.autothrottle_mode.setValue(5);       # A/T SPD
251                                 }
252                                 if(btn==4)
253                                 {
254                                         # Altitude intervention
255                                         if(me.alt_setting.getValue() == me.intervention_alt)
256                                         {
257                                                 # clear current restriction
258                                                 var temp_wpt = me.FMC_current_wp.getValue() + 1;
259                                                 me.altitude_restriction = getprop("autopilot/route-manager/route/wp["~temp_wpt~"]/altitude-ft");
260                                                 if(me.altitude_restriction > 0)
261                                                 {
262                                                         me.altitude_restriction = int((me.altitude_restriction + 50) / 100 )* 100;
263                                                 }
264                                         }
265                                         else
266                                         {
267                                                 me.intervention_alt = me.alt_setting.getValue();
268                                         }
269                                         btn = me.vertical_mode.getValue();
270                                 }
271                                 elsif(btn == 255)
272                                 {
273                                         if(me.vs_setting.getValue() == 0)
274                                         {
275                                                 me.target_alt.setValue(current_alt);
276                                         }
277                                         else
278                                         {
279                                                 me.target_alt.setValue(me.alt_setting.getValue());
280                                         }
281                                         btn = 2;
282                                 }
283                                 if(btn==5)              # VNAV
284                                 {
285                                         if (!me.FMC_active.getValue() or
286                                                 me.FMC_current_wp.getValue()<0 or
287                                                 (getprop("autopilot/route-manager/wp/id")==""))
288                                         {
289                                                 # Oops, route manager isn't active. Keep current mode.
290                                                 btn = me.vertical_mode.getValue();
291                                                 copilot("Captain, VNAV doesn't engage. We forgot to program or activate the route manager!");
292                                         }
293                                         else
294                                         {
295                                                 var vnav_mode = me.vertical_mode.getValue();
296                                                 if(vnav_mode == 3)                      # Current mode is VNAV PTH
297                                                 {
298                                                 }
299                                                 elsif(vnav_mode == 4)           # Current mode is VNAV SPD
300                                                 {
301                                                 }
302                                                 elsif(vnav_mode == 5)           # Current mode is VNAV ALT
303                                                 {
304                                                 }
305                                                 elsif(me.vnav_armed.getValue())
306                                                 {       # VNAV armed then disarm
307                                                         me.vnav_armed.setValue(0);
308                                                         btn = vnav_mode;
309                                                 }
310                                                 else
311                                                 {       # VNAV arm
312                                                         me.vnav_armed.setValue(1);
313                                                         me.vnav_path_mode.setValue(0);          # VNAV PTH HOLD
314                                                         me.vnav_mcp_reset.setValue(0);
315                                                         me.vnav_descent.setValue(0);
316                                                         btn = vnav_mode;
317                                                         me.descent_step = 0;
318                                                         me.manual_intervention.setValue(0);
319                                                 }
320                                         }
321                                 }
322                                 if(btn==8)              # FLCH SPD
323                                 {
324                                         # change flight level
325                                         if(((current_alt
326                                                 - getprop("autopilot/internal/airport-height")) < 400)
327                                                 or (me.at1.getValue() == 0) or (me.at2.getValue() == 0))
328                                         {
329                                                 btn = 0;
330                                         }
331                                         elsif(current_alt < me.alt_setting.getValue())
332                                         {
333                                                 me.autothrottle_mode.setValue(1);       # A/T THR
334                                         }
335                                         else
336                                         {
337                                                 me.autothrottle_mode.setValue(4);       # A/T IDLE
338                                         }
339                                         setprop("autopilot/internal/current-pitch-deg", getprop("orientation/pitch-deg"));
340                                         var alt = me.alt_setting.getValue();
341                                         me.target_alt.setValue(alt);
342                                 }
343                                 me.vertical_mode.setValue(btn);
344                         }
345                         elsif(mode == 2)
346                         {
347                                 # throttle AP controls
348                                 if(me.autothrottle_mode.getValue() != 0
349                                         or (me.at1.getValue() == 0) or (me.at2.getValue() == 0))
350                                 {
351                                         btn = 0;
352                                 }
353                                 elsif(btn == 2)         # TOGA
354                                 {
355                                         if((getprop("instrumentation/airspeed-indicator/indicated-speed-kt") > 50)
356                                                 or (getprop("controls/flight/flaps") == 0))
357                                         {
358                                                 btn = 0;
359                                         }
360                                         me.auto_popup.setValue(1);
361                                 }
362                                 elsif((current_alt
363                                                 - getprop("autopilot/internal/airport-height")) < 400)
364                                 {
365                                         btn=0;
366                                         copilot("Captain, auto-throttle won't engage below 400ft.");
367                                 }
368                                 if(btn == 2)
369                                 {
370                                         setprop("autopilot/locks/takeoff-mode", 1);
371                                 }
372                                 me.autothrottle_mode.setValue(btn);
373                         }
374                         elsif(mode==3)  #FD, LOC or G/S button
375                         {
376                                 if(btn == 2)    # FD button toggle
377                                 {
378                                         if(me.FD.getValue())
379                                         {
380                                                 if(getprop("gear/gear[1]/wow"))
381                                                 {
382                                                         me.lateral_mode.setValue(9);            # TOGA
383                                                         me.vertical_mode.setValue(10);          # TOGA
384                                                 }
385                                         }
386                                         else
387                                         {
388                                                 if(!me.AP.getValue())
389                                                 {
390                                                         me.lateral_mode.setValue(0);            # Clear
391                                                         me.vertical_mode.setValue(0);           # Clear
392                                                         setprop("autopilot/settings/roll-transition", 0);
393                                                         setprop("autopilot/settings/pitch-transition", 0);
394                                                 }
395                                         }
396                                 }
397                                 elsif(btn == 3) # AP button toggle
398                                 {
399                                         if(!me.AP.getValue())
400                                         {
401                                                 me.rollout_armed.setValue(0);
402                                                 me.flare_armed.setValue(0);
403                                                 me.loc_armed.setValue(0);                       # Disarm
404                                                 me.gs_armed.setValue(0);                        # Disarm
405                                                 if(!me.FD.getValue())
406                                                 {
407                                                         me.lateral_mode.setValue(0);            # NO MODE
408                                                         me.vertical_mode.setValue(0);           # NO MODE
409                                                         setprop("autopilot/settings/roll-transition", 0);
410                                                         setprop("autopilot/settings/pitch-transition", 0);
411                                                 }
412                                                 else
413                                                 {
414                                                         if(me.hdg_trk_selected.getValue())
415                                                         {
416                                                                 me.lateral_mode.setValue(7);    # TRK HOLD
417                                                         }
418                                                         else
419                                                         {
420                                                                 me.lateral_mode.setValue(2);    # HDG HOLD
421                                                         }
422                                                         me.vertical_mode.setValue(1);           # ALT
423                                                 }
424                                         }
425                                         else
426                                         {
427                                                 if(!me.FD.getValue()
428                                                         and !me.lnav_armed.getValue()
429                                                         and (me.lateral_mode.getValue() != 3))
430                                                 {
431                                                         me.lateral_mode.setValue(8);            # ATT
432                                                 }
433                                                 if(!me.vnav_armed.getValue()
434                                                         and (me.vertical_mode.getValue() == 0))
435                                                 {
436                                                         # hold current vertical speed
437                                                         var vs = getprop("instrumentation/inst-vertical-speed-indicator/indicated-speed-fpm");
438                                                         vs = int(vs/100)*100;
439                                                         if (vs<-8000) vs = -8000;
440                                                         if (vs>6000) vs = 6000;
441                                                         me.vs_setting.setValue(vs);
442                                                         if(vs == 0)
443                                                         {
444                                                                 me.target_alt.setValue(current_alt);
445                                                         }
446                                                         else
447                                                         {
448                                                                 me.target_alt.setValue(me.alt_setting.getValue());
449                                                         }
450                                                         me.vertical_mode.setValue(2);           # V/S
451                                                 }
452                                         }
453                                 }
454                                 else
455                                 {
456                                         var llocmode = me.lateral_mode.getValue();
457                                         var lgsmode = me.vertical_mode.getValue();
458                                         if(btn==0)
459                                         {
460                                                 if(me.loc_armed.getValue())                     # LOC armed but not captured yet
461                                                 {
462                                                         if(me.gs_armed.getValue())                      # GS armed but not captured yet
463                                                         {
464                                                                 me.gs_armed.setValue(0);
465                                                         }
466                                                         me.loc_armed.setValue(0);
467                                                 }
468                                                 elsif(llocmode == 4)            # Alrady in LOC mode
469                                                 {
470                                                         if(me.gs_armed.getValue())
471                                                         {
472                                                                 me.gs_armed.setValue(0);
473                                                         }
474                                                         elsif((lgsmode != 6)
475                                                                 and (getprop("position/gear-agl-ft") > 1500))
476                                                         {
477                                                                 me.lateral_mode.setValue(8);            # Default roll mode (ATT)
478                                                         }
479                                                 }
480                                                 elsif(me.loc_armed.getValue())                  # LOC armed but not captured yet
481                                                 {
482                                                         me.loc_armed.setValue(0);                       # Disarm
483                                                 }
484                                                 else
485                                                 {
486                                                         me.loc_armed.setValue(1);                       # LOC arm
487                                                 }
488                                         }
489                                         elsif (btn==1)  #APP button
490                                         {
491                                                 if((llocmode == 4)      # Already in LOC mode
492                                                                 and (me.gs_armed.getValue(1)            # GS armed
493                                                                         or (lgsmode == 6))
494                                                                 and (getprop("position/gear-agl-ft") > 1500))
495                                                 {
496                                                         me.lateral_mode.setValue(8);    # Default roll mode (ATT)
497                                                         me.vertical_mode.setValue(2);   # Default pich mode (V/S)
498                                                         me.gs_armed.setValue(0);                # Disarm
499                                                 }
500                                                 elsif(me.loc_armed.getValue())          # loc armed but not captured yet
501                                                 {
502                                                         me.gs_armed.setValue(0);                # Disarm
503                                                         me.loc_armed.setValue(0);               # Disarm
504                                                 }
505                                                 else
506                                                 {
507                                                         me.gs_armed.setValue(1);                # G/S arm
508                                                         me.loc_armed.setValue(1);               # LOC arm
509                                                 }
510                                         }
511                                 }
512                         }
513                         elsif(mode==4)  #Other (HDG REF button, TRK-HDG)
514                         {
515                                 if(btn==0)
516                                 {
517                                         me.referenceChange();
518                                         me.hdg_setting.setValue(me.heading.getValue());
519                                         if(me.hdg_trk_selected.getValue())
520                                         {
521                                                 if((me.lateral_mode.getValue() == 1)
522                                                         or (me.lateral_mode.getValue() == 2))
523                                                 {
524                                                         me.lateral_mode.setValue(6);    # TRK SEL
525                                                 }
526                                         }
527                                         else
528                                         {
529                                                 if((me.lateral_mode.getValue() == 6)
530                                                         or (me.lateral_mode.getValue() == 7))
531                                                 {
532                                                         me.lateral_mode.setValue(1);    # HDG SEL
533                                                 }
534                                         }
535                                 }
536                         }
537                 }
538         },
539 ###################
540         setAP : func{
541                 if(me.heading.getValue() == nil)
542                 {
543                         me.heading.setValue(getprop("sim/presets/heading-deg"));
544                 }
545                 var output = 1-me.AP.getValue();
546                 var disabled = me.AP_disengaged.getValue();
547                 if((output==0)and(getprop("position/gear-agl-ft")<200))
548                 {
549                         disabled = 1;
550                         copilot("Captain, autopilot won't engage below 200ft.");
551                 }
552                 if((disabled)and(output==0)){output = 1;me.AP.setValue(0);}
553                 if (output==1)
554                 {
555                         var msg="";
556                         var msg2="";
557                         var msg3="";
558                         if (abs(getprop("controls/flight/rudder-trim"))   > 0.04) msg  = "rudder";
559                         if (abs(getprop("controls/flight/elevator-trim")) > 0.04) msg2 = "pitch";
560                         if (abs(getprop("controls/flight/aileron-trim"))  > 0.04) msg3 = "aileron";
561                         if (msg ~ msg2 ~ msg3 != "")
562                         {
563                                 if ((msg != "")and(msg2!=""))
564                                         msg = msg ~ ", " ~ msg2;
565                                 else
566                                         msg = msg ~ msg2;
567                                 if ((msg != "")and(msg3!=""))
568                                         msg = msg ~ " and " ~ msg3;
569                                 else
570                                         msg = msg ~ msg3;
571                                 copilot("Captain, autopilot disengaged. Careful, check " ~ msg ~ " trim!");
572                         }
573                         me.rollout_armed.setValue(0);
574                         me.flare_armed.setValue(0);
575                         me.loc_armed.setValue(0);                       # Disarm
576                         me.gs_armed.setValue(0);                        # Disarm
577                         if(!me.FD.getValue())
578                         {
579                                 me.lateral_mode.setValue(0);            # NO MODE
580                                 me.vertical_mode.setValue(0);           # NO MODE
581                                 setprop("autopilot/settings/roll-transition", 0);
582                                 setprop("autopilot/settings/pitch-transition", 0);
583                         }
584                         else
585                         {
586                                 if(me.lateral_mode.getValue() == 0)
587                                 {
588                                         me.lateral_mode.setValue(2);            # HDG HOLD
589                                 }
590                                 if(me.vertical_mode.getValue() == 0)
591                                 {
592                                         me.vertical_mode.setValue(1);           # ALT
593                                 }
594                         }
595                 }
596                 else
597                 {
598                         if(!me.FD.getValue()
599                                 and !me.lnav_armed.getValue()
600                                 and (me.lateral_mode.getValue() != 3))
601                         {
602                                 var current_bank = getprop("orientation/roll-deg");
603                                 me.lateral_mode.setValue(8);            # ATT
604                         }
605                         if(!me.vnav_armed.getValue()
606                                 and (me.vertical_mode.getValue() == 0))
607                         {
608                                 # hold current vertical speed
609                                 var vs = getprop("instrumentation/inst-vertical-speed-indicator/indicated-speed-fpm");
610                                 vs = int(vs/100)*100;
611                                 if (vs<-8000) vs = -8000;
612                                 if (vs>6000) vs = 6000;
613                                 me.vs_setting.setValue(vs);
614                                 if(vs == 0)
615                                 {
616                                         me.target_alt.setValue(getprop("instrumentation/altimeter/indicated-altitude-ft"));
617                                 }
618                                 else
619                                 {
620                                         me.target_alt.setValue(me.alt_setting.getValue());
621                                 }
622                                 me.vertical_mode.setValue(2);           # V/S
623                         }
624                 }
625         },
626 ###################
627         setbank : func{
628                 var banklimit = me.bank_switch.getValue();
629                 var lmt = 25;
630                 if(banklimit>0) {lmt = banklimit * 5};
631                 me.bank_max.setValue(lmt);
632                 lmt = -1 * lmt;
633                 me.bank_min.setValue(lmt);
634         },
635 ###################
636         referenceChange : func()
637         {
638                 # Heading reference selection
639                 if(getprop("systems/navigation/hdgref/button")
640                                 or (abs(getprop("position/latitude-deg")) > 82.0))
641                 {
642                         me.heading_reference.setValue(1);
643                 }
644                 else
645                 {
646                         me.heading_reference.setValue(0);
647                 }
648                 setprop("instrumentation/efis/mfd/true-north", me.heading_reference.getValue());
649                 setprop("instrumentation/efis[1]/mfd/true-north", me.heading_reference.getValue());
650                 if(getprop("velocities/groundspeed-kt") > 5)
651                 {
652                         vheading = (getprop("orientation/heading-deg") - getprop("orientation/track-deg"));
653                         if(vheading < -180) vheading +=360;
654                         if(vheading > 180) vheading +=-360;
655                         if(me.hdg_trk_selected.getValue())
656                         {
657                                 setprop("autopilot/internal/crab-angle-hdg", vheading);
658                                 setprop("autopilot/internal/crab-angle-trk", 0);
659                         }
660                         else
661                         {
662                                 setprop("autopilot/internal/crab-angle-trk", vheading);
663                                 setprop("autopilot/internal/crab-angle-hdg", 0);
664                         }
665                 }
666                 else
667                 {
668                         setprop("autopilot/internal/crab-angle-hdg", 0);
669                         setprop("autopilot/internal/crab-angle-trk", 0);
670                 }
671                 if(me.heading_reference.getValue())
672                 {
673                         if((me.hdg_trk_selected.getValue())
674                                 and (getprop("velocities/groundspeed-kt") > 5))
675                         {
676                                 vheading = getprop("orientation/track-deg");
677                         }
678                         else
679                         {
680                                 vheading = getprop("orientation/heading-deg");
681                         }
682                         me.vorient = 0;
683                 }
684                 else
685                 {
686                         if((me.hdg_trk_selected.getValue())
687                                 and (getprop("velocities/groundspeed-kt") > 5))
688                         {
689                                 vheading = getprop("orientation/track-magnetic-deg");
690                         }
691                         else
692                         {
693                                 vheading = getprop("orientation/heading-magnetic-deg");
694                         }
695                         me.vorient = getprop("environment/magnetic-variation-deg");
696                 }
697                 me.reference_deg.setValue(vheading);
698                 # VOR, ADF direction calculation
699                 setprop("instrumentation/efis/mfd/lvordirection", (getprop("instrumentation/nav/heading-deg") - vheading - me.vorient));
700                 setprop("instrumentation/efis/mfd/rvordirection", (getprop("instrumentation/nav[1]/heading-deg") - vheading - me.vorient));
701                 setprop("instrumentation/efis/mfd/ladfdirection", (getprop("instrumentation/adf/indicated-bearing-deg")
702                                         + getprop("autopilot/internal/crab-angle-hdg")));
703                 setprop("instrumentation/efis/mfd/radfdirection", (getprop("instrumentation/adf[1]/indicated-bearing-deg")
704                                         + getprop("autopilot/internal/crab-angle-hdg")));
705                 # Wind direction and bearing calculation
706                 setprop("instrumentation/efis/mfd/winddirection", (getprop("environment/wind-from-heading-deg") - vheading - me.vorient));
707                 vheading = int(vheading + 0.5);
708                 if(vheading < 0.5)
709                 {
710                         vheading += 360;
711                 }
712                 me.heading.setValue(vheading);
713                 vheading = (getprop("environment/wind-from-heading-deg") - me.vorient);
714                 vheading = int(vheading + 0.5);
715                 if(vheading < 0.5)
716                 {
717                         vheading += 360;
718                 }
719                 setprop("instrumentation/efis/mfd/windbearing", vheading);
720         },
721         
722 ###################
723         updateATMode : func()
724         {
725                 var idx = me.autothrottle_mode.getValue();
726                 if((me.AP_speed_mode.getValue() != me.spd_list[idx])
727                                 and (idx > 0))
728                 {
729                         setprop("autopilot/settings/speed-transition", 1);
730                         settimer(func
731                         {
732                                 setprop("autopilot/settings/speed-transition", 0);
733                         }, 10);
734                 }
735                 me.AP_speed_mode.setValue(me.spd_list[idx]);
736         },
737 #################
738         wpChanged : func{
739                 if((getprop("autopilot/route-manager/wp/id")=="") or
740                         !me.FMC_active.getValue() and
741                         (me.lateral_mode.getValue() == 3) and
742                         me.AP.getValue())
743                 {
744                         # LNAV active, but route manager is disabled now => switch to HDG HOLD (current heading)
745                         me.input(0,2);
746                 }
747         },
748 #################
749         ap_update : func{
750                 var Vcal = func(M)
751                 {
752                         var p = getprop("environment/pressure-inhg") * 3386.388640341;
753                         var pt = p * math.pow(1 + 0.2 * M*M,3.5);
754                         var Vc =  math.sqrt((math.pow((pt-p)/101325+1,0.285714286) -1 ) * 7 * 101325 /1.225) / 0.5144;
755                         return (Vc);
756                 }
757                 var current_alt = getprop("instrumentation/altimeter/indicated-altitude-ft");
758                 var VS = getprop("velocities/vertical-speed-fps");
759                 var TAS = getprop("instrumentation/airspeed-indicator/true-speed-kt") * KT2FPS; # keeping TAS as fps
760                 me.indicated_vs_fpm.setValue(int((abs(VS) * 60 + 50) / 100) * 100);
761                 if(getprop("instrumentation/airspeed-indicator/indicated-speed-kt") < 30)
762                 {
763                         setprop("instrumentation/airspeed-indicator/indicated-speed-kt", 30);
764                 }
765                 # This value is used for displaying negative altitude 
766                 if(current_alt < 0)
767                 {
768                         setprop("instrumentation/altimeter/indicator-altitude-ft", abs(current_alt) + 90000);
769                 }
770                 else
771                 {
772                         setprop("instrumentation/altimeter/indicator-altitude-ft", current_alt);
773                 }
774                 if(TAS < 10) TAS = 10;
775                 if(VS < -200) VS=-200;
776                 if (abs(VS/TAS)<=1)
777                 {
778                         var FPangle = math.asin(VS/TAS);
779                         FPangle *=90;
780                         setprop("autopilot/internal/fpa",FPangle);
781                 }
782                 var msg = " ";
783                 if(me.FD.getValue())
784                 {
785                         msg="FLT DIR";
786                 }
787                 if(me.AP.getValue())
788                 {
789                         msg="A/P";
790                         if(me.rollout_armed.getValue())
791                         {
792                                 msg="LAND 3";
793                         }
794                 }
795                 if(msg == " ")
796                 {
797                         setprop("autopilot/settings/autopilot-transition", 0);
798                 }
799                 elsif(me.AP_annun.getValue() != msg)
800                 {
801                         setprop("autopilot/settings/autopilot-transition", 1);
802                         settimer(func
803                         {
804                                 setprop("autopilot/settings/autopilot-transition", 0);
805                         }, 10);
806                 }
807                 me.AP_annun.setValue(msg);
808                 var tmp = abs(me.vs_setting.getValue());
809                 me.vs_display.setValue(tmp);
810                 tmp = abs(me.fpa_setting.getValue());
811                 me.fpa_display.setValue(tmp);
812                 msg = "";
813                 # Heading reference selection
814                 me.referenceChange();
815                 # Heading bug position calculation
816                 var hdgoffset = 0;
817                 hdgoffset = (me.hdg_setting.getValue()-me.reference_deg.getValue());
818                 if(hdgoffset < -180) hdgoffset +=360;
819                 if(hdgoffset > 180) hdgoffset +=-360;
820                 setprop("autopilot/internal/heading-bug-error-deg",hdgoffset);
821                 # Calculation of localizer pointer
822                 var deflection = getprop("instrumentation/nav/heading-needle-deflection-norm");
823                 if((abs(deflection) < 0.5233) and (getprop("instrumentation/nav/signal-quality-norm") > 0.99))
824                 {
825                         setprop("autopilot/internal/presision-loc", 1);
826                                 setprop("instrumentation/nav/heading-needle-deflection-ptr", (deflection * 1.728));
827                 }
828                 else
829                 {
830                         setprop("autopilot/internal/presision-loc", 0);
831                         setprop("instrumentation/nav/heading-needle-deflection-ptr", deflection);
832                 }
833
834                 if(me.step==0){ ### glideslope armed ?###
835                         var gear_agl_ft = getprop("position/gear-agl-ft");
836                         if(gear_agl_ft > 500)
837                         {
838                                 gear_agl_ft = int(gear_agl_ft / 20) * 20; 
839                         }
840                         elsif(gear_agl_ft > 100)
841                         {
842                                 gear_agl_ft = int(gear_agl_ft / 10) * 10; 
843                         }
844                         me.radio_alt_ind.setValue(gear_agl_ft); 
845                         msg="";
846                         if(me.gs_armed.getValue())
847                         {
848                                 msg="G/S";
849                                 if(me.lateral_mode.getValue() == 4)     #LOC already captured
850                                 {
851                                         var vradials = (getprop("instrumentation/nav[0]/radials/target-radial-deg")
852                                                         - getprop("orientation/heading-deg"));
853                                         if(vradials < -180) vradials += 360;
854                                         elsif(vradials >= 180) vradials -= 360;
855                                         if(abs(vradials) < 80)
856                                         {
857                                                 var gsdefl = getprop("instrumentation/nav/gs-needle-deflection-deg");
858                                                 var gsrange = getprop("instrumentation/nav/gs-in-range");
859                                                 if ((gsdefl< 0.1 and gsdefl>-0.1)and
860                                                         gsrange)
861                                                 {
862                                                         me.vertical_mode.setValue(6);
863                                                         me.gs_armed.setValue(0);
864                                                 }
865                                         }
866                                 }
867                         }
868                         elsif(me.flare_armed.getValue())
869                         {
870                                 msg="FLARE";
871                         }
872                         elsif(me.vnav_armed.getValue())
873                         {
874                                 msg = "VNAV";
875                         }
876                         me.AP_pitch_arm.setValue(msg);
877
878                 }elsif(me.step==1){ ### localizer armed ? ###
879                         msg = "";
880                         if(me.loc_armed.getValue())
881                         {
882                                 msg = "LOC";
883                                 if (getprop("instrumentation/nav/in-range"))
884                                 {
885                                         if(!getprop("instrumentation/nav/nav-loc"))
886                                         {
887                                                 var vheading = getprop("instrumentation/nav/radials/selected-deg");
888                                                 var vvor = getprop("instrumentation/nav/heading-deg");
889                                                 var vdist = getprop("instrumentation/nav/nav-distance");
890                                                 var vheading = getprop("orientation/heading-deg");
891                                                 var vspeed = getprop("instrumentation/airspeed-indicator/indicated-mach");
892                                                 var deg_to_rad = math.pi / 180;
893                                                 var vdiff = abs(vheading - vvor + me.vorient);
894                                                 vdiff = abs(vdist * math.sin(vdiff * deg_to_rad));
895                                                 var vlim = vspeed / 0.3 * 1300 * abs(vheading - vheading) / 45 ;
896                                                 if(vdiff < vlim)
897                                                 {
898                                                         me.lateral_mode.setValue(4);
899                                                         me.loc_armed.setValue(0);
900                                                 }
901                                         }
902                                         else
903                                         {
904                                                 var vradials = (getprop("instrumentation/nav[0]/radials/target-radial-deg")
905                                                                 - getprop("orientation/heading-deg"));
906                                                 if(vradials < -180) vradials += 360;
907                                                 elsif(vradials >= 180) vradials -= 360;
908                                                 if(abs(vradials) < 120)
909                                                 {
910                                                         var hddefl = getprop("instrumentation/nav/heading-needle-deflection");
911                                                         if(abs(hddefl) < 9.9)
912                                                         {
913                                                                 me.lateral_mode.setValue(4);
914                                                                 me.loc_armed.setValue(0);
915                                                                 vradials = getprop("instrumentation/nav[0]/radials/target-radial-deg") - me.vorient + 0.5;
916                                                                 if(vradials < 0.5) vradials += 360;
917                                                                 elsif(vradials >= 360.5) vradials -= 360;
918                                                                 me.hdg_setting.setValue(vradials);
919                                                         }
920                                                         else
921                                                         {
922                                                                 setprop("autopilot/internal/presision-loc", 0);
923                                                         }
924                                                 }
925                                         }
926                                 }
927                                 else
928                                 {
929                                         setprop("autopilot/internal/presision-loc", 0);
930                                 }
931                         }
932                         elsif(me.lnav_armed.getValue())
933                         {
934                                 if(getprop("position/gear-agl-ft") > 50)
935                                 {
936                                         msg = "";
937                                         me.lnav_armed.setValue(0);              # Clear
938                                         me.lateral_mode.setValue(3);    # LNAV
939                                 }
940                                 else
941                                 {
942                                         msg = "LNAV";
943                                 }
944                         }
945                         elsif(me.rollout_armed.getValue())
946                         {
947                                 msg = "ROLLOUT";
948                         }
949                         me.AP_roll_arm.setValue(msg);
950
951                 }elsif(me.step == 2){ ### check lateral modes  ###
952                         # Heading bug line enable control
953                         var vsethdg = me.hdg_setting.getValue();
954                         if(me.hdg_setting_last.getValue() != vsethdg)
955
956                         {
957                                 me.hdg_setting_last.setValue(vsethdg);
958                                 me.hdg_setting_active.setValue(1);
959                         }
960                         else
961                         {
962                                 if(getprop("instrumentation/efis/mfd/display-mode") == "MAP")
963                                 {
964                                         if(me.lateral_mode.getValue() == 3
965                                                 or me.lateral_mode.getValue() == 4
966                                                 or me.lateral_mode.getValue() == 5)
967                                         {
968                                                 if(me.hdg_setting_active.getValue() == 1)
969                                                 {
970                                                         settimer(func
971                                                         {
972                                                                 if(me.hdg_setting_last.getValue() == vsethdg)
973                                                                 {
974                                                                         me.hdg_setting_active.setValue(0);
975                                                                 }
976                                                         }, 10);
977                                                 }
978                                         }
979                                         else
980                                         {
981                                                 me.hdg_setting_active.setValue(1);
982                                         }
983                                 }
984                         }
985                         var idx = me.lateral_mode.getValue();
986                         if(getprop("position/gear-agl-ft") > 50)
987                         {
988                                 if ((idx == 1) or (idx == 2))
989                                 {
990                                         # switch between HDG SEL and HDG HOLD
991                                         if (abs(me.reference_deg.getValue() - me.hdg_setting.getValue())<2)
992                                         {
993                                                 idx = 2; # HDG HOLD
994                                         }
995                                         else
996                                         {
997                                                 idx = 1; # HDG SEL
998                                         }
999                                 }
1000                                 if((idx == 6) or (idx == 7))
1001                                 {
1002                                         # switch between TRK SEL and TRK HOLD
1003                                         if (abs(me.reference_deg.getValue() - me.hdg_setting.getValue())<2)
1004                                         {
1005                                                 idx = 7; # TRK HOLD
1006                                         }
1007                                         else
1008                                         {
1009                                                 idx = 6; # TRK SEL
1010                                         }
1011                                 }
1012                         }
1013                         if(idx == 4)            # LOC
1014                         {
1015                                 if((me.rollout_armed.getValue())
1016                                         and (getprop("position/gear-agl-ft") < 50))
1017                                 {
1018                                         me.rollout_armed.setValue(0);
1019                                         idx = 5;        # ROLLOUT
1020                                 }
1021                                 me.crab_angle.setValue(me.heading.getValue() - getprop("instrumentation/nav[0]/radials/target-radial-deg") + me.vorient);
1022                                 me.crab_angle_total.setValue(abs(me.crab_angle.getValue() + getprop("orientation/side-slip-deg")));
1023                                 if(me.crab_angle.getValue() > 0)
1024                                 {
1025                                         me.rwy_align_limit.setValue(5.0);
1026                                 }
1027                                 else
1028                                 {
1029                                         me.rwy_align_limit.setValue(-5.0);
1030                                 }
1031                         }
1032                         elsif(idx == 5)                                                                 # ROLLOUT
1033                         {
1034                                 if(getprop("velocities/groundspeed-kt") < 50)
1035                                 {
1036                                         me.AP.setValue(0);                                              # Autopilot off
1037                                         setprop("controls/flight/aileron", 0);  # Aileron set neutral
1038                                         setprop("controls/flight/rudder", 0);   # Rudder set neutral
1039                                         me.FMC_destination_ils.setValue(0);             # Clear destination ILS set
1040                                         if(!me.FD.getValue())
1041                                         {
1042                                                 idx = 0;        # NO MODE
1043                                         }
1044                                         else
1045                                         {
1046                                                 idx = 1;        # HDG SEL
1047                                         }
1048                                 }
1049                         }
1050                         elsif(idx == 8)                                                                 # ATT
1051                         {
1052                                 var current_bank = getprop("orientation/roll-deg");
1053                                 if(current_bank > 30)
1054                                 {
1055                                         setprop("autopilot/internal/target-roll-deg", 30);
1056                                 }
1057                                 elsif(current_bank < -30)
1058                                 {
1059                                         setprop("autopilot/internal/target-roll-deg", -30);
1060                                 }
1061                                 elsif((abs(current_bank) > 5) and (abs(current_bank) <= 30))
1062                                 {
1063                                         setprop("autopilot/internal/target-roll-deg", current_bank);
1064                                 }
1065                                 elsif(abs(current_bank) <= 5)
1066                                 {
1067                                         setprop("autopilot/internal/target-roll-deg", 0);
1068                                 }
1069                                 if(abs(current_bank) <= 3)
1070                                 {
1071                                         var tgtHdg = int(me.reference_deg.getValue());
1072                                         me.hdg_setting.setValue(tgtHdg);
1073                                         if(me.hdg_trk_selected.getValue())
1074                                         {
1075                                                 idx = 7;    # TRK HOLD
1076                                         }
1077                                         else
1078                                         {
1079                                                 idx = 2;    #  HDG HOLD
1080                                         }
1081                                 }
1082                         }
1083                         me.lateral_mode.setValue(idx);
1084                         if((me.AP_roll_mode.getValue() != me.roll_list[idx])
1085                                         and (idx > 0))
1086                         {
1087                                 setprop("autopilot/settings/roll-transition", 1);
1088                                 settimer(func
1089                                 {
1090                                         setprop("autopilot/settings/roll-transition", 0);
1091                                 }, 10);
1092                         }
1093                         me.AP_roll_mode.setValue(me.roll_list[idx]);
1094                         me.AP_roll_engaged.setBoolValue(idx > 0);
1095
1096                 }elsif(me.step==3){ ### check vertical modes  ###
1097                         # This is only for Canvas ND pridiction circle indication, not used inside
1098                         setprop("autopilot/settings/target-altitude-ft", me.target_alt.getValue());
1099                         me.alt_setting_FL.setValue(me.alt_setting.getValue() / 1000);
1100                         me.alt_setting_100.setValue(me.alt_setting.getValue() - (me.alt_setting_FL.getValue() * 1000));
1101                         if(getprop("instrumentation/airspeed-indicator/indicated-speed-kt") < 100)
1102                         {
1103                                 setprop("autopilot/internal/airport-height", current_alt);
1104                         }
1105                         ### altitude alert ###
1106                         var alt_deviation = abs(me.alt_setting.getValue() - current_alt);
1107                         if((alt_deviation > 900)
1108                                         or (me.vertical_mode.getValue() == 6)                   # G/S mode
1109                                         or (getprop("gear/gear/position-norm") == 1))   # Gear down and locked
1110                         {
1111                                 me.altitude_alert_from_out = 0;
1112                                 me.altitude_alert_from_in = 0;
1113                                 setprop("autopilot/internal/alt-alert", 0);
1114                         }
1115                         elsif(alt_deviation > 200)
1116                         {
1117                                 if((me.altitude_alert_from_out == 0)
1118                                                 and (me.altitude_alert_from_in == 0))
1119                                 {
1120                                         me.altitude_alert_from_out = 1;
1121                                         setprop("autopilot/internal/alt-alert", 1);
1122                                 }
1123                                 elsif((me.altitude_alert_from_out == 1)
1124                                                 and (me.altitude_alert_from_in == 1))
1125                                 {
1126                                         me.altitude_alert_from_out = 0;
1127                                         setprop("autopilot/internal/alt-alert", 2);
1128                                 }
1129                         }
1130                         else
1131                         {
1132                                 me.altitude_alert_from_out = 1;
1133                                 me.altitude_alert_from_in = 1;
1134                                 setprop("autopilot/internal/alt-alert", 0);
1135                         }
1136
1137                         var idx = me.vertical_mode.getValue();
1138                         var test_fpa = me.vs_fpa_selected.getValue();
1139                         var offset = (abs(getprop("instrumentation/inst-vertical-speed-indicator/indicated-speed-fpm")) / 8);
1140                         if(offset < 20)
1141                         {
1142                                 offset = 20;
1143                         }
1144                         me.optimal_alt = ((getprop("consumables/fuel/total-fuel-lbs") + getprop("sim/weight[0]/weight-lb") + getprop("sim/weight[1]/weight-lb"))
1145                                                         / getprop("sim/max-payload"));
1146                         if(me.optimal_alt > 0.95) me.optimal_alt = 29000;
1147                         elsif(me.optimal_alt > 0.89) me.optimal_alt = 30000;
1148                         elsif(me.optimal_alt > 0.83) me.optimal_alt = 31000;
1149                         elsif(me.optimal_alt > 0.74) me.optimal_alt = 32000;
1150                         elsif(me.optimal_alt > 0.65) me.optimal_alt = 33000;
1151                         elsif(me.optimal_alt > 0.59) me.optimal_alt = 34000;
1152                         elsif(me.optimal_alt > 0.53) me.optimal_alt = 35000;
1153                         elsif(me.optimal_alt > 0.47) me.optimal_alt = 36000;
1154                         elsif(me.optimal_alt > 0.41) me.optimal_alt = 37000;
1155                         elsif(me.optimal_alt > 0.35) me.optimal_alt = 38000;
1156                         elsif(me.optimal_alt > 0.23) me.optimal_alt = 40000;
1157                         elsif(me.optimal_alt > 0.16) me.optimal_alt = 41000;
1158                         else me.optimal_alt = 43000;
1159                         if(idx==2 and test_fpa)idx=9;
1160                         if(idx==9 and !test_fpa)idx=2;
1161                         if((idx==8)or(idx==1)or(idx==2)or(idx==9))
1162                         {
1163                                 # flight level change mode
1164                                 if (abs(current_alt - me.alt_setting.getValue()) < offset)
1165                                 {
1166                                         # within MCP altitude: switch to ALT HOLD mode
1167                                         idx = 1;        # ALT
1168                                         if(me.autothrottle_mode.getValue() != 0)
1169                                         {
1170                                                 me.autothrottle_mode.setValue(5);       # A/T SPD
1171                                         }
1172                                         me.vs_setting.setValue(0);
1173                                 }
1174                                 if((me.mach_setting.getValue() >= me.FMC_cruise_mach.getValue())
1175                                         and (me.ias_mach_selected.getValue() == 0)
1176                                         and (current_alt < me.target_alt.getValue()))
1177                                 {
1178                                         me.ias_mach_selected.setValue(1);
1179                                         me.mach_setting.setValue(me.FMC_cruise_mach.getValue());
1180                                 }
1181                                 elsif((me.ias_setting.getValue() >= me.FMC_cruise_ias.getValue())
1182                                         and (me.ias_mach_selected.getValue() == 1)
1183                                         and (current_alt > me.target_alt.getValue()))
1184                                 {
1185                                         me.ias_mach_selected.setValue(0);
1186                                         me.ias_setting.setValue(me.FMC_cruise_ias.getValue());
1187                                 }
1188                         }
1189                         elsif(idx == 3)         # VNAV PTH
1190                         {
1191                                 if(me.vnav_descent.getValue())
1192                                 {
1193                                         if(me.descent_step == 0)
1194                                         {
1195                                                 if(me.ias_mach_selected.getValue() == 1)
1196                                                 {
1197                                                         if(Vcal(me.FMC_descent_mach.getValue()) > (getprop("instrumentation/weu/state/stall-speed") + 5))
1198                                                         {
1199                                                                 me.mach_setting.setValue(me.FMC_descent_mach.getValue());
1200                                                         }
1201                                                 }
1202                                                 else
1203                                                 {
1204                                                         if(current_alt > 12000)
1205                                                         {
1206                                                                 me.ias_setting.setValue(me.FMC_descent_ias.getValue());
1207                                                         }
1208                                                 }
1209                                                 me.descent_step += 1;
1210                                         }
1211                                         elsif(me.descent_step == 1)
1212                                         {
1213                                                 if(me.ias_mach_selected.getValue() == 1)
1214                                                 {
1215                                                         if(me.mach_setting.getValue() == me.FMC_descent_mach.getValue())
1216                                                         {
1217                                                                 if(getprop("instrumentation/airspeed-indicator/indicated-mach") < (me.FMC_descent_mach.getValue() + 0.015))
1218                                                                 {
1219                                                                         me.vnav_path_mode.setValue(1);          # VNAV PTH DESCEND VS
1220                                                                         me.target_alt.setValue(me.intervention_alt);
1221                                                                         me.vs_setting.setValue(-2000);
1222                                                                         me.descent_step += 1;
1223                                                                 }
1224                                                         }
1225                                                         else
1226                                                         {
1227                                                                 me.vnav_path_mode.setValue(1);          # VNAV PTH DESCEND VS
1228                                                                 me.target_alt.setValue(me.intervention_alt);
1229                                                                 me.vs_setting.setValue(-2000);
1230                                                                 me.descent_step += 1;
1231                                                         }
1232                                                 }
1233                                                 else
1234                                                 {
1235                                                         if(getprop("instrumentation/airspeed-indicator/indicated-speed-kt") < (me.FMC_descent_ias.getValue() + 15))
1236                                                         {
1237                                                                 me.vnav_path_mode.setValue(1);          # VNAV PTH DESCEND VS
1238                                                                 me.target_alt.setValue(me.intervention_alt);
1239                                                                 me.vs_setting.setValue(-2000);
1240                                                                 me.descent_step += 1;
1241                                                         }
1242                                                 }
1243                                         }
1244                                         elsif(me.descent_step == 2)
1245                                         {
1246                                                 if(me.ias_mach_selected.getValue() == 1)
1247                                                 {
1248                                                         if(getprop("instrumentation/airspeed-indicator/indicated-speed-kt") >= me.FMC_descent_ias.getValue())
1249                                                         {
1250                                                                 me.ias_mach_selected.setValue(0);
1251                                                                 me.ias_setting.setValue(me.FMC_descent_ias.getValue());
1252                                                                 me.descent_step += 1;
1253                                                         }
1254                                                         elsif((me.mach_setting.getValue() != me.FMC_descent_mach.getValue())
1255                                                                 and (Vcal(me.FMC_descent_mach.getValue()) > (getprop("instrumentation/weu/state/stall-speed") + 5)))
1256                                                         {
1257                                                                 me.mach_setting.setValue(me.FMC_descent_mach.getValue());
1258                                                         }
1259                                                 }
1260                                                 else
1261                                                 {
1262                                                         me.descent_step += 1;
1263                                                 }
1264                                         }
1265                                         elsif(me.descent_step == 3)
1266                                         {
1267                                                 if(current_alt < 29000)
1268                                                 {
1269                                                         me.vnav_path_mode.setValue(2);                  # VNAV PTH DESCEND FLCH
1270                                                         me.descent_step += 1;
1271                                                 }
1272                                         }
1273                                         elsif(me.descent_step == 4)
1274                                         {
1275                                                 if((current_alt < 12000)
1276                                                         and (me.ias_setting.getValue() > 250))
1277                                                 {
1278                                                         me.ias_setting.setValue(250);
1279                                                         me.descent_step += 1;
1280                                                 }
1281                                         }
1282                                         # flight level change mode
1283                                         if (abs(current_alt - me.intervention_alt) < offset)
1284                                         {
1285                                                 if(me.autothrottle_mode.getValue() != 0)
1286                                                 {
1287                                                         me.autothrottle_mode.setValue(5);       # A/T SPD
1288                                                 }
1289                                                 me.vs_setting.setValue(0);
1290                                                 me.vnav_path_mode.setValue(0);
1291                                                 if(current_alt > (getprop("autopilot/route-manager/destination/field-elevation-ft") + 4750))
1292                                                 {
1293                                                         idx = 5;        # VNAV ALT
1294                                                 }
1295                                         }
1296                                 }
1297                                 else
1298                                 {
1299                                         if(me.intervention_alt != me.FMC_cruise_alt.getValue())
1300                                         {
1301                                                 me.FMC_cruise_alt.setValue(me.intervention_alt);
1302                                                 if(me.intervention_alt <= me.optimal_alt)
1303                                                 {
1304                                                         me.target_alt.setValue(me.intervention_alt);
1305                                                 }
1306                                                 else
1307                                                 {
1308                                                         me.target_alt.setValue(me.optimal_alt);
1309                                                 }
1310                                                 idx = 4;        # VNAV SPD
1311                                         }
1312                                         if((me.mach_setting.getValue() >= me.FMC_cruise_mach.getValue())
1313                                                 and (me.ias_mach_selected.getValue() == 0))
1314                                         {
1315                                                 me.ias_mach_selected.setValue(1);
1316                                                 me.mach_setting.setValue(me.FMC_cruise_mach.getValue());
1317                                         }
1318                                         elsif((me.ias_setting.getValue() >= me.FMC_cruise_ias.getValue())
1319                                                 and (me.ias_mach_selected.getValue() == 1))
1320                                         {
1321                                                 me.ias_mach_selected.setValue(0);
1322                                                 me.ias_setting.setValue(me.FMC_cruise_ias.getValue());
1323                                         }
1324                                         elsif(me.ias_mach_selected.getValue() == 0)
1325                                         {
1326                                                 if(current_alt < 10000)
1327                                                 {
1328                                                         me.ias_setting.setValue(250);
1329                                                 }
1330                                                 else
1331                                                 {
1332                                                         me.ias_setting.setValue(me.FMC_cruise_ias.getValue());
1333                                                 }
1334                                         }
1335                                 }
1336                         }
1337                         elsif(idx == 4)         # VNAV SPD
1338                         {
1339                                 if(getprop("controls/flight/flaps") > 0)                # flaps down
1340                                 {
1341                                         me.ias_setting.setValue(getprop("instrumentation/weu/state/target-speed"));
1342                                 }
1343                                 elsif(current_alt < 10000)
1344                                 {
1345                                         me.ias_setting.setValue(250);
1346                                 }
1347                                 else
1348                                 {
1349                                         if((me.mach_setting.getValue() >= me.FMC_cruise_mach.getValue())
1350                                                 and (me.ias_mach_selected.getValue() == 0)
1351                                                 and (current_alt < me.target_alt.getValue()))
1352                                         {
1353                                                 me.ias_mach_selected.setValue(1);
1354                                                 me.mach_setting.setValue(me.FMC_cruise_mach.getValue());
1355                                         }
1356                                         elsif((me.ias_setting.getValue() >= me.FMC_cruise_ias.getValue())
1357                                                 and (me.ias_mach_selected.getValue() == 1)
1358                                                 and (current_alt > me.target_alt.getValue()))
1359                                         {
1360                                                 me.ias_mach_selected.setValue(0);
1361                                                 me.ias_setting.setValue(me.FMC_cruise_ias.getValue());
1362                                         }
1363                                         elsif(me.ias_mach_selected.getValue() == 0)
1364                                         {
1365                                                 if(current_alt < 10000)
1366                                                 {
1367                                                         me.ias_setting.setValue(250);
1368                                                 }
1369                                                 else
1370                                                 {
1371                                                         me.ias_setting.setValue(me.FMC_cruise_ias.getValue());
1372                                                 }
1373                                         }
1374                                 }
1375                                 if(me.altitude_restriction > 0)
1376                                 {
1377                                         me.target_alt.setValue(me.altitude_restriction);
1378                                 }
1379                                 elsif(me.intervention_alt >= me.optimal_alt)
1380                                 {
1381                                         if(me.FMC_cruise_alt.getValue() >= me.optimal_alt)
1382                                         {
1383                                                 me.target_alt.setValue(me.optimal_alt);
1384                                         }
1385                                         else
1386                                         {
1387                                                 me.target_alt.setValue(me.intervention_alt);
1388                                         }
1389                                 }
1390                                 else
1391                                 {
1392                                         me.target_alt.setValue(me.intervention_alt);
1393                                 }
1394                                 var offset = (abs(getprop("instrumentation/inst-vertical-speed-indicator/indicated-speed-fpm")) / 8);
1395                                 if(offset < 20)
1396                                 {
1397                                         offset = 20;
1398                                 }
1399                                 if (abs(current_alt
1400                                         - me.target_alt.getValue()) < offset)
1401                                 {
1402                                         if(abs(current_alt - me.FMC_cruise_alt.getValue()) < offset)
1403                                         {                       
1404                                                 # within target altitude: switch to VANV PTH mode
1405                                                 idx=3;
1406                                         }
1407                                         else
1408                                         {
1409                                                 idx=5;                          # VNAV ALT
1410                                         }
1411                                         if(me.autothrottle_mode.getValue() != 0)
1412                                         {
1413                                                 me.autothrottle_mode.setValue(5);       # A/T SPD
1414                                         }
1415                                         me.vs_setting.setValue(0);
1416                                 }
1417                         }
1418                         elsif(idx == 5)         # VNAV ALT
1419                         {
1420                                 if(me.vnav_descent.getValue())
1421                                 {
1422                                         if(me.intervention_alt < (current_alt - 500))
1423                                         {
1424                                                 idx = 3;                # VNAV PTH
1425                                                 me.descent_step = 0;
1426                                         }
1427                                 }
1428                                 elsif(me.altitude_restriction > 0)
1429                                 {
1430                                         if(current_alt < (me.altitude_restriction - 500))
1431                                         {
1432                                                 me.target_alt.setValue(me.altitude_restriction);
1433                                                 idx = 4;                # VNAV SPD
1434                                         }
1435                                 }
1436                                 elsif((current_alt <  (me.optimal_alt - 500))
1437                                         and (current_alt < (me.intervention_alt - 500)))
1438                                 {
1439                                         if(me.optimal_alt < me.intervention_alt)
1440                                         {
1441                                                 me.target_alt.setValue(me.optimal_alt);
1442                                         }
1443                                         else
1444                                         {
1445                                                 me.target_alt.setValue(me.intervention_alt);
1446                                         }
1447                                         idx = 4;                # VNAV SPD
1448                                 }
1449                         }
1450                         elsif(idx == 6)                         # G/S
1451                         {
1452                                 var f_angle = getprop("autopilot/constant/flare-base") * 135 / getprop("instrumentation/airspeed-indicator/indicated-speed-kt");
1453                                 me.flare_constant_setting.setValue(f_angle);
1454                                 if(getprop("position/gear-agl-ft") < 50)
1455                                 {
1456                                         me.flare_armed.setValue(0);
1457                                         idx = 7;                        # FLARE
1458                                 }
1459                                 elsif(me.AP.getValue() and (getprop("position/gear-agl-ft") < 1500))
1460                                 {
1461                                         me.rollout_armed.setValue(1);           # ROLLOUT
1462                                         me.flare_armed.setValue(1);                     # FLARE
1463                                         setprop("autopilot/settings/flare-speed-fps", 5);
1464                                 }
1465                         }
1466                         else
1467                         {
1468                                 if(me.autothrottle_mode.getValue() == 5)        # SPD
1469                                 {
1470                                         if(getprop("position/gear-agl-ft") < 50)
1471                                         {
1472                                                 me.autothrottle_mode.setValue(4);       # A/T IDLE
1473                                         }
1474                                         if(getprop("velocities/groundspeed-kt") < 30)
1475                                         {
1476                                                 if(!me.FD.getValue())
1477                                                 {
1478                                                         idx = 0;        # NO MODE
1479                                                 }
1480                                                 else
1481                                                 {
1482                                                         idx = 1;        # ALT
1483                                                 }
1484                                         }
1485                                 }
1486                         }
1487                         if((current_alt
1488                                 - getprop("autopilot/internal/airport-height")) > 400) # Take off mode and above baro 400 ft
1489                         {
1490                                 if(me.vnav_armed.getValue())
1491                                 {
1492                                         if(me.target_alt.getValue() == int(current_alt))
1493                                         {
1494                                                 if(me.FMC_cruise_alt.getValue() == int(current_alt))
1495                                                 {
1496                                                         idx = 3;                # VNAV PTH
1497                                                 }
1498                                                 else
1499                                                 {
1500                                                         idx = 5;                # VNAV ALT
1501                                                 }                                       
1502                                         }
1503                                         else
1504                                         {
1505                                                 idx = 4;                # VNAV SPD
1506                                         }
1507                                         me.intervention_alt = me.alt_setting.getValue();
1508                                         if(me.intervention_alt > me.FMC_cruise_alt.getValue())
1509                                         {
1510                                                 me.target_alt.setValue(me.FMC_cruise_alt.getValue());
1511                                         }
1512                                         else
1513                                         {
1514                                                 me.target_alt.setValue(me.intervention_alt);
1515                                         }
1516                                         me.vnav_armed.setValue(0);
1517                                 }
1518                         }
1519                         me.vertical_mode.setValue(idx);
1520                         if((me.AP_pitch_mode.getValue() != me.pitch_list[idx])
1521                                         and (idx > 0))
1522                         {
1523                                 setprop("autopilot/settings/pitch-transition", 1);
1524                                 settimer(func
1525                                 {
1526                                         setprop("autopilot/settings/pitch-transition", 0);
1527                                 }, 10);
1528                         }
1529                         me.AP_pitch_mode.setValue(me.pitch_list[idx]);
1530                         me.AP_pitch_engaged.setBoolValue(idx>0);
1531
1532                 }
1533                 elsif(me.step == 4)                     ### Auto Throttle mode control  ###
1534                 {
1535                         # Thrust reference rate calculation. This should be provided by FMC
1536                         var payload = getprop("consumables/fuel/total-fuel-lbs") + getprop("sim/weight[0]/weight-lb") + getprop("sim/weight[1]/weight-lb");
1537                         var derate = 0.3 - payload * 0.00000083;
1538                         if(me.ias_setting.getValue() < 251)
1539                         {
1540                                 var vflight_idle = (getprop("autopilot/constant/descent-profile-low-base")
1541                                         + (getprop("autopilot/constant/descent-profile-low-rate") * payload / 1000));
1542                         }
1543                         else
1544                         {
1545                                 var vflight_idle = (getprop("autopilot/constant/descent-profile-high-base")
1546                                         + (getprop("autopilot/constant/descent-profile-high-rate") * payload / 1000));
1547                         }
1548                         if(vflight_idle < 0.00) vflight_idle = 0.00;
1549                         me.flight_idle.setValue(vflight_idle);
1550                         # Thurst limit varis on altitude
1551                         var thrust_lmt = 0.96;
1552                         if(current_alt < 25000)
1553                         {
1554                                 if((me.vertical_mode.getValue() == 8)                   # FLCH SPD mode
1555                                         or(me.vertical_mode.getValue() == 4))           # VNAV SPD mode
1556                                 {
1557                                         if(me.vertical_mode.getValue() == 4)            # VNAV SPD mode
1558                                         {
1559                                                 thrust_lmt = derate / 25000 * abs(current_alt) + (0.95 - derate);
1560                                         }
1561                                         if(getprop("controls/flight/flaps") == 0)
1562                                         {
1563                                                 if(me.ias_mach_selected.getValue())
1564                                                 {
1565                                                         thrust_lmt *= (me.mach_setting.getValue() / 0.84);
1566                                                 }
1567                                                 else
1568                                                 {
1569                                                         thrust_lmt *= (me.ias_setting.getValue() / 320);
1570                                                 }
1571                                         }
1572                                         else
1573                                         {
1574                                                 thrust_lmt *= 0.78125;
1575                                         }
1576                                 }
1577                                 elsif(me.vertical_mode.getValue() != 2)                 # not V/S mode
1578                                 {
1579                                         thrust_lmt = derate / 25000 * abs(current_alt) + (0.95 - derate);
1580                                 }
1581                         }
1582                         me.thrust_lmt.setValue(thrust_lmt);
1583                         # IAS and MACH number update in back ground
1584                         var temp = 0;
1585                         if(me.ias_mach_selected.getValue() == 1)
1586                         {
1587                                 me.ias_setting.setValue(Vcal(me.mach_setting.getValue()));
1588                         }
1589                         else
1590                         {
1591                                 temp = (int(getprop("instrumentation/airspeed-indicator/indicated-mach")  * 1000 + 0.5) / 1000);
1592                                 me.mach_setting.setValue(temp);
1593                         }
1594                         # Auto throttle arm switch is offed
1595                         if((me.at1.getValue() == 0) or (me.at2.getValue() == 0))
1596                         {
1597                                 me.autothrottle_mode.setValue(0);
1598                                 setprop("autopilot/settings/speed-transition", 0);
1599                         }
1600                         # auto-throttle disengaged when reverser is enabled
1601                         elsif (getprop("controls/engines/engine/reverser"))
1602                         {
1603                                 me.autothrottle_mode.setValue(0);
1604                                 setprop("autopilot/settings/speed-transition", 0);
1605                         }
1606                         elsif(me.autothrottle_mode.getValue() == 2)             # THR REF
1607                         {
1608                                 if((getprop("instrumentation/airspeed-indicator/indicated-speed-kt") > 80)
1609                                         and ((current_alt - getprop("autopilot/internal/airport-height")) < 400))
1610                                 {
1611                                         me.autothrottle_mode.setValue(3);                       # HOLD
1612                                 }
1613                                 elsif((me.vertical_mode.getValue() != 3)                # not VNAV PTH
1614                                         and (me.vertical_mode.getValue() != 5))         # not VNAV ALT
1615                                 {
1616                                         if((getprop("controls/flight/flaps") == 0)              # FLAPs up
1617                                                 and (me.vertical_mode.getValue() != 4))         # not VNAV SPD
1618                                         {
1619                                                 me.autothrottle_mode.setValue(5);               # SPD
1620                                         }
1621                                         else
1622                                         {
1623                                                 setprop("controls/engines/engine[0]/throttle", thrust_lmt);
1624                                                 setprop("controls/engines/engine[1]/throttle", thrust_lmt);
1625                                         }
1626                                 }
1627                         }
1628                         elsif((me.autothrottle_mode.getValue() == 4)            # Auto throttle mode IDLE 
1629                                 and ((me.vertical_mode.getValue() == 8)                 # FLCH SPD mode
1630                                         or (me.vertical_mode.getValue() == 3))          # VNAV PTH mode
1631                                 and (int(me.flight_idle.getValue() * 1000) == int(getprop("controls/engines/engine[0]/throttle-act") * 1000))           # #1Thrust is actual flight idle
1632                                 and (int(me.flight_idle.getValue() * 1000) == int(getprop("controls/engines/engine[1]/throttle-act") * 1000)))          # #2Thrust is actual flight idle
1633                         {
1634                                 me.autothrottle_mode.setValue(3);                               # HOLD
1635                         }
1636                         # Take off mode and above baro 400 ft
1637                         elsif((current_alt - getprop("autopilot/internal/airport-height")) > 400)
1638                         {
1639                                 setprop("autopilot/locks/takeoff-mode", 0);
1640                                 if(me.autothrottle_mode.getValue() == 1)                # THR
1641                                 {
1642                                         setprop("controls/engines/engine[0]/throttle", thrust_lmt);
1643                                         setprop("controls/engines/engine[1]/throttle", thrust_lmt);
1644                                 }
1645                                 elsif((me.vertical_mode.getValue() == 10)               # TO/GA
1646                                         or ((me.autothrottle_mode.getValue() == 3)      # HOLD
1647                                         and (me.vertical_mode.getValue() != 8)           # not FLCH
1648                                                 and (me.vertical_mode.getValue() != 3)   # not VNAV PTH
1649                                                 and (me.vertical_mode.getValue() != 5))) # not VNAV ALT
1650                                 {
1651                                         if(getprop("controls/flight/flaps") == 0)
1652                                         {
1653                                                 me.autothrottle_mode.setValue(5);               # SPD
1654                                         }
1655                                         else
1656                                         {
1657                                                 me.autothrottle_mode.setValue(2);               # THR REF
1658                                         }
1659                                 }
1660                                 elsif(me.vertical_mode.getValue() == 4)                 # VNAV SPD
1661                                 {
1662                                         me.autothrottle_mode.setValue(2);                       # THR REF
1663                                 }
1664                                 elsif(me.vertical_mode.getValue() == 3)                 # VNAV PTH
1665                                 {
1666                                         if(me.vnav_path_mode.getValue() == 2)
1667                                         {
1668                                                 if(me.autothrottle_mode.getValue() != 3)
1669                                                 {
1670                                                         me.autothrottle_mode.setValue(4);       # IDLE
1671                                                 }
1672                                         }
1673                                         else
1674                                         {
1675                                                 me.autothrottle_mode.setValue(5);               # SPD
1676                                         }
1677                                 }
1678                                 elsif(me.vertical_mode.getValue() == 5)                 # VNAV ALT
1679                                 {
1680                                         me.autothrottle_mode.setValue(5);               # SPD
1681                                 }
1682                         }
1683                         elsif((getprop("position/gear-agl-ft") > 100)           # Approach mode and above 100 ft
1684                                         and (me.vertical_mode.getValue() == 6)) 
1685                         {
1686                                 me.autothrottle_mode.setValue(5);                               # SPD
1687                         }
1688                         idx = me.autothrottle_mode.getValue();
1689                         if((me.AP_speed_mode.getValue() != me.spd_list[idx])
1690                                         and (idx > 0))
1691                         {
1692                                 setprop("autopilot/settings/speed-transition", 1);
1693                                 settimer(func
1694                                 {
1695                                         setprop("autopilot/settings/speed-transition", 0);
1696                                 }, 10);
1697                         }
1698                         me.AP_speed_mode.setValue(me.spd_list[idx]);
1699                 }
1700                 elsif(me.step==5)                       #LNAV route calculation
1701                 {
1702                         var total_distance = getprop("autopilot/route-manager/total-distance");
1703                         var distance = total_distance - getprop("autopilot/route-manager/distance-remaining-nm");
1704                         var destination_elevation = getprop("autopilot/route-manager/destination/field-elevation-ft");
1705                         if (me.FMC_active.getValue())
1706                         {
1707                                 var max_wpt = getprop("autopilot/route-manager/route/num");
1708                                 var atm_wpt = me.FMC_current_wp.getValue();
1709                                 if(me.lateral_mode.getValue() == 3)             # Current mode is LNAV
1710                                 {
1711                                         if(atm_wpt < (max_wpt - 1))
1712                                         {
1713                                                 me.remaining_distance.setValue(getprop("autopilot/route-manager/wp/remaining-distance-nm")
1714                                                         + getprop("autopilot/route-manager/wp/dist"));
1715                                                 var next_course = getprop("autopilot/route-manager/wp[1]/bearing-deg");
1716                                         }
1717                                         else
1718                                         {
1719                                                 me.remaining_distance.setValue(getprop("autopilot/route-manager/wp/dist"));
1720                                         }
1721                                         if(me.vnav_descent.getValue() == 0)     # Calculation of Top Of Descent distance
1722                                         {
1723                                                 var cruise_alt = me.FMC_cruise_alt.getValue();
1724                                                 me.top_of_descent = 16;
1725                                                 if(cruise_alt > 10000)
1726                                                 {
1727                                                         me.top_of_descent += 21;
1728                                                         if(cruise_alt > 29000)
1729                                                         {
1730                                                                 me.top_of_descent += 41.8;
1731                                                                 if(cruise_alt > 36000)
1732                                                                 {
1733                                                                         me.top_of_descent += 28;
1734                                                                         me.top_of_descent += (cruise_alt - 36000) / 1000 * 3.8;
1735                                                                 }
1736                                                                 else
1737                                                                 {
1738                                                                         me.top_of_descent += (cruise_alt - 29000) / 1000 * 4;
1739                                                                 }
1740                                                         }
1741                                                         else
1742                                                         {
1743                                                                 me.top_of_descent += (cruise_alt - 10000) / 1000 * 2.2;
1744                                                         }
1745                                                         me.top_of_descent += 6.7;
1746                                                 }
1747                                                 else
1748                                                 {
1749                                                         me.top_of_descent += (cruise_alt - 3000) / 1000 * 3;
1750                                                 }
1751                                                 me.top_of_descent -= (destination_elevation / 1000 * 3);
1752                                                 if((me.alt_setting.getValue() > 24000)
1753                                                         and (me.alt_setting.getValue() >= cruise_alt))
1754                                                 {
1755                                                         if(me.remaining_distance.getValue() < (me.top_of_descent + 10))
1756                                                         {
1757                                                                 me.vnav_mcp_reset.setValue(1);
1758                                                                 copilot("Reset MCP ALT");
1759                                                         }
1760                                                 }
1761                                                 else
1762                                                 {
1763                                                         me.vnav_mcp_reset.setValue(0);
1764                                                         if(me.remaining_distance.getValue() < me.top_of_descent)
1765                                                         {
1766                                                                 me.vnav_descent.setValue(1);
1767                                                                 me.intervention_alt = me.alt_setting.getValue();
1768                                                         }
1769                                                 }
1770                                         }
1771                                 }
1772                                 
1773                                 var groundspeed = getprop("velocities/groundspeed-kt");
1774                                 var f= flightplan(); 
1775 #                               var topClimb = f.pathGeod(0, 100);
1776                                 var topDescent = f.pathGeod(-1, -me.top_of_descent);
1777                                 var targetCourse = f.pathGeod(-1, -me.remaining_distance.getValue());
1778                                 var leg = f.currentWP(); 
1779                                 if(leg == nil)
1780                                 {
1781                                         me.step+=1;
1782                                         if(me.step>6) me.step =0;
1783                                         return;
1784                                 }
1785                                 var enroute = leg.courseAndDistanceFrom(targetCourse);
1786                                 if(me.FMC_current_wp.getValue() == 0)
1787                                 {
1788                                         setprop("autopilot/internal/course-deg", getprop("orientation/heading-deg"));
1789                                 }
1790                                 else
1791                                 {
1792                                         setprop("autopilot/internal/course-deg", enroute[0]);
1793                                 }
1794
1795                                 var courseCoord = geo.Coord.new().set_latlon(targetCourse.lat, targetCourse.lon); 
1796                                 var geocoord = geo.aircraft_position(); 
1797                                 var CourseError = (geocoord.course_to(courseCoord) - getprop("orientation/heading-deg"));
1798                                 if(CourseError < -180) CourseError += 360;
1799                                 elsif(CourseError > 180) CourseError -= 360;
1800                                 if(CourseError > 0)
1801                                 {
1802                                         CourseError = geocoord.distance_to(courseCoord);
1803                                 }
1804                                 else
1805                                 {
1806                                         CourseError = (geocoord.distance_to(courseCoord) * -1);
1807                                 }
1808                                 var cCourseError = CourseError * 0.01;
1809                                 if(cCourseError > 4.0) cCourseError = 4.0;
1810                                 elsif(cCourseError < -4.0) cCourseError = -4.0;
1811                                 setprop("autopilot/internal/course-error", cCourseError);
1812
1813 #                               var tcNode = me.NDSymbols.getNode("tc", 1);
1814 #                               tcNode.getNode("longitude-deg", 1).setValue(topClimb.lon);
1815 #                               tcNode.getNode("latitude-deg", 1).setValue(topClimb.lat);
1816
1817                                 var tdNode = me.NDSymbols.getNode("td", 1);
1818                                 tdNode.getNode("longitude-deg", 1).setValue(topDescent.lon);
1819                                 tdNode.getNode("latitude-deg", 1).setValue(topDescent.lat);
1820                                 if(enroute[1] != nil)   # Course deg
1821                                 {
1822                                         var wpt_eta = (enroute[1] / groundspeed * 3600);
1823                                         var gmt = getprop("instrumentation/clock/indicated-sec");
1824                                         if((getprop("gear/gear[1]/wow") == 0) and (getprop("gear/gear[2]/wow") == 0))
1825                                         {
1826                                                 gmt += (wpt_eta + 30);
1827                                                 var gmt_hour = int(gmt / 3600);
1828                                                 if(gmt_hour > 24)
1829                                                 {
1830                                                         gmt_hour -= 24;
1831                                                         gmt -= 24 * 3600;
1832                                                 }
1833                                                 me.estimated_time_arrival.setValue(gmt_hour * 100 + int((gmt - gmt_hour * 3600) / 60));
1834                                                 var change_wp = abs(getprop("autopilot/route-manager/wp[1]/bearing-deg") - me.heading.getValue());
1835                                                 if(change_wp > 180) change_wp = (360 - change_wp);
1836                                                 if(((me.heading_change_rate * change_wp) > wpt_eta)
1837                                                         or (enroute[1] < 0.6))
1838                                                 {
1839                                                         if(atm_wpt < (max_wpt - 1))
1840                                                         {
1841                                                                 atm_wpt += 1;
1842                                                                 me.FMC_current_wp.setValue(atm_wpt);
1843                                                                 me.altitude_restriction = getprop("autopilot/route-manager/route/wp["~atm_wpt~"]/altitude-ft");
1844                                                                 if(me.altitude_restriction > 0)
1845                                                                 {
1846                                                                         me.altitude_restriction = int((me.altitude_restriction + 50) / 100 )* 100;
1847                                                                 }
1848                                                         }
1849                                                 }
1850                                         }
1851                                 }
1852                                 if((me.FMC_destination_ils.getValue() == 0)     #FMC autotune function
1853                                         and (me.lateral_mode.getValue() == 3))  #LNAV engaged
1854                                 {
1855                                         if((me.remaining_distance.getValue() < 150)
1856                                                 or (me.remaining_distance.getValue() < (me.top_of_descent + 50))
1857                                                 or (me.vnav_descent.getValue() == 1))
1858                                         {
1859                                                 var dist_run = flightplan().destination_runway;
1860                                                 if(dist_run != nil)
1861                                                 {
1862                                                         var freq = dist_run.ils_frequency_mhz;
1863                                                         if(freq != nil)
1864                                                         {
1865                                                                 setprop("instrumentation/nav/frequencies/standby-mhz", freq);
1866                                                                 b777.Efis.set_radio_mode(2);
1867                                                                 b777.Efis.swap_freq();
1868                                                                 me.FMC_destination_ils.setValue(1);
1869                                                         }
1870                                                 }
1871                                         }
1872                                 }
1873                                 if((distance > 400) or (distance > (total_distance / 2)))
1874                                 {
1875                                         me.FMC_landing_rwy_elevation.setValue(destination_elevation);
1876                                 }
1877                                 else
1878                                 {
1879                                         me.FMC_landing_rwy_elevation.setValue(getprop("autopilot/route-manager/departure/field-elevation-ft"));
1880                                 }
1881                         }
1882                         else
1883                         {
1884                                 if((distance == nil) or (total_distance == nil))
1885                                 {
1886                                         # Reset flag when not active
1887                                         if(me.FMC_destination_ils.getValue() == 1) me.FMC_destination_ils.setValue(0);
1888                                         me.FMC_landing_rwy_elevation.setValue(getprop("autopilot/route-manager/departure/field-elevation-ft"));
1889                                 }
1890                                 else
1891                                 {
1892                                         if((distance > 400) or (distance > (total_distance / 2)))
1893                                         {
1894                                                 me.FMC_landing_rwy_elevation.setValue(destination_elevation);
1895                                         }
1896                                         else
1897                                         {
1898                                                 # Reset flag when not active
1899                                                 if(me.FMC_destination_ils.getValue() == 1) me.FMC_destination_ils.setValue(0);
1900                                                 me.FMC_landing_rwy_elevation.setValue(getprop("autopilot/route-manager/departure/field-elevation-ft"));
1901                                         }
1902                                 }
1903                         }
1904                 }elsif(me.step==6)
1905                 {
1906                         if(getprop("controls/flight/flaps") == 0)
1907                         {
1908                                 me.auto_popup.setValue(0);
1909                         }
1910                         var ma_spd = getprop("instrumentation/airspeed-indicator/indicated-mach");
1911                         me.pfd_mach_ind.setValue(ma_spd * 1000);
1912                         me.pfd_mach_target.setValue(getprop("autopilot/settings/target-speed-mach") * 1000);
1913                         var banklimit = getprop("instrumentation/afds/inputs/bank-limit-switch");
1914                         if(banklimit==0)
1915                         {
1916                                 var lim = 0;
1917                                 me.heading_change_rate = 0;
1918                                 if(ma_spd > 0.85)
1919                                 {
1920                                         lim=5;
1921                                         me.heading_change_rate = 4.9 * 0.7;
1922                                 }
1923                                 elsif(ma_spd > 0.6666)
1924                                 {
1925                                         lim=10;
1926                                         me.heading_change_rate = 2.45 * 0.7;
1927                                 }
1928                                 elsif(ma_spd > 0.5)
1929                                 {
1930                                         lim=20;
1931                                         me.heading_change_rate = 1.125 * 0.7;
1932                                 }
1933                                 elsif(ma_spd > 0.3333)
1934                                 {
1935                                         lim=30;
1936                                         me.heading_change_rate = 0.625 * 0.7;
1937                                 }
1938                                 else
1939                                 {
1940                                         lim=35;
1941                                         me.heading_change_rate = 0.55 * 0.7;
1942                                 }
1943                                 props.globals.getNode("instrumentation/afds/settings/bank-max").setValue(lim);
1944                                 lim = -1 * lim;
1945                                 props.globals.getNode("instrumentation/afds/settings/bank-min").setValue(lim);
1946                         }
1947                 }
1948
1949                 me.step+=1;
1950                 if(me.step>6) me.step =0;
1951         },
1952 };
1953 #####################
1954
1955
1956 var afds = AFDS.new();
1957
1958         setlistener("sim/signals/fdm-initialized", func {
1959         settimer(update_afds,6);
1960 });
1961
1962 var update_afds = func {
1963         afds.ap_update();
1964         settimer(update_afds, 0);
1965 }