// 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}
};
} 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]);
}
void FGAIAircraft::Run(double dt) {
FGAIAircraft::dt = dt;
-
+
if (fp) {
time_t now = time(NULL) + fgGetLong("/sim/time/warp");
ProcessFlightPlan(dt, now);
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;
} 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;
}
// 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) {
} 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;
if ( isTanker) {
if ( (range_ft2 < 250.0 * 250.0) && (y_shift > 0.0)
&& (elevation > 0.0) ) {
- refuel_node->setBoolValue(true);
+ //refuel_node->setBoolValue(true);
contact = true;
} else {
//refuel_node->setBoolValue(false);
}
-void FGAIAircraft::ClimbTo(double altitude) {
- tgt_altitude = altitude;
+void FGAIAircraft::ClimbTo(double alt_ft ) {
+ tgt_altitude_ft = alt_ft;
alt_lock = true;
}
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;
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();
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) {
//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;
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;
} 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
// //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;
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");
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) {
// 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))
- 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;
}
}
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);
}