CARLA
 
载入中...
搜索中...
未找到
CollisionSensor.cpp
浏览该文件的文档.
1// Copyright (c) 2024 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"
9#include "CoreMinimal.h"
10
19
20ACollisionSensor::ACollisionSensor(const FObjectInitializer& ObjectInitializer)
21 : Super(ObjectInitializer)
22{
23 PrimaryActorTick.bCanEverTick = true;
24}
25
32
34{
35 Super::SetOwner(NewOwner);
36
37 /// @todo Deregister previous owner if there was one.
38 if (IsValid(NewOwner))
39 {
40 ACarlaWheeledVehicle* Vehicle = Cast<ACarlaWheeledVehicle>(NewOwner);
41 if(IsValid(Vehicle))
42 {
43 Vehicle->GetMesh()->OnComponentHit.AddDynamic(this, &ACollisionSensor::OnComponentCollisionEvent);
44 }
45 else
46 {
47 AWalkerBase* Walker = Cast<AWalkerBase>(NewOwner);
48 if(IsValid(Walker))
49 {
50 Walker->GetMesh()->OnComponentHit.AddDynamic(this, &ACollisionSensor::OnComponentCollisionEvent);
51 }
52 else
53 {
54 OnActorHit.AddDynamic(this, &ACollisionSensor::OnActorCollisionEvent);
55 }
56 }
57 }
58 else
59 {
60 UE_LOG(LogCarla, Log, TEXT("ACollisionSensor::SetOwner New owner is not valid or you are destroying collision sensor") );
61 }
62}
63
64void ACollisionSensor::PrePhysTick(float DeltaSeconds) {
65 Super::PrePhysTick(DeltaSeconds);
66
67 // remove all items from previous frames
68 uint64_t CurrentFrame = FCarlaEngine::GetFrameCounter();
70 std::remove_if(
71 CollisionRegistry.begin(),
73 [CurrentFrame](std::tuple<uint64_t, AActor*, AActor*> Item)
74 {
75 return std::get<0>(Item) < CurrentFrame;
76 }),
77 CollisionRegistry.end());
78}
79
81 AActor *Actor,
82 AActor *OtherActor,
83 FVector NormalImpulse,
84 const FHitResult &Hit)
85{
86 if (!IsValid(OtherActor))
87 {
88 UE_LOG(LogCarla, Error, TEXT("ACollisionSensor::OnActorCollisionEvent Error with collided actor; Not valid.\n Collider actor %s"),
89 *(Actor->GetName()) );
90 return;
91 }
92
93 if (!IsValid(Actor))
94 {
95 UE_LOG(LogCarla, Error, TEXT("ACollisionSensor::OnActorCollisionEvent Error with collider actor; Not valid.\n Collided actor %s"),
96 *(OtherActor->GetName()) );
97 return;
98 }
99
100 uint64_t CurrentFrame = FCarlaEngine::GetFrameCounter();
101
102 // check if this collision has been procesed already in this frame
103 for (auto& Collision: CollisionRegistry)
104 {
105 if (std::get<0>(Collision) == CurrentFrame &&
106 std::get<1>(Collision) == Actor &&
107 std::get<2>(Collision) == OtherActor)
108 {
109 return;
110 }
111 }
112
113 const auto& CurrentEpisode = GetEpisode();
114 constexpr float TO_METERS = 1e-2;
115 NormalImpulse *= TO_METERS;
117 *this,
118 CurrentEpisode.SerializeActor(Actor),
119 CurrentEpisode.SerializeActor(OtherActor),
121 (float)NormalImpulse.X,
122 (float)NormalImpulse.Y,
123 (float)NormalImpulse.Z));
124
125 // record the collision event
126 if (CurrentEpisode.GetRecorder()->IsEnabled()){
127 CurrentEpisode.GetRecorder()->AddCollision(Actor, OtherActor);
128 }
129
130 CollisionRegistry.emplace_back(CurrentFrame, Actor, OtherActor);
131
132 // ROS2
133#if defined(WITH_ROS2)
134 auto ROS2 = carla::ros2::ROS2::GetInstance();
135 if (ROS2->IsEnabled())
136 {
137 TRACE_CPUPROFILER_EVENT_SCOPE_STR("ROS2 Send");
139 AActor* ParentActor = GetAttachParentActor();
140 if (ParentActor)
141 {
142 FTransform LocalTransformRelativeToParent = GetActorTransform().GetRelativeTransform(ParentActor->GetActorTransform());
143 ROS2->ProcessDataFromCollisionSensor(0, StreamId, LocalTransformRelativeToParent, OtherActor->GetUniqueID(), carla::geom::Vector3D{NormalImpulse.X, NormalImpulse.Y, NormalImpulse.Z}, this);
144 }
145 else
146 {
147 ROS2->ProcessDataFromCollisionSensor(0, StreamId, GetActorTransform(), OtherActor->GetUniqueID(), carla::geom::Vector3D{NormalImpulse.X, NormalImpulse.Y, NormalImpulse.Z}, this);
148 }
149 }
150#endif
151}
152
154 AActor *Actor,
155 AActor *OtherActor,
156 FVector NormalImpulse,
157 const FHitResult &Hit)
158{
159 OnCollisionEvent(Actor, OtherActor, NormalImpulse, Hit);
160}
161
163 UPrimitiveComponent* HitComp,
164 AActor* OtherActor,
165 UPrimitiveComponent* OtherComp,
166 FVector NormalImpulse,
167 const FHitResult& Hit)
168{
169 AActor* Actor = HitComp->GetOwner();
170 OnCollisionEvent(Actor, OtherActor, NormalImpulse, Hit);
171}
static bool IsValid(const ACarlaWheeledVehicle *Vehicle)
Base class for CARLA wheeled vehicles.
void SetOwner(AActor *NewOwner) override
virtual void PrePhysTick(float DeltaSeconds) override
std::vector< std::tuple< uint64_t, AActor *, AActor * > > CollisionRegistry
Registry that saves all collisions.
static FActorDefinition GetSensorDefinition()
ACollisionSensor(const FObjectInitializer &ObjectInitializer)
void OnCollisionEvent(AActor *Actor, AActor *OtherActor, FVector NormalImpulse, const FHitResult &Hit)
void OnComponentCollisionEvent(UPrimitiveComponent *HitComp, AActor *OtherActor, UPrimitiveComponent *OtherComp, FVector NormalImpulse, const FHitResult &Hit)
void OnActorCollisionEvent(AActor *Actor, AActor *OtherActor, FVector NormalImpulse, const FHitResult &Hit)
auto GetToken() const
Return the token that allows subscribing to this sensor's stream.
FAsyncDataStream GetDataStream(const SensorT &Self)
Return the FDataStream associated with this sensor.
void SerializeAndSend(SensorT &Sensor, ArgsT &&... Args)
static uint64_t GetFrameCounter()
Definition CarlaEngine.h:65
static FActorDefinition MakeGenericSensorDefinition(const FString &Type, const FString &Id)
static std::shared_ptr< ROS2 > GetInstance()
Definition ROS2.h:51
Serializes a stream endpoint.
A definition of a Carla Actor with all the variation and attributes.