From: James Turner Date: Mon, 12 Nov 2012 21:30:28 +0000 (+0100) Subject: Support for creating default SID/approach. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=78d97fa4689059925c5d0ca7bb758000a1ee34e5;p=flightgear.git Support for creating default SID/approach. 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. --- diff --git a/src/Airports/simple.hxx b/src/Airports/simple.hxx index 3ee46ea7b..de7f0b8ca 100644 --- a/src/Airports/simple.hxx +++ b/src/Airports/simple.hxx @@ -262,9 +262,13 @@ private: mutable PositionedIDVec mTaxiways; PositionedIDVec mPavements; - std::vector mSIDs; - std::vector mSTARs; - std::vector mApproaches; + typedef SGSharedPtr SIDRef; + typedef SGSharedPtr STARRef; + typedef SGSharedPtr ApproachRef; + + std::vector mSIDs; + std::vector mSTARs; + std::vector mApproaches; }; // find basic airport location info from airport database diff --git a/src/Autopilot/route_mgr.cxx b/src/Autopilot/route_mgr.cxx index d39c49c55..9d3c17b08 100644 --- a/src/Autopilot/route_mgr.cxx +++ b/src/Autopilot/route_mgr.cxx @@ -37,6 +37,7 @@ #include #include +#include #include #include @@ -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 { diff --git a/src/Navaids/FlightPlan.hxx b/src/Navaids/FlightPlan.hxx index 78dc7e6ab..bdd022830 100644 --- a/src/Navaids/FlightPlan.hxx +++ b/src/Navaids/FlightPlan.hxx @@ -247,9 +247,9 @@ private: FGAirportRef _departure, _destination; FGRunway* _departureRunway, *_destinationRunway; - SID* _sid; - STAR* _star; - Approach* _approach; + SGSharedPtr _sid; + SGSharedPtr _star; + SGSharedPtr _approach; std::string _sidTransition, _starTransition; double _totalDistance; diff --git a/src/Navaids/airways.hxx b/src/Navaids/airways.hxx index d36d203af..514cb6187 100644 --- a/src/Navaids/airways.hxx +++ b/src/Navaids/airways.hxx @@ -36,7 +36,7 @@ struct SearchContext; class AdjacentWaypoint; class InAirwayFilter; -class Airway : public RouteBase +class Airway { public: virtual std::string ident() const diff --git a/src/Navaids/procedure.cxx b/src/Navaids/procedure.cxx index 48a2846ed..94afcdd2c 100644 --- a/src/Navaids/procedure.cxx +++ b/src/Navaids/procedure.cxx @@ -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 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; +} //////////////////////////////////////////////////////////////////////////// diff --git a/src/Navaids/procedure.hxx b/src/Navaids/procedure.hxx index 11bbf4908..1a4ce1229 100644 --- a/src/Navaids/procedure.hxx +++ b/src/Navaids/procedure.hxx @@ -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 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 WptTransitionMap; + typedef std::map 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 RunwayTransitionMap; + typedef std::map 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 WptTransitionMap; + typedef std::map 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 diff --git a/src/Navaids/route.hxx b/src/Navaids/route.hxx index 33d45ce2a..344ac1b38 100644 --- a/src/Navaids/route.hxx +++ b/src/Navaids/route.hxx @@ -219,7 +219,7 @@ private: typedef std::vector WayptVec; -class RouteBase +class RouteBase : public SGReferenced { public: /**