/// <summary> /// the suspension of a single wheel /// </summary> /// <param name="wheel">the wheel for which the suspension is</param> public WheelSuspension(ImportantClasses.Enums.Wheels wheel) { BellCrank = new BellCrank(); Damper = new Damper(); PushRod = new PushRod(); WheelHub = new WheelHub(); Wishbone = new Wishbone(); Wheel = wheel; _actualCalculation = new SuspensionOutput(); }
/// <summary> /// calculates a single wheel /// </summary> public void Calculate() { SuspensionOutput suspensionCalculation = SuspensionOutput.GetLastCalculation(_wheel); //get the outputs of the suspension for this wheel //calculates the half width of the car, so that it is not needed to calculate a couple of times float halfTrackWidth = CalculationController.Instance.OverallCar.TrackWidth / 2; //force = torque/radius of a wheel _actualCalculation.LongitudinalAccelerationForce = suspensionCalculation.AccelerationTorque / (CalculationController.Instance.Wheels.Diameter / 2); if ((int)_wheel < 2) //front axis { _actualCalculation.LongitudinalDecelerationForce = BrakeOutput.LastCalculation.BrakeMomentFront / 2; } else //rear axis { _actualCalculation.LongitudinalDecelerationForce = BrakeOutput.LastCalculation.BrakeMomentRear / 2; } //calculate the drivingRadius and the lateral acceleration float drivingRadius; //the radius which the wheel will take in a curve if (suspensionCalculation.WheelAngle < 0) //drive right { drivingRadius = ((int)_wheel < 2 ? SteeringOutput.LastCalculation.RadiusFrontAxis : SteeringOutput.LastCalculation.RadiusRearAxis) + (((int)_wheel) % 2 == 0 ? halfTrackWidth : -halfTrackWidth); _actualCalculation.LateralAcceleration = OverallCarOutput.LastCalculation.Speed * OverallCarOutput.LastCalculation.Speed / drivingRadius; } else if (suspensionCalculation.WheelAngle > 0) //drive left { drivingRadius = ((int)_wheel < 2 ? SteeringOutput.LastCalculation.RadiusFrontAxis : SteeringOutput.LastCalculation.RadiusRearAxis) + (((int)_wheel) % 2 == 0 ? -halfTrackWidth : halfTrackWidth); _actualCalculation.LateralAcceleration = -OverallCarOutput.LastCalculation.Speed * OverallCarOutput.LastCalculation.Speed / drivingRadius; } else //drive straight ahead { _actualCalculation.LateralAcceleration = 0; } //calculate the direction in which the wheel would like to drive _actualCalculation.Direction = ((Vector2)OverallCarOutput.LastCalculation.Direction).Rotate(suspensionCalculation.WheelAngle); _actualCalculation.Slip = 0; //actually the calculation is not ready; the slip is allways zero and the maximum force is infinity if (OnCalculationReady != null) { OnCalculationReady(); } }
public void TestSuspension() { _suspension.Calculate(); _suspension.StoreResult(); Assert.AreEqual(SuspensionOutput.GetLastCalculation(Wheels.FrontLeft).AccelerationTorque, 0); Assert.AreEqual(SuspensionOutput.GetLastCalculation(Wheels.FrontLeft).WheelAngle, Math.PI / 4, 1e-5); Assert.AreEqual(SuspensionOutput.GetLastCalculation(Wheels.FrontLeft).WheelLoad, 50 * 9.81f, 1e-5); Assert.AreEqual(SuspensionOutput.GetLastCalculation(Wheels.FrontRight).AccelerationTorque, 0); Assert.AreEqual(SuspensionOutput.GetLastCalculation(Wheels.FrontRight).WheelAngle, Math.PI / 5, 1e-5); Assert.AreEqual(SuspensionOutput.GetLastCalculation(Wheels.FrontRight).WheelLoad, 50 * 9.81f, 1e-5); Assert.AreEqual(SuspensionOutput.GetLastCalculation(Wheels.RearLeft).AccelerationTorque, 50); Assert.AreEqual(SuspensionOutput.GetLastCalculation(Wheels.RearLeft).WheelAngle, 0, 1e-5); Assert.AreEqual(SuspensionOutput.GetLastCalculation(Wheels.RearLeft).WheelLoad, 50 * 9.81f, 1e-5); Assert.AreEqual(SuspensionOutput.GetLastCalculation(Wheels.RearRight).AccelerationTorque, 50); Assert.AreEqual(SuspensionOutput.GetLastCalculation(Wheels.RearRight).WheelAngle, 0, 1e-5); Assert.AreEqual(SuspensionOutput.GetLastCalculation(Wheels.RearRight).WheelLoad, 50 * 9.81f, 1e-5); }
public void Init() { _wheels = new Wheels(); SuspensionOutput sout0 = new SuspensionOutput(); sout0.AccelerationTorque = 0; sout0.WheelAngle = (float)Math.PI / 4; sout0.WheelLoad = 50 * 9.81f; SuspensionOutput sout1 = new SuspensionOutput(); sout1.AccelerationTorque = 0; sout1.WheelAngle = (float)Math.PI / 5; sout1.WheelLoad = 50 * 9.81f; SuspensionOutput sout2 = new SuspensionOutput(); sout2.AccelerationTorque = 50; sout2.WheelAngle = 0; sout2.WheelLoad = 50 * 9.81f; SuspensionOutput sout3 = new SuspensionOutput(); sout3.AccelerationTorque = 50; sout3.WheelAngle = 0; sout3.WheelLoad = 50 * 9.81f; SuspensionOutput.LastCalculations[0] = sout0; SuspensionOutput.LastCalculations[1] = sout1; SuspensionOutput.LastCalculations[2] = sout2; SuspensionOutput.LastCalculations[3] = sout3; SteeringOutput.LastCalculation.RadiusFrontAxis = 10; SteeringOutput.LastCalculation.RadiusRearAxis = 10; CalculationController.Instance.Wheels.Diameter = 0.5f; CalculationController.Instance.OverallCar.TrackWidth = 1.5f; CalculationController.Initialize(1); BrakeOutput.LastCalculation.BrakeMomentFront = 10; BrakeOutput.LastCalculation.BrakeMomentRear = 10; OverallCarOutput.LastCalculation.Speed = 10; OverallCarOutput.LastCalculation.Direction = new Vector3(1, 0, 0); }
/// <summary> /// stores the calculation results to the SuspensionOutput class /// </summary> public void StoreResult() { SuspensionOutput.SetLastCalculation(Wheel, _actualCalculation); }