#ifdef _MSC_VER
# include <float.h>
# define finite _finite
+#elif defined(__sun) || defined(sgi)
+# include <ieeefp.h>
#endif
SG_USING_STD(string);
};
-FGAIAircraft::FGAIAircraft(FGAIManager* mgr, FGAISchedule *ref) {
+FGAIAircraft::FGAIAircraft(FGAISchedule *ref) :
+ FGAIBase(otAircraft) {
trafficRef = ref;
if (trafficRef)
groundOffset = trafficRef->getGroundOffset();
else
groundOffset = 0;
- manager = mgr;
- _type_str = "aircraft";
- _otype = otAircraft;
fp = 0;
dt_count = 0;
dt_elev_count = 0;
FGAIAircraft::~FGAIAircraft() {
+ delete fp;
}
+void FGAIAircraft::readFromScenario(SGPropertyNode* scFileNode) {
+ if (!scFileNode)
+ return;
+
+ FGAIBase::readFromScenario(scFileNode);
+
+ setPerformance(scFileNode->getStringValue("class", "jet_transport"));
+ setFlightPlan(scFileNode->getStringValue("flightplan"),
+ scFileNode->getBoolValue("repeat", false));
+}
bool FGAIAircraft::init() {
refuel_node = fgGetNode("systems/refuel/contact", true);
props->tie("controls/gear/gear-down",
SGRawValueMethods<FGAIAircraft,bool>(*this,
&FGAIAircraft::_getGearDown));
-#if 0
- props->getNode("controls/lighting/landing-lights", true)
- ->alias("controls/gear/gear-down");
-#endif
}
void FGAIAircraft::unbind() {
FGAIBase::unbind();
props->untie("controls/gear/gear-down");
-#if 0
- props->getNode("controls/lighting/landing-lights")->unalias();
-#endif
}
Transform();
}
+void FGAIAircraft::setPerformance(const std::string& acclass)
+{
+ if (acclass == "light") {
+ SetPerformance(&FGAIAircraft::settings[FGAIAircraft::LIGHT]);
+ } else if (acclass == "ww2_fighter") {
+ SetPerformance(&FGAIAircraft::settings[FGAIAircraft::WW2_FIGHTER]);
+ } else if (acclass == "jet_transport") {
+ SetPerformance(&FGAIAircraft::settings[FGAIAircraft::JET_TRANSPORT]);
+ } else if (acclass == "jet_fighter") {
+ SetPerformance(&FGAIAircraft::settings[FGAIAircraft::JET_FIGHTER]);
+ } else if (acclass == "tanker") {
+ SetPerformance(&FGAIAircraft::settings[FGAIAircraft::JET_TRANSPORT]);
+ SetTanker(true);
+ } else {
+ SetPerformance(&FGAIAircraft::settings[FGAIAircraft::JET_TRANSPORT]);
+ }
+}
+
void FGAIAircraft::SetPerformance(const PERF_STRUCT *ps) {
performance = ps;
Transform(); // make sure aip is initialized.
getGroundElev(dt); // make sure it's exectuted first time around, so force a large dt value
//getGroundElev(dt); // Need to do this twice.
- //cerr << trafficRef->getRegistration() << " Setting altitude to " << tgt_altitude << endl;
- setAltitude(tgt_altitude);
+ //cerr << trafficRef->getRegistration() << " Setting altitude to " << tgt_altitude;
+ doGroundAltitude();
+ //cerr << " Actual altitude " << altitude << endl;
+ // Transform();
+ pos.setelev(altitude * SG_FEET_TO_METER);
}
return;
}
if (no_roll)
{
getGroundElev(dt);
+ doGroundAltitude();
}
- // 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 (tgt_vs > performance->climb_rate)
- tgt_vs = performance->climb_rate;
- } else {
- tgt_vs = tgt_altitude - altitude_ft;
- if (tgt_vs < (-performance->descent_rate))
- tgt_vs = -performance->descent_rate;
+ 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 (tgt_vs > performance->climb_rate)
+ tgt_vs = performance->climb_rate;
+ } else {
+ tgt_vs = tgt_altitude - 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 min_vs = 100;
+ if (tgt_altitude < altitude) min_vs = -100.0;
+ if ((fabs(tgt_altitude - altitude) < 1500.0) &&
+ (fabs(max_vs) < fabs(tgt_vs))) tgt_vs = max_vs;
+ if (fabs(tgt_vs) < fabs(min_vs)) tgt_vs = min_vs;
+ }
}
- }
-
- if (alt_lock && !use_perf_vs) {
- double max_vs = 4*(tgt_altitude - altitude);
- double min_vs = 100;
- if (tgt_altitude < altitude) min_vs = -100.0;
- if ((fabs(tgt_altitude - altitude) < 1500.0) &&
- (fabs(max_vs) < fabs(tgt_vs))) tgt_vs = max_vs;
- if (fabs(tgt_vs) < fabs(min_vs)) tgt_vs = min_vs;
- }
-
// adjust vertical speed
double vs_diff = tgt_vs - vs;
if (fabs(vs_diff) > 10.0) {
else { return 1.0; }
}
+void FGAIAircraft::setFlightPlan(const std::string& flightplan, bool repeat)
+{
+ if (!flightplan.empty()){
+ FGAIFlightPlan* fp = new FGAIFlightPlan(flightplan);
+ fp->setRepeat(repeat);
+ SetFlightPlan(fp);
+ }
+}
+
void FGAIAircraft::SetFlightPlan(FGAIFlightPlan *f) {
+ delete fp;
fp = f;
}
use_perf_vs = false;
tgt_vs = (curr->crossat - prev->altitude)/
(fp->getDistanceToGo(pos.lat(), pos.lon(), curr)/
- 6076.0/prev->speed*60.0);
- tgt_altitude = curr->crossat;
+ 6076.0/prev->speed*60.0);
+ tgt_altitude = curr->crossat;
} else {
use_perf_vs = true;
tgt_altitude = prev->altitude;
getGroundElev(60.1); // make sure it's exectuted first time around, so force a large dt value
//getGroundElev(60.1); // Need to do this twice.
//cerr << trafficRef->getRegistration() << " Setting altitude to " << tgt_altitude << endl;
- setAltitude(tgt_altitude);
+ doGroundAltitude(); //(tgt_altitude);
}
prevSpeed = 0;
//cout << "First waypoint: " << prev->name << endl;
// Current waypoint's elevation according to Terrain Elevation
if (curr->finished) { //end of the flight plan
{
- setDie(true);
+ if (fp->getRepeat()) {
+ fp->restart();
+ } else {
+ setDie(true);
+ }
+
//cerr << "Done die end of fp" << endl;
}
return;
// << arr->getId() <<endl;
// }
if (prev->name == "park2")
- dep->releaseParking(fp->getGate());
-
+ {
+ dep->getDynamics()->releaseParking(fp->getGate());
+ }
+ // Some debug messages, specific to TESTING THE Logical networks.
//if ((arr->getId() == string("EHAM")) && (prev->name == "Center"))
// {
//
fp->setLeadDistance(speed, tgt_heading, curr, next);
}
//cerr << "5.1" << endl;
- 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)/6076.0/speed*60.0);
- //cerr << "5.1b" << endl;
- tgt_altitude = curr->crossat;
- } else {
- //cerr << "5.1c" << endl;
- use_perf_vs = true;
- //cerr << "5.1d" << endl;
+ if (!(prev->on_ground)) { // only update the tgt altitude from flightplan if not on the ground
tgt_altitude = prev->altitude;
- //cerr << "Setting target altitude : " <<tgt_altitude << endl;
+ 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)/6076.0/speed*60.0);
+ //cerr << "5.1b" << endl;
+ tgt_altitude = curr->crossat;
+ } else {
+ //cerr << "5.1c" << endl;
+ use_perf_vs = true;
+ //cerr << "5.1d" << endl;
+
+ //cerr << "Setting target altitude : " <<tgt_altitude << endl;
+ }
}
//cerr << "6" << endl;
tgt_speed = prev->speed;
void FGAIAircraft::getGroundElev(double dt) {
dt_elev_count += dt;
//return;
- if (dt_elev_count < (10.0 + (rand() % 100))) // Update minimally every 10 secs, but add some randomness to prevent them all IA objects doing this synced
- {
- return;
- }
- else
- {
- dt_elev_count = 0;
- }
+ if (dt_elev_count < (3.0) + (rand() % 10)) //Update minimally every three secs, but add some randomness to prevent all IA objects doing this in synchrony
+ {
+ return;
+ }
+ 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.
return;
}
-
- //globals->get_tile_mgr()->prep_ssg_nodes( acmodel_location,
- globals->get_tile_mgr()->prep_ssg_nodes( aip.getSGLocation(), visibility_meters );
- Point3D scenery_center = globals->get_scenery()->get_center();
-
- globals->get_tile_mgr()->update( aip.getSGLocation(),
- visibility_meters,
- (aip.getSGLocation())->get_absolute_view_pos( scenery_center ) );
- // save results of update in SGLocation for fdm...
-
- //if ( globals->get_scenery()->get_cur_elev() > -9990 ) {
- // acmodel_location->
- // set_cur_elev_m( globals->get_scenery()->get_cur_elev() );
- //}
-
- // The need for this here means that at least 2 consecutive passes are needed :-(
- aip.getSGLocation()->set_tile_center( globals->get_scenery()->get_next_center() );
- globals->get_tile_mgr()->prep_ssg_nodes( aip.getSGLocation(), visibility_meters );
- //Point3D scenery_center = globals->get_scenery()->get_center();
-
- globals->get_tile_mgr()->update( aip.getSGLocation(),
- visibility_meters,
- (aip.getSGLocation())->get_absolute_view_pos( scenery_center ) );
- // save results of update in SGLocation for fdm...
-
- //if ( globals->get_scenery()->get_cur_elev() > -9990 ) {
- // acmodel_location->
- // set_cur_elev_m( globals->get_scenery()->get_cur_elev() );
- //}
-
- // The need for this here means that at least 2 consecutive passes are needed :-(
- aip.getSGLocation()->set_tile_center( globals->get_scenery()->get_next_center() );
- //cerr << "Transform Elev is " << globals->get_scenery()->get_cur_elev() << '\n';
- tgt_altitude = (globals->get_scenery()->get_cur_elev() * SG_METER_TO_FEET) + groundOffset;
-}
-
-//globals->get_tile_mgr()->prep_ssg_nodes( _aip.getSGLocation(), visibility_meters );
-//Point3D scenery_center = globals->get_scenery()->get_center();
-//globals->get_tile_mgr()->update(_aip.getSGLocation(), visibility_meters, (_aip.getSGLocation())->get_absolute_view_pos( scenery_center ) );
-// save results of update in SGLocation for fdm...
-
-//if ( globals->get_scenery()->get_cur_elev() > -9990 ) {
-// acmodel_location->
-// set_cur_elev_m( globals->get_scenery()->get_cur_elev() );
-//}
+ // 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))
+ {
+ // Try to shedule tiles for that position.
+ globals->get_tile_mgr()->update( aip.getSGLocation(), range );
+ }
-// The need for this here means that at least 2 consecutive passes are needed :-(
-//_aip.getSGLocation()->set_tile_center( globals->get_scenery()->get_next_center() );
+ // 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;
+ //cerr << "Target altitude : " << tgt_altitude << 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;
+}
-//cout << "Transform Elev is " << globals->get_scenery()->get_cur_elev() << '\n';
-//_aip.getSGLocation()->set_cur_elev_m(globals->get_scenery()->get_cur_elev());
-//return(globals->get_scenery()->get_cur_elev());
-//}
+void FGAIAircraft::doGroundAltitude()
+{
+ if (fabs(altitude - (tgt_altitude+groundOffset)) > 1000.0)
+ altitude = (tgt_altitude + groundOffset);
+ else
+ altitude += 0.1 * ((tgt_altitude+groundOffset) - altitude);
+}