Adding Bones and VisualTime to Recorder

This commit is contained in:
bernatx 2021-12-23 15:35:25 +01:00 committed by bernat
parent d3dc199085
commit b848ff25ab
16 changed files with 410 additions and 28 deletions

View File

@ -24,6 +24,8 @@
#include "GameFramework/SpectatorPawn.h"
#include "GenericPlatform/GenericPlatformProcess.h"
#include "Kismet/GameplayStatics.h"
#include "Materials/MaterialParameterCollection.h"
#include "Materials/MaterialParameterCollectionInstance.h"
#include "Misc/FileHelper.h"
#include "Misc/Paths.h"
@ -325,6 +327,21 @@ void UCarlaEpisode::InitializeAtBeginPlay()
UE_LOG(LogCarla, Error, TEXT("Can't find spectator!"));
}
// material parameters collection
UMaterialParameterCollection *Collection = LoadObject<UMaterialParameterCollection>(nullptr, TEXT("/Game/Carla/Blueprints/Game/CarlaParameters.CarlaParameters"), nullptr, LOAD_None, nullptr);
if (Collection != nullptr)
{
MaterialParameters = World->GetParameterCollectionInstance(Collection);
if (MaterialParameters == nullptr)
{
UE_LOG(LogCarla, Error, TEXT("Can't find CarlaParameters instance!"));
}
}
else
{
UE_LOG(LogCarla, Error, TEXT("Can't find CarlaParameters asset!"));
}
for (TActorIterator<ATrafficSignBase> It(World); It; ++It)
{
ATrafficSignBase *Actor = *It;

View File

@ -17,6 +17,7 @@
#include "Carla/Sensor/SensorManager.h"
#include "GameFramework/Pawn.h"
#include "Materials/MaterialParameterCollectionInstance.h"
#include <compiler/disable-ue4-macros.h>
#include <carla/geom/BoundingBox.h>
@ -98,6 +99,23 @@ public:
{
return ElapsedGameTime;
}
/// Visual game seconds
double GetVisualGameTime() const
{
return VisualGameTime;
}
void SetVisualGameTime(double Time)
{
VisualGameTime = Time;
// update time in material parameters also
if (MaterialParameters)
{
MaterialParameters->SetScalarParameterValue(FName("VisualTime"), VisualGameTime);
}
}
/// Return the list of actor definitions that are available to be spawned this
/// episode.
@ -327,11 +345,16 @@ private:
void TickTimers(float DeltaSeconds)
{
ElapsedGameTime += DeltaSeconds;
SetVisualGameTime(VisualGameTime + DeltaSeconds);
}
const uint64 Id = 0u;
// simulation time
double ElapsedGameTime = 0.0;
// visual time (used by clounds and other FX that need to be deterministic)
double VisualGameTime = 0.0;
UPROPERTY(VisibleAnywhere)
FString MapName;
@ -347,6 +370,9 @@ private:
UPROPERTY(VisibleAnywhere)
AWeather *Weather = nullptr;
UPROPERTY(VisibleAnywhere)
UMaterialParameterCollectionInstance *MaterialParameters = nullptr;
ACarlaRecorder *Recorder = nullptr;

View File

@ -90,6 +90,8 @@ void ACarlaRecorder::Ticking(float DeltaSeconds)
if (Enabled)
{
PlatformTime.UpdateTime();
VisualTime.SetTime(Episode->GetVisualGameTime());
const FActorRegistry &Registry = Episode->GetActorRegistry();
// through all actors in registry
@ -122,6 +124,7 @@ void ACarlaRecorder::Ticking(float DeltaSeconds)
if (bAdditionalData)
{
AddActorKinematics(View);
AddActorBones(View);
}
break;
@ -318,6 +321,28 @@ void ACarlaRecorder::AddTrafficLightTime(const ATrafficLightBase& TrafficLight)
}
}
void ACarlaRecorder::AddActorBones(FCarlaActor *CarlaActor)
{
check(CarlaActor != nullptr);
// get the bones
FWalkerBoneControlOut Bones;
CarlaActor->GetBonesTransform(Bones);
CarlaRecorderWalkerBones Walker;
Walker.DatabaseId = CarlaActor->GetActorId();
for (auto &Bone : Bones.BoneTransforms)
{
FString Name = Bone.Get<0>();
auto Transforms = Bone.Get<1>();
FVector Loc = Transforms.Relative.GetTranslation();
FVector Rot = Transforms.Relative.GetRotation().Euler();
CarlaRecorderWalkerBone Entry(Name, Loc, Rot);
Walker.Bones.push_back(Entry);
}
WalkersBones.Add(std::move(Walker));
}
std::string ACarlaRecorder::Start(std::string Name, FString MapName, bool AdditionalData)
{
// stop replayer if any in course
@ -391,6 +416,7 @@ void ACarlaRecorder::Clear(void)
TriggerVolumes.Clear();
PhysicsControls.Clear();
TrafficLightTimes.Clear();
WalkersBones.Clear();
}
void ACarlaRecorder::Write(double DeltaSeconds)
@ -400,6 +426,7 @@ void ACarlaRecorder::Write(double DeltaSeconds)
// start
Frames.WriteStart(File);
VisualTime.Write(File);
// events
EventsAdd.Write(File);
@ -426,6 +453,7 @@ void ACarlaRecorder::Write(double DeltaSeconds)
PlatformTime.Write(File);
PhysicsControls.Write(File);
TrafficLightTimes.Write(File);
WalkersBones.Write(File);
}
// end

