CARLA
Loading...
Searching...
No Matches
ObstacleDetectionSensor.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
16#include "carla/ros2/ROS2.h"
18
19AObstacleDetectionSensor::AObstacleDetectionSensor(const FObjectInitializer &ObjectInitializer)
20 : Super(ObjectInitializer)
21{
22 PrimaryActorTick.bCanEverTick = true;
23}
24
26{
27 FActorDefinition SensorDefinition = FActorDefinition();
28 UActorBlueprintFunctionLibrary::MakeObstacleDetectorDefinitions(TEXT("other"), TEXT("obstacle"), SensorDefinition);
29 return SensorDefinition;
30}
31
33{
34 //Multiplying numbers for 100 in order to convert from meters to centimeters
35 Super::Set(Description);
37 "distance",
38 Description.Variations,
39 Distance) * 100.0f;
41 "hit_radius",
42 Description.Variations,
43 HitRadius) * 100.0f;
45 "only_dynamics",
46 Description.Variations,
48#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
50 "debug_linetrace",
51 Description.Variations,
53#endif
54}
55
56void AObstacleDetectionSensor::PostPhysTick(UWorld *World, ELevelTick TickType, float DeltaTime)
57{
58 TRACE_CPUPROFILER_EVENT_SCOPE(AObstacleDetectionSensor::PostPhysTick);
59 const FVector &Start = GetActorLocation();
60 const FVector &End = Start + (GetActorForwardVector() * Distance);
61 UWorld* CurrentWorld = GetWorld();
62
63 // Struct in which the result of the scan will be saved
64 FHitResult HitOut = FHitResult();
65
66 // Initialization of Query Parameters
67 FCollisionQueryParams TraceParams(FName(TEXT("ObstacleDetection Trace")), true, this);
68
69#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
70 // If debug mode enabled, we create a tag that will make the sweep be
71 // displayed.
73 {
74 const FName TraceTag("ObstacleDebugTrace");
75 CurrentWorld->DebugDrawTraceTag = TraceTag;
76 TraceParams.TraceTag = TraceTag;
77 }
78#endif
79
80 // Hit against complex meshes
81 TraceParams.bTraceComplex = true;
82
83 // Ignore trigger boxes
84 TraceParams.bIgnoreTouches = true;
85
86 // Limit the returned information
87 TraceParams.bReturnPhysicalMaterial = false;
88
89 // Ignore ourselves
90 TraceParams.AddIgnoredActor(this);
91 if(Super::GetOwner()!=nullptr)
92 TraceParams.AddIgnoredActor(Super::GetOwner());
93
94 bool isHitReturned;
95 // Choosing a type of sweep is a workaround until everything get properly
96 // organized under correct collision channels and object types.
97 if (bOnlyDynamics)
98 {
99 // If we go only for dynamics, we check the object type AllDynamicObjects
100 FCollisionObjectQueryParams TraceChannel = FCollisionObjectQueryParams(
101 FCollisionObjectQueryParams::AllDynamicObjects);
102 isHitReturned = CurrentWorld->SweepSingleByObjectType(
103 HitOut,
104 Start,
105 End,
106 FQuat(),
107 TraceChannel,
108 FCollisionShape::MakeSphere(HitRadius),
109 TraceParams);
110 }
111 else
112 {
113 // Else, if we go for everything, we get everything that interacts with a
114 // Pawn
115 ECollisionChannel TraceChannel = ECC_WorldStatic;
116 isHitReturned = CurrentWorld->SweepSingleByChannel(
117 HitOut,
118 Start,
119 End,
120 FQuat(),
121 TraceChannel,
122 FCollisionShape::MakeSphere(HitRadius),
123 TraceParams);
124 }
125
126 if (isHitReturned)
127 {
128 OnObstacleDetectionEvent(this, HitOut.GetActor(), HitOut.Distance, HitOut);
129 }
130}
131
133 AActor *Actor,
134 AActor *OtherActor,
135 float HitDistance,
136 const FHitResult &Hit)
137{
138 if ((Actor != nullptr) && (OtherActor != nullptr) && IsStreamReady())
139 {
140 const auto& CurrentEpisode = GetEpisode();
141
142 auto DataStream = GetDataStream(*this);
143
144 // ROS2
145 #if defined(WITH_ROS2)
146 auto ROS2 = carla::ros2::ROS2::GetInstance();
147 if (ROS2->IsEnabled())
148 {
149 TRACE_CPUPROFILER_EVENT_SCOPE_STR("ROS2 Send");
151 AActor* ParentActor = GetAttachParentActor();
152 if (ParentActor)
153 {
154 FTransform LocalTransformRelativeToParent = GetActorTransform().GetRelativeTransform(ParentActor->GetActorTransform());
155 ROS2->ProcessDataFromObstacleDetection(DataStream.GetSensorType(), StreamId, LocalTransformRelativeToParent, Actor, OtherActor, HitDistance/100.0f, this);
156 }
157 else
158 {
159 ROS2->ProcessDataFromObstacleDetection(DataStream.GetSensorType(), StreamId, DataStream.GetSensorTransform(), Actor, OtherActor, HitDistance/100.0f, this);
160 }
161 }
162 #endif
163
164 DataStream.SerializeAndSend(*this,
165 CurrentEpisode.SerializeActorWithPrimaryIds(Actor),
166 CurrentEpisode.SerializeActorWithPrimaryIds(OtherActor),
167 HitDistance/100.0f);
168 }
169}
void Set(const FActorDescription &Description) override
void OnObstacleDetectionEvent(AActor *Actor, AActor *OtherActor, float Distance, const FHitResult &Hit)
AObstacleDetectionSensor(const FObjectInitializer &ObjectInitializer)
virtual void PostPhysTick(UWorld *World, ELevelTick TickType, float DeltaSeconds) override
static FActorDefinition GetSensorDefinition()
auto GetToken() const
Return the token that allows subscribing to this sensor's stream.
FAsyncDataStream GetDataStream(SensorType &&Self)
Return the FDataStream associated with this sensor.
static float RetrieveActorAttributeToFloat(const FString &Id, const TMap< FString, FActorAttribute > &Attributes, float Default)
static bool RetrieveActorAttributeToBool(const FString &Id, const TMap< FString, FActorAttribute > &Attributes, bool Default)
static void MakeObstacleDetectorDefinitions(const FString &Type, const FString &Id, FActorDefinition &Definition)
static std::shared_ptr< ROS2 > GetInstance()
Definition ROS2.h:61
Serializes a stream endpoint.
A definition of a Carla Actor with all the variation and attributes.
A description of a Carla Actor with all its variation.
TMap< FString, FActorAttribute > Variations
User selected variations of the actor.