CARLA
Loading...
Searching...
No Matches
WheeledVehicleAIController.cpp
Go to the documentation of this file.
1// Copyright (c) 2026 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3//
4// This work is licensed under the terms of the MIT license.
5// For a copy, see <https://opensource.org/licenses/MIT>.
6
8#include "Carla.h"
14
15#include <util/ue-header-guard-begin.h>
16#include "EngineUtils.h"
17#include "GameFramework/Pawn.h"
18#include "ChaosWheeledVehicleMovementComponent.h"
19#include <util/ue-header-guard-end.h>
20
21// =============================================================================
22// -- Static local methods -----------------------------------------------------
23// =============================================================================
24
25static bool RayCast(const AActor &Actor, const FVector &Start, const FVector &End)
26{
27 FHitResult OutHit;
28 static FName TraceTag = FName(TEXT("VehicleTrace"));
29 FCollisionQueryParams CollisionParams(TraceTag, true);
30 CollisionParams.AddIgnoredActor(&Actor);
31
32 const bool Success = Actor.GetWorld()->LineTraceSingleByObjectType(
33 OutHit,
34 Start,
35 End,
36 FCollisionObjectQueryParams(FCollisionObjectQueryParams::AllDynamicObjects),
37 CollisionParams);
38
39 // DrawDebugLine(Actor.GetWorld(), Start, End,
40 // Success ? FColor(255, 0, 0) : FColor(0, 255, 0), false);
41
42 return Success && OutHit.bBlockingHit;
43}
44
47 const float Speed,
48 const FVector &Direction)
49{
50 const auto ForwardVector = Vehicle.GetVehicleOrientation();
51 const auto VehicleBounds = Vehicle.GetVehicleBoundingBoxExtent();
52
53 FVector NormDirection = Direction.GetSafeNormal();
54
55 const float Distance = std::max(50.0f, Speed * Speed); // why?
56
57 const FVector StartCenter = Vehicle.GetActorLocation() +
58 (ForwardVector * (250.0f + VehicleBounds.X / 2.0f)) + FVector(0.0f, 0.0f, 50.0f);
59 const FVector EndCenter = StartCenter + NormDirection * (Distance + VehicleBounds.X / 2.0f);
60
61 const FVector StartRight = StartCenter +
62 (FVector(ForwardVector.Y, -ForwardVector.X, ForwardVector.Z) * 100.0f);
63 const FVector EndRight = StartRight + NormDirection * (Distance + VehicleBounds.X / 2.0f);
64
65 const FVector StartLeft = StartCenter +
66 (FVector(-ForwardVector.Y, ForwardVector.X, ForwardVector.Z) * 100.0f);
67 const FVector EndLeft = StartLeft + NormDirection * (Distance + VehicleBounds.X / 2.0f);
68
69 return
70 RayCast(Vehicle, StartCenter, EndCenter) ||
71 RayCast(Vehicle, StartRight, EndRight) ||
72 RayCast(Vehicle, StartLeft, EndLeft);
73}
74
75template <typename T>
76static void ClearQueue(std::queue<T> &Queue)
77{
78 std::queue<T> EmptyQueue;
79 Queue.swap(EmptyQueue);
80}
81
82// =============================================================================
83// -- Constructor and destructor -----------------------------------------------
84// =============================================================================
85
86AWheeledVehicleAIController::AWheeledVehicleAIController(const FObjectInitializer &ObjectInitializer)
87 : Super(ObjectInitializer)
88{
89 RandomEngine = CreateDefaultSubobject<URandomEngine>(TEXT("RandomEngine"));
90
92
93 PrimaryActorTick.bCanEverTick = true;
94 PrimaryActorTick.TickGroup = TG_PrePhysics;
95}
96
98
99// =============================================================================
100// -- AController --------------------------------------------------------------
101// =============================================================================
102
104{
105 Super::OnPossess(aPawn);
106
108 {
109 UE_LOG(LogCarla, Error, TEXT("Controller already possessing a vehicle!"));
110 return;
111 }
112 Vehicle = Cast<ACarlaWheeledVehicle>(aPawn);
113 check(Vehicle != nullptr);
115 if (MaximumSteerAngle <= 0.0f) {
116 UE_LOG(LogCarla, Error, TEXT("MaximumSteerAngle > 0.0f"));
117 }
118
120
121 if (RoadMap == nullptr)
122 {
123 TActorIterator<ACityMapGenerator> It(GetWorld());
124 RoadMap = (It ? It->GetRoadMap() : nullptr);
125 }
126}
127
129{
130 Super::OnUnPossess();
131
132 Vehicle = nullptr;
133}
134
135void AWheeledVehicleAIController::Tick(const float DeltaTime)
136{
137 TRACE_CPUPROFILER_EVENT_SCOPE(AWheeledVehicleAIController::Tick);
138 Super::Tick(DeltaTime);
139
141 {
142 return;
143 }
144
146 {
147 Vehicle->ApplyVehicleControl(FVehicleControl{}, EVehicleInputPriority::Relaxation);
148 }
149
151}
152
153// =============================================================================
154// -- Autopilot ----------------------------------------------------------------
155// =============================================================================
156
157void AWheeledVehicleAIController::ConfigureAutopilot(const bool Enable, const bool KeepState)
158{
159 bAutopilotEnabled = Enable;
160 if (!KeepState)
161 {
162 // Reset state.
165 Vehicle->SetBrakeInput(0.0f);
166 Vehicle->SetReverse(false);
171 ECarlaWheeledVehicleState::FreeDriving :
172 ECarlaWheeledVehicleState::AutopilotOff);
173 }
174
175 TrafficLightState = ETrafficLightState::Green;
176}
177
178// =============================================================================
179// -- Traffic ------------------------------------------------------------------
180// =============================================================================
181
183 const TArray<FVector> &Locations,
184 const bool bOverwriteCurrent)
185{
186 if (bOverwriteCurrent)
187 {
189 }
190 for (auto &Location : Locations)
191 {
192 TargetLocations.emplace(Location);
193 }
194}
static bool RayCast(const AActor &Actor, const FVector &Start, const FVector &End)
static void ClearQueue(std::queue< T > &Queue)
static bool IsThereAnObstacleAhead(const ACarlaWheeledVehicle &Vehicle, const float Speed, const FVector &Direction)
Base class for CARLA wheeled vehicles.
void SetAIVehicleState(ECarlaWheeledVehicleState InState)
void SetThrottleInput(float Value)
float GetMaximumSteerAngle() const
Get the maximum angle at which the front wheel can steer.
void SetBrakeInput(float Value)
void SetSteeringInput(float Value)
void ApplyVehicleControl(const FVehicleControl &Control, EVehicleInputPriority Priority)
void SetHandbrakeInput(bool Value)
void ConfigureAutopilot(const bool Enable, const bool KeepState=false)
AWheeledVehicleAIController(const FObjectInitializer &ObjectInitializer)
void OnPossess(APawn *aPawn) override
void SetFixedRoute(const TArray< FVector > &Locations, bool bOverwriteCurrent=true)
Set a fixed route to follow if autopilot is enabled.
void Tick(float DeltaTime) override
void Seed(int32 InSeed)
Seed the random engine.
static int32 GenerateRandomSeed()
Generate a non-deterministic random seed.