The default GPS delegate now handles sequencing
In conjunction with some FlightGear changes, the delegate can now do all sequencing decisions, i.e the GPS C++ code does not make any policy decisions about sequencing. Update the default Nasal delegate to mimic the old behaviour, and set the config option, both to allow future developments and to demonstrate the new API.
This commit is contained in:
parent
0172ef9d08
commit
f83caf7e45
1 changed files with 108 additions and 11 deletions
|
@ -110,21 +110,40 @@ var RouteManagerDelegate = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var GPSPath = "/instrumentation/gps";
|
||||||
|
|
||||||
var FMSDelegate = {
|
# this delegate corresponds to the default behaviour of the built-in GPS.
|
||||||
|
# depending on the real GPS/FMS you are modelling, you probably need to
|
||||||
|
# replace this with your own.
|
||||||
|
#
|
||||||
|
# To do that, just set /autopilot/route-manager/disable-fms to true, which
|
||||||
|
# will block creation of this delegate.
|
||||||
|
#
|
||||||
|
# Of course you are then responsible for many basic FMS functions, such as
|
||||||
|
# route sequencing and activation
|
||||||
|
#
|
||||||
|
|
||||||
|
var DefaultGPSDeleagte = {
|
||||||
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-fms'))
|
||||||
return nil;
|
return nil;
|
||||||
|
|
||||||
var m = { parents: [FMSDelegate], flightplan:fp, landingCheck:nil };
|
var m = { parents: [DefaultGPSDeleagte], flightplan:fp, landingCheck:nil };
|
||||||
|
|
||||||
|
printlog('info', 'creating default GPS FPDelegate');
|
||||||
|
|
||||||
|
# tell the GPS C++ code we will do sequencing ourselves, so it can disable
|
||||||
|
# its legacy logic for this
|
||||||
|
setprop(GPSPath ~ '/config/delegate-sequencing', 1);
|
||||||
|
|
||||||
# make FlightPlan behaviour match GPS config state
|
# make FlightPlan behaviour match GPS config state
|
||||||
fp.followLegTrackToFix = getprop('/instrumentation/gps/config/follow-leg-track-to-fix');
|
fp.followLegTrackToFix = getprop(GPSPath ~ '/config/follow-leg-track-to-fix') or 0;
|
||||||
|
|
||||||
# similarly, make FlightPlan follow the performance category settings
|
# similarly, make FlightPlan follow the performance category settings
|
||||||
fp.aircraftCategory = getprop('/autopilot/settings/icao-aircraft-category');
|
fp.aircraftCategory = getprop('/autopilot/settings/icao-aircraft-category') or 'A';
|
||||||
|
|
||||||
|
m._modeProp = props.globals.getNode(GPSPath ~ '/mode');
|
||||||
return m;
|
return m;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -133,24 +152,102 @@ var FMSDelegate = {
|
||||||
var wow = getprop('gear/gear[0]/wow');
|
var wow = getprop('gear/gear[0]/wow');
|
||||||
var gs = getprop('velocities/groundspeed-kt');
|
var gs = getprop('velocities/groundspeed-kt');
|
||||||
if (wow and (gs < 25)) {
|
if (wow and (gs < 25)) {
|
||||||
printlog('info', 'touchdown on destination runway, end of route.');
|
printlog('info', 'GPS saw speed < 25kts on destination runway, end of route.');
|
||||||
me.landingCheck.stop();
|
me.landingCheck.stop();
|
||||||
# record touch-down time?
|
# record touch-down time?
|
||||||
me.flightplan.finish();
|
me.flightplan.finish();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_selectOBSMode: func
|
||||||
|
{
|
||||||
|
setprop(GPSPath ~ "/command", "obs");
|
||||||
|
},
|
||||||
|
|
||||||
waypointsChanged: func
|
waypointsChanged: func
|
||||||
{
|
{
|
||||||
},
|
},
|
||||||
|
|
||||||
|
activated: func
|
||||||
|
{
|
||||||
|
if (!me.flightplan.active)
|
||||||
|
return;
|
||||||
|
|
||||||
|
printlog('info', 'flightplan activated, default GPS to LEG mode');
|
||||||
|
setprop(GPSPath ~ "/command", "leg");
|
||||||
|
|
||||||
|
if (getprop(GPSPath ~ '/wp/wp[1]/from-flag')) {
|
||||||
|
printlog('info', 'at GPS activation, already passed active WP, sequencing');
|
||||||
|
me.sequence();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
deactivated: func
|
||||||
|
{
|
||||||
|
if (me._modeProp.getValue() == 'leg') {
|
||||||
|
printlog('info', 'flightplan deactivated, default GPS to OBS mode');
|
||||||
|
me._selectOBSMode();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
endOfFlightPlan: func
|
endOfFlightPlan: func
|
||||||
{
|
{
|
||||||
printlog('info', 'end of flight-plan');
|
if (me._modeProp.getValue() == 'leg') {
|
||||||
|
printlog('info', 'end of flight-plan, switching GPS to OBS mode');
|
||||||
|
me._selectOBSMode();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
cleared: func
|
||||||
|
{
|
||||||
|
if (!me.flightplan.active)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (me._modeProp.getValue() == 'leg') {
|
||||||
|
printlog('info', 'flight-plan cleared, switching GPS to OBS mode');
|
||||||
|
me._selectOBSMode();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
sequence: func
|
||||||
|
{
|
||||||
|
if (!me.flightplan.active)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var mode = me._modeProp.getValue();
|
||||||
|
if (mode == 'dto') {
|
||||||
|
# direct-to is done, check if we should resume the following leg
|
||||||
|
var index = me.flightplan.indexOfWP(getprop(GPSPath ~ '/wp/wp[1]/latitude-deg'),
|
||||||
|
getprop(GPSPath ~ '/wp/wp[1]/longitude-deg'));
|
||||||
|
if (index >= 0) {
|
||||||
|
printlog("info", "default GPS reached Direct-To, resuming FP leg at " ~ index);
|
||||||
|
me.flightplan.current = index + 1;
|
||||||
|
setprop(GPSPath ~ "/command", "leg");
|
||||||
|
} else {
|
||||||
|
# revert to OBS mode
|
||||||
|
printlog("info", "default GPS reached Direct-To, resuming to OSB");
|
||||||
|
me._selectOBSMode();
|
||||||
|
}
|
||||||
|
} else if (mode == 'leg') {
|
||||||
|
# standard leq sequencing
|
||||||
|
var nextIndex = me.flightplan.current + 1;
|
||||||
|
if (nextIndex >= me.flightplan.numWaypoints()) {
|
||||||
|
printlog("info", "default GPS sequencing, finishing flightplan");
|
||||||
|
me.flightplan.finish();
|
||||||
|
} else {
|
||||||
|
printlog("info", "default GPS sequencing to next WP");
|
||||||
|
me.flightplan.current = nextIndex;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
# OBS, do nothing
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
currentWaypointChanged: func
|
currentWaypointChanged: func
|
||||||
{
|
{
|
||||||
|
if (!me.flightplan.active)
|
||||||
|
return;
|
||||||
|
|
||||||
if (me.landingCheck != nil) {
|
if (me.landingCheck != nil) {
|
||||||
me.landingCheck.stop();
|
me.landingCheck.stop();
|
||||||
me.landingCheck = nil; # delete timer
|
me.landingCheck = nil; # delete timer
|
||||||
|
@ -175,12 +272,12 @@ var FMSDelegate = {
|
||||||
(activeRunway != nil) and
|
(activeRunway != nil) and
|
||||||
(activeRunway.id == me.flightplan.destination_runway.id))
|
(activeRunway.id == me.flightplan.destination_runway.id))
|
||||||
{
|
{
|
||||||
me.landingCheck = maketimer(2.0, me, FMSDelegate._landingCheckTimeout);
|
me.landingCheck = maketimer(2.0, me, DefaultGPSDeleagte._landingCheckTimeout);
|
||||||
me.landingCheck.start();
|
me.landingCheck.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
registerFlightPlanDelegate(FMSDelegate.new);
|
registerFlightPlanDelegate(DefaultGPSDeleagte.new);
|
||||||
registerFlightPlanDelegate(RouteManagerDelegate.new);
|
registerFlightPlanDelegate(RouteManagerDelegate.new);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue