]> git.mxchange.org Git - flightgear.git/blobdiff - src/AIModel/AIAircraft.cxx
warnings--
[flightgear.git] / src / AIModel / AIAircraft.cxx
index 5c560d9bcd4209b7b7a2cb07fcadd8b0d0d6ec19..c312e51049bd39dbdd5db24c6273565023ff9001 100644 (file)
@@ -58,7 +58,9 @@ const FGAIAircraft::PERF_STRUCT FGAIAircraft::settings[] = {
     // jet_fighter
     {7.0, 3.0, 4000.0, 2000.0, 150.0, 350.0, 500.0, 350.0, 150.0},
     // tanker
-    {5.0, 2.0, 3000.0, 1500.0, 140.0, 300.0, 430.0, 300.0, 130.0}
+    {5.0, 2.0, 3000.0, 1500.0, 140.0, 300.0, 430.0, 300.0, 130.0},
+    // ufo (extreme accel/decel)
+    {30.0, 30.0, 6000.0, 6000.0, 150.0, 300.0, 430.0, 300.0, 130.0}
 };
 
 
@@ -150,6 +152,8 @@ void FGAIAircraft::setPerformance(const std::string& acclass) {
     } else if (acclass == "tanker") {
         SetPerformance(&FGAIAircraft::settings[FGAIAircraft::JET_TRANSPORT]);
         SetTanker(true);
+    } else if (acclass == "ufo") {
+        SetPerformance(&FGAIAircraft::settings[FGAIAircraft::UFO]);
     } else {
         SetPerformance(&FGAIAircraft::settings[FGAIAircraft::JET_TRANSPORT]);
     }
@@ -165,7 +169,7 @@ void FGAIAircraft::SetPerformance(const PERF_STRUCT *ps) {
 void FGAIAircraft::Run(double dt) {
 
     FGAIAircraft::dt = dt;
-
+    
     if (fp) {
         time_t now = time(NULL) + fgGetLong("/sim/time/warp");
         ProcessFlightPlan(dt, now);
@@ -180,12 +184,40 @@ void FGAIAircraft::Run(double dt) {
                 doGroundAltitude();
                 //cerr << " Actual altitude " << altitude << endl;
                 // Transform();
-                pos.setelev(altitude * SG_FEET_TO_METER);
+                pos.setElevationFt(altitude_ft);
             }
             return;
         }
-    }
+    } else {
+        // no flight plan, update target heading, speed, and altitude
+        // from control properties.  These default to the initial
+        // settings in the config file, but can be changed "on the
+        // fly".
+        string lat_mode = props->getStringValue("controls/flight/lateral-mode");
+        if ( lat_mode == "roll" ) {
+            double angle
+                = props->getDoubleValue("controls/flight/target-roll" );
+            RollTo( angle );
+        } else {
+             double angle
+                = props->getDoubleValue("controls/flight/target-hdg" );
+            TurnTo( angle );
+        }
 
+        string lon_mode
+            = props->getStringValue("controls/flight/longitude-mode");
+        if ( lon_mode == "alt" ) {
+            double alt = props->getDoubleValue("controls/flight/target-alt" );
+            ClimbTo( alt );
+        } else {
+            double angle
+                = props->getDoubleValue("controls/flight/target-pitch" );
+            PitchTo( angle );
+        }
+
+        AccelTo( props->getDoubleValue("controls/flight/target-spd" ) );
+    }
+      
     double turn_radius_ft;
     double turn_circum_ft;
     double speed_north_deg_sec;
@@ -200,27 +232,47 @@ void FGAIAircraft::Run(double dt) {
     } else {
         speed_diff = groundTargetSpeed - speed;
     }
-    if (fabs(speed_diff) > 0.2) {
-        if (speed_diff > 0.0)
-            speed += performance->accel * dt;
-        if (speed_diff < 0.0) {
-            if (no_roll) { // was (!no_roll) but seems more logical this way (ground brakes).
-                speed -= performance->decel * dt * 3;
-            } else {
-                speed -= performance->decel * dt;
-            }
+
+    if (speed_diff > 0.0) {
+        speed += performance->accel * dt;
+       if (no_roll) { // apply overshoot correction
+         if ( speed > groundTargetSpeed ) speed = groundTargetSpeed;
+       }else {
+         if ( speed > tgt_speed ) speed = tgt_speed;
+       }
+    } else if (speed_diff < 0.0) {
+        if (no_roll) {
+            // on ground (aircraft can't roll)
+           // deceleration performance is better due to wheel brakes.
+            speed -= performance->decel * dt * 3;
+        } else {
+            speed -= performance->decel * dt;
         }
+       if (no_roll) { // apply overshoot correction
+        if (speed < groundTargetSpeed ) speed = groundTargetSpeed;
+       } else { 
+         if ( speed < tgt_speed ) speed = tgt_speed;
+       }
     }
-
+    
+    
     // convert speed to degrees per second
-    speed_north_deg_sec = cos( hdg / SG_RADIANS_TO_DEGREES )
+    speed_north_deg_sec = cos( hdg * SGD_DEGREES_TO_RADIANS )
                           * speed * 1.686 / ft_per_deg_lat;
-    speed_east_deg_sec  = sin( hdg / SG_RADIANS_TO_DEGREES )
+    speed_east_deg_sec  = sin( hdg * SGD_DEGREES_TO_RADIANS )
                           * speed * 1.686 / ft_per_deg_lon;
 
     // set new position
-    pos.setlat( pos.lat() + speed_north_deg_sec * dt);
-    pos.setlon( pos.lon() + speed_east_deg_sec * dt);
+    pos.setLatitudeDeg( pos.getLatitudeDeg() + speed_north_deg_sec * dt);
+    pos.setLongitudeDeg( pos.getLongitudeDeg() + speed_east_deg_sec * dt); 
+
+    /* printf("%.7f %0.4f %.7f %.5f %.7f %.7f %.8f %.8f %.9f %.9f\n",
+           dt, hdg, speed, ft_per_deg_lat,
+           cos( hdg * SGD_DEGREES_TO_RADIANS ),
+           speed * 1.686 / ft_per_deg_lat,
+           speed_north_deg_sec, speed_east_deg_sec,
+           pos.getLatitudeDeg(), pos.getLongitudeDeg()); */
+
     //if (!(finite(pos.lat()) && finite(pos.lon())))
     //  {
     //    cerr << "Position is not finite" << endl;
@@ -360,9 +412,8 @@ void FGAIAircraft::Run(double dt) {
     }
 
     // adjust altitude (meters) based on current vertical speed (fpm)
-    altitude += vs / 60.0 * dt;
-    pos.setelev(altitude * SG_FEET_TO_METER);
-    double altitude_ft = altitude;
+    altitude_ft += vs / 60.0 * dt;
+    pos.setElevationFt(altitude_ft);  
 
     // adjust target Altitude, based on ground elevation when on ground
     if (no_roll) {
@@ -371,23 +422,23 @@ void FGAIAircraft::Run(double dt) {
     } else {
         // find target vertical speed if altitude lock engaged
         if (alt_lock && use_perf_vs) {
-            if (altitude_ft < tgt_altitude) {
-                tgt_vs = tgt_altitude - altitude_ft;
+            if (altitude_ft < tgt_altitude_ft) {
+                tgt_vs = tgt_altitude_ft - altitude_ft;
                 if (tgt_vs > performance->climb_rate)
                     tgt_vs = performance->climb_rate;
             } else {
-                tgt_vs = tgt_altitude - altitude_ft;
+                tgt_vs = tgt_altitude_ft - altitude_ft;
                 if (tgt_vs  < (-performance->descent_rate))
                     tgt_vs = -performance->descent_rate;
             }
         }
 
         if (alt_lock && !use_perf_vs) {
-            double max_vs = 4*(tgt_altitude - altitude);
+            double max_vs = 4*(tgt_altitude_ft - altitude_ft);
             double min_vs = 100;
-            if (tgt_altitude < altitude)
+            if (tgt_altitude_ft < altitude_ft)
                 min_vs = -100.0;
-            if ((fabs(tgt_altitude - altitude) < 1500.0)
+            if ((fabs(tgt_altitude_ft - altitude_ft) < 1500.0)
                     && (fabs(max_vs) < fabs(tgt_vs)))
                 tgt_vs = max_vs;
 
@@ -464,8 +515,8 @@ void FGAIAircraft::YawTo(double angle) {
 }
 
 
-void FGAIAircraft::ClimbTo(double altitude) {
-    tgt_altitude = altitude;
+void FGAIAircraft::ClimbTo(double alt_ft ) {
+    tgt_altitude_ft = alt_ft;
     alt_lock = true;
 }
 
@@ -564,12 +615,12 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) {
         if (curr->crossat > -1000.0) { //use a calculated descent/climb rate
             use_perf_vs = false;
             tgt_vs = (curr->crossat - prev->altitude)
-                    / (fp->getDistanceToGo(pos.lat(), pos.lon(), curr)
+                    / (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)
                     / 6076.0 / prev->speed*60.0);
-            tgt_altitude = curr->crossat;
+            tgt_altitude_ft = curr->crossat;
         } else {
             use_perf_vs = true;
-            tgt_altitude = prev->altitude;
+            tgt_altitude_ft = prev->altitude;
         }
         alt_lock = hdg_lock = true;
         no_roll = prev->on_ground;
@@ -597,7 +648,7 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) {
         dt_count = 0;
     }
     // check to see if we've reached the lead point for our next turn
-    double dist_to_go = fp->getDistanceToGo(pos.lat(), pos.lon(), curr);
+    double dist_to_go = fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr);
 
     //cerr << "2" << endl;
     double lead_dist = fp->getLeadDistance();
@@ -666,7 +717,7 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) {
             double userLatitude  = fgGetDouble("/position/latitude-deg");
             double userLongitude = fgGetDouble("/position/longitude-deg");
             double course, distance;
-            SGWayPoint current (pos.lon(), pos.lat(), 0);
+            SGWayPoint current(pos.getLongitudeDeg(), pos.getLatitudeDeg(), 0);
             SGWayPoint user (userLongitude, userLatitude, 0);
             user.CourseAndDistance(current, &course, &distance);
             if ((distance * SG_METER_TO_NM) > TRAFFICTOAIDIST) {
@@ -732,19 +783,19 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) {
 
         //cerr << "5.1" << endl;
         if (!(prev->on_ground)) { // only update the tgt altitude from flightplan if not on the ground
-            tgt_altitude = prev->altitude;
+            tgt_altitude_ft = prev->altitude;
             if (curr->crossat > -1000.0) {
                 //cerr << "5.1a" << endl;
                 use_perf_vs = false;
-                tgt_vs = (curr->crossat - altitude) / (fp->getDistanceToGo(pos.lat(), pos.lon(), curr)
+                tgt_vs = (curr->crossat - altitude_ft) / (fp->getDistanceToGo(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr)
                         / 6076.0 / speed*60.0);
                 //cerr << "5.1b" << endl;
-                tgt_altitude = curr->crossat;
+                tgt_altitude_ft = curr->crossat;
             } else {
                 //cerr << "5.1c" << endl;
                 use_perf_vs = true;
                 //cerr << "5.1d" << endl;
-                //cerr << "Setting target altitude : " <<tgt_altitude << endl;
+                //cerr << "Setting target altitude : " <<tgt_altitude_ft << endl;
             }
         }
         //cerr << "6" << endl;
@@ -753,11 +804,11 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) {
         no_roll = prev->on_ground;
         //cout << "Crossing waypoint: " << prev->name << endl;
         //cout << "  Target speed:    " << tgt_speed << endl;
-        //cout << "  Target altitude: " << tgt_altitude << endl;
+        //cout << "  Target altitude: " << tgt_altitude_ft << endl;
         //cout << "  Target heading:  " << tgt_heading << endl << endl;
 
     } else {
-        double calc_bearing = fp->getBearing(pos.lat(), pos.lon(), curr);
+        double calc_bearing = fp->getBearing(pos.getLatitudeDeg(), pos.getLongitudeDeg(), curr);
         //cerr << "Bearing = " << calc_bearing << endl;
         if (speed < 0) {
             calc_bearing +=180;
@@ -774,7 +825,7 @@ void FGAIAircraft::ProcessFlightPlan( double dt, time_t now ) {
         } else {
             cerr << "calc_bearing is not a finite number : "
                  << "Speed " << speed
-                 << "pos : " << pos.lat() << ", " << pos.lon()
+                 << "pos : " << pos.getLatitudeDeg() << ", " << pos.getLongitudeDeg()
                  << "waypoint " << curr->latitude << ", " << curr->longitude << endl;
             cerr << "waypoint name " << curr->name;
             exit(1);  // FIXME
@@ -863,16 +914,16 @@ void FGAIAircraft::loadNextLeg() {
         //        //cerr << "25.1a" << endl;
         //        use_perf_vs = false;
         //
-        //        tgt_vs = (curr->crossat - altitude)/
+        //        tgt_vs = (curr->crossat - altitude_ft)/
         //          (fp->getDistanceToGo(pos.lat(), pos.lon(), curr)/6076.0/speed*60.0);
         //        //cerr << "25.1b" << endl;
-        //        tgt_altitude = curr->crossat;
+        //        tgt_altitude_ft = curr->crossat;
         //} else {
         //        //cerr << "25.1c" << endl;
         //        use_perf_vs = true;
         //        //cerr << "25.1d" << endl;
-        //        tgt_altitude = prev->altitude;
-        //        //cerr << "Setting target altitude : " <<tgt_altitude << endl;
+        //        tgt_altitude_ft = prev->altitude;
+        //        //cerr << "Setting target altitude : " <<tgt_altitude_ft << endl;
         // }
         //cerr << "26" << endl;
         //tgt_speed = prev->speed;
@@ -909,12 +960,6 @@ void FGAIAircraft::getGroundElev(double dt) {
     else
        dt_elev_count = 0;
 
-    // It would be nice if we could set the correct tile center here in order to get a correct
-    // answer with one call to the function, but what I tried in the two commented-out lines
-    // below only intermittently worked, and I haven't quite groked why yet.
-    //SGBucket buck(pos.lon(), pos.lat());
-    //aip.getSGLocation()->set_tile_center(Point3D(buck.get_center_lon(), buck.get_center_lat(), 0.0));
-
     // Only do the proper hitlist stuff if we are within visible range of the viewer.
     if (!invisible) {
         double visibility_meters = fgGetDouble("/environment/visibility-m");
@@ -922,9 +967,7 @@ void FGAIAircraft::getGroundElev(double dt) {
         FGViewer* vw = globals->get_current_view();
         double course, distance;
 
-        //Point3D currView(vw->getLongitude_deg(),
-        //                 vw->getLatitude_deg(), 0.0);
-        SGWayPoint current (pos.lon(), pos.lat(), 0);
+        SGWayPoint current(pos.getLongitudeDeg(), pos.getLatitudeDeg(), 0);
         SGWayPoint view (vw->getLongitude_deg(), vw->getLatitude_deg(), 0);
         view.CourseAndDistance(current, &course, &distance);
         if(distance > visibility_meters) {
@@ -934,21 +977,21 @@ void FGAIAircraft::getGroundElev(double dt) {
 
         // FIXME: make sure the pos.lat/pos.lon values are in degrees ...
         double range = 500.0;
-        if (!globals->get_tile_mgr()->scenery_available(pos.lat(), pos.lon(), range)) {
+        if (!globals->get_tile_mgr()->scenery_available(pos.getLatitudeDeg(), pos.getLongitudeDeg(), range)) {
             // Try to shedule tiles for that position.
             globals->get_tile_mgr()->update( aip.getSGLocation(), range );
         }
 
         // FIXME: make sure the pos.lat/pos.lon values are in degrees ...
         double alt;
-        if (globals->get_scenery()->get_elevation_m(pos.lat(), pos.lon(), 20000.0, alt, 0))
-            tgt_altitude = alt * SG_METER_TO_FEET;
+        if (globals->get_scenery()->get_elevation_m(pos.getLatitudeDeg(), pos.getLongitudeDeg(), 20000.0, alt, 0))
+            tgt_altitude_ft = alt * SG_METER_TO_FEET;
 
-        //cerr << "Target altitude : " << tgt_altitude << endl;
+        //cerr << "Target altitude : " << tgt_altitude_ft << endl;
         // if (globals->get_scenery()->get_elevation_m(pos.lat(), pos.lon(),
         //                                            20000.0, alt))
-        //    tgt_altitude = alt * SG_METER_TO_FEET;
-        //cerr << "Target altitude : " << tgt_altitude << endl;
+        //    tgt_altitude_ft = alt * SG_METER_TO_FEET;
+        //cerr << "Target altitude : " << tgt_altitude_ft << endl;
     }
 }
 
@@ -964,9 +1007,9 @@ void FGAIAircraft::setTACANChannelID(const string& id) {
 
 
 void FGAIAircraft::doGroundAltitude() {
-   if (fabs(altitude - (tgt_altitude+groundOffset)) > 1000.0)
-       altitude = (tgt_altitude + groundOffset);
+   if (fabs(altitude_ft - (tgt_altitude_ft+groundOffset)) > 1000.0)
+       altitude_ft = (tgt_altitude_ft + groundOffset);
    else
-      altitude += 0.1 * ((tgt_altitude+groundOffset) - altitude);
+      altitude_ft += 0.1 * ((tgt_altitude_ft+groundOffset) - altitude_ft);
 }