]> git.mxchange.org Git - flightgear.git/commitdiff
GPS fixes
authorJames Turner <zakalawe@mac.com>
Sun, 16 Mar 2014 16:20:03 +0000 (16:20 +0000)
committerJames Turner <zakalawe@mac.com>
Sun, 16 Mar 2014 16:20:03 +0000 (16:20 +0000)
- fix corrupted ident on Mac (libc++ issue)
- don't clear scratch when activating DTO mode
- use the real navaid/airport for the waypt where possible
- expose active waypt name

src/Instrumentation/gps.cxx
src/Instrumentation/gps.hxx

index 8e6e066bb1249a72fe7573fc1d7609822c3f7df2..2e8f5bc47b24c296d037aba9175a13cfa3f1991b 100644 (file)
@@ -222,14 +222,17 @@ GPS::bind()
   tieSGGeodReadOnly(wp0_node, _wp0_position, "longitude-deg", "latitude-deg", "altitude-ft");
   tie(wp0_node, "ID", SGRawValueMethods<GPS, const char*>
       (*this, &GPS::getWP0Ident, NULL));
-    
+  tie(wp0_node, "name", SGRawValueMethods<GPS, const char*>
+      (*this, &GPS::getWP0Name, NULL));
 
   tie(_currentWayptNode, "valid", SGRawValueMethods<GPS, bool>
        (*this, &GPS::getWP1IValid, NULL));
     
   tie(_currentWayptNode, "ID", SGRawValueMethods<GPS, const char*>
     (*this, &GPS::getWP1Ident, NULL));
-  
+  tie(_currentWayptNode, "name", SGRawValueMethods<GPS, const char*>
+    (*this, &GPS::getWP1Name, NULL));
+    
   tie(_currentWayptNode, "distance-nm", SGRawValueMethods<GPS, double>
     (*this, &GPS::getWP1Distance, NULL));
   tie(_currentWayptNode, "bearing-true-deg", SGRawValueMethods<GPS, double>
@@ -922,16 +925,25 @@ double GPS::getCDIDeflection() const
 
 const char* GPS::getWP0Ident() const
 {
-  if (!_dataValid || (_mode != "leg") || (!_prevWaypt)) {
+  if (!_dataValid || (_mode != "leg") || !_prevWaypt) {
     return "";
   }
   
-  return _prevWaypt->ident().c_str();
+// work around std::string::c_str() storage lifetime with libc++
+// real fix is to allow tie-ing with std::string instead of char*
+  static char identBuf[8];
+  strncpy(identBuf, _prevWaypt->ident().c_str(), 8);
+
+  return identBuf;
 }
 
 const char* GPS::getWP0Name() const
 {
-  return "";
+    if (!_dataValid || !_prevWaypt || !_prevWaypt->source()) {
+        return "";
+    }
+    
+    return _prevWaypt->source()->name().c_str();
 }
 
 bool GPS::getWP1IValid() const
@@ -941,16 +953,25 @@ bool GPS::getWP1IValid() const
 
 const char* GPS::getWP1Ident() const
 {
-  if ((!_dataValid)||(!_currentWaypt)) {
+  if (!_dataValid || !_currentWaypt) {
     return "";
   }
   
-  return _currentWaypt->ident().c_str();
+// work around std::string::c_str() storage lifetime with libc++
+// real fix is to allow tie-ing with std::string instead of char*
+  static char identBuf[8];
+  strncpy(identBuf, _currentWaypt->ident().c_str(), 8);
+    
+  return identBuf;
 }
 
 const char* GPS::getWP1Name() const
 {
-  return "";
+    if (!_dataValid || !_currentWaypt || !_currentWaypt->source()) {
+        return "";
+    }
+    
+    return _currentWaypt->source()->name().c_str();
 }
 
 double GPS::getWP1Distance() const
@@ -1157,6 +1178,16 @@ bool GPS::isScratchPositionValid() const
   return true;
 }
 
+FGPositionedRef GPS::positionedFromScratch() const
+{
+    if (!isScratchPositionValid()) {
+        return NULL;
+    }
+    
+    std::string ident(_scratchNode->getStringValue("ident"));
+    return FGPositioned::findClosestWithIdent(ident, _scratchPos);
+}
+
 void GPS::directTo()
 {  
   if (!isScratchPositionValid()) {
@@ -1165,22 +1196,31 @@ void GPS::directTo()
   
   _prevWaypt = NULL;
   _wp0_position = _indicated_pos;
-  _currentWaypt = new BasicWaypt(_scratchPos, _scratchNode->getStringValue("ident"), NULL);
-  _mode = "dto";
-  clearScratch();
+    
+    FGPositionedRef pos = positionedFromScratch();
+    if (pos) {
+        _currentWaypt = new NavaidWaypoint(pos, NULL);
+    } else {
+        _currentWaypt = new BasicWaypt(_scratchPos, _scratchNode->getStringValue("ident"), NULL);
+    }
+    
+    _mode = "dto";
   wp1Changed();
 }
 
 void GPS::selectOBSMode(flightgear::Waypt* waypt)
 {
-  if (!waypt) {
-    // initialise from scratch
-    if (isScratchPositionValid()) {
+  if (!waypt && isScratchPositionValid()) {
+    FGPositionedRef pos = positionedFromScratch();
+    if (pos) {
+        waypt = new NavaidWaypoint(pos, NULL);
+    } else {
         waypt = new BasicWaypt(_scratchPos, _scratchNode->getStringValue("ident"), NULL);
     }
   }
   
   _mode = "obs";
+  _prevWaypt = NULL;
   _wp0_position = _indicated_pos;
   _currentWaypt = waypt;
   wp1Changed();
index a142330ce54742a9c062fe72fc2a5b1d7fc00354..100d236b6ce4424d1d9f17a7104f691da6639e46 100644 (file)
@@ -206,7 +206,8 @@ private:
     /** Predicate, determine if the lon/lat position in the scratch is
      * valid or not. */
     bool isScratchPositionValid() const;
-
+    FGPositionedRef positionedFromScratch() const;
+    
 #if FG_210_COMPAT
     void setScratchFromPositioned(FGPositioned* aPos, int aIndex);
     void setScratchFromCachedSearchResult();
@@ -350,7 +351,7 @@ private:
      * the instrument manager creates a default instance of us,
      * if no explicit GPS is specific in the aircraft's instruments.xml file.
      * This allows default route-following to work with the generic autopilot.
-     * This flat is set in that case, to inform us we're a 'fake' installation,
+     * This flag is set in that case, to inform us we're a 'fake' installation,
      * and not to worry about electrical power or similar.
      */
     bool _defaultGPSMode;