14#include "ROSIntegration/Classes/ROSIntegrationGameInstance.h"
15#include "ROSIntegration/Classes/RI/Topic.h"
17#include "PhysicsEngine/PhysicsObjectExternalInterface.h"
18#include "Physics/Experimental/PhysScene_Chaos.h"
19#include "Physics/PhysicsInterfaceUtils.h"
21#include "Math/Vector.h"
22#include "Engine/CollisionProfile.h"
23#include "Runtime/Engine/Classes/Kismet/KismetMathLibrary.h"
24#include "Runtime/Core/Public/Async/ParallelFor.h"
25#include "Kismet/GameplayStatics.h"
26#include "Kismet/KismetMathLibrary.h"
27#include "Misc/CommandLine.h"
34 PrimaryActorTick.bCanEverTick =
false;
36 if (FParse::Param(FCommandLine::Get(), TEXT(
"-save-combined-pointcloud")))
47 UWorld* World = GetWorld();
48 TArray<AActor*> FoundActors;
49 UGameplayStatics::GetAllActorsOfClass(World, ALidarManager::StaticClass(), FoundActors);
50 if (FoundActors.Num() != 1)
53 UE_LOG(LogTemp, Warning, TEXT(
"LidarManager.cpp: LidarManager already exists in the level. Destroying this one."));
59 RosInstance = Cast<UROSIntegrationGameInstance>(GetGameInstance());
64 FString UnixTimeStamp = FString::FromInt(FDateTime::Now().ToUnixTimestamp());
65 FileSavePath = DataLocation +
"LidarCombined_" + UnixTimeStamp +
"/";
76 PointCloudMessage->fields[0].datatype = ROSMessages::sensor_msgs::PointCloud2::PointField::FLOAT32;
81 PointCloudMessage->fields[1].datatype = ROSMessages::sensor_msgs::PointCloud2::PointField::FLOAT32;
86 PointCloudMessage->fields[2].datatype = ROSMessages::sensor_msgs::PointCloud2::PointField::FLOAT32;
91 PointCloudMessage->fields[3].datatype = ROSMessages::sensor_msgs::PointCloud2::PointField::UINT32;
99 Super::EndPlay(EndPlayReason);
148 std::vector<FPointData> flattenedPoints;
157#ifdef ParallelLineTraceSingleByChannel_EXISTS
160 auto PhysicsLock = FPhysicsObjectExternalInterface::LockRead(GetWorld()->GetPhysicsScene());
164 PhysicsLock.Release();
175 std::vector<std::vector<FPointData>> points(lidarCount);
176 ParallelFor(lidarCount, [&](int32 lidarIndex)
181#ifdef ParallelLineTraceSingleByChannel_EXISTS
184 auto PhysicsLock = FPhysicsObjectExternalInterface::LockRead(GetWorld()->GetPhysicsScene());
188 PhysicsLock.Release();
194 }, EParallelForFlags::Unbalanced);
200 for (
const auto& subVector : points)
202 TotalSize += subVector.size();
207 flattenedPoints.reserve(TotalSize);
208 for (
auto& subVector : points)
210 flattenedPoints.insert(flattenedPoints.end(), std::make_move_iterator(subVector.begin()), std::make_move_iterator(subVector.end()));
216 if (!flattenedPoints.empty())
251 UE_LOG(LogTemp, Warning, TEXT(
"LidarManager.cpp: Saving combined Lidar pointcloud to disk: %s"), (
SendCombinedCloudToROS ? TEXT(
"true") : TEXT(
"false")));
265 UE_LOG(LogTemp, Warning, TEXT(
"LidarManager.cpp: Added Lidar sensor."));
293 UE_LOG(LogTemp, Warning, TEXT(
"LidarManager.cpp: Removed Lidar sensor"));
336 CombinedLidarTopic->Init(
RosInstance->ROSIntegrationCore, FString::Printf(TEXT(
"/agrarsense/out/sensors/lidars_combined")), TEXT(
"sensor_msgs/PointCloud2"));
340 UE_LOG(LogTemp, Warning, TEXT(
"LidarManager.cpp: Created combined Lidar ROS topic. Topic name: /agrarsense/sensors/lidars_combined"));
384 const int pointSize = points.size();
385 size_t dataSize = pointSize *
sizeof(
FPointData);
static auto BindTick(ObjectType *Object, FunctionType Function)
void SendCombinedPointcloud(const std::vector< FPointData > &points)
FLidarDelegate_LidarSpawned OnLidarSpawned
UROSIntegrationGameInstance * RosInstance
void SaveCombinedPointcloud(const std::vector< FPointData > &points)
TSharedPtr< ROSMessages::sensor_msgs::PointCloud2 > PointCloudMessage
virtual void BeginPlay() override
TWeakObjectPtr< UTopic > CombinedLidarTopic
void SetSaveCombinedCloudToDisk(bool bSaveCombinedCloud)
void AddRaycastLidar(ALidar *lidarPtr)
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override
void SimulateRaycastLidars(const float DeltaTime)
bool SaveCombinedCloudToDisk
void ROSBridgeStateChanged(EROSState RosState)
void SetSendCombinedCloud(bool bSaveCombinedCloud)
void SetMeasurePerformance(bool bMeasurePerformance)
void SetSimulateLidars(bool bSimulateLidars)
void RemoveRaycastLidar(ALidar *lidarPtr)
SimpleTimer * TotalAverageTimer
ALidarManager(const FObjectInitializer &ObjectInitializer)
bool SendCombinedCloudToROS
std::vector< ALidar * > RaycastLidars
FLidarDelegate_LidarDestroyed OnLidarDestroyed
void TickParallel(float DeltaTime)
std::vector< FPointData > SimulateRaycastLidar(const float DeltaTime)
static void RemoveTick(FTickEntry TickEntry)
static FTickEntry AddTick(UObject *Object, std::function< void(float)> Function, ETickType Type)
double PrintAverageTime(FString prefix="Average execution time ", FString suffix=" milliseconds", bool printToScreen=false)
static FString GetDataFolder()
static void SaveVectorArrayAsPlyAsync(FString FullFileName, const std::vector< FPointData > points)