public virtual float GetMinAoA(Conditions conditions, float guess = float.NaN) { Accord.Math.Optimization.BrentSearch minimizer = new Accord.Math.Optimization.BrentSearch((aoa) => GetLiftForceMagnitude(conditions, (float)aoa, 1), -60 * Mathf.Deg2Rad, -10 * Mathf.Deg2Rad, 0.0001); if (float.IsNaN(guess) || float.IsInfinity(guess)) { minimizer.Maximize(); } else { minimizer.LowerBound = guess - 2 * Mathf.Deg2Rad; minimizer.UpperBound = guess + 2 * Mathf.Deg2Rad; if (!minimizer.Maximize()) { minimizer.LowerBound = guess - 5 * Mathf.Deg2Rad; minimizer.UpperBound = guess + 5 * Mathf.Deg2Rad; if (!minimizer.Maximize()) { minimizer.LowerBound = Mathf.Clamp(guess - 10 * Mathf.Deg2Rad, -90 * Mathf.Deg2Rad, -60 * Mathf.Deg2Rad); minimizer.UpperBound = Math.Max(-10 * Mathf.Deg2Rad, guess + 10 * Mathf.Deg2Rad); minimizer.Maximize(); } } } return((float)minimizer.Solution); }
protected float GetAoA(Conditions conditions, float offsettingForce, bool useThrust = true, bool dryTorque = false, float guess = float.NaN, float pitchInputGuess = float.NaN, bool lockPitchInput = false, float tolerance = 0.0001f) { if (lockPitchInput && (float.IsNaN(pitchInputGuess) || float.IsInfinity(pitchInputGuess))) { pitchInputGuess = 0; } Vector3 thrustForce = useThrust ? this.GetThrustForce(conditions) : Vector3.zero; Accord.Math.Optimization.BrentSearch solver; if (lockPitchInput) { solver = new Accord.Math.Optimization.BrentSearch((aoa) => GetLiftForceMagnitude(this.GetLiftForce(conditions, (float)aoa, pitchInputGuess) + thrustForce, (float)aoa) - offsettingForce, -10 * Mathf.Deg2Rad, 35 * Mathf.Deg2Rad, tolerance); } else { solver = new Accord.Math.Optimization.BrentSearch((aoa) => GetLiftForceMagnitude(this.GetLiftForce(conditions, (float)aoa, GetPitchInput(conditions, (float)aoa, dryTorque, pitchInputGuess)) + thrustForce, (float)aoa) - offsettingForce, -10 * Mathf.Deg2Rad, 35 * Mathf.Deg2Rad, tolerance); } if (float.IsNaN(guess) || float.IsInfinity(guess)) { solver.FindRoot(); } else { solver.LowerBound = guess - 2 * Mathf.Deg2Rad; solver.UpperBound = guess + 2 * Mathf.Deg2Rad; if (!solver.FindRoot()) { solver.LowerBound = guess - 5 * Mathf.Deg2Rad; solver.UpperBound = guess + 5 * Mathf.Deg2Rad; if (!solver.FindRoot()) { solver.LowerBound = Math.Min(-10 * Mathf.Deg2Rad, guess - 10 * Mathf.Deg2Rad); solver.UpperBound = Math.Max(35 * Mathf.Deg2Rad, guess + 10 * Mathf.Deg2Rad); solver.FindRoot(); } } } return((float)solver.Solution); }
// TODO: Add ITorqueProvider and thrust effect on torque public override float GetPitchInput(Conditions conditions, float AoA, bool dryTorque = false, float guess = float.NaN) { Accord.Math.Optimization.BrentSearch solver = new Accord.Math.Optimization.BrentSearch((input) => this.GetAeroTorque(conditions, AoA, (float)input, dryTorque).x, -0.3, 0.3, 0.0001); if (solver.FindRoot()) { return((float)solver.Solution); } solver.LowerBound = -1; solver.UpperBound = 1; if (solver.FindRoot()) { return((float)solver.Solution); } if (this.GetAeroTorque(conditions, AoA, 0, dryTorque).x > 0) { return(-1); } else { return(1); } }