]> git.mxchange.org Git - flightgear.git/commitdiff
Support for creating default SID/approach.
authorJames Turner <zakalawe@mac.com>
Mon, 12 Nov 2012 21:30:28 +0000 (22:30 +0100)
committerJames Turner <zakalawe@mac.com>
Mon, 12 Nov 2012 21:30:28 +0000 (22:30 +0100)
Durk reminded me of this - when we're missing procedures data (the common case), synthesise a plausible (but possibly dangerously unrealistic) departure and approach. Will work fine for airports in gentle terrain, and likely kill you at challenging airports. You have been warned.

src/Airports/simple.hxx
src/Autopilot/route_mgr.cxx
src/Navaids/FlightPlan.hxx
src/Navaids/airways.hxx
src/Navaids/procedure.cxx
src/Navaids/procedure.hxx
src/Navaids/route.hxx

index 3ee46ea7b45e6273646d173df9c634da7cb237c4..de7f0b8cab153568631e8e45b5532c060170ee29 100644 (file)
@@ -262,9 +262,13 @@ private:
     mutable PositionedIDVec mTaxiways;
     PositionedIDVec mPavements;
     
-    std::vector<flightgear::SID*> mSIDs;
-    std::vector<flightgear::STAR*> mSTARs;
-    std::vector<flightgear::Approach*> mApproaches;
+    typedef SGSharedPtr<flightgear::SID> SIDRef;
+    typedef SGSharedPtr<flightgear::STAR> STARRef;
+    typedef SGSharedPtr<flightgear::Approach> ApproachRef;
+    
+    std::vector<SIDRef> mSIDs;
+    std::vector<STARRef> mSTARs;
+    std::vector<ApproachRef> mApproaches;
   };
 
 // find basic airport location info from airport database
index d39c49c5546e877908abc71445f8e82bddba3e84..9d3c17b080ea6a787fed710e8351ec0b83c86e9c 100644 (file)
@@ -37,6 +37,7 @@
 
 #include <boost/algorithm/string/case_conv.hpp>
 #include <boost/tuple/tuple.hpp>
+#include <boost/foreach.hpp>
 
 #include <simgear/misc/strutils.hxx>
 #include <simgear/structure/exception.hxx>
@@ -913,6 +914,41 @@ const char* FGRouteMgr::getSID() const
   return "";
 }
 
+flightgear::SID* createDefaultSID(FGRunway* aRunway)
+{
+  if (!aRunway) {
+    return NULL;
+  }
+  
+  double runwayElevFt = aRunway->end().getElevationFt();
+  WayptVec wpts;
+  std::ostringstream ss;
+  ss << aRunway->ident() << "-3";
+  
+  SGGeod p = aRunway->pointOnCenterline(aRunway->lengthM() + (3.0 * SG_NM_TO_METER));
+  p.setElevationFt(runwayElevFt + 2000.0);
+  wpts.push_back(new BasicWaypt(p, ss.str(), NULL));
+  
+  ss.str("");
+  ss << aRunway->ident() << "-6";
+  p = aRunway->pointOnCenterline(aRunway->lengthM() + (6.0 * SG_NM_TO_METER));
+  p.setElevationFt(runwayElevFt + 4000.0);
+  wpts.push_back(new BasicWaypt(p, ss.str(), NULL));
+
+    ss.str("");
+    ss << aRunway->ident() << "-9";
+    p = aRunway->pointOnCenterline(aRunway->lengthM() + (9.0 * SG_NM_TO_METER));
+    p.setElevationFt(runwayElevFt + 6000.0);
+    wpts.push_back(new BasicWaypt(p, ss.str(), NULL));
+    
+  BOOST_FOREACH(Waypt* w, wpts) {
+    w->setFlag(WPT_DEPARTURE);
+    w->setFlag(WPT_GENERATED);
+  }
+  
+  return SID::createTempSID("DEFAULT", aRunway, wpts);
+}
+
 void FGRouteMgr::setSID(const char* aIdent)
 {
   FGAirport* apt = _plan->departureAirport();
@@ -921,6 +957,11 @@ void FGRouteMgr::setSID(const char* aIdent)
     return;
   } 
   
