Instrument panel / steam updates for more realistic modeling of various
instruments (contributed by Alex Perry)
This commit is contained in:
parent
a975fd77c5
commit
4f6ed28a17
8 changed files with 152 additions and 69 deletions
|
@ -108,6 +108,7 @@ void HudLadder :: draw( void )
|
|||
|
||||
glPushMatrix();
|
||||
glTranslatef( centroid.x, centroid.y, 0);
|
||||
glScalef( current_options.get_fov()/55.0, 1.0, 1.0 );
|
||||
glRotatef(roll_value * RAD_TO_DEG, 0.0, 0.0, 1.0);
|
||||
|
||||
// Draw the target spot.
|
||||
|
|
|
@ -183,8 +183,8 @@ createTurnCoordinator (int x, int y)
|
|||
// moves with roll
|
||||
inst->addLayer(createTexture("Textures/Panel/turn.rgb"));
|
||||
inst->addTransformation(FGInstrumentLayer::ROTATION,
|
||||
FGSteam::get_TC_radps,
|
||||
-30.0, 30.0, 1.0, 0.0);
|
||||
FGSteam::get_TC_std,
|
||||
-2.5, 2.5, 20.0, 0.0);
|
||||
|
||||
// Layer 2: little ball
|
||||
// moves with slip/skid
|
||||
|
@ -227,18 +227,18 @@ createGyroCompass (int x, int y)
|
|||
// rotates with heading
|
||||
inst->addLayer(createTexture("Textures/Panel/gyro-bg.rgb"));
|
||||
inst->addTransformation(FGInstrumentLayer::ROTATION,
|
||||
FGBFI::getHeading,
|
||||
-360.0, 360.0, -1.0, 0.0);
|
||||
FGSteam::get_MH_deg,
|
||||
-720.0, 720.0, -1.0, 0.0);
|
||||
|
||||
// Layer 1: heading bug
|
||||
// rotates with heading and AP heading
|
||||
inst->addLayer(createTexture("Textures/Panel/bug.rgb"));
|
||||
inst->addTransformation(FGInstrumentLayer::ROTATION,
|
||||
FGBFI::getHeading,
|
||||
-360.0, 360.0, -1.0, 0.0);
|
||||
FGSteam::get_MH_deg,
|
||||
-720.0, 720.0, -1.0, 0.0);
|
||||
inst->addTransformation(FGInstrumentLayer::ROTATION,
|
||||
FGBFI::getAPHeading,
|
||||
-360.0, 360.0, 1.0, 0.0);
|
||||
-720.0, 720.0, 1.0, 0.0);
|
||||
|
||||
// Layer 2: fixed center
|
||||
inst->addLayer(createTexture("Textures/Panel/gyro-fg.rgb"));
|
||||
|
|
|
@ -31,8 +31,10 @@
|
|||
|
||||
#include <simgear/constants.h>
|
||||
#include <simgear/math/fg_types.hxx>
|
||||
#include <Aircraft/aircraft.hxx>
|
||||
#include <Main/options.hxx>
|
||||
#include <Main/bfi.hxx>
|
||||
#include <NetworkOLK/features.hxx>
|
||||
|
||||
FG_USING_NAMESPACE(std);
|
||||
|
||||
|
@ -48,9 +50,6 @@ FG_USING_NAMESPACE(std);
|
|||
// Anything that reads the BFI directly is not implemented at all!
|
||||
|
||||
|
||||
#define VARY_E (14)
|
||||
|
||||
|
||||
double FGSteam::the_STATIC_inhg = 29.92;
|
||||
double FGSteam::the_ALT_ft = 0.0;
|
||||
double FGSteam::get_ALT_ft() { _CatchUp(); return the_ALT_ft; }
|
||||
|
@ -64,15 +63,20 @@ double FGSteam::get_VSI_fps() { _CatchUp(); return the_VSI_fps; }
|
|||
double FGSteam::the_VACUUM_inhg = 0.0;
|
||||
double FGSteam::get_VACUUM_inhg() { _CatchUp(); return the_VACUUM_inhg; }
|
||||
|
||||
double FGSteam::get_MH_deg () {
|
||||
return FGBFI::getHeading () - FGBFI::getMagVar ();
|
||||
}
|
||||
double FGSteam::get_DG_deg () {
|
||||
return FGBFI::getHeading () - FGBFI::getMagVar ();
|
||||
}
|
||||
double FGSteam::the_MH_err = 0.0;
|
||||
double FGSteam::the_MH_deg = 0.0;
|
||||
double FGSteam::the_MH_degps = 0.0;
|
||||
double FGSteam::get_MH_deg () { _CatchUp(); return the_MH_deg; }
|
||||
|
||||
double FGSteam::get_TC_rad () { return FGBFI::getSideSlip (); }
|
||||
double FGSteam::get_TC_radps () { return FGBFI::getRoll (); }
|
||||
double FGSteam::the_DG_deg = 0.0;
|
||||
double FGSteam::the_DG_degps = 0.0;
|
||||
double FGSteam::the_DG_inhg = 0.0;
|
||||
double FGSteam::get_DG_deg () { _CatchUp(); return the_DG_deg; }
|
||||
|
||||
double FGSteam::the_TC_rad = 0.0;
|
||||
double FGSteam::the_TC_std = 0.0;
|
||||
double FGSteam::get_TC_rad () { _CatchUp(); return the_TC_rad; }
|
||||
double FGSteam::get_TC_std () { _CatchUp(); return the_TC_std; }
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
@ -126,14 +130,124 @@ void FGSteam::set_lowpass ( double *outthe, double inthe, double tc )
|
|||
void FGSteam::_CatchUp()
|
||||
{ if ( _UpdatesPending != 0 )
|
||||
{ double dt = _UpdatesPending * 1.0 / current_options.get_model_hz();
|
||||
double AccN, AccE, AccU;
|
||||
int i,j;
|
||||
double d, the_ENGINE_rpm;
|
||||
/*
|
||||
|
||||
#if 0
|
||||
/**************************
|
||||
There is the possibility that this is the first call.
|
||||
If this is the case, we will emit the feature registrations
|
||||
just to be on the safe side. Doing it more than once will
|
||||
waste CPU time but doesn't hurt anything really.
|
||||
*/
|
||||
if ( _UpdatesPending == 999 )
|
||||
{ FGFeature::register_int ( "Avionics/NAV1/Localizer", &NAV1_LOC );
|
||||
FGFeature::register_double ( "Avionics/NAV1/Latitude", &NAV1_Lat );
|
||||
FGFeature::register_double ( "Avionics/NAV1/Longitude", &NAV1_Lon );
|
||||
FGFeature::register_double ( "Avionics/NAV1/Radial", &NAV1_Rad );
|
||||
FGFeature::register_double ( "Avionics/NAV1/Altitude", &NAV1_Alt );
|
||||
FGFeature::register_int ( "Avionics/NAV2/Localizer", &NAV2_LOC );
|
||||
FGFeature::register_double ( "Avionics/NAV2/Latitude", &NAV2_Lat );
|
||||
FGFeature::register_double ( "Avionics/NAV2/Longitude", &NAV2_Lon );
|
||||
FGFeature::register_double ( "Avionics/NAV2/Radial", &NAV2_Rad );
|
||||
FGFeature::register_double ( "Avionics/NAV2/Altitude", &NAV2_Alt );
|
||||
FGFeature::register_double ( "Avionics/ADF/Latitude", &ADF_Lat );
|
||||
FGFeature::register_double ( "Avionics/ADF/Longitude", &ADF_Lon );
|
||||
}
|
||||
#endif
|
||||
|
||||
/**************************
|
||||
Someone has called our update function and
|
||||
it turns out that we are running somewhat behind.
|
||||
Here, we recalculate everything for a 'dt' second step.
|
||||
*/
|
||||
|
||||
/**************************
|
||||
The ball responds to the acceleration vector in the body
|
||||
frame, only the components perpendicular to the longitudinal
|
||||
axis of the aircraft. This is only related to actual
|
||||
side slip for a symmetrical aircraft which is not touching
|
||||
the ground and not changing its attitude. Math simplifies
|
||||
by assuming (for small angles) arctan(x)=x in radians.
|
||||
Obvious failure mode is the absence of liquid in the
|
||||
tube, which is there to damp the motion, so that instead
|
||||
the ball will bounce around, hitting the tube ends.
|
||||
More subtle flaw is having it not move or a travel limit
|
||||
occasionally due to some dirt in the tube or on the ball.
|
||||
*/
|
||||
// the_TC_rad = - ( FGBFI::getSideSlip () ); /* incorrect */
|
||||
d = - current_aircraft.fdm_state->get_A_Z_pilot();
|
||||
if ( d < 1 ) d = 1;
|
||||
set_lowpass ( & the_TC_rad,
|
||||
current_aircraft.fdm_state->get_A_Y_pilot () / d,
|
||||
dt );
|
||||
|
||||
/**************************
|
||||
The rate of turn indication is from an electric gyro.
|
||||
We should have it spin up with the master switch.
|
||||
It is mounted at a funny angle so that it detects
|
||||
both rate of bank (i.e. rolling into and out of turns)
|
||||
and the rate of turn (i.e. how fast heading is changing).
|
||||
*/
|
||||
set_lowpass ( & the_TC_std,
|
||||
current_aircraft.fdm_state->get_Phi_dot ()
|
||||
* RAD_TO_DEG / 20.0 +
|
||||
current_aircraft.fdm_state->get_Psi_dot ()
|
||||
* RAD_TO_DEG / 3.0 , dt );
|
||||
|
||||
/**************************
|
||||
We want to know the pilot accelerations,
|
||||
to compute the magnetic compass errors.
|
||||
*/
|
||||
AccN = current_aircraft.fdm_state->get_V_dot_north();
|
||||
AccE = current_aircraft.fdm_state->get_V_dot_east();
|
||||
AccU = current_aircraft.fdm_state->get_V_dot_down()
|
||||
- 9.81 / 0.3;
|
||||
if ( fabs(the_TC_rad) > 0.2 )
|
||||
{ /* Massive sideslip jams it; it stops turning */
|
||||
the_MH_degps = 0.0;
|
||||
the_MH_err = FGBFI::getHeading () - the_MH_deg;
|
||||
} else
|
||||
{ double MagDip, MagVar, CosDip;
|
||||
double FrcN, FrcE, FrcU, AccTot;
|
||||
double EdgN, EdgE, EdgU;
|
||||
double TrqN, TrqE, TrqU, Torque;
|
||||
/* Find a force vector towards exact magnetic north */
|
||||
MagVar = FGBFI::getMagVar() / RAD_TO_DEG;
|
||||
MagDip = FGBFI::getMagDip() / RAD_TO_DEG;
|
||||
CosDip = cos ( MagDip );
|
||||
FrcN = CosDip * cos ( MagVar );
|
||||
FrcE = CosDip * sin ( MagVar );
|
||||
FrcU = sin ( MagDip );
|
||||
/* Rotation occurs around acceleration axis,
|
||||
but axis magnitude is irrelevant. So compute it. */
|
||||
AccTot = AccN*AccN + AccE*AccE + AccU*AccU;
|
||||
if ( AccTot > 1.0 ) AccTot = sqrt ( AccTot );
|
||||
else AccTot = 1.0;
|
||||
/* Force applies to north marking on compass card */
|
||||
EdgN = cos ( the_MH_err / RAD_TO_DEG );
|
||||
EdgE = sin ( the_MH_err / RAD_TO_DEG );
|
||||
EdgU = 0.0;
|
||||
/* Apply the force to the edge to get torques */
|
||||
TrqN = EdgE * FrcU - EdgU * FrcE;
|
||||
TrqE = EdgU * FrcN - EdgN * FrcU;
|
||||
TrqU = EdgN * FrcE - EdgE * FrcN;
|
||||
/* Select the component parallel to the axis */
|
||||
Torque = ( TrqN * AccN +
|
||||
TrqE * AccE +
|
||||
TrqU * AccU ) * 5.0 / AccTot;
|
||||
/* The magnetic compass has angular momentum,
|
||||
so we apply a torque to it and wait */
|
||||
if ( dt < 1.0 )
|
||||
{ the_MH_degps= the_MH_degps * (1.0 - dt) - Torque;
|
||||
the_MH_err += dt * the_MH_degps;
|
||||
}
|
||||
if ( the_MH_err > 180.0 ) the_MH_err -= 360.0; else
|
||||
if ( the_MH_err < -180.0 ) the_MH_err += 360.0;
|
||||
the_MH_deg = FGBFI::getHeading () - the_MH_err;
|
||||
}
|
||||
|
||||
/**************************
|
||||
This is not actually correct, but provides a
|
||||
scaling capability for the vacuum pump later on.
|
||||
|
@ -201,6 +315,7 @@ void FGSteam::_CatchUp()
|
|||
> have it tumble when you exceed the usual pitch or bank limits,
|
||||
> put in those insidious turning errors ... for now anyway.
|
||||
*/
|
||||
the_DG_deg = FGBFI::getHeading () - FGBFI::getMagVar ();
|
||||
|
||||
/**************************
|
||||
Finished updates, now clear the timer
|
||||
|
@ -216,19 +331,6 @@ void FGSteam::_CatchUp()
|
|||
|
||||
|
||||
double FGSteam::get_HackGS_deg () {
|
||||
|
||||
#if 0
|
||||
double x,y,dme;
|
||||
if (0==NAV1_LOC) return 0.0;
|
||||
y = 60.0 * ( NAV1_Lat - FGBFI::getLatitude () );
|
||||
x = 60.0 * ( NAV1_Lon - FGBFI::getLongitude() )
|
||||
* cos ( FGBFI::getLatitude () / RAD_TO_DEG );
|
||||
dme = x*x + y*y;
|
||||
if ( dme > 0.1 ) x = sqrt ( dme ); else x = 0.3;
|
||||
y = FGBFI::getAltitude() - NAV1_Alt;
|
||||
return 3.0 - (y/x) * 60.0 / 6000.0;
|
||||
#endif
|
||||
|
||||
if ( current_radiostack->get_nav1_inrange() &&
|
||||
current_radiostack->get_nav1_loc() )
|
||||
{
|
||||
|
@ -246,14 +348,6 @@ double FGSteam::get_HackGS_deg () {
|
|||
double FGSteam::get_HackVOR1_deg () {
|
||||
double r;
|
||||
|
||||
#if 0
|
||||
double x,y;
|
||||
y = 60.0 * ( NAV1_Lat - FGBFI::getLatitude () );
|
||||
x = 60.0 * ( NAV1_Lon - FGBFI::getLongitude() )
|
||||
* cos ( FGBFI::getLatitude () / RAD_TO_DEG );
|
||||
r = atan2 ( x, y ) * RAD_TO_DEG - NAV1_Rad - FGBFI::getMagVar();
|
||||
#endif
|
||||
|
||||
if ( current_radiostack->get_nav1_inrange() ) {
|
||||
r = current_radiostack->get_nav1_radial() -
|
||||
current_radiostack->get_nav1_heading();
|
||||
|
@ -277,14 +371,6 @@ double FGSteam::get_HackVOR1_deg () {
|
|||
double FGSteam::get_HackVOR2_deg () {
|
||||
double r;
|
||||
|
||||
#if 0
|
||||
double x,y;
|
||||
y = 60.0 * ( NAV2_Lat - FGBFI::getLatitude () );
|
||||
x = 60.0 * ( NAV2_Lon - FGBFI::getLongitude() )
|
||||
* cos ( FGBFI::getLatitude () / RAD_TO_DEG );
|
||||
r = atan2 ( x, y ) * RAD_TO_DEG - NAV2_Rad - FGBFI::getMagVar();
|
||||
#endif
|
||||
|
||||
if ( current_radiostack->get_nav2_inrange() ) {
|
||||
r = current_radiostack->get_nav2_radial() -
|
||||
current_radiostack->get_nav2_heading() + 180.0;
|
||||
|
@ -316,14 +402,6 @@ double FGSteam::get_HackOBS2_deg () {
|
|||
double FGSteam::get_HackADF_deg () {
|
||||
double r;
|
||||
|
||||
#if 0
|
||||
double x,y;
|
||||
y = 60.0 * ( ADF_Lat - FGBFI::getLatitude () );
|
||||
x = 60.0 * ( ADF_Lon - FGBFI::getLongitude() )
|
||||
* cos ( FGBFI::getLatitude () / RAD_TO_DEG );
|
||||
r = atan2 ( x, y ) * RAD_TO_DEG - FGBFI::getHeading ();
|
||||
#endif
|
||||
|
||||
if ( current_radiostack->get_adf_inrange() ) {
|
||||
r = current_radiostack->get_adf_heading() - FGBFI::getHeading() + 180.0;
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ public:
|
|||
|
||||
// Velocities
|
||||
static double get_ASI_kias ();
|
||||
static double get_TC_radps ();
|
||||
static double get_TC_std ();
|
||||
static double get_VSI_fps ();
|
||||
|
||||
// Engine Gauges
|
||||
|
@ -81,8 +81,11 @@ public:
|
|||
|
||||
private:
|
||||
static double the_ALT_ft;
|
||||
static double the_TC_rad, the_TC_std;
|
||||
static double the_STATIC_inhg, the_VACUUM_inhg;
|
||||
static double the_VSI_fps, the_VSI_case;
|
||||
static double the_MH_deg, the_MH_degps, the_MH_err;
|
||||
static double the_DG_deg, the_DG_degps, the_DG_inhg;
|
||||
|
||||
static int _UpdatesPending;
|
||||
static void _CatchUp ();
|
||||
|
|
|
@ -327,7 +327,7 @@ int FGLaRCsim::copy_from_LaRCsim() {
|
|||
// set_Moments_Gear( M_l_gear, M_m_gear, M_n_gear );
|
||||
|
||||
// Accelerations
|
||||
// set_Accels_Local( V_dot_north, V_dot_east, V_dot_down );
|
||||
set_Accels_Local( V_dot_north, V_dot_east, V_dot_down );
|
||||
set_Accels_Body( U_dot_body, V_dot_body, W_dot_body );
|
||||
set_Accels_CG_Body( A_X_cg, A_Y_cg, A_Z_cg );
|
||||
set_Accels_Pilot_Body( A_X_pilot, A_Y_pilot, A_Z_pilot );
|
||||
|
|
|
@ -298,14 +298,14 @@ public:
|
|||
|
||||
FG_VECTOR_3 v_dot_local_v;
|
||||
// inline double * get_V_dot_local_v() { return v_dot_local_v; }
|
||||
// inline double get_V_dot_north() const { return v_dot_local_v[0]; }
|
||||
// inline double get_V_dot_east() const { return v_dot_local_v[1]; }
|
||||
// inline double get_V_dot_down() const { return v_dot_local_v[2]; }
|
||||
/* inline void set_Accels_Local( double north, double east, double down ) {
|
||||
inline double get_V_dot_north() const { return v_dot_local_v[0]; }
|
||||
inline double get_V_dot_east() const { return v_dot_local_v[1]; }
|
||||
inline double get_V_dot_down() const { return v_dot_local_v[2]; }
|
||||
inline void set_Accels_Local( double north, double east, double down ) {
|
||||
v_dot_local_v[0] = north;
|
||||
v_dot_local_v[1] = east;
|
||||
v_dot_local_v[2] = down;
|
||||
} */
|
||||
}
|
||||
|
||||
FG_VECTOR_3 v_dot_body_v;
|
||||
// inline double * get_V_dot_body_v() { return v_dot_body_v; }
|
||||
|
@ -529,9 +529,9 @@ public:
|
|||
|
||||
FG_VECTOR_3 euler_rates_v;
|
||||
// inline double * get_Euler_rates_v() { return euler_rates_v; }
|
||||
// inline double get_Phi_dot() const { return euler_rates_v[0]; }
|
||||
// inline double get_Theta_dot() const { return euler_rates_v[1]; }
|
||||
// inline double get_Psi_dot() const { return euler_rates_v[2]; }
|
||||
inline double get_Phi_dot() const { return euler_rates_v[0]; }
|
||||
inline double get_Theta_dot() const { return euler_rates_v[1]; }
|
||||
inline double get_Psi_dot() const { return euler_rates_v[2]; }
|
||||
inline void set_Euler_Rates( double phi, double theta, double psi ) {
|
||||
euler_rates_v[0] = phi;
|
||||
euler_rates_v[1] = theta;
|
||||
|
|
|
@ -678,7 +678,7 @@ void guiFixPanel( void )
|
|||
int toggle_pause;
|
||||
|
||||
if ( current_options.get_panel_status() ) {
|
||||
FGView *v = ¤t_view;
|
||||
// FGView *v = ¤t_view;
|
||||
FGTime *t = FGTime::cur_time_params;
|
||||
|
||||
if( (toggle_pause = !t->getPause()) )
|
||||
|
@ -809,11 +809,11 @@ void ConfirmExitDialogInit(void)
|
|||
|
||||
YNdialogBoxOkButton = new puOneShot (100, 10, 160, 50);
|
||||
YNdialogBoxOkButton -> setLegend (gui_msg_OK);
|
||||
YNdialogBoxOkButton -> makeReturnDefault (TRUE );
|
||||
YNdialogBoxOkButton -> setCallback (goodBye);
|
||||
|
||||
YNdialogBoxNoButton = new puOneShot (240, 10, 300, 50);
|
||||
YNdialogBoxNoButton -> setLegend (gui_msg_NO);
|
||||
// YNdialogBoxNoButton -> makeReturnDefault (TRUE );
|
||||
YNdialogBoxNoButton -> setCallback (goAwayYesNoCb);
|
||||
}
|
||||
FG_FINALIZE_PUI_DIALOG( YNdialogBox );
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
noinst_LIBRARIES = libNetworkOLK.a
|
||||
|
||||
libNetworkOLK_a_SOURCES = \
|
||||
net_send.cxx net_hud.cxx network.cxx network.h fgd.h
|
||||
net_send.cxx net_hud.cxx network.cxx network.h fgd.h \
|
||||
features.cxx features.hxx
|
||||
|
||||
INCLUDES += -I$(top_builddir) -I$(top_builddir)/src
|
||||
|
|
Loading…
Reference in a new issue