Agrarsense
PIDDrone.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
9
10#include "Components/SkeletalMeshComponent.h"
11#include "Components/StaticMeshComponent.h"
12#include "Camera/CameraComponent.h"
13#include "Field/FieldSystemNodes.h"
14#include "Algo/Reverse.h"
15
16#if WITH_EDITOR
17#include "DrawDebugHelpers.h"
18#endif
19
21{
22 PrimaryActorTick.bCanEverTick = true;
23 InteractableName = NSLOCTEXT("Agrarsense", "DroneInteractableName", "Drone");
24}
25
27{
28 Super::BeginPlay();
29
30 World = GetWorld();
31
32 mesh = Cast<USkeletalMeshComponent>(GetComponentByClass(USkeletalMeshComponent::StaticClass()));
33 desiredPositionMesh = Cast<UStaticMeshComponent>(GetComponentByClass(UStaticMeshComponent::StaticClass()));
34
35 StartingPosition = GetActorLocation();
36}
37
38void APIDDrone::EndPlay(const EEndPlayReason::Type EndPlayReason)
39{
40 Super::EndPlay(EndPlayReason);
41}
42
43void APIDDrone::Tick(float DeltaTime)
44{
45 Super::Tick(DeltaTime);
46
47 if (!IsVehicleInGarage())
48 {
49 AutoPilot(DeltaTime);
50 }
51}
52
54{
55 // TODO: Check if in garage
56 // include drone rotation to point
57
58 // Don't try to fly if no waypoints
59 if (DroneParameters.Points.Num() == 0 && IsRoaming())
60 {
62 }
63
64 FVector waypoint = GetCurrentWaypointTarget();
65 FVector currentlocation = mesh->GetRelativeTransform().GetLocation();
66
68 {
69 // Doesn't work
70 desiredPositionMesh->SetWorldLocation(waypoint);
71 }
72#if WITH_EDITOR
73 else
74 {
75 UE_LOG(LogTemp, Warning, TEXT("Desired location mesh not found"));
76 //DrawDebugLine(World, currentlocation, waypoint, FColor::Red, false, 0.0f, 0.0f, 5.0f);
77 }
78#endif
79
80 if (FVector2f::Distance(FVector2f(waypoint.X, waypoint.Y), FVector2f(currentlocation.X, currentlocation.Y)) < 1000)
81 {
82 waypointReached = true;
83 if (passedWaypoints != DroneParameters.Points.Num() - 1)
84 {
85#if WITH_EDITOR
86 UE_LOG(LogTemp, Warning, TEXT("Changing waypoint from %i to %i"), passedWaypoints, passedWaypoints + 1);
87#endif
88
90 }
91 else
92 {
94 {
97 }
98 else
99 {
101 {
104 break;
107 passedWaypoints = 0;
108 break;
110 passedWaypoints = 0;
111 break;
113 Algo::Reverse(DroneParameters.Points);
114 passedWaypoints = 0;
115 break;
116 default:
117 break;
118 }
119 }
120 }
121 }
122}
123
124void APIDDrone::MoveDroneToPosition(const FTransform Transform)
125{
126 if (DroneParameters.Points.Num() > 0)
127 {
128 DroneParameters.Points.Empty();
130 }
131 else
132 {
134 }
135}
136
138{
139 // UE_LOG(LogTemp, Warning, TEXT(" % s"), *DroneParameters.Points[passedWaypoints].GetLocation().ToString());
141 {
142 return FVector(0, 0, 0);
143 }
144
145 return DroneParameters.Points[passedWaypoints].GetLocation();
146}
147
148void APIDDrone::AssignRoamingPoints(const TArray<FTransform> Points)
149{
150 // Empty current waypoints if any
152
153 for (const FTransform& point : Points)
154 {
155 // Assing new waypoints to the array
156 WayPoints.Add(point.GetLocation());
157 }
158}
159
160void APIDDrone::SetDroneRotation(USkeletalMeshComponent* target, FRotator rotator)
161{
162 if (!target)
163 {
164 return;
165 }
166
167 FRotator rotation = FRotator(
168 FMath::Clamp(rotator.Pitch, -2, 2),
169 FMath::Clamp(rotator.Yaw, -2, 2),
170 FMath::Clamp(rotator.Roll, -2, 2));
171
172 FRotator currentRotation = target->GetRelativeRotation();
173
174 FRotator rotationDifference = currentRotation - rotator;
175
176 if (FMath::Abs(rotator.Pitch) > 0 && FMath::Abs(currentRotation.Pitch) < FMath::Abs(rotationDifference.Pitch))
177 {
178 target->AddRelativeRotation(FRotator(rotation.Pitch, 0, 0), false, nullptr, ETeleportType::TeleportPhysics);
179 }
180 if (FMath::Abs(rotator.Yaw) > 0 && FMath::Abs(currentRotation.Yaw) < FMath::Abs(rotationDifference.Yaw))
181 {
182 target->AddRelativeRotation(FRotator(0, rotation.Yaw, 0), false, nullptr, ETeleportType::TeleportPhysics);
183 }
184 if (FMath::Abs(rotator.Roll) > 0 && FMath::Abs(currentRotation.Roll) < FMath::Abs(rotationDifference.Roll))
185 {
186 target->AddRelativeRotation(FRotator(0, 0, rotation.Roll), false, nullptr, ETeleportType::TeleportPhysics);
187 }
188
189 if (rotator.Pitch == 0 || rotator.Yaw == 0 || rotator.Roll == 0)
190 {
191 target->AddRelativeRotation(FRotator(-FMath::Clamp(rotationDifference.Pitch, -2, 2), -FMath::Clamp(rotationDifference.Yaw, -2, 2), -FMath::Clamp(rotationDifference.Roll, -2, 2)), false, nullptr, ETeleportType::TeleportPhysics);
192 }
193}
194
195TArray<FTransform> APIDDrone::GenerateRoamingPoints(float radius, int32 roamingPoints)
196{
197 TArray<FTransform> generatedRoamingPoints;
198 generatedRoamingPoints.Reserve(roamingPoints);
199
200 FVector currentPosition = this->GetTransform().GetLocation();
201
202 FVector min = currentPosition - FVector(radius / 2, radius / 2, 0);
203 FVector max = currentPosition + FVector(radius / 2, radius / 2, 0);
204
205 for (int32 i = 0; i < roamingPoints; i++)
206 {
207 FTransform randomPoint;
208 randomPoint.SetLocation(FVector(FMath::RandRange(min.X, max.X), FMath::RandRange(min.Y, max.Y), 5000));
209
210 generatedRoamingPoints.Add(randomPoint);
211#if WITH_EDITOR
212 UE_LOG(LogTemp, Warning, TEXT("Waypoint %i: (%s)"), i, *randomPoint.GetLocation().ToString());
213#endif
214 }
215
216 return generatedRoamingPoints;
217}
218
219void APIDDrone::AutoPilot(float DeltaTime)
220{
222 {
223 return;
224 }
225
227}
bool waypointReached
Definition: PIDDrone.h:183
TArray< FVector > WayPoints
Definition: PIDDrone.h:187
void AssignRoamingPoints(const TArray< FTransform > Points)
Definition: PIDDrone.cpp:148
void SetDroneRotation(USkeletalMeshComponent *target, FRotator rotator)
Definition: PIDDrone.cpp:160
FVector GetCurrentWaypointTarget()
Definition: PIDDrone.cpp:137
void MoveDroneToPosition(const FTransform Transform)
Override all drone roaming points and continue towards this position.
Definition: PIDDrone.cpp:124
UWorld * World
Definition: PIDDrone.h:176
int32 passedWaypoints
Definition: PIDDrone.h:192
FVector StartingPosition
Definition: PIDDrone.h:178
virtual void BeginPlay() override
Definition: PIDDrone.cpp:26
void ClearWaypoints()
Definition: PIDDrone.h:92
UStaticMeshComponent * desiredPositionMesh
Definition: PIDDrone.h:181
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override
Definition: PIDDrone.cpp:38
void AutoPilot(float DeltaTime)
Definition: PIDDrone.cpp:219
FDroneParameters DroneParameters
Definition: PIDDrone.h:170
bool IsRoaming() const
Definition: PIDDrone.h:150
USkeletalMeshComponent * mesh
Definition: PIDDrone.h:180
void FlySetFlightpath()
Called in tick function for drone roaming through points.
Definition: PIDDrone.cpp:53
TArray< FTransform > GenerateRoamingPoints(float radius, int32 roamingPoints)
Generates a roadming points array for the drone in radius.
Definition: PIDDrone.cpp:195
virtual void Tick(float DeltaTime) override
Definition: PIDDrone.cpp:43
FText InteractableName
Definition: Vehicle.h:241
bool IsVehicleInGarage() const
Definition: Vehicle.h:131
EDroneEndAction DroneEndAction
EDroneAction DroneAction
TArray< FTransform > Points