]> git.mxchange.org Git - flightgear.git/blobdiff - src/AIModel/AIFlightPlanCreateCruise.cxx
Fix crashes (activating the route-manager) with a default GPS.
[flightgear.git] / src / AIModel / AIFlightPlanCreateCruise.cxx
old mode 100755 (executable)
new mode 100644 (file)
index c60e40b..13df4b6
  *
  *
  **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
 #include <fstream>
 #include <iostream>
-#include "AIFlightPlan.hxx"
-#include <simgear/math/polar3d.hxx>
-#include <simgear/math/sg_geodesy.hxx>
 #include <simgear/route/waypoint.hxx>
 
 #include <Navaids/awynet.hxx>
 #include <Airports/runways.hxx>
+#include <Airports/dynamics.hxx>
 
 #include <Environment/environment_mgr.hxx>
 #include <Environment/environment.hxx>
 
-SG_USING_STD(iostream);
+#include "AIFlightPlan.hxx"
+#include "AIAircraft.hxx"
+#include "performancedata.hxx"
+
+using std::iostream;
 
 void FGAIFlightPlan::evaluateRoutePart(double deplat,
                                       double deplon,
@@ -43,69 +50,31 @@ void FGAIFlightPlan::evaluateRoutePart(double deplat,
   intVec nodes;
   int tmpNode, prevNode;
 
+  SGGeoc dep(SGGeoc::fromDegM(deplon, deplat, 100.0));
+  SGGeoc arr(SGGeoc::fromDegM(arrlon, arrlat, 100.0));
+  
+  SGVec3d a = SGVec3d::fromGeoc(dep);
+  SGVec3d nb = normalize(SGVec3d::fromGeoc(arr));
+  SGVec3d na = normalize(a);
+  
+  SGVec3d _cross = cross(nb, na);
 
-  SGWayPoint first (deplon,
-                   deplat,
-                   100);
-  SGWayPoint sec (arrlon,
-                 arrlat,
-                 100);
-  first.CourseAndDistance(sec, &course, &distance);
-  distance *= SG_METER_TO_NM;
-  temp = sgPolarToCart3d(Point3D(deplon *
-                                SG_DEGREES_TO_RADIANS,
-                                deplat  *
-                                SG_DEGREES_TO_RADIANS,
-                                1.0));
-  a[0] = temp.x();
-  a[1] = temp.y();
-  a[2] = temp.z();
-
-  temp = sgPolarToCart3d(Point3D(arrlon *
-                                SG_DEGREES_TO_RADIANS,
-                                arrlat  *
-                                SG_DEGREES_TO_RADIANS,
-                                1.0));
-  b[0] = temp.x();
-  b[1] = temp.y();
-  b[2] = temp.z();
-  sgdNormaliseVec3(a);
-  sgdNormaliseVec3(b);
-  sgdVectorProductVec3(cross,b,a);
-
-  angle = sgACos(sgdScalarProductVec3(a,b));
+  double angle = acos(dot(na, nb));
+  const double angleStep = 0.05 * SG_DEGREES_TO_RADIANS;
   tmpNode = 0;
-  for (double ang = 0.0; ang < angle; ang += 0.05)
-    {
-      //cerr << "Angle = " << ang << endl;
-      sgdMakeRotMat4(matrix, ang, cross);
-      for(int j = 0; j < 3; j++)
-       {
-         newPos[j] =0.0;
-         for (int k = 0; k<3; k++)
-           {
-             newPos[j] += matrix[j][k]*a[k];
-           }
-       }
-      //cerr << "1"<< endl;
-      temp = sgCartToPolar3d(Point3D(newPos[0], newPos[1],newPos[2]));
-      midlat = temp.lat() * SG_RADIANS_TO_DEGREES;
-      midlon = temp.lon() * SG_RADIANS_TO_DEGREES;
+  for (double ang = 0.0; ang < angle; ang += angleStep)
+  {  
+      SGQuatd q = SGQuatd::fromAngleAxis(ang, _cross);
+      SGGeod geod = SGGeod::fromCart(q.transform(a));
 
       prevNode = tmpNode;
-      tmpNode = globals->get_airwaynet()->findNearestNode(midlat, midlon);
+      tmpNode = globals->get_airwaynet()->findNearestNode(geod);
 
-      double nodelat = globals->get_airwaynet()->findNode(tmpNode)->getLatitude  ();
-      double nodelon = globals->get_airwaynet()->findNode(tmpNode)->getLongitude ();
-      SGWayPoint curr(midlat,
-                     midlon,
-                     100);
-      SGWayPoint node(nodelat,
-                     nodelon,
-                     100);
-      curr.CourseAndDistance(node, &course, &distance);
-      if ((distance < 25000) && (tmpNode != prevNode))
-       nodes.push_back(tmpNode);
+      FGNode* node = globals->get_airwaynet()->findNode(tmpNode);
+    
+      if ((tmpNode != prevNode) && (SGGeodesy::distanceM(geod, node->getPosition()) < 25000)) {
+        nodes.push_back(tmpNode);
+      }
     }
 
     intVecIterator i = nodes.begin();
@@ -316,62 +285,23 @@ void FGAIFlightPlan::createCruise(bool firstFlight, FGAirport *dep,
  * Note that this is the original version that does not 
  * do any dynamic route computation.
  ******************************************************************/
-void FGAIFlightPlan::createCruise(bool firstFlight, FGAirport *dep, 
+void FGAIFlightPlan::createCruise(FGAIAircraft *ac, bool firstFlight, FGAirport *dep, 
                                  FGAirport *arr, double latitude, 
                                  double longitude, double speed, 
-                                 double alt)
+                                 double alt, const string& fltType)
 {
-  double wind_speed;
-  double wind_heading;
-  double heading;
-  double lat, lon, az;
-  double lat2, lon2, az2;
-  double azimuth;
+  double vCruise = ac->getPerformance()->vCruise();
   waypoint *wpt;
-
-  wpt = new waypoint;
-  wpt->name      = "Cruise"; //wpt_node->getStringValue("name", "END");
-  wpt->latitude  = latitude;
-  wpt->longitude = longitude;
-  wpt->altitude  = alt;
-  wpt->speed     = speed; 
-  wpt->crossat   = -10000;
-  wpt->gear_down = false;
-  wpt->flaps_down= false;
-  wpt->finished  = false;
-  wpt->on_ground = false;
+  wpt = createInAir(ac, "Cruise", SGGeod::fromDeg(longitude, latitude), alt, vCruise);
   waypoints.push_back(wpt); 
   
-  // should be changed dynamically to allow "gen" and "mil"
-  arr->getDynamics()->getActiveRunway("com", 2, activeRunway);
-  if (!(globals->get_runways()->search(arr->getId(), 
-                                      activeRunway, 
-                                      &rwy)))
-    {
-      SG_LOG(SG_INPUT, SG_ALERT, "Failed to find runway " << 
-            activeRunway << 
-            " at airport     " << arr->getId());
-      exit(1);
-    }
-  heading = rwy._heading;
-  azimuth = heading + 180.0;
-  while ( azimuth >= 360.0 ) { azimuth -= 360.0; }
-  
+  string rwyClass = getRunwayClassFromTrafficType(fltType);
+  double heading = ac->getTrafficRef()->getCourse();
+  arr->getDynamics()->getActiveRunway(rwyClass, 2, activeRunway, heading);
+  rwy = arr->getRunwayByIdent(activeRunway);
+  // begin descent 110km out
+  SGGeod beginDescentPoint = rwy->pointOnCenterline(-110000);
   
-  geo_direct_wgs_84 ( 0, rwy._lat, rwy._lon, azimuth, 
-                     110000,
-                     &lat2, &lon2, &az2 );
-  wpt = new waypoint;
-  wpt->name      = "BOD";
-  wpt->latitude  = lat2;
-  wpt->longitude = lon2;
-  wpt->altitude  = alt;
-  wpt->speed     = speed; 
-  wpt->crossat   = alt;
-  wpt->gear_down = false;
-  wpt->flaps_down= false;
-  wpt->finished  = false;
-  wpt->on_ground = false;
+  wpt = createInAir(ac, "BOD", beginDescentPoint, alt, vCruise);
   waypoints.push_back(wpt); 
 }