protected void Clip() { if (clip) { double vmin = ClipMin.GetValue(); double vmax = ClipMax.GetValue(); double range = vmax - vmin; if (range < 0.0) { log.Error("Trying to clip with a max value " + ClipMax.GetName() + " lower than the min value " + ClipMin.GetName()); throw new Exception("JSBSim aborts"); } if (cyclic_clip && range != 0.0) { double value = output - vmin; output = (value % range) + vmin; if (output < vmin) { output += range; } } else { output = MathExt.Constrain(vmin, output, vmax); } } }
/** This function processes the input. * It calls private functions if needed to perform the hysteresis, lag, * limiting, etc. functions. */ public override bool Run() { input = inputNodes[0].GetDoubleValue(); if (fcs.GetTrimStatus()) { initialized = false; } if (fail_zero) { input = 0; } if (fail_hardover) { input = input < 0.0 ? ClipMin.GetValue() : ClipMax.GetValue(); } 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 (fail_stuck) { output = PreviousOutput; } else { if (lag != 0.0) { Lag(); // models actuator lag } if (rate_limit_incr != null || rate_limit_decr != null) { RateLimit(); // limit the actuator rate } if (deadband_width != 0.0) { Deadband(); } if (hysteresis_width != 0.0) { Hysteresis(); } if (bias != 0.0) { Bias(); // models a finite bias } if (delay != 0) { Delay(); // Model transport latency } } PreviousOutput = output; // previous value needed for "stuck" malfunction initialized = true; Clip(); if (clip) { double clipmax = ClipMax.GetValue(); saturated = false; if (output >= clipmax && clipmax != 0) { saturated = true; } else { double clipmin = ClipMin.GetValue(); if (output <= clipmin && clipmin != 0) { saturated = true; } } } SetOutput(); return(true); }