From 08d6570ea3b7bd22302ab5d8c9b4f98c18073534 Mon Sep 17 00:00:00 2001 From: JB Briant Date: Wed, 7 May 2025 20:04:41 +0700 Subject: [PATCH] FT - Write Jsonl file --- .../RobotPawnActors/BP_mujokoSO_100.uasset | Bin 1264920 -> 1264942 bytes .../Private/LuckyDataTransferSubsystem.cpp | 4 +-- .../Private/Episode/EpisodeSubSystem.cpp | 16 +++++++----- .../LuckyWorldV2/Private/_Utils/FileUtils.cpp | 24 ++++++++++++++++++ Source/LuckyWorldV2/Public/_Utils/FileUtils.h | 14 ++++++++++ 5 files changed, 49 insertions(+), 9 deletions(-) create mode 100644 Source/LuckyWorldV2/Private/_Utils/FileUtils.cpp create mode 100644 Source/LuckyWorldV2/Public/_Utils/FileUtils.h diff --git a/Content/Blueprint/RobotPawnActors/BP_mujokoSO_100.uasset b/Content/Blueprint/RobotPawnActors/BP_mujokoSO_100.uasset index 87a704d663d0761961a2300d17e3daf9755e0329..4d8a6bcb136c8c45691a441a288f802689d2b10e 100644 GIT binary patch delta 10031 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 delta 10243 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 = EImageFormat::PNG; + ImageTask->Format = EImageFormat::JPEG; ImageTask->Filename = Filename; ImageTask->PixelData = MakeUnique>(FIntPoint(Sensor->RenderTarget->GetSurfaceWidth(), Sensor->RenderTarget->GetSurfaceHeight()), TArray64(OutPixels)); ImageTask->bOverwriteFile = true; diff --git a/Source/LuckyWorldV2/Private/Episode/EpisodeSubSystem.cpp b/Source/LuckyWorldV2/Private/Episode/EpisodeSubSystem.cpp index c5848e5a..41971e10 100644 --- a/Source/LuckyWorldV2/Private/Episode/EpisodeSubSystem.cpp +++ b/Source/LuckyWorldV2/Private/Episode/EpisodeSubSystem.cpp @@ -12,6 +12,7 @@ #include "Dom/JsonObject.h" #include "Serialization/JsonWriter.h" #include "Serialization/JsonSerializer.h" +#include "_Utils/FileUtils.h" UEpisodeSubSystem::UEpisodeSubSystem() { @@ -57,9 +58,11 @@ void UEpisodeSubSystem::Tick(float DeltaTime) if (DataTransfer) DataTransfer->WriteImageToDisk(CurrentRobot->PhysicsSceneProxy->GetMujocoData().time); EpisodeFrames++; - if (bIsEpisodeCompleted && CapturedEpisodes <= EpisodesToCapture) + if (!bIsEpisodeCompleted) return; + + EndEpisode(); + if (CapturedEpisodes < EpisodesToCapture) { - EndEpisode(); StartEpisode(); } else @@ -122,6 +125,7 @@ void UEpisodeSubSystem::StartTraining(const int32 EpisodesCountIn, FString BaseI void UEpisodeSubSystem::EndTraining() { StopTicking(); + CreateEpisodesStatsJsonFile(); // Create jsonl files } @@ -138,9 +142,6 @@ void UEpisodeSubSystem::StartEpisode() RobotTransform.GetLocation() + RobotTransform.GetRotation().GetForwardVector() * HardCodedRewardDistanceFromRobotPivot * (FMath::RandBool() ? 1 : -1) }; - // DrawDebugLine(this->GetWorld(), EpisodeRewardZone.GetLocation() + FVector::UpVector * 70, EpisodeRewardZone.GetLocation(), FColor::Red, true); - // DrawDebugLine(this->GetWorld(), RobotTransform.GetLocation() + FVector::UpVector * 70, RobotTransform.GetLocation(), FColor::Blue, true); - // Ask the bot to give a reachable location for the Training Object Transform EpisodeObjectBaseTransform = CurrentRobot->RobotPilotComponent->GetReachableTransform(); @@ -276,7 +277,7 @@ void UEpisodeSubSystem::CreateEpisodeStatJsonLine(const FTrainingEpisodeData& Tr // Serialize into FString FString Output; - const TSharedRef> Writer = TJsonWriterFactory<>::Create(&Output); + const TSharedRef< TJsonWriter< TCHAR, TCondensedJsonPrintPolicy > > Writer = TJsonWriterFactory< TCHAR, TCondensedJsonPrintPolicy >::Create(&Output); FJsonSerializer::Serialize(Root.ToSharedRef(), Writer); EpisodeStatLines.Add(Output); } @@ -294,7 +295,8 @@ void UEpisodeSubSystem::ConvertImagesToVideo() void UEpisodeSubSystem::CreateEpisodesStatsJsonFile() { // TODO Do not use FJsonObject - simply concat the FStrings into a file - + UFileUtils::WriteJsonlFile(EpisodeStatLines, FPaths::ProjectSavedDir(), FString("episodes_stats")); + // Create a jsonl file and store in the correct directory // concat TArray EpisodeStatLines into a single file // https://huggingface.co/datasets/youliangtan/so100_strawberry_grape/blob/main/meta/episodes_stats.jsonl diff --git a/Source/LuckyWorldV2/Private/_Utils/FileUtils.cpp b/Source/LuckyWorldV2/Private/_Utils/FileUtils.cpp new file mode 100644 index 00000000..d4bb9b0b --- /dev/null +++ b/Source/LuckyWorldV2/Private/_Utils/FileUtils.cpp @@ -0,0 +1,24 @@ +#include "_Utils/FileUtils.h" +#include "Misc/FileHelper.h" +#include "Misc/Paths.h" + +UFileUtils::UFileUtils() +{ +} + + + +bool UFileUtils::WriteJsonlFile(const TArray& JsonLines, const FString& BasePath, const FString& FileName) +{ + // Ensure the directory exists + IFileManager::Get().MakeDirectory(*BasePath, true); + + // Construct the full file path + const FString FullFilePath = FPaths::Combine(BasePath, FileName + TEXT(".jsonl")); + + // Join the array into one string with line breaks + const FString FileContent = FString::Join(JsonLines, TEXT("")); + + // Write to file + return FFileHelper::SaveStringToFile(FileContent, *FullFilePath); +} \ No newline at end of file diff --git a/Source/LuckyWorldV2/Public/_Utils/FileUtils.h b/Source/LuckyWorldV2/Public/_Utils/FileUtils.h new file mode 100644 index 00000000..e0a58af7 --- /dev/null +++ b/Source/LuckyWorldV2/Public/_Utils/FileUtils.h @@ -0,0 +1,14 @@ +#pragma once +#include "CoreMinimal.h" +#include "FileUtils.generated.h" + +UCLASS() +class LUCKYWORLDV2_API UFileUtils : public UObject +{ + GENERATED_BODY() + +public: + UFileUtils(); + + static bool WriteJsonlFile(const TArray& JsonLines, const FString& BasePath, const FString& FileName); +}; \ No newline at end of file