- new version with doc by Zakharov
This commit is contained in:
parent
ce1b5ac7e1
commit
763860f42c
7 changed files with 603 additions and 100 deletions
|
@ -24,7 +24,7 @@ var screenAirportMain = {
|
||||||
me.searched = 0;
|
me.searched = 0;
|
||||||
me.oaci = nil;
|
me.oaci = nil;
|
||||||
},
|
},
|
||||||
start : func { #add bookmark, enter turnpoint mode
|
start : func { #add bookmark, enter turnpoint mode
|
||||||
add_bookmark(me.apt.id, me.apt.name, "APT",
|
add_bookmark(me.apt.id, me.apt.name, "APT",
|
||||||
[me.apt_coord.lat(), me.apt_coord.lon(),
|
[me.apt_coord.lat(), me.apt_coord.lon(),
|
||||||
me.apt_coord.alt()*alt_conv[1][0]]);
|
me.apt_coord.alt()*alt_conv[1][0]]);
|
||||||
|
@ -63,10 +63,6 @@ var screenAirportInfos = {
|
||||||
page : 0,
|
page : 0,
|
||||||
rwylist: [],
|
rwylist: [],
|
||||||
right : func {
|
right : func {
|
||||||
me.page = 0;
|
|
||||||
displayed_screen = 4;# screenAirportMain
|
|
||||||
},
|
|
||||||
left : func {
|
|
||||||
np = int(size(me.rwylist) / 4) + (math.mod(size(me.rwylist),4) ? 1 : 0);
|
np = int(size(me.rwylist) / 4) + (math.mod(size(me.rwylist),4) ? 1 : 0);
|
||||||
me.page = cycle(np, me.page, arg[0]);
|
me.page = cycle(np, me.page, arg[0]);
|
||||||
},
|
},
|
||||||
|
@ -83,7 +79,7 @@ var screenAirportInfos = {
|
||||||
screenAirportMain.apt.runways[r].width]);
|
screenAirportMain.apt.runways[r].width]);
|
||||||
line[0].setValue(sprintf("%s", screenAirportMain.apt.name)); #TODO check length to truncate if too long
|
line[0].setValue(sprintf("%s", screenAirportMain.apt.name)); #TODO check length to truncate if too long
|
||||||
rwyindex = me.page * 4;
|
rwyindex = me.page * 4;
|
||||||
for (var l = 1; l < 5; l += 1) {
|
for (var l = 1; l < LINES; l += 1) {
|
||||||
rwyindex += 1;
|
rwyindex += 1;
|
||||||
if (rwyindex < size(me.rwylist))
|
if (rwyindex < size(me.rwylist))
|
||||||
line[l].setValue(sprintf("%s [%dm / %dm]",
|
line[l].setValue(sprintf("%s [%dm / %dm]",
|
||||||
|
@ -108,13 +104,14 @@ var screenSearchAirport = {
|
||||||
var found = screenAirportMain.search();
|
var found = screenAirportMain.search();
|
||||||
if (found != 0) {
|
if (found != 0) {
|
||||||
screenAirportMain.searched = 1;
|
screenAirportMain.searched = 1;
|
||||||
|
screenEdit.previous_page = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
lines : func {
|
lines : func {
|
||||||
EditMode(4, "AIRPORT CODE", "SEARCH", 2, 0);
|
EditMode(4, "AIRPORT CODE", "SEARCH");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,45 +1,37 @@
|
||||||
var screenModeAndSettings = { # screen for changing the GPS mode and settings
|
var screenModeAndSettings = { # screen for changing the GPS mode and settings
|
||||||
help : 0,
|
help : 0,
|
||||||
mode_: 0,
|
mode_: 0,
|
||||||
|
page_: 0,
|
||||||
|
available_modes : ["POSITION","AIRPORT","TURNPOINT","TASK"],
|
||||||
quit_help : func {
|
quit_help : func {
|
||||||
me.help = 0;
|
me.help = 0;
|
||||||
me.lines();
|
me.lines();
|
||||||
},
|
},
|
||||||
right : func {
|
right : func {
|
||||||
if (page == 1)
|
if (page == 1)
|
||||||
alt_unit = cycle(2, alt_unit, arg[0]);
|
alt_unit = cycle(size(alt_unit_full_name), alt_unit, arg[0]);
|
||||||
elsif (page == 2)
|
elsif (page == 2)
|
||||||
dist_unit = cycle(2, dist_unit, arg[0]);
|
dist_unit = cycle(size(dist_unit_full_name), dist_unit, arg[0]);
|
||||||
elsif (page == 3)
|
elsif (page == 3)
|
||||||
spd_unit = cycle(2, spd_unit, arg[0]);
|
spd_unit = cycle(size(spd_unit_full_name), spd_unit, arg[0]);
|
||||||
elsif (page == 4)
|
elsif (page == 4)
|
||||||
thresold_alert_index = cycle(size(thresold_alert), thresold_alert_index, arg[0]);
|
thresold_alert_index = cycle(size(thresold_alert), thresold_alert_index, arg[0]);
|
||||||
elsif (page == 5)
|
elsif (page == 5)
|
||||||
thresold_next_waypoint = cycle(10, thresold_next_waypoint, arg[0]);
|
thresold_next_waypoint = cycle(10, thresold_next_waypoint, arg[0]);
|
||||||
},
|
},
|
||||||
changemode : func {
|
|
||||||
if (page == 0) me.mode_ = cycle(4, me.mode_, arg[0]);
|
|
||||||
},
|
|
||||||
enter : func {
|
enter : func {
|
||||||
if (!me.help) {
|
if (!me.help) {
|
||||||
display ([
|
display (NOT_YET_IMPLEMENTED);
|
||||||
"HERE THERE WILL SEAT",
|
|
||||||
"A SIMPLE EXPLANATION",
|
|
||||||
"TEXT ABOUT USE OF GPS",
|
|
||||||
"PRESS ANY OF THE",
|
|
||||||
"THREE BUTTONS"
|
|
||||||
]);
|
|
||||||
me.help = 1;
|
me.help = 1;
|
||||||
}
|
}
|
||||||
else me.quit_help();
|
else me.quit_help();
|
||||||
},
|
},
|
||||||
escape : func {
|
escape : func {
|
||||||
if (me.help) me.quit_help();
|
if (me.help) me.quit_help();
|
||||||
else me.dispatch();
|
|
||||||
},
|
},
|
||||||
start : func {
|
start : func {
|
||||||
if (me.help) me.quit_help();
|
if (me.help) me.quit_help();
|
||||||
else {
|
else {
|
||||||
mode = me.mode_ + 1;
|
mode = me.mode_ + 1;
|
||||||
page = 0;
|
page = 0;
|
||||||
displayed_screen = page_list[mode][page];
|
displayed_screen = page_list[mode][page];
|
||||||
|
@ -47,10 +39,7 @@ var screenModeAndSettings = { # screen for changing the GPS mode and settings
|
||||||
},
|
},
|
||||||
lines : func {
|
lines : func {
|
||||||
if (page == 0) {
|
if (page == 0) {
|
||||||
if (me.mode_ == 0) mode_str = "POSITION";
|
var mode_str = me.available_modes[me.mode_];
|
||||||
elsif (me.mode_ == 1) mode_str = "AIRPORT";
|
|
||||||
elsif (me.mode_ == 2) mode_str = "TURNPOINT";
|
|
||||||
else mode_str = "TASK";
|
|
||||||
l0 = " -- GPS STATUS : --";
|
l0 = " -- GPS STATUS : --";
|
||||||
l1 = sprintf("MODE: %s", mode_str);
|
l1 = sprintf("MODE: %s", mode_str);
|
||||||
}
|
}
|
||||||
|
@ -87,7 +76,7 @@ var screenPositionMain = { # screens for POSITION mode
|
||||||
enter : func {
|
enter : func {
|
||||||
var ac = geo.aircraft_position();
|
var ac = geo.aircraft_position();
|
||||||
me.coord = [ac.lat(), ac.lon(), ac.alt()];
|
me.coord = [ac.lat(), ac.lon(), ac.alt()];
|
||||||
EditMode(6, "EDIT WAYPOINT ID", "SAVE", mode, page);
|
EditMode(6, "EDIT WAYPOINT ID", "SAVE");
|
||||||
},
|
},
|
||||||
escape : func {
|
escape : func {
|
||||||
},
|
},
|
||||||
|
@ -257,29 +246,29 @@ var screenNavigationMain = {
|
||||||
var screenEdit = {
|
var screenEdit = {
|
||||||
previous_mode: 0,
|
previous_mode: 0,
|
||||||
previous_page: 0,
|
previous_page: 0,
|
||||||
alphanum: ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P",
|
carset: [["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P",
|
||||||
"Q","R","S","T","U","V","W","X","Y","Z",
|
"Q","R","S","T","U","V","W","X","Y","Z", "0","1","2","3","4","5","6","7","8","9"],
|
||||||
"0","1","2","3","4","5","6","7","8","9"],
|
["0","1","2","3","4","5","6","7","8","9","."]],
|
||||||
numeric: ["0","1","2","3","4","5","6","7","8","9","."],
|
|
||||||
start_command: "",
|
start_command: "",
|
||||||
edit_zone: "",
|
edit_zone: "",
|
||||||
edit_title : "",
|
edit_title : "",
|
||||||
carset: [],
|
set: 0,
|
||||||
map: [],
|
map: [],
|
||||||
pointer: 0,
|
pointer: 0,
|
||||||
value: 0,
|
value: 0,
|
||||||
init: func (length, title, start_command, backmode, backpage, set = 0) {
|
init: func (length, title, start_command, set) {
|
||||||
|
me.map = [];
|
||||||
for (var i = 0; i < length; i += 1) append(me.map, "-");
|
for (var i = 0; i < length; i += 1) append(me.map, "-");
|
||||||
me.edit_title = title;
|
me.edit_title = title;
|
||||||
me.start_command = start_command;
|
me.start_command = start_command;
|
||||||
me.carset = set != 0 ? me.numeric : me.alphanum;
|
me.set = set;
|
||||||
me.previous_mode = backmode;
|
me.pointer = 0;
|
||||||
me.previous_page = backpage;
|
me.value = 0;
|
||||||
left_knob(0); # force display
|
left_knob(0); # force display
|
||||||
},
|
},
|
||||||
right : func {
|
right : func {
|
||||||
me.value = cycle(size(me.carset), me.value, arg[0]);
|
me.value = cycle(size(me.carset[me.set]), me.value, arg[0]);
|
||||||
me.map[me.pointer] = me.carset[me.value];
|
me.map[me.pointer] = me.carset[me.set][me.value];
|
||||||
},
|
},
|
||||||
enter : func {
|
enter : func {
|
||||||
me.pointer = cycle(size(me.map), me.pointer, 1);
|
me.pointer = cycle(size(me.map), me.pointer, 1);
|
||||||
|
@ -292,7 +281,7 @@ var screenEdit = {
|
||||||
me.start_command = "";
|
me.start_command = "";
|
||||||
me.edit_zone = "";
|
me.edit_zone = "";
|
||||||
me.edit_title = "";
|
me.edit_title = "";
|
||||||
me.carset = [];
|
me.set = 0;
|
||||||
me.map = [];
|
me.map = [];
|
||||||
mode = me.previous_mode;
|
mode = me.previous_mode;
|
||||||
page = me.previous_page;
|
page = me.previous_page;
|
||||||
|
@ -302,7 +291,10 @@ var screenEdit = {
|
||||||
var str = "";
|
var str = "";
|
||||||
for (var i = 0; i < size(me.map); i += 1)
|
for (var i = 0; i < size(me.map); i += 1)
|
||||||
str ~= me.map[i] != "-" ? me.map[i] : "";
|
str ~= me.map[i] != "-" ? me.map[i] : "";
|
||||||
if (screen[page_list[me.previous_mode][me.previous_page]].start(str)) me.escape();
|
if (screen[page_list[me.previous_mode][me.previous_page]].start(str))
|
||||||
|
me.escape();
|
||||||
|
else
|
||||||
|
me.init(size(me.map), me.edit_title, me.start_command, me.set);
|
||||||
},
|
},
|
||||||
lines : func {
|
lines : func {
|
||||||
me.right(0); #init car
|
me.right(0); #init car
|
||||||
|
|
|
@ -54,9 +54,9 @@ var screenTaskSelect = {
|
||||||
""
|
""
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
else for (var l = 0; l < 5; l += 1) {
|
else for (var l = 0; l < LINES; l += 1) {
|
||||||
if ((me.page * 5 + l) < me.n) {
|
if ((me.page * LINES + l) < me.n) {
|
||||||
name = routes[me.page * 5 + l];
|
name = routes[me.page * LINES + l];
|
||||||
if (substr(name, -4) == ".xml") name = substr(name, 0, size(name) - 4);
|
if (substr(name, -4) == ".xml") name = substr(name, 0, size(name) - 4);
|
||||||
name = string.uc(name);
|
name = string.uc(name);
|
||||||
line[l].setValue(sprintf("%s %s",me.pointer == l ? ">" : " ", name));
|
line[l].setValue(sprintf("%s %s",me.pointer == l ? ">" : " ", name));
|
||||||
|
@ -83,9 +83,9 @@ var screenWaypointsList = {
|
||||||
start : func {
|
start : func {
|
||||||
},
|
},
|
||||||
lines : func {
|
lines : func {
|
||||||
for (var l = 0; l < 5; l += 1) {
|
for (var l = 0; l < LINES; l += 1) {
|
||||||
if ((me.page * 5 + l) < me.n) {
|
if ((me.page * LINES + l) < me.n) {
|
||||||
name = gps_data.getNode("route/Waypoint["~((me.page*5) + l)~"]/ID").getValue();
|
name = gps_data.getNode("route/Waypoint["~((me.page * LINES) + l)~"]/ID").getValue();
|
||||||
line[l].setValue(sprintf("%s %s",me.pointer == l ? ">" : " ", name));
|
line[l].setValue(sprintf("%s %s",me.pointer == l ? ">" : " ", name));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -10,7 +10,7 @@ var screenTurnpointSelect = {
|
||||||
var t = browse(me.n, me.pointer, me.page, arg[0]);
|
var t = browse(me.n, me.pointer, me.page, arg[0]);
|
||||||
me.pointer = t[0];
|
me.pointer = t[0];
|
||||||
me.page = t[1];
|
me.page = t[1];
|
||||||
me.selected = me.page*5 + me.pointer;
|
me.selected = me.page * LINES + me.pointer;
|
||||||
},
|
},
|
||||||
enter : func {
|
enter : func {
|
||||||
},
|
},
|
||||||
|
@ -24,10 +24,14 @@ var screenTurnpointSelect = {
|
||||||
gps_wp.getNode("wp/ID").setValue("startpos");
|
gps_wp.getNode("wp/ID").setValue("startpos");
|
||||||
|
|
||||||
var bookmark = gps_data.getNode("bookmarks/bookmark["~me.selected~"]/");
|
var bookmark = gps_data.getNode("bookmarks/bookmark["~me.selected~"]/");
|
||||||
gps_wp.getNode("wp[1]/latitude-deg",1).setValue(bookmark.getNode("latitude-deg",1).getValue());
|
gps_wp.getNode("wp[1]/latitude-deg",1).setValue(bookmark.getNode("latitude-deg").getValue());
|
||||||
gps_wp.getNode("wp[1]/longitude-deg",1).setValue(bookmark.getNode("longitude-deg",1).getValue());
|
gps_wp.getNode("wp[1]/longitude-deg",1).setValue(bookmark.getNode("longitude-deg").getValue());
|
||||||
gps_wp.getNode("wp[1]/altitude-ft",1).setValue(bookmark.getNode("altitude-ft",1).getValue());
|
gps_wp.getNode("wp[1]/altitude-ft",1).setValue(bookmark.getNode("altitude-ft").getValue());
|
||||||
gps_wp.getNode("wp[1]/ID").setValue(bookmark.getNode("ID",1).getValue());
|
gps_wp.getNode("wp[1]/ID").setValue(bookmark.getNode("ID").getValue());
|
||||||
|
if (bookmark.getNode("name") != nil)
|
||||||
|
gps_wp.getNode("wp[1]/name").setValue(bookmark.getNode("name").getValue());
|
||||||
|
if (bookmark.getNode("waypoint-type") != nil)
|
||||||
|
gps_wp.getNode("wp[1]/waypoint-type").setValue(bookmark.getNode("waypoint-type").getValue());
|
||||||
blocked = 0;
|
blocked = 0;
|
||||||
page = 1;
|
page = 1;
|
||||||
mode = 3;
|
mode = 3;
|
||||||
|
@ -36,9 +40,9 @@ var screenTurnpointSelect = {
|
||||||
lines : func {
|
lines : func {
|
||||||
if (me.loaded != 1) blocked = 1;
|
if (me.loaded != 1) blocked = 1;
|
||||||
if (me.n > 0)
|
if (me.n > 0)
|
||||||
for (var l = 0; l < 5; l += 1) {
|
for (var l = 0; l < LINES; l += 1) {
|
||||||
if ((me.page * 5 + l) < me.n) {
|
if ((me.page * LINES + l) < me.n) {
|
||||||
name = gps_data.getNode("bookmarks/bookmark["~((me.page * 5) + l)~"]/ID").getValue();
|
name = gps_data.getNode("bookmarks/bookmark["~((me.page * LINES) + l)~"]/ID").getValue();
|
||||||
line[l].setValue(sprintf("%s %s",me.pointer == l ? ">" : " ", name));
|
line[l].setValue(sprintf("%s %s",me.pointer == l ? ">" : " ", name));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
var mode = 0;
|
var mode = 0; #current mode
|
||||||
var displayed_screen = 0; #screenModeAndSettings
|
var displayed_screen = 0; #screenModeAndSettings
|
||||||
var page = 0;
|
var page = 0; #current page
|
||||||
var blocked = 0;
|
var blocked = 0; #boolean: 0 -> possible to cycle pages
|
||||||
var isOn = 0;
|
var isOn = 0; #ON/OFF: 0 -> OFF
|
||||||
var freq = 1;
|
var freq = 1; #settimer frequency (in sec)
|
||||||
var screen = [];
|
var screen = []; #array containing all screens
|
||||||
var line = [];
|
var line = []; #array containing the displayed lines
|
||||||
var routes = [];
|
var routes = []; #array containing the preprogrammed tasks
|
||||||
var alt_unit_full_name = ["Feet", "Meters"];
|
var alt_unit_full_name = ["Feet", "Meters"];
|
||||||
var dist_unit_full_name = ["Nautic Miles", "Kilometers"];
|
var dist_unit_full_name = ["Nautic Miles", "Kilometers"];
|
||||||
var spd_unit_full_name = ["Knots", "KM/H"];
|
var spd_unit_full_name = ["Knots", "KM/H"];
|
||||||
|
@ -16,9 +16,8 @@ var spd_unit_short_name = ["kt", "km/h"];
|
||||||
var spd_unit = 0;
|
var spd_unit = 0;
|
||||||
var dist_unit = 0;
|
var dist_unit = 0;
|
||||||
var alt_unit = 0;
|
var alt_unit = 0;
|
||||||
#var apt = nil;
|
var startpos = nil; #geo.nas aircraft position
|
||||||
var startpos = nil;
|
var waypointindex = 0; #step in actual task
|
||||||
var waypointindex = 0;
|
|
||||||
var thresold_alert = [120, 60, 30, 15];
|
var thresold_alert = [120, 60, 30, 15];
|
||||||
var thresold_alert_index = 1;
|
var thresold_alert_index = 1;
|
||||||
var thresold_next_waypoint = 5;
|
var thresold_next_waypoint = 5;
|
||||||
|
@ -29,7 +28,7 @@ NOT_YET_IMPLEMENTED = [
|
||||||
"IMPLEMENTED",
|
"IMPLEMENTED",
|
||||||
""
|
""
|
||||||
];
|
];
|
||||||
var page = 0;
|
var LINES = 5; #lines in display
|
||||||
var page_list = [
|
var page_list = [
|
||||||
[0,0,0,0,0,0], #0 ModeAndSettings: 1 page for mode, 5 pages for settings
|
[0,0,0,0,0,0], #0 ModeAndSettings: 1 page for mode, 5 pages for settings
|
||||||
[1,2,3], #1 PositionMain, Odometers, WindInfos
|
[1,2,3], #1 PositionMain, Odometers, WindInfos
|
||||||
|
@ -52,54 +51,56 @@ var gps_data = props.globals.getNode("/instrumentation/gps",1);
|
||||||
var gps_wp = gps_data.getNode("wp",1);
|
var gps_wp = gps_data.getNode("wp",1);
|
||||||
|
|
||||||
#### warps for buttons and knobs ########################################"
|
#### warps for buttons and knobs ########################################"
|
||||||
var right_knob = func(dir) {
|
var right_knob = func(dir) { #manage right knob, depends of displayed screen
|
||||||
isOn == 1 or return;
|
isOn == 1 or return;
|
||||||
screen[displayed_screen].right(dir);
|
screen[displayed_screen].right(dir);
|
||||||
refresh_display();
|
refresh_display();
|
||||||
}
|
}
|
||||||
|
|
||||||
var enter_button = func() {
|
var enter_button = func() { #manage enter button, depends of displayed screen
|
||||||
isOn == 1 or return;
|
isOn == 1 or return;
|
||||||
screen[displayed_screen].enter();
|
screen[displayed_screen].enter();
|
||||||
refresh_display();
|
refresh_display();
|
||||||
}
|
}
|
||||||
|
|
||||||
var escape_button = func() {
|
var escape_button = func() { #manage escape button, depends of displayed screen
|
||||||
isOn == 1 or return;
|
isOn == 1 or return;
|
||||||
screen[displayed_screen].escape();
|
screen[displayed_screen].escape();
|
||||||
refresh_display();
|
refresh_display();
|
||||||
}
|
}
|
||||||
|
|
||||||
var start_button = func() {
|
var start_button = func() { #manage start button, depends of displayed screen
|
||||||
isOn == 1 or return;
|
isOn == 1 or return;
|
||||||
screen[displayed_screen].start();
|
screen[displayed_screen].start();
|
||||||
refresh_display();
|
refresh_display();
|
||||||
}
|
}
|
||||||
|
|
||||||
var left_knob = func(dir) {
|
var left_knob = func(dir) { #manage left button, cycle in mode's pages if not blocked
|
||||||
isOn == 1 or return;
|
isOn == 1 or return;
|
||||||
page = cycle(size(page_list[mode]), page, dir);
|
if (blocked == 0) {
|
||||||
if (blocked == 0) displayed_screen = page_list[mode][page];
|
page = cycle(size(page_list[mode]), page, dir);
|
||||||
|
displayed_screen = page_list[mode][page];
|
||||||
|
}
|
||||||
refresh_display();
|
refresh_display();
|
||||||
}
|
}
|
||||||
|
|
||||||
var select_mode = func(dir) {
|
var select_mode = func(dir) { #manage mode knob, cycle into available modes
|
||||||
isOn == 1 or return;
|
isOn == 1 or return;
|
||||||
blocked = 0;
|
blocked = 0;
|
||||||
if (displayed_screen != 0) {
|
if (displayed_screen != 0) {
|
||||||
displayed_screen = 0; #screenModeAndSettings
|
displayed_screen = 0; #screenModeAndSettings
|
||||||
page = 0;
|
page = 0;
|
||||||
screen[displayed_screen].changemode(0);
|
mode = 0;
|
||||||
}
|
}
|
||||||
else
|
elsif (page == 0)
|
||||||
screen[displayed_screen].changemode(dir);
|
screen[0].mode_ = cycle(size(screen[0].available_modes), screen[0].mode_, dir);
|
||||||
refresh_display();
|
refresh_display();
|
||||||
}
|
}
|
||||||
|
|
||||||
var switch_ON_OFF = func() {
|
var switch_ON_OFF = func() { #manage ON/OFF knob
|
||||||
if (isOn) {
|
if (isOn) {
|
||||||
isOn = 0;
|
isOn = 0;
|
||||||
for (var i = 0; i < 5; i += 1) line[i].setValue("");
|
for (var i = 0; i < LINES; i += 1) line[i].setValue("");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
isOn = 1;
|
isOn = 1;
|
||||||
|
@ -111,33 +112,35 @@ var switch_ON_OFF = func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
### useful funcs #########################################################
|
### useful funcs #########################################################
|
||||||
var display = func () {
|
var display = func () { #display the array line[]
|
||||||
for (var i = 0; i < 5; i += 1) line[i].setValue(arg[0][i]);
|
for (var i = 0; i < LINES; i += 1) line[i].setValue(arg[0][i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
var browse = func (entries_nbr, index_pointer, index_page,dir) {
|
var browse = func (entries_nbr, index_pointer, index_page,dir) {
|
||||||
nl = entries_nbr - (index_page * 5) > 5 ? 5 : math.mod(entries_nbr - (index_page * 5), 5);
|
#browse multipaged entries, returns [pointer in page, page]
|
||||||
|
nl = entries_nbr - (index_page * LINES) > LINES ? LINES : math.mod(entries_nbr - (index_page * LINES), LINES);
|
||||||
if (index_pointer + 1 == nl) {
|
if (index_pointer + 1 == nl) {
|
||||||
np = int(entries_nbr / 5) + (math.mod(entries_nbr,5) ? 1 : 0);
|
np = int(entries_nbr / LINES) + (math.mod(entries_nbr,LINES) ? 1 : 0);
|
||||||
index_page = cycle(np, index_page, dir);
|
index_page = cycle(np, index_page, dir);
|
||||||
}
|
}
|
||||||
index_pointer = cycle(nl, index_pointer, dir);
|
index_pointer = cycle(nl, index_pointer, dir);
|
||||||
return [index_pointer, index_page];
|
return [index_pointer, index_page];
|
||||||
}
|
}
|
||||||
|
|
||||||
var cycle = func (entries_nbr, actual_entrie, dir) {
|
var cycle = func (entries_nbr, actual_entrie, dir) {
|
||||||
|
#cycle through entries, return entry index
|
||||||
entries_nbr -= 1;
|
entries_nbr -= 1;
|
||||||
if (dir == 1 and actual_entrie == entries_nbr) return 0;
|
if (dir == 1 and actual_entrie == entries_nbr) return 0;
|
||||||
elsif (dir == -1 and actual_entrie == 0) return entries_nbr;
|
elsif (dir == -1 and actual_entrie == 0) return entries_nbr;
|
||||||
else return actual_entrie + dir;
|
else return actual_entrie + dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
var refresh_display = func() {
|
var refresh_display = func() { #refresh displayed lines, settimer if necessary
|
||||||
screen[displayed_screen].lines();
|
screen[displayed_screen].lines();
|
||||||
if (isOn and 0 < displayed_screen < 5 ) settimer(func { refresh_display(); }, freq, 1);
|
if (isOn and 0 < displayed_screen < 5 ) settimer(func { refresh_display(); }, freq, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
var seconds_to_string = func (time) {
|
var seconds_to_string = func (time) { #converts secs (double) in string "hh:mm:ss"
|
||||||
var hh = int(time / 3600);
|
var hh = int(time / 3600);
|
||||||
if (hh > 100) return "--:--:--";
|
if (hh > 100) return "--:--:--";
|
||||||
var mm = int((time - (hh * 3600)) / 60);
|
var mm = int((time - (hh * 3600)) / 60);
|
||||||
|
@ -146,7 +149,7 @@ var seconds_to_string = func (time) {
|
||||||
}
|
}
|
||||||
|
|
||||||
### route management ######################################################
|
### route management ######################################################
|
||||||
var list_routes = func {
|
var list_routes = func { #load preprogrammed tasks
|
||||||
routes = [];
|
routes = [];
|
||||||
var path = getprop("/sim/fg-home") ~ "/Routes";
|
var path = getprop("/sim/fg-home") ~ "/Routes";
|
||||||
var s = io.stat(path);
|
var s = io.stat(path);
|
||||||
|
@ -163,7 +166,7 @@ var list_routes = func {
|
||||||
return size(routes);
|
return size(routes);
|
||||||
}
|
}
|
||||||
|
|
||||||
var add_waypoint = func (ID, name, type, coord) {
|
var add_waypoint = func (ID, name, type, coord) { #add a waypoint to a route
|
||||||
var waypoint = gps_data.getNode("route/Waypoint["~screenWaypointsList.n~"]/",1);
|
var waypoint = gps_data.getNode("route/Waypoint["~screenWaypointsList.n~"]/",1);
|
||||||
screenWaypointsList.n += 1;
|
screenWaypointsList.n += 1;
|
||||||
waypoint.getNode("ID",1).setValue(ID);
|
waypoint.getNode("ID",1).setValue(ID);
|
||||||
|
@ -175,7 +178,8 @@ var add_waypoint = func (ID, name, type, coord) {
|
||||||
waypoint.getNode("waypoint-type",1).setValue(type);
|
waypoint.getNode("waypoint-type",1).setValue(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
var save_route = func {
|
var save_route = func { #save the route
|
||||||
|
screenWaypointsList.n != 0 or return;
|
||||||
var first_id = gps_data.getNode("route/Waypoint/ID").getValue();
|
var first_id = gps_data.getNode("route/Waypoint/ID").getValue();
|
||||||
var last_id = gps_data.getNode("route/Waypoint["~(screenWaypointsList.n - 1)~"]/ID").getValue();
|
var last_id = gps_data.getNode("route/Waypoint["~(screenWaypointsList.n - 1)~"]/ID").getValue();
|
||||||
var path = getprop("/sim/fg-home") ~ "/Export/"~first_id~"-"~last_id~".xml";
|
var path = getprop("/sim/fg-home") ~ "/Export/"~first_id~"-"~last_id~".xml";
|
||||||
|
@ -185,7 +189,7 @@ var save_route = func {
|
||||||
fgcommand("savexml", args);
|
fgcommand("savexml", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
var waypointAlert = func {
|
var waypointAlert = func { #alert pilot about waypoint approach
|
||||||
mode > 0 or return;
|
mode > 0 or return;
|
||||||
var ttw = gps_wp.getNode("wp[1]/TTW",1).getValue();
|
var ttw = gps_wp.getNode("wp[1]/TTW",1).getValue();
|
||||||
var ttw_secs = 9999;
|
var ttw_secs = 9999;
|
||||||
|
@ -197,12 +201,12 @@ var waypointAlert = func {
|
||||||
else
|
else
|
||||||
gps_data.getNode("waypoint-alert",1).setBoolValue(0);
|
gps_data.getNode("waypoint-alert",1).setBoolValue(0);
|
||||||
|
|
||||||
if (mode == 3 and ttw_secs < thresold_next_waypoint)
|
if (mode == 4 and ttw_secs < thresold_next_waypoint)
|
||||||
screenNavigationMain.nextWaypoint();
|
screenNavigationMain.nextWaypoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
### turnpoints management ######################################################
|
### turnpoints management ######################################################
|
||||||
var load_bookmarks = func {
|
var load_bookmarks = func { #load turnpoints
|
||||||
var n = 0;
|
var n = 0;
|
||||||
gps_data.getNode("bookmarks",1).removeChildren("bookmark");
|
gps_data.getNode("bookmarks",1).removeChildren("bookmark");
|
||||||
var file = getprop("/sim/fg-home") ~ "/Export/bookmarks.xml";
|
var file = getprop("/sim/fg-home") ~ "/Export/bookmarks.xml";
|
||||||
|
@ -217,7 +221,7 @@ var load_bookmarks = func {
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
var save_bookmarks = func {
|
var save_bookmarks = func { #save turnpoints
|
||||||
var path = getprop("/sim/fg-home") ~ "/Export/bookmarks.xml";
|
var path = getprop("/sim/fg-home") ~ "/Export/bookmarks.xml";
|
||||||
var args = props.Node.new({ filename : path });
|
var args = props.Node.new({ filename : path });
|
||||||
var export = args.getNode("data", 1);
|
var export = args.getNode("data", 1);
|
||||||
|
@ -225,30 +229,39 @@ var save_bookmarks = func {
|
||||||
fgcommand("savexml", args);
|
fgcommand("savexml", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
var add_bookmark = func (ID, name, type, coord) {
|
var add_bookmark = func (ID, name, type, coord) { #add turnpoint
|
||||||
var bookmark = gps_data.getNode("bookmarks/bookmark["~screenTurnpointSelect.n~"]/",1);
|
var bookmark = gps_data.getNode("bookmarks/bookmark["~screenTurnpointSelect.n~"]/",1);
|
||||||
screenTurnpointSelect.n += 1;
|
screenTurnpointSelect.n += 1;
|
||||||
bookmark.getNode("ID",1).setValue(ID);
|
bookmark.getNode("ID",1).setValue(ID);
|
||||||
bookmark.getNode("latitude-deg",1).setDoubleValue(coord[0]);
|
bookmark.getNode("latitude-deg",1).setDoubleValue(coord[0]);
|
||||||
bookmark.getNode("longitude-deg",1).setDoubleValue(coord[1]);
|
bookmark.getNode("longitude-deg",1).setDoubleValue(coord[1]);
|
||||||
bookmark.getNode("altitude-ft",1).setDoubleValue(coord[2]*alt_conv[1][0]);
|
bookmark.getNode("altitude-ft",1).setDoubleValue(coord[2]*alt_conv[1][0]);
|
||||||
bookmark.getNode("name",1).setValue(name);
|
|
||||||
bookmark.getNode("desc",1).setValue("no infos");
|
bookmark.getNode("desc",1).setValue("no infos");
|
||||||
|
bookmark.getNode("name",1).setValue(name);
|
||||||
bookmark.getNode("waypoint-type",1).setValue(type);
|
bookmark.getNode("waypoint-type",1).setValue(type);
|
||||||
save_bookmarks();
|
save_bookmarks();
|
||||||
}
|
}
|
||||||
|
|
||||||
var EditMode = func (length, start_command, start_func, backmode, backpage, numcar = 0) {
|
var EditMode = func (length, title, start_command, numcar = 0) {
|
||||||
#screenEdit.previous_mode = backmode;
|
#special mode for editing simple text
|
||||||
#screenEdit.previous_page = backpage;
|
screenEdit.previous_mode = mode;
|
||||||
|
screenEdit.previous_page = page;
|
||||||
mode = 5; #ID edition
|
mode = 5; #ID edition
|
||||||
page = 0;
|
page = 0;
|
||||||
screenEdit.init(length, start_command, start_func, backmode, backpage, numcar = 0);
|
screenEdit.init(length, title, start_command, numcar);
|
||||||
}
|
}
|
||||||
|
|
||||||
### initialisation stuff ###################################################
|
### initialisation stuff ###################################################
|
||||||
var init = func() {
|
var init = func() {
|
||||||
for (var i = 0; i < 5; i += 1) {
|
mode = 0;
|
||||||
|
page = 0;
|
||||||
|
displayed_screen = 0; #screenModeAndSettings
|
||||||
|
blocked = 0; #unlock left_knob
|
||||||
|
isOn = 0; #start OFF
|
||||||
|
startpos = nil; #unset start position
|
||||||
|
waypointindex = 0; #route waypoint index on beginning
|
||||||
|
screen = []; #empty screens
|
||||||
|
for (var i = 0; i < LINES; i += 1) {
|
||||||
append(line, props.globals.getNode("/instrumentation/zkv500/line[" ~ i ~ "]", 1));
|
append(line, props.globals.getNode("/instrumentation/zkv500/line[" ~ i ~ "]", 1));
|
||||||
line[i].setValue("");
|
line[i].setValue("");
|
||||||
}
|
}
|
||||||
|
|
389
Aircraft/Instruments-3d/zkv500/manual.txt
Normal file
389
Aircraft/Instruments-3d/zkv500/manual.txt
Normal file
|
@ -0,0 +1,389 @@
|
||||||
|
############## GPL
|
||||||
|
# GPS ZKV500 # Sébastien MARQUE
|
||||||
|
############## 2008, Paris (France)
|
||||||
|
|
||||||
|
note that it is still under heavy development, some functions planned haven't
|
||||||
|
been 100% tested yet... there surely will be bugs or errors (most of the time:
|
||||||
|
nasal runtime error : props.setValue() with non number, etc.)
|
||||||
|
|
||||||
|
|
||||||
|
CONTENTS
|
||||||
|
=========
|
||||||
|
1. A bit of history
|
||||||
|
2. Install onboard
|
||||||
|
1. Normal installation
|
||||||
|
2. Debugging installation
|
||||||
|
3. Without 3D interface
|
||||||
|
3. Global presentation
|
||||||
|
4. User's Manual
|
||||||
|
1. Powering ON
|
||||||
|
2. List of screens
|
||||||
|
3. The modes
|
||||||
|
4. Editing some text
|
||||||
|
5. FG integration
|
||||||
|
6. Examples
|
||||||
|
7. The future
|
||||||
|
|
||||||
|
1. A BIT OF HISTORY
|
||||||
|
===================
|
||||||
|
Don't search on the market this device, it doesn't exists! :p Indeed I was
|
||||||
|
looking how to create a GPS device in my favorite aircraft, I found the
|
||||||
|
nice 3D object in the not less nice Grob-G115, which it was told me it
|
||||||
|
is intented for the LX5000 gps (http://www.wingsandwheels.com/manuals.htm).
|
||||||
|
|
||||||
|
So I began to write some nasal code, using the C++ implementation of KLN89
|
||||||
|
already built-in FG, to fit as much as possible the LX5000 specifications.
|
||||||
|
But after some tries, I began to create on my own way the interface (which
|
||||||
|
is much more funny for me than following a manual :)). The ZKV500 was born.
|
||||||
|
(read ZaKharoV, which is my current nickname, from Proktor Zakharov in Sid
|
||||||
|
Meyer's Alpha Centauri game :))
|
||||||
|
It keeps by default the very nice 3D object from Jon Stockill, a bit modified.
|
||||||
|
I created also for this device a special font in order to make the LCD diplay
|
||||||
|
more... lcd-compliant (see Fonts/lcd.README).
|
||||||
|
|
||||||
|
2. INSTALL THE ZKV500 ONBOARD
|
||||||
|
=============================
|
||||||
|
|
||||||
|
1. Normal installation
|
||||||
|
|
||||||
|
For now the ZKV500 seats in Aircraft/Instruments-3d/zvk500/, making it easily
|
||||||
|
available for all aircrafts. To install it, just add these lines in your config
|
||||||
|
files, inside the <nasal> section:
|
||||||
|
<zkv500>
|
||||||
|
<file>Aircraft/Instruments-3d/zkv500/ZKV500.nas</file>
|
||||||
|
<file>Aircraft/Instruments-3d/zkv500/MainScreens.nas</file>
|
||||||
|
<file>Aircraft/Instruments-3d/zkv500/TurnpointScreens.nas</file>
|
||||||
|
<file>Aircraft/Instruments-3d/zkv500/TaskScreens.nas</file>
|
||||||
|
<file>Aircraft/Instruments-3d/zkv500/AirportScreens.nas</file>
|
||||||
|
</zkv500>
|
||||||
|
[example from Lionceau: Aircraft/Lionceau/lionceau-base.xml]
|
||||||
|
Please note that <zkv500> is mandatory for namespaces reasons.
|
||||||
|
|
||||||
|
Then in your panel configuration file, just put the 3D model, as usual:
|
||||||
|
<!-- GPS -->
|
||||||
|
<model>
|
||||||
|
<path>Aircraft/Instruments-3d/zkv500/ZKV500.xml</path>
|
||||||
|
<offsets>
|
||||||
|
<x-m> 0.002 </x-m>
|
||||||
|
<y-m> -0.051 </y-m>
|
||||||
|
<z-m> -0.022 </z-m>
|
||||||
|
</offsets>
|
||||||
|
</model>
|
||||||
|
[example from Lionceau: Aircraft/Lionceau/Models/Panel/front-panel.xml]
|
||||||
|
Your ZKV500 is ready to be powered on!
|
||||||
|
|
||||||
|
The ZKV500 has IO capacities: routes are red from $FGHOME/Routes and
|
||||||
|
written in $FGHOME/Export, the bookmarks are red and written in
|
||||||
|
$FGHOME/Export/bookmarks.xml
|
||||||
|
|
||||||
|
An easy way to populate your $FGHOME/Routes directory is a perl script
|
||||||
|
of my own (see the end of file for an how-to). You can also editing by
|
||||||
|
hand, the format is simple and conform to the format used by the KLN89
|
||||||
|
<PropertyList>
|
||||||
|
<Waypoint n="0">
|
||||||
|
<ID type="double">TL</ID>
|
||||||
|
<latitude-deg type="double">43.28838900</latitude-deg>
|
||||||
|
<longitude-deg type="double">000.04963900</longitude-deg>
|
||||||
|
<altitude-ft type="double">0</altitude-ft>
|
||||||
|
<waypoint-type type="string">NBD</waypoint-type>
|
||||||
|
<name type="string">TARBES NDB</name>
|
||||||
|
<desc type="string">Xroads freq: 321</desc>
|
||||||
|
</Waypoint>
|
||||||
|
<Waypoint n="1">
|
||||||
|
<ID type="string">LFCB</ID>
|
||||||
|
<latitude-deg type="double">42.800000</latitude-deg>
|
||||||
|
<longitude-deg type="double">000.600000</longitude-deg>
|
||||||
|
<altitude-ft type="double">2028</altitude-ft>
|
||||||
|
<waypoint-type type="string">APT</waypoint-type>
|
||||||
|
<name type="string">Bagneres de Luchon</name>
|
||||||
|
<desc type="string">In a valley</desc>
|
||||||
|
</Waypoint>
|
||||||
|
</PropertyList>
|
||||||
|
The less easy way is to edit your flightplan direcly from the ZKV500, but
|
||||||
|
as it has very limited editing capacities, and the search of already-known
|
||||||
|
waypoints is limited to airports, it is not a really recommended way.
|
||||||
|
|
||||||
|
The $FGHOME/Export/bookmarks.xml file contains favorites points, it has
|
||||||
|
quite the same format than a route file:
|
||||||
|
<PropertyList>
|
||||||
|
...
|
||||||
|
<bookmark n="2">
|
||||||
|
<ID type="string">LFBT</ID>
|
||||||
|
<latitude-deg type="double">43.178643</latitude-deg>
|
||||||
|
<longitude-deg type="double">-0.006341</longitude-deg>
|
||||||
|
<altitude-ft type="double">1179.785445</altitude-ft>
|
||||||
|
<name type="string">Tarbes Ossun Lourdes</name>
|
||||||
|
<desc type="string">no infos</desc>
|
||||||
|
<waypoint-type type="string">APT</waypoint-type>
|
||||||
|
</bookmark>
|
||||||
|
...
|
||||||
|
</PropertyList>
|
||||||
|
The ZKV500 is quite useful to create bookmarks on the fly.
|
||||||
|
|
||||||
|
2. Debugging installation
|
||||||
|
|
||||||
|
if you want to debug the nasal, you can use the "debugging tool" I've created:
|
||||||
|
- comment in your aircraft files all gps-related installation
|
||||||
|
- edit the Aircraft/Instruments-3d/zkv500/*.nas files with your favourite
|
||||||
|
text editor
|
||||||
|
- in the Nasal console from FGside type:
|
||||||
|
var zkv_dir = getprop("/sim/fg-root") ~ "/Aircraft/Instruments-3d/zkv500/";
|
||||||
|
io.load_nasal(zkv_dir ~ "zkv_dbg.nas", "zkv_dbg");
|
||||||
|
zkv_dbg.reload_zkv_code();
|
||||||
|
- click on "Execute"
|
||||||
|
- find errors
|
||||||
|
- modify source code then re-click on "Execute" until satisfaction (or death :D)
|
||||||
|
|
||||||
|
3. Without 3D interface
|
||||||
|
|
||||||
|
if you want to use the zkv500 without the 3D interface and all installation steps
|
||||||
|
as described above, type in a Nasal console:
|
||||||
|
var zkv_dir = getprop("/sim/fg-root") ~ "/Aircraft/Instruments-3d/zkv500/";
|
||||||
|
io.load_nasal(zkv_dir ~ "zkv_dbg.nas", "zkv_dbg");
|
||||||
|
zkv_dbg.test();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3. GLOBAL PRESENTATION
|
||||||
|
======================
|
||||||
|
The interface is simple:
|
||||||
|
(http://seb.marque.free.fr/fichiers/flightgear/zkv500/presentation.png)
|
||||||
|
* 4 knobs turning left (left mouse clic) or right (right mous clic)
|
||||||
|
* 3 white buttons
|
||||||
|
* 1 LCD display
|
||||||
|
* 2 LEDs (red and green)
|
||||||
|
|
||||||
|
enter escape start
|
||||||
|
button button button
|
||||||
|
PAGE|------------------------|SELECT
|
||||||
|
KNOB| |KNOB
|
||||||
|
| LCD DISPLAY |
|
||||||
|
| 5 LINES |
|
||||||
|
MODE| |ON/OFF
|
||||||
|
KNOB|------------------------|KNOB
|
||||||
|
red green
|
||||||
|
led led
|
||||||
|
|
||||||
|
-> PAGE knob allows you to cycle in the different pages available for
|
||||||
|
each mode.
|
||||||
|
-> SELECT knob allows yo to navigate in a page, or select element, or
|
||||||
|
edit some simple text (depending of screen).
|
||||||
|
-> MODE knob allows you to select a mode, and acces to the ZKV500 settings
|
||||||
|
you can access this knob at any time, any screen.
|
||||||
|
-> ON/OFF knob allows you to turn ON and OFF the ZKV500, note it is a knob
|
||||||
|
because I plan to associate some sounds with the ZKV500, this knob then
|
||||||
|
could be used to change the volume.
|
||||||
|
|
||||||
|
The goal of each button depends of the displayed screen.
|
||||||
|
|
||||||
|
4. USER'S MANUAL
|
||||||
|
================
|
||||||
|
1. Powering ON
|
||||||
|
To power ON, just left click on the ON/OFF knob. Clicking again wil make it
|
||||||
|
turning OFF. When powered you are on the ModeAndSettings screen.
|
||||||
|
|
||||||
|
2. Screens list
|
||||||
|
*** ModeAndSettings ***
|
||||||
|
From this screen you can change from a mode to another mode (see 4.3 Modes, below)
|
||||||
|
START...enter in a mode
|
||||||
|
PAGE....enter in settings pages (cycle)
|
||||||
|
SELECT..modify settings
|
||||||
|
|
||||||
|
the available settings are:
|
||||||
|
* units
|
||||||
|
you can change the displayed unit for altitude, distance and speed.
|
||||||
|
the units are long named, on other screens only short name wilm be
|
||||||
|
displayed.
|
||||||
|
* thresolds
|
||||||
|
you can change the thresold from when the ZKV500 will alert you about
|
||||||
|
next waypoint approach, or will load the next waypoint into calculation.
|
||||||
|
|
||||||
|
*** PositionMain ***
|
||||||
|
This page gives you infos about the aircraft position.
|
||||||
|
You find it in every modes.
|
||||||
|
ENTER...save the position as a bookmark (entering in Edit screen)
|
||||||
|
|
||||||
|
LAT: latitude in deg:min:sec
|
||||||
|
LON: longitude in deg:min:sec
|
||||||
|
ALT: altitude
|
||||||
|
HDG: geographic cap (! not magnetic cap, or aircraft heading)
|
||||||
|
SPD: speed
|
||||||
|
|
||||||
|
*** Odometers ***
|
||||||
|
This screen gives you odo-values. You can find it in every modes.
|
||||||
|
ESCAPE...reset odometers, except TRIP
|
||||||
|
|
||||||
|
ODO: travelled distance
|
||||||
|
TRIP: total travelled distance
|
||||||
|
TIME: elapsed time from last reset
|
||||||
|
AVG HDG: average heading
|
||||||
|
AVG SPD: average speed
|
||||||
|
|
||||||
|
*** WindInfos ***
|
||||||
|
This screens gives you infos about wind as it should be calculated by the
|
||||||
|
GPS, indeed, as the calculation is already done elsewhere, it takes the value
|
||||||
|
from /environnement/* node (btw I don't really know how to calculate correctly
|
||||||
|
these values). You need to have a airspped > 10kts for having it work. This
|
||||||
|
screen is available on every modes
|
||||||
|
|
||||||
|
SPEED: windspeed
|
||||||
|
FROM: the direction where the wind come from (geographic North)
|
||||||
|
|
||||||
|
*** NavigationMain ***
|
||||||
|
This screen gives the related position of the aircraft about the calcualted
|
||||||
|
route. It is only available in TURNPOINT and TASK modes.
|
||||||
|
|
||||||
|
ENTER...TURNPOINT mode: add the actual position to the route,
|
||||||
|
TASK mode: jump to next waypoint
|
||||||
|
START...save the route (mode TURNPOINT only)
|
||||||
|
|
||||||
|
ID: Id of the waypoint to go [waypoint type]
|
||||||
|
BRG: bearing from the aircraft to the waypoint (geographic)
|
||||||
|
DST: remaining distance
|
||||||
|
XCRS: course error in degree (in distance unit)
|
||||||
|
TTW: remaining estimated time
|
||||||
|
The graph represent the position of the aircraft along the leg. Each + means 1°,
|
||||||
|
the | symbol represents the route, the little aircraft represents... the aircraft.
|
||||||
|
|
||||||
|
*** AirportMain ***
|
||||||
|
This screen gives infos about the nearest, or a specific searched airport (see
|
||||||
|
SearcAirport screen, below). It is only reachable from AIRPORT mode.
|
||||||
|
|
||||||
|
ENTER...add the airport to route
|
||||||
|
ESCAPE..get the nearest airport
|
||||||
|
START...add airport to bookmarks, and enter TURNPOINT mode, to go directly
|
||||||
|
|
||||||
|
NEAREST or SEARCHED APT: OACI code of airport
|
||||||
|
ELEV: airport altitude
|
||||||
|
DIST: distance between aircraft and airport
|
||||||
|
BRG: bearing from aircraft to airport (geographic)
|
||||||
|
RWY: best runway calculated from known wind, it is to say not really useful
|
||||||
|
when airport is very far away...
|
||||||
|
ETE: estimated time enroute to go
|
||||||
|
|
||||||
|
*** AirportInfos ***
|
||||||
|
This screen gives infos about the airport (nearest or searched). It is only
|
||||||
|
reachable from AIRPORT mode.
|
||||||
|
|
||||||
|
SELECT...navigate in the runway list (not yet implemented)
|
||||||
|
|
||||||
|
First line gives the full name of airport
|
||||||
|
Lines below show the runways with the format
|
||||||
|
heading (length in meters / width in meters)
|
||||||
|
|
||||||
|
*** SearchAirport ***
|
||||||
|
This screen allows you to search an airport from OACI code. It is reachable from
|
||||||
|
AIRPORT mode.
|
||||||
|
If the search is successful, the AirportMain screen is shown, in other case the text
|
||||||
|
is erased, and you are invited to retry.
|
||||||
|
|
||||||
|
SELECT...modify letter (from A to Z then 0 to 9, cycled)
|
||||||
|
ENTER....next step
|
||||||
|
ESCAPE...back to AirportMain screen, without search
|
||||||
|
START....search the given OACI code
|
||||||
|
|
||||||
|
*** TurnpointSelect ***
|
||||||
|
This screen shows a list of already bookmarked gps points. It is only available
|
||||||
|
in TURNPOINT mode.
|
||||||
|
|
||||||
|
SELECT...navigate through the list (eventually through multiple pages)
|
||||||
|
START....begin the navigation from actual position to the bookmark
|
||||||
|
|
||||||
|
*** TurnpointInfos ***
|
||||||
|
This screen is not yet implemented. It will gives infos about the bookmark
|
||||||
|
|
||||||
|
*** TaskSelect ***
|
||||||
|
This screen allows you to choose a route (if one available). It is only available
|
||||||
|
in TASK mode.
|
||||||
|
|
||||||
|
SELECT...navigate through the routes list (eventually through multiple pages)
|
||||||
|
START....load the route, and begins navigation
|
||||||
|
|
||||||
|
*** WaypointInfos ***
|
||||||
|
Not yet implemented, will give infos about waypoint. Only available in TASK mode.
|
||||||
|
|
||||||
|
*** WaypointsList ***
|
||||||
|
This screen shows the list of waypoint loaded from a route.
|
||||||
|
SELECT...navigate through the list
|
||||||
|
|
||||||
|
*** WaypointEdit ***
|
||||||
|
This screen allows you to name a gps point in order to bookmark it.
|
||||||
|
|
||||||
|
SELECT...cycle letters (from A to Z then 1 to 9)
|
||||||
|
ENTER....next step
|
||||||
|
ESCAPE...abort saving bookmark
|
||||||
|
START....save bookmark
|
||||||
|
|
||||||
|
3. the 4 modes
|
||||||
|
*** POSITION ***
|
||||||
|
The simpliest one, just give information about the aircraft position. You can
|
||||||
|
save bookmarks from this mode (pressing ENTER in PositionMain screen).
|
||||||
|
PAGE...cycle through these screens (both ways):
|
||||||
|
PositionMain, Odometers, WindInfos
|
||||||
|
|
||||||
|
*** AIRPORT ***
|
||||||
|
Useful to know wher you can put you aircraft safely on the ground, gives other infos
|
||||||
|
as the best runway, it is possible to search an airport (turn the PAGE knob until
|
||||||
|
Search airport page), add the airport to a route or as a bookmark (automatically
|
||||||
|
called by airports ID and name).
|
||||||
|
PAGE...cycle through these screens (both ways)
|
||||||
|
AirportMain, NavigationMain, PositionMain, Odometers, WindInfos, AirportInfos, SearchAirport
|
||||||
|
|
||||||
|
*** TURNPOINT ***
|
||||||
|
Useful mode to join a specific point of interest, or to navigate around.
|
||||||
|
PAGE...cycle through these screens (both ways)
|
||||||
|
TurnpointSelect, NavigationMain, PositionMain, Odometers, WindInfos, TurnpointInfos
|
||||||
|
|
||||||
|
*** TASK ***
|
||||||
|
Most useful mode :). Follow the route to go through long distances, without being
|
||||||
|
lost at anytime (even with no VOR or NDB near enough to get capted by radios). Or
|
||||||
|
if you aren't IFR skilled :D
|
||||||
|
When approaching a waypoint, a red led blink (this can be set in ModeAndSettings screens)
|
||||||
|
When on the point (idem), it loads autmatically the next point and calculate the leg infos
|
||||||
|
When the last point is reached, it come back to TaskSelect screen to allow chosing an other
|
||||||
|
route.
|
||||||
|
PAGE...cycle through these screens (both ways)
|
||||||
|
TaskSelect, NavigationMain, PositionMain, Odometers, WindInfos, WaypointInfos, WaypointsList
|
||||||
|
|
||||||
|
5. FG INTEGRATION
|
||||||
|
=================
|
||||||
|
You can change the waypoints directly from the property tree (/instrumentation/gps)
|
||||||
|
or using the GUI (Menu Instruments -> GPS Settings).
|
||||||
|
Please note that, at this stage of development, I haven't yes set listeners
|
||||||
|
on the properties, when changing the waypoint, new route is automatically
|
||||||
|
calculated, but changing them don't call yet the correct mode and page.
|
||||||
|
|
||||||
|
6. PRACTICAL EXAMPLES
|
||||||
|
=====================
|
||||||
|
|
||||||
|
7. THE FUTURE
|
||||||
|
=============
|
||||||
|
The ZKV500 still lacks many features I plan to implement. I stop adding features
|
||||||
|
for now, as I want it to be the more bug-free possible before creating other bugs.
|
||||||
|
1. PLANNED FEATURES
|
||||||
|
* integrated help
|
||||||
|
* description pages (waypoints and airports)
|
||||||
|
* more useful informations
|
||||||
|
* make use of green led (for which use? surely depends of the above)
|
||||||
|
* altitude control
|
||||||
|
* two ways routes (toward and back)
|
||||||
|
|
||||||
|
2. PLANNED FEATURES LIMITED BY FG "API'S"
|
||||||
|
* search for VOR/TAC, NDB and FIX capacities
|
||||||
|
|
||||||
|
2. NOT PLANNED FEATURES
|
||||||
|
* graphical view of regions
|
||||||
|
|
||||||
|
8. ANNEXES
|
||||||
|
==========
|
||||||
|
1. creating flightplans with ./flightplan
|
||||||
|
You can get ./flightplan from this link: http://seb.marque.free.fr/fichiers/scripts/perl/flightplan
|
||||||
|
Make it executable, best to set $FGROOT and $FGHOME to respectives folders
|
||||||
|
For creating a flightplan from LFPT to LFBD:
|
||||||
|
$ ./flightplan -d lfpt -a lfbd --wpt
|
||||||
|
This will write in $FGHOME/Routes a file named lfpt-lfbd.xml, suitable for the
|
||||||
|
ZKV500
|
||||||
|
|
||||||
|
Sébastien MARQUE
|
||||||
|
seb.marque@free.fr
|
||||||
|
|
108
Aircraft/Instruments-3d/zkv500/zkv_dbg.nas
Normal file
108
Aircraft/Instruments-3d/zkv500/zkv_dbg.nas
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
var dialog = nil;
|
||||||
|
var namenode = nil;
|
||||||
|
|
||||||
|
var close = func {
|
||||||
|
zkv500.isOn = 0;
|
||||||
|
fgcommand("dialog-close", namenode);
|
||||||
|
delete(gui.dialog, "\"zkv500\"");
|
||||||
|
dialog = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
var _title = func {
|
||||||
|
var titlebar = dialog.addChild("group");
|
||||||
|
titlebar.set("layout", "hbox");
|
||||||
|
var wdg = titlebar.addChild("text");
|
||||||
|
wdg.set("label", "test zkv500");
|
||||||
|
titlebar.addChild("empty").set("stretch", 1);
|
||||||
|
var wdg = titlebar.addChild("button");
|
||||||
|
wdg.node.setValues({"pref-width": 16, "pref-height": 16, legend: "", default: 0});
|
||||||
|
wdg.setBinding("nasal", "zkv_dbg.close()");
|
||||||
|
}
|
||||||
|
|
||||||
|
var _top_buttons = func {
|
||||||
|
dialog.addChild("hrule");
|
||||||
|
var buttons = dialog.addChild("group");
|
||||||
|
buttons.set("layout", "hbox");
|
||||||
|
var wdg = buttons.addChild("button");
|
||||||
|
wdg.node.setValues({legend: "P", "pref-height": 20});
|
||||||
|
wdg.setBinding("nasal", "zkv500.left_knob(1)");
|
||||||
|
var wdg = buttons.addChild("button");
|
||||||
|
wdg.node.setValues({legend: "en", "pref-height": 20});
|
||||||
|
wdg.setBinding("nasal", "zkv500.enter_button()");
|
||||||
|
var wdg = buttons.addChild("button");
|
||||||
|
wdg.node.setValues({legend: "es", "pref-height": 20});
|
||||||
|
wdg.setBinding("nasal", "zkv500.escape_button()");
|
||||||
|
var wdg = buttons.addChild("button");
|
||||||
|
wdg.node.setValues({legend: "st", "pref-height": 20});
|
||||||
|
wdg.setBinding("nasal", "zkv500.start_button()");
|
||||||
|
var wdg = buttons.addChild("button");
|
||||||
|
wdg.node.setValues({legend: "S", "pref-height": 20});
|
||||||
|
wdg.setBinding("nasal", "zkv500.right_knob(1)");
|
||||||
|
}
|
||||||
|
|
||||||
|
var _content = func {
|
||||||
|
dialog.addChild("hrule");
|
||||||
|
var content = dialog.addChild("group");
|
||||||
|
content.set("layout", "table");
|
||||||
|
content.set("default-padding", 0);
|
||||||
|
for (var i = 0; i < 5; i += 1) {
|
||||||
|
var line = content.addChild("text");
|
||||||
|
line.node.setValues({"row":i,"col":0,"label":" "});
|
||||||
|
var line = content.addChild("text");
|
||||||
|
line.node.setValues({
|
||||||
|
"row": i,
|
||||||
|
"col": 1,
|
||||||
|
"property": "/instrumentation/zkv500/line["~i~"]",
|
||||||
|
"halign": "left",
|
||||||
|
"live": 1
|
||||||
|
});
|
||||||
|
var line = content.addChild("text");
|
||||||
|
line.node.setValues({"row":i,"col":2,"label":" "});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var _bottom_buttons = func {
|
||||||
|
dialog.addChild("hrule");
|
||||||
|
var buttons = dialog.addChild("group");
|
||||||
|
buttons.set("layout", "hbox");
|
||||||
|
var wdg = buttons.addChild("button");
|
||||||
|
wdg.node.setValues({legend: "M", "pref-height": 20});
|
||||||
|
wdg.setBinding("nasal", "zkv500.select_mode(1)");
|
||||||
|
buttons.addChild("empty").set("stretch", 1);
|
||||||
|
var wdg = buttons.addChild("button");
|
||||||
|
wdg.node.setValues({legend: "0/1", "pref-height": 20});
|
||||||
|
wdg.setBinding("nasal", "zkv500.switch_ON_OFF()");
|
||||||
|
}
|
||||||
|
|
||||||
|
var reload_zkv_code = func {
|
||||||
|
var zkv500_dir = getprop("/sim/fg-root") ~ "/Aircraft/Instruments-3d/zkv500/";
|
||||||
|
io.load_nasal(zkv500_dir ~ "ZKV500.nas","zkv500");
|
||||||
|
io.load_nasal(zkv500_dir ~ "AirportScreens.nas","zkv500");
|
||||||
|
io.load_nasal(zkv500_dir ~ "TurnpointScreens.nas","zkv500");
|
||||||
|
io.load_nasal(zkv500_dir ~ "MainScreens.nas","zkv500");
|
||||||
|
io.load_nasal(zkv500_dir ~ "TaskScreens.nas","zkv500");
|
||||||
|
print("debugger: zkv500 loaded");
|
||||||
|
zkv500.isOn = 0;
|
||||||
|
zkv500.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
var test = func {
|
||||||
|
dialog == nil or close();
|
||||||
|
reload_zkv_code();
|
||||||
|
|
||||||
|
namenode = props.Node.new({"dialog-name" : "zkv500" });
|
||||||
|
dialog = gui.Widget.new();
|
||||||
|
dialog.set("name", "zkv500");
|
||||||
|
|
||||||
|
dialog.set("layout", "vbox");
|
||||||
|
dialog.set("default-padding", 0);
|
||||||
|
|
||||||
|
_title();
|
||||||
|
_top_buttons();
|
||||||
|
_content();
|
||||||
|
_bottom_buttons();
|
||||||
|
|
||||||
|
fgcommand("dialog-new", dialog.prop());
|
||||||
|
fgcommand("dialog-show", namenode);
|
||||||
|
print("debugger: zkv500 testing interface loaded");
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue