Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Vehicle/MotorcycleController.h
9912 views
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)1// SPDX-FileCopyrightText: 2023 Jorrit Rouwe2// SPDX-License-Identifier: MIT34#pragma once56#include <Jolt/Physics/Vehicle/WheeledVehicleController.h>78JPH_NAMESPACE_BEGIN910/// Settings of a two wheeled motorcycle (adds a spring to balance the motorcycle)11/// Note: The motor cycle controller is still in development and may need a lot of tweaks/hacks to work properly!12class JPH_EXPORT MotorcycleControllerSettings : public WheeledVehicleControllerSettings13{14JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, MotorcycleControllerSettings)1516public:17// See: VehicleControllerSettings18virtual VehicleController * ConstructController(VehicleConstraint &inConstraint) const override;19virtual void SaveBinaryState(StreamOut &inStream) const override;20virtual void RestoreBinaryState(StreamIn &inStream) override;2122/// How far we're willing to make the bike lean over in turns (in radians)23float mMaxLeanAngle = DegreesToRadians(45.0f);2425/// Spring constant for the lean spring26float mLeanSpringConstant = 5000.0f;2728/// Spring damping constant for the lean spring29float mLeanSpringDamping = 1000.0f;3031/// The lean spring applies an additional force equal to this coefficient * Integral(delta angle, 0, t), this effectively makes the lean spring a PID controller32float mLeanSpringIntegrationCoefficient = 0.0f;3334/// How much to decay the angle integral when the wheels are not touching the floor: new_value = e^(-decay * t) * initial_value35float mLeanSpringIntegrationCoefficientDecay = 4.0f;3637/// How much to smooth the lean angle (0 = no smoothing, 1 = lean angle never changes)38/// Note that this is frame rate dependent because the formula is: smoothing_factor * previous + (1 - smoothing_factor) * current39float mLeanSmoothingFactor = 0.8f;40};4142/// Runtime controller class43class JPH_EXPORT MotorcycleController : public WheeledVehicleController44{45public:46JPH_OVERRIDE_NEW_DELETE4748/// Constructor49MotorcycleController(const MotorcycleControllerSettings &inSettings, VehicleConstraint &inConstraint);5051/// Get the distance between the front and back wheels52float GetWheelBase() const;5354/// Enable or disable the lean spring. This allows you to temporarily disable the lean spring to allow the motorcycle to fall over.55void EnableLeanController(bool inEnable) { mEnableLeanController = inEnable; }5657/// Check if the lean spring is enabled.58bool IsLeanControllerEnabled() const { return mEnableLeanController; }5960/// Enable or disable the lean steering limit. When enabled (default) the steering angle is limited based on the vehicle speed to prevent steering that would cause an inertial force that causes the motorcycle to topple over.61void EnableLeanSteeringLimit(bool inEnable) { mEnableLeanSteeringLimit = inEnable; }62bool IsLeanSteeringLimitEnabled() const { return mEnableLeanSteeringLimit; }6364/// Spring constant for the lean spring65void SetLeanSpringConstant(float inConstant) { mLeanSpringConstant = inConstant; }66float GetLeanSpringConstant() const { return mLeanSpringConstant; }6768/// Spring damping constant for the lean spring69void SetLeanSpringDamping(float inDamping) { mLeanSpringDamping = inDamping; }70float GetLeanSpringDamping() const { return mLeanSpringDamping; }7172/// The lean spring applies an additional force equal to this coefficient * Integral(delta angle, 0, t), this effectively makes the lean spring a PID controller73void SetLeanSpringIntegrationCoefficient(float inCoefficient) { mLeanSpringIntegrationCoefficient = inCoefficient; }74float GetLeanSpringIntegrationCoefficient() const { return mLeanSpringIntegrationCoefficient; }7576/// How much to decay the angle integral when the wheels are not touching the floor: new_value = e^(-decay * t) * initial_value77void SetLeanSpringIntegrationCoefficientDecay(float inDecay) { mLeanSpringIntegrationCoefficientDecay = inDecay; }78float GetLeanSpringIntegrationCoefficientDecay() const { return mLeanSpringIntegrationCoefficientDecay; }7980/// How much to smooth the lean angle (0 = no smoothing, 1 = lean angle never changes)81/// Note that this is frame rate dependent because the formula is: smoothing_factor * previous + (1 - smoothing_factor) * current82void SetLeanSmoothingFactor(float inFactor) { mLeanSmoothingFactor = inFactor; }83float GetLeanSmoothingFactor() const { return mLeanSmoothingFactor; }8485protected:86// See: VehicleController87virtual void PreCollide(float inDeltaTime, PhysicsSystem &inPhysicsSystem) override;88virtual bool SolveLongitudinalAndLateralConstraints(float inDeltaTime) override;89virtual void SaveState(StateRecorder &inStream) const override;90virtual void RestoreState(StateRecorder &inStream) override;91#ifdef JPH_DEBUG_RENDERER92virtual void Draw(DebugRenderer *inRenderer) const override;93#endif // JPH_DEBUG_RENDERER9495// Configuration properties96bool mEnableLeanController = true;97bool mEnableLeanSteeringLimit = true;98float mMaxLeanAngle;99float mLeanSpringConstant;100float mLeanSpringDamping;101float mLeanSpringIntegrationCoefficient;102float mLeanSpringIntegrationCoefficientDecay;103float mLeanSmoothingFactor;104105// Run-time calculated target lean vector106Vec3 mTargetLean = Vec3::sZero();107108// Integrated error for the lean spring109float mLeanSpringIntegratedDeltaAngle = 0.0f;110111// Run-time total angular impulse applied to turn the cycle towards the target lean angle112float mAppliedImpulse = 0.0f;113};114115JPH_NAMESPACE_END116117118