WheeledVehicleController.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #pragma once
  4. #include <Physics/Vehicle/VehicleConstraint.h>
  5. #include <Physics/Vehicle/VehicleController.h>
  6. #include <Physics/Vehicle/VehicleEngine.h>
  7. #include <Physics/Vehicle/VehicleTransmission.h>
  8. #include <Physics/Vehicle/VehicleDifferential.h>
  9. #include <Core/LinearCurve.h>
  10. namespace JPH {
  11. class PhysicsSystem;
  12. /// WheelSettings object specifically for WheeledVehicleController
  13. class WheelSettingsWV : public WheelSettings
  14. {
  15. public:
  16. JPH_DECLARE_SERIALIZABLE_VIRTUAL(WheelSettingsWV)
  17. /// Constructor
  18. WheelSettingsWV();
  19. // See: WheelSettings
  20. virtual void SaveBinaryState(StreamOut &inStream) const override;
  21. virtual void RestoreBinaryState(StreamIn &inStream) override;
  22. float mInertia = 0.9f; ///< Moment of inertia (kg m^2), for a cylinder this would be 0.5 * M * R^2 which is 0.9 for a wheel with a mass of 20 kg and radius 0.3 m
  23. float mAngularDamping = 0.2f; ///< Angular damping factor of the wheel: dw/dt = -c * w
  24. float mMaxSteerAngle = DegreesToRadians(70.0f); ///< How much this wheel can steer (radians)
  25. LinearCurve mLongitudinalFriction; ///< Friction in forward direction of tire as a function of the slip ratio (fraction): (omega_wheel * r_wheel - v_longitudinal) / |v_longitudinal|
  26. LinearCurve mLateralFriction; ///< Friction in sideway direction of tire as a function of the slip angle (degrees): angle between relative contact velocity and vehicle direction
  27. float mMaxBrakeTorque = 1500.0f; ///< How much torque (Nm) the brakes can apply to this wheel
  28. float mMaxHandBrakeTorque = 4000.0f; ///< How much torque (Nm) the hand brake can apply to this wheel (usually only applied to the rear wheels)
  29. };
  30. /// Wheel object specifically for WheeledVehicleController
  31. class WheelWV : public Wheel
  32. {
  33. public:
  34. /// Constructor
  35. explicit WheelWV(const WheelSettingsWV &inWheel);
  36. /// Override GetSettings and cast to the correct class
  37. const WheelSettingsWV * GetSettings() const { return static_cast<const WheelSettingsWV *>(mSettings.GetPtr()); }
  38. /// Apply a torque (N m) to the wheel for a particular delta time
  39. void ApplyTorque(float inTorque, float inDeltaTime)
  40. {
  41. mAngularVelocity += inTorque * inDeltaTime / GetSettings()->mInertia;
  42. }
  43. /// Update the wheel rotation based on the current angular velocity
  44. void Update(float inDeltaTime, const VehicleConstraint &inConstraint);
  45. float mCombinedLongitudinalFriction = 0.0f; ///< Combined friction coefficient in longitudinal direction (combines terrain and tires)
  46. float mCombinedLateralFriction = 0.0f; ///< Combined friction coefficient in lateral direction (combines terrain and tires)
  47. float mBrakeImpulse = 0.0f; ///< Amount of impulse that the brakes can apply to the floor (excluding friction)
  48. };
  49. /// Settings of a vehicle with regular wheels
  50. ///
  51. /// The properties in this controller are largely based on "Car Physics for Games" by Marco Monster.
  52. /// See: https://www.asawicki.info/Mirror/Car%20Physics%20for%20Games/Car%20Physics%20for%20Games.html
  53. class WheeledVehicleControllerSettings : public VehicleControllerSettings
  54. {
  55. public:
  56. JPH_DECLARE_SERIALIZABLE_VIRTUAL(WheeledVehicleControllerSettings)
  57. // See: VehicleControllerSettings
  58. virtual VehicleController * ConstructController(VehicleConstraint &inConstraint) const override;
  59. virtual void SaveBinaryState(StreamOut &inStream) const override;
  60. virtual void RestoreBinaryState(StreamIn &inStream) override;
  61. VehicleEngineSettings mEngine; ///< The properties of the engine
  62. VehicleTransmissionSettings mTransmission; ///< The properties of the transmission (aka gear box)
  63. vector<VehicleDifferentialSettings> mDifferentials; ///< List of differentials and their properties
  64. };
  65. /// Runtime controller class
  66. class WheeledVehicleController : public VehicleController
  67. {
  68. public:
  69. /// Constructor
  70. WheeledVehicleController(const WheeledVehicleControllerSettings &inSettings, VehicleConstraint &inConstraint);
  71. /// Typedefs
  72. using Differentials = vector<VehicleDifferentialSettings>;
  73. /// Set input from driver
  74. /// @param inForward Value between -1 and 1 for auto transmission and value between 0 and 1 indicating desired driving direction and amount the gas pedal is pressed
  75. /// @param inRight Value between -1 and 1 indicating desired steering angle (1 = right)
  76. /// @param inBrake Value between 0 and 1 indicating how strong the brake pedal is pressed
  77. /// @param inHandBrake Value between 0 and 1 indicating how strong the hand brake is pulled
  78. void SetDriverInput(float inForward, float inRight, float inBrake, float inHandBrake) { mForwardInput = inForward; mRightInput = inRight; mBrakeInput = inBrake; mHandBrakeInput = inHandBrake; }
  79. /// Get current engine state
  80. const VehicleEngine & GetEngine() const { return mEngine; }
  81. /// Get current engine state (writable interface, allows you to make changes to the configuration which will take effect the next time step)
  82. VehicleEngine & GetEngine() { return mEngine; }
  83. /// Get current transmission state
  84. const VehicleTransmission & GetTransmission() const { return mTransmission; }
  85. /// Get current transmission state (writable interface, allows you to make changes to the configuration which will take effect the next time step)
  86. VehicleTransmission & GetTransmission() { return mTransmission; }
  87. /// Get the differentials this vehicle has
  88. const Differentials & GetDifferentials() const { return mDifferentials; }
  89. /// Get the differentials this vehicle has (writable interface, allows you to make changes to the configuration which will take effect the next time step)
  90. Differentials & GetDifferentials() { return mDifferentials; }
  91. #ifdef JPH_DEBUG_RENDERER
  92. /// Debug drawing of RPM meter
  93. void SetRPMMeter(Vec3Arg inPosition, float inSize) { mRPMMeterPosition = inPosition; mRPMMeterSize = inSize; }
  94. #endif // JPH_DEBUG_RENDERER
  95. protected:
  96. // See: VehicleController
  97. virtual Wheel * ConstructWheel(const WheelSettings &inWheel) const override { JPH_ASSERT(IsKindOf(&inWheel, JPH_RTTI(WheelSettingsWV))); return new WheelWV(static_cast<const WheelSettingsWV &>(inWheel)); }
  98. virtual void PreCollide(float inDeltaTime, PhysicsSystem &inPhysicsSystem) override;
  99. virtual void PostCollide(float inDeltaTime, PhysicsSystem &inPhysicsSystem) override;
  100. virtual bool SolveLongitudinalAndLateralConstraints(float inDeltaTime) override;
  101. virtual void SaveState(StateRecorder &inStream) const override;
  102. virtual void RestoreState(StateRecorder &inStream) override;
  103. #ifdef JPH_DEBUG_RENDERER
  104. virtual void Draw(DebugRenderer *inRenderer) const override;
  105. #endif // JPH_DEBUG_RENDERER
  106. // Control information
  107. float mForwardInput = 0.0f; ///< Value between -1 and 1 for auto transmission and value between 0 and 1 indicating desired driving direction and amount the gas pedal is pressed
  108. float mRightInput = 0.0f; ///< Value between -1 and 1 indicating desired steering angle
  109. float mBrakeInput = 0.0f; ///< Value between 0 and 1 indicating how strong the brake pedal is pressed
  110. float mHandBrakeInput = 0.0f; ///< Value between 0 and 1 indicating how strong the hand brake is pulled
  111. // Simluation information
  112. VehicleEngine mEngine; ///< Engine state of the vehicle
  113. VehicleTransmission mTransmission; ///< Transmission state of the vehicle
  114. Differentials mDifferentials; ///< Differential states of the vehicle
  115. #ifdef JPH_DEBUG_RENDERER
  116. // Debug settings
  117. Vec3 mRPMMeterPosition { 0, 1, 0 }; ///< Position (in local space of the body) of the RPM meter when drawing the constraint
  118. float mRPMMeterSize = 0.5f; ///< Size of the RPM meter when drawing the constraint
  119. #endif // JPH_DEBUG_RENDERER
  120. };
  121. } // JPH