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