1
0
Fork 0
A320-family/Models/Instruments/ND/canvas/map/TERRAIN.symbol

352 lines
9.3 KiB
Text
Raw Normal View History

2021-02-11 22:46:04 +00:00
# See: http://wiki.flightgear.org/MapStructure
# Class things:
var name = 'TERRAIN';
var parents = [DotSym];
var __self__ = caller(0)[0];
DotSym.makeinstance( name, __self__ );
var element_type = "group";
var terrain_minalt = props.globals.initNode("/instrumentation/efis[0]/nd/terrain-on-nd/min-altitude", 0,"INT");
var terrain_maxalt = props.globals.initNode("/instrumentation/efis[0]/nd/terrain-on-nd/max-altitude", -9999,"INT");
var terrain_alert = props.globals.initNode("/instrumentation/efis[0]/nd/terrain-on-nd/alert", 0,"INT");
2021-02-14 20:02:32 +00:00
var tile_list = [
nil,"tile_gl.png","tile_gh.png","tile_yl.png","tile_yh.png","tile_rh.png", # 0-5 low alt
"tile_gl.png","tile_gh.png","tile_gs.png",nil, # 6-8 hi alt
"tile_ml.png","tile_cl.png", # 10 magenta - 11 cyan (water)
"tile_ys.png","tile_rs.png" # 12-13 alert
];
var is_terrain = 0;
var get_elevation = func (lat, lon) {
var info = geodinfo(lat, lon);
var elevation = 0;
if (info != nil) {
elevation = int(info[0] * 3.2808399);
me.is_terrain = (info[1] == nil) ? 1 : info[1].solid;
}
else { elevation = nil; }
return elevation;
}
var updateTerrain = func {
if (me.reference == nil) return;
2021-02-11 22:46:04 +00:00
if(me.fetching) return;
2021-02-11 22:46:04 +00:00
me.fetching = 1;
2021-02-14 20:02:32 +00:00
if (me.request_clear == 1) {
me.request_clear = 0;
me.clear();
me.group.setVisible(1);
2021-02-14 20:02:32 +00:00
}
2021-02-11 22:46:04 +00:00
var RAD2DEG = 57.2957795;
var DEG2RAD = 0.016774532925;
2021-02-11 22:46:04 +00:00
var pos_lat = me.reference.lat();
var pos_lon = me.reference.lon();
var heading = me.refheading;
var altitudeft = me.refaltitudeft;
var lowaltft = me.reflowaltft;
var basealtft = me.basealtitudeft;
var alert_level = me.terrain_alert.getValue();
2021-02-11 22:46:04 +00:00
var side = (math.mod(me.radar_beacon,2)==0) ? "L" : "R";
var a = int(me.radar_beacon/2);
var col = a + 0.5;
2021-02-12 23:39:38 +00:00
if (side == "R") {
col = -col;
}
2021-02-14 20:02:32 +00:00
var trn = me.terrlayer[side ~ a];
2021-02-14 20:02:32 +00:00
var len = size(trn);
var range = me.range;
2021-02-11 22:46:04 +00:00
2021-02-14 20:02:32 +00:00
var tiles = me.tile_list;
2021-02-13 10:21:29 +00:00
2021-02-14 20:02:32 +00:00
var proj_lon = pos_lon + ((col * (range/30) * math.sin(DEG2RAD * (heading - 90))) / 40);
var proj_lat = pos_lat + ((col * (range/30) * math.cos(DEG2RAD * (heading - 90))) / 40);
2021-02-14 20:02:32 +00:00
var elevft = [];
me.radar_cleared = 0;
2021-02-14 20:02:32 +00:00
for (var row = 0; row < len; row += 1) {
2021-02-14 20:02:32 +00:00
if (trn[row] == nil) {
append(elevft,-1);
continue;
}
2021-02-14 20:02:32 +00:00
var point_lon = proj_lon + ((row * (range/30) / 40) * math.sin(DEG2RAD * heading));
var point_lat = proj_lat + ((row * (range/30) / 40) * math.cos(DEG2RAD * heading));
var elev = me.get_elevation(point_lat, point_lon);
var grad = 0; #black
if (elev != nil) {
if (elev<me.min_altitude) me.min_altitude = elev;
else if (elev>me.max_altitude) me.max_altitude = elev;
if (me.is_terrain) {
if (elev < basealtft) grad = 0; # < 400 near runway use blank
else {
var diff = elev - altitudeft;
if (diff>=0) {
grad = int(diff/1000) + 3;
if (grad>5) grad = 5;
if (alert_level > 0 and a < 6 and grad > 3) {
if (alert_level == 1 and (grad == 3 or grad == 4)) grad = 12; # solid yellow
else if (alert_level == 2 and grad == 5) grad = 13; # solid red
}
} else {
if (me.hialtmode == 0) {
if (diff>=lowaltft) grad = 3; # lite yellow
else {
grad = int(diff/1000) + 2;
if (grad<0) grad = 0;
}
} else {
if (diff>=lowaltft) grad = 3; # lite yellow
else {
if (me.bands_range > 0 and elev > me.bands_minalt) {
grad = int((elev-me.bands_minalt) / me.bands_range) + 6;
if (grad>8) grad = 8; # solid green
}
}
}
2021-02-13 10:21:29 +00:00
}
}
} else {
grad = 11; #water
}
2021-02-14 20:02:32 +00:00
append(elevft,grad); # 0-5
} else {
append(elevft,0); # no data - black (magenta)
}
2021-02-14 20:02:32 +00:00
}
2021-02-14 20:02:32 +00:00
for (var r=0; r < len; r+=1) {
var imgx = elevft[r];
if (imgx == -1) continue;
if (imgx < 1) trn[r].hide();
else trn[r].setFile(me.imgpath ~ me.tile_list[imgx]).show();
}
me.radar_beacon += 1;
2021-02-14 20:02:32 +00:00
if (me.radar_beacon >= (me.tileradiusw*2)) {
me.restart_beacon();
2021-02-11 22:46:04 +00:00
}
2021-02-11 22:46:04 +00:00
me.fetching = 0;
};
2021-02-14 20:02:32 +00:00
var update_altitudes = func {
2021-02-14 20:02:32 +00:00
me.terrain_minalt.setValue(me.min_altitude);
me.terrain_maxalt.setValue(me.max_altitude);
if (me.onground == 0 and (me.max_altitude + 250) < me.refaltitudeft) { # 250 ft tollerance
me.hialtmode = 1;
me.bands_range = math.min(2000,(me.max_altitude - math.max(me.min_altitude,me.basealtitudeft))) / 5;
var maxrange = math.min(2000,me.max_altitude - (me.bands_range * 3));
me.bands_minalt = int(me.max_altitude - maxrange);
me.bands_maxalt = me.max_altitude;
} else {
me.hialtmode = 0;
}
me.min_altitude = 9999;
me.max_altitude = -9999;
2021-02-14 20:02:32 +00:00
}
var restart_beacon = func {
me.radar_beacon = 0;
me.radar_cycle += 1;
me.reference = nil;
2021-02-14 20:02:32 +00:00
};
2021-02-11 22:46:04 +00:00
var init = func {
#print('TERRAIN init');
2021-02-13 22:00:50 +00:00
me.tile = 33; # preferred 34
2021-02-11 22:46:04 +00:00
me.fetching = 0;
me.timeStamp = nil;
me.fetchRad = me.model.fetchRad; # Radius of radar layer to fetch
me.range = me.model.rangeNm; # Range of Navigation Display
me.viewport_radius = me.getOption('viewport_radius', 670);
me.imgpath = get_local_path('res/terrainv2/');
2021-02-14 20:02:32 +00:00
me.radar_beacon = 0;
me.radar_cycle = 0;
me.radar_cleared = 1;
me.request_clear = 0;
2021-02-13 22:00:50 +00:00
me.visible = 0;
2021-02-14 20:02:32 +00:00
me.min_altitude = 9999;
me.max_altitude = -9999;
me.bands_minalt = 0;
me.bands_maxalt = 0;
me.bands_range = 0;
me.basealtitudeft = nil;
me.reference = nil;
me.onfailure = 0;
me.hialtmode = 0; # high aircraft relative altitude mode
me.checkarrival = 0;
me.onground = 1;
2021-02-11 22:46:04 +00:00
var tile = me.tile;
var gx = int(me.viewport_radius / tile);
me.tileradius = gx;
2021-02-14 20:02:32 +00:00
var limx = int((512/tile)+0.5); # horiz space is smaller
me.tileradiusw = limx;
me.terrlayer = {};
2021-02-11 22:46:04 +00:00
2021-02-14 20:02:32 +00:00
var centx = 0;
var centy = -me.viewport_radius;
2021-02-11 22:46:04 +00:00
2021-02-13 22:00:50 +00:00
var group = me.group.createChild("group").set("z-index", -100); #me.element
2021-02-14 20:02:32 +00:00
for (var c=0; c<limx; c+=1) {
2021-02-11 22:46:04 +00:00
var hh = c * tile;
var mx = (c == 0) ? gx : int(math.sqrt(gx*gx-c*c) + 0.5);
var my = int(c*4/gx);
var py = centy + (gx-1) * tile;
2021-02-11 22:46:04 +00:00
var pxr = centx+(c*tile);
var pxl = centx-(c*tile)-tile;
var grplx = [];
var grprx = [];
for (var r=0; r<mx; r+=1) {
if (r<my) {
append(grplx , nil); #skip
append(grprx , nil);
} else {
append(grplx , group.createChild("image").setSize(tile,tile).setTranslation(pxl,py).hide());
append(grprx , group.createChild("image").setSize(tile,tile).setTranslation(pxr,py).hide());
}
2021-02-11 22:46:04 +00:00
py-=tile;
}
me.terrlayer["L" ~ c] = grplx;
me.terrlayer["R" ~ c] = grprx;
}
2021-02-14 20:02:32 +00:00
setlistener("/instrumentation/mk-viii/inputs/discretes/ta-tcf-inhibit", func{ # detect GPWS switch status
me.onfailure = getprop("/instrumentation/mk-viii/inputs/discretes/ta-tcf-inhibit");
},0,0);
2021-02-11 22:46:04 +00:00
};
2021-02-13 10:21:29 +00:00
var clear = func {
2021-02-14 20:02:32 +00:00
if (me.radar_cleared == 0) {
me.radar_cleared = 1;
for (var c=0; c<me.tileradiusw; c+=1 ) {
var rowL = me.terrlayer["L" ~ c];
2021-02-13 10:21:29 +00:00
var rowR = me.terrlayer["R" ~ c];
var len = size(rowL);
for (var r=0; r<len; r+=1) {
if (rowL[r] != nil) {
rowL[r].hide();
rowR[r].hide();
}
2021-02-14 20:02:32 +00:00
}
}
2021-02-13 10:21:29 +00:00
}
}
2021-02-11 22:46:04 +00:00
var draw = func {
2021-02-14 22:11:52 +00:00
if(me.fetching) return;
if (me.onfailure == 1) {
me.clear();
me.restart_beacon();
return;
}
if (me.reference == nil) { # update aircraft reference
var ref = geo.aircraft_position();
me.reference = ref;
if (ref != nil) {
me.refheading = getprop("orientation/heading-magnetic-deg");
var refalt = ref.alt() * 3.2808399;
me.refaltitudeft = refalt;
me.reflowaltft = (pts.Gear.position[1].getValue()) ? -250 : -500;
me.onground = getprop("/gear/gear[0]/wow");
if (me.min_altitude != 9999) me.update_altitudes();
if (me.basealtitudeft == nil and fmgc.FMGCInternal.phase<2) {
me.basealtitudeft = refalt + 400;
me.checkarrival = 1;
}
if (fmgc.FMGCInternal.phase == 2) {
me.basealtitudeft = math.min(me.basealtitudeft,400+me.terrain_minalt.getValue());
}
if (fmgc.FMGCInternal.phase == 5 and me.checkarrival == 1) {
me.checkarrival = 0;
me.basealtitudeft = nil;
if (fmgc.FMGCInternal.arrApt != nil) {
var airport = airportinfo(fmgc.FMGCInternal.arrApt);
if (airport != nil) me.basealtitudeft = 400 + (airport.elevation * M2FT);
}
if (me.basealtitudeft == nil) {
me.basealtitudeft = 400 + me.terrain_minalt.getValue(); # that's fun
}
}
if (fmgc.FMGCInternal.phase == 6 and me.checkarrival == 0) {
me.checkarrival == 1;
#me.basealtitudeft = 0;
}
if (fmgc.FMGCInternal.phase == 7 and me.checkarrival == 0) {
me.checkarrival == 1;
me.basealtitudeft = refalt + 400;
}
}
} else {
var range = me.layer.map.getRange(); # Range of Navigation Display
var update_size = (range != me.range);
me.range = range;
2021-02-13 22:00:50 +00:00
if (me.layer.display_changed == 1 or update_size) {
me.layer.display_changed = 0;
me.request_clear = 1;
}
2021-02-11 22:46:04 +00:00
me.updateTerrain(); # left
me.updateTerrain(); # right
}
2021-02-11 22:46:04 +00:00
};
setlistener("/instrumentation/mk-viii/outputs/discretes/gpws-warning", func { #warning - TERRAIN red - solid red
2021-02-19 22:40:43 +00:00
me.terrain_alert.setValue( (getprop("/instrumentation/mk-viii/outputs/discretes/gpws-warning") == 1 ) ? 2 : 0 );
print("Terrain alert:" ~ getprop("/instrumentation/mk-viii/outputs/discretes/gpws-warning"));
print(me.terrain_alert.getValue());
});
setlistener("/instrumentation/mk-viii/outputs/discretes/gpws-alert", func { #caution - TERRAIN amber - solid yellow
2021-02-19 22:40:43 +00:00
me.terrain_alert.setValue( (getprop("/instrumentation/mk-viii/outputs/discretes/gpws-alert") == 1 ) ? 1 : 0 );
print("Terrain alert:" ~ getprop("/instrumentation/mk-viii/outputs/discretes/gpws-warning"));
print(me.terrain_alert.getValue());
});