1
0
Fork 0
fgdata/Aircraft/Instruments-3d/glider/vario/S3/S3.nas

277 lines
7 KiB
Text

# LX Vario S3 by Benedikt Wolf (D-ECHO) based on
# A3XX Lower ECAM Canvas
# Joshua Davidson (it0uchpods)
# THANKS TO Colin Geniet (SoundPitchController), original developers of the ilec-sc7 (WooT)
# Information based on manual http://www.lx-avionik.de/wp/download/manuals/LXS3ManualGermanVer0100.pdf
#######################################
## REQUIRES:
## * second altimeter module enabled from <sim><instrumentation>
## * power supply from systems/electrical/outputs/S3
## (opt) * vario sound set up in the aircraft's sound file (see S3-sound.txt as an example)
#####################
## Version 05/2020 ##
#####################
## Features of this version:
## * use maketimer, only update visible pages
## * use props.nas, store in local variables where sensible
## * store instrument directory in variable
## * clarity through indentation
## * use functions for common functionality
## * clean up listeners
var S3_start = nil;
var S3_main = nil;
var S3_display = nil;
var s3 = props.globals.initNode("/instrumentation/s3");
var start_prop = s3.initNode("start", 0.0, "DOUBLE");
var pushknob_prop = s3.initNode("knob-pushed", 0, "BOOL");
var te_rdg = s3.initNode("te-reading-mps", 0.0, "DOUBLE");
var te_avg = s3.initNode("te-average-mps", 0.0, "DOUBLE");
var volume = s3.initNode("volume", 0.5, "DOUBLE");
var alt = props.globals.initNode("instrumentation/altimeter[1]/indicated-altitude-ft", 0.0, "DOUBLE");
var volt_prop = props.globals.initNode("/systems/electrical/outputs/S3", 0.0, "DOUBLE");
var mc = s3.initNode("mc", 1.5, "DOUBLE");
var needle = s3.initNode( "needle-deg", 0.0, "DOUBLE" );
var instrument_dir = "Aircraft/Instruments-3d/glider/vario/S3/";
var canvas_S3_base = {
init: func(canvas_group, file) {
var font_mapper = func(family, weight) {
return "LiberationFonts/LiberationSans-Bold.ttf";
};
canvas.parsesvg(canvas_group, file, {'font-mapper': font_mapper});
var svg_keys = me.getKeys();
foreach(var key; svg_keys) {
me[key] = canvas_group.getElementById(key);
}
me.page = canvas_group;
return me;
},
getKeys: func() {
return [];
},
update: func() {
var start = start_prop.getDoubleValue();
var volts = volt_prop.getDoubleValue();
if ( start == 1 and volts > 9 ) {
S3_start.page.hide();
S3_main.page.show();
S3_main.update();
} else if ( start > 0 and start < 1 and volts > 9 ){
S3_main.page.hide();
S3_start.page.show();
} else {
S3_main.page.hide();
S3_start.page.hide();
}
},
};
var canvas_S3_main = {
new: func(canvas_group, file) {
var m = { parents: [canvas_S3_main , canvas_S3_base] };
m.init(canvas_group, file);
return m;
},
getKeys: func() {
return ["altitude","average","average.needle","mccready.needle"];
},
update: func() {
#Altimeter
me["altitude"].setText( sprintf( "%4d", math.round( alt.getDoubleValue() * FT2M ) ) );
#Average climbrate
var av = te_avg.getDoubleValue();
me["average"].setText(sprintf("%2.1f", av));
if(av<5 and av>-5){
var av2=av;
}else if(av<-5){
var av2=-5;
}else if(av>5){
var av2=5;
}
me["average.needle"].setRotation(av2*D2R*24);
#McCready
me["mccready.needle"].setRotation( mc.getDoubleValue()*D2R*24 );
}
};
var canvas_S3_start = {
new: func(canvas_group, file) {
var m = { parents: [canvas_S3_start , canvas_S3_base] };
m.init(canvas_group, file);
return m;
},
getKeys: func() {
return [];
},
update: func() {
}
};
var s3_update = maketimer(0.2, func() { canvas_S3_base.update() } );
s3_update.simulatedTime = 1;
var vario_needle_ctrl = func {
if( start_prop.getDoubleValue() == 1.0 ){
needle.setDoubleValue( math.clamp( te_rdg.getDoubleValue() * 24, -132, 132 ) ); # max deflection: 132 deg at +- 5.5 m/s
} else {
needle.setDoubleValue( 0.0 );
}
}
var needle_update = maketimer( 0.0, vario_needle_ctrl );
needle_update.simulatedTime = 1;
var ls = setlistener("sim/signals/fdm-initialized", func {
S3_display = canvas.new({
"name": "S3",
"size": [320, 240],
"view": [320, 240],
"mipmapping": 1
});
S3_display.addPlacement({"node": "S3.display"});
var groupMain = S3_display.createGroup();
var groupStart = S3_display.createGroup();
S3_main = canvas_S3_main.new(groupMain, instrument_dir~"S3_main.svg");
S3_start = canvas_S3_start.new(groupStart, instrument_dir~"S3_start.svg");
s3_update.start();
needle_update.start();
removelistener(ls);
});
var i=0;
var check_off = func () {
if( pushknob_prop.getBoolValue() and i<50){
i=i+1;
settimer(check_off, 0.1);
}else if( pushknob_prop.getBoolValue() and i >= 50){
i=0;
start_prop.setDoubleValue( 0.0 ); #put proper shutdown routine here later
}else{
i=0;
}
}
var check_electric_off = func () {
if( volt_prop.getDoubleValue() < 9.0 and start_prop.getDoubleValue() != 0.0 ){
start_prop.setDoubleValue( 0.0 );
}
}
setlistener(pushknob_prop, func {
if( pushknob_prop.getBoolValue() ) {
if( volt_prop.getDoubleValue() >= 9.0 and start_prop.getDoubleValue() == 0.0 ){
interpolate(start_prop, 1, 4 );
} else {
check_electric_off();
}
check_off();
}
});
setlistener(volt_prop, func {
check_electric_off();
});
#The following code is based on the ILEC SC7 e-vario and computes the different values shown by the display and the mechanical needle
io.include("Aircraft/Generic/soaring-instrumentation-sdk.nas");
####################################
#### INSTRUMENT SETUP ####
####################################
# Vario sound pitch controller by Colin Geniet (for ASK21), thanks!
#
# var vario_sound = SoundPitchController.new(
# input: Object connected to the pitch controller input, e.g. a variometer reading.
# max_pitch: (optional) Maximum sound frequency factor, the output will be
# in the range [1/max_pitch, max_pitch], default 2.
# max_input: Value of input for which max_pitch is reached.
# on_update: (optional) function to call whenever a new output is available
var SoundPitchController = {
parents: [InstrumentComponent],
new: func(input, max_input, max_pitch = 2, on_update = nil) {
return {
parents: [me],
input: input,
max_pitch: max_pitch,
max_input: max_input,
on_update: on_update,
};
},
update: func {
var input = math.clamp(me.input.output, -me.max_input, me.max_input);
me.output = math.pow(me.max_pitch, input / me.max_input);
if (me.on_update != nil) me.on_update(me.output);
},
};
var probe = TotalEnergyProbe.new();
var s3_needle = Dampener.new(
input: probe,
dampening: 1.5,
on_update: update_prop("/instrumentation/s3/te-reading-mps"));#1.5 is default dampening value according to POH
var averager = Averager.new(
input: probe,
buffer_size: 20,
on_update: update_prop("/instrumentation/s3/te-average-mps")); #20s is default time according to POH
var s3_sound = SoundPitchController.new(
input: s3_needle,
max_input: 5,
on_update: update_prop("/instrumentation/s3/sound-pitch"));
# Wrap everything together into an instrument
var fast_instruments = UpdateLoop.new(
update_period: 0,
components: [probe, s3_needle, s3_sound],
enable: 1);
var slow_instruments = UpdateLoop.new(
update_period: 1,
components: [averager],
enable: 1);