VehicleDifferential.cpp 2.9 KB

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