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;
} }
@ -4337,67 +4335,53 @@ bool
MK_VIII::TCFHandler::is_tcf () MK_VIII::TCFHandler::is_tcf ()
{ {
if (mk_data(radio_altitude).get() > 10) if (mk_data(radio_altitude).get() > 10)
{
if (has_runway)
{ {
if (has_runway) double distance = SGGeodesy::distanceNm( SGGeod::fromDegFt(mk_data(gps_longitude).get(),
{ mk_data(gps_latitude).get(),
double distance = SGGeodesy::distanceNm( SGGeod::fromDeg(mk_data(gps_longitude).get(), runway.elevation),
mk_data(gps_latitude).get()), runway.center);
runway.center);
// distance to the inner envelope edge
double edge_distance = distance - runway.half_length - k;
if (edge_distance >= 15) // distance to the inner envelope edge
{ double edge_distance = distance - runway.half_length - k;
if (mk_data(radio_altitude).get() < 700)
return true; if (edge_distance > 15)
} {
else if (edge_distance >= 12) if (mk_data(radio_altitude).get() < 700)
{ return true;
if (mk_data(radio_altitude).get() < 100 * edge_distance - 800) }
return true; else if (edge_distance > 12)
} {
else if (edge_distance >= 4) if (mk_data(radio_altitude).get() < 100 * edge_distance - 800)
{ return true;
if (mk_data(radio_altitude).get() < 400) }
return true; else if (edge_distance > 4)
} {
else if (edge_distance >= 2.45) if (mk_data(radio_altitude).get() < 400)
{ return true;
if (mk_data(radio_altitude).get() < 66.666667 * edge_distance + 133.33333) }
return true; else if (edge_distance > 2.45)
} {
else if (mk_data(radio_altitude).get() < 100 * edge_distance)
{ return true;
if (is_inside_edge_triangle(&runway.edges[0]) || is_inside_edge_triangle(&runway.edges[1])) }
{ else if ( is_inside_edge_triangle(&runway.edge) && (edge_distance > 0.01) )
if (edge_distance >= 1) {
{ if (mk_data(radio_altitude).get() < 100 * edge_distance)
if (mk_data(radio_altitude).get() < 66.666667 * edge_distance + 133.33333) return true;
return true; }
} else if (! is_inside_bias_area())
else if (edge_distance >= 0.05) {
{ if (mk_data(radio_altitude).get() < 245)
if (mk_data(radio_altitude).get() < 200 * edge_distance) return true;
return true; }
}
}
else
{
if (! is_inside_bias_area())
{
if (mk_data(radio_altitude).get() < 245)
return true;
}
}
}
}
else
{
if (mk_data(radio_altitude).get() < 700)
return true;
}
} }
else if (mk_data(radio_altitude).get() < 700)
{
return true;
}
}
return false; return false;
} }
@ -4405,31 +4389,25 @@ bool
MK_VIII::TCFHandler::is_rfcf () MK_VIII::TCFHandler::is_rfcf ()
{ {
if (has_runway) if (has_runway)
{
double distance = SGGeodesy::distanceNm( SGGeod::fromDegFt(mk_data(gps_longitude).get(),
mk_data(gps_latitude).get(),
runway.elevation),
runway.center);
distance -= runway.half_length;
if (distance < 5.0)
{ {
double distance = SGGeodesy::distanceNm( SGGeod::fromDeg(mk_data(gps_longitude).get(),
mk_data(gps_latitude).get()),
runway.center);
double krf = k + mk_data(gps_vertical_figure_of_merit).get() / 200; double krf = k + mk_data(gps_vertical_figure_of_merit).get() / 200;
distance = distance - runway.half_length - krf; distance -= krf;
double altitude_above_field = mk_data(geometric_altitude).get() - runway.elevation;
if (distance <= 5) if ( (distance > 1.5) && (altitude_above_field < 300.0) )
{ return true;
double altitude_above_field = mk_data(geometric_altitude).get() - runway.elevation; else if ( (distance > 0.0) && (altitude_above_field < 200 * distance) )
return true;
if (distance >= 1.5)
{
if (altitude_above_field < 300)
return true;
}
else if (distance >= 0)
{
if (altitude_above_field < 200 * distance)
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;