Author: Jon Berndt
Date started: 21 February 2006
- ------------- Copyright (C) 2007 Jon S. Berndt (jsb@hal-pc.org) -------------
+ ------------- Copyright (C) 2007 Jon S. Berndt (jon@jsbsim.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
#include "FGActuator.h"
+using namespace std;
+
namespace JSBSim {
-static const char *IdSrc = "$Id$";
+static const char *IdSrc = "$Id: FGActuator.cpp,v 1.19 2011/06/18 13:30:27 bcoconni Exp $";
static const char *IdHdr = ID_ACTUATOR;
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGActuator::FGActuator(FGFCS* fcs, Element* element) : FGFCSComponent(fcs, element)
{
double denom;
- dt = fcs->GetDt();
// inputs are read from the base class constructor
bool FGActuator::Run(void )
{
- dt = fcs->GetDt();
-
Input = InputNodes[0]->getDoubleValue() * InputSigns[0];
- Output = Input; // perfect actuator
if (fail_zero) Input = 0;
- if (fail_hardover) Input = clipmax*fabs(Input)/Input;
+ if (fail_hardover) Input = clipmax*sign(Input);
+
+ Output = Input; // Perfect actuator. At this point, if no failures are present
+ // and no subsequent lag, limiting, etc. is done, the output
+ // is simply the input. If any further processing is done
+ // (below) such as lag, rate limiting, hysteresis, etc., then
+ // the Input will be further processed and the eventual Output
+ // will be overwritten from this perfect value.
if (lag != 0.0) Lag(); // models actuator lag
if (rate_limit != 0) RateLimit(); // limit the actuator rate
// "Output" on the right side of the "=" is the current frame input
// for this Lag filter
double input = Output;
- Output = ca * (input + PreviousLagInput) + PreviousLagOutput * cb;
+
+ if (!fcs->GetTrimStatus())
+ Output = ca * (input + PreviousLagInput) + PreviousLagOutput * cb;
+
PreviousLagInput = input;
PreviousLagOutput = Output;
}
// method.
double input = Output;
- if (input > PreviousHystOutput) {
- Output = max(PreviousHystOutput, input-0.5*hysteresis_width);
- } else if (input < PreviousHystOutput) {
- Output = min(PreviousHystOutput, input+0.5*hysteresis_width);
+ if (!fcs->GetTrimStatus()) {
+ if (input > PreviousHystOutput)
+ Output = max(PreviousHystOutput, input-0.5*hysteresis_width);
+ else if (input < PreviousHystOutput)
+ Output = min(PreviousHystOutput, input+0.5*hysteresis_width);
}
PreviousHystOutput = Output;
// is - for the purposes of this RateLimit method - really the input to the
// method.
double input = Output;
- if (dt > 0.0) {
+ if (!fcs->GetTrimStatus()) {
double rate = (input - PreviousRateLimOutput)/dt;
if (fabs(rate) > rate_limit) {
Output = PreviousRateLimOutput + (rate_limit*fabs(rate)/rate)*dt;
void FGActuator::Deadband(void)
{
+ // Note: this function acts cumulatively on the "Output" parameter. So, "Output"
+ // is - for the purposes of this Deadband method - really the input to the
+ // method.
+ double input = Output;
+
+ if (input < -deadband_width/2.0) {
+ Output = (input + deadband_width/2.0);
+ } else if (input > deadband_width/2.0) {
+ Output = (input - deadband_width/2.0);
+ } else {
+ Output = 0.0;
+ }
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGActuator::bind(void)
{
- string tmp = "fcs/" + PropertyManager->mkPropertyName(Name, true);
+ string tmp = Name;
+ if (Name.find("/") == string::npos) {
+ tmp = "fcs/" + PropertyManager->mkPropertyName(Name, true);
+ }
const string tmp_zero = tmp + "/malfunction/fail_zero";
const string tmp_hardover = tmp + "/malfunction/fail_hardover";
const string tmp_stuck = tmp + "/malfunction/fail_stuck";
if (debug_lvl & 1) { // Standard console startup message output
if (from == 0) { // Constructor
if (InputSigns[0] < 0)
- cout << " INPUT: -" << InputNodes[0]->getName() << endl;
+ cout << " INPUT: -" << InputNames[0] << endl;
else
- cout << " INPUT: " << InputNodes[0]->getName() << endl;
+ cout << " INPUT: " << InputNames[0] << endl;
- if (IsOutput) cout << " OUTPUT: " << OutputNode->getName() << endl;
+ if (IsOutput) {
+ for (unsigned int i=0; i<OutputNodes.size(); i++)
+ cout << " OUTPUT: " << OutputNodes[i]->getName() << endl;
+ }
if (bias != 0.0) cout << " Bias: " << bias << endl;
if (rate_limit != 0) cout << " Rate limit: " << rate_limit << endl;
if (lag != 0) cout << " Actuator lag: " << lag << endl;