Fixed file modes.
[fg:toms-fgdata.git] / Aircraft / 777-200 / 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
34                 m.AFDS_node = props.globals.getNode("instrumentation/afds",1);
35                 m.AFDS_inputs = m.AFDS_node.getNode("inputs",1);
36                 m.AFDS_apmodes = m.AFDS_node.getNode("ap-modes",1);
37                 m.AFDS_settings = m.AFDS_node.getNode("settings",1);
38                 m.AP_settings = props.globals.getNode("autopilot/settings",1);
39
40                 m.AP = m.AFDS_inputs.initNode("AP",0,"BOOL");
41                 m.AP_disengaged = m.AFDS_inputs.initNode("AP-disengage",0,"BOOL");
42                 m.AP_passive = props.globals.initNode("autopilot/locks/passive-mode",1,"BOOL");
43                 m.AP_pitch_engaged = props.globals.initNode("autopilot/locks/pitch-engaged",1,"BOOL");
44                 m.AP_roll_engaged = props.globals.initNode("autopilot/locks/roll-engaged",1,"BOOL");
45
46                 m.FD = m.AFDS_inputs.initNode("FD",0,"BOOL");
47                 m.at1 = m.AFDS_inputs.initNode("at-armed[0]",0,"BOOL");
48                 m.at2 = m.AFDS_inputs.initNode("at-armed[1]",0,"BOOL");
49                 m.alt_knob = m.AFDS_inputs.initNode("alt-knob",0,"BOOL");
50                 m.autothrottle_mode = m.AFDS_inputs.initNode("autothrottle-index",0,"INT");
51                 m.lateral_mode = m.AFDS_inputs.initNode("lateral-index",0,"INT");
52                 m.vertical_mode = m.AFDS_inputs.initNode("vertical-index",0,"INT");
53                 m.gs_armed = m.AFDS_inputs.initNode("gs-armed",0,"BOOL");
54                 m.loc_armed = m.AFDS_inputs.initNode("loc-armed",0,"BOOL");
55                 m.vor_armed = m.AFDS_inputs.initNode("vor-armed",0,"BOOL");
56                 m.lnav_armed = m.AFDS_inputs.initNode("lnav-armed",0,"BOOL");
57                 m.vnav_armed = m.AFDS_inputs.initNode("vnav-armed",0,"BOOL");
58                 m.rollout_armed = m.AFDS_inputs.initNode("rollout-armed",0,"BOOL");
59                 m.flare_armed = m.AFDS_inputs.initNode("flare-armed",0,"BOOL");
60                 m.ias_mach_selected = m.AFDS_inputs.initNode("ias-mach-selected",0,"BOOL");
61                 m.hdg_trk_selected = m.AFDS_inputs.initNode("hdg-trk-selected",0,"BOOL");
62                 m.vs_fpa_selected = m.AFDS_inputs.initNode("vs-fpa-selected",0,"BOOL");
63                 m.bank_switch = m.AFDS_inputs.initNode("bank-limit-switch",0,"INT");
64
65                 m.ias_setting = m.AP_settings.initNode("target-speed-kt",200);# 100 - 399 #
66                 m.mach_setting = m.AP_settings.initNode("target-speed-mach",0.40);# 0.40 - 0.95 #
67                 m.vs_setting = m.AP_settings.initNode("vertical-speed-fpm",0); # -8000 to +6000 #
68                 m.hdg_setting = m.AP_settings.initNode("heading-bug-deg",360,"INT"); # 1 to 360
69                 m.fpa_setting = m.AP_settings.initNode("flight-path-angle",0); # -9.9 to 9.9 #
70                 m.alt_setting = m.AP_settings.initNode("counter-set-altitude-ft",10000,"DOUBLE");
71                 m.target_alt = m.AP_settings.initNode("actual-target-altitude-ft",10000,"DOUBLE");
72                 m.auto_brake_setting = m.AP_settings.initNode("autobrake",0.000,"DOUBLE");
73
74                 m.trk_setting = m.AFDS_settings.initNode("trk",0,"INT");
75                 m.vs_display = m.AFDS_settings.initNode("vs-display",0);
76                 m.fpa_display = m.AFDS_settings.initNode("fpa-display",0);
77                 m.bank_min = m.AFDS_settings.initNode("bank-min",-25);
78                 m.bank_max = m.AFDS_settings.initNode("bank-max",25);
79                 m.pitch_min = m.AFDS_settings.initNode("pitch-min",-10);
80                 m.pitch_max = m.AFDS_settings.initNode("pitch-max",15);
81                 m.vnav_alt = m.AFDS_settings.initNode("vnav-alt",35000);
82
83                 m.AP_roll_mode = m.AFDS_apmodes.initNode("roll-mode","TO/GA");
84                 m.AP_roll_arm = m.AFDS_apmodes.initNode("roll-mode-arm"," ");
85                 m.AP_pitch_mode = m.AFDS_apmodes.initNode("pitch-mode","TO/GA");
86                 m.AP_pitch_arm = m.AFDS_apmodes.initNode("pitch-mode-arm"," ");
87                 m.AP_speed_mode = m.AFDS_apmodes.initNode("speed-mode","");
88                 m.AP_annun = m.AFDS_apmodes.initNode("mode-annunciator"," ");
89
90                 m.APl = setlistener(m.AP, func m.setAP(),0,0);
91                 m.APdisl = setlistener(m.AP_disengaged, func m.setAP(),0,0);
92                 m.Lbank = setlistener(m.bank_switch, func m.setbank(),0,0);
93                 m.LTMode = setlistener(m.autothrottle_mode, func m.updateATMode(),0,0);
94                 m.WpChanged = setlistener(props.globals.getNode("/autopilot/route-manager/wp/id",1), func m.wpChanged(),0,0);
95                 m.RmDisabled = setlistener(props.globals.getNode("/autopilot/route-manager/active",1), func m.wpChanged(),0,0);
96                 return m;
97         },
98
99 ####  Inputs   ####
100 ###################
101         input : func(mode,btn)
102         {
103                 if(getprop("sim/model/start-idling"))
104                 {
105                         ind_alt = getprop("instrumentation/altimeter/indicated-altitude-ft");
106                         if((mode==0) and (me.FD.getValue()))
107                         {
108                                 # horizontal AP controls
109                                 if(btn == 1)            # Heading Sel button
110                                 {
111                                         if(getprop("position/gear-agl-ft") < 50)
112                                         {
113                                                 btn = me.lateral_mode.getValue();
114                                         }
115                                 }
116                                 elsif(btn == 2)         # Heading Hold button
117                                 {
118                                         # set target to current magnetic heading
119                                         var tgtHdg = int(getprop("orientation/heading-magnetic-deg") + 0.50);
120                                         if (tgtHdg==0) tgtHdg=360;
121                                         me.hdg_setting.setValue(tgtHdg);
122                                         if(getprop("position/gear-agl-ft") < 50)
123                                         {
124                                                 btn = me.lateral_mode.getValue();
125                                         }
126                                         else
127                                         {
128                                                 btn = 1;    # Heading sel
129                                         }
130                                 }
131                                 elsif(btn==3)           # LNAV button
132                                 {
133                                         if ((!getprop("/autopilot/route-manager/active"))or
134                                                 (getprop("/autopilot/route-manager/current-wp")<0)or
135                                                 (getprop("/autopilot/route-manager/wp/id")==""))
136                                         {
137                                                 # Oops, route manager isn't active. Keep current mode.
138                                                 btn = me.lateral_mode.getValue();
139                                                 copilot("Captain, LNAV doesn't engage. We forgot to program or activate the route manager!");
140                                         }
141                                         else
142                                         {
143                                                 if(me.lateral_mode.getValue() == 3)             # Current mode is LNAV
144                                                 {
145                                                         # set target to current magnetic heading
146                                                         var tgtHdg = int(getprop("orientation/heading-magnetic-deg") + 0.50);
147                                                         if (tgtHdg==0) tgtHdg=360;
148                                                         me.hdg_setting.setValue(tgtHdg);
149                                                         btn = 1;        # Heading sel
150                                                 }
151                                                 elsif(me.lnav_armed.getValue())
152                                                 {       # LNAV armed then disarm
153                                                         me.lnav_armed.setValue(0);
154                                                         btn = me.lateral_mode.getValue();
155                                                 }
156                                                 else
157                                                 {       # LNAV arm
158                                                         me.lnav_armed.setValue(1);
159                                                         btn = me.lateral_mode.getValue();
160                                                 }
161                                         }
162                                 }
163                                 me.lateral_mode.setValue(btn);
164                         }
165                         elsif(mode==1)
166                         {
167                                 # vertical AP controls
168                                 if (btn==1)
169                                 {
170                                         # hold current altitude
171                                         if(me.AP.getValue() or me.FD.getValue())
172                                         {
173                                                 var alt = int((ind_alt+50)/100)*100;
174                                                 me.alt_setting.setValue(alt);
175                                                 me.target_alt.setValue(alt);
176                                         }
177                                         else
178                                         {
179                                                 btn = 0;
180                                         }
181                                 }
182                                 if(btn==2)
183                                 {
184                                         # hold current vertical speed
185                                         var vs = getprop("instrumentation/inst-vertical-speed-indicator/indicated-speed-fpm");
186                                         vs = int(vs/100)*100;
187                                         if (vs<-8000) vs = -8000;
188                                         if (vs>6000) vs = 6000;
189                                         me.vs_setting.setValue(vs);
190                                         alt = me.alt_setting.getValue();
191                                         me.target_alt.setValue(alt);
192                                 }
193                                 if(btn==5)              # VNAV
194                                 {
195                                         if ((!getprop("/autopilot/route-manager/active"))or
196                                                 (getprop("/autopilot/route-manager/current-wp")<0)or
197                                                 (getprop("/autopilot/route-manager/wp/id")==""))
198                                         {
199                                                 # Oops, route manager isn't active. Keep current mode.
200                                                 btn = me.vertical_mode.getValue();
201                                                 copilot("Captain, VNAV doesn't engage. We forgot to program or activate the route manager!");
202                                         }
203                                         else
204                                         {
205                                                 vnav_mode = me.vertical_mode.getValue();
206                                                 if(vnav_mode == 3)                      # Current mode is VNAV PTH
207                                                 {
208                                                 }
209                                                 elsif(vnav_mode == 4)           # Current mode is VNAV SPD
210                                                 {
211                                                 }
212                                                 elsif(vnav_mode == 5)           # Current mode is VNAV ALT
213                                                 {
214                                                 }
215                                                 elsif(me.vnav_armed.getValue())
216                                                 {       # VNAV armed then disarm
217                                                         me.vnav_armed.setValue(0);
218                                                         btn = vnav_mode;
219                                                 }
220                                                 else
221                                                 {       # VNAV arm
222                                                         me.vnav_armed.setValue(1);
223                                                         btn = vnav_mode;
224                                                 }
225                                         }
226                                 }
227                                 if(btn==8)              # FLCH SPD
228                                 {
229                                         # change flight level
230                                         if(((ind_alt
231                                                 - getprop("autopilot/internal/airport-height")) < 400)
232                                                 or (me.at1.getValue() == 0) or (me.at2.getValue() == 0))
233                                         {
234                                                 btn = 0;
235                                         }
236                                         elsif(ind_alt < me.alt_setting.getValue())
237                                         {
238                                                 me.autothrottle_mode.setValue(1);       # A/T THR
239                                         }
240                                         else
241                                         {
242                                                 me.autothrottle_mode.setValue(4);       # A/T IDLE
243                                         }
244                                         alt = me.alt_setting.getValue();
245                                         me.target_alt.setValue(alt);
246                                 }
247                                 me.vertical_mode.setValue(btn);
248                         }
249                         elsif(mode == 2)
250                         {
251                                 # throttle AP controls
252                                 if(me.autothrottle_mode.getValue() != 0
253                                         or (me.at1.getValue() == 0) or (me.at2.getValue() == 0))
254                                 {
255                                         btn = 0;
256                                 }
257                                 elsif(btn == 2)         # TOGA
258                                 {
259                                         if((getprop("instrumentation/airspeed-indicator/indicated-speed-kt") > 50)
260                                                 or (getprop("/controls/flight/flaps") == 0))
261                                         {
262                                                 btn = 0;
263                                         }
264                                 }
265                                 elsif((ind_alt
266                                                 - getprop("autopilot/internal/airport-height")) < 400)
267                                 {
268                                         btn=0;
269                                         copilot("Captain, auto-throttle won't engage below 400ft.");
270                                 }
271                                 me.autothrottle_mode.setValue(btn);
272                         }
273                         elsif(mode==3)  #FD, LOC or G/S button
274                         {
275                                 if(btn == 2)    # FD button toggle
276                                 {
277                                         if(me.FD.getValue())
278                                         {
279                                                 me.lateral_mode.setValue(9);            # TOGA
280                                                 me.vertical_mode.setValue(10);          # TOGA
281                                         }
282                                         else
283                                         {
284                                                 me.lateral_mode.setValue(0);            # Clear
285                                                 me.vertical_mode.setValue(0);           # Clear
286                                         }
287                                 }
288                                 else
289                                 {
290                                         if (btn==1)     #APP button
291                                         {
292                                                 lgsmode = me.vertical_mode.getValue();
293                                                 if(lgsmode == 6)        # Already in G/S mode
294                                                 {
295                                                         me.vertical_mode.setValue(1);   # Keep current altitude
296                                                         me.gs_armed.setValue(0);                # Disarm
297                                                 }
298                                                 elsif(me.gs_armed.getValue())           # G/S armed but not captured yet
299                                                 {
300                                                         me.gs_armed.setValue(0);                # Disarm
301                                                 }
302                                                 else
303                                                 {
304                                                         me.gs_armed.setValue(1);                # G/S arm
305                                                 }
306                                         }
307                                         llocmode = me.lateral_mode.getValue();
308                                         if(llocmode == 4)               # Alrady in LOC mode
309                                         {
310                                                 # set target to current magnetic heading
311                                                 tgtHdg = int(getprop("orientation/heading-magnetic-deg") + 0.50);
312                                                 if (tgtHdg==0) tgtHdg=360;
313                                                 me.hdg_setting.setValue(tgtHdg);
314                                                 me.lateral_mode.setValue(2);            # Keep current headding
315                                                 me.loc_armed.setValue(0);                       # Disarm
316                                         }
317                                         elsif(me.loc_armed.getValue())                  # LOC armed but not captured yet
318                                         {
319                                                 if(!me.gs_armed.getValue())                     # G/S not armed
320                                                 {
321                                                         me.loc_armed.setValue(0);               # Disarm
322                                                 }
323                                         }
324                                         else
325                                         {
326                                                 me.loc_armed.setValue(1);                       # LOC arm
327                                         }
328                                 }
329                         }
330                 }
331         },
332 ###################
333         setAP : func{
334                 var output=1-me.AP.getValue();
335                 var disabled = me.AP_disengaged.getValue();
336                 if((output==0)and(getprop("position/gear-agl-ft")<200))
337                 {
338                         disabled = 1;
339                         copilot("Captain, autopilot won't engage below 200ft.");
340                 }
341                 if((disabled)and(output==0)){output = 1;me.AP.setValue(0);}
342                 if (output==1)
343                 {
344                         var msg="";
345                         var msg2="";
346                         var msg3="";
347                         if (abs(getprop("controls/flight/rudder-trim"))>0.04)   msg  = "rudder";
348                         if (abs(getprop("controls/flight/elevator-trim"))>0.04) msg2 = "pitch";
349                         if (abs(getprop("controls/flight/aileron-trim"))>0.04)  msg3 = "aileron";
350                         if (msg ~ msg2 ~ msg3 != "")
351                         {
352                                 if ((msg != "")and(msg2!=""))
353                                         msg = msg ~ ", " ~ msg2;
354                                 else
355                                         msg = msg ~ msg2;
356                                 if ((msg != "")and(msg3!=""))
357                                         msg = msg ~ " and " ~ msg3;
358                                 else
359                                         msg = msg ~ msg3;
360                                 copilot("Captain, autopilot disengaged. Careful, check " ~ msg ~ " trim!");
361                         }
362                 }
363                 else
364                         if(me.lateral_mode.getValue() != 3) me.input(0,1);
365                 setprop("autopilot/internal/target-pitch-deg",0);
366                 setprop("autopilot/internal/target-roll-deg",0);
367                 me.AP_passive.setValue(output);
368         },
369 ###################
370         setbank : func{
371                 var banklimit=me.bank_switch.getValue();
372                 var lmt=25;
373                 if(banklimit>0){lmt=banklimit * 5};
374                 me.bank_max.setValue(lmt);
375                 lmt = -1 * lmt;
376                 me.bank_min.setValue(lmt);
377         },
378 ###################
379         updateATMode : func()
380         {
381                 var idx=me.autothrottle_mode.getValue();
382                 me.AP_speed_mode.setValue(me.spd_list[idx]);
383         },
384 #################
385         wpChanged : func{
386                 if (((getprop("/autopilot/route-manager/wp/id")=="")or
387                         (!getprop("/autopilot/route-manager/active")))and
388                         (me.lateral_mode.getValue() == 3)and
389                         me.AP.getValue())
390                 {
391                         # LNAV active, but route manager is disabled now => switch to HDG HOLD (current heading)
392                         me.input(0,2);
393                 }
394         },
395 #################
396         ap_update : func{
397                 var VS =getprop("velocities/vertical-speed-fps");
398                 var TAS =getprop("velocities/uBody-fps");
399                 if(TAS < 10) TAS = 10;
400                 if(VS < -200) VS=-200;
401                 if (abs(VS/TAS)<=1)
402                 {
403                         var FPangle = math.asin(VS/TAS);
404                         FPangle *=90;
405                         setprop("autopilot/internal/fpa",FPangle);
406                 }
407                 var msg=" ";
408                 if(me.FD.getValue())
409                 {
410                         msg="FLT DIR";
411                 }
412                 if(me.AP.getValue())
413                 {
414                         msg="A/P";
415                         if(me.rollout_armed.getValue())
416                         {
417                                 msg="LAND 3";
418                         }
419                 }
420                 me.AP_annun.setValue(msg);
421                 var tmp = abs(me.vs_setting.getValue());
422                 me.vs_display.setValue(tmp);
423                 tmp = abs(me.fpa_setting.getValue());
424                 me.fpa_display.setValue(tmp);
425                 msg="";
426                 var hdgoffset = me.hdg_setting.getValue()-getprop("orientation/heading-magnetic-deg");
427                 if(hdgoffset < -180) hdgoffset +=360;
428                 if(hdgoffset > 180) hdgoffset +=-360;
429                 setprop("autopilot/internal/fdm-heading-bug-error-deg",hdgoffset);
430
431                 if(me.step==0){ ### glideslope armed ?###
432                         msg="";
433                         if(me.gs_armed.getValue())
434                         {
435                                 msg="G/S";
436                                 var gsdefl = getprop("instrumentation/nav/gs-needle-deflection");
437                                 var gsrange = getprop("instrumentation/nav/gs-in-range");
438                                 if ((gsdefl< 0.5 and gsdefl>-0.5)and
439                                         gsrange)
440                                 {
441                                         me.vertical_mode.setValue(6);
442                                         me.gs_armed.setValue(0);
443                                 }
444                         }
445                         elsif(me.flare_armed.getValue())
446                         {
447                                 msg="FLARE";
448                         }
449                         elsif(me.vnav_armed.getValue())
450                         {
451                                 msg = "VNAV";
452                         }
453                         me.AP_pitch_arm.setValue(msg);
454
455                 }elsif(me.step==1){ ### localizer armed ? ###
456                         msg="";
457                         if(me.loc_armed.getValue())
458                         {
459                                 msg="LOC";
460                                 if (getprop("instrumentation/nav/signal-quality-norm") > 0.9)
461                                 {
462                                         var hddefl = getprop("instrumentation/nav/heading-needle-deflection");
463                                         var vtemp = 9.9;
464                                         if(!getprop("instrumentation/nav/nav-loc"))
465                                         {
466                                                 var vspeed = getprop("instrumentation/airspeed-indicator/indicated-speed-kt");
467                                                 var vcourse = getprop("instrumentation/nav/heading-deg");
468                                                 var vdistance = getprop("instrumentation/nav/nav-distance");
469                                                 vtemp = getprop("orientation/heading-deg");
470                                                 vcourse = abs(vcourse - vtemp);
471                                                 if (vcourse <= 90)
472                                                         vtemp = vcourse*vspeed*vdistance/(10*200*1852*15);
473                                                 if(vtemp > 9.9)
474                                                         vtemp = 9.9;
475                                         }
476
477                                         if(abs(hddefl) < vtemp)
478                                         {
479                                                 me.lateral_mode.setValue(4);
480                                                 me.loc_armed.setValue(0);
481                                         }
482                                 }
483                         }
484                         elsif(me.lnav_armed.getValue())
485                         {
486                                 if(getprop("position/gear-agl-ft") > 50)
487                                 {
488                                         msg = "";
489                                         me.lnav_armed.setValue(0);              # Clear
490                                         me.lateral_mode.setValue(3);    # LNAV
491                                 }
492                                 else
493                                 {
494                                         msg = "LNAV";
495                                 }
496                         }
497                         elsif(me.rollout_armed.getValue())
498                         {
499                                 msg = "ROLLOUT";
500                         }
501                         me.AP_roll_arm.setValue(msg);
502
503                 }elsif(me.step==2){ ### check lateral modes  ###
504                         var idx=me.lateral_mode.getValue();
505                         if ((idx == 1) or (idx == 2))
506                         {
507                                 if(getprop("position/gear-agl-ft") > 50)
508                                 {
509                                         # switch between HDG SEL to HDG HOLD
510                                         if (abs(getprop("orientation/heading-magnetic-deg")-me.hdg_setting.getValue())<2)
511                                                 idx = 2; # HDG HOLD
512                                         else
513                                                 idx = 1; # HDG SEL
514                                 }
515                         }
516                         elsif(idx == 4)         # LOC
517                         {
518                                 if((me.rollout_armed.getValue())
519                                         and (getprop("position/gear-agl-ft") < 5))
520                                 {
521                                         me.rollout_armed.setValue(0);
522                                         idx = 5;        # ROLLOUT
523                                 }
524                         }
525                         me.lateral_mode.setValue(idx);
526                         me.AP_roll_mode.setValue(me.roll_list[idx]);
527                         me.AP_roll_engaged.setBoolValue(idx>0);
528
529                 }elsif(me.step==3){ ### check vertical modes  ###
530                         if(getprop("instrumentation/airspeed-indicator/indicated-speed-kt") < 100)
531                         {
532                                 setprop("autopilot/internal/airport-height", getprop("instrumentation/altimeter/indicated-altitude-ft"));
533                         }
534                         var idx=me.vertical_mode.getValue();
535                         var test_fpa=me.vs_fpa_selected.getValue();
536                         if(idx==2 and test_fpa)idx=9;
537                         if(idx==9 and !test_fpa)idx=2;
538                         if ((idx==8)or(idx==1)or(idx==2)or(idx==9))
539                         {
540                                 # flight level change mode
541                                 if (abs(getprop("instrumentation/altimeter/indicated-altitude-ft")-me.target_alt.getValue()) < 200)
542                                 {
543                                         # within target altitude: switch to ALT HOLD mode
544                                         idx=1;
545                                         if(me.autothrottle_mode.getValue() != 0)
546                                         {
547                                                 me.autothrottle_mode.setValue(5);       # A/T SPD
548                                         }
549                                         me.vs_setting.setValue(0);
550                                 }
551                                 if((me.mach_setting.getValue() >= 0.840)
552                                         and (me.ias_mach_selected.getValue() == 0)
553                                         and (getprop("instrumentation/altimeter/indicated-altitude-ft") < me.target_alt.getValue()))
554                                 {
555                                         me.ias_mach_selected.setValue(1);
556                                         me.mach_setting.setValue(0.840);
557                                 }
558                                 elsif((me.ias_setting.getValue() >= 310)
559                                         and (me.ias_mach_selected.getValue() == 1)
560                                         and (getprop("instrumentation/altimeter/indicated-altitude-ft") > me.target_alt.getValue()))
561                                 {
562                                         me.ias_mach_selected.setValue(0);
563                                         me.ias_setting.setValue(310);
564                                 }
565                         }
566                         elsif(idx == 3)         # VNAV PATH
567                         {
568                                 if((me.mach_setting.getValue() > 0.841)
569                                         and (me.ias_mach_selected.getValue() == 0))
570                                 {
571                                         me.ias_mach_selected.setValue(1);
572                                         me.mach_setting.setValue(0.840);
573                                 }
574                                 elsif((me.ias_setting.getValue() > 321)
575                                         and (me.ias_mach_selected.getValue() == 1))
576                                 {
577                                         me.ias_mach_selected.setValue(0);
578                                         me.ias_setting.setValue(320);
579                                 }
580                                 elsif(me.ias_mach_selected.getValue() == 0)
581                                 {
582                                         if(getprop("instrumentation/altimeter/indicated-altitude-ft") < 10000)
583                                         {
584                                                 me.ias_setting.setValue(250);
585                                         }
586                                         else
587                                         {
588                                                 me.ias_setting.setValue(320);
589                                         }
590                                 }
591                         }
592                         elsif(idx == 4)         # VNAV SPD
593                         {
594                                 if(getprop("/controls/flight/flaps") > 0.033)           # flaps 5
595                                 {
596                                         me.ias_setting.setValue(180);
597                                 }
598                                 elsif(getprop("/controls/flight/flaps") > 0)            # flaps 1
599                                 {
600                                         me.ias_setting.setValue(195);
601                                 }
602                                 elsif(getprop("instrumentation/altimeter/indicated-altitude-ft") < 2000)
603                                 {
604                                         me.ias_setting.setValue(210);
605                                 }
606                                 elsif(getprop("instrumentation/altimeter/indicated-altitude-ft") < 10000)
607                                 {
608                                         me.ias_setting.setValue(250);
609                                 }
610                                 else
611                                 {
612                                         if((me.mach_setting.getValue() >= 0.840)
613                                                 and (me.ias_mach_selected.getValue() == 0)
614                                                 and (getprop("instrumentation/altimeter/indicated-altitude-ft") < me.target_alt.getValue()))
615                                         {
616                                                 me.ias_mach_selected.setValue(1);
617                                                 me.mach_setting.setValue(0.840);
618                                         }
619                                         elsif((me.ias_setting.getValue() >= 310)
620                                                 and (me.ias_mach_selected.getValue() == 1)
621                                                 and (getprop("instrumentation/altimeter/indicated-altitude-ft") > me.target_alt.getValue()))
622                                         {
623                                                 me.ias_mach_selected.setValue(0);
624                                                 me.ias_setting.setValue(310);
625                                         }
626                                         elsif(me.ias_mach_selected.getValue() == 0)
627                                         {
628                                                 if(getprop("instrumentation/altimeter/indicated-altitude-ft") < 10000)
629                                                 {
630                                                         me.ias_setting.setValue(250);
631                                                 }
632                                                 else
633                                                 {
634                                                         me.ias_setting.setValue(320);
635                                                 }
636                                         }
637                                 }
638                                 me.alt_setting.setValue(getprop("autopilot/route-manager/cruise/altitude-ft"));
639                                 me.target_alt.setValue(me.alt_setting.getValue());
640                                 if (abs(getprop("instrumentation/altimeter/indicated-altitude-ft")
641                                         - me.alt_setting.getValue()) < 200)
642                                 {
643                                         # within target altitude: switch to VANV PTH mode
644                                         idx=3;
645                                         if(me.autothrottle_mode.getValue() != 0)
646                                         {
647                                                 me.autothrottle_mode.setValue(5);       # A/T SPD
648                                         }
649                                         me.vs_setting.setValue(0);
650                                 }
651                         }
652                         elsif(idx == 6)
653                         {
654                                 if((getprop("position/gear-agl-ft") < 50)
655                                         and (me.flare_armed.getValue()))
656                                 {
657                                         me.flare_armed.setValue(0);
658                                         idx = 7;
659                                 }
660                                 elsif(getprop("position/gear-agl-ft") < 1500)
661                                 {
662                                         me.rollout_armed.setValue(1);           # ROLLOUT
663                                         me.flare_armed.setValue(1);                     # FLARE
664                                         setprop("autopilot/settings/flare-speed-fps", 0);
665                                 }
666                         }
667                         elsif(idx == 7)
668                         {
669                                 if(me.autothrottle_mode.getValue())
670                                 {
671                                         if(getprop("position/gear-agl-ft") < 25)
672                                         {
673                                                 me.autothrottle_mode.setValue(4);       # A/T IDLE
674                                         }
675                                 }
676                         }
677                         if((getprop("instrumentation/altimeter/indicated-altitude-ft")
678                                 - getprop("autopilot/internal/airport-height")) > 400) # Take off mode and above baro 400 ft
679                         {
680                                 if(me.vnav_armed.getValue())
681                                 {
682                                         if(me.alt_setting.getValue() == int(getprop("instrumentation/altimeter/indicated-altitude-ft")))
683                                         {
684                                                 idx = 3;                # VNAV PTH
685                                         }
686                                         else
687                                         {
688                                                 idx = 4;                # VNAV SPD
689                                         }
690                                         me.vnav_armed.setValue(0);
691                                 }
692                         }
693                         me.vertical_mode.setValue(idx);
694                         me.AP_pitch_mode.setValue(me.pitch_list[idx]);
695                         me.AP_pitch_engaged.setBoolValue(idx>0);
696
697                 }
698                 elsif(me.step==4)                       ### Auto Throttle mode control  ###
699                 {
700                         derate = getprop("consumables/fuel/total-fuel-lbs") + getprop("/sim/weight[0]/weight-lb") + getprop("/sim/weight[1]/weight-lb");
701                         derate = 0.3 - derate * 0.00000083;
702                         if(me.ias_mach_selected.getValue() == 1)
703                         {
704                                 temp = int(getprop("instrumentation/airspeed-indicator/indicated-speed-kt"));
705                                 me.ias_setting.setValue(temp);
706                         }
707                         else
708                         {
709                                 temp = (int(getprop("instrumentation/airspeed-indicator/indicated-mach") * 1000) / 1000);
710                                 me.mach_setting.setValue(temp);
711                         }
712                         ind_alt = getprop("instrumentation/altimeter/indicated-altitude-ft");
713                         if((me.at1.getValue() == 0) or (me.at2.getValue() == 0))
714                         {
715                                 me.autothrottle_mode.setValue(0);
716                         }
717                         elsif (getprop("controls/engines/engine/reverser"))
718                         {
719                                 # auto-throttle disables when reverser is enabled
720                                 me.autothrottle_mode.setValue(0);
721                         }
722                         elsif((me.autothrottle_mode.getValue() == 2)            # THR REF
723                                 and (me.vertical_mode.getValue() != 3)
724                                 and (me.vertical_mode.getValue() != 5))
725                         {
726                                 if((getprop("/controls/flight/flaps") == 0)
727                                         and (me.vertical_mode.getValue() != 4))
728                                 {
729                                         me.autothrottle_mode.setValue(5);               # SPD
730                                 }
731                                 else
732                                 {
733                                         if(ind_alt < 35000)
734                                         {
735                                                 thrust_lmt = derate / 35000 * abs(ind_alt) + (0.95 - derate);
736                                         }
737                                         else
738                                         {
739                                                 thrust_lmt = 0.96;
740                                         }
741                                         setprop("/controls/engines/engine[0]/throttle", thrust_lmt);
742                                         setprop("/controls/engines/engine[1]/throttle", thrust_lmt);
743                                 }
744                                         
745                         }
746                         elsif((ind_alt
747                                 - getprop("autopilot/internal/airport-height")) > 400) # Take off mode and above baro 400 ft
748                         {
749                                 if(me.autothrottle_mode.getValue() == 1)                # THR
750                                 {
751                                         if(ind_alt < 35000)
752                                         {
753                                                 thrust_lmt = derate / 35000 * abs(ind_alt) + (0.95 - derate);
754                                         }
755                                         else
756                                         {
757                                                 thrust_lmt = 0.96;
758                                         }
759                                         setprop("/controls/engines/engine[0]/throttle", thrust_lmt);
760                                         setprop("/controls/engines/engine[1]/throttle", thrust_lmt);
761                                 }
762                                 elsif((me.vertical_mode.getValue() == 0)
763                                         or (me.autothrottle_mode.getValue() == 3))      # HOLD
764                                 {
765                                         if(getprop("/controls/flight/flaps") == 0)
766                                         {
767                                                 me.autothrottle_mode.setValue(5);               # SPD
768                                         }
769                                         else
770                                         {
771                                                 me.autothrottle_mode.setValue(2);               # THR REF
772                                         }
773                                 }
774                                 elsif(me.vertical_mode.getValue() == 4)                 # VNAV SPD
775                                 {
776                                         me.autothrottle_mode.setValue(2);                       # THR REF
777                                 }
778                                 elsif(me.vertical_mode.getValue() == 3)                 # VNAV PATH
779                                 {
780                                         me.autothrottle_mode.setValue(5);                       # SPD
781                                 }
782                         }
783                         elsif((getprop("position/gear-agl-ft") > 100)           # Approach mode and above 100 ft
784                                         and (me.vertical_mode.getValue() == 6)) 
785                         {
786                                 me.autothrottle_mode.setValue(5);                               # SPD
787                         }
788                         elsif((getprop("instrumentation/airspeed-indicator/indicated-speed-kt") > 80)
789                                 and (me.autothrottle_mode.getValue() == 2))
790                         {
791                                 me.autothrottle_mode.setValue(3);                               # HOLD
792                         }
793                         elsif((me.autothrottle_mode.getValue() == 4)            # Auto throttle mode IDLE 
794                                 and (me.vertical_mode.getValue() == 8)                  # FLCH SPD mode
795                                 and (getprop("controls/engines/engine[0]/throttle") < 0.13)                     # #1Thrust is actual flight idle
796                                 and (getprop("controls/engines/engine[1]/throttle") < 0.13))            # #2Thrust is actual flight idle
797                         {
798                                 me.autothrottle_mode.setValue(3);                               # HOLD
799                         }
800                         idx = me.autothrottle_mode.getValue();
801                         me.AP_speed_mode.setValue(me.spd_list[idx]);
802                 }
803                 elsif(me.step==5)
804                 {
805                         if (getprop("/autopilot/route-manager/active")){
806                                 max_wpt=getprop("/autopilot/route-manager/route/num");
807                                 atm_wpt=getprop("/autopilot/route-manager/current-wp");
808                                 wpt_distance = getprop("/autopilot/route-manager/wp/dist");
809                                 if(wpt_distance == nil) wpt_distance = 36000;
810                                 max_wpt-=1;
811                                 if(wpt_distance < (5 * getprop("/instrumentation/airspeed-indicator/indicated-mach")))
812                                 {
813                                         if (getprop("/autopilot/route-manager/current-wp")<=max_wpt){
814                                                 atm_wpt+=1;
815                                                 props.globals.getNode("/autopilot/route-manager/current-wp").setValue(atm_wpt);
816                                         }
817                                 }
818                         }
819                 }elsif(me.step==6){
820                         ma_spd=getprop("/instrumentation/airspeed-indicator/indicated-mach");
821                         banklimit=getprop("/instrumentation/afds/inputs/bank-limit-switch");
822                         if(banklimit==0)
823                         {
824                                 if(ma_spd > 0.85)
825                                 {
826                                         lim=5;
827                                 }
828                                 elsif(ma_spd > 0.6666)
829                                 {
830                                         lim=10;
831                                 }
832                                 elsif(ma_spd > 0.5)
833                                 {
834                                         lim=20;
835                                 }
836                                 elsif(ma_spd > 0.3333)
837                                 {
838                                         lim=30;
839                                 }
840                                 else
841                                 {
842                                         lim=35;
843                                 }
844                                 props.globals.getNode("/instrumentation/afds/settings/bank-max").setValue(lim);
845                                 lim = -1 * lim;
846                                 props.globals.getNode("/instrumentation/afds/settings/bank-min").setValue(lim);
847                         }
848                 }
849
850                 me.step+=1;
851                 if(me.step>6)me.step =0;
852         },
853 };
854 #####################
855
856
857 var afds = AFDS.new();
858
859 setlistener("/sim/signals/fdm-initialized", func {
860         settimer(update_afds,6);
861         print("AFDS System ... check");
862 });
863
864 var update_afds = func {
865         afds.ap_update();
866         settimer(update_afds, 0);
867 }