Expose position along the flight-path to Nasal.
Useful to query a point '100nm before wpt X' from Nasal, especially for VNAV calculations (T/C, T/D).
This commit is contained in:
parent
a1031b052d
commit
12076bce0e
3 changed files with 67 additions and 1 deletions
src
|
@ -1035,6 +1035,39 @@ void FlightPlan::rebuildLegData()
|
|||
}
|
||||
}
|
||||
|
||||
SGGeod FlightPlan::pointAlongRoute(int aIndex, double aOffsetNm) const
|
||||
{
|
||||
if (aIndex >= (int) _legs.size()) {
|
||||
throw sg_range_exception();
|
||||
}
|
||||
|
||||
const int lastLeg = static_cast<int>(_legs.size()) - 1;
|
||||
// convert the relative offset and leg index into an absolute, positive
|
||||
// distance in nm from the route origin. This means we can simply walk
|
||||
// forwards to find the actual leg.
|
||||
Leg* leg = _legs[(aIndex >= 0) ? aIndex : lastLeg];
|
||||
double absolutePathDistance = leg->_distanceAlongPath + aOffsetNm;
|
||||
if (absolutePathDistance < 0.0) {
|
||||
return _legs[0]->waypoint()->position(); // begining of route
|
||||
}
|
||||
|
||||
if (absolutePathDistance > _totalDistance) {
|
||||
return _legs[lastLeg]->waypoint()->position(); // end of route
|
||||
}
|
||||
|
||||
// find the leg containing the absolute distance
|
||||
for (int l=0; l<lastLeg; ++l) {
|
||||
leg = _legs[l];
|
||||
if (absolutePathDistance < leg->_pathDistance) {
|
||||
break; // found our matching leg
|
||||
}
|
||||
absolutePathDistance -= leg->_pathDistance;
|
||||
} // of forwards walk along route to find leg
|
||||
|
||||
return SGGeodesy::direct(leg->waypoint()->position(),
|
||||
leg->_courseDeg, absolutePathDistance * SG_NM_TO_METER);
|
||||
}
|
||||
|
||||
void FlightPlan::lockDelegate()
|
||||
{
|
||||
if (_delegateLock == 0) {
|
||||
|
|
|
@ -199,6 +199,13 @@ public:
|
|||
double totalDistanceNm() const
|
||||
{ return _totalDistance; }
|
||||
|
||||
/**
|
||||
* given a waypoint index, and an offset in NM, find the geodetic
|
||||
* position on the route path. I.e the point 10nm before or after
|
||||
* a particular waypoint.
|
||||
*/
|
||||
SGGeod pointAlongRoute(int aIndex, double aOffsetNm) const;
|
||||
|
||||
/**
|
||||
* Create a WayPoint from a string in the following format:
|
||||
* - simple identifier
|
||||
|
|
|
@ -2125,6 +2125,31 @@ static naRef f_flightplan_clone(naContext c, naRef me, int argc, naRef* args)
|
|||
return ghostForFlightPlan(c, fp->clone());
|
||||
}
|
||||
|
||||
static naRef f_flightplan_pathGeod(naContext c, naRef me, int argc, naRef* args)
|
||||
{
|
||||
FlightPlan* fp = flightplanGhost(me);
|
||||
if (!fp) {
|
||||
naRuntimeError(c, "flightplan.clone called on non-flightplan object");
|
||||
}
|
||||
|
||||
if ((argc < 1) || !naIsNum(args[0])) {
|
||||
naRuntimeError(c, "bad argument to flightplan.pathGeod");
|
||||
}
|
||||
|
||||
if ((argc > 1) && !naIsNum(args[1])) {
|
||||
naRuntimeError(c, "bad argument to flightplan.pathGeod");
|
||||
}
|
||||
|
||||
int index = (int) args[0].num;
|
||||
double offset = (argc > 1) ? args[1].num : 0.0;
|
||||
naRef result = naNewHash(c);
|
||||
SGGeod g = fp->pointAlongRoute(index, offset);
|
||||
hashset(c, result, "lat", naNum(g.getLatitudeDeg()));
|
||||
hashset(c, result, "lon", naNum(g.getLongitudeDeg()));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static naRef f_leg_setSpeed(naContext c, naRef me, int argc, naRef* args)
|
||||
{
|
||||
FlightPlan::Leg* leg = fpLegGhost(me);
|
||||
|
@ -2365,7 +2390,8 @@ naRef initNasalPositioned(naRef globals, naContext c, naRef gcSave)
|
|||
hashset(c, flightplanPrototype, "cleanPlan", naNewFunc(c, naNewCCode(c, f_flightplan_clearPlan)));
|
||||
hashset(c, flightplanPrototype, "clearWPType", naNewFunc(c, naNewCCode(c, f_flightplan_clearWPType)));
|
||||
hashset(c, flightplanPrototype, "clone", naNewFunc(c, naNewCCode(c, f_flightplan_clone)));
|
||||
|
||||
hashset(c, flightplanPrototype, "pathGeod", naNewFunc(c, naNewCCode(c, f_flightplan_pathGeod)));
|
||||
|
||||
waypointPrototype = naNewHash(c);
|
||||
hashset(c, gcSave, "wayptProto", waypointPrototype);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue