diff --git a/Nasal/route_manager.nas b/Nasal/route_manager.nas
index 92b860065..a3f1e2a3e 100644
--- a/Nasal/route_manager.nas
+++ b/Nasal/route_manager.nas
@@ -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);
diff --git a/gui/dialogs/gps.xml b/gui/dialogs/gps.xml
index 62c9f7092..73d99691b 100644
--- a/gui/dialogs/gps.xml
+++ b/gui/dialogs/gps.xml
@@ -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);
]]>
@@ -399,6 +415,8 @@
ndb
fix
wpt
+ city
+ town
true
dialog-apply
diff --git a/gui/dialogs/route-manager.xml b/gui/dialogs/route-manager.xml
index 1781c7471..1b72bb38e 100644
--- a/gui/dialogs/route-manager.xml
+++ b/gui/dialogs/route-manager.xml
@@ -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();