1
0
Fork 0

mk-viii: tweak some values (according to spec), improve bias calculation.

Should now give less unjustified "too low - terrain" messages.
This commit is contained in:
Christian Schmitt 2013-03-29 20:17:27 +01:00
parent 6bd8bbc25e
commit 7795fa6ffa
2 changed files with 70 additions and 92 deletions

View file

@ -4287,20 +4287,16 @@ MK_VIII::TCFHandler::update_runway ()
double half_length_m = _runway->lengthM() * 0.5; double half_length_m = _runway->lengthM() * 0.5;
runway.half_length = half_length_m * SG_METER_TO_NM; runway.half_length = half_length_m * SG_METER_TO_NM;
// ________________ // _________
// | | // |
// h1>>> | e1<<<<<<<<e0 | <<<h0 // <<<<e0 | <<<h0
// |________________| // _________|
// get heading to runway threshold (h0) and end (h1) // get heading of runway end (h0)
runway.edges[0].heading = _runway->headingDeg(); runway.edge.heading = _runway->headingDeg();
runway.edges[1].heading = _runway->reciprocalRunway()->headingDeg();
// get position of runway threshold (e0) // get position of runway threshold (e0)
runway.edges[0].position = _runway->begin(); runway.edge.position = _runway->begin();
// get position of runway end (e1)
runway.edges[1].position = _runway->end();
// get cartesian coordinates of both runway ends // get cartesian coordinates of both runway ends
runway.bias_points[0] = _runway->cart(); runway.bias_points[0] = _runway->cart();
@ -4328,7 +4324,9 @@ bool
MK_VIII::TCFHandler::is_inside_bias_area () MK_VIII::TCFHandler::is_inside_bias_area ()
{ {
double half_bias_width_m = k * SG_NM_TO_METER + runway.half_width_m; double half_bias_width_m = k * SG_NM_TO_METER + runway.half_width_m;
SGVec3d cpos = SGVec3d::fromGeod( SGGeod::fromDeg(mk_data(gps_longitude).get(), mk_data(gps_latitude).get()) ); SGVec3d cpos = SGVec3d::fromGeod( SGGeod::fromDegFt(mk_data(gps_longitude).get(),
mk_data(gps_latitude).get(),
runway.elevation) );
SGLineSegmentd bias_line = SGLineSegmentd(runway.bias_points[0], runway.bias_points[1]); SGLineSegmentd bias_line = SGLineSegmentd(runway.bias_points[0], runway.bias_points[1]);
return dist(cpos, bias_line) < half_bias_width_m; return dist(cpos, bias_line) < half_bias_width_m;
} }
@ -4340,64 +4338,50 @@ MK_VIII::TCFHandler::is_tcf ()
{ {
if (has_runway) if (has_runway)
{ {
double distance = SGGeodesy::distanceNm( SGGeod::fromDeg(mk_data(gps_longitude).get(), double distance = SGGeodesy::distanceNm( SGGeod::fromDegFt(mk_data(gps_longitude).get(),
mk_data(gps_latitude).get()), mk_data(gps_latitude).get(),
runway.elevation),
runway.center); runway.center);
// distance to the inner envelope edge // distance to the inner envelope edge
double edge_distance = distance - runway.half_length - k; double edge_distance = distance - runway.half_length - k;
if (edge_distance >= 15) if (edge_distance > 15)
{ {
if (mk_data(radio_altitude).get() < 700) if (mk_data(radio_altitude).get() < 700)
return true; return true;
} }
else if (edge_distance >= 12) else if (edge_distance > 12)
{ {
if (mk_data(radio_altitude).get() < 100 * edge_distance - 800) if (mk_data(radio_altitude).get() < 100 * edge_distance - 800)
return true; return true;
} }
else if (edge_distance >= 4) else if (edge_distance > 4)
{ {
if (mk_data(radio_altitude).get() < 400) if (mk_data(radio_altitude).get() < 400)
return true; return true;
} }
else if (edge_distance >= 2.45) else if (edge_distance > 2.45)
{ {
if (mk_data(radio_altitude).get() < 66.666667 * edge_distance + 133.33333) if (mk_data(radio_altitude).get() < 100 * edge_distance)
return true; return true;
} }
else else if ( is_inside_edge_triangle(&runway.edge) && (edge_distance > 0.01) )
{ {
if (is_inside_edge_triangle(&runway.edges[0]) || is_inside_edge_triangle(&runway.edges[1])) if (mk_data(radio_altitude).get() < 100 * edge_distance)
{
if (edge_distance >= 1)
{
if (mk_data(radio_altitude).get() < 66.666667 * edge_distance + 133.33333)
return true; return true;
} }
else if (edge_distance >= 0.05) else if (! is_inside_bias_area())
{
if (mk_data(radio_altitude).get() < 200 * edge_distance)
return true;
}
}
else
{
if (! is_inside_bias_area())
{ {
if (mk_data(radio_altitude).get() < 245) if (mk_data(radio_altitude).get() < 245)
return true; return true;
} }
} }
} else if (mk_data(radio_altitude).get() < 700)
}
else
{ {
if (mk_data(radio_altitude).get() < 700)
return true; return true;
} }
} }
return false; return false;
} }
@ -4406,30 +4390,24 @@ MK_VIII::TCFHandler::is_rfcf ()
{ {
if (has_runway) if (has_runway)
{ {
double distance = SGGeodesy::distanceNm( SGGeod::fromDegFt(mk_data(gps_longitude).get(),
double distance = SGGeodesy::distanceNm( SGGeod::fromDeg(mk_data(gps_longitude).get(), mk_data(gps_latitude).get(),
mk_data(gps_latitude).get()), runway.elevation),
runway.center); runway.center);
distance -= runway.half_length;
double krf = k + mk_data(gps_vertical_figure_of_merit).get() / 200; if (distance < 5.0)
distance = distance - runway.half_length - krf;
if (distance <= 5)
{ {
double krf = k + mk_data(gps_vertical_figure_of_merit).get() / 200;
distance -= krf;
double altitude_above_field = mk_data(geometric_altitude).get() - runway.elevation; double altitude_above_field = mk_data(geometric_altitude).get() - runway.elevation;
if (distance >= 1.5) if ( (distance > 1.5) && (altitude_above_field < 300.0) )
{
if (altitude_above_field < 300)
return true; return true;
} else if ( (distance > 0.0) && (altitude_above_field < 200 * distance) )
else if (distance >= 0)
{
if (altitude_above_field < 200 * distance)
return true; return true;
} }
} }
}
return false; return false;
} }

View file

@ -1287,7 +1287,7 @@ private:
double elevation; // elevation in feet double elevation; // elevation in feet
double half_length; // runway half length, in nautical miles double half_length; // runway half length, in nautical miles
double half_width_m; // runway half width, in meters double half_width_m; // runway half width, in meters
RunwayEdge edges[2]; // runway threshold and end RunwayEdge edge; // runway threshold
SGVec3d bias_points[2]; // vertices of the bias area SGVec3d bias_points[2]; // vertices of the bias area
} runway; } runway;