Agrarsense
SensorsManagerComponent.cpp
Go to the documentation of this file.
1// Copyright (c) 2023 FrostBit Software Lab at the Lapland University of Applied Sciences
2//
3// This work is licensed under the terms of the MIT license.
4// For a copy, see <https://opensource.org/licenses/MIT>.
5
18
19const FString USensorsManagerComponent::ComponentHierarchySeparator = TEXT("_|_");
20
21USensorsManagerComponent::USensorsManagerComponent()
22{
23 PrimaryComponentTick.bCanEverTick = false;
24}
25
26USensorsManagerComponent::~USensorsManagerComponent()
27{
28}
29
30ALidar* USensorsManagerComponent::SpawnLidar(const FTransform& transform, bool isTransformRelativeToComponent, const FString sensorIdentifier, const FString sensorName, FLidarParameters lidarParameters, bool simulateSensor, ASensorModel*& createdModel, USceneComponent* attachToComponent, FName attachToBone)
31{
32 // Check if attachToComponent is not set but attachToBone is set
33 if (!attachToComponent && !attachToBone.IsNone())
34 {
35 attachToComponent = GetOwner()->GetRootComponent();
36 }
37
38 FTransform sensorTransform = isTransformRelativeToComponent ? GetSensorAttachmentTransform(transform, attachToComponent, attachToBone) : transform;
39
40 ALidar* lidar = USensorFactory::SpawnLidarSensor(sensorTransform, sensorIdentifier, sensorName, lidarParameters, simulateSensor, GetOwner());
41
42 if (!lidar)
43 {
44 return nullptr;
45 }
46
47 createdModel = lidar->GetSensorModel();
48
49 ASensor* CastedSensor = Cast<ASensor>(lidar);
50
51 AddSensorDestroyListener(CastedSensor);
52
53 AttachSensor(CastedSensor, attachToComponent, attachToBone);
54
55 Lidars.Emplace(lidar);
56 Sensors.Emplace(CastedSensor);
57
58 OnLidarSpawned.Broadcast(lidar);
59 OnSensorSpawned.Broadcast(CastedSensor);
60
61 return lidar;
62}
63
64ACamera* USensorsManagerComponent::SpawnCamera(const FTransform& transform, bool isTransformRelativeToComponent, const FString sensorIdentifier, const FString sensorName, FCameraBaseParameters cameraParameters, bool simulateSensor, ASensorModel*& createdModel, USceneComponent* attachToComponent, FName attachToBone)
65{
66 // Check if attachToComponent is not set but attachToBone is set
67 if (!attachToComponent && !attachToBone.IsNone())
68 {
69 attachToComponent = GetOwner()->GetRootComponent();
70 }
71
72 FTransform sensorTransform = isTransformRelativeToComponent ? GetSensorAttachmentTransform(transform, attachToComponent, attachToBone) : transform;
73
74 ACamera* camera = USensorFactory::SpawnCamera(sensorTransform, sensorIdentifier, sensorName, cameraParameters, simulateSensor, GetOwner());
75
76 if (!camera)
77 {
78 return nullptr;
79 }
80
81 createdModel = camera->GetSensorModel();
82
83 ASensor* CastedSensor = Cast<ASensor>(camera);
84
85 AttachSensor(CastedSensor, attachToComponent, attachToBone);
86
87 AddSensorDestroyListener(CastedSensor);
88
89 Cameras.Emplace(camera);
90 Sensors.Emplace(CastedSensor);
91
92 camera->OnCameraWindowClosed.AddDynamic(this, &USensorsManagerComponent::OnCameraWindowClosed);
93
94 OnCameraSpawned.Broadcast(camera);
95 OnSensorSpawned.Broadcast(CastedSensor);
96
97 return camera;
98}
99
100AThermalCamera* USensorsManagerComponent::SpawnThermalCamera(const FTransform& transform, bool isTransformRelativeToComponent, const FString sensorIdentifier, const FString sensorName, FThermalCameraParameters thermalCameraParameters, bool simulateSensor, ASensorModel*& createdModel, USceneComponent* attachToComponent, FName attachToBone)
101{
102
103 // Check if attachToComponent is not set but attachToBone is set
104 if (!attachToComponent && !attachToBone.IsNone())
105 {
106 attachToComponent = GetOwner()->GetRootComponent();
107 }
108
109 FTransform sensorTransform = isTransformRelativeToComponent ? GetSensorAttachmentTransform(transform, attachToComponent, attachToBone) : transform;
110
111 AThermalCamera* thermalCamera = USensorFactory::SpawnThermalCamera(sensorTransform, sensorIdentifier, sensorName, thermalCameraParameters, simulateSensor, GetOwner());
112
113 if (!thermalCamera)
114 {
115 return nullptr;
116 }
117
118 createdModel = thermalCamera->GetSensorModel();
119
120 ASensor* CastedSensor = Cast<ASensor>(thermalCamera);
121
122 AttachSensor(CastedSensor, attachToComponent, attachToBone);
123
124 AddSensorDestroyListener(CastedSensor);
125
126 ThermalCameras.Emplace(thermalCamera);
127 Sensors.Emplace(CastedSensor);
128
129 thermalCamera->OnCameraWindowClosed.AddDynamic(this, &USensorsManagerComponent::OnCameraWindowClosed);
130
131 OnThermalCameraSpawned.Broadcast(thermalCamera);
132 OnSensorSpawned.Broadcast(CastedSensor);
133
134 return thermalCamera;
135}
136
137ADVSCamera* USensorsManagerComponent::SpawnDVSCamera(const FTransform& transform, bool isTransformRelativeToComponent, const FString sensorIdentifier, const FString sensorName, FDVSCameraParameters DVSCameraParameters, bool simulateSensor, ASensorModel*& createdModel, USceneComponent* attachToComponent, FName attachToBone)
138{
139 // Check if attachToComponent is not set but attachToBone is set
140 if (!attachToComponent && !attachToBone.IsNone())
141 {
142 attachToComponent = GetOwner()->GetRootComponent();
143 }
144
145 FTransform sensorTransform = isTransformRelativeToComponent ? GetSensorAttachmentTransform(transform, attachToComponent, attachToBone) : transform;
146
147 ADVSCamera* DVSCamera = USensorFactory::SpawnDVSCamera(sensorTransform, sensorIdentifier, sensorName, DVSCameraParameters, simulateSensor, GetOwner());
148
149 if (!DVSCamera)
150 {
151 return nullptr;
152 }
153
154 createdModel = DVSCamera->GetSensorModel();
155
156 ASensor* CastedSensor = Cast<ASensor>(DVSCamera);
157
158 AttachSensor(CastedSensor, attachToComponent, attachToBone);
159
160 AddSensorDestroyListener(CastedSensor);
161
162 DVSCameras.Emplace(DVSCamera);
163 Sensors.Emplace(CastedSensor);
164
165 DVSCamera->OnCameraWindowClosed.AddDynamic(this, &USensorsManagerComponent::OnCameraWindowClosed);
166
167 OnDVSCameraSpawned.Broadcast(DVSCamera);
168 OnSensorSpawned.Broadcast(CastedSensor);
169
170 return DVSCamera;
171}
172
173ASemanticSegmentationCamera* USensorsManagerComponent::SpawnSegmentationCamera(const FTransform& transform, bool isTransformRelativeToComponent, const FString sensorIdentifier, const FString sensorName, FCameraBaseParameters cameraParameters, bool simulateSensor, ASensorModel*& createdModel, USceneComponent* attachToComponent, FName attachToBone)
174{
175 // Check if attachToComponent is not set but attachToBone is set
176 if (!attachToComponent && !attachToBone.IsNone())
177 {
178 attachToComponent = GetOwner()->GetRootComponent();
179 }
180
181 FTransform sensorTransform = isTransformRelativeToComponent ? GetSensorAttachmentTransform(transform, attachToComponent, attachToBone) : transform;
182
183 ASemanticSegmentationCamera* segmentationCamera = USensorFactory::SpawnSegmentationCamera(sensorTransform, sensorIdentifier, sensorName, cameraParameters, simulateSensor, GetOwner());
184
185 if (!segmentationCamera)
186 {
187 return nullptr;
188 }
189
190 createdModel = segmentationCamera->GetSensorModel();
191
192 ASensor* CastedSensor = Cast<ASensor>(segmentationCamera);
193
194 AttachSensor(CastedSensor, attachToComponent, attachToBone);
195
196 AddSensorDestroyListener(CastedSensor);
197
198 SegmentationCameras.Emplace(segmentationCamera);
199 Sensors.Emplace(CastedSensor);
200
201 segmentationCamera->OnCameraWindowClosed.AddDynamic(this, &USensorsManagerComponent::OnCameraWindowClosed);
202
203 OnSegmentationCameraSpawned.Broadcast(segmentationCamera);
204 OnSensorSpawned.Broadcast(CastedSensor);
205
206 return segmentationCamera;
207}
208
209AInstanceSegmentationCamera* USensorsManagerComponent::SpawnInstanceSegmentationCamera(const FTransform& transform, bool isTransformRelativeToComponent, const FString sensorIdentifier, const FString sensorName, FCameraBaseParameters CameraParameters, bool simulateSensor, ASensorModel*& createdModel, USceneComponent* attachToComponent, FName attachToBone)
210{
211 // Check if attachToComponent is not set but attachToBone is set
212 if (!attachToComponent && !attachToBone.IsNone())
213 {
214 attachToComponent = GetOwner()->GetRootComponent();
215 }
216
217 FTransform sensorTransform = isTransformRelativeToComponent ? GetSensorAttachmentTransform(transform, attachToComponent, attachToBone) : transform;
218
219 AInstanceSegmentationCamera* InstanceSegmentationCamera = USensorFactory::SpawnInstanceSegmentationCamera(sensorTransform, sensorIdentifier, sensorName, CameraParameters, simulateSensor, GetOwner());
220
221 if (!InstanceSegmentationCamera)
222 {
223 return nullptr;
224 }
225
226 createdModel = InstanceSegmentationCamera->GetSensorModel();
227
228 ASensor* CastedSensor = Cast<ASensor>(InstanceSegmentationCamera);
229
230 AttachSensor(CastedSensor, attachToComponent, attachToBone);
231
232 AddSensorDestroyListener(CastedSensor);
233
234 InstanceSegmentationCameras.Emplace(InstanceSegmentationCamera);
235 Sensors.Emplace(CastedSensor);
236
237 InstanceSegmentationCamera->OnCameraWindowClosed.AddDynamic(this, &USensorsManagerComponent::OnCameraWindowClosed);
238
239 OnInstanceSegmentationCameraSpawned.Broadcast(InstanceSegmentationCamera);
240 OnSensorSpawned.Broadcast(CastedSensor);
241
243}
244
245ADepthCamera* USensorsManagerComponent::SpawnDepthCamera(const FTransform& transform, bool isTransformRelativeToComponent, const FString sensorIdentifier, const FString sensorName, FDepthCameraParameters DepthCameraParameters, bool simulateSensor, ASensorModel*& createdModel, USceneComponent* attachToComponent, FName attachToBone)
246{
247 // Check if attachToComponent is not set but attachToBone is set
248 if (!attachToComponent && !attachToBone.IsNone())
249 {
250 attachToComponent = GetOwner()->GetRootComponent();
251 }
252
253 FTransform sensorTransform = isTransformRelativeToComponent ? GetSensorAttachmentTransform(transform, attachToComponent, attachToBone) : transform;
254
255 ADepthCamera* depthCamera = USensorFactory::SpawnDepthCamera(sensorTransform, sensorIdentifier, sensorName, DepthCameraParameters, simulateSensor, GetOwner());
256
257 if (!depthCamera)
258 {
259 return nullptr;
260 }
261
262 createdModel = depthCamera->GetSensorModel();
263
264 ASensor* CastedSensor = Cast<ASensor>(depthCamera);
265
266 AttachSensor(CastedSensor, attachToComponent, attachToBone);
267
268 AddSensorDestroyListener(CastedSensor);
269
270 DepthCameras.Emplace(depthCamera);
271 Sensors.Emplace(CastedSensor);
272
273 depthCamera->OnCameraWindowClosed.AddDynamic(this, &USensorsManagerComponent::OnCameraWindowClosed);
274
275 OnDepthCameraSpawned.Broadcast(depthCamera);
276 OnSensorSpawned.Broadcast(CastedSensor);
277
278 return depthCamera;
279}
280
281ARadar* USensorsManagerComponent::SpawnRadar(const FTransform& transform, bool isTransformRelativeToComponent, const FString sensorIdentifier, const FString sensorName, FRadarParameters radarParameters, bool simulateSensor, ASensorModel*& createdModel, USceneComponent* attachToComponent, FName attachToBone)
282{
283 // Check if attachToComponent is not set but attachToBone is set
284 if (!attachToComponent && !attachToBone.IsNone())
285 {
286 attachToComponent = GetOwner()->GetRootComponent();
287 }
288
289 FTransform sensorTransform = isTransformRelativeToComponent ? GetSensorAttachmentTransform(transform, attachToComponent, attachToBone) : transform;
290
291 ARadar* radar = USensorFactory::SpawnRadar(sensorTransform, sensorIdentifier, sensorName, radarParameters, simulateSensor, GetOwner());
292
293 if (!radar)
294 {
295 return nullptr;
296 }
297
298 createdModel = radar->GetSensorModel();
299
300 ASensor* CastedSensor = Cast<ASensor>(radar);
301
302 AttachSensor(CastedSensor, attachToComponent, attachToBone);
303
304 AddSensorDestroyListener(CastedSensor);
305
306 Radars.Emplace(radar);
307 Sensors.Emplace(CastedSensor);
308
309 OnRadarSpawned.Broadcast(radar);
310 OnSensorSpawned.Broadcast(CastedSensor);
311
312 return radar;
313}
314
315ASensor* USensorsManagerComponent::SpawnSensor(const FTransform& transform, bool isTransformRelativeToComponent, const FString sensorIdentifier, const FString sensorName, ESensorTypes sensorType, bool simulateSensor, ASensorModel*& createdModel, USceneComponent* attachToComponent, FName attachToBone)
316{
317 ASensor* sensor = nullptr;
318
319 switch (sensorType)
320 {
322 sensor = Cast<ASensor>(SpawnLidar(transform, isTransformRelativeToComponent, sensorIdentifier, sensorName, FLidarParameters(), simulateSensor, createdModel, attachToComponent, attachToBone));
323 break;
325 sensor = Cast<ASensor>(SpawnCamera(transform, isTransformRelativeToComponent, sensorIdentifier, sensorName, FCameraBaseParameters(), simulateSensor, createdModel, attachToComponent, attachToBone));
326 break;
328 sensor = Cast<ASensor>(SpawnThermalCamera(transform, isTransformRelativeToComponent, sensorIdentifier, sensorName, FThermalCameraParameters(), simulateSensor, createdModel, attachToComponent, attachToBone));
329 break;
331 sensor = Cast<ASensor>(SpawnDVSCamera(transform, isTransformRelativeToComponent, sensorIdentifier, sensorName, FDVSCameraParameters(), simulateSensor, createdModel, attachToComponent, attachToBone));
332 break;
334 sensor = Cast<ASensor>(SpawnSegmentationCamera(transform, isTransformRelativeToComponent, sensorIdentifier, sensorName, FCameraBaseParameters(), simulateSensor, createdModel, attachToComponent, attachToBone));
335 break;
337 sensor = Cast<ASensor>(SpawnDepthCamera(transform, isTransformRelativeToComponent, sensorIdentifier, sensorName, FDepthCameraParameters(), simulateSensor, createdModel, attachToComponent, attachToBone));
338 break;
340 sensor = Cast<ASensor>(SpawnRadar(transform, isTransformRelativeToComponent, sensorIdentifier, sensorName, FRadarParameters(), simulateSensor, createdModel, attachToComponent, attachToBone));
341 break;
342 default:
343 break;
344 }
345
346 return sensor;
347}
348
349void USensorsManagerComponent::DestroyLidar(ALidar* lidarToDestroy)
350{
351 if (lidarToDestroy)
352 {
353 FString sensorIdentifier = lidarToDestroy->GetSensorIdentifier();
354 Lidars.Remove(lidarToDestroy);
355
356 ASensor* CastedSensor = Cast<ASensor>(lidarToDestroy);
357
358 RemoveSensorDestroyListener(CastedSensor);
359
360 Sensors.Remove(CastedSensor);
361 DestroySensorActor(CastedSensor);
362
363 OnLidarDestroyed.Broadcast(sensorIdentifier);
364 OnSensorDestroyed.Broadcast(ESensorTypes::Lidar, sensorIdentifier);
365 }
366}
367
368void USensorsManagerComponent::DestroyCamera(ACamera* cameraToDestroy)
369{
370 if (cameraToDestroy)
371 {
372 FString sensorIdentifier = cameraToDestroy->GetSensorIdentifier();
373
374 cameraToDestroy->OnCameraWindowClosed.RemoveDynamic(this, &USensorsManagerComponent::OnCameraWindowClosed);
375 Cameras.Remove(cameraToDestroy);
376
377 ASensor* CastedSensor = Cast<ASensor>(cameraToDestroy);
378
379 RemoveSensorDestroyListener(CastedSensor);
380
381 Sensors.Remove(CastedSensor);
382 DestroySensorActor(CastedSensor);
383
384 OnCameraDestroyed.Broadcast(sensorIdentifier);
385 OnSensorDestroyed.Broadcast(ESensorTypes::RGBCamera, sensorIdentifier);
386 }
387}
388
389void USensorsManagerComponent::DestroyThermalCamera(AThermalCamera* thermalCameraToDestroy)
390{
391 if (thermalCameraToDestroy)
392 {
393 FString sensorIdentifier = thermalCameraToDestroy->GetSensorIdentifier();
394
395 thermalCameraToDestroy->OnCameraWindowClosed.RemoveDynamic(this, &USensorsManagerComponent::OnCameraWindowClosed);
396 ThermalCameras.Remove(thermalCameraToDestroy);
397
398 ASensor* CastedSensor = Cast<ASensor>(thermalCameraToDestroy);
399
400 RemoveSensorDestroyListener(CastedSensor);
401
402 Sensors.Remove(CastedSensor);
403 DestroySensorActor(CastedSensor);
404
405 OnThermalCameraDestroyed.Broadcast(sensorIdentifier);
406 OnSensorDestroyed.Broadcast(ESensorTypes::ThermalCamera, sensorIdentifier);
407 }
408}
409
410void USensorsManagerComponent::DestroyDVSCamera(ADVSCamera* DVSCameraToDestroy)
411{
412 if (DVSCameraToDestroy)
413 {
414 FString sensorIdentifier = DVSCameraToDestroy->GetSensorIdentifier();
415
416 DVSCameraToDestroy->OnCameraWindowClosed.RemoveDynamic(this, &USensorsManagerComponent::OnCameraWindowClosed);
417 DVSCameras.Remove(DVSCameraToDestroy);
418
419 ASensor* CastedSensor = Cast<ASensor>(DVSCameraToDestroy);
420
421 RemoveSensorDestroyListener(CastedSensor);
422
423 Sensors.Remove(CastedSensor);
424 DestroySensorActor(CastedSensor);
425
426 OnDVSCameraDestroyed.Broadcast(sensorIdentifier);
427 OnSensorDestroyed.Broadcast(ESensorTypes::DVSCamera, sensorIdentifier);
428 }
429}
430
431void USensorsManagerComponent::DestroySegmentationCamera(ASemanticSegmentationCamera* segmentationCameraToDestroy)
432{
433 if (segmentationCameraToDestroy)
434 {
435 FString sensorIdentifier = segmentationCameraToDestroy->GetSensorIdentifier();
436
437 segmentationCameraToDestroy->OnCameraWindowClosed.RemoveDynamic(this, &USensorsManagerComponent::OnCameraWindowClosed);
438 SegmentationCameras.Remove(segmentationCameraToDestroy);
439
440 ASensor* CastedSensor = Cast<ASensor>(segmentationCameraToDestroy);
441
442 RemoveSensorDestroyListener(CastedSensor);
443
444 Sensors.Remove(CastedSensor);
445 DestroySensorActor(CastedSensor);
446
447 OnSegmentationCameraDestroyed.Broadcast(sensorIdentifier);
448 OnSensorDestroyed.Broadcast(ESensorTypes::SemanticSegmentationCamera, sensorIdentifier);
449 }
450}
451
452void USensorsManagerComponent::DestroyDepthCamera(ADepthCamera* depthCameraToDestroy)
453{
454 if (depthCameraToDestroy)
455 {
456 FString sensorIdentifier = depthCameraToDestroy->GetSensorIdentifier();
457
458 depthCameraToDestroy->OnCameraWindowClosed.RemoveDynamic(this, &USensorsManagerComponent::OnCameraWindowClosed);
459 DepthCameras.Remove(depthCameraToDestroy);
460
461 ASensor* CastedSensor = Cast<ASensor>(depthCameraToDestroy);
462
463 RemoveSensorDestroyListener(CastedSensor);
464
465 Sensors.Remove(CastedSensor);
466 DestroySensorActor(CastedSensor);
467
468 OnDepthCameraDestroyed.Broadcast(sensorIdentifier);
469 OnSensorDestroyed.Broadcast(ESensorTypes::DepthCamera, sensorIdentifier);
470 }
471}
472
473void USensorsManagerComponent::DestroyRadar(ARadar* radarToDestroy)
474{
475 if (radarToDestroy)
476 {
477 FString sensorIdentifier = radarToDestroy->GetSensorIdentifier();
478
479 Radars.Remove(radarToDestroy);
480
481 ASensor* CastedSensor = Cast<ASensor>(radarToDestroy);
482
483 RemoveSensorDestroyListener(CastedSensor);
484
485 Sensors.Remove(CastedSensor);
486 DestroySensorActor(CastedSensor);
487
488 OnRadarDestroyed.Broadcast(sensorIdentifier);
489 OnSensorDestroyed.Broadcast(ESensorTypes::Radar, sensorIdentifier);
490 }
491}
492
493void USensorsManagerComponent::DestroySensor(ASensor* sensorToDestroy)
494{
495 if (sensorToDestroy)
496 {
497 ESensorTypes sensorType = sensorToDestroy->GetSensorType();
498
499 switch (sensorType)
500 {
502 DestroyLidar(Cast<ALidar>(sensorToDestroy));
503 break;
505 DestroyCamera(Cast<ACamera>(sensorToDestroy));
506 break;
508 DestroyThermalCamera(Cast<AThermalCamera>(sensorToDestroy));
509 break;
511 DestroyDVSCamera(Cast<ADVSCamera>(sensorToDestroy));
512 break;
514 DestroySegmentationCamera(Cast<ASemanticSegmentationCamera>(sensorToDestroy));
515 break;
517 DestroyDepthCamera(Cast<ADepthCamera>(sensorToDestroy));
518 break;
520 DestroyRadar(Cast<ARadar>(sensorToDestroy));
521 break;
522 default:
523 break;
524 }
525 }
526}
527
528void USensorsManagerComponent::DestroyAllSensors()
529{
530 TArray<ASensor*> SensorsTempArray = Sensors;
531
532 for (const auto& sensor : SensorsTempArray)
533 {
534 DestroySensor(sensor);
535 }
536}
537
538FTransform USensorsManagerComponent::SensorRelativeTransformToWorld(const FTransform& relativeTransform)
539{
540 AActor* owner = GetOwner();
541 return relativeTransform * owner->GetActorTransform();
542}
543
544FTransform USensorsManagerComponent::SensorRelativeTransformToComponentWorld(const FTransform& relativeTransform, const FTransform& componentTransformWorld)
545{
546 return relativeTransform * componentTransformWorld;
547}
548
549FTransform USensorsManagerComponent::GetSensorAttachmentTransform(const FTransform& sensorRelativeTransform, USceneComponent* attachToComponent, const FName& attachToBone, bool revertScaleToVectorOne)
550{
551 FTransform worldTransform;
552
553 // Calculate worldTransform based on attachToComponent availability
554 if (attachToComponent)
555 {
556 worldTransform = SensorRelativeTransformToComponentWorld(sensorRelativeTransform, attachToComponent->GetSocketTransform(attachToBone));
557 }
558 else
559 {
560 worldTransform = SensorRelativeTransformToWorld(sensorRelativeTransform);
561 }
562
563 if (revertScaleToVectorOne)
564 {
565 worldTransform.SetScale3D(FVector(1, 1, 1));
566 }
567
568 return worldTransform;
569}
570
571USceneComponent* USensorsManagerComponent::GetComponentByHierarchyName(FString hierarchyName)
572{
573
574 // Array to hold the split parts
575 TArray<FString> componentNames;
576
577 AActor* owner = GetOwner();
578
579 // Always fallback to owner root component
580 USceneComponent* matchingComponent = owner->GetRootComponent();
581
582 // Split the hierarchy
583 hierarchyName.ParseIntoArray(componentNames, *ComponentHierarchySeparator, true);
584
585 if (componentNames.Num() > 0)
586 {
587 // Search for the initial component using the first element in the split array
588 FString initialComponentName = componentNames[0];
589 USceneComponent* initialComponent = nullptr;
590 bool skipFirstComponentName = true;
591
592 TArray<USceneComponent*> ownerComponents;
593 owner->GetComponents<USceneComponent>(ownerComponents);
594
595 // Iterate over owner's components to find the initial component
596 for (USceneComponent* childComponent : ownerComponents)
597 {
598 if (childComponent && childComponent->GetName() == initialComponentName)
599 {
600 initialComponent = childComponent;
601 matchingComponent = initialComponent;
602 break;
603 }
604 }
605
606 if (!initialComponent)
607 {
608 // UE_LOG(LogTemp, Warning, TEXT("Initial component '%s' not found. Fallback to using owner root component"), *initialComponentName);
609
610 initialComponent = owner->GetRootComponent();
611
612 skipFirstComponentName = false;
613 }
614
615 USceneComponent* currentComponent = initialComponent;
616
617 // Check if there is more components to search through.
618 if (currentComponent && componentNames.Num() > (skipFirstComponentName ? 1 : 0))
619 {
620 // Flag to check if the component with the given name is found
621 bool bComponentFound = false;
622
623 // Iterate over each part of the hierarchy
624 for (int32 i = (skipFirstComponentName ? 1 : 0); i < componentNames.Num(); ++i)
625 {
626 FString componentName = componentNames[i];
627
628 bComponentFound = false;
629
630 // Loop through the child components of the current component
631 for (USceneComponent* childComponent : currentComponent->GetAttachChildren())
632 {
633 FString childComponentName = childComponent->GetName();
634
635 // Check if the child component's name matches the current part of the split string
636 // UE_LOG(LogTemp, Warning, TEXT("Compare between %s and %s."), *childComponentName, *componentName);
637
638 if (childComponent && childComponent->GetName() == componentName)
639 {
640 // Match found, update the current component
641 currentComponent = childComponent;
642 bComponentFound = true;
643 // break out of this inner component search loop
644 break;
645 }
646 }
647
648 // If the component was not found, can't continue the search anymore
649 if (!bComponentFound)
650 {
651 // Component not found, break out of the loop or handle as needed
652 UE_LOG(LogTemp, Warning, TEXT("Component '%s' not found. Breaking out of the loop"), *componentName);
653 // break out of the whole search loop
654 break;
655 }
656 }
657
658 // At this point, CurrentComponent should point to the component matching the hierarchy
659 if (bComponentFound)
660 {
661 FString foundComponentName = currentComponent->GetName();
662 matchingComponent = currentComponent;
663 }
664 else
665 {
666 // Component not found, handle as needed
667 UE_LOG(LogTemp, Warning, TEXT("Component not found"));
668 }
669 }
670 }
671
672 return matchingComponent;
673}
674
675void USensorsManagerComponent::AttachSensorToOwner(ASensor* sensor)
676{
677 // Owner is probably a vehicle
678 AActor* owner = GetOwner();
679
680 // Parent sensor to the owner of this component (vehicle)
681 AttachSensorToActor(sensor, owner);
682}
683
684void USensorsManagerComponent::AttachSensorToActor(ASensor* sensor, AActor* attachToActor)
685{
686 if (sensor && attachToActor)
687 {
688 sensor->AttachToActor(attachToActor, FAttachmentTransformRules::KeepWorldTransform);
689 sensor->AttachedToComponent = FString();
690 sensor->AttachedToBone = NAME_None;
691 }
692}
693
694void USensorsManagerComponent::AttachSensorToBone(ASensor* sensor, USceneComponent* attachToComponent, const FName& boneName)
695{
696 if (!sensor || !attachToComponent)
697 {
698 return;
699 }
700
701 if (IsValid(attachToComponent))
702 {
703 sensor->AttachToComponent(attachToComponent, FAttachmentTransformRules::KeepWorldTransform, boneName);
704
705 USceneComponent* currentParentComponent = attachToComponent->GetAttachParent();
706
707 // FString fullComponentName = FString();
708 FString fullComponentName = attachToComponent->GetName();
709
710 // If this does not have a parent, this is the highest attach parent which we will not include
711 if (currentParentComponent)
712 {
713 fullComponentName = attachToComponent->GetName();
714
715 // Skip the highest attach parent which should be the owner itself. Having only the currentParentComponent-check would include the owner as well.
716 while (currentParentComponent && currentParentComponent->GetAttachParent())
717 {
718 FString ParentComponentName = currentParentComponent->GetName();
719 // Prepend the parent's name into the full component name like ParentComponent_|_ChildComponent.
720 // This could have been a TArray<FString> because that can be also saved easily
721 fullComponentName = FString::Format(TEXT("{0}{1}{2}"), { *ParentComponentName, *ComponentHierarchySeparator, *fullComponentName });
722
723 // Move to the next parent
724 currentParentComponent = currentParentComponent->GetAttachParent();
725 }
726 }
727
728 sensor->AttachedToComponent = fullComponentName;
729 sensor->AttachedToBone = boneName;
730
731 //UE_LOG(LogTemp, Warning, TEXT("Full component name: %s"), *fullComponentName);
732 }
733}
734
735void USensorsManagerComponent::AttachSensor(ASensor* sensor, USceneComponent* attachToComponent, const FName& boneName)
736{
737 // If attachToComponent is valid OR if the boneName is set.
738 if (IsValid(attachToComponent) || !boneName.IsNone())
739 {
740 AttachSensorToBone(sensor, attachToComponent, boneName);
741 }
742 else
743 {
744 AttachSensorToOwner(sensor);
745 }
746}
747
748void USensorsManagerComponent::DestroySensorActor(AActor* sensorActor)
749{
750 if (!sensorActor)
751 {
752 return;
753 }
754
755 TArray<AActor*> attachedActors;
756 sensorActor->GetAttachedActors(attachedActors);
757
758 for (AActor* CActor : attachedActors)
759 {
760 if (CActor)
761 {
762 CActor->Destroy();
763 }
764 }
765
766 sensorActor->Destroy();
767}
768
769void USensorsManagerComponent::LoadPreset(FVehicleSensorsPreset preset, bool simulateSensors)
770{
771 DestroyAllSensors();
772
773 for (const auto& LidarData : preset.LidarDatas)
774 {
775 FSensorPreset sensorData = LidarData.SensorData;
776 FTransform sensorTransform(sensorData.Rotation, sensorData.Location);
777
778 USceneComponent* attachToComponent = GetComponentByHierarchyName(sensorData.AttachedToComponent);
779 FName attachToBone = sensorData.AttachedToBone;
780
781 ASensorModel* createdModel = nullptr;
782
783 SpawnLidar(sensorTransform, true, sensorData.SensorIdentifier, sensorData.SensorName, LidarData.LidarParameters, simulateSensors, createdModel, attachToComponent, attachToBone);
784 }
785
786 for (const auto& RadarData : preset.RadarDatas)
787 {
788 FSensorPreset sensorData = RadarData.SensorData;
789 FTransform sensorTransform(sensorData.Rotation, sensorData.Location);
790
791 USceneComponent* attachToComponent = GetComponentByHierarchyName(sensorData.AttachedToComponent);
792 FName attachToBone = sensorData.AttachedToBone;
793
794 ASensorModel* createdModel = nullptr;
795
796 SpawnRadar(sensorTransform, true, sensorData.SensorIdentifier, sensorData.SensorName, RadarData.RadarParameters, simulateSensors, createdModel, attachToComponent, attachToBone);
797 }
798
799 for (const auto& CameraData : preset.CameraDatas)
800 {
801 FSensorPreset sensorData = CameraData.SensorData;
802
803 FTransform sensorTransform(sensorData.Rotation, sensorData.Location);
804
805 USceneComponent* attachToComponent = GetComponentByHierarchyName(sensorData.AttachedToComponent);
806 FName attachToBone = sensorData.AttachedToBone;
807
808 ASensorModel* createdModel = nullptr;
809
810 SpawnCamera(sensorTransform, true, sensorData.SensorIdentifier, sensorData.SensorName, CameraData.CameraParameters, simulateSensors, createdModel, attachToComponent, attachToBone);
811 }
812
813 for (const auto& CameraData : preset.ThermalCameraDatas)
814 {
815 FSensorPreset sensorData = CameraData.SensorData;
816
817 FTransform sensorTransform(sensorData.Rotation, sensorData.Location);
818
819 USceneComponent* attachToComponent = GetComponentByHierarchyName(sensorData.AttachedToComponent);
820 FName attachToBone = sensorData.AttachedToBone;
821
822 ASensorModel* createdModel = nullptr;
823
824 SpawnThermalCamera(sensorTransform, true, sensorData.SensorIdentifier, sensorData.SensorName, CameraData.CameraParameters, simulateSensors, createdModel, attachToComponent, attachToBone);
825 }
826
827 for (const auto& CameraData : preset.DVSCameraDatas)
828 {
829 FSensorPreset sensorData = CameraData.SensorData;
830
831 FTransform sensorTransform(sensorData.Rotation, sensorData.Location);
832
833 USceneComponent* attachToComponent = GetComponentByHierarchyName(sensorData.AttachedToComponent);
834 FName attachToBone = sensorData.AttachedToBone;
835
836 ASensorModel* createdModel = nullptr;
837
838 SpawnDVSCamera(sensorTransform, true, sensorData.SensorIdentifier, sensorData.SensorName, CameraData.DVSCameraParameters, simulateSensors, createdModel, attachToComponent, attachToBone);
839 }
840
841 for (const auto& CameraData : preset.SegmentationCameraDatas)
842 {
843 FSensorPreset sensorData = CameraData.SensorData;
844
845 FTransform sensorTransform(sensorData.Rotation, sensorData.Location);
846
847 USceneComponent* attachToComponent = GetComponentByHierarchyName(sensorData.AttachedToComponent);
848 FName attachToBone = sensorData.AttachedToBone;
849
850 ASensorModel* createdModel = nullptr;
851
852 SpawnSegmentationCamera(sensorTransform, true, sensorData.SensorIdentifier, sensorData.SensorName, CameraData.CameraParameters, simulateSensors, createdModel, attachToComponent, attachToBone);
853 }
854
855 for (const auto& CameraData : preset.DepthCameraDatas)
856 {
857 FSensorPreset sensorData = CameraData.SensorData;
858
859 FTransform sensorTransform(sensorData.Rotation, sensorData.Location);
860
861 USceneComponent* attachToComponent = GetComponentByHierarchyName(sensorData.AttachedToComponent);
862 FName attachToBone = sensorData.AttachedToBone;
863
864 ASensorModel* createdModel = nullptr;
865
866 SpawnDepthCamera(sensorTransform, true, sensorData.SensorIdentifier, sensorData.SensorName, CameraData.CameraParameters, simulateSensors, createdModel, attachToComponent, attachToBone);
867 }
868}
869
870FVehicleSensorsPreset USensorsManagerComponent::GetSensorsAsPreset()
871{
873
874 for (const auto& Lidar : Lidars)
875 {
876 FSensorPreset sensorPreset = GetSensorPreset(Cast<ASensor>(Lidar));
877 FLidarPreset lidarPreset;
878 lidarPreset.SensorData = sensorPreset;
879 lidarPreset.LidarParameters = Lidar->GetLidarParameters();
880
881 preset.LidarDatas.Add(lidarPreset);
882 }
883
884 for (const auto& Radar : Radars)
885 {
886 FSensorPreset sensorPreset = GetSensorPreset(Cast<ASensor>(Radar));
887 FRadarPreset radarPreset;
888 radarPreset.SensorData = sensorPreset;
889 radarPreset.RadarParameters = Radar->GetRadarParameters();
890
891 preset.RadarDatas.Add(radarPreset);
892 }
893
894 for (const auto& Camera : Cameras)
895 {
896 FSensorPreset sensorPreset = GetSensorPreset(Cast<ASensor>(Camera));
897 FCameraPreset cameraPreset;
898 cameraPreset.SensorData = sensorPreset;
899 cameraPreset.CameraParameters = Camera->GetCameraParameters();
900 preset.CameraDatas.Add(cameraPreset);
901 }
902
903 for (const auto& ThermalCamera : ThermalCameras)
904 {
905 FSensorPreset sensorPreset = GetSensorPreset(Cast<ASensor>(ThermalCamera));
906 FThermalCameraPreset cameraPreset;
907 cameraPreset.SensorData = sensorPreset;
908 cameraPreset.CameraParameters = ThermalCamera->GetThermalCameraParameters();
909 preset.ThermalCameraDatas.Add(cameraPreset);
910 }
911
912 for (const auto& DVSCamera : DVSCameras)
913 {
914 FSensorPreset sensorPreset = GetSensorPreset(Cast<ASensor>(DVSCamera));
915 FDVSCameraPreset cameraPreset;
916 cameraPreset.SensorData = sensorPreset;
917 cameraPreset.DVSCameraParameters = DVSCamera->GetDVSCameraParameters();
918 preset.DVSCameraDatas.Add(cameraPreset);
919 }
920
921 for (const auto& SegmentationCamera : SegmentationCameras)
922 {
923 FSensorPreset sensorPreset = GetSensorPreset(Cast<ASensor>(SegmentationCamera));
925 cameraPreset.SensorData = sensorPreset;
926 cameraPreset.CameraParameters = SegmentationCamera->GetCameraParameters();
927 preset.SegmentationCameraDatas.Add(cameraPreset);
928 }
929
930 for (const auto& DepthCamera : DepthCameras)
931 {
932 FSensorPreset sensorPreset = GetSensorPreset(Cast<ASensor>(DepthCamera));
933 FDepthCameraPreset cameraPreset;
934 cameraPreset.SensorData = sensorPreset;
935 cameraPreset.CameraParameters = DepthCamera->GetDepthCameraParameters();
936 preset.DepthCameraDatas.Add(cameraPreset);
937 }
938
939 return preset;
940}
941
942FSensorPreset USensorsManagerComponent::GetSensorPreset(ASensor* sensor)
943{
944 FSensorPreset sensorPreset;
945
946 FTransform relativeTransform = sensor->GetRootComponent()->GetRelativeTransform();
947
948 sensorPreset.Location = relativeTransform.GetLocation();
949 sensorPreset.Rotation = relativeTransform.Rotator();
950 sensorPreset.SensorIdentifier = sensor->GetSensorIdentifier();
951 sensorPreset.SensorName = sensor->GetSensorName();
952 sensorPreset.SensorType = sensor->GetSensorType();
953 sensorPreset.AttachedToComponent = sensor->AttachedToComponent;
954 sensorPreset.AttachedToBone = sensor->AttachedToBone;
955
956 return sensorPreset;
957}
958
959void USensorsManagerComponent::AddSensorDestroyListener(ASensor* sensor)
960{
961 if (sensor)
962 {
963 sensor->OnSensorDestroy.AddDynamic(this, &USensorsManagerComponent::OnSensorDestroy);
964 }
965}
966
967void USensorsManagerComponent::RemoveSensorDestroyListener(ASensor* sensor)
968{
969 if (sensor)
970 {
971 sensor->OnSensorDestroy.RemoveDynamic(this, &USensorsManagerComponent::OnSensorDestroy);
972 }
973}
974
975void USensorsManagerComponent::OnCameraWindowClosed(ACamera* camera)
976{
977 if (camera)
978 {
979 ASensor* CastedSensor = Cast<ASensor>(camera);
980 DestroySensor(CastedSensor);
981 }
982}
983
984void USensorsManagerComponent::OnSensorDestroy(ASensor* sensor)
985{
986 if (sensor)
987 {
988 // Calling this will actually try to remove the sensor again but I think that is OK
989 DestroySensor(sensor);
990 }
991}
ESensorTypes
Definition: SensorTypes.h:15
@ SemanticSegmentationCamera
@ InstanceSegmentationCamera
Definition: Camera.h:53
FCameraDelegate_OnWindowClosed OnCameraWindowClosed
Definition: Camera.h:141
Definition: Lidar.h:35
Definition: Radar.h:26
Definition: Sensor.h:45
FSensorDestroy OnSensorDestroy
Definition: Sensor.h:283
FString GetSensorIdentifier() const
Definition: Sensor.h:75
FString GetSensorName() const
Definition: Sensor.h:96
virtual ESensorTypes GetSensorType() const
Definition: Sensor.h:65
FString AttachedToComponent
Definition: Sensor.h:286
ASensorModel * GetSensorModel() const
Definition: Sensor.h:181
FName AttachedToBone
Definition: Sensor.h:289
static ASemanticSegmentationCamera * SpawnSegmentationCamera(const FTransform &transform, const FString sensorIdentifier, const FString sensorName, FCameraBaseParameters cameraParameters, bool SimulateSensor=true, AActor *Parent=nullptr)
static ARadar * SpawnRadar(const FTransform &transform, const FString sensorIdentifier, const FString sensorName, FRadarParameters radarParameters, bool SimulateSensor=true, AActor *Parent=nullptr)
static ADVSCamera * SpawnDVSCamera(const FTransform &transform, const FString sensorIdentifier, const FString sensorName, FDVSCameraParameters DVSCameraParameters, bool SimulateSensor, AActor *Parent=nullptr)
static AInstanceSegmentationCamera * SpawnInstanceSegmentationCamera(const FTransform &transform, const FString sensorIdentifier, const FString sensorName, FCameraBaseParameters cameraParameters, bool SimulateSensor=true, AActor *Parent=nullptr)
static ALidar * SpawnLidarSensor(const FTransform &transform, const FString sensorIdentifier, const FString sensorName, FLidarParameters lidarParameters, bool SimulateSensor=true, AActor *Parent=nullptr)
static ACamera * SpawnCamera(const FTransform &transform, const FString sensorIdentifier, const FString sensorName, FCameraBaseParameters cameraParameters, bool SimulateSensor=true, AActor *Parent=nullptr)
static ADepthCamera * SpawnDepthCamera(const FTransform &transform, const FString sensorIdentifier, const FString sensorName, FDepthCameraParameters depthCameraParameters, bool SimulateSensor=true, AActor *Parent=nullptr)
static AThermalCamera * SpawnThermalCamera(const FTransform &transform, const FString sensorIdentifier, const FString sensorName, FThermalCameraParameters thermalCameraParameters, bool SimulateSensor=true, AActor *Parent=nullptr)
FCameraBaseParameters CameraParameters
Definition: CameraPreset.h:30
FSensorPreset SensorData
Definition: CameraPreset.h:24
FSensorPreset SensorData
FDVSCameraParameters DVSCameraParameters
FDepthCameraParameters CameraParameters
FSensorPreset SensorData
FSensorPreset SensorData
Definition: LidarPreset.h:24
FLidarParameters LidarParameters
Definition: LidarPreset.h:30
FSensorPreset SensorData
Definition: RadarPreset.h:24
FRadarParameters RadarParameters
Definition: RadarPreset.h:30
FRotator Rotation
Definition: SensorPreset.h:50
FString SensorName
Definition: SensorPreset.h:32
ESensorTypes SensorType
Definition: SensorPreset.h:38
FString SensorIdentifier
Definition: SensorPreset.h:26
FName AttachedToBone
Definition: SensorPreset.h:56
FString AttachedToComponent
Definition: SensorPreset.h:53
FVector Location
Definition: SensorPreset.h:44
FThermalCameraParameters CameraParameters
TArray< FRadarPreset > RadarDatas
TArray< FLidarPreset > LidarDatas
TArray< FThermalCameraPreset > ThermalCameraDatas
TArray< FDVSCameraPreset > DVSCameraDatas
TArray< FSemanticSegmentationCameraPreset > SegmentationCameraDatas
TArray< FCameraPreset > CameraDatas
TArray< FDepthCameraPreset > DepthCameraDatas