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
45 FTransform transform = GetTransform();
46
47 if (!IsDrone)
48 {
49
50 // Create Collision sensor
51 FString VehicleCollisionSensorID = ActorID + "/collision";
52 FSensorSpawnParameters CollisionSensorSpawnParams;
53 CollisionSensorSpawnParams.Transform = transform;
54 CollisionSensorSpawnParams.SensorIdentifier = VehicleCollisionSensorID;
55 CollisionSensorSpawnParams.SensorName = "collision";
56 CollisionSensorSpawnParams.SimulateSensor = true;
57 CollisionSensorSpawnParams.Parent = this;
58
59 FCollisionSensorParameters FCollisionSensorSpawnParams;
60 FCollisionSensorSpawnParams.OwningActor = this;
61 FCollisionSensorSpawnParams.UseActorCollision = true;
62
63 CollisionSensor = USensorFactory::SpawnCollisionSensor(CollisionSensorSpawnParams, FCollisionSensorSpawnParams);
64
65 // Create Transform sensor for forwarder and harvester
66 FString VehicleTransformSensorID = ActorID + "/transform";
67 FSensorSpawnParameters TransformSensorSpawnParams;
68 TransformSensorSpawnParams.Transform = transform;
69 TransformSensorSpawnParams.SensorIdentifier = VehicleTransformSensorID;
70 TransformSensorSpawnParams.SensorName = "transform";
71 TransformSensorSpawnParams.SimulateSensor = true;
72 TransformSensorSpawnParams.Parent = this;
73
74 FTransformSensorParameters SensorParams;
75 SensorParams.SaveTransformDataToDisk = true;
76 SensorParams.OwningActor = this;
77
78 TransformSensor = USensorFactory::SpawnTransformSensor(TransformSensorSpawnParams, SensorParams);
79 }
80
81
82 // If in the bluerprint side, we have added extra transform sensor positions,
83 // we will create Transform sensors for those positions as well (eg. forwarder/harvester front and back sensors).
84 for (UStaticMeshComponent* Comp : ExtraTransformSensorPositions)
85 {
86 if (Comp)
87 {
88 FString CompName = Comp->GetName();
89
90 const FString VehicleTransformSensorID = FString::Printf(TEXT("%s/%s/transform"), *ActorID, *CompName);
91
92 FSensorSpawnParameters TransformSensorSpawnParams;
93 TransformSensorSpawnParams.Transform = transform;
94 TransformSensorSpawnParams.SensorIdentifier = VehicleTransformSensorID;
95 TransformSensorSpawnParams.SensorName = "transform";
96 TransformSensorSpawnParams.SimulateSensor = true;
97 TransformSensorSpawnParams.Parent = this;
98
100 Params.OwningActor = this;
101 Params.SaveTransformDataToDisk = false;
102 Params.UseOwningActorTransform = false;
103 Params.UsePrimiteRelativeTransform = false;
104 Params.PrimitiveComponent = Cast<UPrimitiveComponent>(Comp);
105
106 ExtraTransformSensors.AddUnique(USensorFactory::SpawnTransformSensor(TransformSensorSpawnParams, Params));
107 }
108 }
109
110 float NiagaraComponentHeight = 500.0f;
111 float OverlapBoundsSize = 50.0f;
112
113 if (IsDrone)
114 {
115 NiagaraComponentHeight = 200.0f;
116 }
117
118 FVector RelativePosition = FVector(0.0f, 0.0f, 0.0f);
120 {
121 // TODO make better solution for this.
122 RelativePosition = FVector(150.0f, -120.0f, 250.0f);
123 }
124
125 if (!IsDrone)
126 {
127 // Create overlap sensor for Forwarder and Harvester
128 // Drone overlap sensor(s) are created in PIDDrone BeginPlay
129
130 FString OverlapSensorID = ActorID + "/overlap";
131
132 FSensorSpawnParameters OverlapSensorSpawnParams;
133 OverlapSensorSpawnParams.Transform = transform;
134 OverlapSensorSpawnParams.SensorIdentifier = OverlapSensorID;
135 OverlapSensorSpawnParams.SensorName = "transform";
136 OverlapSensorSpawnParams.SimulateSensor = true;
137 OverlapSensorSpawnParams.Parent = this;
138
139 FOverlapSensorParameters SensorParams;
140 SensorParams.OwningActor = this;
141 SensorParams.Size = FVector(OverlapBoundsSize, OverlapBoundsSize, OverlapBoundsSize);
142 SensorParams.RelativePosition = RelativePosition;
143
144 OverlapSensor = USensorFactory::SpawnOverlapSensor(OverlapSensorSpawnParams, SensorParams);
145 }
146
147 // Load and setup rain/snow fall niagara system
148 UNiagaraSystem* NiagaraSystem = LoadObject<UNiagaraSystem>(nullptr, TEXT("/Game/Agrarsense/Particles/WaterAndSnow/NS_Particles.NS_Particles"));
149 if (NiagaraSystem)
150 {
151 NiagaraComponent = UNiagaraFunctionLibrary::SpawnSystemAttached(NiagaraSystem, this->GetRootComponent(),
152 FName("NiagaraEmitterSocketName"),
153 FVector(0.0, 0.0, NiagaraComponentHeight), FRotator::ZeroRotator, EAttachLocation::KeepRelativeOffset, true);
154 }
155 else
156 {
157 UE_LOG(LogTemp, Warning, TEXT("Vehicle.cpp: Couldn't find NS_Particles"));
158 }
159
161}
162
163void AVehicle::EndPlay(const EEndPlayReason::Type EndPlayReason)
164{
165 Super::EndPlay(EndPlayReason);
166
167 UROSHandler* ROSHandler = UAgrarsenseStatics::GetROSHandle(GetWorld());
168 if (ROSHandler)
169 {
170 ROSHandler->OnROSStateChanged.RemoveDynamic(this, &AVehicle::ROSBridgeStateChanged);
171 }
172
173 if (TransformSensor)
174 {
175 TransformSensor->Destroy();
176 TransformSensor = nullptr;
177 }
178
179 for (int32 i = 0; i < ExtraTransformSensors.Num(); i++)
180 {
181 if (ATransformSensor* SensorPtr = ExtraTransformSensors[i])
182 {
183 SensorPtr->Destroy();
184 }
185 }
186 ExtraTransformSensors.Empty();
187
188 if (CollisionSensor)
189 {
190 CollisionSensor->Destroy();
191 CollisionSensor = nullptr;
192 }
193
194 if (OverlapSensor)
195 {
196 OverlapSensor->Destroy();
197 OverlapSensor = nullptr;
198 }
199
200 // Destroy attached sensors when vehicle is destroyed
201 if (IsValid(SensorsManager) && EndPlayReason == EEndPlayReason::Destroyed)
202 {
203 SensorsManager->DestroyAllSensors();
204 }
205
207 {
208 NiagaraComponent->UnregisterComponent();
209 NiagaraComponent->DestroyComponent();
210 NiagaraComponent = nullptr;
211 }
212
213 // Destroy all remaining Actors that are attached to this vehicle, if any
214 TArray<AActor*> AttachedActors;
215 GetAttachedActors(AttachedActors);
216 for (AActor* Actor : AttachedActors)
217 {
218 if (Actor)
219 {
220 Actor->Destroy();
221 }
222 }
223}
224
226{
227
228}
229
231{
232 VehicleParameters = NewParameters;
233
235 {
237
239 {
240 const float BoundsSizeMEters = VehicleParameters.OverlapRadiusMeters;
241 OverlapSensor->SetOverlapBounds(FVector(BoundsSizeMEters, BoundsSizeMEters, BoundsSizeMEters));
242 }
243 }
244
245 // BlueprintImplementableEvent, this is handled in BP_Forwarder and BP_harvester.
247}
248
249void AVehicle::PossessedBy(AController* NewController)
250{
251 Super::PossessedBy(NewController);
252
253 ResetCamera();
254}
255
256void AVehicle::TeleportVehicleTo_Implementation(FVector NewLocation, FRotator NewRotation)
257{
258 SetActorLocationAndRotation(NewLocation, NewRotation, false, nullptr, ETeleportType::TeleportPhysics);
259}
260
262{
263 if (OverlapSensor)
264 {
266 }
267}
268
269FString AVehicle::ExportToJsonFile(const FString& FileName)
270{
271 bool OverrideTransform = IsVehicleInGarage();
272
273 FTransform TransformToUse = GetActorTransform();
274
275 if (OverrideTransform)
276 {
277 TransformToUse = MovedFromGarageTransform;
278 }
279
280 return USimulatorJsonExporter::ExportVehicleAndSensorsToJSON(FileName, this, OverrideTransform, TransformToUse);
281}
EROSState
Definition: ROSState.h:16
void SetVisualizeOverlapArea(bool Visualize)
void SetOverlapBounds(const FVector &NewSize)
ACollisionSensor * CollisionSensor
Definition: Vehicle.h:290
FTransform MovedFromGarageTransform
Definition: Vehicle.h:315
TArray< UStaticMeshComponent * > ExtraTransformSensorPositions
Definition: Vehicle.h:304
FWheeledVehicleParameters VehicleParameters
Definition: Vehicle.h:281
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override
Definition: Vehicle.cpp:163
void SetVehicleParameters(FWheeledVehicleParameters NewParameters)
Definition: Vehicle.cpp:230
FText InteractableName
Definition: Vehicle.h:263
virtual void BeginPlay() override
Definition: Vehicle.cpp:30
virtual void PossessedBy(AController *NewController) override
Definition: Vehicle.cpp:249
void ResetCamera()
TArray< ATransformSensor * > ExtraTransformSensors
Definition: Vehicle.h:319
virtual void TeleportVehicleTo_Implementation(FVector NewLocation, FRotator NewRotation)
Definition: Vehicle.cpp:256
bool IsVehicleInGarage() const
Definition: Vehicle.h:133
FString ActorID
Definition: Vehicle.h:310
FString ExportToJsonFile(const FString &FileName)
Definition: Vehicle.cpp:269
AVehicle()
Definition: Vehicle.cpp:23
void SetVisualizeVehicleOverlapArea(bool Visible)
Definition: Vehicle.cpp:261
AOverlapSensor * OverlapSensor
Definition: Vehicle.h:296
virtual EVehicleTypes GetVehicleType() const
Definition: Vehicle.h:54
void ApplyVehicleParameters(FWheeledVehicleParameters CurrentParameters)
void TogglePhysics(bool isOn)
ATransformSensor * TransformSensor
Definition: Vehicle.h:293
UNiagaraComponent * NiagaraComponent
Definition: Vehicle.h:299
virtual void ROSBridgeStateChanged(EROSState ROSState)
Definition: Vehicle.cpp:225
TObjectPtr< USensorsManagerComponent > SensorsManager
Definition: Vehicle.h:287
static UROSHandler * GetROSHandle(const UObject *WorldContextObject)
FROSDelegate_ROState OnROSStateChanged
Definition: ROSHandler.h:81
static ATransformSensor * SpawnTransformSensor(const FSensorSpawnParameters SpawnParameters, FTransformSensorParameters SensorParameters)
static ACollisionSensor * SpawnCollisionSensor(const FSensorSpawnParameters SpawnParameters, const FCollisionSensorParameters CollisionSensorParameters)
static AOverlapSensor * SpawnOverlapSensor(const FSensorSpawnParameters SpawnParameters, FOverlapSensorParameters SensorParameters)
static FString ExportVehicleAndSensorsToJSON(FString FileName, AVehicle *Vehicle, bool OverrideTransform=false, const FTransform &Transform=FTransform())
UPrimitiveComponent * PrimitiveComponent