Agrarsense
Sensor.h
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
6#pragma once
7
8#include "CoreMinimal.h"
9#include "GameFramework/Actor.h"
10#include "Engine/EngineTypes.h"
11#include "Engine/World.h"
12#include "Templates/SharedPointer.h"
13#include "UObject/ObjectPtr.h"
14#include "Containers/UnrealString.h"
15#include "Components/PrimitiveComponent.h"
16#include "JsonObjectConverter.h"
17
18#include <vector>
19
20#include "ROSIntegration/Classes/ROSIntegrationGameInstance.h"
21#include "ROSIntegration/Classes/RI/Topic.h"
22
29
30
31#include "Sensor.generated.h"
32
33class ASensorModel;
34
36
37DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FPrimitiveAdded, UPrimitiveComponent*, PrimitiveComponent);
38
42UCLASS()
43class AGRARSENSE_API ASensor : public AActor, public IActorInformation
44{
45 GENERATED_BODY()
46
47public:
48
49 ASensor(const FObjectInitializer& ObjectInitializer);
50
56 UFUNCTION(BlueprintCallable)
57 FString ExportToJsonFile(const FString& FileName);
58
63 UFUNCTION(BlueprintCallable)
64 virtual ESensorTypes GetSensorType() const
65 {
66 return ESensorTypes::NONE;
67 }
68
73 UFUNCTION(BlueprintPure)
74 FString GetSensorIdentifier() const
75 {
76 return SensorIdentifier;
77 }
78
83 UFUNCTION(BlueprintCallable)
84 void SetSensorIdentifier(const FString newIdentifier)
85 {
86 SensorIdentifier = newIdentifier;
87 SetAndValidateActorIDAndName(SensorName, SensorIdentifier, TWeakObjectPtr<AActor>(this));
88 }
89
94 UFUNCTION(BlueprintPure)
95 FString GetSensorName() const
96 {
97 return SensorName;
98 }
99
103 UFUNCTION(BlueprintPure)
104 virtual FString GetParametersAsString() const
105 {
106 return FString();
107 }
108
113 UFUNCTION(BlueprintCallable)
114 void SetSensorName(const FString newName)
115 {
116 SensorName = newName;
117 }
118
123 UFUNCTION(BlueprintPure)
124 virtual FString GetTopicName()
125 {
126 FString Name = "Undefined";
127
128 if (ROSTopic)
129 {
130 Name = ROSTopic->GetName();
131 }
132
133 return Name;
134 }
135
140 UFUNCTION(BlueprintCallable)
141 UTopic* GetROSTopic() const
142 {
143 return ROSTopic;
144 }
145
150 UFUNCTION(BlueprintCallable)
151 void SetSimulateSensor(bool SimulateSensor)
152 {
153 SimulateThisSensor = SimulateSensor;
154 }
155
160 UFUNCTION(BlueprintCallable)
161 inline bool CanSimulateSensor() const
162 {
163 return SimulateThisSensor;
164 }
165
171 UFUNCTION(BlueprintCallable, BlueprintPure)
172 ASensorModel* GetSensorModel() const
173 {
174 return SensorModel.Get();
175 }
176
181 UFUNCTION(BlueprintCallable)
182 void SetSensorModel(ASensorModel* NewSensorModel)
183 {
184 SensorModel = NewSensorModel;
185 }
186
191 UFUNCTION(BlueprintCallable)
192 bool IsROSConnected() const
193 {
194 return ROSConnected;
195 }
196
201 UFUNCTION(BlueprintPure)
202 UROSIntegrationGameInstance* GetROSGameInstance() const
203 {
204 return ROSInstance;
205 }
206
207 virtual FString GetActorID_Implementation() const override
208 {
209 return GetSensorIdentifier();
210 }
211
212 virtual FString GetActorName_Implementation() const override
213 {
214 return GetSensorName();
215 }
216
217 virtual FString GetActorInformation_Implementation() const override
218 {
219 const FString Sensor = UEnumUtilities::ConvertSensorTypeToString(GetSensorType());
220 const FString ID = GetActorID_Implementation();
221 const FTransform VehicleTransform = GetActorTransform();
222 const FVector Location = VehicleTransform.GetLocation();
223 const FRotator Rotation = VehicleTransform.Rotator();
224 const FString Parameters = GetParametersAsString();
225
226 FString Information = FString::Printf(TEXT("Sensor: %s \nID: %s \nLocation: %s \nRotation: %s \nParameters: %s"),
227 *Sensor, *ID, *Location.ToString(), *Rotation.ToString(), *Parameters);
228
229 return Information;
230 }
231
232 virtual void SetActorName_Implementation(const FString& NewActorName) override
233 {
234 SetSensorName(NewActorName);
235 }
236
237 virtual void SetActorIDAndName_Implementation(const FString& NewActorName, const FString& NewID) override
238 {
239 SetSensorName(NewActorName);
240 SetSensorIdentifier(NewID);
241 }
242
247 static void HideComponentForAllCameras(UPrimitiveComponent* PrimitiveComponent);
248
249 UFUNCTION(BlueprintCallable)
250 static TMap<FString, FColor> GetSemanticColors();
251
256 static TArray<TWeakObjectPtr<UPrimitiveComponent>> GetComponentsToHide()
257 {
258 // Since we don't know whether some UPrimitiveComponent has been destroyed,
259 // we need to check these are still valid.
260 ComponentsToHide.RemoveAll([](const TWeakObjectPtr<UPrimitiveComponent>& WeakComponent)
261 {
262 return !WeakComponent.IsValid();
263 });
264
265 return ComponentsToHide;
266 }
267
268 UPROPERTY(BlueprintAssignable)
269 FSensorDestroy OnSensorDestroy;
270
271 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Sensor")
272 FString AttachedToComponent;
273
274 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Sensor")
275 FName AttachedToBone;
276
277protected:
278
279 virtual void BeginPlay() override;
280
281 virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
282
286 virtual void CreateROSTopic();
287
291 virtual void DestroyROSTopic();
292
296 virtual void CreateDataSavePath();
297
304 template<typename InStructType>
305 static FString StructToString(const InStructType& InStruct)
306 {
307 FString AsString;
308 FJsonObjectConverter::UStructToJsonObjectString(InStruct, AsString);
309 return AsString;
310 }
311
315 UFUNCTION(BlueprintCallable, BlueprintPure)
316 bool IsLogFileCreated()
317 {
318 if (LogFile)
319 {
320 return true;
321 }
322
323 return false;
324 }
325
331 UFUNCTION(BlueprintCallable)
332 virtual void CreateLogFile();
333
337 UFUNCTION(BlueprintCallable)
338 void WriteToLogFile(const FString& Message);
339
340 UPROPERTY()
341 UTopic* ROSTopic = nullptr;
342
343 UPROPERTY(VisibleAnywhere, Category = "Sensor")
344 bool SendDataToROS = true;
345
346 UPROPERTY()
347 ULogFile* LogFile = nullptr;
348
349 FString FileSavePath;
350
351 UPROPERTY()
352 UROSIntegrationGameInstance* ROSInstance = nullptr;
353
354 static FPrimitiveAdded OnPrimitiveAdded;
355
356 // Lidar Niagara particle system visualization FName constants
357 inline static const FName NiagaraPointsInt = "User.PointCount";
358 inline static const FName NiagaraHitPoints = "User.HitPoints";
359 inline static const FName NiagaraHitColors = "User.HitColors";
360 inline static const FName NiagaraPointsFloat = "User.Test";
361
362private:
363
368 UFUNCTION()
369 void ROSBridgeStateChanged(EROSState ROSState);
370
371 UPROPERTY()
372 TObjectPtr<ASensorModel> SensorModel;
373
374 UPROPERTY(EditAnywhere, Category = "Sensor")
375 FString SensorIdentifier;
376
377 UPROPERTY(EditAnywhere, Category = "Sensor")
378 FString SensorName;
379
380 UPROPERTY(EditAnywhere, Category = "Sensor")
381 bool SimulateThisSensor = true;
382
383 UPROPERTY(VisibleAnywhere, Category = "Sensor")
384 bool ROSConnected = false;
385
386 static TArray<TWeakObjectPtr<UPrimitiveComponent>> ComponentsToHide;
387
388};
EROSState
Definition: ROSState.h:16
ESensorTypes
Definition: SensorTypes.h:15
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FSensorDestroy, ASensor *, sensor)
Definition: Sensor.h:44
virtual FString GetActorID_Implementation() const override
Definition: Sensor.h:207
static TArray< TWeakObjectPtr< UPrimitiveComponent > > GetComponentsToHide()
Definition: Sensor.h:256
virtual void SetActorName_Implementation(const FString &NewActorName) override
Definition: Sensor.h:232
virtual void SetActorIDAndName_Implementation(const FString &NewActorName, const FString &NewID) override
Definition: Sensor.h:237
virtual FString GetActorName_Implementation() const override
Definition: Sensor.h:212
virtual FString GetActorInformation_Implementation() const override
Definition: Sensor.h:217
static FString ConvertSensorTypeToString(ESensorTypes Sensortype)