public float Update(float angleError, float angularVelocity, float maxAA) { var aaNorm = Utils.ClampH(maxAngularAcceleration / maxAA, 1); var aaCap = Mathf.Min(maxAngularAcceleration, maxAA); var tau = avFilter * TimeWarp.fixedDeltaTime; avActionFilter.Tau = tau; pid.setTau(tau); var errorDecreases = angleError < 0 && angularVelocity > 0 || angleError > 0 && angularVelocity < 0; if (Mathf.Abs(angleError) < angularErrorTolerance) { pid.Update(Utils.Clamp(angularVelocity / aaCap, -1, 1) * aaNorm); } else if (errorDecreases) { var accelToStop = angleError.Equals(0) ? 0 : angularVelocity * angularVelocity / 2 / angleError; var accelToStopAbs = Mathf.Abs(accelToStop); var decelerateThreshold = Mathf.Abs(pid.Action) < upperLowerActionThreshold ? decelerateThresholdUpper : decelerateThresholdLower; if (accelToStopAbs > decelerateThreshold * aaCap) { pid.Update(-Utils.Clamp(accelToStop, -aaCap, aaCap) / maxAA); } else if (accelToStopAbs < accelerateThreshold * aaCap && Math.Abs(angularVelocity) < maxAngularVelocity) { pid.Update(Utils.Clamp(angleError * angleErrorToActionP, -1, 1) * aaNorm); } else { pid.Update(0); } } else { pid.Update(Utils.Clamp(angleError * angleErrorToActionP + angularVelocity / aaCap, -1, 1) * aaNorm); } var action = tau > 0 ? avActionFilter.Update(pid.Action) : pid.Action; if (odFilter > 0) { action *= 1 - odFilter * OD.Update(pid.Action, TimeWarp.fixedDeltaTime); } // DebugUtils.CSV($"AxisAttitudeCascade-{name}.csv", // Time.timeSinceLevelLoad, // angleError, // angularVelocity, // pid.Action, // action); //debug return(-action); }
public float UpdateAV(float avError) { var tau = ATCB.avAction_Filter * TimeWarp.fixedDeltaTime; avFilter.Tau = tau; avPID.setTau(tau); avPID.Update(avError); avPID.Action = avFilter.Update(avPID.Action); return(avPID.Action); }