42 #include "FGActuator.h" 43 #include "input_output/FGXMLElement.h" 44 #include "math/FGRealValue.h" 45 #include "models/FGFCS.h" 51 IDENT(IdSrc,
"$Id: FGActuator.cpp,v 1.38 2015/07/12 19:34:08 bcoconni Exp $");
52 IDENT(IdHdr,ID_ACTUATOR);
64 PreviousHystOutput = 0.0;
65 PreviousRateLimOutput = 0.0;
66 PreviousLagInput = PreviousLagOutput = 0.0;
67 bias = lag = hysteresis_width = deadband_width = 0.0;
68 rate_limit_incr = rate_limit_decr = 0;
69 fail_zero = fail_hardover = fail_stuck =
false;
85 while ( ratelim_el ) {
90 if (is_number(rate_limit_str))
91 rate_limit =
new FGRealValue(fabs(atof(rate_limit_str.c_str())));
93 if (rate_limit_str[0] ==
'-') rate_limit_str.erase(0,1);
94 FGPropertyNode* rate_limit_prop = PropertyManager->GetNode(rate_limit_str,
true);
95 if (!rate_limit_prop) {
96 std::cerr <<
"No such property, " << rate_limit_str <<
" for rate limiting" << std::endl;
105 if (sense.substr(0,4) ==
"incr")
106 rate_limit_incr = rate_limit;
107 else if (sense.substr(0,4) ==
"decr")
108 rate_limit_decr = rate_limit;
110 rate_limit_incr = rate_limit;
111 rate_limit_decr = rate_limit;
121 double denom = 2.00 + dt*lag;
123 cb = (2.00 - dt*lag) / denom;
126 FGFCSComponent::bind();
136 delete rate_limit_incr;
137 if (rate_limit_decr != rate_limit_incr)
138 delete rate_limit_decr;
145 void FGActuator::ResetPastStates(
void)
147 FGFCSComponent::ResetPastStates();
149 PreviousOutput = PreviousHystOutput = PreviousRateLimOutput
150 = PreviousLagInput = PreviousLagOutput = Output = 0.0;
157 Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
159 if( fcs->GetTrimStatus() ) initialized = 0;
161 if (fail_zero) Input = 0;
162 if (fail_hardover) Input = clipmax*sign(Input);
172 Output = PreviousOutput;
174 if (lag != 0.0) Lag();
175 if (rate_limit_incr != 0 || rate_limit_decr != 0) RateLimit();
176 if (deadband_width != 0.0) Deadband();
177 if (hysteresis_width != 0.0) Hysteresis();
178 if (bias != 0.0) Bias();
179 if (delay != 0) Delay();
182 PreviousOutput = Output;
190 if (Output >= clipmax && clipmax != 0) saturated =
true;
191 else if (Output <= clipmin && clipmin != 0) saturated =
true;
194 if (IsOutput) SetOutput();
201 void FGActuator::Bias(
void)
208 void FGActuator::Lag(
void)
212 double input = Output;
215 Output = ca * (input + PreviousLagInput) + PreviousLagOutput * cb;
217 PreviousLagInput = input;
218 PreviousLagOutput = Output;
223 void FGActuator::Hysteresis(
void)
228 double input = Output;
231 if (input > PreviousHystOutput)
232 Output = max(PreviousHystOutput, input-0.5*hysteresis_width);
233 else if (input < PreviousHystOutput)
234 Output = min(PreviousHystOutput, input+0.5*hysteresis_width);
237 PreviousHystOutput = Output;
242 void FGActuator::RateLimit(
void)
247 double input = Output;
249 double delta = input - PreviousRateLimOutput;
250 if (rate_limit_incr) {
251 double rate_limit = rate_limit_incr->GetValue();
252 if (delta > dt * rate_limit)
253 Output = PreviousRateLimOutput + rate_limit * dt;
255 if (rate_limit_decr) {
256 double rate_limit = -rate_limit_decr->GetValue();
257 if (delta < dt * rate_limit)
258 Output = PreviousRateLimOutput + rate_limit * dt;
261 PreviousRateLimOutput = Output;
266 void FGActuator::Deadband(
void)
271 double input = Output;
273 if (input < -deadband_width/2.0) {
274 Output = (input + deadband_width/2.0);
275 }
else if (input > deadband_width/2.0) {
276 Output = (input - deadband_width/2.0);
284 void FGActuator::bind(
void)
287 if (Name.find(
"/") == string::npos) {
290 const string tmp_zero = tmp +
"/malfunction/fail_zero";
291 const string tmp_hardover = tmp +
"/malfunction/fail_hardover";
292 const string tmp_stuck = tmp +
"/malfunction/fail_stuck";
293 const string tmp_sat = tmp +
"/saturated";
296 PropertyManager->
Tie( tmp_hardover,
this, &FGActuator::GetFailHardover, &FGActuator::SetFailHardover);
297 PropertyManager->
Tie( tmp_stuck,
this, &FGActuator::GetFailStuck, &FGActuator::SetFailStuck);
298 PropertyManager->
Tie( tmp_sat,
this, &FGActuator::IsSaturated);
320 void FGActuator::Debug(
int from)
322 if (debug_lvl <= 0)
return;
326 if (InputSigns[0] < 0)
327 cout <<
" INPUT: -" << InputNames[0] << endl;
329 cout <<
" INPUT: " << InputNames[0] << endl;
332 for (
unsigned int i=0; i<OutputNodes.size(); i++)
333 cout <<
" OUTPUT: " << OutputNodes[i]->getName() << endl;
335 if (bias != 0.0) cout <<
" Bias: " << bias << endl;
336 if (rate_limit_incr != 0) {
337 cout <<
" Increasing rate limit: " << rate_limit_incr->GetName() << endl;
339 if (rate_limit_decr != 0) {
340 cout <<
" Decreasing rate limit: " << rate_limit_decr->GetName() << endl;
342 if (lag != 0) cout <<
" Actuator lag: " << lag << endl;
343 if (hysteresis_width != 0) cout <<
" Hysteresis width: " << hysteresis_width << endl;
344 if (deadband_width != 0) cout <<
" Deadband width: " << deadband_width << endl;
347 if (debug_lvl & 2 ) {
348 if (from == 0) cout <<
"Instantiated: FGActuator" << endl;
349 if (from == 1) cout <<
"Destroyed: FGActuator" << endl;
351 if (debug_lvl & 4 ) {
353 if (debug_lvl & 8 ) {
355 if (debug_lvl & 16) {
357 if (debug_lvl & 64) {
359 cout << IdSrc << endl;
360 cout << IdHdr << endl;
void SetFailZero(bool set)
This function fails the actuator to zero.
std::string GetAttributeValue(const std::string &key)
Retrieves an attribute.
std::string mkPropertyName(std::string name, bool lowercase)
Property-ify a name replaces spaces with '-' and, optionally, makes name all lower case...
bool HasAttribute(const std::string &key)
Determines if an element has the supplied attribute.
Represents a property value which can use late binding.
Class wrapper for property handling.
Element * FindElement(const std::string &el="")
Searches for a specified element.
double FindElementValueAsNumber(const std::string &el="")
Searches for the named element and returns the data belonging to it as a number.
Represents various types of parameters.
void Tie(const std::string &name, bool *pointer, bool useDefault=true)
Tie a property to an external bool variable.
std::string GetDataLine(unsigned int i=0)
Gets a line of data belonging to an element.
bool Run(void)
This function processes the input.
Encapsulates the Flight Control System (FCS) functionality.
Element * FindNextElement(const std::string &el="")
Searches for the next element as specified.
Base class for JSBSim Flight Control System Components.