UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
SteeringUtility.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreMinimal.h"
7#include "VehicleUtility.h"
8
9#if VEHICLE_DEBUGGING_ENABLED
11#endif
12
13namespace Chaos
14{
16 {
27 static bool IntersectTwoCircles(float R1, float R2, float D, FVector2D& OutIntersection)
28 {
29 OutIntersection.Set(0, 0);
30
31 // no intersection of circumference if radii are too far apart or one circle is completely inside the other
32 if ((D > (R1 + R2)) || (D < (R1 - R2)))
33 {
34 return false;
35 }
36
37 float TwoD = D * 2.0f;
38 float R1Sqr = R1 * R1;
39 float R2Sqr = R2 * R2;
40 float DSqr = D * D;
41
43 OutIntersection.Y = FMath::Sqrt(4.0f * DSqr * R1Sqr - Sqr(DSqr - R2Sqr + R1Sqr)) / TwoD;
44
45 return true;
46 }
47
48 //static void CalculateAkermannAngle(float Input, float& OutSteerLeft, float& OutSteerRight
49 // , FVector2D& OutPtLeft = FVector2D(), FVector2D& OutPtRight = FVector2D())
50 //{
51 // float RestAngle;
52 // FVector2D PtRest;
53 // CalculateAkermannAngle(false, 0.0f, PtRest, RestAngle);
54
55 // CalculateAkermannAngle(true, Input, OutSteerLeft, OutPtLeft);
56 // CalculateAkermannAngle(false, Input, OutSteerRight, OutPtRight);
57
58 // OutSteerLeft -= RestAngle;
59 // OutSteerRight -= RestAngle;
60 //}
61
62 static void CalculateAkermannAngle(bool Flip, float Input, FVector2D& C2, float R1, float R2
64 {
65 if (Flip)
66 {
67 Input = -Input;
68 }
69
70 OutC1.Set(0.0f + Input, 0.0f);
71
72 FVector2D C2RelC1 = C2 - OutC1;
73 float Angle = RadToDeg(FMath::Atan2(C2RelC1.Y, C2RelC1.X));
74
75 // D isn't a fixed value because C1 moves with steering rack
76 float D = C2RelC1.Size();
77
78 FVector2D Intersection;
79 IntersectTwoCircles(R1, R2, D, Intersection);
80 Intersection.Y = -Intersection.Y;
81
82 FVector2D Arm= Intersection.GetRotated(Angle);
83 OutPt = OutC1 + Arm;
84
86 OutSteerAngle = RadToDeg(FMath::Atan2(WheelArm.X, WheelArm.Y));
87 }
88
89 static float CalculateBetaDegrees(float TrackWidth, float WheelBase)
90 {
91 return RadToDeg(FMath::Atan2(TrackWidth*0.5f, WheelBase));
92 }
93 static void AkermannSetup(float T, float Beta, float R, float& OutH, float& OutS)
94 {
95 OutH = R * FMath::Cos(DegToRad(Beta));
96 OutS = T - 2.0f * R * FMath::Sin(DegToRad(Beta));
97 }
98
99 static void CalcJointPositions(float T, float Beta, float R, FVector2D& C1, float& R1, FVector2D& C2, float& R2)
100 {
101 float H = R * FMath::Cos(DegToRad(Beta));
102 float S = T - 2.0f * R * FMath::Sin(DegToRad(Beta));
103
104 C1.Set(0.f, 0.f);
105 C2.Set(T*0.5f, H);
106 R1 = S * 0.5f;
107 R2 = R;
108 }
109
110
111/* static void Akerman(float Input, float& OutSteerA, float& OutSteerB)
112 {
113 float l1 = 2.0f;
114 float l2 = 0.15f;
115 float Gamma = DegToRad(18.0f);
116
117 //FMath::Sin(Gamma - A) + FMath::Sin(Gamma + B);
118
119
120 //float K1 = Sqr(l1 / l2 - 2.0f * FMath::Sin(Gamma));
121
122 //float PartSum = K1 - Sqr(FMath::Cos(Gamma - A) - FMath::Cos(Gamma - B));
124 //float Gamma = DegToRad(18.0f);
125
126
127 float t = 2.0f; // width between wheels
128 float r = 0.15f; // track length
129 float h = r * FMath::Cos(Gamma); // track depth
130 float s = t - 2.0f * r * FMath::Sin(Gamma);
131
132 float Beta = FMath::Atan((t - s) / (2.0f * h));
133
134 float dev = Input * 0.5f;
135 OutSteerA = RadToDeg(FMath::Atan((t - (s - dev)) / (2.0f * h)));
136 OutSteerB = RadToDeg(FMath::Atan((t - (s + dev)) / (2.0f * h)));
137
138 if (Input < 0.f)
139 {
140 OutSteerA = -OutSteerA;
141 OutSteerB = -OutSteerB;
142 }
143 //for (float dev = 0.0f; dev < 0.3f; dev += 0.02f)
144 //{
145 // float BetaA = FMath::Atan((t - (s - dev)) / (2.0f * h));
146 // float BetaB = FMath::Atan((t - (s + dev)) / (2.0f * h));
147
148 // float BetaADeg = RadToDeg(BetaA);
149 // float BetaBDeg = RadToDeg(BetaB);
150
151 // UE_LOG(LogChaos, Warning, TEXT("%f %f"), BetaADeg - 18.0f, BetaBDeg - 18.0f);
152 //}
153 }
154 */
155 };
156
157}
158
159#if VEHICLE_DEBUGGING_ENABLED
161#endif
#define UE_ENABLE_OPTIMIZATION
Definition CoreMiscDefines.h:60
#define UE_DISABLE_OPTIMIZATION
Definition CoreMiscDefines.h:59
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
Definition SkeletalMeshComponent.h:307
FORCEINLINE float RadToDeg(float InRad)
Definition VehicleUtility.h:282
FORCEINLINE float Sqr(float Val)
Definition VehicleUtility.h:287
FORCEINLINE float DegToRad(float InDeg)
Definition VehicleUtility.h:277
Definition SteeringUtility.h:16
static float CalculateBetaDegrees(float TrackWidth, float WheelBase)
Definition SteeringUtility.h:89
static bool IntersectTwoCircles(float R1, float R2, float D, FVector2D &OutIntersection)
Definition SteeringUtility.h:27
static void CalcJointPositions(float T, float Beta, float R, FVector2D &C1, float &R1, FVector2D &C2, float &R2)
Definition SteeringUtility.h:99
static void CalculateAkermannAngle(bool Flip, float Input, FVector2D &C2, float R1, float R2, float &OutSteerAngle, FVector2D &OutC1, FVector2D &OutPt)
Definition SteeringUtility.h:62
static void AkermannSetup(float T, float Beta, float R, float &OutH, float &OutS)
Definition SteeringUtility.h:93
void Set(T InX, T InY)
Definition Vector2D.h:1074
TVector2< T > GetRotated(T AngleDeg) const
Definition Vector2D.h:1129
T Y
Definition Vector2D.h:52