41#include "models/FGFCS.h"
42#include "math/FGParameterValue.h"
43#include "input_output/FGLog.h"
53FGFilter::FGFilter(FGFCS* fcs, Element* element)
54 : FGFCSComponent(fcs, element), DynamicFilter(false), Initialize(true)
56 C[1] = C[2] = C[3] = C[4] = C[5] = C[6] =
nullptr;
58 CheckInputNodes(1, 1, element);
60 auto PropertyManager = fcs->GetPropertyManager();
61 for (
int i=1; i<7; i++)
62 ReadFilterCoefficients(element, i, PropertyManager);
64 if (Type ==
"LAG_FILTER") FilterType = eLag ;
65 else if (Type ==
"LEAD_LAG_FILTER") FilterType = eLeadLag ;
66 else if (Type ==
"SECOND_ORDER_FILTER") FilterType = eOrder2 ;
67 else if (Type ==
"WASHOUT_FILTER") FilterType = eWashout ;
68 else FilterType = eUnknown ;
70 CalculateDynamicFilters();
72 bind(element, PropertyManager.get());
86void FGFilter::ResetPastStates(
void)
88 FGFCSComponent::ResetPastStates();
90 Input = 0.0; Initialize =
true;
95void FGFilter::ReadFilterCoefficients(Element* element,
int index,
96 std::shared_ptr<FGPropertyManager> PropertyManager)
100 string coefficient =
"c0";
101 coefficient[1] += index;
103 if ( element->FindElement(coefficient) ) {
104 C[index] =
new FGParameterValue(element->FindElement(coefficient),
106 DynamicFilter |= !C[index]->IsConstant();
112void FGFilter::CalculateDynamicFilters(
void)
116 switch (FilterType) {
118 denom = 2.0 + dt*C[1];
119 ca = dt*C[1] / denom;
120 cb = (2.0 - dt*C[1]) / denom;
124 denom = 2.0*C[3] + dt*C[4];
125 ca = (2.0*C[1] + dt*C[2]) / denom;
126 cb = (dt*C[2] - 2.0*C[1]) / denom;
127 cc = (2.0*C[3] - dt*C[4]) / denom;
130 denom = 4.0*C[4] + 2.0*C[5]*dt + C[6]*dt*dt;
131 ca = (4.0*C[1] + 2.0*C[2]*dt + C[3]*dt*dt) / denom;
132 cb = (2.0*C[3]*dt*dt - 8.0*C[1]) / denom;
133 cc = (4.0*C[1] - 2.0*C[2]*dt + C[3]*dt*dt) / denom;
134 cd = (2.0*C[6]*dt*dt - 8.0*C[4]) / denom;
135 ce = (4.0*C[4] - 2.0*C[5]*dt + C[6]*dt*dt) / denom;
138 denom = 2.0 + dt*C[1];
140 cb = (2.0 - dt*C[1]) / denom;
144 FGLogging log(LogLevel::ERROR);
145 log <<
"Unknown filter type\n";
154bool FGFilter::Run(
void)
158 PreviousOutput2 = PreviousInput2 = PreviousOutput1 = PreviousInput1 = Output = Input;
163 Input = InputNodes[0]->getDoubleValue();
165 if (DynamicFilter) CalculateDynamicFilters();
167 switch (FilterType) {
169 Output = (Input + PreviousInput1) * ca + PreviousOutput1 * cb;
172 Output = Input * ca + PreviousInput1 * cb + PreviousOutput1 * cc;
175 Output = Input * ca + PreviousInput1 * cb + PreviousInput2 * cc
176 - PreviousOutput1 * cd - PreviousOutput2 * ce;
179 Output = Input * ca - PreviousInput1 * ca + PreviousOutput1 * cb;
187 PreviousOutput2 = PreviousOutput1;
188 PreviousOutput1 = Output;
189 PreviousInput2 = PreviousInput1;
190 PreviousInput1 = Input;
217void FGFilter::Debug(
int from)
219 if (debug_lvl <= 0)
return;
223 FGLogging log(LogLevel::DEBUG);
224 log <<
" INPUT: " << InputNodes[0]->GetName() << fixed <<
"\n";
226 for (
int i=1; i < 7; i++) {
229 log <<
" C[" << i <<
"]";
230 if (!C[i]->IsConstant()) log <<
" is the value of property";
231 log <<
": "<< C[i]->GetName() <<
"\n";
234 for (
auto node: OutputNodes)
235 log <<
" OUTPUT: " << node->getNameString() <<
"\n";
238 if (debug_lvl & 2 ) {
239 FGLogging log(LogLevel::DEBUG);
240 if (from == 0) log <<
"Instantiated: FGFilter\n";
241 if (from == 1) log <<
"Destroyed: FGFilter\n";
243 if (debug_lvl & 4 ) {
245 if (debug_lvl & 8 ) {
247 if (debug_lvl & 16) {
249 if (debug_lvl & 64) {
Main namespace for the JSBSim Flight Dynamics Model.