Move more high-level GPS logic to Nasal/XML.
This commit is contained in:
parent
4d3a00bf68
commit
b64dd768d3
3 changed files with 129 additions and 35 deletions
|
@ -1,13 +1,13 @@
|
||||||
# route_manager.nas - default FlightPlan delegate corresponding to the build
|
# route_manager.nas - FlightPlan delegate(s) corresponding to the built-
|
||||||
# in route-manager dialog. Intended to provide a sensible default behaviour,
|
# in route-manager dialog and GPS. Intended to provide a sensible default behaviour,
|
||||||
# but be disabled by an aircraft-specific FMS / GPS system.
|
# but can be disabled by an aircraft-specific FMS / GPS system.
|
||||||
|
|
||||||
var RouteManagerDelegate = {
|
var RouteManagerDelegate = {
|
||||||
new: func(fp) {
|
new: func(fp) {
|
||||||
# if this property is set, don't build a delegate at all
|
# if this property is set, don't build a delegate at all
|
||||||
if (getprop('/autopilot/route-manager/disable-fms'))
|
if (getprop('/autopilot/route-manager/disable-route-manager'))
|
||||||
return nil;
|
return nil;
|
||||||
|
|
||||||
var m = { parents: [RouteManagerDelegate] };
|
var m = { parents: [RouteManagerDelegate] };
|
||||||
m.flightplan = fp;
|
m.flightplan = fp;
|
||||||
return m;
|
return m;
|
||||||
|
@ -86,19 +86,66 @@ var RouteManagerDelegate = {
|
||||||
{
|
{
|
||||||
debug.dump("end of flight-plan, deactivating");
|
debug.dump("end of flight-plan, deactivating");
|
||||||
fgcommand("activate-flightplan", props.Node.new({"activate": 0}));
|
fgcommand("activate-flightplan", props.Node.new({"activate": 0}));
|
||||||
},
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var FMSDelegate = {
|
||||||
|
new: func(fp) {
|
||||||
|
# if this property is set, don't build a delegate at all
|
||||||
|
if (getprop('/autopilot/route-manager/disable-fms'))
|
||||||
|
return nil;
|
||||||
|
|
||||||
|
var m = { parents: [FMSDelegate], flightplan:fp, landingCheck:nil };
|
||||||
|
return m;
|
||||||
|
},
|
||||||
|
|
||||||
|
_landingCheckTimeout: func
|
||||||
|
{
|
||||||
|
var cur = me.flightplan.currentWP();
|
||||||
|
var wow = getprop('gear/gear[0]/wow');
|
||||||
|
var gs = getprop('velocities/groundspeed-kt');
|
||||||
|
if (wow and (gs < 25)) {
|
||||||
|
debug.dump('touchdown on destination runway, end of route.');
|
||||||
|
me.landingCheck.stop();
|
||||||
|
# record touch-down time?
|
||||||
|
me.flightplan.finish();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
waypointsChanged: func
|
waypointsChanged: func
|
||||||
{
|
{
|
||||||
},
|
},
|
||||||
|
|
||||||
|
endOfFlightPlan: func
|
||||||
|
{
|
||||||
|
debug.dump('end of flight-plan');
|
||||||
|
},
|
||||||
|
|
||||||
currentWaypointChanged: func
|
currentWaypointChanged: func
|
||||||
{
|
{
|
||||||
debug.dump('saw current WP changed, now ' ~ me.flightplan.current);
|
if (me.landingCheck != nil) {
|
||||||
|
me.landingCheck.stop();
|
||||||
|
me.landingCheck = nil; # delete timer
|
||||||
|
}
|
||||||
|
|
||||||
|
#debug.dump('saw current WP changed, now ' ~ me.flightplan.current);
|
||||||
|
var active = me.flightplan.currentWP();
|
||||||
|
if (active == nil) return;
|
||||||
|
|
||||||
|
if (active.alt_cstr_type != 'none') {
|
||||||
|
debug.dump('new WP has valid altitude restriction, setting on AP');
|
||||||
|
setprop('/autopilot/settings/target-altitude-ft', active.alt_cstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
var activeRunway = active.runway();
|
||||||
|
if ((activeRunway != nil) and (activeRunway.id == me.flightplan.destination_runway.id)) {
|
||||||
|
me.landingCheck = maketimer(2.0, me, FMSDelegate._landingCheckTimeout);
|
||||||
|
me.landingCheck.start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
# debug.dump('register routemanager delegate factory');
|
registerFlightPlanDelegate(FMSDelegate.new);
|
||||||
|
|
||||||
registerFlightPlanDelegate(RouteManagerDelegate.new);
|
registerFlightPlanDelegate(RouteManagerDelegate.new);
|
||||||
|
|
||||||
|
|
|
@ -11,14 +11,17 @@
|
||||||
var cmd = gps.getNode("command", 1);
|
var cmd = gps.getNode("command", 1);
|
||||||
var scratch = gps.getNode("scratch", 1);
|
var scratch = gps.getNode("scratch", 1);
|
||||||
var scratchValid = scratch.getNode("valid", 1);
|
var scratchValid = scratch.getNode("valid", 1);
|
||||||
|
var searchIsWaypoints = 0;
|
||||||
var updateSearchResults = func
|
var anySpec = 'vor,airport,heliport,ils,seaport,fix,ndb,waypoint,tacan,city,town';
|
||||||
{
|
|
||||||
debug.dump('search results is:', searchResults);
|
|
||||||
|
|
||||||
dlg.getNode("scratch-index", 1).setValue(0);
|
var updateSearchResults = func(isWpts, index = 0)
|
||||||
dlg.getNode("scratch-has-next", 1).setBoolValue(size(searchResults) > 1);
|
{
|
||||||
|
searchIsWaypoints = isWpts;
|
||||||
|
dlg.getNode("scratch-index", 1).setValue(index);
|
||||||
|
|
||||||
|
var lastIndex = size(searchResults) - 1;
|
||||||
|
dlg.getNode("scratch-has-next", 1).setValue((index + 1) < lastIndex);
|
||||||
|
|
||||||
if (size(searchResults) < 1) {
|
if (size(searchResults) < 1) {
|
||||||
scratchValid.setBoolValue(0);
|
scratchValid.setBoolValue(0);
|
||||||
return;
|
return;
|
||||||
|
@ -34,23 +37,33 @@
|
||||||
scratchValid.setBoolValue(0);
|
scratchValid.setBoolValue(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var ty = result.type;
|
|
||||||
scratchValid.setBoolValue(1);
|
scratchValid.setBoolValue(1);
|
||||||
scratch.getNode("type", 1).setValue(ty);
|
|
||||||
scratch.getNode("latitude-deg", 1).setValue(result.lat);
|
scratch.getNode("latitude-deg", 1).setValue(result.lat);
|
||||||
scratch.getNode("longitude-deg", 1).setValue(result.lon);
|
scratch.getNode("longitude-deg", 1).setValue(result.lon);
|
||||||
scratch.getNode("altitude-ft", 1).setValue(result.elevation);
|
|
||||||
scratch.getNode("ident", 1).setValue(result.id);
|
scratch.getNode("ident", 1).setValue(result.id);
|
||||||
scratch.getNode("name", 1).setValue(result.name);
|
var cd = nil;
|
||||||
|
|
||||||
if (ty == 'vor') {
|
if (searchIsWaypoints) {
|
||||||
scratch.getNode("frequency-mhz", 1).setValue(result.frequency);
|
scratch.getNode("type", 1).setValue('WPT');
|
||||||
} elsif (ty == 'ndb') {
|
|
||||||
scratch.getNode("frequency-khz", 1).setValue(result.frequency);
|
cd = result.courseAndDistanceFrom(geo.aircraft_position());
|
||||||
|
} else {
|
||||||
|
var ty = result.type;
|
||||||
|
scratch.getNode("type", 1).setValue(ty);
|
||||||
|
scratch.getNode("name", 1).setValue(result.name);
|
||||||
|
scratch.getNode("altitude-ft", 1).setValue(result.elevation);
|
||||||
|
|
||||||
|
if (ty == 'vor') {
|
||||||
|
scratch.getNode("frequency-mhz", 1).setValue(result.frequency);
|
||||||
|
} elsif (ty == 'ndb') {
|
||||||
|
scratch.getNode("frequency-khz", 1).setValue(result.frequency);
|
||||||
|
}
|
||||||
|
|
||||||
|
cd = positioned.courseAndDistance(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
var cd = positioned.courseAndDistance(result);
|
|
||||||
scratch.getNode("mag-bearing-deg", 1).setValue(cd[0] + magvar());
|
scratch.getNode("mag-bearing-deg", 1).setValue(cd[0] + magvar());
|
||||||
scratch.getNode("distance-nm", 1).setValue(cd[1]);
|
scratch.getNode("distance-nm", 1).setValue(cd[1]);
|
||||||
|
|
||||||
|
@ -60,24 +73,27 @@
|
||||||
var doSearch = func()
|
var doSearch = func()
|
||||||
{
|
{
|
||||||
var ty = dlg.getNode("search-type").getValue();
|
var ty = dlg.getNode("search-type").getValue();
|
||||||
|
if (ty == 'any') ty = anySpec;
|
||||||
|
|
||||||
var query = dlg.getNode("search-query").getValue();
|
var query = dlg.getNode("search-query").getValue();
|
||||||
searchResults = positioned.sortByRange(positioned.findByIdent(query, ty));
|
searchResults = positioned.sortByRange(positioned.findByIdent(query, ty));
|
||||||
updateSearchResults();
|
updateSearchResults(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
var doSearchNames = func
|
var doSearchNames = func
|
||||||
{
|
{
|
||||||
var ty = dlg.getNode("search-type").getValue();
|
var ty = dlg.getNode("search-type").getValue();
|
||||||
|
if (ty == 'any') ty = anySpec;
|
||||||
var query = dlg.getNode("search-query").getValue();
|
var query = dlg.getNode("search-query").getValue();
|
||||||
searchResults = positioned.sortByRange(positioned.findByName(query, ty));
|
searchResults = positioned.sortByRange(positioned.findByName(query, ty));
|
||||||
updateSearchResults();
|
updateSearchResults(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
var doSearchNearest = func
|
var doSearchNearest = func
|
||||||
{
|
{
|
||||||
var ty = dlg.getNode("search-type").getValue();
|
var ty = dlg.getNode("search-type").getValue();
|
||||||
searchResults = positioned.findWithinRange(200.0, ty);
|
searchResults = positioned.findWithinRange(200.0, ty);
|
||||||
updateSearchResults();
|
updateSearchResults(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
var doLoadRouteWaypoint = func
|
var doLoadRouteWaypoint = func
|
||||||
|
@ -87,7 +103,7 @@
|
||||||
for (var i=0; i < fp.getPlanSize(); i+=1) {
|
for (var i=0; i < fp.getPlanSize(); i+=1) {
|
||||||
append(searchResults, fp.getWP(i));
|
append(searchResults, fp.getWP(i));
|
||||||
}
|
}
|
||||||
updateSearchResults();
|
updateSearchResults(1, fp.current);
|
||||||
}
|
}
|
||||||
|
|
||||||
var doScratchPrevious = func
|
var doScratchPrevious = func
|
||||||
|
@ -111,7 +127,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
var searchResults = [];
|
var searchResults = [];
|
||||||
updateSearchResults();
|
updateSearchResults(0);
|
||||||
|
|
||||||
var slaved = props.globals.getNode("/instrumentation/nav[0]/slaved-to-gps", 1);
|
var slaved = props.globals.getNode("/instrumentation/nav[0]/slaved-to-gps", 1);
|
||||||
]]></open>
|
]]></open>
|
||||||
|
@ -399,6 +415,8 @@
|
||||||
<value>ndb</value>
|
<value>ndb</value>
|
||||||
<value>fix</value>
|
<value>fix</value>
|
||||||
<value>wpt</value>
|
<value>wpt</value>
|
||||||
|
<value>city</value>
|
||||||
|
<value>town</value>
|
||||||
<live>true</live>
|
<live>true</live>
|
||||||
<binding>
|
<binding>
|
||||||
<command>dialog-apply</command>
|
<command>dialog-apply</command>
|
||||||
|
|
|
@ -224,9 +224,38 @@ command interface /autopilot/route-manager/input:
|
||||||
gui.dialog_update("route-manager", "approach");
|
gui.dialog_update("route-manager", "approach");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var initPosition = func {
|
||||||
|
var routeActive = routem.getNode("active").getValue();
|
||||||
|
if (routeActive) return;
|
||||||
|
|
||||||
|
# FIXME have user waypoints check
|
||||||
|
var fp = flightplan();
|
||||||
|
|
||||||
|
var airborne = getprop('/gear/gear[0]/wow') == 0;
|
||||||
|
if (airborne) {
|
||||||
|
debug.dump('route-manager dialog, init in-air, clearing departure settings');
|
||||||
|
fp.departure = nil;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# we're on the ground, find the nearest airport to start from
|
||||||
|
if (fp.departure == nil) {
|
||||||
|
var apts = findAirportsWithinRange(25.0);
|
||||||
|
if (size(apts) == 0) return; # no airports nearby
|
||||||
|
fp.departure = apts[0]; # use the closest one
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fp.departure_runway == nil) {
|
||||||
|
debug.dump('selecting departure runway');
|
||||||
|
var rwy = fp.departure.findBestRunwayForPos( geo.aircraft_position() );
|
||||||
|
fp.departure_runway = rwy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# initialise departure values based on current position
|
# initialise departure values based on current position
|
||||||
cmd.setValue("@posinit");
|
initPosition();
|
||||||
|
|
||||||
updateRunways();
|
updateRunways();
|
||||||
updateSIDs();
|
updateSIDs();
|
||||||
|
|
Loading…
Add table
Reference in a new issue