Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Vehicle/MotorcycleController.h
9912 views
1
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2
// SPDX-FileCopyrightText: 2023 Jorrit Rouwe
3
// SPDX-License-Identifier: MIT
4
5
#pragma once
6
7
#include <Jolt/Physics/Vehicle/WheeledVehicleController.h>
8
9
JPH_NAMESPACE_BEGIN
10
11
/// Settings of a two wheeled motorcycle (adds a spring to balance the motorcycle)
12
/// Note: The motor cycle controller is still in development and may need a lot of tweaks/hacks to work properly!
13
class JPH_EXPORT MotorcycleControllerSettings : public WheeledVehicleControllerSettings
14
{
15
JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, MotorcycleControllerSettings)
16
17
public:
18
// See: VehicleControllerSettings
19
virtual VehicleController * ConstructController(VehicleConstraint &inConstraint) const override;
20
virtual void SaveBinaryState(StreamOut &inStream) const override;
21
virtual void RestoreBinaryState(StreamIn &inStream) override;
22
23
/// How far we're willing to make the bike lean over in turns (in radians)
24
float mMaxLeanAngle = DegreesToRadians(45.0f);
25
26
/// Spring constant for the lean spring
27
float mLeanSpringConstant = 5000.0f;
28
29
/// Spring damping constant for the lean spring
30
float mLeanSpringDamping = 1000.0f;
31
32
/// The lean spring applies an additional force equal to this coefficient * Integral(delta angle, 0, t), this effectively makes the lean spring a PID controller
33
float mLeanSpringIntegrationCoefficient = 0.0f;
34
35
/// How much to decay the angle integral when the wheels are not touching the floor: new_value = e^(-decay * t) * initial_value
36
float mLeanSpringIntegrationCoefficientDecay = 4.0f;
37
38
/// How much to smooth the lean angle (0 = no smoothing, 1 = lean angle never changes)
39
/// Note that this is frame rate dependent because the formula is: smoothing_factor * previous + (1 - smoothing_factor) * current
40
float mLeanSmoothingFactor = 0.8f;
41
};
42
43
/// Runtime controller class
44
class JPH_EXPORT MotorcycleController : public WheeledVehicleController
45
{
46
public:
47
JPH_OVERRIDE_NEW_DELETE
48
49
/// Constructor
50
MotorcycleController(const MotorcycleControllerSettings &inSettings, VehicleConstraint &inConstraint);
51
52
/// Get the distance between the front and back wheels
53
float GetWheelBase() const;
54
55
/// Enable or disable the lean spring. This allows you to temporarily disable the lean spring to allow the motorcycle to fall over.
56
void EnableLeanController(bool inEnable) { mEnableLeanController = inEnable; }
57
58
/// Check if the lean spring is enabled.
59
bool IsLeanControllerEnabled() const { return mEnableLeanController; }
60
61
/// 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.
62
void EnableLeanSteeringLimit(bool inEnable) { mEnableLeanSteeringLimit = inEnable; }
63
bool IsLeanSteeringLimitEnabled() const { return mEnableLeanSteeringLimit; }
64
65
/// Spring constant for the lean spring
66
void SetLeanSpringConstant(float inConstant) { mLeanSpringConstant = inConstant; }
67
float GetLeanSpringConstant() const { return mLeanSpringConstant; }
68
69
/// Spring damping constant for the lean spring
70
void SetLeanSpringDamping(float inDamping) { mLeanSpringDamping = inDamping; }
71
float GetLeanSpringDamping() const { return mLeanSpringDamping; }
72
73
/// The lean spring applies an additional force equal to this coefficient * Integral(delta angle, 0, t), this effectively makes the lean spring a PID controller
74
void SetLeanSpringIntegrationCoefficient(float inCoefficient) { mLeanSpringIntegrationCoefficient = inCoefficient; }
75
float GetLeanSpringIntegrationCoefficient() const { return mLeanSpringIntegrationCoefficient; }
76
77
/// How much to decay the angle integral when the wheels are not touching the floor: new_value = e^(-decay * t) * initial_value
78
void SetLeanSpringIntegrationCoefficientDecay(float inDecay) { mLeanSpringIntegrationCoefficientDecay = inDecay; }
79
float GetLeanSpringIntegrationCoefficientDecay() const { return mLeanSpringIntegrationCoefficientDecay; }
80
81
/// How much to smooth the lean angle (0 = no smoothing, 1 = lean angle never changes)
82
/// Note that this is frame rate dependent because the formula is: smoothing_factor * previous + (1 - smoothing_factor) * current
83
void SetLeanSmoothingFactor(float inFactor) { mLeanSmoothingFactor = inFactor; }
84
float GetLeanSmoothingFactor() const { return mLeanSmoothingFactor; }
85
86
protected:
87
// See: VehicleController
88
virtual void PreCollide(float inDeltaTime, PhysicsSystem &inPhysicsSystem) override;
89
virtual bool SolveLongitudinalAndLateralConstraints(float inDeltaTime) override;
90
virtual void SaveState(StateRecorder &inStream) const override;
91
virtual void RestoreState(StateRecorder &inStream) override;
92
#ifdef JPH_DEBUG_RENDERER
93
virtual void Draw(DebugRenderer *inRenderer) const override;
94
#endif // JPH_DEBUG_RENDERER
95
96
// Configuration properties
97
bool mEnableLeanController = true;
98
bool mEnableLeanSteeringLimit = true;
99
float mMaxLeanAngle;
100
float mLeanSpringConstant;
101
float mLeanSpringDamping;
102
float mLeanSpringIntegrationCoefficient;
103
float mLeanSpringIntegrationCoefficientDecay;
104
float mLeanSmoothingFactor;
105
106
// Run-time calculated target lean vector
107
Vec3 mTargetLean = Vec3::sZero();
108
109
// Integrated error for the lean spring
110
float mLeanSpringIntegratedDeltaAngle = 0.0f;
111
112
// Run-time total angular impulse applied to turn the cycle towards the target lean angle
113
float mAppliedImpulse = 0.0f;
114
};
115
116
JPH_NAMESPACE_END
117
118