]> git.mxchange.org Git - flightgear.git/commitdiff
Expose position along the flight-path to Nasal.
authorJames Turner <jmt@Bishop.local>
Wed, 26 Dec 2012 23:48:19 +0000 (23:48 +0000)
committerJames Turner <jmt@Bishop.local>
Wed, 26 Dec 2012 23:48:19 +0000 (23:48 +0000)
Useful to query a point '100nm before wpt X' from Nasal, especially for VNAV calculations (T/C, T/D).

src/Navaids/FlightPlan.cxx
src/Navaids/FlightPlan.hxx
src/Scripting/NasalPositioned.cxx

index cb7e41c0dfe1590084ac2b3cb28012e9b06d031b..b66108fbb39c472fadb7a0191cb51995bbd1fd3d 100644 (file)
@@ -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) {
index bdd022830d5968d78d8ee7dd6d5b33acec94d1f2..3eeb02cf64f7f30e1f2e18017bf44665b32920ff 100644 (file)
@@ -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
index 9deebee891600857182bea0888c3da958192ef51..66bfb5826a370b55bf7af5642dbdf78096d6baf3 100644 (file)
@@ -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);