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
|
||||
# in route-manager dialog. Intended to provide a sensible default behaviour,
|
||||
# but be disabled by an aircraft-specific FMS / GPS system.
|
||||
# route_manager.nas - FlightPlan delegate(s) corresponding to the built-
|
||||
# in route-manager dialog and GPS. Intended to provide a sensible default behaviour,
|
||||
# but can be disabled by an aircraft-specific FMS / GPS system.
|
||||
|
||||
var RouteManagerDelegate = {
|
||||
new: func(fp) {
|
||||
# if this property is set, don't build a delegate at all
|
||||
if (getprop('/autopilot/route-manager/disable-fms'))
|
||||
return nil;
|
||||
|
||||
# if this property is set, don't build a delegate at all
|
||||
if (getprop('/autopilot/route-manager/disable-route-manager'))
|
||||
return nil;
|
||||
|
||||
var m = { parents: [RouteManagerDelegate] };
|
||||
m.flightplan = fp;
|
||||
return m;
|
||||
|
@ -86,19 +86,66 @@ var RouteManagerDelegate = {
|
|||
{
|
||||
debug.dump("end of flight-plan, deactivating");
|
||||
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
|
||||
{
|
||||
},
|
||||
|
||||
endOfFlightPlan: func
|
||||
{
|
||||
debug.dump('end of flight-plan');
|
||||
},
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -11,14 +11,17 @@
|
|||
var cmd = gps.getNode("command", 1);
|
||||
var scratch = gps.getNode("scratch", 1);
|
||||
var scratchValid = scratch.getNode("valid", 1);
|
||||
|
||||
var updateSearchResults = func
|
||||
{
|
||||
debug.dump('search results is:', searchResults);
|
||||
var searchIsWaypoints = 0;
|
||||
var anySpec = 'vor,airport,heliport,ils,seaport,fix,ndb,waypoint,tacan,city,town';
|
||||
|
||||
dlg.getNode("scratch-index", 1).setValue(0);
|
||||
dlg.getNode("scratch-has-next", 1).setBoolValue(size(searchResults) > 1);
|
||||
var updateSearchResults = func(isWpts, index = 0)
|
||||
{
|
||||
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) {
|
||||
scratchValid.setBoolValue(0);
|
||||
return;
|
||||
|
@ -34,23 +37,33 @@
|
|||
scratchValid.setBoolValue(0);
|
||||
return;
|
||||
}
|
||||
|
||||
var ty = result.type;
|
||||
|
||||
scratchValid.setBoolValue(1);
|
||||
scratch.getNode("type", 1).setValue(ty);
|
||||
scratch.getNode("latitude-deg", 1).setValue(result.lat);
|
||||
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("name", 1).setValue(result.name);
|
||||
var cd = nil;
|
||||
|
||||
if (ty == 'vor') {
|
||||
scratch.getNode("frequency-mhz", 1).setValue(result.frequency);
|
||||
} elsif (ty == 'ndb') {
|
||||
scratch.getNode("frequency-khz", 1).setValue(result.frequency);
|
||||
if (searchIsWaypoints) {
|
||||
scratch.getNode("type", 1).setValue('WPT');
|
||||
|
||||
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("distance-nm", 1).setValue(cd[1]);
|
||||
|
||||
|
@ -60,24 +73,27 @@
|
|||
var doSearch = func()
|
||||
{
|
||||
var ty = dlg.getNode("search-type").getValue();
|
||||
if (ty == 'any') ty = anySpec;
|
||||
|
||||
var query = dlg.getNode("search-query").getValue();
|
||||
searchResults = positioned.sortByRange(positioned.findByIdent(query, ty));
|
||||
updateSearchResults();
|
||||
updateSearchResults(0);
|
||||
}
|
||||
|
||||
var doSearchNames = func
|
||||
{
|
||||
var ty = dlg.getNode("search-type").getValue();
|
||||
if (ty == 'any') ty = anySpec;
|
||||
var query = dlg.getNode("search-query").getValue();
|
||||
searchResults = positioned.sortByRange(positioned.findByName(query, ty));
|
||||
updateSearchResults();
|
||||
updateSearchResults(0);
|
||||
}
|
||||
|
||||
var doSearchNearest = func
|
||||
{
|
||||
var ty = dlg.getNode("search-type").getValue();
|
||||
searchResults = positioned.findWithinRange(200.0, ty);
|
||||
updateSearchResults();
|
||||
updateSearchResults(0);
|
||||
}
|
||||
|
||||
var doLoadRouteWaypoint = func
|
||||
|
@ -87,7 +103,7 @@
|
|||
for (var i=0; i < fp.getPlanSize(); i+=1) {
|
||||
append(searchResults, fp.getWP(i));
|
||||
}
|
||||
updateSearchResults();
|
||||
updateSearchResults(1, fp.current);
|
||||
}
|
||||
|
||||
var doScratchPrevious = func
|
||||
|
@ -111,7 +127,7 @@
|
|||
}
|
||||
|
||||
var searchResults = [];
|
||||
updateSearchResults();
|
||||
updateSearchResults(0);
|
||||
|
||||
var slaved = props.globals.getNode("/instrumentation/nav[0]/slaved-to-gps", 1);
|
||||
]]></open>
|
||||
|
@ -399,6 +415,8 @@
|
|||
<value>ndb</value>
|
||||
<value>fix</value>
|
||||
<value>wpt</value>
|
||||
<value>city</value>
|
||||
<value>town</value>
|
||||
<live>true</live>
|
||||
<binding>
|
||||
<command>dialog-apply</command>
|
||||
|
|
|
@ -224,9 +224,38 @@ command interface /autopilot/route-manager/input:
|
|||
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
|
||||
cmd.setValue("@posinit");
|
||||
initPosition();
|
||||
|
||||
updateRunways();
|
||||
updateSIDs();
|
||||
|
|
Loading…
Reference in a new issue