View File

@ -29,6 +29,8 @@
#include "CarlaRecorderPosition.h"
#include "CarlaRecorderQuery.h"
#include "CarlaRecorderState.h"
#include "CarlaRecorderVisualTime.h"
#include "CarlaRecorderWalkerBones.h"
#include "CarlaReplayer.h"
#include "CarlaRecorder.generated.h"
@ -60,7 +62,9 @@ enum class CarlaRecorderPacketId : uint8_t
PhysicsControl,
TrafficLightTime,
TriggerVolume,
FrameCounter
FrameCounter,
WalkerBones,
VisualTime
};
/// Recorder for the simulation
@ -123,6 +127,8 @@ public:
void AddTrafficLightTime(const ATrafficLightBase& TrafficLight);
void AddActorBones(FCarlaActor *CarlaActor);
// set episode
void SetEpisode(UCarlaEpisode *ThisEpisode)
{
@ -189,7 +195,8 @@ private:
CarlaRecorderPlatformTime PlatformTime;
CarlaRecorderPhysicsControls PhysicsControls;
CarlaRecorderTrafficLightTimes TrafficLightTimes;
CarlaRecorderWalkersBones WalkersBones;
CarlaRecorderVisualTime VisualTime;
// replayer
CarlaReplayer Replayer;

View File

@ -42,10 +42,11 @@ void WriteFVector(std::ostream &OutFile, const FVector &InObj)
}
// write binary data from FTransform
// void WriteFTransform(std::ostream &OutFile, const FTransform &InObj){
// WriteFVector(OutFile, InObj.GetTranslation());
// WriteFVector(OutFile, InObj.GetRotation().Euler());
// }
void WriteFTransform(std::ofstream &OutFile, const FTransform &InObj)
{
WriteFVector(OutFile, InObj.GetTranslation());
WriteFVector(OutFile, InObj.GetRotation().Euler());
}
// write binary data from FString (length + text)
void WriteFString(std::ostream &OutFile, const FString &InObj)
@ -71,13 +72,14 @@ void ReadFVector(std::istream &InFile, FVector &OutObj)
}
// read binary data to FTransform
// void ReadFTransform(std::istream &InFile, FTransform &OutObj){
// FVector Vec;
// ReadFVector(InFile, Vec);
// OutObj.SetTranslation(Vec);
// ReadFVector(InFile, Vec);
// OutObj.GetRotation().MakeFromEuler(Vec);
// }
void ReadFTransform(std::ifstream &InFile, FTransform &OutObj)
{
FVector Vec;
ReadFVector(InFile, Vec);
OutObj.SetTranslation(Vec);
ReadFVector(InFile, Vec);
OutObj.GetRotation().MakeFromEuler(Vec);
}
// read binary data to FString (length + text)
void ReadFString(std::istream &InFile, FString &OutObj)

View File

@ -47,7 +47,7 @@ void WriteTArray(std::ostream &OutFile, const TArray<T> &InVec)
void WriteFVector(std::ostream &OutFile, const FVector &InObj);
// write binary data from FTransform
// void WriteFTransform(std::ostream &OutFile, const FTransform &InObj);
void WriteFTransform(std::ofstream &OutFile, const FTransform &InObj);
// write binary data from FString (length + text)
void WriteFString(std::ostream &OutFile, const FString &InObj);
@ -94,6 +94,6 @@ void ReadTArray(std::istream &InFile, TArray<T> &OutVec)
void ReadFVector(std::istream &InFile, FVector &OutObj);
// read binary data from FTransform
// void ReadTransform(std::istream &InFile, FTransform &OutObj);
void ReadTransform(std::ifstream &InFile, FTransform &OutObj);
// read binary data from FString (length + text)
void ReadFString(std::istream &InFile, FString &OutObj);

