zkv1000 / Nasal / afcs.nas /
Newer Older
416 lines | 19.734kb
adds AFCS
Sébastien MARQUE authored on 2020-05-06
1
var APClass = {
2
    new : func {
3
        var m = { parents: [ APClass ] };
4

            
5
        m.system = 'none';
6
        var ap_systems = { # described AP systems to search, if it returns true system is set
autopilot S-TEC 55X integrat...
Sébastien MARQUE authored on 2020-05-06
7
            STEC55X: func contains(stec55x, 'ITAF'),
creates entry point for GFC7...
Sébastien MARQUE authored on 2020-05-16
8
            GFC700: func props.globals.getNode('/autopilot/GFC700/FSM/lateral').getPath(),
add KAP140 to afcs
Sébastien MARQUE authored on 2021-03-24
9
            KAP140: func contains(kap140, 'apButton'),
adds AFCS
Sébastien MARQUE authored on 2020-05-06
10
        };
11
        foreach (var s; sort(keys(ap_systems), func(a,b) cmp(a,b))) {
12
            call(ap_systems[s], [], nil, nil, var errors = []);
13
            if (!size(errors)) {
14
                msg('found autopilot system: ' ~ s);
15
                m.system = s;
16
                break;
17
            }
18
        }
19

            
20
        m.engaged = 0;
21

            
22
        if (! contains(data.timers, 'updateAP')) {
23
            data.timers.updateAP = maketimer(1, m, m.systems[m.system].updateDisplay);
24
            data.timers.updateAP.start();
25
        }
26

            
autopilot status with separa...
Sébastien MARQUE authored on 2020-05-08
27
        var ap_annun = [
28
            'LATMOD-Armed-text',  'LATMOD-Active-text',
29
            'AP-Status-text',     'YD-Status-text',
30
            'VERMOD-Active-text', 'VERMOD-Reference-text', 'VERMOD-Armed-text'
31
        ];
show AP infos on MFDs if the...
Sébastien MARQUE authored on 2021-03-22
32

            
33
        var terminal_count = { PFD: 0, MFD: 0 };
34
        m.terminals = [];
35
        foreach (var name; keys(flightdeck)) {
36
            terminal_count[flightdeck[name].role] += 1;
37
            if (flightdeck[name].role == 'PFD')
38
                append(m.terminals, name);
39
        }
40

            
41
        if (terminal_count.PFD == 0 and terminal_count.MFD > 0) {
42
            foreach (var name; keys(flightdeck)) {
43
                if (flightdeck[name].role == 'MFD') {
44
                    append(m.terminals, name);
45
                    flightdeck[name].display.loadGroup({text: ap_annun});
46
                }
47
            }
48
        }
49

            
50
        foreach (var terminal; m.terminals) {
51
            foreach (var elem; ap_annun) {
52
                var color = (elem == 'LATMOD-Armed-text' or elem == 'VERMOD-Armed-text') ? 'white' : 'green';
53
                flightdeck[terminal].display.screenElements[elem]
54
                    .setColor(flightdeck[terminal].display.colors[color])
55
                    .setVisible(0);
56
            }
57
            foreach (var ap; [ 'AP', 'YD' ])
58
                flightdeck[terminal].display.screenElements[ap ~ '-Status-text']
59
                    .setDrawMode(canvas.Text.TEXT + canvas.Text.FILLEDBOUNDINGBOX)
60
                    .setColorFill(flightdeck[terminal].display.colors.black)
61
                    .setText(ap);
autopilot status with separa...
Sébastien MARQUE authored on 2020-05-08
62
        }
63

            
64
        ap_annun = nil;
65
        ap_systems = nil;
show AP infos on MFDs if the...
Sébastien MARQUE authored on 2021-03-22
66
        terminal_count = nil;
delete unused afcs systems
Sébastien MARQUE authored on 2020-05-16
67
        # delete unused systems
68
        foreach (var e; keys(m.systems))
69
            if (e != m.system)
70
                delete(m.systems, e);
autopilot status with separa...
Sébastien MARQUE authored on 2020-05-08
71

            
adds AFCS
Sébastien MARQUE authored on 2020-05-06
72
        if (contains(m.systems[m.system], 'hook') and typeof(m.systems[m.system].hook) == 'func')
show AP infos on MFDs if the...
Sébastien MARQUE authored on 2021-03-22
73
            m.systems[m.system].hook();
adds AFCS
Sébastien MARQUE authored on 2020-05-06
74

            
75
        return m;
76
    },
77
    softkey: func (side, row, a) {
little fixes
Sébastien MARQUE authored on 2020-05-11
78
        if (a)
adds AFCS
Sébastien MARQUE authored on 2020-05-06
79
            return;
afcs improvements
Sébastien MARQUE authored on 2020-05-17
80
        call(me.systems[me.system][side][row], [], autopilot.parents[0].systems[me.system]);
adds AFCS
Sébastien MARQUE authored on 2020-05-06
81
    },
82
    systems : {
83
        # L: AP FD  NAV ALT VS FLC
84
        # R: YD HDG APR VNV UP DN
85
        none: {
86
            updateDisplay: func,
87
            hook: func,
88
            L: [ func, func, func, func, func, func ],
89
            R: [ func, func, func, func, func, func ],
90
        },
creates entry point for GFC7...
Sébastien MARQUE authored on 2020-05-16
91
        GFC700: {
integration of GFC700 capabi...
Sébastien MARQUE authored on 2020-05-17
92
# Many thanks to the great work on the FG1000
93
            _blink_count: 0,
94
            updateDisplay: func {
improve and fix afcs for mul...
Sébastien MARQUE authored on 2021-03-24
95
                var annunciator = props.globals.getNode('/autopilot/annunciator');
96
                var ap_enabled  = annunciator.getValue('autopilot-enabled');
97

            
98
                var latmod         = annunciator.getValue('lateral-mode');
99
                var latmod_armed   = annunciator.getValue('lateral-mode-armed');
100
                var vertmod        = annunciator.getValue('vertical-mode');
101
                var vertmod_armed  = annunciator.getValue('vertical-mode-armed');
102
                var vertmod_target = annunciator.getValue('vertical-mode-target');
103
                if (vertmod_target != nil) {
104
                    vertmod_target = string.replace(vertmod_target, '+', utf8.chstr(9650));
105
                    vertmod_target = string.replace(vertmod_target, '-', utf8.chstr(9660));
106
                }
show AP infos on MFDs if the...
Sébastien MARQUE authored on 2021-03-22
107
                foreach (var terminal; me.terminals) {
108
                    var se = flightdeck[terminal].display.screenElements;
integration of GFC700 capabi...
Sébastien MARQUE authored on 2020-05-17
109

            
show AP infos on MFDs if the...
Sébastien MARQUE authored on 2021-03-22
110
                    se['LATMOD-Active-text'].setVisible(latmod != nil and ap_enabled).setText(latmod);
111
                    se['LATMOD-Armed-text'].setVisible(latmod_armed != nil and ap_enabled).setText(latmod_armed);
112
                    se['VERMOD-Active-text'].setVisible(vertmod != nil and ap_enabled).setText(vertmod);
113
                    se['VERMOD-Reference-text'].setVisible(vertmod_target != nil and ap_enabled).setText(vertmod_target);
114
                    se['VERMOD-Armed-text'].setVisible(vertmod_armed != nil and ap_enabled).setText(vertmod_armed);
115

            
116
                    if (se['AP-Status-text'].getVisible() and !ap_enabled) {
117
                        if (math.mod(me._blink_count,2))
118
                            se['AP-Status-text']
119
                                .setDrawMode(canvas.Text.TEXT + canvas.Text.FILLEDBOUNDINGBOX)
120
                                .setColorFill(flightdeck[terminal].display.colors.yellow)
121
                                .setColor(flightdeck[terminal].display.colors.black);
122
                        else
123
                            se['AP-Status-text']
124
                                .setDrawMode(canvas.Text.TEXT + canvas.Text.FILLEDBOUNDINGBOX)
125
                                .setColorFill(flightdeck[terminal].display.colors.black)
126
                                .setColor(flightdeck[terminal].display.colors.yellow);
127
                        me._blink_count += 1;
128
                        if (me._blink_count == 5) {
129
                            se['AP-Status-text']
130
                                .setColor(flightdeck[terminal].display.colors.green)
131
                                .setVisible(0);
132
                            me._blink_count = 0;
133
                        }
134
                        return;
135
                    }
136
                    else {
137
                        se['AP-Status-text'].setVisible(ap_enabled);
integration of GFC700 capabi...
Sébastien MARQUE authored on 2020-05-17
138
                        me._blink_count = 0;
139
                    }
140
                }
141
            },
142
            hook: func {
143
                me._vertical_mode = globals.props.getNode("/autopilot/annunciator/vertical-mode", 1);
144
                me._pitch_setting = globals.props.getNode("/autopilot/settings/target-pitch-deg", 1);
145
                me._climb_setting = globals.props.getNode("/autopilot/settings/vertical-speed-fpm", 1);
146
                me._speed_setting = globals.props.getNode("/autopilot/settings/target-speed-kt", 1);
147
                me._vertical_mode_button = globals.props.getNode("/autopilot/vertical-mode-button", 1);
148
                me._lateral_mode_button = globals.props.getNode("/autopilot/lateral-mode-button", 1);
149
                me._ap_mode_button = globals.props.getNode("/autopilot/AP-mode-button", 1);
150
                me._ap_enabled = globals.props.getNode("/autopilot/annunciator/autopilot-enabled", 1);;
151
                me._fd_enabled = globals.props.getNode("/autopilot/annunciator/flight-director-enabled", 1);;
152

            
153
            },
154
            sendModeChange: func (value) {
155
                me._vertical_mode_button.setValue(value);
156
                me._lateral_mode_button.setValue(value);
157
                if (value == "AP") {
158
                    me._ap_mode_button.setValue(value);
159
                }
160
            },
161
            handleNoseUpDown : func(value) {
162
                var vertical_mode = me._vertical_mode.getValue();
163

            
164
                if (vertical_mode == "PIT")
165
                    me._pitch_setting.setValue(me._pitch_setting.getValue() + (value * 1));
166

            
167
                if (vertical_mode == "VS") {
168
                    me._climb_setting.setValue(me._climb_setting.getValue() + (value * 100));
169
                    setprop("/autopilot/annunciator/vertical-mode-target",
170
                        sprintf("%+ifpm", me._climb_setting.getValue())
171
                    );
172
                }
173

            
174
                if (vertical_mode == "FLC") {
175
                    me._speed_setting.setValue(me._speed_setting.getValue() - (value * 1));
176
                    setprop("/autopilot/annunciator/vertical-mode-target",
177
                        sprintf("%i kt", me._speed_setting.getValue())
178
                    );
179
                }
180
            },
nothing interesting
Sébastien MARQUE authored on 2020-05-17
181
            L: [
integration of GFC700 capabi...
Sébastien MARQUE authored on 2020-05-17
182
               func { me.sendModeChange('AP');  },
183
               func { me.sendModeChange('FD');  },
fix issue with AP/NAV
Sébastien MARQUE authored on 2020-09-27
184
               func { setprop('/autopilot/settings/nav-mode-source', cdi.getValue('source')); me.sendModeChange('NAV'); },
integration of GFC700 capabi...
Sébastien MARQUE authored on 2020-05-17
185
               func { me.sendModeChange('ALT'); },
186
               func { me.sendModeChange('VS');  },
187
               func { me.sendModeChange('FLC'); },
188
            ],
nothing interesting
Sébastien MARQUE authored on 2020-05-17
189
            R: [
integration of GFC700 capabi...
Sébastien MARQUE authored on 2020-05-17
190
               func { me.sendModeChange('YD');  },
191
               func { me.sendModeChange('HDG'); },
192
               func { me.sendModeChange('APR'); },
193
               func { me.sendModeChange('VNV'); },
194
               func { me.handleNoseUpDown(1);   },
195
               func { me.handleNoseUpDown(-1);  },
196
            ],
creates entry point for GFC7...
Sébastien MARQUE authored on 2020-05-16
197
        },
autopilot S-TEC 55X integrat...
Sébastien MARQUE authored on 2020-05-06
198
        STEC55X: {
code more clear
Sébastien MARQUE authored on 2020-05-16
199
            _aliases: {
200
                hdg:          afcs.getNode('heading-bug-deg'),
201
                alt:          afcs.getNode('selected-alt-ft'),
202
                NAVCourse:    cdi.getNode('course'),
203
                OBSNAVNeedle: cdi.getNode('course-deflection'),
204
            },
autopilot status with separa...
Sébastien MARQUE authored on 2020-05-08
205
            hook : func {
206
                me.trimTarget = 0;
code more clear
Sébastien MARQUE authored on 2020-05-16
207
                foreach (var a; keys(me._aliases)) stec55x[a].alias(me._aliases[a]);
stec55x integration (suite)
Sébastien MARQUE authored on 2020-05-11
208
                setprop('/it-stec55x/input/ap-master-sw', 1);
autopilot status with separa...
Sébastien MARQUE authored on 2020-05-08
209
            },
autopilot S-TEC 55X integrat...
Sébastien MARQUE authored on 2020-05-06
210
            updateDisplay: func {
autopilot status with separa...
Sébastien MARQUE authored on 2020-05-08
211
                if (stec55x.pitchMode != 1) {
212
                    var armed     = '';
213
                    var active    = '';
214
                    var reference = '';
215
                    if (stec55x.ALT_annun.getBoolValue()) {
216
                        if (abs(data.alt - afcs.getValue('selected-alt-ft')) < 150) {
217
                            active    = 'ALT';
218
                            reference = sprintf('%5d ft', afcs.getValue('selected-alt-ft'));
219
                            armed     = 'ALTS'
220
                        }
221
                        else {
222
                            active    = 'ALT';
223
                            reference = sprintf('%5d ft', math.round(data.alt, 10));
224
                            armed     = 'ALT';
225
                        }
226
                    }
227
                    elsif (stec55x.VS_annun.getBoolValue()) {
228
                        active    = 'VS';
229
                        reference = sprintf('%s%4d fpm',
autopilot S-TEC 55X integrat...
Sébastien MARQUE authored on 2020-05-06
230
                                        utf8.chstr(stec55x.vs.getValue() > 0 ? 9650 : 9660),
231
                                        math.abs(math.round(stec55x.vs.getValue(), 10)));
autopilot status with separa...
Sébastien MARQUE authored on 2020-05-08
232
                    }
233
                    elsif (stec55x.GSArmed.getBoolValue()) {
234
                        armed  = 'VPATH';
235
                        active = 'GS';
236
                    }
237
# TODO: ask Octal450 which prop or variable can be used here
238
#                    elsif (stec55x.???) {
239
#                        armed  = 'PIT';
240
#                        active = 'ALT';
241
#                        reference = sprintf("%d°", autopilot.systems.STEC55X.trim);
242
#                    }
improve and fix afcs for mul...
Sébastien MARQUE authored on 2021-03-24
243
                }
244

            
245
                foreach (var terminal; me.terminals) {
246
                    var se = flightdeck[me.terminal].display.screenElements;
autopilot status with separa...
Sébastien MARQUE authored on 2020-05-08
247
                    se['VERMOD-Active-text'].setVisible(size(active)).setText(active);
248
                    se['VERMOD-Armed-text'].setVisible(size(armed)).setText(armed);
249
                    se['VERMOD-Reference-text'].setVisible(size(reference)).setText(reference);
improve and fix afcs for mul...
Sébastien MARQUE authored on 2021-03-24
250
                    se['AP-Status-text'].setVisible(stec55x.rollMode  != -1 or stec55x.pitchMode != -1);
251
                    se['YD-Status-text'].setVisible(stec55x.yaw.getValue() != -1);
252
                    if (stec55x.rollMode  != -1) {
253
                        se['LATMOD-Active-text'].setVisible(1).setText('ROL');
254
                        var armed = '';
255
                        foreach (var m; [ 'NAV', 'CNAV', 'REV', 'CREV' ])
256
                            if (stec55x[m]) armed = m;
257
                        if (stec55x.roll.getValue() == 0) armed = 'HDG';
258
                        elsif (stec55x.roll.getValue() == 2) armed = 'GPS';
259
                        elsif (stec55x.APR_annun.getValue()) armed = 'APR';
260
                        se['LATMOD-Armed-text']
261
                            .setVisible(size(armed))
262
                            .setText(armed);
263
                    }
264
                    else {
265
                        se['LATMOD-Active-text'].setVisible(0);
266
                        se['LATMOD-Armed-text'].setVisible(0);
267
                    }
autopilot status with separa...
Sébastien MARQUE authored on 2020-05-08
268
                }
improve and fix afcs for mul...
Sébastien MARQUE authored on 2021-03-24
269

            
autopilot S-TEC 55X integrat...
Sébastien MARQUE authored on 2020-05-06
270
            },
271
            L: [
only HDG roll mode is availa...
Sébastien MARQUE authored on 2020-05-11
272
                func,
autopilot S-TEC 55X integrat...
Sébastien MARQUE authored on 2020-05-06
273
                func {
only HDG roll mode is availa...
Sébastien MARQUE authored on 2020-05-11
274
#                    var apfd_master_sw = '/it-stec55x/input/apfd-master-sw';
275
#                    setprop(apfd_master_sw, !getprop(apfd_master_sw));
autopilot S-TEC 55X integrat...
Sébastien MARQUE authored on 2020-05-06
276
                },
277
                func {
add STEC55X GPS roll mode
Sébastien MARQUE authored on 2020-05-11
278
                    var _roll = stec55x.roll.getValue();
279
                    if (_roll == 1 or _roll == 2 or _roll == 4)
280
                        stec55x.roll.setValue(-1);
281
                    else {
282
                        stec55x.roll.setValue(1);
283
                        call(stec55x.button.NAV, [], nil, stec55x);
284
                    }
autopilot S-TEC 55X integrat...
Sébastien MARQUE authored on 2020-05-06
285
                },
286
                func {
only HDG roll mode is availa...
Sébastien MARQUE authored on 2020-05-11
287
#                    call(stec55x.button.ALT, [], nil, stec55x);
autopilot S-TEC 55X integrat...
Sébastien MARQUE authored on 2020-05-06
288
                },
289
                func {
only HDG roll mode is availa...
Sébastien MARQUE authored on 2020-05-11
290
#                    stec55x.vs.setValue(math.round(data.vsi, 100));
291
#                    call(stec55x.button.VS, [], nil, stec55x);
autopilot S-TEC 55X integrat...
Sébastien MARQUE authored on 2020-05-06
292
                },
293
                func,
294
            ],
295
            R: [
296
                func {
only HDG roll mode is availa...
Sébastien MARQUE authored on 2020-05-11
297
#                    var yaw_dumper_sw = '/it-stec55x/input/yaw-damper-sw';
298
#                    setprop(yaw_dumper_sw, !getprop(yaw_dumper_sw));
autopilot S-TEC 55X integrat...
Sébastien MARQUE authored on 2020-05-06
299
                },
300
                func {
only HDG roll mode is availa...
Sébastien MARQUE authored on 2020-05-11
301
                    if (stec55x.roll.getValue() == 0)
302
                        stec55x.roll.setValue(-1);
303
                    else
304
                        call(stec55x.button.HDG, [], nil, stec55x);
autopilot S-TEC 55X integrat...
Sébastien MARQUE authored on 2020-05-06
305
                },
306
                func {
only HDG roll mode is availa...
Sébastien MARQUE authored on 2020-05-11
307
#                    call(stec55x.button.APR, [], nil, stec55x);
autopilot S-TEC 55X integrat...
Sébastien MARQUE authored on 2020-05-06
308
                },
309
                func,
310
                func { # UP (trim)
only HDG roll mode is availa...
Sébastien MARQUE authored on 2020-05-11
311
#                    if (autopilot.systems.STEC55X.trimTarget > -15)
312
#                        autopilot.systems.STEC55X.trimTarget -= 1;
313
#                    fgcommand('property-assign', {property: '/it-stec55x/input/man-trim', value: -1});
314
#                    fgcommand('property-assign', {property: '/it-stec55x/input/man-trim', value:  0});
autopilot S-TEC 55X integrat...
Sébastien MARQUE authored on 2020-05-06
315
                },
316
                func { # DN (trim)
only HDG roll mode is availa...
Sébastien MARQUE authored on 2020-05-11
317
#                    if (autopilot.systems.STEC55X.trimTarget < 20)
318
#                        autopilot.systems.STEC55X.trimTarget += 1;
319
#                    fgcommand('property-assign', {property: '/it-stec55x/input/man-trim', value: 1});
320
#                    fgcommand('property-assign', {property: '/it-stec55x/input/man-trim', value: 0});
autopilot S-TEC 55X integrat...
Sébastien MARQUE authored on 2020-05-06
321
                },
322
            ],
add KAP140 to afcs
Sébastien MARQUE authored on 2021-03-24
323
        },
324
        KAP140: {
325
            _blink_count: 0,
326
            updateDisplay: func {
327
                var latmod = latmod_armed = vertmod = vertmod_armed = "";
328
                var vertmod_target = 0;
fix syntax error
Sébastien MARQUE authored on 2021-03-24
329
                var ap_enabled = kap140.lockRollMode.getValue() != kap140.rollModes["OFF"]
330
                              or kap140.lockPitchMode.getValue() != kap140.pitchModes["OFF"];
add KAP140 to afcs
Sébastien MARQUE authored on 2021-03-24
331

            
332
                if (ap_enabled) {
333
                    foreach (var mode; keys(kap140.rollModes))
334
                        if (kap140.lockRollMode.getValue() == kap140.rollModes[mode]) {
335
                            latmod = mode;
336
                            break;
337
                        }
338

            
339
                    foreach (var mode; keys(kap140.rollArmModes))
340
                        if (kap140.lockRollArm.getValue() == kap140.rollArmModes[mode]) {
341
                            latmod_armed = mode;
342
                            break;
343
                        }
344

            
345
                    foreach (var mode; keys(kap140.pitchModes))
346
                        if (kap140.lockPitchMode.getValue() == kap140.pitchModes[mode]) {
347
                            vertmod = mode;
348
                            break;
349
                        }
350

            
351
                    foreach (var mode; keys(kap140.pitchArmModes))
352
                        if (kap140.lockPitchArm.getValue() == kap140.pitchArmModes[mode]) {
353
                            vertmod_armed = mode;
354
                            break;
355
                        }
356

            
357
                    vertmod_target = kap140.settingTargetPressureRate.getValue() * 58000;
358
                    if (kap140.lockPitchMode.getValue() == pitchModes["VS"]
359
                    or kap140.lockPitchArm.getValue() == pitchArmModes["VS"])
360
                        vertmod_target = sprintf('%s%4d fpm',
361
                                utf8.chstr(vertmod_target > 0 ? 9650 : 9660),
362
                                math.abs(math.round(vertmod_target, 10)));
363
                }
364

            
365
                foreach (var terminal; me.terminals) {
366
                    var se = flightdeck[terminal].display.screenElements;
367
                    if (se['AP-Status-text'].getVisible() and !ap_enabled) {
368
                        if (math.mod(me._blink_count,2))
369
                            se['AP-Status-text']
370
                                .setDrawMode(canvas.Text.TEXT + canvas.Text.FILLEDBOUNDINGBOX)
371
                                .setColorFill(flightdeck[terminal].display.colors.yellow)
372
                                .setColor(flightdeck[terminal].display.colors.black);
373
                        else
374
                            se['AP-Status-text']
375
                                .setDrawMode(canvas.Text.TEXT + canvas.Text.FILLEDBOUNDINGBOX)
376
                                .setColorFill(flightdeck[terminal].display.colors.black)
377
                                .setColor(flightdeck[terminal].display.colors.yellow);
378
                        me._blink_count += 1;
379
                        if (me._blink_count == 5) {
380
                            se['AP-Status-text']
381
                                .setColor(flightdeck[terminal].display.colors.green)
382
                                .setVisible(0);
383
                            me._blink_count = 0;
384
                        }
385
                        return;
386
                    }
387
                    else {
388
                        se['AP-Status-text'].setVisible(ap_enabled);
389
                        me._blink_count = 0;
390
                        se['LATMOD-Active-text'].setVisible(ap_enabled).setText(latmod);
391
                        se['LATMOD-Armed-text'].setVisible(ap_enabled).setText(latmod_armed);
392
                        se['VERMOD-Active-text'].setVisible(ap_enabled).setText(vertmod);
393
                        se['VERMOD-Reference-text'].setVisible(ap_enabled).setText(vertmod_target);
394
                        se['VERMOD-Armed-text'].setVisible(ap_enabled).setText(vertmod_armed);
395
                    }
396
                }
397
            },
398
            L: [
399
                func { kap140.apButton(); },
400
                func,
401
                func { kap140.navButton(); },
402
                func { kap140.altButton(); },
403
                func,
404
                func,
405
            ],
406
            R: [
407
                func,
408
                func { kap140.hdgButton(); },
409
                func { kap140.aprButton(); },
410
                func,
411
                func { kap140.upButton(); },
412
                func { kap140.downButton(); }
413
            ],
414
        },
adds AFCS
Sébastien MARQUE authored on 2020-05-06
415
    }
416
};