]> git.mxchange.org Git - flightgear.git/blobdiff - src/Autopilot/route_mgr.cxx
toggle fullscreen: also adapt GUI plane when resizing
[flightgear.git] / src / Autopilot / route_mgr.cxx
index ffb9dc306235f50fec29189059fa957ca9742fa7..f28403197e0ccbb1d98e22a1d37c9f362f7a6221 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>
@@ -56,6 +57,7 @@
 #define RM "/autopilot/route-manager/"
 
 using namespace flightgear;
+using std::string;
 
 static bool commandLoadFlightPlan(const SGPropertyNode* arg)
 {
@@ -78,7 +80,7 @@ static bool commandActivateFlightPlan(const SGPropertyNode* arg)
   if (activate) {
     self->activate();
   } else {
-    
+    self->deactivate();
   }
   
   return true;
@@ -585,77 +587,6 @@ void FGRouteMgr::removeLegAtIndex(int aIndex)
   _plan->deleteIndex(aIndex);
 }
   
-void FGRouteMgr::departureChanged()
-{
-  _plan->clearWayptsWithFlag(WPT_DEPARTURE);
-  WayptRef enroute;
-  WayptVec wps;
-  buildDeparture(enroute, wps);
-  _plan->insertWayptsAtIndex(wps, 0);
-}
-
-void FGRouteMgr::buildDeparture(WayptRef enroute, WayptVec& wps)
-{
-  if (!_plan->departureAirport()) {
-    return;
-  }
-  
-  if (!_plan->departureRunway()) {
-// valid airport, but no runway selected, so just the airport _plan itself
-    WayptRef w = new NavaidWaypoint(_plan->departureAirport(), _plan);
-    w->setFlag(WPT_DEPARTURE);
-    wps.push_back(w);
-    return;
-  }
-  
-  WayptRef rwyWaypt = new RunwayWaypt(_plan->departureRunway(), _plan);
-  rwyWaypt->setFlag(WPT_DEPARTURE);
-  wps.push_back(rwyWaypt);
-  
-  if (!_plan->sid()) {
-    return;
-  }
-  
-  _plan->sid()->route(_plan->departureRunway(), _plan->sidTransition(), wps);
-}
-
-void FGRouteMgr::arrivalChanged()
-{  
-  _plan->clearWayptsWithFlag(WPT_ARRIVAL);
-  _plan->clearWayptsWithFlag(WPT_APPROACH);
-  WayptVec wps;
-  WayptRef enroute;
-  buildArrival(enroute, wps);
-  _plan->insertWayptsAtIndex(wps, -1);
-}
-
-void FGRouteMgr::buildArrival(WayptRef enroute, WayptVec& wps)
-{
-  FGAirportRef apt = _plan->destinationAirport();
-  if (!apt.valid()) {
-    return;
-  }
-  
-  if (!_plan->destinationRunway()) {
-    WayptRef w = new NavaidWaypoint(apt.ptr(), _plan);
-    w->setFlag(WPT_ARRIVAL);
-    wps.push_back(w);
-    return;
-  }
-  
-  if (_plan->star()) {
-    _plan->star()->route(_plan->destinationRunway(), _plan->starTransition(), wps);
-  }
-  
-  if (_plan->approach()) {
-    _plan->approach()->route(wps.back(), wps);
-  } else {
-    WayptRef w = new RunwayWaypt(_plan->destinationRunway(), _plan);
-    w->setFlag(WPT_APPROACH);
-    wps.push_back(w);
-  }
-}
-
 void FGRouteMgr::waypointsChanged()
 {
   update_mirror();
@@ -854,6 +785,15 @@ bool FGRouteMgr::activate()
   return true;
 }
 
+void FGRouteMgr::deactivate()
+{
+  if (!isRouteActive()) {
+    return;
+  }
+  
+  SG_LOG(SG_AUTOPILOT, SG_INFO, "deactivating flight plan");
+  active->setBoolValue(false);
+}
 
 void FGRouteMgr::sequence()
 {
@@ -974,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 flightgear::SID::createTempSID("DEFAULT", aRunway, wpts);
+}
+
 void FGRouteMgr::setSID(const char* aIdent)
 {
   FGAirport* apt = _plan->departureAirport();
@@ -982,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) {
@@ -1051,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 {