Torsten Dreyer:
Here is a little patch that changes the behaviour of the VOR CDI and OFF-flag for indicators like the HSI when getting outside the range of the VOR station. Currently, when flying at a distance between the effective_range and twice the effective_range of a VOR station, the in-range property is computed based on a random value, causing the OFF Flag and the CDI bar to perform an ugly jitter. The attached patch introduces a new property signal-quality-norm which is computed based on the distance to the station and the range. It is 1.0 when the distance is less than the range and decreases by 1/x^2 for distances greater than the range leading to a signal-quality-norm of 0.25 for distances two times the range, 0.125 for three times the range and so on. The in-range flag is tied to a signal-quality-norm greater than 0.2 (fixed squelch). The CDI and GS needle deflection is multiplied with the signal-quality-norm. The benefit is: - Ability to animate the OFF-Flag with a smooth transition. - CDI and GS needle deflection shows correct values when in range (signal-quality-norm=1.0) and show some wrong indication when the range is exceeded - CDI and GS needle start to move, even when the OFF flag is visible - No more jitter for flag and needles See the new SenecaII ki525a hsi as an example at http://www.t3r.de/fg/navpatch.jpg The numbers on the image are: (1) the new property signal-quality-norm (2) distance exceeds the effective-range by 30% (3) NAV flag has a rotation animation bound to signal-quality-norm and is partially visible (4) CDI is partially deflected even with NAV flag shown This implementation better matches reality - at least, how I observed it ;-)
This commit is contained in:
parent
d92d39f576
commit
b423d0bc1d
2 changed files with 31 additions and 9 deletions
|
@ -35,6 +35,7 @@
|
|||
#include <simgear/structure/exception.hxx>
|
||||
|
||||
#include <Navaids/navlist.hxx>
|
||||
#include <Main/util.hxx>
|
||||
#include "navradio.hxx"
|
||||
|
||||
using std::string;
|
||||
|
@ -68,6 +69,7 @@ FGNavRadio::FGNavRadio(SGPropertyNode *node) :
|
|||
to_flag_node(NULL),
|
||||
from_flag_node(NULL),
|
||||
inrange_node(NULL),
|
||||
signal_quality_norm_node(NULL),
|
||||
cdi_deflection_node(NULL),
|
||||
cdi_xtrack_error_node(NULL),
|
||||
cdi_xtrack_hdg_err_node(NULL),
|
||||
|
@ -176,6 +178,7 @@ FGNavRadio::init ()
|
|||
to_flag_node = node->getChild("to-flag", 0, true);
|
||||
from_flag_node = node->getChild("from-flag", 0, true);
|
||||
inrange_node = node->getChild("in-range", 0, true);
|
||||
signal_quality_norm_node = node->getChild("signal-quality-norm", 0, true);
|
||||
cdi_deflection_node = node->getChild("heading-needle-deflection", 0, true);
|
||||
cdi_xtrack_error_node = node->getChild("crosstrack-error-m", 0, true);
|
||||
cdi_xtrack_hdg_err_node
|
||||
|
@ -314,6 +317,8 @@ FGNavRadio::update(double dt)
|
|||
bool has_gs = has_gs_node->getBoolValue();
|
||||
bool is_loc = loc_node->getBoolValue();
|
||||
double loc_dist = loc_dist_node->getDoubleValue();
|
||||
double effective_range_m;
|
||||
double signal_quality_norm = signal_quality_norm_node->getDoubleValue();
|
||||
|
||||
double az1, az2, s;
|
||||
|
||||
|
@ -418,18 +423,32 @@ FGNavRadio::update(double dt)
|
|||
effective_range
|
||||
= adjustNavRange( nav_elev, pos.getElevationM(), range );
|
||||
}
|
||||
|
||||
effective_range_m = effective_range * SG_NM_TO_METER;
|
||||
|
||||
// cout << "nav range = " << effective_range
|
||||
// << " (" << range << ")" << endl;
|
||||
|
||||
if ( loc_dist < effective_range * SG_NM_TO_METER ) {
|
||||
inrange = true;
|
||||
} else if ( loc_dist < 2 * effective_range * SG_NM_TO_METER ) {
|
||||
inrange = sg_random() < ( 2 * effective_range * SG_NM_TO_METER
|
||||
- loc_dist )
|
||||
/ (effective_range * SG_NM_TO_METER);
|
||||
} else {
|
||||
inrange = false;
|
||||
}
|
||||
//////////////////////////////////////////////////////////
|
||||
// compute signal quality
|
||||
// 100% within effective_range
|
||||
// decreases 1/x^2 further out
|
||||
//////////////////////////////////////////////////////////
|
||||
{
|
||||
double last_signal_quality_norm = signal_quality_norm;
|
||||
|
||||
if ( loc_dist < effective_range_m ) {
|
||||
signal_quality_norm = 1.0;
|
||||
} else {
|
||||
double range_exceed_norm = loc_dist/effective_range_m;
|
||||
signal_quality_norm = 1/(range_exceed_norm*range_exceed_norm);
|
||||
}
|
||||
|
||||
signal_quality_norm = fgGetLowPass( last_signal_quality_norm,
|
||||
signal_quality_norm, dt );
|
||||
}
|
||||
signal_quality_norm_node->setDoubleValue( signal_quality_norm );
|
||||
inrange = signal_quality_norm > 0.2;
|
||||
inrange_node->setBoolValue( inrange );
|
||||
|
||||
if ( !is_loc ) {
|
||||
|
@ -507,6 +526,7 @@ FGNavRadio::update(double dt)
|
|||
r *= 4.0;
|
||||
}
|
||||
SG_CLAMP_RANGE( r, -10.0, 10.0 );
|
||||
r *= signal_quality_norm;
|
||||
}
|
||||
}
|
||||
cdi_deflection_node->setDoubleValue( r );
|
||||
|
@ -591,6 +611,7 @@ FGNavRadio::update(double dt)
|
|||
// cout << "dist = " << x << " height = " << y << endl;
|
||||
double angle = asin( y / x ) * SGD_RADIANS_TO_DEGREES;
|
||||
r = (target_gs - angle) * 5.0;
|
||||
r *= signal_quality_norm;
|
||||
}
|
||||
}
|
||||
gs_deflection_node->setDoubleValue( r );
|
||||
|
|
|
@ -85,6 +85,7 @@ class FGNavRadio : public SGSubsystem
|
|||
SGPropertyNode_ptr to_flag_node;
|
||||
SGPropertyNode_ptr from_flag_node;
|
||||
SGPropertyNode_ptr inrange_node;
|
||||
SGPropertyNode_ptr signal_quality_norm_node;
|
||||
SGPropertyNode_ptr cdi_deflection_node;
|
||||
SGPropertyNode_ptr cdi_xtrack_error_node;
|
||||
SGPropertyNode_ptr cdi_xtrack_hdg_err_node;
|
||||
|
|
Loading…
Add table
Reference in a new issue