View File

@ -86,7 +86,6 @@ std::string CarlaRecorderQuery::QueryInfo(std::string Filename, bool bShowAll)
// parse only frames
while (File)
{
// get header
if (!ReadHeader())
{
@ -517,7 +516,7 @@ std::string CarlaRecorderQuery::QueryInfo(std::string Filename, bool bShowAll)
SkipPacket();
break;
case static_cast<char>(CarlaRecorderPacketId::TrafficLightTime):
case static_cast<char>(CarlaRecorderPacketId::TrafficLightTime):
if (bShowAll)
{
ReadValue<uint16_t>(File, Total);
@ -542,8 +541,37 @@ std::string CarlaRecorderQuery::QueryInfo(std::string Filename, bool bShowAll)
SkipPacket();
break;
case static_cast<char>(CarlaRecorderPacketId::WalkerBones):
if (bShowAll)
{
ReadValue<uint16_t>(File, Total);
if (Total > 0 && !bFramePrinted)
{
PrintFrame(Info);
bFramePrinted = true;
}
Info << " Walkers Bones: " << Total << std::endl;
for (i = 0; i < Total; ++i)
{
WalkerBones.Clear();
WalkerBones.Read(File);
Info << " Id: " << WalkerBones.DatabaseId << "\n";
for (const auto &Bone : WalkerBones.Bones)
{
Info << " Bone: \"" << TCHAR_TO_UTF8(*Bone.Name) << "\" relative: " << "Loc("
<< Bone.Location.X << ", " << Bone.Location.Y << ", " << Bone.Location.Z << ") Rot("
<< Bone.Rotation.X << ", " << Bone.Rotation.Y << ", " << Bone.Rotation.Z << ")\n";
}
}
Info << std::endl;
}
else
SkipPacket();
break;
// frame end
case static_cast<char>(CarlaRecorderPacketId::FrameEnd):
case static_cast<char>(CarlaRecorderPacketId::FrameEnd):
// do nothing, it is empty
break;

View File

@ -24,6 +24,7 @@
#include "CarlaRecorderInfo.h"
#include "CarlaRecorderPosition.h"
#include "CarlaRecorderState.h"
#include "CarlaRecorderWalkerBones.h"
class CarlaRecorderQuery
{
@ -66,6 +67,7 @@ private:
CarlaRecorderPlatformTime PlatformTime;
CarlaRecorderPhysicsControl PhysicsControl;
CarlaRecorderTrafficLightTime TrafficLightTime;
CarlaRecorderWalkerBones WalkerBones;
// read next header packet
bool ReadHeader(void);

View File

@ -0,0 +1,31 @@
// Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#include "CarlaRecorderVisualTime.h"
#include "CarlaRecorder.h"
#include "CarlaRecorderHelpers.h"
void CarlaRecorderVisualTime::SetTime(double ThisTime)
{
Time = ThisTime;
}
void CarlaRecorderVisualTime::Read(std::ifstream &InFile)
{
ReadValue<double>(InFile, this->Time);
}
void CarlaRecorderVisualTime::Write(std::ofstream &OutFile)
{
// write the packet id
WriteValue<char>(OutFile, static_cast<char>(CarlaRecorderPacketId::VisualTime));
// write packet size
uint32_t Total = sizeof(double);
WriteValue<uint32_t>(OutFile, Total);
WriteValue<double>(OutFile, this->Time);
}

View File

@ -0,0 +1,24 @@
// Copyright (c) 2021 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#pragma once
#include <fstream>
#include <chrono>
#pragma pack(push, 1)
struct CarlaRecorderVisualTime
{
double Time;
void SetTime(double ThisTime);
void Read(std::ifstream &InFile);
void Write(std::ofstream &OutFile);
};
#pragma pack(pop)

View File

@ -0,0 +1,91 @@
// Copyright (c) 2021 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#include "CarlaRecorder.h"
#include "CarlaRecorderWalkerBones.h"
#include "CarlaRecorderHelpers.h"
void CarlaRecorderWalkerBones::Write(std::ofstream &OutFile)
{
// database id
WriteValue<uint32_t>(OutFile, this->DatabaseId);
// write all bones
WriteValue<uint16_t>(OutFile, this->Bones.size());
for (const auto& Obj : this->Bones)
{
// name & transform
WriteFString(OutFile, Obj.Name);
WriteFVector(OutFile, Obj.Location);
WriteFVector(OutFile, Obj.Rotation);
}
}
void CarlaRecorderWalkerBones::Read(std::ifstream &InFile)
{
// database id
ReadValue<uint32_t>(InFile, this->DatabaseId);
// read all bones
uint16_t Total;
ReadValue<uint16_t>(InFile, Total);
this->Bones.reserve(Total);
FString Name;
FVector Location, Rotation;
for (int i=0; i<Total; ++i)
{
// name & transform
ReadFString(InFile, Name);
ReadFVector(InFile, Location);
ReadFVector(InFile, Rotation);
// add to the vector of bones
this->Bones.emplace_back(Name, Location, Rotation);
}
}
void CarlaRecorderWalkerBones::Clear(void)
{
Bones.clear();
}
// ---------------------------------------------
void CarlaRecorderWalkersBones::Clear(void)
{
Walkers.clear();
}
void CarlaRecorderWalkersBones::Add(const CarlaRecorderWalkerBones &Walker)
{
Walkers.push_back(Walker);
}
void CarlaRecorderWalkersBones::Write(std::ofstream &OutFile)
{
// write the packet id
WriteValue<char>(OutFile, static_cast<char>(CarlaRecorderPacketId::WalkerBones));
std::streampos PosStart = OutFile.tellp();
// write a dummy packet size
uint32_t Total = 0;
WriteValue<uint32_t>(OutFile, Total);
// write total records
Total = Walkers.size();
WriteValue<uint16_t>(OutFile, Total);
// write records
for (uint16_t i=0; i<Total; ++i)
Walkers[i].Write(OutFile);
// write the real packet size
std::streampos PosEnd = OutFile.tellp();
Total = PosEnd - PosStart - sizeof(uint32_t);
OutFile.seekp(PosStart, std::ios::beg);
WriteValue<uint32_t>(OutFile, Total);
OutFile.seekp(PosEnd, std::ios::beg);
}

View File

@ -0,0 +1,49 @@
// Copyright (c) 2021 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#pragma once
#include <fstream>
#include <vector>
#pragma pack(push, 1)
struct CarlaRecorderWalkerBone
{
FString Name;
FVector Location;
FVector Rotation;
CarlaRecorderWalkerBone(FString &InName, FVector &InLocation, FVector &InRotation) : Name(InName), Location(InLocation), Rotation(InRotation) {}
};
struct CarlaRecorderWalkerBones
{
uint32_t DatabaseId;
std::vector<CarlaRecorderWalkerBone> Bones;
void Read(std::ifstream &InFile);
void Write(std::ofstream &OutFile);
void Clear();
};
#pragma pack(pop)
class CarlaRecorderWalkersBones
{
public:
void Add(const CarlaRecorderWalkerBones &InObj);
void Clear(void);
void Write(std::ofstream &OutFile);
private:
std::vector<CarlaRecorderWalkerBones> Walkers;
};

View File

@ -290,6 +290,11 @@ void CarlaReplayer::ProcessToTime(double Time, bool IsFirstTime)
}
break;
// visual time for FX
case static_cast<char>(CarlaRecorderPacketId::VisualTime):
ProcessVisualTime();
break;
// events add
case static_cast<char>(CarlaRecorderPacketId::EventAdd):
ProcessEventsAdd();
@ -358,6 +363,14 @@ void CarlaReplayer::ProcessToTime(double Time, bool IsFirstTime)
SkipPacket();
break;
// walker bones
case static_cast<char>(CarlaRecorderPacketId::WalkerBones):
if (bFrameFound)
ProcessWalkerBones();
else
SkipPacket();
break;
// frame end
case static_cast<char>(CarlaRecorderPacketId::FrameEnd):
if (bFrameFound)
@ -390,6 +403,15 @@ void CarlaReplayer::ProcessToTime(double Time, bool IsFirstTime)
}
}
void CarlaReplayer::ProcessVisualTime(void)
{
CarlaRecorderVisualTime VisualTime;
VisualTime.Read(File);
// set the visual time
Episode->SetVisualGameTime(VisualTime.Time);
}
void CarlaReplayer::ProcessEventsAdd(void)
{
uint16_t i, Total;
@ -607,6 +629,26 @@ void CarlaReplayer::ProcessPositions(bool IsFirstTime)
}
}
void CarlaReplayer::ProcessWalkerBones(void)
{
uint16_t i, Total;
CarlaRecorderWalkerBones Walker;
std::stringstream Info;
// read Total walkers
ReadValue<uint16_t>(File, Total);
for (i = 0; i < Total; ++i)
{
Walker.Read(File);
Walker.DatabaseId = MappedId[Walker.DatabaseId];
// check if ignore this actor
if (!(IgnoreHero && IsHeroMap[Walker.DatabaseId]))
{
Helper.ProcessReplayerWalkerBones(Walker);
}
}
}
void CarlaReplayer::UpdatePositions(double Per, double DeltaTime)
{
unsigned int i;

View File

@ -133,6 +133,8 @@ private:
// processing packets
void ProcessToTime(double Time, bool IsFirstTime = false);
void ProcessVisualTime(void);
void ProcessEventsAdd(void);
void ProcessEventsDel(void);
void ProcessEventsParent(void);
@ -147,6 +149,8 @@ private:
void ProcessLightVehicle(void);
void ProcessLightScene(void);
void ProcessWalkerBones(void);
// positions
void UpdatePositions(double Per, double DeltaTime);

View File

@ -8,24 +8,24 @@
#include "Carla/Recorder/CarlaReplayerHelper.h"
#include "Carla/Actor/ActorDescription.h"
#include "Carla/Actor/CarlaActor.h"
#include "Carla/Actor/ActorRegistry.h"
#include "Carla/Vehicle/WheeledVehicleAIController.h"
#include "Carla/Walker/WalkerControl.h"
#include "Carla/Walker/WalkerController.h"
#include "Carla/Actor/ActorSpawnResult.h"
#include "Carla/Actor/CarlaActor.h"
#include "Carla/Game/CarlaEpisode.h"
#include "Carla/Game/CarlaStatics.h"
#include "Carla/Lights/CarlaLight.h"
#include "Carla/Lights/CarlaLightSubsystem.h"
#include "Carla/Actor/ActorSpawnResult.h"
#include "Carla/Game/CarlaEpisode.h"
#include "Carla/Traffic/TrafficSignBase.h"
#include "Carla/MapGen/LargeMapManager.h"
#include "Carla/Traffic/TrafficLightBase.h"
#include "Carla/Traffic/TrafficLightController.h"
#include "Carla/Traffic/TrafficLightGroup.h"
#include "Carla/Traffic/TrafficSignBase.h"
#include "Carla/Vehicle/CarlaWheeledVehicle.h"
#include "Engine/StaticMeshActor.h"
#include "Carla/Game/CarlaStatics.h"
#include "Carla/MapGen/LargeMapManager.h"
#include "Carla/Vehicle/WheeledVehicleAIController.h"
#include "Carla/Walker/WalkerControl.h"
#include "Carla/Walker/WalkerController.h"
#include "Components/BoxComponent.h"
#include "Engine/StaticMeshActor.h"
#include <compiler/disable-ue4-macros.h>
#include <carla/rpc/VehicleLightState.h>
@ -419,6 +419,34 @@ void CarlaReplayerHelper::ProcessReplayerAnimWalker(CarlaRecorderAnimWalker Walk
SetWalkerSpeed(Walker.DatabaseId, Walker.Speed);
}
// set walker bones
void CarlaReplayerHelper::ProcessReplayerWalkerBones(const CarlaRecorderWalkerBones &WalkerBones)
{
check(Episode != nullptr);
FCarlaActor* CarlaActor = Episode->FindCarlaActor(WalkerBones.DatabaseId);
if (!CarlaActor) return;
AActor* Actor = CarlaActor->GetActor();
auto Walker = Cast<APawn>(Actor);
if (!Walker) return;
AWalkerController *Controller = Cast<AWalkerController>(Walker->GetController());
if (!Controller) return;
// build bones structure
FWalkerBoneControlIn BonesIn;
for (const auto &Bone : WalkerBones.Bones)
{
FTransform Trans(FRotator::MakeFromEuler(Bone.Rotation), Bone.Location, FVector(1, 1, 1));
BonesIn.BoneTransforms.Add(Bone.Name, Trans);
}
// set the pose and blend
Controller->SetBonesTransform(BonesIn);
Controller->BlendPose(1.0f);
}
// replay finish
bool CarlaReplayerHelper::ProcessReplayerFinish(bool bApplyAutopilot, bool bIgnoreHero, std::unordered_map<uint32_t, bool> &IsHero)
{

View File

@ -64,6 +64,9 @@ public:
// set scene lights
void ProcessReplayerLightScene(CarlaRecorderLightScene LightScene);
// set walker bones
void ProcessReplayerWalkerBones(const CarlaRecorderWalkerBones &Walker);
// replay finish
bool ProcessReplayerFinish(bool bApplyAutopilot, bool bIgnoreHero, std::unordered_map<uint32_t, bool> &IsHero);