public VelPoint(AeroPredictor vessel, CelestialBody body, float altitude, float speed) { this.altitude = altitude; this.speed = speed; AeroPredictor.Conditions conditions = new AeroPredictor.Conditions(body, speed, altitude); float gravParameter, radius; lock (body) { gravParameter = (float)body.gravParameter; radius = (float)body.Radius; } this.mach = conditions.mach; this.dynamicPressure = 0.0005f * conditions.atmDensity * speed * speed; float weight = (vessel.Mass * gravParameter / ((radius + altitude) * (radius + altitude))) - (vessel.Mass * speed * speed / (radius + altitude)); Vector3 thrustForce = vessel.GetThrustForce(conditions); AoA_max = vessel.GetMaxAoA(conditions, out Lift_max); AoA_level = Mathf.Min(vessel.GetAoA(conditions, weight), AoA_max); pitchInput = vessel.GetPitchInput(conditions, AoA_level); Thrust_available = thrustForce.magnitude; Vector3 force = vessel.GetAeroForce(conditions, AoA_level, pitchInput); drag = AeroPredictor.GetDragForceMagnitude(force, AoA_level); Thrust_excess = -drag - AeroPredictor.GetDragForceMagnitude(thrustForce, AoA_level); Accel_excess = Thrust_excess / vessel.Mass / WindTunnelWindow.gAccel; LDRatio = Mathf.Abs(AeroPredictor.GetLiftForceMagnitude(force, AoA_level) / drag); dLift = (vessel.GetLiftForceMagnitude(conditions, AoA_level + WindTunnelWindow.AoAdelta, pitchInput) - vessel.GetLiftForceMagnitude(conditions, AoA_level, pitchInput)) / (WindTunnelWindow.AoAdelta * Mathf.Rad2Deg); }
public EnvelopePoint(AeroPredictor vessel, CelestialBody body, float altitude, float speed, float AoA_guess = float.NaN, float maxA_guess = float.NaN, float pitchI_guess = float.NaN) { this.altitude = altitude; this.speed = speed; AeroPredictor.Conditions conditions = new AeroPredictor.Conditions(body, speed, altitude); float gravParameter, radius; lock (body) { gravParameter = (float)body.gravParameter; radius = (float)body.Radius; } this.mach = conditions.mach; this.dynamicPressure = 0.0005f * conditions.atmDensity * speed * speed; float weight = (vessel.Mass * gravParameter / ((radius + altitude) * (radius + altitude))); // TODO: Minus centrifugal force... Vector3 thrustForce = vessel.GetThrustForce(conditions); //AoA_max = vessel.GetMaxAoA(conditions, out Lift_max, maxA_guess); if (float.IsNaN(maxA_guess)) { AoA_max = vessel.GetMaxAoA(conditions, out Lift_max, maxA_guess); } else { AoA_max = maxA_guess; Lift_max = AeroPredictor.GetLiftForceMagnitude(vessel.GetAeroForce(conditions, AoA_max, 1) + thrustForce, AoA_max); } AoA_level = vessel.GetAoA(conditions, weight, guess: AoA_guess, pitchInputGuess: 0, lockPitchInput: true); if (AoA_level < AoA_max) { pitchInput = vessel.GetPitchInput(conditions, AoA_level, guess: pitchI_guess); } else { pitchInput = 1; } Thrust_available = thrustForce.magnitude; force = vessel.GetAeroForce(conditions, AoA_level, pitchInput); liftforce = AeroPredictor.ToFlightFrame(force, AoA_level); //vessel.GetLiftForce(body, speed, altitude, AoA_level, mach, atmDensity); drag = AeroPredictor.GetDragForceMagnitude(force, AoA_level); float lift = AeroPredictor.GetLiftForceMagnitude(force, AoA_level); Thrust_excess = -drag - AeroPredictor.GetDragForceMagnitude(thrustForce, AoA_level); if (weight > Lift_max)// AoA_level >= AoA_max) { Thrust_excess = Lift_max - weight; AoA_level = AoA_max; } Accel_excess = (Thrust_excess / vessel.Mass / WindTunnelWindow.gAccel); LDRatio = Mathf.Abs(lift / drag); dLift = (vessel.GetLiftForceMagnitude(conditions, AoA_level + WindTunnelWindow.AoAdelta, pitchInput) - vessel.GetLiftForceMagnitude(conditions, AoA_level, pitchInput)) / (WindTunnelWindow.AoAdelta * Mathf.Rad2Deg); }
public virtual Vector3 GetLiftForce(Vector3 inflow, AeroPredictor.Conditions conditions, float AoA, float pitchInput, out Vector3 torque, Vector3 torquePoint) { Vector3 aeroForce = Vector3.zero; torque = Vector3.zero; for (int i = parts.Count - 1; i >= 0; i--) { if (parts[i].shieldedFromAirstream) { continue; } aeroForce += parts[i].GetLift(inflow, conditions.mach, out Vector3 pTorque, torquePoint); torque += pTorque; } for (int i = surfaces.Count - 1; i >= 0; i--) { if (surfaces[i].part.shieldedFromAirstream) { continue; } aeroForce += surfaces[i].GetLift(inflow, conditions.mach, out Vector3 pTorque, torquePoint); torque += pTorque; } for (int i = ctrls.Count - 1; i >= 0; i--) { if (ctrls[i].part.shieldedFromAirstream) { continue; } aeroForce += ctrls[i].GetLift(inflow, conditions.mach, pitchInput, out Vector3 pTorque, torquePoint); torque += pTorque; } for (int i = partCollections.Count - 1; i >= 0; i--) { aeroForce += partCollections[i].GetLiftForce(inflow, conditions, AoA, pitchInput, out Vector3 pTorque, torquePoint); torque += pTorque; } //float Q = 0.0005f * conditions.atmDensity * conditions.speed * conditions.speed; //torque *= Q; return(aeroForce); // * Q; }
public AoAPoint(AeroPredictor vessel, CelestialBody body, float altitude, float speed, float AoA) { this.altitude = altitude; this.speed = speed; AeroPredictor.Conditions conditions = new AeroPredictor.Conditions(body, speed, altitude); this.AoA = AoA; this.mach = conditions.mach; this.dynamicPressure = 0.0005f * conditions.atmDensity * speed * speed; this.pitchInput = vessel.GetPitchInput(conditions, AoA); this.pitchInput_dry = vessel.GetPitchInput(conditions, AoA, true); Vector3 force = AeroPredictor.ToFlightFrame(vessel.GetAeroForce(conditions, AoA, pitchInput), AoA); torque = vessel.GetAeroTorque(conditions, AoA).x; torque_dry = vessel.GetAeroTorque(conditions, AoA, 0, true).x; Lift = force.y; Drag = -force.z; LDRatio = Mathf.Abs(Lift / Drag); dLift = (vessel.GetLiftForceMagnitude(conditions, AoA + WindTunnelWindow.AoAdelta, pitchInput) - Lift) / (WindTunnelWindow.AoAdelta * Mathf.Rad2Deg); }
private static void GetStabilityValues(AeroPredictor vessel, AeroPredictor.Conditions conditions, float AoA_centre, out float stabilityRange, out float stabilityScore) { const int step = 5; const int range = 90; const int alphaSteps = range / step; float[] torques = new float[2 * alphaSteps + 1]; float[] aoas = new float[2 * alphaSteps + 1]; int start, end; for (int i = 0; i <= 2 * alphaSteps; i++) { aoas[i] = (i - alphaSteps) * step * Mathf.Deg2Rad; torques[i] = vessel.GetAeroTorque(conditions, aoas[i], 0).x; } int eq = 0 + alphaSteps; int dir = (int)Math.Sign(torques[eq]); if (dir == 0) { start = eq - 1; end = eq + 1; } else { while (eq > 0 && eq < 2 * alphaSteps) { eq += dir; if (Math.Sign(torques[eq]) != dir) { break; } } if (eq == 0 || eq == 2 * alphaSteps) { stabilityRange = 0; stabilityScore = 0; return; } if (dir < 0) { start = eq; end = eq + 1; } else { start = eq - 1; end = eq; } } while (torques[start] > 0 && start > 0) { start -= 1; } while (torques[end] < 0 && end < 2 * alphaSteps - 1) { end += 1; } float min = (Mathf.InverseLerp(torques[start], torques[start + 1], 0) + start) * step; float max = (-Mathf.InverseLerp(torques[end], torques[end - 1], 0) + end) * step; stabilityRange = max - min; stabilityScore = 0; for (int i = start; i < end; i++) { stabilityScore += (torques[i] + torques[i + 1]) / 2 * step; } }
public EnvelopePoint(AeroPredictor vessel, CelestialBody body, float altitude, float speed, float AoA_guess = float.NaN, float maxA_guess = float.NaN, float pitchI_guess = float.NaN) { this.altitude = altitude; this.speed = speed; AeroPredictor.Conditions conditions = new AeroPredictor.Conditions(body, speed, altitude); float gravParameter, radius; gravParameter = (float)body.gravParameter; radius = (float)body.Radius; this.mach = conditions.mach; this.dynamicPressure = 0.0005f * conditions.atmDensity * speed * speed; float weight = (vessel.Mass * gravParameter / ((radius + altitude) * (radius + altitude))) - (vessel.Mass * speed * speed / (radius + altitude)); Vector3 thrustForce = vessel.GetThrustForce(conditions); fuelBurnRate = vessel.GetFuelBurnRate(conditions); //AoA_max = vessel.GetMaxAoA(conditions, out Lift_max, maxA_guess); if (float.IsNaN(maxA_guess)) { AoA_max = vessel.GetMaxAoA(conditions, out Lift_max, maxA_guess); //Lift_max = AeroPredictor.GetLiftForceMagnitude(vessel.GetAeroForce(conditions, AoA_max, 1) + thrustForce, AoA_max); } else { AoA_max = maxA_guess; Lift_max = AeroPredictor.GetLiftForceMagnitude(vessel.GetAeroForce(conditions, AoA_max, 1) + thrustForce, AoA_max); } AoA_level = vessel.GetAoA(conditions, weight, guess: AoA_guess, pitchInputGuess: 0, lockPitchInput: true); if (AoA_level < AoA_max) { pitchInput = vessel.GetPitchInput(conditions, AoA_level, guess: pitchI_guess); } else { pitchInput = 1; } if (speed < 5 && Math.Abs(altitude) < 10) { AoA_level = 0; } Thrust_available = thrustForce.magnitude; //vessel.GetAeroCombined(conditions, AoA_level, pitchInput, out force, out Vector3 torque); force = vessel.GetAeroForce(conditions, AoA_level, pitchInput); aeroforce = AeroPredictor.ToFlightFrame(force, AoA_level); //vessel.GetLiftForce(body, speed, altitude, AoA_level, mach, atmDensity); drag = -aeroforce.z; float lift = aeroforce.y; Thrust_excess = -drag - AeroPredictor.GetDragForceMagnitude(thrustForce, AoA_level); if (weight > Lift_max)// AoA_level >= AoA_max) { Thrust_excess = Lift_max - weight; AoA_level = AoA_max; } Accel_excess = (Thrust_excess / vessel.Mass / WindTunnelWindow.gAccel); LDRatio = Math.Abs(lift / drag); dLift = (vessel.GetLiftForceMagnitude(conditions, AoA_level + WindTunnelWindow.AoAdelta, pitchInput) - lift) / (WindTunnelWindow.AoAdelta * Mathf.Rad2Deg); //stabilityDerivative = (vessel.GetAeroTorque(conditions, AoA_level + WindTunnelWindow.AoAdelta, pitchInput).x - torque.x) // / (WindTunnelWindow.AoAdelta * Mathf.Rad2Deg); //GetStabilityValues(vessel, conditions, AoA_level, out stabilityRange, out stabilityScore); completed = true; }
public override Vector3 GetLiftForce(Vector3 inflow, AeroPredictor.Conditions conditions, float pitchInput, out Vector3 torque, Vector3 torquePoint) { Vector3 aeroForce = Vector3.zero; torque = Vector3.zero; int rotationCount = WindTunnelSettings.Instance.rotationCount; float Q = 0.0005f * conditions.atmDensity; // The root part is the rotor hub, so since the rotating mesh is usually cylindrical we // only need to evaluate this part once. if (!parts[0].shieldedFromAirstream) { float localMach = inflow.magnitude; float localVelFactor = localMach * localMach; float localPRDM; lock (PhysicsGlobals.DragCurvePseudoReynolds) localPRDM = PhysicsGlobals.DragCurvePseudoReynolds.Evaluate(conditions.atmDensity * localMach); localMach /= conditions.speedOfSound; aeroForce += parts[0].GetAero(inflow.normalized, localMach, localPRDM, out Vector3 pTorque, origin) * localVelFactor * Q; torque += pTorque * localVelFactor * Q; } for (int r = 0; r < rotationCount; r++) { Quaternion rotation = Quaternion.AngleAxis(360f / rotationCount * r, axis); Vector3 rTorque = Vector3.zero; Vector3 rAeroForce = Vector3.zero; // Rotate inflow Vector3 rotatedInflow = rotation * inflow; // Calculate forces for (int i = parts.Count - 1; i >= 1; i--) { if (parts[i].shieldedFromAirstream) { continue; } //Vector3 partMotion = Vector3.Cross(axis, (parts[i].transformPosition - origin)) * angularVelocity + rotatedInflow; Vector3 partMotion = Vector3.Cross((parts[i].transformPosition - origin), axis) * angularVelocity + rotatedInflow; Vector3 partInflow = partMotion.normalized; float localMach = partMotion.magnitude; float localVelFactor = localMach * localMach; localMach /= conditions.speedOfSound; rAeroForce += parts[i].GetLift(partInflow, localMach, out Vector3 pTorque, torquePoint) * localVelFactor; rTorque += pTorque * localVelFactor; } for (int i = surfaces.Count - 1; i >= 0; i--) { if (surfaces[i].part.shieldedFromAirstream) { continue; } //Vector3 partMotion = Vector3.Cross(axis, (surfaces[i].part.transformPosition + surfaces[i].velocityOffset - origin)) * angularVelocity + rotatedInflow; Vector3 partMotion = Vector3.Cross((surfaces[i].part.transformPosition + surfaces[i].velocityOffset - origin), axis) * angularVelocity + rotatedInflow; Vector3 partInflow = partMotion.normalized; float localMach = partMotion.magnitude; float localVelFactor = localMach * localMach; localMach /= conditions.speedOfSound; rAeroForce += surfaces[i].GetLift(partInflow, localMach, out Vector3 pTorque, torquePoint) * localVelFactor; rTorque += pTorque * localVelFactor; } for (int i = ctrls.Count - 1; i >= 0; i--) { if (ctrls[i].part.shieldedFromAirstream) { continue; } //Vector3 partMotion = Vector3.Cross(axis, (ctrls[i].part.transformPosition + ctrls[i].velocityOffset - origin)) * angularVelocity + rotatedInflow; Vector3 partMotion = Vector3.Cross((ctrls[i].part.transformPosition + ctrls[i].velocityOffset - origin), axis) * angularVelocity + rotatedInflow; Vector3 partInflow = partMotion.normalized; float localMach = partMotion.magnitude; float localVelFactor = localMach * localMach; localMach /= conditions.speedOfSound; rAeroForce += ctrls[i].GetLift(partInflow, localMach, pitchInput, out Vector3 pTorque, torquePoint) * localVelFactor; rTorque += pTorque * localVelFactor; } rTorque *= Q; rAeroForce *= Q; for (int i = partCollections.Count - 1; i >= 0; i--) { //Vector3 partMotion = Vector3.Cross(axis, partCollections[i].origin - this.origin) * angularVelocity; Vector3 partMotion = Vector3.Cross(partCollections[i].origin - this.origin, axis) * angularVelocity; rAeroForce += partCollections[i].GetLiftForce(rotatedInflow + partMotion, conditions, pitchInput, out Vector3 pTorque, torquePoint); rTorque += pTorque; } // Rotate torque backwards rTorque = Quaternion.AngleAxis(-360f / rotationCount * r, axis) * rTorque; torque += rTorque; aeroForce += rAeroForce; } aeroForce /= rotationCount; torque /= rotationCount; torque += Vector3.Cross(aeroForce, origin - torquePoint); return(aeroForce); }
public override Vector3 GetAeroForce(Vector3 inflow, AeroPredictor.Conditions conditions, float pitchInput, out Vector3 torque, Vector3 torquePoint) { Vector3 aeroForce = Vector3.zero; torque = Vector3.zero; int rotationCount = WindTunnelSettings.Instance.rotationCount; float Q = 0.0005f * conditions.atmDensity; // The root part is the rotor hub, so since the rotating mesh is usually cylindrical we // only need to evaluate this part once. if (!parts[0].shieldedFromAirstream) { float localMach = inflow.magnitude; float localVelFactor = localMach * localMach; float localPRDM; lock (PhysicsGlobals.DragCurvePseudoReynolds) localPRDM = PhysicsGlobals.DragCurvePseudoReynolds.Evaluate(conditions.atmDensity * localMach); localMach /= conditions.speedOfSound; aeroForce += parts[0].GetAero(inflow.normalized, localMach, localPRDM, out Vector3 pTorque, origin) * localVelFactor * Q; torque += pTorque * localVelFactor * Q; } for (int r = 0; r < rotationCount; r++) { Quaternion rotation = Quaternion.AngleAxis(360f / rotationCount * r, axis); Vector3 rTorque = Vector3.zero; Vector3 rAeroForce = Vector3.zero; // Rotate inflow Vector3 rotatedInflow = rotation * inflow; // Calculate forces for (int i = parts.Count - 1; i >= 1; i--) { if (parts[i].shieldedFromAirstream) { continue; } Vector3 partMotion = Vector3.Cross(axis, (parts[i].transformPosition - origin)) * angularVelocity + rotatedInflow; //Vector3 partMotion = Vector3.Cross((parts[i].transformPosition - origin), axis) * angularVelocity + rotatedInflow; Vector3 partInflow = partMotion.normalized; float localMach = partMotion.magnitude; float localVelFactor = localMach * localMach; float localPRDM; lock (PhysicsGlobals.DragCurvePseudoReynolds) localPRDM = PhysicsGlobals.DragCurvePseudoReynolds.Evaluate(conditions.atmDensity * localMach); localMach /= conditions.speedOfSound; rAeroForce += parts[i].GetAero(partInflow, localMach, localPRDM, out Vector3 pTorque, origin) * localVelFactor; rTorque += pTorque * localVelFactor; } for (int i = surfaces.Count - 1; i >= 0; i--) { if (surfaces[i].part.shieldedFromAirstream) { continue; } Vector3 partMotion = Vector3.Cross(axis, (surfaces[i].part.transformPosition + surfaces[i].velocityOffset - origin)) * angularVelocity + rotatedInflow; //Vector3 partMotion = Vector3.Cross((surfaces[i].part.transformPosition + surfaces[i].velocityOffset - origin), axis) * angularVelocity + rotatedInflow; Vector3 partInflow = partMotion.normalized; float localMach = partMotion.magnitude; float localVelFactor = localMach * localMach; localMach /= conditions.speedOfSound; rAeroForce += surfaces[i].GetForce(partInflow, localMach, out Vector3 pTorque, origin) * localVelFactor; rTorque += pTorque * localVelFactor; if (conditions.altitude <= 50 && conditions.speed >= 15 && conditions.speed < 25 && Vector3.Angle(inflow, Vector3.forward) < 10) { if (i == surfaces.Count - 1) { Debug.LogFormat("\nAxis {0}\tAngularVelocity {1}\nSpeed {2}\tAltitude {3}", axis, angularVelocity, conditions.speed, conditions.altitude); } Debug.LogFormat("Surface {4}\tInflow {0}\tPartMotion {1}\tTorque {2}\tAeroForce{3}", rotatedInflow, partMotion, Quaternion.AngleAxis(-360f / rotationCount * r, axis) * pTorque, surfaces[i].GetForce(inflow + partMotion, conditions.mach, out _, origin), i); } } for (int i = ctrls.Count - 1; i >= 0; i--) { if (ctrls[i].part.shieldedFromAirstream) { continue; } Vector3 partMotion = Vector3.Cross(axis, (ctrls[i].part.transformPosition + ctrls[i].velocityOffset - origin)) * angularVelocity + rotatedInflow; //Vector3 partMotion = Vector3.Cross((ctrls[i].part.transformPosition + ctrls[i].velocityOffset - origin), axis) * angularVelocity + rotatedInflow; Vector3 partInflow = partMotion.normalized; float localMach = partMotion.magnitude; float localVelFactor = localMach * localMach; float localPRDM; lock (PhysicsGlobals.DragCurvePseudoReynolds) localPRDM = PhysicsGlobals.DragCurvePseudoReynolds.Evaluate(conditions.atmDensity * localMach); localMach /= conditions.speedOfSound; rAeroForce += ctrls[i].GetForce(partInflow, localMach, pitchInput, localPRDM, out Vector3 pTorque, origin) * localVelFactor; rTorque += pTorque * localVelFactor; if (conditions.altitude <= 50 && conditions.speed >= 15 && conditions.speed < 25 && Vector3.Angle(inflow, Vector3.forward) < 10) { if (i == ctrls.Count - 1 && surfaces.Count == 0) { Debug.LogFormat("\nAxis {0}\tAngularVelocity {1}\nSpeed {2}\tAltitude {3}\tRotated Inflow {4}", axis, angularVelocity, conditions.speed, conditions.altitude, rotatedInflow); float surfaceInput = 0; if (!ctrls[i].ignorePitch) { Vector3 input = ctrls[i].inputRotation * new Vector3(!ctrls[i].ignorePitch ? pitchInput : 0, 0, 0); surfaceInput = Vector3.Dot(input, ctrls[i].rotationAxis); surfaceInput *= ctrls[i].authorityLimiter * 0.01f; surfaceInput = Mathf.Clamp(surfaceInput, -1, 1); } if (ctrls[i].deployed) { surfaceInput += ctrls[i].deployAngle; surfaceInput = Mathf.Clamp(surfaceInput, -1.5f, 1.5f); } surfaceInput *= ctrls[i].deflectionDirection; Vector3 relLiftVector; if (surfaceInput != 0) { relLiftVector = Quaternion.AngleAxis(ctrls[i].ctrlSurfaceRange * surfaceInput, ctrls[i].rotationAxis) * ctrls[i].liftVector; } else { relLiftVector = ctrls[i].liftVector; } float dot = Vector3.Dot(partInflow, relLiftVector); float absdot = ctrls[i].omnidirectional ? Math.Abs(dot) : Mathf.Clamp01(dot); Vector3 lift = Vector3.zero; lock (ctrls[i].liftCurve) lift = -relLiftVector *Math.Sign(dot) * ctrls[i].liftCurve.Evaluate(absdot) * ctrls[i].liftMachCurve.Evaluate(localMach) * ctrls[i].deflectionLiftCoeff * PhysicsGlobals.LiftMultiplier; if (ctrls[i].perpendicularOnly) { lift = Vector3.ProjectOnPlane(lift, -partInflow); } Debug.LogFormat("Inflow vector: {3}\tBase lift vector: {0}\tCtrl lift vector: {1}\tDot: {2}\tAoA: {4}", ctrls[i].liftVector, relLiftVector, dot, partInflow, Mathf.Acos(-dot) * Mathf.Rad2Deg); Debug.LogFormat("Lifting surface forces: {0} (without part drag)", lift * 1000 * Q * localVelFactor); } Debug.LogFormat("Ctrl {3}\tPartMotion {0}\tTorque {1}\tAeroForce{2}", partMotion, Quaternion.AngleAxis(-360f / rotationCount * r, axis) * pTorque * Q, ctrls[i].GetForce(inflow + partMotion, conditions.mach, pitchInput, conditions.pseudoReDragMult, out _, origin) * localVelFactor * Q, i); } } rTorque *= Q; rAeroForce *= Q; for (int i = partCollections.Count - 1; i >= 0; i--) { //Vector3 partMotion = Vector3.Cross(axis, (parts[i].transformPosition - origin)) * angularVelocity; Vector3 partMotion = Vector3.Cross((parts[i].transformPosition - origin), axis) * angularVelocity; rAeroForce += partCollections[i].GetAeroForce(rotatedInflow + partMotion, conditions, pitchInput, out Vector3 pTorque, origin); rTorque += pTorque; } // Rotate torque backwards rTorque = Quaternion.AngleAxis(-360f / rotationCount * r, axis) * rTorque; torque += rTorque; aeroForce += rAeroForce; } aeroForce /= rotationCount; torque /= rotationCount; if (conditions.altitude <= 50 && conditions.speed >= 15 && conditions.speed < 25 && Vector3.Angle(inflow, Vector3.forward) < 10) { Debug.LogFormat("Aeroforce {0}\tTorque {1}", aeroForce, torque); } torque += Vector3.Cross(aeroForce, origin - torquePoint); return(aeroForce); }
public virtual void GetAeroCombined(Vector3 inflow, AeroPredictor.Conditions conditions, float AoA, float pitchInput, out Vector3 forces, out Vector3 torques, Vector3 torquePoint) { forces = GetAeroForce(inflow, conditions, AoA, pitchInput, out torques, torquePoint); }
public virtual Vector3 GetAeroTorque(Vector3 inflow, AeroPredictor.Conditions conditions, float AoA, Vector3 torquePoint, float pitchInput = 0) { GetAeroForce(inflow, conditions, AoA, pitchInput, out Vector3 torque, torquePoint); return(torque); }