CARLA
 
载入中...
搜索中...
未找到
CarlaWheeledVehicle.cpp
浏览该文件的文档.
1// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3// Copyright (c) 2019 Intel Corporation
4//
5// This work is licensed under the terms of the MIT license.
6// For a copy, see <https://opensource.org/licenses/MIT>.
7
8#include "Components/BoxComponent.h"
9#include "Engine/CollisionProfile.h"
11#include "Rendering/SkeletalMeshRenderData.h"
12#include "UObject/UObjectGlobals.h"
13#include "DrawDebugHelpers.h"
14#include "Kismet/KismetSystemLibrary.h"
15
16#include "PhysXPublic.h"
17#include "PhysXVehicleManager.h"
18#include "TireConfig.h"
19#include "VehicleWheel.h"
20
21#include "Carla.h"
22#include "Carla/Game/CarlaHUD.h"
30
31// =============================================================================
32// -- Constructor and destructor -----------------------------------------------
33// =============================================================================
34
35ACarlaWheeledVehicle::ACarlaWheeledVehicle(const FObjectInitializer& ObjectInitializer) :
36 Super(ObjectInitializer)
37{
38 VehicleBounds = CreateDefaultSubobject<UBoxComponent>(TEXT("VehicleBounds"));
39 VehicleBounds->SetupAttachment(RootComponent);
40 VehicleBounds->SetHiddenInGame(true);
41 VehicleBounds->SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName);
42
43 VelocityControl = CreateDefaultSubobject<UVehicleVelocityControl>(TEXT("VelocityControl"));
44 VelocityControl->Deactivate();
45
46 GetVehicleMovementComponent()->bReverseAsBrake = false;
47 BaseMovementComponent = CreateDefaultSubobject<UBaseCarlaMovementComponent>(TEXT("BaseMovementComponent"));
48}
49
51
52void ACarlaWheeledVehicle::SetWheelCollision(UWheeledVehicleMovementComponent4W *Vehicle4W,
54
55 #ifdef WHEEL_SWEEP_ENABLED
56 const bool IsBike = IsTwoWheeledVehicle();
57
58 if (IsBike)
59 return;
60
61 const bool IsEqual = Vehicle4W->UseSweepWheelCollision == PhysicsControl.UseSweepWheelCollision;
62
63 if (IsEqual)
64 return;
65
66 Vehicle4W->UseSweepWheelCollision = PhysicsControl.UseSweepWheelCollision;
67
68 #else
69
70 if (PhysicsControl.UseSweepWheelCollision)
71 UE_LOG(LogCarla, Warning, TEXT("Error: Sweep for wheel collision is not available. \
72 Make sure you have installed the required patch.") );
73
74 #endif
75
76}
77
78void ACarlaWheeledVehicle::SetWheelCollisionNW(UWheeledVehicleMovementComponentNW *VehicleNW,
80
81 #ifdef WHEEL_SWEEP_ENABLED
82 const bool IsEqual = VehicleNW->UseSweepWheelCollision == PhysicsControl.UseSweepWheelCollision;
83
84 if (IsEqual)
85 return;
86
87 VehicleNW->UseSweepWheelCollision = PhysicsControl.UseSweepWheelCollision;
88
89 #else
90
91 if (PhysicsControl.UseSweepWheelCollision)
92 UE_LOG(LogCarla, Warning, TEXT("Error: Sweep for wheel collision is not available. \
93 Make sure you have installed the required patch.") );
94
95 #endif
96}
97
99{
100 Super::BeginPlay();
101
103
104 // Get constraint components and their initial transforms
105 FTransform ActorInverseTransform = GetActorTransform().Inverse();
106 ConstraintsComponents.Empty();
108 ConstraintDoor.Empty();
109 for (FName& ComponentName : ConstraintComponentNames)
110 {
111 UPhysicsConstraintComponent* ConstraintComponent =
112 Cast<UPhysicsConstraintComponent>(GetDefaultSubobjectByName(ComponentName));
113 if (ConstraintComponent)
114 {
115 UPrimitiveComponent* DoorComponent = Cast<UPrimitiveComponent>(
116 GetDefaultSubobjectByName(ConstraintComponent->ComponentName1.ComponentName));
117 if(DoorComponent)
118 {
119 UE_LOG(LogCarla, Warning, TEXT("Door name: %s"), *(DoorComponent->GetName()));
120 FTransform ComponentWorldTransform = DoorComponent->GetComponentTransform();
121 FTransform RelativeTransform = ComponentWorldTransform * ActorInverseTransform;
122 DoorComponentsTransform.Add(DoorComponent, RelativeTransform);
123 ConstraintDoor.Add(ConstraintComponent, DoorComponent);
124 ConstraintsComponents.Add(ConstraintComponent);
125 ConstraintComponent->TermComponentConstraint();
126 }
127 else
128 {
129 UE_LOG(LogCarla, Error, TEXT("Missing component for constraint: %s"), *(ConstraintComponent->GetName()));
130 }
131 }
132 }
134
135 // get collision disable constraints (used to prevent doors from colliding with each other)
137 TArray<UPhysicsConstraintComponent*> Constraints;
138 GetComponents(Constraints);
139 for (UPhysicsConstraintComponent* Constraint : Constraints)
140 {
141 if (!ConstraintsComponents.Contains(Constraint))
142 {
143 UPrimitiveComponent* CollisionDisabledComponent1 = Cast<UPrimitiveComponent>(
144 GetDefaultSubobjectByName(Constraint->ComponentName1.ComponentName));
145 UPrimitiveComponent* CollisionDisabledComponent2 = Cast<UPrimitiveComponent>(
146 GetDefaultSubobjectByName(Constraint->ComponentName2.ComponentName));
147 if (CollisionDisabledComponent1)
148 {
149 CollisionDisableConstraints.Add(CollisionDisabledComponent1, Constraint);
150 }
151 if (CollisionDisabledComponent2)
152 {
153 CollisionDisableConstraints.Add(CollisionDisabledComponent2, Constraint);
154 }
155 }
156 }
157
158 float FrictionScale = 3.5f;
159
160 UWheeledVehicleMovementComponent* MovementComponent = GetVehicleMovementComponent();
161
162 if (MovementComponent)
163 {
164 check(MovementComponent != nullptr);
165
166 // Setup Tire Configs with default value. This is needed to avoid getting
167 // friction values of previously created TireConfigs for the same vehicle
168 // blueprint.
169 TArray<float> OriginalFrictions;
170 OriginalFrictions.Init(FrictionScale, MovementComponent->Wheels.Num());
171 SetWheelsFrictionScale(OriginalFrictions);
172
173 // Check if it overlaps with a Friction trigger, if so, update the friction
174 // scale.
175 TArray<AActor *> OverlapActors;
176 GetOverlappingActors(OverlapActors, AFrictionTrigger::StaticClass());
177 for (const auto &Actor : OverlapActors)
178 {
179 AFrictionTrigger *FrictionTrigger = Cast<AFrictionTrigger>(Actor);
180 if (FrictionTrigger)
181 {
182 FrictionScale = FrictionTrigger->Friction;
183 }
184 }
185
186 // Set the friction scale to Wheel CDO and update wheel setups
187 TArray<FWheelSetup> NewWheelSetups = MovementComponent->WheelSetups;
188 for (const auto &WheelSetup : NewWheelSetups)
189 {
190 UVehicleWheel *Wheel = WheelSetup.WheelClass.GetDefaultObject();
191 check(Wheel != nullptr);
192 }
193
194 MovementComponent->WheelSetups = NewWheelSetups;
195
197
198 // Update physics in the Ackermann Controller
200 }
201
203}
204
205bool ACarlaWheeledVehicle::IsInVehicleRange(const FVector& Location) const
206{
207 TRACE_CPUPROFILER_EVENT_SCOPE(ACarlaWheeledVehicle::IsInVehicleRange);
208
209 return FoliageBoundingBox.IsInside(Location);
210}
211
213{
214 const FTransform GlobalTransform = GetActorTransform();
215 const FVector Vec { DetectionSize, DetectionSize, DetectionSize };
216 FBox Box = FBox(-Vec, Vec);
217 const FTransform NonScaledTransform(GlobalTransform.GetRotation(), GlobalTransform.GetLocation(), {1.0f, 1.0f, 1.0f});
218 FoliageBoundingBox = Box.TransformBy(NonScaledTransform);
219}
220
221const TArray<int32> ACarlaWheeledVehicle::GetFoliageInstancesCloseToVehicle(const UInstancedStaticMeshComponent* Component) const
222{
223 TRACE_CPUPROFILER_EVENT_SCOPE(ACarlaWheeledVehicle::GetFoliageInstancesCloseToVehicle);
224 return Component->GetInstancesOverlappingBox(FoliageBoundingBox);
225}
226
228{
229 TRACE_CPUPROFILER_EVENT_SCOPE(ACarlaWheeledVehicle::GetDetectionBox);
230 return FoliageBoundingBox;
231}
232
234{
235 return DetectionSize;
236}
237
239{
240 const FVector& Center = FoliageBoundingBox.GetCenter();
241 const FVector& Extent = FoliageBoundingBox.GetExtent();
242 const FQuat& Rotation = GetActorQuat();
243 DrawDebugBox(GetWorld(), Center, Extent, Rotation, FColor::Magenta, false, 0.0f, 0, 5.0f);
244}
245
247{
249 if (LargeMap)
250 {
251 FTransform GlobalTransform = LargeMap->LocalToGlobalTransform(GetActorTransform());
252 return VehicleBounds->CalcBounds(GlobalTransform);
253 }
254 return VehicleBounds->CalcBounds(GetActorTransform());
255}
256
258{
260
261 const FTransform& CompToWorldTransform = RootComponent->GetComponentTransform();
262 const FRotator Rotation = CompToWorldTransform.GetRotation().Rotator();
263 const FVector Translation = CompToWorldTransform.GetLocation();
264 const FVector Scale = CompToWorldTransform.GetScale3D();
265
266 // Invert BB origin to local space
267 BoundingBox.Origin -= Translation;
268 BoundingBox.Origin = Rotation.UnrotateVector(BoundingBox.Origin);
269 BoundingBox.Origin /= Scale;
270
271 // Prepare Box Collisions
272 FTransform Transform;
273 Transform.SetTranslation(BoundingBox.Origin);
274 VehicleBounds->SetRelativeTransform(Transform);
275 VehicleBounds->SetBoxExtent(BoundingBox.Extent);
276}
277
278// =============================================================================
279// -- Get functions ------------------------------------------------------------
280// =============================================================================
281
286
288{
289 return GetVehicleTransform().GetRotation().GetForwardVector();
290}
291
296
298{
299 return VehicleBounds->GetRelativeTransform();
300}
301
303{
304 return VehicleBounds->GetScaledBoxExtent();
305}
306
308{
309 const auto &Wheels = GetVehicleMovementComponent()->Wheels;
310 check(Wheels.Num() > 0);
311 const auto *FrontWheel = Wheels[0];
312 check(FrontWheel != nullptr);
313 return FrontWheel->SteerAngle;
314}
315
316// =============================================================================
317// -- Set functions ------------------------------------------------------------
318// =============================================================================
319
332
334{
336 Control.Throttle = Value;
337 ApplyVehicleControl(Control, EVehicleInputPriority::User);
338}
339
341{
343 Control.Steer = Value;
344 ApplyVehicleControl(Control, EVehicleInputPriority::User);
345}
346
348{
350 Control.Brake = Value;
351 ApplyVehicleControl(Control, EVehicleInputPriority::User);
352}
353
355{
357 Control.bReverse = Value;
358 ApplyVehicleControl(Control, EVehicleInputPriority::User);
359}
360
362{
364 Control.bHandBrake = Value;
365 ApplyVehicleControl(Control, EVehicleInputPriority::User);
366}
367
369{
370
371 UWheeledVehicleMovementComponent* Movement = GetVehicleMovement();
372 TArray<float> WheelsFrictionScale;
373 if (Movement)
374 {
375 check(Movement != nullptr);
376
377 for (auto &Wheel : Movement->Wheels)
378 {
379 WheelsFrictionScale.Add(Wheel->TireConfig->GetFrictionScale());
380 }
381 }
382 return WheelsFrictionScale;
383}
384
385void ACarlaWheeledVehicle::SetWheelsFrictionScale(TArray<float> &WheelsFrictionScale)
386{
387
388 UWheeledVehicleMovementComponent* Movement = GetVehicleMovement();
389 if (Movement)
390 {
391 check(Movement != nullptr);
392 check(Movement->Wheels.Num() == WheelsFrictionScale.Num());
393
394 for (int32 i = 0; i < Movement->Wheels.Num(); ++i)
395 {
396 Movement->Wheels[i]->TireConfig->SetFrictionScale(WheelsFrictionScale[i]);
397 }
398 }
399}
400
402{
404
405 if (!bIsNWVehicle) {
406 UWheeledVehicleMovementComponent4W *Vehicle4W = Cast<UWheeledVehicleMovementComponent4W>(
407 GetVehicleMovement());
408 check(Vehicle4W != nullptr);
409
410 // Engine Setup
411 PhysicsControl.TorqueCurve = Vehicle4W->EngineSetup.TorqueCurve.EditorCurveData;
412 PhysicsControl.MaxRPM = Vehicle4W->EngineSetup.MaxRPM;
413 PhysicsControl.MOI = Vehicle4W->EngineSetup.MOI;
414 PhysicsControl.DampingRateFullThrottle = Vehicle4W->EngineSetup.DampingRateFullThrottle;
415 PhysicsControl.DampingRateZeroThrottleClutchEngaged =
416 Vehicle4W->EngineSetup.DampingRateZeroThrottleClutchEngaged;
417 PhysicsControl.DampingRateZeroThrottleClutchDisengaged =
418 Vehicle4W->EngineSetup.DampingRateZeroThrottleClutchDisengaged;
419
420 // Transmission Setup
421 PhysicsControl.bUseGearAutoBox = Vehicle4W->TransmissionSetup.bUseGearAutoBox;
422 PhysicsControl.GearSwitchTime = Vehicle4W->TransmissionSetup.GearSwitchTime;
423 PhysicsControl.ClutchStrength = Vehicle4W->TransmissionSetup.ClutchStrength;
424 PhysicsControl.FinalRatio = Vehicle4W->TransmissionSetup.FinalRatio;
425
426 TArray<FGearPhysicsControl> ForwardGears;
427
428 for (const auto &Gear : Vehicle4W->TransmissionSetup.ForwardGears)
429 {
430 FGearPhysicsControl GearPhysicsControl;
431
432 GearPhysicsControl.Ratio = Gear.Ratio;
433 GearPhysicsControl.UpRatio = Gear.UpRatio;
434 GearPhysicsControl.DownRatio = Gear.DownRatio;
435
436 ForwardGears.Add(GearPhysicsControl);
437 }
438
439 PhysicsControl.ForwardGears = ForwardGears;
440
441 // Vehicle Setup
442 PhysicsControl.Mass = Vehicle4W->Mass;
443 PhysicsControl.DragCoefficient = Vehicle4W->DragCoefficient;
444
445 // Center of mass offset (Center of mass is always zero vector in local
446 // position)
447 UPrimitiveComponent *UpdatedPrimitive = Cast<UPrimitiveComponent>(Vehicle4W->UpdatedComponent);
448 check(UpdatedPrimitive != nullptr);
449
450 PhysicsControl.CenterOfMass = UpdatedPrimitive->BodyInstance.COMNudge;
451
452 // Transmission Setup
453 PhysicsControl.SteeringCurve = Vehicle4W->SteeringCurve.EditorCurveData;
454
455 // Wheels Setup
456 TArray<FWheelPhysicsControl> Wheels;
457
458 for (int32 i = 0; i < Vehicle4W->WheelSetups.Num(); ++i)
459 {
460 FWheelPhysicsControl PhysicsWheel;
461
462 if (bPhysicsEnabled) {
463 PxVehicleWheelData PWheelData = Vehicle4W->PVehicle->mWheelsSimData.getWheelData(i);
464
465 PhysicsWheel.DampingRate = Cm2ToM2(PWheelData.mDampingRate);
466 PhysicsWheel.MaxSteerAngle = FMath::RadiansToDegrees(PWheelData.mMaxSteer);
467 PhysicsWheel.Radius = PWheelData.mRadius;
468 PhysicsWheel.MaxBrakeTorque = Cm2ToM2(PWheelData.mMaxBrakeTorque);
469 PhysicsWheel.MaxHandBrakeTorque = Cm2ToM2(PWheelData.mMaxHandBrakeTorque);
470
471 PxVehicleTireData PTireData = Vehicle4W->PVehicle->mWheelsSimData.getTireData(i);
472
473 PhysicsWheel.LatStiffMaxLoad = PTireData.mLatStiffX;
474 PhysicsWheel.LatStiffValue = PTireData.mLatStiffY;
475 PhysicsWheel.LongStiffValue = PTireData.mLongitudinalStiffnessPerUnitGravity;
476 } else {
477 if (i < LastPhysicsControl.Wheels.Num()) {
478 PhysicsWheel = LastPhysicsControl.Wheels[i];
479 }
480 }
481
482 PhysicsWheel.TireFriction = Vehicle4W->Wheels[i]->TireConfig->GetFrictionScale();
483 PhysicsWheel.Position = Vehicle4W->Wheels[i]->Location;
484
485 Wheels.Add(PhysicsWheel);
486 }
487
488 PhysicsControl.Wheels = Wheels;
489
490 } else {
491 UWheeledVehicleMovementComponentNW *VehicleNW = Cast<UWheeledVehicleMovementComponentNW>(
492 GetVehicleMovement());
493
494 check(VehicleNW != nullptr);
495
496 // Engine Setup
497 PhysicsControl.TorqueCurve = VehicleNW->EngineSetup.TorqueCurve.EditorCurveData;
498 PhysicsControl.MaxRPM = VehicleNW->EngineSetup.MaxRPM;
499 PhysicsControl.MOI = VehicleNW->EngineSetup.MOI;
500 PhysicsControl.DampingRateFullThrottle = VehicleNW->EngineSetup.DampingRateFullThrottle;
501 PhysicsControl.DampingRateZeroThrottleClutchEngaged =
502 VehicleNW->EngineSetup.DampingRateZeroThrottleClutchEngaged;
503 PhysicsControl.DampingRateZeroThrottleClutchDisengaged =
504 VehicleNW->EngineSetup.DampingRateZeroThrottleClutchDisengaged;
505
506 // Transmission Setup
507 PhysicsControl.bUseGearAutoBox = VehicleNW->TransmissionSetup.bUseGearAutoBox;
508 PhysicsControl.GearSwitchTime = VehicleNW->TransmissionSetup.GearSwitchTime;
509 PhysicsControl.ClutchStrength = VehicleNW->TransmissionSetup.ClutchStrength;
510 PhysicsControl.FinalRatio = VehicleNW->TransmissionSetup.FinalRatio;
511
512 TArray<FGearPhysicsControl> ForwardGears;
513
514 for (const auto &Gear : VehicleNW->TransmissionSetup.ForwardGears)
515 {
516 FGearPhysicsControl GearPhysicsControl;
517
518 GearPhysicsControl.Ratio = Gear.Ratio;
519 GearPhysicsControl.UpRatio = Gear.UpRatio;
520 GearPhysicsControl.DownRatio = Gear.DownRatio;
521
522 ForwardGears.Add(GearPhysicsControl);
523 }
524
525 PhysicsControl.ForwardGears = ForwardGears;
526
527 // VehicleNW Setup
528 PhysicsControl.Mass = VehicleNW->Mass;
529 PhysicsControl.DragCoefficient = VehicleNW->DragCoefficient;
530
531 // Center of mass offset (Center of mass is always zero vector in local
532 // position)
533 UPrimitiveComponent *UpdatedPrimitive = Cast<UPrimitiveComponent>(VehicleNW->UpdatedComponent);
534 check(UpdatedPrimitive != nullptr);
535
536 PhysicsControl.CenterOfMass = UpdatedPrimitive->BodyInstance.COMNudge;
537
538 // Transmission Setup
539 PhysicsControl.SteeringCurve = VehicleNW->SteeringCurve.EditorCurveData;
540
541 // Wheels Setup
542 TArray<FWheelPhysicsControl> Wheels;
543
544 for (int32 i = 0; i < VehicleNW->WheelSetups.Num(); ++i)
545 {
546 FWheelPhysicsControl PhysicsWheel;
547
548 if (bPhysicsEnabled) {
549 PxVehicleWheelData PWheelData = VehicleNW->PVehicle->mWheelsSimData.getWheelData(i);
550 PhysicsWheel.DampingRate = Cm2ToM2(PWheelData.mDampingRate);
551 PhysicsWheel.MaxSteerAngle = FMath::RadiansToDegrees(PWheelData.mMaxSteer);
552 PhysicsWheel.Radius = PWheelData.mRadius;
553 PhysicsWheel.MaxBrakeTorque = Cm2ToM2(PWheelData.mMaxBrakeTorque);
554 PhysicsWheel.MaxHandBrakeTorque = Cm2ToM2(PWheelData.mMaxHandBrakeTorque);
555
556 PxVehicleTireData PTireData = VehicleNW->PVehicle->mWheelsSimData.getTireData(i);
557 PhysicsWheel.LatStiffMaxLoad = PTireData.mLatStiffX;
558 PhysicsWheel.LatStiffValue = PTireData.mLatStiffY;
559 PhysicsWheel.LongStiffValue = PTireData.mLongitudinalStiffnessPerUnitGravity;
560 } else {
561 if (i < LastPhysicsControl.Wheels.Num()) {
562 PhysicsWheel = LastPhysicsControl.Wheels[i];
563 }
564 }
565
566 PhysicsWheel.TireFriction = VehicleNW->Wheels[i]->TireConfig->GetFrictionScale();
567 PhysicsWheel.Position = VehicleNW->Wheels[i]->Location;
568
569 Wheels.Add(PhysicsWheel);
570 }
571
572 PhysicsControl.Wheels = Wheels;
573
574 }
575 return PhysicsControl;
576}
577
582
587
589{
591 if (!bIsNWVehicle) {
592 UWheeledVehicleMovementComponent4W *Vehicle4W = Cast<UWheeledVehicleMovementComponent4W>(
593 GetVehicleMovement());
594 check(Vehicle4W != nullptr);
595
596
597
598 // Engine Setup
599 Vehicle4W->EngineSetup.TorqueCurve.EditorCurveData = PhysicsControl.TorqueCurve;
600 Vehicle4W->EngineSetup.MaxRPM = PhysicsControl.MaxRPM;
601
602 Vehicle4W->EngineSetup.MOI = PhysicsControl.MOI;
603
604 Vehicle4W->EngineSetup.DampingRateFullThrottle = PhysicsControl.DampingRateFullThrottle;
605 Vehicle4W->EngineSetup.DampingRateZeroThrottleClutchEngaged =
606 PhysicsControl.DampingRateZeroThrottleClutchEngaged;
607 Vehicle4W->EngineSetup.DampingRateZeroThrottleClutchDisengaged =
608 PhysicsControl.DampingRateZeroThrottleClutchDisengaged;
609
610 // Transmission Setup
611 Vehicle4W->TransmissionSetup.bUseGearAutoBox = PhysicsControl.bUseGearAutoBox;
612 Vehicle4W->TransmissionSetup.GearSwitchTime = PhysicsControl.GearSwitchTime;
613 Vehicle4W->TransmissionSetup.ClutchStrength = PhysicsControl.ClutchStrength;
614 Vehicle4W->TransmissionSetup.FinalRatio = PhysicsControl.FinalRatio;
615
616 TArray<FVehicleGearData> ForwardGears;
617
618 for (const auto &Gear : PhysicsControl.ForwardGears)
619 {
620 FVehicleGearData GearData;
621
622 GearData.Ratio = Gear.Ratio;
623 GearData.UpRatio = Gear.UpRatio;
624 GearData.DownRatio = Gear.DownRatio;
625
626 ForwardGears.Add(GearData);
627 }
628
629 Vehicle4W->TransmissionSetup.ForwardGears = ForwardGears;
630
631 // Vehicle Setup
632 Vehicle4W->Mass = PhysicsControl.Mass;
633 Vehicle4W->DragCoefficient = PhysicsControl.DragCoefficient;
634
635 // Center of mass
636 UPrimitiveComponent *UpdatedPrimitive = Cast<UPrimitiveComponent>(Vehicle4W->UpdatedComponent);
637 check(UpdatedPrimitive != nullptr);
638
639 UpdatedPrimitive->BodyInstance.COMNudge = PhysicsControl.CenterOfMass;
640
641 // Transmission Setup
642 Vehicle4W->SteeringCurve.EditorCurveData = PhysicsControl.SteeringCurve;
643
644 // Wheels Setup
645 const int PhysicsWheelsNum = PhysicsControl.Wheels.Num();
646 if (PhysicsWheelsNum != 4)
647 {
648 UE_LOG(LogCarla, Error, TEXT("Number of WheelPhysicsControl is not 4."));
649 return;
650 }
651
652 // Change, if required, the collision mode for wheels
654
655 TArray<FWheelSetup> NewWheelSetups = Vehicle4W->WheelSetups;
656
657 for (int32 i = 0; i < PhysicsWheelsNum; ++i)
658 {
659 UVehicleWheel *Wheel = NewWheelSetups[i].WheelClass.GetDefaultObject();
660 check(Wheel != nullptr);
661
662 // Assigning new tire config
663 Wheel->TireConfig = DuplicateObject<UTireConfig>(Wheel->TireConfig, nullptr);
664
665 // Setting a new value to friction
666 Wheel->TireConfig->SetFrictionScale(PhysicsControl.Wheels[i].TireFriction);
667 }
668
669 Vehicle4W->WheelSetups = NewWheelSetups;
670
671 // Recreate Physics State for vehicle setup
672 GetWorld()->GetPhysicsScene()->GetPxScene()->lockWrite();
673 Vehicle4W->RecreatePhysicsState();
674 GetWorld()->GetPhysicsScene()->GetPxScene()->unlockWrite();
675
676 for (int32 i = 0; i < PhysicsWheelsNum; ++i)
677 {
678 PxVehicleWheelData PWheelData = Vehicle4W->PVehicle->mWheelsSimData.getWheelData(i);
679
680 PWheelData.mRadius = PhysicsControl.Wheels[i].Radius;
681 PWheelData.mMaxSteer = FMath::DegreesToRadians(PhysicsControl.Wheels[i].MaxSteerAngle);
682 PWheelData.mDampingRate = M2ToCm2(PhysicsControl.Wheels[i].DampingRate);
683 PWheelData.mMaxBrakeTorque = M2ToCm2(PhysicsControl.Wheels[i].MaxBrakeTorque);
684 PWheelData.mMaxHandBrakeTorque = M2ToCm2(PhysicsControl.Wheels[i].MaxHandBrakeTorque);
685 Vehicle4W->PVehicle->mWheelsSimData.setWheelData(i, PWheelData);
686
687 PxVehicleTireData PTireData = Vehicle4W->PVehicle->mWheelsSimData.getTireData(i);
688 PTireData.mLatStiffX = PhysicsControl.Wheels[i].LatStiffMaxLoad;
689 PTireData.mLatStiffY = PhysicsControl.Wheels[i].LatStiffValue;
690 PTireData.mLongitudinalStiffnessPerUnitGravity = PhysicsControl.Wheels[i].LongStiffValue;
691 Vehicle4W->PVehicle->mWheelsSimData.setTireData(i, PTireData);
692 }
693
695 } else {
696 UWheeledVehicleMovementComponentNW *VehicleNW = Cast<UWheeledVehicleMovementComponentNW>(
697 GetVehicleMovement());
698
699 check(VehicleNW != nullptr);
700
701 // Engine Setup
702 VehicleNW->EngineSetup.TorqueCurve.EditorCurveData = PhysicsControl.TorqueCurve;
703 VehicleNW->EngineSetup.MaxRPM = PhysicsControl.MaxRPM;
704
705 VehicleNW->EngineSetup.MOI = PhysicsControl.MOI;
706
707 VehicleNW->EngineSetup.DampingRateFullThrottle = PhysicsControl.DampingRateFullThrottle;
708 VehicleNW->EngineSetup.DampingRateZeroThrottleClutchEngaged =
709 PhysicsControl.DampingRateZeroThrottleClutchEngaged;
710 VehicleNW->EngineSetup.DampingRateZeroThrottleClutchDisengaged =
711 PhysicsControl.DampingRateZeroThrottleClutchDisengaged;
712
713 // Transmission Setup
714 VehicleNW->TransmissionSetup.bUseGearAutoBox = PhysicsControl.bUseGearAutoBox;
715 VehicleNW->TransmissionSetup.GearSwitchTime = PhysicsControl.GearSwitchTime;
716 VehicleNW->TransmissionSetup.ClutchStrength = PhysicsControl.ClutchStrength;
717 VehicleNW->TransmissionSetup.FinalRatio = PhysicsControl.FinalRatio;
718
719 TArray<FVehicleNWGearData> ForwardGears;
720
721 for (const auto &Gear : PhysicsControl.ForwardGears)
722 {
723 FVehicleNWGearData GearData;
724
725 GearData.Ratio = Gear.Ratio;
726 GearData.UpRatio = Gear.UpRatio;
727 GearData.DownRatio = Gear.DownRatio;
728
729 ForwardGears.Add(GearData);
730 }
731
732 VehicleNW->TransmissionSetup.ForwardGears = ForwardGears;
733
734 // VehicleNW Setup
735 VehicleNW->Mass = PhysicsControl.Mass;
736 VehicleNW->DragCoefficient = PhysicsControl.DragCoefficient;
737
738 // Center of mass
739 UPrimitiveComponent *UpdatedPrimitive = Cast<UPrimitiveComponent>(VehicleNW->UpdatedComponent);
740 check(UpdatedPrimitive != nullptr);
741
742 UpdatedPrimitive->BodyInstance.COMNudge = PhysicsControl.CenterOfMass;
743
744 // Transmission Setup
745 VehicleNW->SteeringCurve.EditorCurveData = PhysicsControl.SteeringCurve;
746
747 // Wheels Setup
748 const int PhysicsWheelsNum = PhysicsControl.Wheels.Num();
749
750 // Change, if required, the collision mode for wheels
752
753 TArray<FWheelSetup> NewWheelSetups = VehicleNW->WheelSetups;
754
755 for (int32 i = 0; i < PhysicsWheelsNum; ++i)
756 {
757 UVehicleWheel *Wheel = NewWheelSetups[i].WheelClass.GetDefaultObject();
758 check(Wheel != nullptr);
759
760 // Assigning new tire config
761 Wheel->TireConfig = DuplicateObject<UTireConfig>(Wheel->TireConfig, nullptr);
762
763 // Setting a new value to friction
764 Wheel->TireConfig->SetFrictionScale(PhysicsControl.Wheels[i].TireFriction);
765 }
766
767 VehicleNW->WheelSetups = NewWheelSetups;
768
769 // Recreate Physics State for vehicle setup
770 GetWorld()->GetPhysicsScene()->GetPxScene()->lockWrite();
771 VehicleNW->RecreatePhysicsState();
772 GetWorld()->GetPhysicsScene()->GetPxScene()->unlockWrite();
773
774 for (int32 i = 0; i < PhysicsWheelsNum; ++i)
775 {
776 PxVehicleWheelData PWheelData = VehicleNW->PVehicle->mWheelsSimData.getWheelData(i);
777
778 PWheelData.mRadius = PhysicsControl.Wheels[i].Radius;
779 PWheelData.mMaxSteer = FMath::DegreesToRadians(PhysicsControl.Wheels[i].MaxSteerAngle);
780 PWheelData.mDampingRate = M2ToCm2(PhysicsControl.Wheels[i].DampingRate);
781 PWheelData.mMaxBrakeTorque = M2ToCm2(PhysicsControl.Wheels[i].MaxBrakeTorque);
782 PWheelData.mMaxHandBrakeTorque = M2ToCm2(PhysicsControl.Wheels[i].MaxHandBrakeTorque);
783 VehicleNW->PVehicle->mWheelsSimData.setWheelData(i, PWheelData);
784
785 PxVehicleTireData PTireData = VehicleNW->PVehicle->mWheelsSimData.getTireData(i);
786 PTireData.mLatStiffX = PhysicsControl.Wheels[i].LatStiffMaxLoad;
787 PTireData.mLatStiffY = PhysicsControl.Wheels[i].LatStiffValue;
788 PTireData.mLongitudinalStiffnessPerUnitGravity = PhysicsControl.Wheels[i].LongStiffValue;
789 VehicleNW->PVehicle->mWheelsSimData.setTireData(i, PTireData);
790 }
791
793
794 }
795
796 auto * Recorder = UCarlaStatics::GetRecorder(GetWorld());
797 if (Recorder && Recorder->IsEnabled())
798 {
799 Recorder->AddPhysicsControl(*this);
800 }
801
802 // Update physics in the Ackermann Controller
804
805}
806
808{
809 VelocityControl->Activate(Velocity);
810}
811
816
818{
819 FVehicleTelemetryData TelemetryData;
820
821 auto *MovementComponent = GetVehicleMovement();
822
823 // Vehicle telemetry data
824 TelemetryData.Speed = GetVehicleForwardSpeed() / 100.0f; // From cm/s to m/s
825 TelemetryData.Steer = LastAppliedControl.Steer;
826 TelemetryData.Throttle = LastAppliedControl.Throttle;
827 TelemetryData.Brake = LastAppliedControl.Brake;
828 TelemetryData.EngineRPM = MovementComponent->GetEngineRotationSpeed();
829 TelemetryData.Gear = GetVehicleCurrentGear();
830 TelemetryData.Drag = MovementComponent->DebugDragMagnitude / 100.0f; // kg*cm/s2 to Kg*m/s2
831
832 // Wheels telemetry data
833 FPhysXVehicleManager* MyVehicleManager = FPhysXVehicleManager::GetVehicleManagerFromScene(GetWorld()->GetPhysicsScene());
834
835 SCOPED_SCENE_READ_LOCK(MyVehicleManager->GetScene());
836 PxWheelQueryResult* WheelsStates = MyVehicleManager->GetWheelsStates_AssumesLocked(MovementComponent);
837 check(WheelsStates);
838
839 TArray<FWheelTelemetryData> Wheels;
840 for (uint32 w = 0; w < MovementComponent->PVehicle->mWheelsSimData.getNbWheels(); ++w)
841 {
842 FWheelTelemetryData WheelTelemetryData;
843
844 WheelTelemetryData.TireFriction = WheelsStates[w].tireFriction;
845 WheelTelemetryData.LatSlip = FMath::RadiansToDegrees(WheelsStates[w].lateralSlip);
846 WheelTelemetryData.LongSlip = WheelsStates[w].longitudinalSlip;
847 WheelTelemetryData.Omega = MovementComponent->PVehicle->mWheelsDynData.getWheelRotationSpeed(w);
848
849 UVehicleWheel* Wheel = MovementComponent->Wheels[w];
850 WheelTelemetryData.TireLoad = Wheel->DebugTireLoad / 100.0f;
851 WheelTelemetryData.NormalizedTireLoad = Wheel->DebugNormalizedTireLoad;
852 WheelTelemetryData.Torque = Wheel->DebugWheelTorque / (100.0f * 100.0f); // From cm2 to m2
853 WheelTelemetryData.LongForce = Wheel->DebugLongForce / 100.f;
854 WheelTelemetryData.LatForce = Wheel->DebugLatForce / 100.f;
855 WheelTelemetryData.NormalizedLongForce = (FMath::Abs(WheelTelemetryData.LongForce)*WheelTelemetryData.NormalizedTireLoad) / (WheelTelemetryData.TireLoad);
856 WheelTelemetryData.NormalizedLatForce = (FMath::Abs(WheelTelemetryData.LatForce)*WheelTelemetryData.NormalizedTireLoad) / (WheelTelemetryData.TireLoad);
857
858 Wheels.Add(WheelTelemetryData);
859 }
860
861 TelemetryData.Wheels = Wheels;
862
863 return TelemetryData;
864
865}
866
868{
869 if (GetWorld()->GetFirstPlayerController())
870 {
871 ACarlaHUD* hud = Cast<ACarlaHUD>(GetWorld()->GetFirstPlayerController()->GetHUD());
872 if (hud) {
873
874 // Set/Unset the car movement component in HUD to show the temetry
875 if (Enabled) {
876 hud->AddDebugVehicleForTelemetry(GetVehicleMovementComponent());
877 }
878 else{
879 if (hud->DebugVehicle == GetVehicleMovementComponent()) {
880 hud->AddDebugVehicleForTelemetry(nullptr);
881 GetVehicleMovementComponent()->StopTelemetry();
882 }
883 }
884
885 }
886 else {
887 UE_LOG(LogCarla, Warning, TEXT("ACarlaWheeledVehicle::ShowDebugTelemetry:: Cannot find HUD for debug info"));
888 }
889 }
890}
891
893{
894 if (LightState.Position != InputControl.LightState.Position ||
895 LightState.LowBeam != InputControl.LightState.LowBeam ||
896 LightState.HighBeam != InputControl.LightState.HighBeam ||
897 LightState.Brake != InputControl.LightState.Brake ||
898 LightState.RightBlinker != InputControl.LightState.RightBlinker ||
899 LightState.LeftBlinker != InputControl.LightState.LeftBlinker ||
900 LightState.Reverse != InputControl.LightState.Reverse ||
901 LightState.Fog != InputControl.LightState.Fog ||
902 LightState.Interior != InputControl.LightState.Interior ||
903 LightState.Special1 != InputControl.LightState.Special1 ||
904 LightState.Special2 != InputControl.LightState.Special2)
905 {
906 InputControl.LightState = LightState;
908 }
909}
910
912{
913 FailureState = InFailureState;
914}
915
917{
919 {
920 BaseMovementComponent->DestroyComponent();
921 }
922 BaseMovementComponent = MovementComponent;
923}
924
926
927 if (bPhysicsEnabled == false)
928 {
929 check((uint8)WheelLocation >= 0)
930 UVehicleAnimInstance *VehicleAnim = Cast<UVehicleAnimInstance>(GetMesh()->GetAnimInstance());
931 check(VehicleAnim != nullptr)
932 VehicleAnim->SetWheelRotYaw((uint8)WheelLocation, AngleInDeg);
933 }
934 else
935 {
936 UE_LOG(LogTemp, Warning, TEXT("Cannot set wheel steer direction. Physics are enabled."))
937 }
938}
939
941
942 check((uint8)WheelLocation >= 0)
943 UVehicleAnimInstance *VehicleAnim = Cast<UVehicleAnimInstance>(GetMesh()->GetAnimInstance());
944 check(VehicleAnim != nullptr)
945 check(VehicleAnim->GetWheeledVehicleMovementComponent() != nullptr)
946
947 if (bPhysicsEnabled == true)
948 {
949 return VehicleAnim->GetWheeledVehicleMovementComponent()->Wheels[(uint8)WheelLocation]->GetSteerAngle();
950 }
951 else
952 {
953 return VehicleAnim->GetWheelRotAngle((uint8)WheelLocation);
954 }
955}
956
958 if(!GetCarlaMovementComponent<UDefaultMovementComponent>())
959 {
960 return;
961 }
962
963 UWheeledVehicleMovementComponent* Movement = GetVehicleMovement();
964 if (Movement)
965 {
966 check(Movement != nullptr);
967
968 if(bPhysicsEnabled == enabled)
969 return;
970
971 SetActorEnableCollision(true);
972 auto RootComponent = Cast<UPrimitiveComponent>(GetRootComponent());
973 RootComponent->SetSimulatePhysics(enabled);
974 RootComponent->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
975
976 UVehicleAnimInstance *VehicleAnim = Cast<UVehicleAnimInstance>(GetMesh()->GetAnimInstance());
977 check(VehicleAnim != nullptr)
978
979 GetWorld()->GetPhysicsScene()->GetPxScene()->lockWrite();
980 if (enabled)
981 {
982 Movement->RecreatePhysicsState();
983 VehicleAnim->ResetWheelCustomRotations();
984 }
985 else
986 {
987 Movement->DestroyPhysicsState();
988 }
989
990 GetWorld()->GetPhysicsScene()->GetPxScene()->unlockWrite();
991
992 bPhysicsEnabled = enabled;
993
995 }
996
997}
998
1000{
1001 for (int i = 0; i < ConstraintsComponents.Num(); i++)
1002 {
1004 }
1005 for (int i = 0; i < ConstraintsComponents.Num(); i++)
1006 {
1008 }
1009}
1010
1012{
1014}
1015
1016void ACarlaWheeledVehicle::EndPlay(const EEndPlayReason::Type EndPlayReason)
1017{
1018 ShowDebugTelemetry(false);
1019 Super::EndPlay(EndPlayReason);
1021}
1022
1024 if (int(DoorIdx) >= ConstraintsComponents.Num() && DoorIdx != EVehicleDoor::All) {
1025 UE_LOG(LogTemp, Warning, TEXT("This door is not configured for this car."));
1026 return;
1027 }
1028
1029 if (DoorIdx == EVehicleDoor::All) {
1030 for (int i = 0; i < ConstraintsComponents.Num(); i++)
1031 {
1033 }
1034 return;
1035 }
1036
1037 OpenDoorPhys(DoorIdx);
1038}
1039
1041 if (int(DoorIdx) >= ConstraintsComponents.Num() && DoorIdx != EVehicleDoor::All) {
1042 UE_LOG(LogTemp, Warning, TEXT("This door is not configured for this car."));
1043 return;
1044 }
1045
1046 if (DoorIdx == EVehicleDoor::All) {
1047 for (int i = 0; i < ConstraintsComponents.Num(); i++)
1048 {
1050 }
1051 return;
1052 }
1053
1054 CloseDoorPhys(DoorIdx);
1055}
1056
1058{
1059 UPhysicsConstraintComponent* Constraint = ConstraintsComponents[static_cast<int>(DoorIdx)];
1060 UPrimitiveComponent* DoorComponent = ConstraintDoor[Constraint];
1061 DoorComponent->DetachFromComponent(
1062 FDetachmentTransformRules(EDetachmentRule::KeepWorld, false));
1063 FTransform DoorInitialTransform =
1064 DoorComponentsTransform[DoorComponent] * GetActorTransform();
1065 DoorComponent->SetWorldTransform(DoorInitialTransform);
1066 DoorComponent->SetSimulatePhysics(true);
1067 DoorComponent->SetCollisionProfileName(TEXT("BlockAll"));
1068 float AngleLimit = Constraint->ConstraintInstance.GetAngularSwing1Limit();
1069 FRotator AngularRotationOffset = Constraint->ConstraintInstance.AngularRotationOffset;
1070
1071 if (Constraint->ConstraintInstance.AngularRotationOffset.Yaw < 0.0f)
1072 {
1073 AngleLimit = -AngleLimit;
1074 }
1075 Constraint->SetAngularOrientationTarget(FRotator(0, AngleLimit, 0));
1076 Constraint->SetAngularDriveParams(DoorOpenStrength, 1.0, 0.0);
1077
1078 Constraint->InitComponentConstraint();
1079
1080 UPhysicsConstraintComponent** CollisionDisable =
1081 CollisionDisableConstraints.Find(DoorComponent);
1082 if (CollisionDisable)
1083 {
1084 (*CollisionDisable)->InitComponentConstraint();
1085 }
1086
1087 RecordDoorChange(DoorIdx, true);
1088}
1089
1091{
1092 UPhysicsConstraintComponent* Constraint = ConstraintsComponents[static_cast<int>(DoorIdx)];
1093 UPrimitiveComponent* DoorComponent = ConstraintDoor[Constraint];
1094 FTransform DoorInitialTransform =
1095 DoorComponentsTransform[DoorComponent] * GetActorTransform();
1096 DoorComponent->SetSimulatePhysics(false);
1097 DoorComponent->SetCollisionProfileName(TEXT("NoCollision"));
1098 DoorComponent->SetWorldTransform(DoorInitialTransform);
1099 DoorComponent->AttachToComponent(
1100 GetMesh(), FAttachmentTransformRules(EAttachmentRule::KeepWorld, true));
1101 RecordDoorChange(DoorIdx, false);
1102}
1103
1105{
1106 auto * Recorder = UCarlaStatics::GetRecorder(GetWorld());
1107 if (Recorder && Recorder->IsEnabled())
1108 {
1109 Recorder->AddVehicleDoor(*this, DoorIdx, bIsOpen);
1110 }
1111}
1112
1114{
1115 auto roll = GetVehicleTransform().Rotator().Roll;
1116
1117 // The angular velocity reduction is applied in 4 stages, to improve its smoothness.
1118 // Case 4 starts the timer to set the rollover flag, so users are notified.
1119 switch (RolloverBehaviorTracker) {
1120 case 0: CheckRollover(roll, std::make_pair(130.0, 230.0)); break;
1121 case 1: CheckRollover(roll, std::make_pair(140.0, 220.0)); break;
1122 case 2: CheckRollover(roll, std::make_pair(150.0, 210.0)); break;
1123 case 3: CheckRollover(roll, std::make_pair(160.0, 200.0)); break;
1124 case 4:
1125 GetWorld()->GetTimerManager().SetTimer(TimerHandler, this, &ACarlaWheeledVehicle::SetRolloverFlag, RolloverFlagTime);
1127 break;
1128 case 5: break;
1129 default:
1131 }
1132
1133 // In case the vehicle recovers, reset the rollover tracker
1134 if (RolloverBehaviorTracker > 0 && -30 < roll && roll < 30){
1137 }
1138}
1139
1140void ACarlaWheeledVehicle::CheckRollover(const float roll, const std::pair<float, float> threshold_roll){
1141 if (threshold_roll.first < roll && roll < threshold_roll.second){
1142 auto RootComponent = Cast<UPrimitiveComponent>(GetRootComponent());
1143 auto angular_velocity = RootComponent->GetPhysicsAngularVelocityInDegrees();
1144 RootComponent->SetPhysicsAngularVelocity((1 - RolloverBehaviorForce) * angular_velocity);
1146 }
1147}
1148
1150 // Make sure the vehicle hasn't recovered since the timer started
1151 if (RolloverBehaviorTracker >= 4) {
1153 }
1154}
1155
1159
1161{
1162 const UObject* World = GetWorld();
1163 TArray<AActor*> ActorsInLevel;
1164 UGameplayStatics::GetAllActorsOfClass(World, AActor::StaticClass(), ActorsInLevel);
1165 for (AActor* Actor : ActorsInLevel)
1166 {
1167 AVegetationManager* Manager = Cast<AVegetationManager>(Actor);
1168 if (!IsValid(Manager))
1169 continue;
1170 Manager->AddVehicle(this);
1171 return;
1172 }
1173}
1174
1176{
1177 const UObject* World = GetWorld();
1178 TArray<AActor*> ActorsInLevel;
1179 UGameplayStatics::GetAllActorsOfClass(World, AActor::StaticClass(), ActorsInLevel);
1180 for (AActor* Actor : ActorsInLevel)
1181 {
1182 AVegetationManager* Manager = Cast<AVegetationManager>(Actor);
1183 if (!IsValid(Manager))
1184 continue;
1185 Manager->RemoveVehicle(this);
1186 return;
1187 }
1188}
1189
1191 UPhysicsConstraintComponent* Component)
1192{
1193 return Component->ConstraintInstance.AngularRotationOffset;
1194}
1195
1197 UPhysicsConstraintComponent* Component, const FRotator &NewAngle)
1198{
1199 Component->ConstraintInstance.AngularRotationOffset = NewAngle;
1200}
EVehicleWheelLocation
EVehicleDoor
Type of door to open/close
static bool IsValid(const ACarlaWheeledVehicle *Vehicle)
Class to draw on HUD
Definition CarlaHUD.h:50
UWheeledVehicleMovementComponent * DebugVehicle
Definition CarlaHUD.h:63
void AddDebugVehicleForTelemetry(UWheeledVehicleMovementComponent *Veh)
Definition CarlaHUD.h:64
FVector GetVehicleBoundingBoxExtent() const
Extent of the vehicle's bounding box.
void SetWheelsFrictionScale(TArray< float > &WheelsFrictionScale)
FBoxSphereBounds GetBoxSphereBounds() const
void RecordDoorChange(const EVehicleDoor DoorIdx, const bool bIsOpen)
FVehicleLightState LightState
void CloseDoorPhys(const EVehicleDoor DoorIdx)
UBoxComponent * VehicleBounds
FVehicleLightState GetVehicleLightState() const
void SetThrottleInput(float Value)
carla::rpc::VehicleFailureState GetFailureState() const
void RefreshLightState(const FVehicleLightState &VehicleLightState)
void SetWheelCollisionNW(UWheeledVehicleMovementComponentNW *VehicleNW, const FVehiclePhysicsControl &PhysicsControl)
TMap< UPrimitiveComponent *, UPhysicsConstraintComponent * > CollisionDisableConstraints
void SetWheelCollision(UWheeledVehicleMovementComponent4W *Vehicle4W, const FVehiclePhysicsControl &PhysicsControl)
const TArray< int32 > GetFoliageInstancesCloseToVehicle(const UInstancedStaticMeshComponent *Component) const
float GetWheelSteerAngle(EVehicleWheelLocation WheelLocation)
bool IsInVehicleRange(const FVector &Location) const
void SetCarlaMovementComponent(UBaseCarlaMovementComponent *MoementComponent)
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.
void ApplyVehiclePhysicsControl(const FVehiclePhysicsControl &PhysicsControl)
FVehiclePhysicsControl GetVehiclePhysicsControl() const
TArray< float > GetWheelsFrictionScale()
FVehicleControl LastAppliedControl
void SetFailureState(const carla::rpc::VehicleFailureState &FailureState)
FVehicleTelemetryData GetVehicleTelemetryData() const
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)
TArray< UPhysicsConstraintComponent * > ConstraintsComponents
int32 GetVehicleCurrentGear() const
Active gear of the vehicle.
struct ACarlaWheeledVehicle::@1 InputControl
FVehiclePhysicsControl LastPhysicsControl
static FRotator GetPhysicsConstraintAngle(UPhysicsConstraintComponent *Component)
float GetVehicleForwardSpeed() const
Forward speed in cm/s. Might be negative if goes backwards.
void SetBrakeInput(float Value)
void CloseDoor(const EVehicleDoor DoorIdx)
TMap< UPhysicsConstraintComponent *, UPrimitiveComponent * > ConstraintDoor
void SetSimulatePhysics(bool enabled)
TMap< UPrimitiveComponent *, FTransform > DoorComponentsTransform
virtual FVector GetVelocity() const override
void SetSteeringInput(float Value)
void ShowDebugTelemetry(bool Enabled)
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
void ActivateVelocityControl(const FVector &Velocity)
void ApplyVehicleControl(const FVehicleControl &Control, EVehicleInputPriority Priority)
ACarlaWheeledVehicle(const FObjectInitializer &ObjectInitializer)
void OpenDoor(const EVehicleDoor DoorIdx)
carla::rpc::VehicleFailureState FailureState
void OpenDoorPhys(const EVehicleDoor DoorIdx)
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)
UVehicleVelocityControl * VelocityControl
FTransform GetVehicleBoundingBoxTransform() const
Transform of the vehicle's bounding box relative to the vehicle.
void SetHandbrakeInput(bool Value)
FAckermannController AckermannController
FTransform LocalToGlobalTransform(const FTransform &InTransform) const
void AddVehicle(ACarlaWheeledVehicle *Vehicle)
void RemoveVehicle(ACarlaWheeledVehicle *Vehicle)
void UpdateVehicleState(const ACarlaWheeledVehicle *Vehicle)
void RunLoop(FVehicleControl &Control)
void UpdateVehiclePhysics(const ACarlaWheeledVehicle *Vehicle)
virtual void ProcessControl(FVehicleControl &Control)
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)
float Ratio
Determines the amount of torque multiplication
float DownRatio
Value of engineRevs/maxEngineRevs that is low enough to gear down
float UpRatio
Value of engineRevs/maxEngineRevs that is high enough to gear up