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