Change the start of descent point of the AI plane when the circuit has been extended when following previous traffic - it should not land short now, although it can land a way down the runway if start of descent should occur during a turn, since it doesnt start descending until the turn is finished
This commit is contained in:
parent
be274df23b
commit
b898c5e4ff
2 changed files with 103 additions and 17 deletions
|
@ -82,6 +82,9 @@ FGAILocalTraffic::FGAILocalTraffic() {
|
|||
reportReadyForDeparture = false;
|
||||
contactTower = false;
|
||||
contactGround = false;
|
||||
|
||||
descending = false;
|
||||
targetDescentRate = 0.0;
|
||||
}
|
||||
|
||||
FGAILocalTraffic::~FGAILocalTraffic() {
|
||||
|
@ -540,6 +543,11 @@ void FGAILocalTraffic::Update(double dt) {
|
|||
break;
|
||||
}
|
||||
//cout << "I " << flush;
|
||||
|
||||
// Convienience output for AI debugging user the property logger
|
||||
fgSetDouble("/AI/Local1/ortho-x", (ortho.ConvertToLocal(pos)).x());
|
||||
fgSetDouble("/AI/Local1/ortho-y", (ortho.ConvertToLocal(pos)).y());
|
||||
fgSetDouble("/AI/Local1/elev", pos.elev() * SG_METER_TO_FEET);
|
||||
}
|
||||
|
||||
void FGAILocalTraffic::RegisterTransmission(int code) {
|
||||
|
@ -619,7 +627,8 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) {
|
|||
leg = CLIMBOUT;
|
||||
pitch = 10.0;
|
||||
IAS = best_rate_of_climb_speed;
|
||||
slope = 7.0;
|
||||
//slope = 7.0;
|
||||
slope = 6.0; // Reduced it slightly since it's climbing a lot steeper than I can in the JSBSim C172.
|
||||
inAir = true;
|
||||
}
|
||||
break;
|
||||
|
@ -704,15 +713,32 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) {
|
|||
TransmitPatternPositionReport();
|
||||
transmitted = true;
|
||||
}
|
||||
if(orthopos.y() < -480) {
|
||||
// FIXME - TODO - take tower baseleg constraint ie. other traffic, into account when calculating start of descent
|
||||
slope = -4.0; // FIXME - calculate to descent at 500fpm and hit the threshold (taking wind into account as well!!)
|
||||
if((orthopos.y() < -100) && (!descending)) {
|
||||
// Maybe we should think about when to start descending.
|
||||
// For now we're assuming that we aim to follow the same glidepath regardless of wind.
|
||||
double d1;
|
||||
double d2;
|
||||
CalculateSoD((tower->GetBaseConstraint(d1) ? d1 : -1000.0), (tower->GetDownwindConstraint(d2) ? d2 : 1000.0 * patternDirection), (patternDirection ? true : false));
|
||||
if(SoD.leg == DOWNWIND) {
|
||||
descending = (orthopos.y() < SoD.y ? true : false);
|
||||
}
|
||||
|
||||
}
|
||||
if(descending) {
|
||||
slope = -5.5; // FIXME - calculate to descent at 500fpm and hit the desired point on the runway (taking wind into account as well!!)
|
||||
pitch = -3.0;
|
||||
IAS = 85.0;
|
||||
}
|
||||
if(orthopos.y() < -980) {
|
||||
|
||||
// Try and arrange to turn nicely onto base
|
||||
turn_circumference = IAS * 0.514444 * turn_time;
|
||||
//Hmmm - this is an interesting one - ground vs airspeed in relation to turn radius
|
||||
//We'll leave it as a hack with IAS for now but it needs revisiting.
|
||||
turn_radius = turn_circumference / (2.0 * DCL_PI);
|
||||
if(orthopos.y() < -1000.0 + turn_radius) {
|
||||
//if(orthopos.y() < -980) {
|
||||
double bb = 0.0;
|
||||
if(tower->GetDownwindConstraint(bb)) {
|
||||
if(tower->GetBaseConstraint(bb)) {
|
||||
if(fabs(orthopos.y()) > fabs(bb)) {
|
||||
cout << "Turning to base, distance from threshold = " << fabs(orthopos.y()) << '\n';
|
||||
leg = TURN3;
|
||||
|
@ -740,15 +766,29 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) {
|
|||
TransmitPatternPositionReport();
|
||||
transmitted = true;
|
||||
}
|
||||
|
||||
if(!descending) {
|
||||
double d1;
|
||||
// Make downwind leg position artifically large to avoid any chance of SoD being returned as
|
||||
// on downwind when we are already on base.
|
||||
CalculateSoD((tower->GetBaseConstraint(d1) ? d1 : -1000.0), (10000.0 * patternDirection), (patternDirection ? true : false));
|
||||
if(SoD.leg == BASE) {
|
||||
descending = (fabs(orthopos.y()) < fabs(SoD.y) ? true : false);
|
||||
}
|
||||
|
||||
}
|
||||
if(descending) {
|
||||
slope = -5.5; // FIXME - calculate to descent at 500fpm and hit the threshold (taking wind into account as well!!)
|
||||
pitch = -4.0;
|
||||
IAS = 70.0;
|
||||
}
|
||||
|
||||
track = rwy.hdg - (90 * patternDirection);
|
||||
slope = -6.0; // FIXME - calculate to descent at 500fpm and hit the threshold
|
||||
pitch = -4.0;
|
||||
IAS = 70.0; // FIXME - slowdown gradually
|
||||
// Try and arrange to turn nicely onto base
|
||||
|
||||
// Try and arrange to turn nicely onto final
|
||||
turn_circumference = IAS * 0.514444 * turn_time;
|
||||
//Hmmm - this is an interesting one - ground vs airspeed in relation to turn radius
|
||||
//We'll leave it as a hack with IAS for now but it needs revisiting.
|
||||
|
||||
//We'll leave it as a hack with IAS for now but it needs revisiting.
|
||||
turn_radius = turn_circumference / (2.0 * DCL_PI);
|
||||
if(fabs(orthopos.x()) < (turn_radius + 50)) {
|
||||
leg = TURN4;
|
||||
|
@ -770,6 +810,20 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) {
|
|||
TransmitPatternPositionReport();
|
||||
transmitted = true;
|
||||
}
|
||||
if(!descending) {
|
||||
// Make base leg position artifically large to avoid any chance of SoD being returned as
|
||||
// on base or downwind when we are already on final.
|
||||
CalculateSoD(-10000.0, (1000.0 * patternDirection), (patternDirection ? true : false));
|
||||
if(SoD.leg == FINAL) {
|
||||
descending = (fabs(orthopos.y()) < fabs(SoD.y) ? true : false);
|
||||
}
|
||||
|
||||
}
|
||||
if(descending) {
|
||||
slope = -5.5; // FIXME - calculate to descent at 500fpm and hit the threshold (taking wind into account as well!!)
|
||||
pitch = -4.0;
|
||||
IAS = 70.0;
|
||||
}
|
||||
// Try and track the extended centreline
|
||||
track = rwy.hdg - (0.2 * orthopos.x());
|
||||
//cout << "orthopos.x() = " << orthopos.x() << " hdg = " << hdg << '\n';
|
||||
|
@ -861,6 +915,36 @@ void FGAILocalTraffic::FlyTrafficPattern(double dt) {
|
|||
pos = dclUpdatePosition(pos, track, slope, dist);
|
||||
}
|
||||
|
||||
// Pattern direction is true for right, false for left
|
||||
void FGAILocalTraffic::CalculateSoD(double base_leg_pos, double downwind_leg_pos, bool pattern_direction) {
|
||||
// For now we'll ignore wind and hardwire the glide angle.
|
||||
double ga = 5.5; //degrees
|
||||
double pa = 1000.0 * SG_FEET_TO_METER; // pattern altitude in meters
|
||||
// FIXME - get glideslope angle and pattern altitude agl from airport details if available
|
||||
|
||||
// For convienience, we'll have +ve versions of the input distances
|
||||
double blp = fabs(base_leg_pos);
|
||||
double dlp = fabs(downwind_leg_pos);
|
||||
|
||||
//double turn_allowance = 150.0; // Approximate distance in meters that a 90deg corner is shortened by turned in a light plane.
|
||||
|
||||
double stod = pa / tan(ga * DCL_DEGREES_TO_RADIANS); // distance in meters from touchdown point to start descent
|
||||
cout << "Descent to start = " << stod << " meters out\n";
|
||||
if(stod < blp) { // Start descending on final
|
||||
SoD.leg = FINAL;
|
||||
SoD.y = stod * -1.0;
|
||||
SoD.x = 0.0;
|
||||
} else if(stod < (blp + dlp)) { // Start descending on base leg
|
||||
SoD.leg = BASE;
|
||||
SoD.y = blp * -1.0;
|
||||
SoD.x = (pattern_direction ? (stod - dlp) : (stod - dlp) * -1.0);
|
||||
} else { // Start descending on downwind leg
|
||||
SoD.leg = DOWNWIND;
|
||||
SoD.x = (pattern_direction ? dlp : dlp * -1.0);
|
||||
SoD.y = (blp - (stod - (blp + dlp))) * -1.0;
|
||||
}
|
||||
}
|
||||
|
||||
void FGAILocalTraffic::TransmitPatternPositionReport(void) {
|
||||
// airport name + "traffic" + airplane callsign + pattern direction + pattern leg + rwy + ?
|
||||
string trns = "";
|
||||
|
|
|
@ -48,10 +48,10 @@ enum OperatingState {
|
|||
PARKED
|
||||
};
|
||||
|
||||
struct StartofDescent {
|
||||
struct StartOfDescent {
|
||||
PatternLeg leg;
|
||||
double orthopos_x;
|
||||
double orthopos_y;
|
||||
double x; // Runway aligned orthopos
|
||||
double y; // ditto
|
||||
};
|
||||
|
||||
class FGAILocalTraffic : public FGAIPlane {
|
||||
|
@ -143,7 +143,9 @@ private:
|
|||
int numAhead; // More importantly - how many of them are ahead of us?
|
||||
double distToNext; // And even more importantly, how near are we getting to the one immediately ahead?
|
||||
//PatternLeg leg; // Our current position in the pattern - now moved to FGAIPlane
|
||||
StartofDescent SoD; // Start of descent calculated wrt wind, pattern size & altitude, glideslope etc
|
||||
StartOfDescent SoD; // Start of descent calculated wrt wind, pattern size & altitude, glideslope etc
|
||||
bool descending; // We're in the coming down phase of the pattern
|
||||
double targetDescentRate; // m/s
|
||||
|
||||
// Taxiing details
|
||||
// At the moment this assumes that all taxiing in is to gates (a loose term that includes
|
||||
|
@ -179,7 +181,7 @@ private:
|
|||
|
||||
void TransmitPatternPositionReport();
|
||||
|
||||
void CalculateStartofDescent();
|
||||
void CalculateSoD(double base_leg_pos, double downwind_leg_pos, bool pattern_direction);
|
||||
|
||||
void ExitRunway(Point3D orthopos);
|
||||
|
||||
|
|
Loading…
Reference in a new issue