Agrarsense
Vehicle.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
6#include "Vehicle.h"
7
13
17
18#include "Kismet/GameplayStatics.h"
19#include "NiagaraFunctionLibrary.h"
20#include "NiagaraComponent.h"
21#include "NiagaraSystem.h"
22
24{
25 PrimaryActorTick.bCanEverTick = false;
26 SensorsManager = CreateDefaultSubobject<USensorsManagerComponent>(TEXT("SensorsManagerComp"));
27 InteractableName = NSLOCTEXT("Agrarsense", "VehicleInteractableName", "Vehicle");
28}
29
31{
32 Super::BeginPlay();
33
34 TogglePhysics(true);
35
36 UROSHandler* ROSHandler = UAgrarsenseStatics::GetROSHandle(GetWorld());
37 if (ROSHandler)
38 {
39 ROSHandler->OnROSStateChanged.AddUniqueDynamic(this, &AVehicle::ROSBridgeStateChanged);
40 }
41
42 bool IsDrone = GetVehicleType() == EVehicleTypes::Drone;
43
44 // Spawn Transform and Collision sensors for each vehicle
45 FTransform transform = GetTransform();
46
47 // Create Collision sensor
48 FString VehicleCollisionSensorID = ActorID + "/collision";
49 CollisionSensor = USensorFactory::SpawnCollisionSensor(transform, this, VehicleCollisionSensorID, "collision", true, this);
50
51 if (!IsDrone)
52 {
53 // Create Transform sensor for forwarder and harvester
55 Params.SaveTransformDataToDisk = true;
56 Params.OwningActor = this;
57
58 FString VehicleTransformSensorID = ActorID + "/transform";
59 TransformSensor = USensorFactory::SpawnTransformSensor(transform, Params, VehicleTransformSensorID, "transform", true, this);
60 }
61
62
63 // Create Transform sensor for extra transform sensor positions
64 // (Front and Back for forwarder and harvester)
65 for (UStaticMeshComponent* Comp : ExtraTransformSensorPositions)
66 {
67 if (Comp)
68 {
69 FString CompName = Comp->GetName();
70
72 Params.OwningActor = this;
73 Params.SaveTransformDataToDisk = false;
74 Params.UseOwningActorTransform = false;
75 Params.UsePrimiteRelativeTransform = false;
76 Params.PrimitiveComponent = Cast<UPrimitiveComponent>(Comp);
77
78 const FString VehicleTransformSensorID = FString::Printf(TEXT("%s/%s/transform"), *ActorID, *CompName);
79 //UE_LOG(LogTemp, Log, TEXT("Creating Transform Sensor: %s"), *VehicleTransformSensorID);
80
81 ExtraTransformSensors.AddUnique(USensorFactory::SpawnTransformSensor(transform, Params, VehicleTransformSensorID, TEXT("transform"), true, this));
82 }
83 }
84
85 float NiagaraComponentHeight = 500.0f;
86 float OverlapBoundsSize = 50.0f;
87
88 if (IsDrone)
89 {
90 NiagaraComponentHeight = 200.0f;
91 }
92
93 FVector RelativePosition = FVector(0.0f, 0.0f, 0.0f);
95 {
96 // TODO make better solution for this.
97 RelativePosition = FVector(150.0f, -120.0f, 250.0f);
98 }
99
100 if (!IsDrone)
101 {
102 // Create overlap sensor for Forwarder and Harvester
103 // Drone overlap sensor(s) are created in PIDDrone BeginPlay
105 Params.OwningActor = this;
106 Params.Size = FVector(OverlapBoundsSize, OverlapBoundsSize, OverlapBoundsSize);
107 Params.RelativePosition = RelativePosition;
108 FString OverlapSensorID = ActorID + "/overlap";
109 OverlapSensor = USensorFactory::SpawnOverlapSensor(transform, Params, OverlapSensorID, "overlap", this);
110 }
111
112 // Load and setup rain/snow fall niagara system
113 UNiagaraSystem* NiagaraSystem = LoadObject<UNiagaraSystem>(nullptr, TEXT("/Game/Agrarsense/Particles/WaterAndSnow/NS_Particles.NS_Particles"));
114 if (NiagaraSystem)
115 {
116 NiagaraComponent = UNiagaraFunctionLibrary::SpawnSystemAttached(NiagaraSystem, this->GetRootComponent(),
117 FName("NiagaraEmitterSocketName"),
118 FVector(0.0, 0.0, NiagaraComponentHeight), FRotator::ZeroRotator, EAttachLocation::KeepRelativeOffset, true);
119 }
120 else
121 {
122 UE_LOG(LogTemp, Warning, TEXT("Vehicle.cpp: Couldn't find NS_Particles"));
123 }
124
126}
127
128void AVehicle::EndPlay(const EEndPlayReason::Type EndPlayReason)
129{
130 Super::EndPlay(EndPlayReason);
131
132 UROSHandler* ROSHandler = UAgrarsenseStatics::GetROSHandle(GetWorld());
133 if (ROSHandler)
134 {
135 ROSHandler->OnROSStateChanged.RemoveDynamic(this, &AVehicle::ROSBridgeStateChanged);
136 }
137
138 if (TransformSensor)
139 {
140 TransformSensor->Destroy();
141 TransformSensor = nullptr;
142 }
143
144 for (int32 i = 0; i < ExtraTransformSensors.Num(); i++)
145 {
146 if (ATransformSensor* SensorPtr = ExtraTransformSensors[i])
147 {
148 SensorPtr->Destroy();
149 }
150 }
151 ExtraTransformSensors.Empty();
152
153 if (CollisionSensor)
154 {
155 CollisionSensor->Destroy();
156 CollisionSensor = nullptr;
157 }
158
159 if (OverlapSensor)
160 {
161 OverlapSensor->Destroy();
162 OverlapSensor = nullptr;
163 }
164
165 // Destroy attached sensors when vehicle is destroyed
166 if (IsValid(SensorsManager) && EndPlayReason == EEndPlayReason::Destroyed)
167 {
168 SensorsManager->DestroyAllSensors();
169 }
170
172 {
173 NiagaraComponent->UnregisterComponent();
174 NiagaraComponent->DestroyComponent();
175 NiagaraComponent = nullptr;
176 }
177
178 // Destroy all remaining Actors that are attached to this vehicle, if any
179 TArray<AActor*> AttachedActors;
180 GetAttachedActors(AttachedActors);
181 for (AActor* Actor : AttachedActors)
182 {
183 if (Actor)
184 {
185 Actor->Destroy();
186 }
187 }
188}
189
191{
192
193}
194
196{
197 VehicleParameters = NewParameters;
198
200 {
202
204 {
205 const float BoundsSizeMEters = VehicleParameters.OverlapRadiusMeters;
206 OverlapSensor->SetOverlapBounds(FVector(BoundsSizeMEters, BoundsSizeMEters, BoundsSizeMEters));
207 }
208 }
209
210 // BlueprintImplementableEvent, this is handled in BP_Forwarder and BP_harvester.
212}
213
214void AVehicle::PossessedBy(AController* NewController)
215{
216 Super::PossessedBy(NewController);
217
218 ResetCamera();
219}
220
221void AVehicle::TeleportVehicleTo_Implementation(FVector NewLocation, FRotator NewRotation)
222{
223 SetActorLocationAndRotation(NewLocation, NewRotation, false, nullptr, ETeleportType::TeleportPhysics);
224}
225
227{
228 if (OverlapSensor)
229 {
231 }
232}
233
234FString AVehicle::ExportToJsonFile(const FString& FileName)
235{
236 bool OverrideTransform = IsVehicleInGarage();
237
238 FTransform TransformToUse = GetActorTransform();
239
240 if (OverrideTransform)
241 {
242 TransformToUse = MovedFromGarageTransform;
243 }
244
245 return USimulatorJsonExporter::ExportVehicleAndSensorsToJSON(FileName, this, OverrideTransform, TransformToUse);
246}
EROSState
Definition: ROSState.h:16
void SetVisualizeOverlapArea(bool Visualize)
void SetOverlapBounds(const FVector &NewSize)
ACollisionSensor * CollisionSensor
Definition: Vehicle.h:288
FTransform MovedFromGarageTransform
Definition: Vehicle.h:313
TArray< UStaticMeshComponent * > ExtraTransformSensorPositions
Definition: Vehicle.h:302
FWheeledVehicleParameters VehicleParameters
Definition: Vehicle.h:279
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override
Definition: Vehicle.cpp:128
void SetVehicleParameters(FWheeledVehicleParameters NewParameters)
Definition: Vehicle.cpp:195
FText InteractableName
Definition: Vehicle.h:261
virtual void BeginPlay() override
Definition: Vehicle.cpp:30
virtual void PossessedBy(AController *NewController) override
Definition: Vehicle.cpp:214
void ResetCamera()
TArray< ATransformSensor * > ExtraTransformSensors
Definition: Vehicle.h:317
virtual void TeleportVehicleTo_Implementation(FVector NewLocation, FRotator NewRotation)
Definition: Vehicle.cpp:221
bool IsVehicleInGarage() const
Definition: Vehicle.h:131
FString ActorID
Definition: Vehicle.h:308
FString ExportToJsonFile(const FString &FileName)
Definition: Vehicle.cpp:234
AVehicle()
Definition: Vehicle.cpp:23
void SetVisualizeVehicleOverlapArea(bool Visible)
Definition: Vehicle.cpp:226
AOverlapSensor * OverlapSensor
Definition: Vehicle.h:294
virtual EVehicleTypes GetVehicleType() const
Definition: Vehicle.h:52
void ApplyVehicleParameters(FWheeledVehicleParameters CurrentParameters)
void TogglePhysics(bool isOn)
ATransformSensor * TransformSensor
Definition: Vehicle.h:291
UNiagaraComponent * NiagaraComponent
Definition: Vehicle.h:297
virtual void ROSBridgeStateChanged(EROSState ROSState)
Definition: Vehicle.cpp:190
TObjectPtr< USensorsManagerComponent > SensorsManager
Definition: Vehicle.h:285
static UROSHandler * GetROSHandle(const UObject *WorldContextObject)
FROSDelegate_ROState OnROSStateChanged
Definition: ROSHandler.h:81
static AOverlapSensor * SpawnOverlapSensor(const FTransform &transform, FOverlapSensorParameters Parameters, const FString sensorIdentifier, const FString sensorName, AActor *Parent=nullptr)
static ATransformSensor * SpawnTransformSensor(const FTransform &transform, FTransformSensorParameters Parameters, const FString sensorIdentifier, const FString sensorName, bool SimulateSensor=true, AActor *Parent=nullptr)
static ACollisionSensor * SpawnCollisionSensor(const FTransform &transform, AActor *Owner, const FString sensorIdentifier, const FString sensorName, bool SimulateSensor=true, AActor *Parent=nullptr)
static FString ExportVehicleAndSensorsToJSON(FString FileName, AVehicle *Vehicle, bool OverrideTransform=false, const FTransform &Transform=FTransform())
UPrimitiveComponent * PrimitiveComponent