+  if (!strcmp(aIdent, "DEFAULT")) {
+    _plan->setSID(createDefaultSID(_plan->departureRunway()));
+    return;
+  }
+  
   string ident(aIdent);
   size_t hyphenPos = ident.find('-');
   if (hyphenPos != string::npos) {
@@ -990,9 +1031,56 @@ const char* FGRouteMgr::getApproach() const
   return "";
 }
 
+flightgear::Approach* createDefaultApproach(FGRunway* aRunway)
+{
+  if (!aRunway) {
+    return NULL;
+  }
+
+  double thresholdElevFt = aRunway->threshold().getElevationFt();
+  const double approachHeightFt = 2000.0;
+  double glideslopeDistanceM = (approachHeightFt * SG_FEET_TO_METER) /
+    tan(3.0 * SG_DEGREES_TO_RADIANS);
+  
+  std::ostringstream ss;
+  ss << aRunway->ident() << "-12";
+  WayptVec wpts;
+  SGGeod p = aRunway->pointOnCenterline(-12.0 * SG_NM_TO_METER);
+  p.setElevationFt(thresholdElevFt + 4000);
+  wpts.push_back(new BasicWaypt(p, ss.str(), NULL));
+
+    
+  p = aRunway->pointOnCenterline(-8.0 * SG_NM_TO_METER);
+  p.setElevationFt(thresholdElevFt + approachHeightFt);
+  ss.str("");
+  ss << aRunway->ident() << "-8";
+  wpts.push_back(new BasicWaypt(p, ss.str(), NULL));
+  
+  p = aRunway->pointOnCenterline(-glideslopeDistanceM);
+  p.setElevationFt(thresholdElevFt + approachHeightFt);
+    
+  ss.str("");
+  ss << aRunway->ident() << "-GS";
+  wpts.push_back(new BasicWaypt(p, ss.str(), NULL));
+  
+  wpts.push_back(new RunwayWaypt(aRunway, NULL));
+  
+  BOOST_FOREACH(Waypt* w, wpts) {
+    w->setFlag(WPT_APPROACH);
+    w->setFlag(WPT_GENERATED);
+  }
+  
+  return Approach::createTempApproach("DEFAULT", aRunway, wpts);
+}
+
 void FGRouteMgr::setApproach(const char* aIdent)
 {
   FGAirport* apt = _plan->destinationAirport();
+  if (!strcmp(aIdent, "DEFAULT")) {
+    _plan->setApproach(createDefaultApproach(_plan->destinationRunway()));
+    return;
+  }
+  
   if (!apt || (aIdent == NULL)) {
     _plan->setApproach(NULL);
   } else {
index 78dc7e6ab4f88bf389afdd117a417959b655f361..bdd022830d5968d78d8ee7dd6d5b33acec94d1f2 100644 (file)
@@ -247,9 +247,9 @@ private:
   
   FGAirportRef _departure, _destination;
   FGRunway* _departureRunway, *_destinationRunway;
-  SID* _sid;
-  STAR* _star;
-  Approach* _approach;
+  SGSharedPtr<SID> _sid;
+  SGSharedPtr<STAR> _star;
+  SGSharedPtr<Approach> _approach;
   std::string _sidTransition, _starTransition;
   
   double _totalDistance;
index d36d203af69d4ed6e99999488c1477193929b777..514cb6187b2879c837597150ed9745b90e25e6bf 100644 (file)
@@ -36,7 +36,7 @@ struct SearchContext;
 class AdjacentWaypoint;
 class InAirwayFilter;
 
-class Airway : public RouteBase
+class Airway
 {
 public:
   virtual std::string ident() const
index 48a2846ed85fc065086076cbc50c460c17536ce6..94afcdd2c69b3cd9f9e6a64dff5696ad0e650705 100644 (file)
@@ -49,6 +49,14 @@ Approach::Approach(const string& aIdent, ProcedureType ty) :
 {
 
 }
+    
+Approach* Approach::createTempApproach(const std::string& aIdent, FGRunway* aRunway, const WayptVec& aPath)
+{
+    Approach* app = new Approach(aIdent, PROCEDURE_APPROACH_RNAV);
+    app->setRunway(aRunway);
+    app->setPrimaryAndMissed(aPath, WayptVec());
+    return app;
+}
 
 void Approach::setRunway(FGRunwayRef aRwy)
 {
@@ -329,6 +337,19 @@ bool SID::route(FGRunwayRef aWay, Transition* trans, WayptVec& aPath)
 
   return true;
 }
+    
+SID* SID::createTempSID(const std::string& aIdent, FGRunway* aRunway, const WayptVec& aPath)
+{
+// flip waypoints since SID stores them reversed
+    WayptVec path;
+    std::back_insert_iterator<WayptVec> bi(path);
+    std::reverse_copy(aPath.begin(), aPath.end(), bi);
+    
+    SID* sid = new SID(aIdent, aRunway->airport());
+    sid->setCommon(path);
+    sid->addRunway(aRunway);
+    return sid;
+}
 
 ////////////////////////////////////////////////////////////////////////////
 
index 11bbf4908632236b80c08798a28493c1d29f45fb..1a4ce12298139ec969c936842d4ac97c1576a523 100644 (file)
@@ -72,6 +72,8 @@ protected:
 class Transition : public Procedure
 {
 public:
+  virtual ~Transition() { ; }
+    
   bool route(WayptVec& aPath);
   
   Procedure* parent() const
@@ -106,6 +108,8 @@ private:
   WayptVec _primary;
 };
 
+typedef SGSharedPtr<Transition> TransitionRef;
+    
 /**
  * Describe an approach procedure, including the missed approach
  * segment
@@ -113,6 +117,8 @@ private:
 class Approach : public Procedure
 {
 public:
+  virtual ~Approach() { ; }
+    
   FGRunwayRef runway() 
   { return _runway; }
 
@@ -143,6 +149,8 @@ public:
 
   virtual ProcedureType type() const
   { return _type; }
+    
+  static Approach* createTempApproach(const std::string& aIdent, FGRunway* aRunway, const WayptVec& aPath);
 private:
   friend class NavdataVisitor;
   
@@ -155,7 +163,7 @@ private:
   FGRunwayRef _runway;
   ProcedureType _type;
   
-  typedef std::map<WayptRef, Transition*> WptTransitionMap;
+  typedef std::map<WayptRef, TransitionRef> WptTransitionMap;
   WptTransitionMap _transitions;
   
   WayptVec _primary; // unify these?
@@ -207,26 +215,26 @@ protected:
   
   ArrivalDeparture(const std::string& aIdent, FGAirport* apt);
   
-  
   void addRunway(FGRunwayRef aRwy);
 
-  typedef std::map<FGRunwayRef, Transition*> RunwayTransitionMap;
+  typedef std::map<FGRunwayRef, TransitionRef> RunwayTransitionMap;
   RunwayTransitionMap _runways;
   
   virtual WayptFlag flagType() const = 0;
+    
+    void setCommon(const WayptVec& aWps);
+
 private:
   friend class NavdataVisitor;
   
   void addTransition(Transition* aTrans);
   
-  void setCommon(const WayptVec& aWps);
-
   void addRunwayTransition(FGRunwayRef aRwy, Transition* aTrans);
   
   FGAirport* _airport;
   WayptVec _common;
   
-  typedef std::map<WayptRef, Transition*> WptTransitionMap;
+  typedef std::map<WayptRef, TransitionRef> WptTransitionMap;
   WptTransitionMap _enrouteTransitions;
   
   
@@ -234,12 +242,15 @@ private:
 
 class SID : public ArrivalDeparture
 {
-public:  
+public:
+    virtual ~SID() { ; }
+        
   virtual bool route(FGRunwayRef aWay, Transition* aTrans, WayptVec& aPath);
   
   virtual ProcedureType type() const
   { return PROCEDURE_SID; }
   
+  static SID* createTempSID(const std::string& aIdent, FGRunway* aRunway, const WayptVec& aPath);
 protected:
   virtual WayptFlag flagType() const
   { return WPT_DEPARTURE; }
@@ -252,7 +263,9 @@ private:
 
 class STAR : public ArrivalDeparture
 {
-public:  
+public:
+  virtual ~STAR() { ; }
+    
   virtual bool route(FGRunwayRef aWay, Transition* aTrans, WayptVec& aPath);
   
   virtual ProcedureType type() const
index 33d45ce2a5cbd46cafab29fa4c486359bd2b7b49..344ac1b38d8afb2f917d41ef041368253ee05029 100644 (file)
@@ -219,7 +219,7 @@ private:
 
 typedef std::vector<WayptRef> WayptVec;
   
-class RouteBase
+class RouteBase : public SGReferenced
 {
 public:
   /**