23#include <util/ue-header-guard-begin.h>
24#include "Components/BoxComponent.h"
25#include "Components/LightComponent.h"
26#include "Components/StaticMeshComponent.h"
27#include "Engine/CollisionProfile.h"
28#include "UObject/UnrealType.h"
30#include "Rendering/SkeletalMeshRenderData.h"
31#include "VehicleAnimationInstance.h"
32#include "UObject/UObjectGlobals.h"
33#include "DrawDebugHelpers.h"
34#include "Kismet/KismetSystemLibrary.h"
35#include "PhysicsEngine/PhysicsObjectExternalInterface.h"
36#include "Physics/Experimental/PhysScene_Chaos.h"
37#include <util/ue-header-guard-end.h>
51 const FTransform ComponentToWorld = Mesh->GetComponentTransform();
52 const int32 NumBones = FMath::Min(Pose.LocalTransforms.Num(), Mesh->GetNumBones());
53 for (int32 BoneIndex = 0; BoneIndex < NumBones; ++BoneIndex)
55 Pose.LocalTransforms[BoneIndex] = Mesh->GetBoneTransform(BoneIndex, ComponentToWorld);
61 FString ROSMessage = Message;
62 UE_LOG(LogCarla, Warning, TEXT(
"ROS2 Message received: %s"), *ROSMessage);
66 Super(ObjectInitializer)
68 VehicleBounds = CreateDefaultSubobject<UBoxComponent>(TEXT(
"VehicleBounds"));
71 VehicleBounds->SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName);
74 VelocityControl = CreateDefaultSubobject<UVehicleVelocityControl>(TEXT(
"VelocityControl"));
77 AccelerationControl = CreateDefaultSubobject<UVehicleAccelerationControl>(TEXT(
"AccelerationControl"));
81 BaseMovementComponent = CreateDefaultSubobject<UBaseCarlaMovementComponent>(TEXT(
"BaseMovementComponent"));
96 FTransform ActorInverseTransform = GetActorTransform().Inverse();
102 UPhysicsConstraintComponent* ConstraintComponent =
103 Cast<UPhysicsConstraintComponent>(GetDefaultSubobjectByName(ComponentName));
104 if (ConstraintComponent)
106 UPrimitiveComponent* DoorComponent = Cast<UPrimitiveComponent>(
107 GetDefaultSubobjectByName(ConstraintComponent->ComponentName1.ComponentName));
110 UE_LOG(LogCarla, Log, TEXT(
"Door name: %s"), *(DoorComponent->GetName()));
111 FTransform ComponentWorldTransform = DoorComponent->GetComponentTransform();
112 FTransform RelativeTransform = ComponentWorldTransform * ActorInverseTransform;
116 ConstraintComponent->TermComponentConstraint();
120 UE_LOG(LogCarla, Error, TEXT(
"Missing component for constraint: %s"), *(ConstraintComponent->GetName()));
126 TArray<UPhysicsConstraintComponent*> Constraints;
127 GetComponents(Constraints);
128 for (UPhysicsConstraintComponent* Constraint : Constraints)
134 Constraint->TermComponentConstraint();
135 UPrimitiveComponent* CollisionDisabledComponent1 = Cast<UPrimitiveComponent>(
136 GetDefaultSubobjectByName(Constraint->ComponentName1.ComponentName));
137 UPrimitiveComponent* CollisionDisabledComponent2 = Cast<UPrimitiveComponent>(
138 GetDefaultSubobjectByName(Constraint->ComponentName2.ComponentName));
139 if (CollisionDisabledComponent1)
143 if (CollisionDisabledComponent2)
153 if (MovementComponent)
155 check(MovementComponent !=
nullptr);
163 MovementComponent->SteeringInputRate.InputCurveFunction = EInputFunctionType::LinearFunction;
166 TArray<FChaosWheelSetup> NewWheelSetups = MovementComponent->WheelSetups;
167 for (
const FChaosWheelSetup& WheelSetup : NewWheelSetups)
169 UChaosVehicleWheel* Wheel = WheelSetup.WheelClass.GetDefaultObject();
170 check(Wheel !=
nullptr);
173 MovementComponent->WheelSetups = NewWheelSetups;
190 TEXT(
"carla.Light.VehicleBeamIntensityScale"),
192 TEXT(
"Multiplier converting the authored UE4-era intensity of vehicle low/high beam ")
193 TEXT(
"light components (and the blueprint's 'Beam Lights' group variable) to UE5 ")
194 TEXT(
"photometric units. Set 1 to leave them untouched."),
215 TArray<ULightComponent*> LightComponents;
216 GetComponents<ULightComponent>(LightComponents);
217 for (ULightComponent* LightComponent : LightComponents)
219 if (!LightComponent->IsActive())
221 LightComponent->SetActive(
true);
223 const FString Name = LightComponent->GetName();
224 if (BeamScale != 1.0f &&
225 (Name.Contains(TEXT(
"low_beam")) || Name.Contains(TEXT(
"high_beam"))) &&
226 LightComponent->Intensity > 0.0f && LightComponent->Intensity < 1000.0f)
228 LightComponent->SetIntensity(LightComponent->Intensity * BeamScale);
232 if (BeamScale != 1.0f)
234 for (TFieldIterator<FFloatProperty> PropIt(GetClass()); PropIt; ++PropIt)
236 FFloatProperty* Property = *PropIt;
237 if (Property->GetAuthoredName() != TEXT(
"Beam Lights"))
241 float* ValuePtr = Property->ContainerPtrToValuePtr<
float>(
this);
242 if (ValuePtr !=
nullptr && *ValuePtr > 0.0f && *ValuePtr < 1000.0f)
244 *ValuePtr *= BeamScale;
245 UE_LOG(LogCarla, Verbose, TEXT(
"%s: scaled blueprint 'Beam Lights' to %f"),
246 *GetName(), *ValuePtr);
269 const FString ClassName = GetClass()->GetName();
282 TMap<FString, bool> GroupOn;
294 TMap<FString, float> MaterialGroupValue;
295 for (
const TPair<FString, bool>& Pair : GroupOn)
306 TInlineComponentArray<ULightComponent*> AuthoredLights(
this);
307 for (ULightComponent* Light : AuthoredLights)
309 bool bControlled =
false;
310 bool bEnabled =
false;
311 for (
const TPair<FString, bool>& Pair : GroupOn)
313 if (Light->ComponentHasTag(FName(*(FString(TEXT(
"Carla.Light.")) + Pair.Key))))
316 bEnabled |= Pair.Value;
320 Light->SetVisibility(bEnabled);
343 UE_LOG(LogCarla, Warning,
344 TEXT(
"%s: IsTwoWheeledVehicle is true but rider component '%s' or seat socket '%s' could not be resolved -- rider seat-lock disabled."),
361 RiderMeshComponent->DetachFromComponent(FDetachmentTransformRules::KeepWorldTransform);
386 FOnBoneTransformsFinalizedMultiCast::FDelegate::CreateUObject(
436 if (
const UWorld* World = GetWorld())
480 else if (
const UWorld* World = GetWorld())
482 const float FrameDeltaTime = World->GetDeltaSeconds();
485 SmoothedTranslation.Z = FMath::FInterpTo(
492 const FRotator NewSmoothedRotator(
511 Super::TickActor(DeltaTime, TickType, ThisTickFunction);
515 if (ActorHasTag(TEXT(
"Carla.ModularWheelCalipers")))
518 if (Movement && Movement->PhysicsVehicleOutput())
520 static const FName CaliperTags[] = {TEXT(
"Carla.Caliper.0"), TEXT(
"Carla.Caliper.1"),
521 TEXT(
"Carla.Caliper.2"), TEXT(
"Carla.Caliper.3")};
522 TInlineComponentArray<UStaticMeshComponent*> Components(
this);
523 for (UStaticMeshComponent* Component : Components)
525 for (int32 Index = 0; Index < UE_ARRAY_COUNT(CaliperTags) && Index < Movement->WheelSetups.Num() && Index < Movement->Wheels.Num(); ++Index)
527 if (Component->ComponentHasTag(CaliperTags[Index]))
529 const FQuat Rotation = GetMesh()->GetComponentQuat() *
530 FRotator(0.0f, Movement->Wheels[Index]->GetSteerAngle(), 0.0f).Quaternion();
531 Component->SetWorldLocationAndRotation(
532 GetMesh()->GetSocketLocation(Movement->WheelSetups[Index].BoneName), Rotation);
562 GetMesh()->SnapshotPose(pose);
578 const FTransform GlobalTransform = GetActorTransform();
580 FBox Box = FBox(-Vec, Vec);
581 const FTransform NonScaledTransform(GlobalTransform.GetRotation(), GlobalTransform.GetLocation(), { 1.0f, 1.0f, 1.0f });
606 const FQuat& Rotation = GetActorQuat();
607 DrawDebugBox(GetWorld(), Center, Extent, Rotation, FColor::Magenta,
false, 0.0f, 0, 5.0f);
625 const FTransform& CompToWorldTransform = RootComponent->GetComponentTransform();
626 const FRotator Rotation = CompToWorldTransform.GetRotation().Rotator();
627 const FVector Translation = CompToWorldTransform.GetLocation();
628 const FVector Scale = CompToWorldTransform.GetScale3D();
636 FTransform Transform;
690 if (MovementComponent !=
nullptr && MovementComponent->Wheels.Num() > 0 &&
691 MovementComponent->Wheels[0] !=
nullptr)
693 return MovementComponent->Wheels[0]->MaxSteerAngle;
695 if (MovementComponent !=
nullptr && MovementComponent->WheelSetups.Num() > 0 &&
696 MovementComponent->WheelSetups[0].WheelClass !=
nullptr)
698 const UChaosVehicleWheel* FrontWheel =
699 Cast<UChaosVehicleWheel>(MovementComponent->WheelSetups[0].WheelClass->GetDefaultObject());
700 if (FrontWheel !=
nullptr)
702 return FrontWheel->MaxSteerAngle;
708 UE_LOG(LogCarla, Warning, TEXT(
"%s: no wheel setups, returning default max steer angle"), *GetName());
772 TArray<float> WheelsFrictionScale;
776 check(Movement !=
nullptr);
778 for (
auto& Wheel : Movement->Wheels)
780 WheelsFrictionScale.Add(Wheel->FrictionForceMultiplier);
784 return WheelsFrictionScale;
794 const int32 Count = FMath::Min(Movement->Wheels.Num(), WheelsFrictionScale.Num());
795 for (int32 i = 0; i < Count; ++i)
797 Movement->SetWheelFrictionMultiplier(i, WheelsFrictionScale[i]);
798 Movement->Wheels[i]->FrictionForceMultiplier = WheelsFrictionScale[i];
811 check(VehicleMovComponentPtr !=
nullptr);
812 auto& VehicleMovComponent = *VehicleMovComponentPtr;
813 auto& EngineSetup = VehicleMovComponent.EngineSetup;
814 auto RCurve = EngineSetup.TorqueCurve.GetRichCurve();
815 check(RCurve !=
nullptr);
823 auto& DifferentialSetup = VehicleMovComponent.DifferentialSetup;
824 PhysicsControl.DifferentialType = (uint8_t)DifferentialSetup.DifferentialType;
826 auto& TransmissionSetup = VehicleMovComponent.TransmissionSetup;
827 PhysicsControl.bUseAutomaticGears = TransmissionSetup.bUseAutomaticGears;
830 PhysicsControl.ForwardGearRatios = TransmissionSetup.ForwardGearRatios;
831 PhysicsControl.ReverseGearRatios = TransmissionSetup.ReverseGearRatios;
834 PhysicsControl.TransmissionEfficiency = TransmissionSetup.TransmissionEfficiency;
836 PhysicsControl.DragCoefficient = VehicleMovComponent.DragCoefficient;
840 PhysicsControl.DownforceCoefficient = VehicleMovComponent.DownforceCoefficient;
842 PhysicsControl.InertiaTensorScale = VehicleMovComponent.InertiaTensorScale;
843 PhysicsControl.SleepThreshold = VehicleMovComponent.SleepThreshold;
844 PhysicsControl.SleepSlopeLimit = VehicleMovComponent.SleepSlopeLimit;
845 RCurve = VehicleMovComponent.SteeringSetup.SteeringCurve.GetRichCurve();
846 check(RCurve !=
nullptr);
854 PhysicsControl.Wheels.SetNum(VehicleMovComponent.WheelSetups.Num());
857 const UChaosVehicleWheel* InPtr =
nullptr;
858 if (VehicleMovComponent.Wheels.IsValidIndex(i))
860 InPtr = VehicleMovComponent.Wheels[i];
862 else if (
auto WheelClass = VehicleMovComponent.WheelSetups[i].WheelClass)
864 InPtr = WheelClass->GetDefaultObject<UChaosVehicleWheel>();
866 if (InPtr ==
nullptr)
872 Out.AxleType = In.AxleType;
873 Out.Offset = In.Offset;
874 Out.WheelRadius = In.WheelRadius;
875 Out.WheelWidth = In.WheelWidth;
876 Out.WheelMass = In.WheelMass;
877 Out.CorneringStiffness = In.CorneringStiffness;
878 Out.FrictionForceMultiplier = In.FrictionForceMultiplier;
879 Out.SideSlipModifier = In.SideSlipModifier;
880 Out.SlipThreshold = In.SlipThreshold;
881 Out.SkidThreshold = In.SkidThreshold;
882 Out.MaxSteerAngle = In.MaxSteerAngle;
883 Out.bAffectedBySteering = In.bAffectedBySteering;
884 Out.bAffectedByBrake = In.bAffectedByBrake;
885 Out.bAffectedByHandbrake = In.bAffectedByHandbrake;
886 Out.bAffectedByEngine = In.bAffectedByEngine;
887 Out.bABSEnabled = In.bABSEnabled;
888 Out.bTractionControlEnabled = In.bTractionControlEnabled;
889 Out.MaxWheelspinRotation = In.MaxWheelspinRotation;
890 Out.ExternalTorqueCombineMethod = In.ExternalTorqueCombineMethod;
891 auto SlipCurve = In.LateralSlipGraph.GetRichCurveConst();
892 check(SlipCurve !=
nullptr);
893 Out.LateralSlipGraph = *SlipCurve;
894 Out.SuspensionAxis = In.SuspensionAxis;
895 Out.SuspensionForceOffset = In.SuspensionForceOffset;
896 Out.SuspensionMaxRaise = In.SuspensionMaxRaise;
897 Out.SuspensionMaxDrop = In.SuspensionMaxDrop;
898 Out.SuspensionDampingRatio = In.SuspensionDampingRatio;
899 Out.WheelLoadRatio = In.WheelLoadRatio;
900 Out.SpringRate = In.SpringRate;
901 Out.SpringPreload = In.SpringPreload;
902 Out.SuspensionSmoothing = In.SuspensionSmoothing;
903 Out.RollbarScaling = In.RollbarScaling;
904 Out.SweepShape = In.SweepShape;
905 Out.SweepType = In.SweepType;
906 Out.MaxBrakeTorque = In.MaxBrakeTorque;
907 Out.MaxHandBrakeTorque = In.MaxHandBrakeTorque;
908 Out.WheelIndex = In.WheelIndex;
909 Out.Location = In.Location;
910 Out.OldLocation = In.OldLocation;
911 Out.Velocity = In.Velocity;
914 if (In.SweepShape == ESweepShape::Spherecast)
922 if (VehicleMovComponent.bEnableCenterOfMassOverride)
924 return VehicleMovComponent.CenterOfMassOverride;
927 auto PrimitiveComponentPtr = Cast<UPrimitiveComponent>(VehicleMovComponent.UpdatedComponent);
928 check(PrimitiveComponentPtr !=
nullptr);
929 auto& PrimitiveComponent = *PrimitiveComponentPtr;
930 return PrimitiveComponent.BodyInstance.COMNudge;
949 check(VehicleMovComponentPtr !=
nullptr);
950 auto& VehicleMovComponent = *VehicleMovComponentPtr;
951 auto& EngineSetup = VehicleMovComponent.EngineSetup;
952 EngineSetup.TorqueCurve.EditorCurveData =
PhysicsControl.TorqueCurve;
959 auto& DifferentialSetup = VehicleMovComponent.DifferentialSetup;
960 DifferentialSetup.DifferentialType = (EVehicleDifferential)
PhysicsControl.DifferentialType;
962 auto& TransmissionSetup = VehicleMovComponent.TransmissionSetup;
963 TransmissionSetup.bUseAutomaticGears =
PhysicsControl.bUseAutomaticGears;
966 TransmissionSetup.ForwardGearRatios =
PhysicsControl.ForwardGearRatios;
967 TransmissionSetup.ReverseGearRatios =
PhysicsControl.ReverseGearRatios;
970 TransmissionSetup.TransmissionEfficiency =
PhysicsControl.TransmissionEfficiency;
972 VehicleMovComponent.DragCoefficient =
PhysicsControl.DragCoefficient;
976 VehicleMovComponent.DownforceCoefficient =
PhysicsControl.DownforceCoefficient;
978 VehicleMovComponent.InertiaTensorScale =
PhysicsControl.InertiaTensorScale;
979 VehicleMovComponent.SleepThreshold =
PhysicsControl.SleepThreshold;
980 VehicleMovComponent.SleepSlopeLimit =
PhysicsControl.SleepSlopeLimit;
981 auto& SteeringSetup = VehicleMovComponent.SteeringSetup;
982 SteeringSetup.SteeringCurve.EditorCurveData =
PhysicsControl.SteeringCurve;
985 VehicleMovComponent.RecreatePhysicsState();
990 if (Recorder && Recorder->IsEnabled())
992 Recorder->AddPhysicsControl(*
this);
1002 if (Movement ==
nullptr)
1007 const int32 WheelCount = WheelControls.Num();
1008 if (WheelCount == 0)
1012 if (WheelCount != Movement->WheelSetups.Num())
1014 UE_LOG(LogCarla, Error,
1015 TEXT(
"%s: %d WheelPhysicsControl for %d wheels, skipping wheel setup"),
1016 *GetName(), WheelCount, Movement->WheelSetups.Num());
1022 if (Movement->Wheels.Num() < WheelCount)
1024 UE_LOG(LogCarla, Warning,
1025 TEXT(
"ApplyVehiclePhysicsControl: wheels not initialized yet on %s, skipping wheel setup"),
1030 for (int32 i = 0; i < WheelCount; ++i)
1033 UChaosVehicleWheel* OutPtr = Movement->Wheels[i];
1034 check(OutPtr !=
nullptr);
1035 UChaosVehicleWheel& Out = *OutPtr;
1071 ESweepShape::Spherecast :
1072 ESweepShape::Raycast;
1079 if (VehicleMovComponent.bEnableCenterOfMassOverride)
1081 VehicleMovComponent.CenterOfMassOverride =
PhysicsControl.CenterOfMass;
1084 auto PrimitiveComponentPtr = Cast<UPrimitiveComponent>(VehicleMovComponent.UpdatedComponent);
1085 check(PrimitiveComponentPtr !=
nullptr);
1086 auto& PrimitiveComponent = *PrimitiveComponentPtr;
1087 PrimitiveComponent.BodyInstance.COMNudge =
PhysicsControl.CenterOfMass;
1142 const FVector AccelerationCmps2(LongitudinalAccelerationMps2 * 100.0f, 0.0f, 0.0f);
1154 check(VehicleMovComponent !=
nullptr);
1164 TelemetryData.EngineRPM = VehicleMovComponent->GetEngineRotationSpeed();
1173 const int32 WheelCount = VehicleMovComponent->Wheels.Num();
1174 TelemetryData.Wheels.Reserve(WheelCount);
1175 for (int32 i = 0; i < WheelCount; ++i)
1181 const auto &Wheel = VehicleMovComponent->Wheels[i];
1184 TelemetryData.Wheels.Add(WheelData);
1188 const FWheelStatus &WheelStatus = VehicleMovComponent->GetWheelState(i);
1190 WheelData.
LatSlip = FMath::RadiansToDegrees(WheelStatus.SlipAngle);
1191 WheelData.LongSlip = WheelStatus.SlipMagnitude;
1192 WheelData.Omega = Wheel->GetWheelAngularVelocity();
1194 TelemetryData.Wheels.Add(WheelData);
1197 return TelemetryData;
1202 if (GetWorld()->GetFirstPlayerController())
1204 ACarlaHUD* hud = Cast<ACarlaHUD>(GetWorld()->GetFirstPlayerController()->GetHUD());
1220 UE_LOG(LogCarla, Warning, TEXT(
"ACarlaWheeledVehicle::ShowDebugTelemetry:: Cannot find HUD for debug info"));
1270 const auto *VehicleAnim = Cast<UCarlaVehicleAnimationInstance>(Mesh.GetAnimInstance());
1271 const FWheelAnimationData *Pose = VehicleAnim !=
nullptr ? VehicleAnim->GetWheelPose(WheelIndex) :
nullptr;
1272 return Pose !=
nullptr ? *Pose : FWheelAnimationData{NAME_None, FRotator::ZeroRotator, FVector::ZeroVector};
1279 Pose->RotOffset.Yaw = AngleInDeg;
1288 const int32 WheelIndex =
static_cast<int32
>(WheelLocation);
1296 Pose->RotOffset.Pitch = AngleInDeg;
1302 const int32 WheelIndex =
static_cast<int32
>(WheelLocation);
1317 const int32 WheelIndex =
static_cast<int32
>(WheelLocation);
1318 if (!
HasWheelOrWarn(WheelIndex, TEXT(
"GetWheelSuspensionOffset")))
1329 UE_LOG(LogCarla, Warning,
1330 TEXT(
"SetWheelAnimationOverride: the animation blueprint of %s does not derive from CarlaVehicleAnimationInstance."),
1352 const TCHAR *Caller)
1354 const int32 WheelIndex =
static_cast<int32
>(WheelLocation);
1361 UE_LOG(LogCarla, Warning,
1362 TEXT(
"%s: the wheel animation override is off on %s; enable it first."),
1363 Caller, *GetName());
1378 const FRotator Rotation(Wheel->GetRotationAngle(), Wheel->GetSteerAngle(), 0.0f);
1380 return FWheelAnimationData{NAME_None, Rotation, Offset};
1387 const auto *VehicleAnim = Cast<UCarlaVehicleAnimationInstance>(GetMesh()->GetAnimInstance());
1388 if (
const FWheelAnimationData *Pose = VehicleAnim !=
nullptr ? VehicleAnim->GetWheelPose(WheelIndex) :
nullptr)
1397 TArray<FWheelAnimationData> Poses;
1398 for (int32 i = 0;
HasWheel(i); ++i)
1408 if (Movement ==
nullptr)
1413 TUniquePtr<FPhysicsVehicleOutput> &Output = Movement->PhysicsVehicleOutput();
1414 if (!Output.IsValid() || Output->Wheels.Num() != Poses.Num())
1418 FWheeledSnaphotData Snapshot;
1419 Movement->GetBaseSnapshot(Snapshot);
1420 TArray<float> Spins;
1421 const float ForwardSpeed = FVector::DotProduct(Snapshot.LinearVelocity, GetActorForwardVector());
1422 for (int32 i = 0; i < Poses.Num(); ++i)
1425 const FWheelAnimationData &Pose = Poses[i];
1427 FWheelSnapshot &Wheel = Snapshot.WheelSnapshots.AddDefaulted_GetRef();
1428 Wheel.WheelRotationAngle = Pose.RotOffset.Pitch;
1429 Wheel.SteeringAngle = Pose.RotOffset.Yaw;
1431 Wheel.WheelRadius = Radius;
1432 Wheel.WheelAngularVelocity = Radius > UE_KINDA_SMALL_NUMBER ? ForwardSpeed / Radius : 0.0f;
1434 Output->Wheels[i].AngularPosition = FMath::DegreesToRadians(-Wheel.WheelRotationAngle);
1435 Spins.Add(Wheel.WheelRotationAngle);
1437 Movement->SetSnapshot(Snapshot);
1444 FPhysScene *Scene = GetWorld() !=
nullptr ? GetWorld()->GetPhysicsScene() :
nullptr;
1445 if (Scene ==
nullptr)
1457 FPhysScene *Scene = GetWorld() !=
nullptr ? GetWorld()->GetPhysicsScene() :
nullptr;
1458 if (Scene !=
nullptr)
1481 if (Movement !=
nullptr)
1483 TUniquePtr<FPhysicsVehicleOutput> &Output = Movement->PhysicsVehicleOutput();
1488 Output->Wheels[i].AngularPosition = FMath::DegreesToRadians(-
PendingSeedSpins[i]);
1501 UE_LOG(LogCarla, Warning,
1502 TEXT(
"%s: wheel location %d does not exist on %s."),
1503 Caller, WheelIndex, *GetName());
1512 return Movement !=
nullptr && Movement->WheelSetups.IsValidIndex(WheelIndex);
1517 return Cast<UCarlaVehicleAnimationInstance>(GetMesh()->GetAnimInstance()) !=
nullptr;
1525 !Movement->Wheels.IsValidIndex(WheelIndex))
1531 const UChaosVehicleWheel *Wheel = Movement->Wheels[WheelIndex];
1532 const TUniquePtr<FPhysicsVehicleOutput> &VehicleOutput = Movement->PhysicsVehicleOutput();
1533 if (Wheel ==
nullptr || !VehicleOutput.IsValid() ||
1534 !VehicleOutput->Wheels.IsValidIndex(Wheel->WheelIndex))
1554 return Wheel !=
nullptr ? Wheel->WheelRadius : 0.0f;
1564 return Wheel !=
nullptr ? Wheel->SuspensionAxis.GetSafeNormal() : FVector::DownVector;
1571 if (Movement ==
nullptr || !Movement->WheelSetups.IsValidIndex(WheelIndex))
1575 return Movement->WheelSetups[WheelIndex].WheelClass.GetDefaultObject();
1579 if (!GetCarlaMovementComponent<UDefaultMovementComponent>())
1587 check(Movement !=
nullptr);
1593 const TArray<FWheelAnimationData> ShownPoses =
GetWheelPoses();
1595 SetActorEnableCollision(
true);
1596 UPrimitiveComponent* RootPrimitive =
1597 Cast<UPrimitiveComponent>(GetRootComponent());
1598 RootPrimitive->SetSimulatePhysics(enabled);
1599 RootPrimitive->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
1603 Movement->SetUpdatedComponent(GetMesh());
1604 Movement->RecreatePhysicsState();
1609 RootPrimitive->WakeAllRigidBodies();
1614 Movement->DestroyPhysicsState();
1661 Super::EndPlay(EndPlayReason);
1667 UE_LOG(LogTemp, Warning, TEXT(
"This door is not configured for this car."));
1684 UE_LOG(LogTemp, Warning, TEXT(
"This door is not configured for this car."));
1703 DoorComponent->DetachFromComponent(
1704 FDetachmentTransformRules(EDetachmentRule::KeepWorld,
false));
1705 FTransform DoorInitialTransform =
1707 DoorComponent->SetWorldTransform(DoorInitialTransform);
1708 DoorComponent->SetSimulatePhysics(
true);
1709 DoorComponent->SetCollisionProfileName(TEXT(
"BlockAll"));
1710 float AngleLimit = Constraint->ConstraintInstance.GetAngularSwing1Limit();
1711 FRotator AngularRotationOffset = Constraint->ConstraintInstance.AngularRotationOffset;
1713 if (Constraint->ConstraintInstance.AngularRotationOffset.Yaw < 0.0f)
1715 AngleLimit = -AngleLimit;
1717 Constraint->SetAngularOrientationTarget(FRotator(0, AngleLimit, 0));
1720 Constraint->InitComponentConstraint();
1722 UPhysicsConstraintComponent** CollisionDisable =
1724 if (CollisionDisable)
1726 (*CollisionDisable)->InitComponentConstraint();
1738 Constraint->TermComponentConstraint();
1741 (*CollisionDisable)->TermComponentConstraint();
1743 FTransform DoorInitialTransform =
1745 DoorComponent->SetSimulatePhysics(
false);
1746 DoorComponent->SetCollisionProfileName(TEXT(
"NoCollision"));
1747 DoorComponent->SetWorldTransform(DoorInitialTransform);
1748 DoorComponent->AttachToComponent(
1749 GetMesh(), FAttachmentTransformRules(EAttachmentRule::KeepWorld,
true));
1755 TArray<TPair<int32, FTransform>> Poses;
1756 const FTransform ActorInverseTransform = GetActorTransform().Inverse();
1761 if ((Door !=
nullptr) && (*Door !=
nullptr) && ((*Door)->GetAttachParent() ==
nullptr))
1763 Poses.Emplace(i, (*Door)->GetComponentTransform() * ActorInverseTransform);
1771 const FTransform ActorTransform = GetActorTransform();
1775 UPrimitiveComponent* Door = (DoorPtr !=
nullptr) ? *DoorPtr :
nullptr;
1776 if (Door ==
nullptr)
1780 const TPair<int32, FTransform>* Open =
1781 OpenDoors.FindByPredicate([i](
const TPair<int32, FTransform>& Pose) {
return Pose.Key == i; });
1782 const bool bShownOpen = (Door->GetAttachParent() ==
nullptr);
1783 if (Open !=
nullptr)
1787 Door->DetachFromComponent(FDetachmentTransformRules(EDetachmentRule::KeepWorld,
false));
1789 Door->SetCollisionProfileName(TEXT(
"BlockAll"));
1791 Door->SetWorldTransform(Open->Value * ActorTransform);
1793 else if (bShownOpen)
1796 Door->SetCollisionProfileName(TEXT(
"NoCollision"));
1798 Door->AttachToComponent(GetMesh(), FAttachmentTransformRules(EAttachmentRule::KeepWorld,
true));
1806 if (Recorder && Recorder->IsEnabled())
1808 Recorder->AddVehicleDoor(*
this, DoorIdx, bIsOpen);
1819 case 0:
CheckRollover(roll, std::make_pair(130.0, 230.0));
break;
1820 case 1:
CheckRollover(roll, std::make_pair(140.0, 220.0));
break;
1821 case 2:
CheckRollover(roll, std::make_pair(150.0, 210.0));
break;
1822 case 3:
CheckRollover(roll, std::make_pair(160.0, 200.0));
break;
1840 if (threshold_roll.first < roll && roll < threshold_roll.second) {
1841 auto Root = Cast<UPrimitiveComponent>(GetRootComponent());
1842 auto AngularVelocity = Root->GetPhysicsAngularVelocityInDegrees();
1861 const UObject* World = GetWorld();
1862 TArray<AActor*> ActorsInLevel;
1863 UGameplayStatics::GetAllActorsOfClass(World, AActor::StaticClass(), ActorsInLevel);
1864 for (
AActor* Actor : ActorsInLevel)
1876 const UObject* World = GetWorld();
1877 TArray<AActor*> ActorsInLevel;
1878 UGameplayStatics::GetAllActorsOfClass(World, AActor::StaticClass(), ActorsInLevel);
1879 for (
AActor* Actor : ActorsInLevel)
1890 UPhysicsConstraintComponent* Component)
1892 return Component->ConstraintInstance.AngularRotationOffset;
1896 UPhysicsConstraintComponent* Component,
const FRotator& NewAngle)
1898 Component->ConstraintInstance.AngularRotationOffset = NewAngle;
1905 SetActorTickEnabled(
true);
FVector CarlaGetActorAngularVelocityInRadians(const AActor &Actor)
Angular velocity of Actor in the world frame, in rad/s: on a Multi-GPU secondary the primary's (a mir...
static FWheelAnimationData GetShownWheelPose(const USkeletalMeshComponent &Mesh, int32 WheelIndex)
static TAutoConsoleVariable< float > CVarCarlaVehicleBeamIntensityScale(TEXT("carla.Light.VehicleBeamIntensityScale"), 100000.0f, TEXT("photometric units. Set 1 to leave them untouched."), ECVF_Default)
static void MakePoseWorldSpace(USkeletalMeshComponent *Mesh, FPoseSnapshot &Pose)
EVehicleDoor
Type of door to open/close.
static bool IsValid(const ACarlaWheeledVehicle *Vehicle)
void AddDebugVehicleForTelemetry(UChaosWheeledVehicleMovementComponent *NewDebugVehiclePtr)
UChaosWheeledVehicleMovementComponent * DebugVehicle
FVector GetVehicleBoundingBoxExtent() const
Extent of the vehicle's bounding box.
TObjectPtr< UVehicleVelocityControl > VelocityControl
void SetWheelsFrictionScale(TArray< float > &WheelsFrictionScale)
FBoxSphereBounds GetBoxSphereBounds() const
void ApplyVehicleLightDefaultsForCurrentState()
void RecordDoorChange(const EVehicleDoor DoorIdx, const bool bIsOpen)
FVehicleLightState LightState
void ArmSeedRewrite(TArray< float > Spins)
The next physics pre-tick copies in the output of the step before the seed, so the seeded spins are w...
bool HasWheelOrWarn(int32 WheelIndex, const TCHAR *Caller) const
void RestoreVehiclePhysicsControl()
void CloseDoorPhys(const EVehicleDoor DoorIdx)
FName VehicleMeshSeatSocketName
FDelegateHandle SeedPreTickHandle
float GetWheelRadius(int32 WheelIndex) const
Radius of the wheel at WheelIndex, in cm, as last applied through the physics control.
FVector CachedVehicleWorldAngularVelocityDegrees
FTransform CachedVehicleMeshTransform
bool IsTwoWheeledVehicle()
void AddReferenceToManager()
FVehicleLightState GetVehicleLightState() const
void SetMirroredMotion(const FVector &Velocity, float ForwardSpeed)
Multi-GPU secondary: the primary's motion of the vehicle this one mirrors (world frame,...
void SetThrottleInput(float Value)
int RolloverBehaviorTracker
carla::rpc::VehicleFailureState GetFailureState() const
virtual void TickActor(float DeltaTime, enum ELevelTick TickType, FActorTickFunction &ThisTickFunction) override
void RefreshLightState(const FVehicleLightState &VehicleLightState)
FPoseSnapshot WorldTransformedPose
void SetWheelSuspensionOffset(EVehicleWheelLocation WheelLocation, float OffsetInCm)
Suspension compression of a wheel, in cm.
void SetReverse(bool Value)
void ActivateAccelerationControl(const FVector &Acceleration)
TMap< UPrimitiveComponent *, UPhysicsConstraintComponent * > CollisionDisableConstraints
float RolloverBehaviorForce
bool HasCarlaVehicleAnimation() const
Whether the animation blueprint derives from UCarlaVehicleAnimationInstance, which is what draws the ...
bool IsSimulatedByChaos() const
Whether the Chaos vehicle simulation is moving this vehicle.
const TArray< int32 > GetFoliageInstancesCloseToVehicle(const UInstancedStaticMeshComponent *Component) const
float GetWheelSteerAngle(EVehicleWheelLocation WheelLocation)
void ApplyVehicleAccelerationControl(float LongitudinalAccelerationMps2, float Steer, float SteerSpeed)
Apply control from Autoware /control/command/control_cmd (acceleration [m/s^2] + steering)
void SetCenterOfMass(UChaosWheeledVehicleMovementComponent &VehicleMovComponent, const FVehiclePhysicsControl &PhysicsControl)
bool IsInVehicleRange(const FVector &Location) const
bool bRiderComponentsResolved
void SetCarlaMovementComponent(UBaseCarlaMovementComponent *MoementComponent)
float GetWheelPitchAngle(EVehicleWheelLocation WheelLocation)
FVector GetVehicleOrientation() const
Orientation vector of the vehicle, pointing forward.
virtual void BeginPlay() override
float GetMaximumSteerAngle() const
Get the maximum angle at which the front wheel can steer.
EVehicleInputPriority Priority
void ApplyVehiclePhysicsControl(const FVehiclePhysicsControl &PhysicsControl)
FVehiclePhysicsControl GetVehiclePhysicsControl() const
TArray< float > GetWheelsFrictionScale()
FVehicleControl LastAppliedControl
void SetFailureState(const carla::rpc::VehicleFailureState &FailureState)
FVehicleTelemetryData GetVehicleTelemetryData() const
Returns a snapshot of the vehicle's runtime telemetry: forward speed, last applied control inputs,...
static void SetPhysicsConstraintAngle(UPhysicsConstraintComponent *Component, const FRotator &NewAngle)
void SetVehicleLightState(const FVehicleLightState &LightState)
void CheckRollover(const float roll, const std::pair< float, float > threshold_roll)
UChaosWheeledVehicleMovementComponent * GetChaosWheeledVehicleMovementComponent() const
Get chaos wheeled vehicle movement component casted.
float MirroredForwardSpeed
TArray< UPhysicsConstraintComponent * > ConstraintsComponents
TObjectPtr< UVehicleAccelerationControl > AccelerationControl
int32 GetVehicleCurrentGear() const
Active gear of the vehicle.
float CachedVehicleTransformsTimeSeconds
TArray< FWheelAnimationData > OverriddenWheelPoses
FVehicleAckermannControl LastAppliedAckermannControl
void SeedChaosWheels(const TArray< FWheelAnimationData > &Poses)
Sets the Chaos wheels to these poses, so that they do not jump when Chaos takes over the wheels again...
FDelegateHandle SeedPostTickHandle
struct ACarlaWheeledVehicle::@1 InputControl
float RiderSeatSmoothingSpeed
Chaos suspension has small, real, high-frequency vertical jitter on the vehicle mesh every frame (vis...
void SetMirroredDoorPoses(const TArray< TPair< int32, FTransform > > &OpenDoors)
Multi-GPU secondary: shows these doors open, at these poses relative to the vehicle,...
FWheelAnimationData * GetOverriddenWheelPoseOrWarn(EVehicleWheelLocation WheelLocation, const TCHAR *Caller)
The overridden pose for a setter to write, or nullptr, with a warning, if it cannot be set.
FVehiclePhysicsControl LastPhysicsControl
void OnSeedPostTick(FChaosScene *Scene)
static FRotator GetPhysicsConstraintAngle(UPhysicsConstraintComponent *Component)
float GetWheelSuspensionOffset(EVehicleWheelLocation WheelLocation)
FWheelAnimationData GetWheelPose(int32 WheelIndex) const
The pose shown for a wheel: the overridden one, otherwise Chaos's, otherwise the one last drawn.
float GetVehicleForwardSpeed() const
Forward speed in cm/s. Might be negative if goes backwards.
TArray< float > PendingSeedSpins
Degrees, as drawn.
void SetWheelAnimationOverride(bool bEnabled)
While the wheel animation is overridden the wheels show only the values set through the wheel setters...
void SetBrakeInput(float Value)
FVector GetWheelSuspensionAxis(int32 WheelIndex) const
Unit vector, component space, along which the wheel's suspension drops.
void CloseDoor(const EVehicleDoor DoorIdx)
FRotator RiderSeatRelativeRotationOffset
The rider mesh's rest pose isn't authored to sit flush with the socket's own local axes โ its compone...
TObjectPtr< UBoxComponent > VehicleBounds
void ActivateVehicleLightComponents()
Some vehicle Blueprints (Tesla, Mustang, DodgeCharger, ...) author real Spot/Point light components f...
TMap< UPhysicsConstraintComponent *, UPrimitiveComponent * > ConstraintDoor
void OnSeedPreTick(FPhysScene_Chaos *Scene, float DeltaSeconds)
void SetSimulatePhysics(bool enabled)
FTimerHandle TimerHandler
void ResolveRiderComponentsIfNeeded()
void ApplyVehicleAckermannControl(const FVehicleAckermannControl &AckermannControl, EVehicleInputPriority Priority)
void DeactivateVelocityControl()
void ClearMirroredMotion()
TMap< UPrimitiveComponent *, FTransform > DoorComponentsTransform
TObjectPtr< USkeletalMeshComponent > RiderMeshComponent
virtual FVector GetVelocity() const override
FBox GetDetectionBox() const
void SetSteeringInput(float Value)
void ShowDebugTelemetry(bool Enabled)
TMap< FName, FTransform > CachedVehicleSocketTransforms
void ApplyRolloverBehavior()
Rollovers tend to have too much angular velocity, resulting in the vehicle doing a full 360ยบ flip.
UBaseCarlaMovementComponent * BaseMovementComponent
FTransform GetVehicleTransform() const
Transform of the vehicle.
TArray< FName > ConstraintComponentNames
FTransform GetCachedVehicleSocketWorldTransform(FName SocketName) const
Cached, extrapolated world transform of ANY socket on the vehicle mesh (Seat, HandlerLeftSocket,...
float PedalRotationDegreesPerCm
Degrees the pedal bone rotates per centimeter of real vehicle travel (see GetPedalRotation).
void ActivateVelocityControl(const FVector &Velocity)
void DrawFoliageBoundingBox() const
void UpdateDetectionBox()
void DeactivateAccelerationControl()
void FlushVehicleControl()
void ApplyVehicleControl(const FVehicleControl &Control, EVehicleInputPriority Priority)
bool bHasSavedVehicleLightDefault
FWheelAnimationData GetDrawnWheelPose(int32 WheelIndex) const
Wheel pose the animation instance drew this frame (else GetWheelPose); what secondaries must draw.
TObjectPtr< USkeletalMeshComponent > VehicleMeshForRiderSeat
ACarlaWheeledVehicle(const FObjectInitializer &ObjectInitializer)
FVector GetCenterOfMass(UChaosWheeledVehicleMovementComponent &VehicleMovComponent) const
void OpenDoor(const EVehicleDoor DoorIdx)
carla::rpc::VehicleFailureState FailureState
FTransform SmoothedVehicleMeshTransform
void OnRiderBoneTransformsFinalized()
void OpenDoorPhys(const EVehicleDoor DoorIdx)
float GetDetectionSize() const
FVector CachedVehicleWorldVelocity
bool bWheelAnimationOverridden
void AdjustVehicleBounds()
void SetWheelSteerDirection(EVehicleWheelLocation WheelLocation, float AngleInDeg)
Set the rotation of the car wheels indicated by the user 0 = FL_VehicleWheel, 1 = FR_VehicleWheel,...
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason)
bool HasWheel(int32 WheelIndex) const
bool bAckermannControlActive
float SavedVehicleLightIntensity
TArray< FWheelAnimationData > GetWheelPoses() const
GetWheelPose for every wheel.
bool bSmoothedVehicleMeshTransformInitialized
FPoseSnapshot GetWorldTransformedPose()
FTransform GetVehicleBoundingBoxTransform() const
Transform of the vehicle's bounding box relative to the vehicle.
void ApplyWheelPhysicsControl()
Applies LastPhysicsControl.Wheels to the live Chaos wheels.
const UChaosVehicleWheel * GetWheelDefaults(int32 WheelIndex) const
void SetHandbrakeInput(bool Value)
const UChaosVehicleWheel * GetSimulatedWheel(int32 WheelIndex) const
The Chaos wheel, while Chaos simulates the vehicle and has output for it.
void RemoveReferenceToManager()
void SetWheelPitchAngle(EVehicleWheelLocation WheelLocation, float AngleInDeg)
Spin angle of a wheel, in degrees. Purely visual, wheel animation override only.
TMap< FString, float > SavedVehicleLightGroupIntensity
FAckermannController AckermannController
void PrintROS2Message(const char *Message)
FName RiderMeshComponentName
Two-wheeled vehicles (bikes/motorcycles) embed their rider as a SkeletalMeshComponent (named RiderMes...
TArray< TPair< int32, FTransform > > GetOpenDoorPoses() const
Every door open now (a physics body of its own while open), by door index, with its pose relative to ...
FTransform LocalToGlobalTransform(const FTransform &InTransform) const
void AddVehicle(ACarlaWheeledVehicle *Vehicle)
void RemoveVehicle(ACarlaWheeledVehicle *Vehicle)
void UpdateVehicleState(const ACarlaWheeledVehicle *Vehicle)
void RunLoop(FVehicleControl &Control)
void SetTargetPoint(const FVehicleAckermannControl &AckermannControl)
void UpdateVehiclePhysics(const ACarlaWheeledVehicle *Vehicle)
virtual void ProcessControl(FVehicleControl &Control)
virtual int32 GetVehicleCurrentGear() const
virtual float GetVehicleForwardSpeed() const
virtual FVector GetVelocity() const
static FBoundingBox GetVehicleBoundingBox(const ACarlaWheeledVehicle *Vehicle, uint8 InTagQueried=0xFF)
static ALargeMapManager * GetLargeMapManager(const UObject *WorldContextObject)
static ACarlaRecorder * GetRecorder(const UObject *WorldContextObject)
static void CreateDefaultMovementComponent(ACarlaWheeledVehicle *Vehicle)
static void ApplyVehicleLightsRuntimeState(AActor *Actor, const TMap< FString, float > &MaterialGroupValue, const TMap< FString, float > &RealLightGroupIntensity)
static bool LoadVehicleLightDefault(const FString &ClassName, UPARAM(ref) float &OutIntensity, UPARAM(ref) TMap< FString, float > &OutGroupIntensity)
bool UseSweepWheelCollision
TArray< FWheelPhysicsControl > Wheels
ETorqueCombineMethod ExternalTorqueCombineMethod
Determines how the SetDriveTorque/SetBrakeTorque inputs are combined with the internal torques.
bool bAffectedByHandbrake
Whether handbrake should affect this wheel.
float MaxHandBrakeTorque
Max handbrake brake torque for this wheel (Nm).
bool bABSEnabled
Advanced Braking System Enabled.
bool bTractionControlEnabled
Straight Line Traction Control Enabled.
float WheelRadius
Radius of the wheel.
bool bAffectedByEngine
Whether engine should power this wheel.
float FrictionForceMultiplier
Friction Force Multiplier.
bool bAffectedByBrake
Whether brake should affect this wheel.
float MaxBrakeTorque
max brake torque for this wheel (Nm)
ESweepType SweepType
Whether wheel suspension considers simple, complex.
bool bAffectedBySteering
Whether steering should affect this wheel.