VehicleDifferential.cpp 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #include <Jolt/Jolt.h>
  4. #include <Jolt/Physics/Vehicle/VehicleDifferential.h>
  5. #include <Jolt/ObjectStream/TypeDeclarations.h>
  6. JPH_NAMESPACE_BEGIN
  7. JPH_IMPLEMENT_SERIALIZABLE_NON_VIRTUAL(VehicleDifferentialSettings)
  8. {
  9. JPH_ADD_ATTRIBUTE(VehicleDifferentialSettings, mLeftWheel)
  10. JPH_ADD_ATTRIBUTE(VehicleDifferentialSettings, mRightWheel)
  11. JPH_ADD_ATTRIBUTE(VehicleDifferentialSettings, mDifferentialRatio)
  12. JPH_ADD_ATTRIBUTE(VehicleDifferentialSettings, mLeftRightSplit)
  13. JPH_ADD_ATTRIBUTE(VehicleDifferentialSettings, mLimitedSlipRatio)
  14. JPH_ADD_ATTRIBUTE(VehicleDifferentialSettings, mEngineTorqueRatio)
  15. }
  16. void VehicleDifferentialSettings::SaveBinaryState(StreamOut &inStream) const
  17. {
  18. inStream.Write(mLeftWheel);
  19. inStream.Write(mRightWheel);
  20. inStream.Write(mDifferentialRatio);
  21. inStream.Write(mLeftRightSplit);
  22. inStream.Write(mLimitedSlipRatio);
  23. inStream.Write(mEngineTorqueRatio);
  24. }
  25. void VehicleDifferentialSettings::RestoreBinaryState(StreamIn &inStream)
  26. {
  27. inStream.Read(mLeftWheel);
  28. inStream.Read(mRightWheel);
  29. inStream.Read(mDifferentialRatio);
  30. inStream.Read(mLeftRightSplit);
  31. inStream.Read(mLimitedSlipRatio);
  32. inStream.Read(mEngineTorqueRatio);
  33. }
  34. void VehicleDifferentialSettings::CalculateTorqueRatio(float inLeftAngularVelocity, float inRightAngularVelocity, float &outLeftTorqueFraction, float &outRightTorqueFraction) const
  35. {
  36. // Start with the default torque ratio
  37. outLeftTorqueFraction = 1.0f - mLeftRightSplit;
  38. outRightTorqueFraction = mLeftRightSplit;
  39. if (mLimitedSlipRatio < FLT_MAX)
  40. {
  41. JPH_ASSERT(mLimitedSlipRatio > 1.0f);
  42. // This is a limited slip differential, adjust torque ratios according to wheel speeds
  43. float omega_l = max(1.0e-3f, abs(inLeftAngularVelocity)); // prevent div by zero by setting a minimum velocity and ignoring that the wheels may be rotating in different directions
  44. float omega_r = max(1.0e-3f, abs(inRightAngularVelocity));
  45. float omega_min = min(omega_l, omega_r);
  46. float omega_max = max(omega_l, omega_r);
  47. // Map into a value that is 0 when the wheels are turning at an equal rate and 1 when the wheels are turning at mLimitedSlipRotationRatio
  48. float alpha = min((omega_max / omega_min - 1.0f) / (mLimitedSlipRatio - 1.0f), 1.0f);
  49. JPH_ASSERT(alpha >= 0.0f);
  50. float one_min_alpha = 1.0f - alpha;
  51. if (omega_l < omega_r)
  52. {
  53. // Redirect more power to the left wheel
  54. outLeftTorqueFraction = outLeftTorqueFraction * one_min_alpha + alpha;
  55. outRightTorqueFraction = outRightTorqueFraction * one_min_alpha;
  56. }
  57. else
  58. {
  59. // Redirect more power to the right wheel
  60. outLeftTorqueFraction = outLeftTorqueFraction * one_min_alpha;
  61. outRightTorqueFraction = outRightTorqueFraction * one_min_alpha + alpha;
  62. }
  63. }
  64. // Assert the values add up to 1
  65. JPH_ASSERT(abs(outLeftTorqueFraction + outRightTorqueFraction - 1.0f) < 1.0e-6f);
  66. }
  67. JPH_NAMESPACE_END