when searching for the runway best matching a target heading, also consider
the runway length/width/surface material, so that fgfs doesn't drop one on the ridiculous grass stripe parallel to the grown up concrete runway (LOWL, LOXZ, ...). The weighting factors are for now made configurable, so that they are easier to adjust. This can later be made static. (will soon get forward ported to fg/osg)
This commit is contained in:
parent
5986ddc6d6
commit
d20db83c86
1 changed files with 68 additions and 53 deletions
|
@ -216,63 +216,78 @@ bool FGRunwayList::search( const string& aptid, const int tgt_hdg,
|
||||||
|
|
||||||
|
|
||||||
// Return the runway number of the runway closest to a given heading
|
// Return the runway number of the runway closest to a given heading
|
||||||
string FGRunwayList::search( const string& aptid, const int tgt_hdg ) {
|
#include <Main/fg_props.hxx> // FIXME remove
|
||||||
FGRunway r;
|
string FGRunwayList::search( const string& aptid, const int hdg ) {
|
||||||
FGRunway tmp_r;
|
//SG_LOG(SG_GENERAL, SG_DEBUG, "searching runway for " << aptid
|
||||||
string rn;
|
// << " with target heading " << hdg);
|
||||||
double found_dir = 0.0;
|
|
||||||
|
|
||||||
if ( !search( aptid, &tmp_r ) ) {
|
FGRunway r;
|
||||||
SG_LOG( SG_GENERAL, SG_ALERT,
|
if (!search(aptid, &r)) {
|
||||||
"Failed to find " << aptid << " in database." );
|
SG_LOG(SG_GENERAL, SG_ALERT, "Failed to find "
|
||||||
return "NN";
|
<< aptid << " in database.");
|
||||||
|
return "NN";
|
||||||
}
|
}
|
||||||
|
|
||||||
double diff;
|
double LENWGT = fgGetDouble("/tmp/runway-search/length", 0.01);
|
||||||
double min_diff = 360.0;
|
double WIDWGT = fgGetDouble("/tmp/runway-search/width", 0.01);
|
||||||
|
double SURFWGT = fgGetDouble("/tmp/runway-search/surface", 10);
|
||||||
while ( tmp_r._id == aptid ) {
|
double DEVWGT = fgGetDouble("/tmp/runway-search/deviation", 1);
|
||||||
// forward direction
|
|
||||||
diff = tgt_hdg - tmp_r._heading;
|
FGRunway best;
|
||||||
while ( diff < -180.0 ) { diff += 360.0; }
|
double max = 0.0;
|
||||||
while ( diff > 180.0 ) { diff -= 360.0; }
|
bool reversed = false;
|
||||||
diff = fabs(diff);
|
|
||||||
// SG_LOG( SG_GENERAL, SG_INFO,
|
while (r._id == aptid) {
|
||||||
// "Runway " << tmp_r._rwy_no << " heading = "
|
if (r._type != "runway")
|
||||||
// << tmp_r._heading << " diff = " << diff );
|
continue;
|
||||||
if ((diff < min_diff) && (tmp_r._type == "runway")) {
|
|
||||||
min_diff = diff;
|
int surface = 0;
|
||||||
r = tmp_r;
|
if (r._surface_code == 1 || r._surface_code == 2) // asphalt & concrete
|
||||||
found_dir = 0;
|
surface = 2;
|
||||||
}
|
else if (r._surface_code == 12 || r._surface_code == 5) // dry lakebed & gravel
|
||||||
|
surface = 1;
|
||||||
// reverse direction
|
|
||||||
diff = tgt_hdg - tmp_r._heading - 180.0;
|
double quality, bad, diff;
|
||||||
while ( diff < -180.0 ) { diff += 360.0; }
|
double good = LENWGT * r._length + WIDWGT * r._width + SURFWGT * surface;
|
||||||
while ( diff > 180.0 ) { diff -= 360.0; }
|
|
||||||
diff = fabs(diff);
|
// this side
|
||||||
// SG_LOG( SG_GENERAL, SG_INFO,
|
diff = hdg - r._heading;
|
||||||
// "Runway -" << tmp_r._rwy_no << " heading = " <<
|
while (diff < -180)
|
||||||
// tmp_r._heading + 180.0 <<
|
diff += 360;
|
||||||
// " diff = " << diff );
|
while (diff >= 180)
|
||||||
if ((diff < min_diff) && (tmp_r._type == "runway")) {
|
diff -= 360;
|
||||||
min_diff = diff;
|
bad = DEVWGT * fabs(diff) + 1e-20;
|
||||||
r = tmp_r;
|
|
||||||
found_dir = 180.0;
|
quality = good / bad;
|
||||||
}
|
//SG_LOG(SG_GENERAL, SG_DEBUG, " runway " << r._rwy_no << " -> " << quality);
|
||||||
|
if (quality > max) {
|
||||||
if (!next( &tmp_r ))
|
max = quality;
|
||||||
|
best = r;
|
||||||
|
reversed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// other side
|
||||||
|
diff = hdg - r._heading - 180;
|
||||||
|
while (diff < -180)
|
||||||
|
diff += 360;
|
||||||
|
while (diff >= 180)
|
||||||
|
diff -= 360;
|
||||||
|
bad = DEVWGT * fabs(diff) + 1e-20;
|
||||||
|
|
||||||
|
quality = good / bad;
|
||||||
|
//SG_LOG(SG_GENERAL, SG_DEBUG, " runway " << GetReverseRunwayNo(r._rwy_no)
|
||||||
|
// << " -> " << quality);
|
||||||
|
if (quality > max) {
|
||||||
|
max = quality;
|
||||||
|
best = r;
|
||||||
|
reversed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!next(&r))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SG_LOG( SG_GENERAL, SG_INFO, "closest runway = " << r._rwy_no
|
return reversed ? GetReverseRunwayNo(best._rwy_no) : best._rwy_no;
|
||||||
// << " + " << found_dir );
|
|
||||||
rn = r._rwy_no;
|
|
||||||
if ( found_dir == 180 ) {
|
|
||||||
rn = GetReverseRunwayNo(rn);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rn;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue