Add the ability to control turbulence rate as well as magnitude.
Square the normalized direction acceleration for the y and z axes, so that turbulence predominantly affects pitch. Bind to the /environment/turbulence/magnitude-norm and /environment/turbulence/rate-hz properties in FlightGear.
This commit is contained in:
parent
7e15ed39a1
commit
1691d3ba19
9 changed files with 80 additions and 33 deletions
|
@ -126,7 +126,8 @@ FGEnvironment::FGEnvironment()
|
||||||
wind_from_north_fps(0),
|
wind_from_north_fps(0),
|
||||||
wind_from_east_fps(0),
|
wind_from_east_fps(0),
|
||||||
wind_from_down_fps(0),
|
wind_from_down_fps(0),
|
||||||
turbulence_norm(0)
|
turbulence_magnitude_norm(0),
|
||||||
|
turbulence_rate_hz(1)
|
||||||
{
|
{
|
||||||
_setup_tables();
|
_setup_tables();
|
||||||
_recalc_density();
|
_recalc_density();
|
||||||
|
@ -157,14 +158,15 @@ FGEnvironment::copy (const FGEnvironment &env)
|
||||||
wind_from_north_fps = env.wind_from_north_fps;
|
wind_from_north_fps = env.wind_from_north_fps;
|
||||||
wind_from_east_fps = env.wind_from_east_fps;
|
wind_from_east_fps = env.wind_from_east_fps;
|
||||||
wind_from_down_fps = env.wind_from_down_fps;
|
wind_from_down_fps = env.wind_from_down_fps;
|
||||||
turbulence_norm = env.turbulence_norm;
|
turbulence_magnitude_norm = env.turbulence_magnitude_norm;
|
||||||
|
turbulence_rate_hz = env.turbulence_rate_hz;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
maybe_copy_value (FGEnvironment * env, const SGPropertyNode * node,
|
maybe_copy_value (FGEnvironment * env, const SGPropertyNode * node,
|
||||||
const char * name, void (FGEnvironment::*setter)(double))
|
const char * name, void (FGEnvironment::*setter)(double))
|
||||||
{
|
{
|
||||||
const SGPropertyNode * child = node->getChild(name);
|
const SGPropertyNode * child = node->getNode(name);
|
||||||
// fragile: depends on not being typed
|
// fragile: depends on not being typed
|
||||||
// as a number
|
// as a number
|
||||||
if (child != 0 && child->getStringValue()[0] != '\0') {
|
if (child != 0 && child->getStringValue()[0] != '\0') {
|
||||||
|
@ -205,8 +207,11 @@ FGEnvironment::read (const SGPropertyNode * node)
|
||||||
maybe_copy_value(this, node, "elevation-ft",
|
maybe_copy_value(this, node, "elevation-ft",
|
||||||
&FGEnvironment::set_elevation_ft);
|
&FGEnvironment::set_elevation_ft);
|
||||||
|
|
||||||
maybe_copy_value(this, node, "turbulence-norm",
|
maybe_copy_value(this, node, "turbulence/magnitude-norm",
|
||||||
&FGEnvironment::set_turbulence_norm);
|
&FGEnvironment::set_turbulence_magnitude_norm);
|
||||||
|
|
||||||
|
maybe_copy_value(this, node, "turbulence/rate-hz",
|
||||||
|
&FGEnvironment::set_turbulence_rate_hz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -289,9 +294,15 @@ FGEnvironment::get_wind_from_down_fps () const
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
double
|
||||||
FGEnvironment::get_turbulence_norm () const
|
FGEnvironment::get_turbulence_magnitude_norm () const
|
||||||
{
|
{
|
||||||
return turbulence_norm;
|
return turbulence_magnitude_norm;
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
FGEnvironment::get_turbulence_rate_hz () const
|
||||||
|
{
|
||||||
|
return turbulence_rate_hz;
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
double
|
||||||
|
@ -394,9 +405,15 @@ FGEnvironment::set_wind_from_down_fps (double d)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FGEnvironment::set_turbulence_norm (double t)
|
FGEnvironment::set_turbulence_magnitude_norm (double t)
|
||||||
{
|
{
|
||||||
turbulence_norm = t;
|
turbulence_magnitude_norm = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FGEnvironment::set_turbulence_rate_hz (double r)
|
||||||
|
{
|
||||||
|
turbulence_rate_hz = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -588,9 +605,14 @@ interpolate (const FGEnvironment * env1, const FGEnvironment * env2,
|
||||||
env2->get_elevation_ft(),
|
env2->get_elevation_ft(),
|
||||||
fraction));
|
fraction));
|
||||||
|
|
||||||
result->set_turbulence_norm
|
result->set_turbulence_magnitude_norm
|
||||||
(do_interp(env1->get_turbulence_norm(),
|
(do_interp(env1->get_turbulence_magnitude_norm(),
|
||||||
env2->get_turbulence_norm(),
|
env2->get_turbulence_magnitude_norm(),
|
||||||
|
fraction));
|
||||||
|
|
||||||
|
result->set_turbulence_rate_hz
|
||||||
|
(do_interp(env1->get_turbulence_rate_hz(),
|
||||||
|
env2->get_turbulence_rate_hz(),
|
||||||
fraction));
|
fraction));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,8 @@ public:
|
||||||
virtual double get_wind_from_east_fps () const;
|
virtual double get_wind_from_east_fps () const;
|
||||||
virtual double get_wind_from_down_fps () const;
|
virtual double get_wind_from_down_fps () const;
|
||||||
|
|
||||||
virtual double get_turbulence_norm () const;
|
virtual double get_turbulence_magnitude_norm () const;
|
||||||
|
virtual double get_turbulence_rate_hz () const;
|
||||||
|
|
||||||
virtual void set_visibility_m (double v);
|
virtual void set_visibility_m (double v);
|
||||||
|
|
||||||
|
@ -89,7 +90,8 @@ public:
|
||||||
virtual void set_wind_from_east_fps (double e);
|
virtual void set_wind_from_east_fps (double e);
|
||||||
virtual void set_wind_from_down_fps (double d);
|
virtual void set_wind_from_down_fps (double d);
|
||||||
|
|
||||||
virtual void set_turbulence_norm (double t);
|
virtual void set_turbulence_magnitude_norm (double t);
|
||||||
|
virtual void set_turbulence_rate_hz (double t);
|
||||||
|
|
||||||
virtual double get_elevation_ft () const;
|
virtual double get_elevation_ft () const;
|
||||||
virtual void set_elevation_ft (double elevation_ft);
|
virtual void set_elevation_ft (double elevation_ft);
|
||||||
|
@ -120,7 +122,8 @@ private:
|
||||||
double pressure_inhg;
|
double pressure_inhg;
|
||||||
double density_slugft3;
|
double density_slugft3;
|
||||||
|
|
||||||
double turbulence_norm;
|
double turbulence_magnitude_norm;
|
||||||
|
double turbulence_rate_hz;
|
||||||
|
|
||||||
double wind_from_heading_deg;
|
double wind_from_heading_deg;
|
||||||
double wind_speed_kt;
|
double wind_speed_kt;
|
||||||
|
|
|
@ -106,10 +106,14 @@ FGEnvironmentMgr::bind ()
|
||||||
&FGEnvironment::get_wind_from_down_fps,
|
&FGEnvironment::get_wind_from_down_fps,
|
||||||
&FGEnvironment::set_wind_from_down_fps);
|
&FGEnvironment::set_wind_from_down_fps);
|
||||||
fgSetArchivable("/environment/wind-from-down-fps");
|
fgSetArchivable("/environment/wind-from-down-fps");
|
||||||
fgTie("/environment/turbulence-norm", _environment,
|
fgTie("/environment/turbulence/magnitude-norm", _environment,
|
||||||
&FGEnvironment::get_turbulence_norm,
|
&FGEnvironment::get_turbulence_magnitude_norm,
|
||||||
&FGEnvironment::set_turbulence_norm);
|
&FGEnvironment::set_turbulence_magnitude_norm);
|
||||||
fgSetArchivable("/environment/turbulence-norm");
|
fgSetArchivable("/environment/turbulence/magnitude-norm");
|
||||||
|
fgTie("/environment/turbulence/rate_hz", _environment,
|
||||||
|
&FGEnvironment::get_turbulence_rate_hz,
|
||||||
|
&FGEnvironment::set_turbulence_rate_hz);
|
||||||
|
fgSetArchivable("/environment/turbulence/rate_hz");
|
||||||
|
|
||||||
for (int i = 0; i < MAX_CLOUD_LAYERS; i++) {
|
for (int i = 0; i < MAX_CLOUD_LAYERS; i++) {
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
|
|
@ -92,6 +92,7 @@ FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex)
|
||||||
turbType = ttStandard;
|
turbType = ttStandard;
|
||||||
// turbType = ttBerndt;
|
// turbType = ttBerndt;
|
||||||
TurbGain = 0.0;
|
TurbGain = 0.0;
|
||||||
|
TurbRate = 1.0;
|
||||||
|
|
||||||
bind();
|
bind();
|
||||||
Debug(0);
|
Debug(0);
|
||||||
|
@ -272,11 +273,13 @@ void FGAtmosphere::Turbulence(void)
|
||||||
// away from the peaks
|
// away from the peaks
|
||||||
MagnitudedAccelDt = ((MagnitudedAccelDt - Magnitude) /
|
MagnitudedAccelDt = ((MagnitudedAccelDt - Magnitude) /
|
||||||
(1 + fabs(Magnitude)));
|
(1 + fabs(Magnitude)));
|
||||||
MagnitudeAccel += MagnitudedAccelDt*rate*State->Getdt();
|
MagnitudeAccel += MagnitudedAccelDt*rate*TurbRate*State->Getdt();
|
||||||
Magnitude += MagnitudeAccel*rate*State->Getdt();
|
Magnitude += MagnitudeAccel*rate*State->Getdt();
|
||||||
|
|
||||||
vDirectiondAccelDt.Normalize();
|
vDirectiondAccelDt.Normalize();
|
||||||
vDirectionAccel += vDirectiondAccelDt*rate*State->Getdt();
|
vDirectiondAccelDt(eY) *= vDirectiondAccelDt(eY);
|
||||||
|
vDirectiondAccelDt(eZ) *= vDirectiondAccelDt(eZ);
|
||||||
|
vDirectionAccel += vDirectiondAccelDt*rate*TurbRate*State->Getdt();
|
||||||
vDirectionAccel.Normalize();
|
vDirectionAccel.Normalize();
|
||||||
vDirection += vDirectionAccel*rate*State->Getdt();
|
vDirection += vDirectionAccel*rate*State->Getdt();
|
||||||
|
|
||||||
|
@ -284,7 +287,7 @@ void FGAtmosphere::Turbulence(void)
|
||||||
|
|
||||||
// Diminish turbulence within three wingspans
|
// Diminish turbulence within three wingspans
|
||||||
// of the ground
|
// of the ground
|
||||||
vTurbulence = TurbGain*Magnitude * vDirection;
|
vTurbulence = TurbGain * Magnitude * vDirection;
|
||||||
double HOverBMAC = Position->GetHOverBMAC();
|
double HOverBMAC = Position->GetHOverBMAC();
|
||||||
if (HOverBMAC < 3.0)
|
if (HOverBMAC < 3.0)
|
||||||
vTurbulence *= (HOverBMAC / 3.0) * (HOverBMAC / 3.0);
|
vTurbulence *= (HOverBMAC / 3.0) * (HOverBMAC / 3.0);
|
||||||
|
|
|
@ -150,6 +150,7 @@ public:
|
||||||
inline double GetWindPsi(void) const { return psiw; }
|
inline double GetWindPsi(void) const { return psiw; }
|
||||||
|
|
||||||
inline void SetTurbGain(double tt) {TurbGain = tt;}
|
inline void SetTurbGain(double tt) {TurbGain = tt;}
|
||||||
|
inline void SetTurbRate(double tt) {TurbRate = tt;}
|
||||||
|
|
||||||
inline double GetTurbPQR(int idx) const {return vTurbPQR(idx);}
|
inline double GetTurbPQR(int idx) const {return vTurbPQR(idx);}
|
||||||
inline FGColumnVector3& GetTurbPQR(void) {return vTurbPQR;}
|
inline FGColumnVector3& GetTurbPQR(void) {return vTurbPQR;}
|
||||||
|
@ -176,6 +177,7 @@ private:
|
||||||
|
|
||||||
double MagnitudedAccelDt, MagnitudeAccel, Magnitude;
|
double MagnitudedAccelDt, MagnitudeAccel, Magnitude;
|
||||||
double TurbGain;
|
double TurbGain;
|
||||||
|
double TurbRate;
|
||||||
FGColumnVector3 vDirectiondAccelDt;
|
FGColumnVector3 vDirectiondAccelDt;
|
||||||
FGColumnVector3 vDirectionAccel;
|
FGColumnVector3 vDirectionAccel;
|
||||||
FGColumnVector3 vDirection;
|
FGColumnVector3 vDirection;
|
||||||
|
|
|
@ -182,7 +182,8 @@ FGJSBsim::FGJSBsim( double dt )
|
||||||
temperature = fgGetNode("/environment/temperature-degc",true);
|
temperature = fgGetNode("/environment/temperature-degc",true);
|
||||||
pressure = fgGetNode("/environment/pressure-inhg",true);
|
pressure = fgGetNode("/environment/pressure-inhg",true);
|
||||||
density = fgGetNode("/environment/density-slugft3",true);
|
density = fgGetNode("/environment/density-slugft3",true);
|
||||||
turbulence = fgGetNode("environment/turbulence-norm",true);
|
turbulence_gain = fgGetNode("/environment/turbulence/magnitude-norm",true);
|
||||||
|
turbulence_rate = fgGetNode("/environment/turbulence/rate-hz",true);
|
||||||
|
|
||||||
wind_from_north= fgGetNode("/environment/wind-from-north-fps",true);
|
wind_from_north= fgGetNode("/environment/wind-from-north-fps",true);
|
||||||
wind_from_east = fgGetNode("/environment/wind-from-east-fps" ,true);
|
wind_from_east = fgGetNode("/environment/wind-from-east-fps" ,true);
|
||||||
|
@ -202,6 +203,8 @@ FGJSBsim::~FGJSBsim(void) {
|
||||||
|
|
||||||
void FGJSBsim::init() {
|
void FGJSBsim::init() {
|
||||||
|
|
||||||
|
double tmp;
|
||||||
|
|
||||||
SG_LOG( SG_FLIGHT, SG_INFO, "Starting and initializing JSBsim" );
|
SG_LOG( SG_FLIGHT, SG_INFO, "Starting and initializing JSBsim" );
|
||||||
|
|
||||||
// Explicitly call the superclass's
|
// Explicitly call the superclass's
|
||||||
|
@ -216,9 +219,13 @@ void FGJSBsim::init() {
|
||||||
9.0/5.0*(temperature->getDoubleValue()+273.15) );
|
9.0/5.0*(temperature->getDoubleValue()+273.15) );
|
||||||
Atmosphere->SetExPressure(pressure->getDoubleValue()*70.726566);
|
Atmosphere->SetExPressure(pressure->getDoubleValue()*70.726566);
|
||||||
Atmosphere->SetExDensity(density->getDoubleValue());
|
Atmosphere->SetExDensity(density->getDoubleValue());
|
||||||
Atmosphere->SetTurbGain(turbulence->getDoubleValue() *
|
|
||||||
turbulence->getDoubleValue() *
|
tmp = turbulence_gain->getDoubleValue();
|
||||||
100.0);
|
Atmosphere->SetTurbGain(tmp * tmp * 100.0);
|
||||||
|
|
||||||
|
tmp = turbulence_rate->getDoubleValue();
|
||||||
|
Atmosphere->SetTurbRate(tmp);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Atmosphere->UseInternal();
|
Atmosphere->UseInternal();
|
||||||
}
|
}
|
||||||
|
@ -364,6 +371,7 @@ FGJSBsim::update( double dt ) {
|
||||||
// Convert from the FGInterface struct to the JSBsim generic_ struct
|
// Convert from the FGInterface struct to the JSBsim generic_ struct
|
||||||
|
|
||||||
bool FGJSBsim::copy_to_JSBsim() {
|
bool FGJSBsim::copy_to_JSBsim() {
|
||||||
|
double tmp;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
// copy control positions into the JSBsim structure
|
// copy control positions into the JSBsim structure
|
||||||
|
@ -412,9 +420,12 @@ bool FGJSBsim::copy_to_JSBsim() {
|
||||||
9.0/5.0*(temperature->getDoubleValue()+273.15) );
|
9.0/5.0*(temperature->getDoubleValue()+273.15) );
|
||||||
Atmosphere->SetExPressure(pressure->getDoubleValue()*70.726566);
|
Atmosphere->SetExPressure(pressure->getDoubleValue()*70.726566);
|
||||||
Atmosphere->SetExDensity(density->getDoubleValue());
|
Atmosphere->SetExDensity(density->getDoubleValue());
|
||||||
Atmosphere->SetTurbGain(turbulence->getDoubleValue() *
|
|
||||||
turbulence->getDoubleValue() *
|
tmp = turbulence_gain->getDoubleValue();
|
||||||
100.0);
|
Atmosphere->SetTurbGain(tmp * tmp * 100.0);
|
||||||
|
|
||||||
|
tmp = turbulence_rate->getDoubleValue();
|
||||||
|
Atmosphere->SetTurbRate(tmp);
|
||||||
|
|
||||||
Atmosphere->SetWindNED( wind_from_north->getDoubleValue(),
|
Atmosphere->SetWindNED( wind_from_north->getDoubleValue(),
|
||||||
wind_from_east->getDoubleValue(),
|
wind_from_east->getDoubleValue(),
|
||||||
|
|
|
@ -265,7 +265,8 @@ private:
|
||||||
SGPropertyNode *temperature;
|
SGPropertyNode *temperature;
|
||||||
SGPropertyNode *pressure;
|
SGPropertyNode *pressure;
|
||||||
SGPropertyNode *density;
|
SGPropertyNode *density;
|
||||||
SGPropertyNode *turbulence;
|
SGPropertyNode *turbulence_gain;
|
||||||
|
SGPropertyNode *turbulence_rate;
|
||||||
|
|
||||||
SGPropertyNode *wind_from_north;
|
SGPropertyNode *wind_from_north;
|
||||||
SGPropertyNode *wind_from_east;
|
SGPropertyNode *wind_from_east;
|
||||||
|
|
|
@ -995,7 +995,7 @@ fgOptWind( const char *arg )
|
||||||
static int
|
static int
|
||||||
fgOptTurbulence( const char *arg)
|
fgOptTurbulence( const char *arg)
|
||||||
{
|
{
|
||||||
fgDefaultWeatherValue("turbulence-norm", atof(arg));
|
fgDefaultWeatherValue("turbulence/magnitude-norm", atof(arg));
|
||||||
return FG_OPTIONS_OK;
|
return FG_OPTIONS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -180,7 +180,8 @@ void FGProps2NetCtrls( FGNetCtrls *net, bool net_byte_order ) {
|
||||||
|
|
||||||
net->wind_speed_kt = fgGetDouble("/environment/wind-speed-kt");
|
net->wind_speed_kt = fgGetDouble("/environment/wind-speed-kt");
|
||||||
net->wind_dir_deg = fgGetDouble("/environment/wind-from-heading-deg");
|
net->wind_dir_deg = fgGetDouble("/environment/wind-from-heading-deg");
|
||||||
net->turbulence_norm = fgGetDouble("/environment/turbulence-norm");
|
net->turbulence_norm =
|
||||||
|
fgGetDouble("/environment/turbulence/magnitude-norm");
|
||||||
|
|
||||||
// cur_fdm_state->get_ground_elev_ft() is what we want ... this
|
// cur_fdm_state->get_ground_elev_ft() is what we want ... this
|
||||||
// reports the altitude of the aircraft.
|
// reports the altitude of the aircraft.
|
||||||
|
@ -338,7 +339,7 @@ void FGNetCtrls2Props( FGNetCtrls *net, bool net_byte_order ) {
|
||||||
node = fgGetNode( "/environment", true );
|
node = fgGetNode( "/environment", true );
|
||||||
node->setDoubleValue( "wind-speed-kt", net->wind_speed_kt );
|
node->setDoubleValue( "wind-speed-kt", net->wind_speed_kt );
|
||||||
node->setDoubleValue( "wind-from-heading-deg", net->wind_dir_deg );
|
node->setDoubleValue( "wind-from-heading-deg", net->wind_dir_deg );
|
||||||
node->setDoubleValue( "turbulence-norm", net->turbulence_norm );
|
node->setDoubleValue( "turbulence/magnitude-norm", net->turbulence_norm );
|
||||||
node->setBoolValue( "magnetic-variation-deg", net->magvar );
|
node->setBoolValue( "magnetic-variation-deg", net->magvar );
|
||||||
|
|
||||||
// ground elevation ???
|
// ground elevation ???
|
||||||
|
|
Loading…
Reference in a new issue