%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGSensor.h"
+#include "input_output/FGXMLElement.h"
+#include <iostream>
+#include <cstdlib>
+
+using namespace std;
namespace JSBSim {
-static const char *IdSrc = "$Id$";
+static const char *IdSrc = "$Id: FGSensor.cpp,v 1.20 2009/10/24 22:59:30 jberndt Exp $";
static const char *IdHdr = ID_SENSOR;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGSensor::FGSensor(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
{
double denom;
- dt = fcs->GetDt();
// inputs are read from the base class constructor
bits = quantized = divisions = 0;
PreviousInput = PreviousOutput = 0.0;
- min = max = bias = noise_variance = lag = drift_rate = drift = span = 0.0;
+ min = max = bias = gain = noise_variance = lag = drift_rate = drift = span = 0.0;
granularity = 0.0;
noise_type = 0;
fail_low = fail_high = fail_stuck = false;
if ( element->FindElement("bias") ) {
bias = element->FindElementValueAsNumber("bias");
}
+ if ( element->FindElement("gain") ) {
+ gain = element->FindElementValueAsNumber("gain");
+ }
if ( element->FindElement("drift_rate") ) {
drift_rate = element->FindElementValueAsNumber("drift_rate");
}
cerr << "Unknown noise type in sensor: " << Name << endl;
cerr << " defaulting to PERCENT." << endl;
}
+ string distribution = element->FindElement("noise")->GetAttributeValue("distribution");
+ if (distribution == "UNIFORM") {
+ DistributionType = eUniform;
+ } else if (distribution == "GAUSSIAN") {
+ DistributionType = eGaussian;
+ } else {
+ DistributionType = eUniform;
+ cerr << "Unknown random distribution type in sensor: " << Name << endl;
+ cerr << " defaulting to UNIFORM." << endl;
+ }
}
FGFCSComponent::bind();
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-bool FGSensor::Run(void )
+bool FGSensor::Run(void)
{
Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
+ ProcessSensorSignal();
+
+ return true;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGSensor::ProcessSensorSignal(void)
+{
Output = Input; // perfect sensor
// Degrade signal as specified
if (fail_stuck) {
Output = PreviousOutput;
- return true;
- }
+ } else {
+ if (lag != 0.0) Lag(); // models sensor lag and filter
+ if (noise_variance != 0.0) Noise(); // models noise
+ if (drift_rate != 0.0) Drift(); // models drift over time
+ if (gain != 0.0) Gain(); // models a finite gain
+ if (bias != 0.0) Bias(); // models a finite bias
- if (lag != 0.0) Lag(); // models sensor lag
- if (noise_variance != 0.0) Noise(); // models noise
- if (drift_rate != 0.0) Drift(); // models drift over time
- if (bias != 0.0) Bias(); // models a finite bias
+ if (delay != 0) Delay(); // models system signal transport latencies
- if (fail_low) Output = -HUGE_VAL;
- if (fail_high) Output = HUGE_VAL;
+ if (fail_low) Output = -HUGE_VAL;
+ if (fail_high) Output = HUGE_VAL;
- if (bits != 0) Quantize(); // models quantization degradation
-// if (delay != 0.0) Delay(); // models system signal transport latencies
+ if (bits != 0) Quantize(); // models quantization degradation
- Clip(); // Is it right to clip a sensor?
- return true;
+ Clip();
+ }
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGSensor::Noise(void)
{
- double random_value = ((double)rand()/(double)RAND_MAX) - 0.5;
+ double random_value=0.0;
+
+ if (DistributionType == eUniform) {
+ random_value = ((double)rand()/(double)RAND_MAX) - 0.5;
+ } else {
+ random_value = GaussianRandomNumber();
+ }
switch( NoiseType ) {
case ePercent:
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+void FGSensor::Gain(void)
+{
+ Output *= gain;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
void FGSensor::Drift(void)
{
drift += drift_rate*dt;
void FGSensor::Lag(void)
{
- // "Output" on the right side of the "=" is the current frame input
+ // "Output" on the right side of the "=" is the current input
Output = ca * (Output + PreviousInput) + PreviousOutput * cb;
PreviousOutput = Output;
else
cout << " INPUT: " << InputNodes[0]->getName() << endl;
}
- if (IsOutput) cout << " OUTPUT: " << OutputNode->getName() << endl;
if (bits != 0) {
if (quant_property.empty())
cout << " Quantized output" << endl;
cout << " (span: " << span << ", granularity: " << granularity << ")" << endl;
}
if (bias != 0.0) cout << " Bias: " << bias << endl;
+ if (gain != 0.0) cout << " Gain: " << gain << endl;
if (drift_rate != 0) cout << " Sensor drift rate: " << drift_rate << endl;
if (lag != 0) cout << " Sensor lag: " << lag << endl;
if (noise_variance != 0) {
} else {
cout << " Noise variance type is invalid" << endl;
}
+ if (DistributionType == eUniform) {
+ cout << " Random noise is uniformly distributed." << endl;
+ } else if (DistributionType == eGaussian) {
+ cout << " Random noise is gaussian distributed." << endl;
+ }
+ }
+ if (IsOutput) {
+ for (unsigned int i=0; i<OutputNodes.size(); i++)
+ cout << " OUTPUT: " << OutputNodes[i]->getName() << endl;
}
}
}