diff --git a/Content/Blueprint/RobotPawnActors/BP_mujokoSO_100.uasset b/Content/Blueprint/RobotPawnActors/BP_mujokoSO_100.uasset index a11657d3..b8c6bc78 100644 Binary files a/Content/Blueprint/RobotPawnActors/BP_mujokoSO_100.uasset and b/Content/Blueprint/RobotPawnActors/BP_mujokoSO_100.uasset differ diff --git a/Source/LuckyWorldV2/Private/Robot/PilotComponent/RobotPilotComponent.cpp b/Source/LuckyWorldV2/Private/Robot/PilotComponent/RobotPilotComponent.cpp new file mode 100644 index 00000000..2db3f0ca --- /dev/null +++ b/Source/LuckyWorldV2/Private/Robot/PilotComponent/RobotPilotComponent.cpp @@ -0,0 +1,41 @@ +#include "Robot/PilotComponent/RobotPilotComponent.h" + +#include "Actors/MujocoVolumeActor.h" +#include "Robot/RobotPawn.h" + +URobotPilotComponent::URobotPilotComponent() +{ + +} + +void URobotPilotComponent::BeginPlay() +{ + Super::BeginPlay(); + + // Reference owning robot + RobotOwner = Cast(GetOwner()); +} + +void URobotPilotComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, + FActorComponentTickFunction* ThisTickFunction) +{ + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); +} + +void URobotPilotComponent::InitPilotComponent() +{ + if (RobotOwner.IsValid() && RobotOwner->PhysicSceneProxy.IsValid()) + { + RobotOwner->PhysicSceneProxy->BindPostPhysicStepDelegate(this, &URobotPilotComponent::AnimateActuators); + } +} + +void URobotPilotComponent::StartAnimation(const FRobotActuators& NewAnimationTarget) +{ + AnimTargetRobotActuators = NewAnimationTarget; +} + +void URobotPilotComponent::AnimateActuators(float SimulationTime) +{ + // Override in each dedicated RobotPilotComponent +} diff --git a/Source/LuckyWorldV2/Private/Robot/PilotComponent/RobotPilotMultiRotorDrone.cpp b/Source/LuckyWorldV2/Private/Robot/PilotComponent/RobotPilotMultiRotorDrone.cpp new file mode 100644 index 00000000..78af2c80 --- /dev/null +++ b/Source/LuckyWorldV2/Private/Robot/PilotComponent/RobotPilotMultiRotorDrone.cpp @@ -0,0 +1,5 @@ +#include "Robot/PilotComponent/RobotPilotMultiRotorDrone.h" + +URobotPilotMultiRotorDrone::URobotPilotMultiRotorDrone() +{ +} diff --git a/Source/LuckyWorldV2/Private/Robot/PilotComponent/RobotPilotSO100Component.cpp b/Source/LuckyWorldV2/Private/Robot/PilotComponent/RobotPilotSO100Component.cpp new file mode 100644 index 00000000..e9fb3645 --- /dev/null +++ b/Source/LuckyWorldV2/Private/Robot/PilotComponent/RobotPilotSO100Component.cpp @@ -0,0 +1,22 @@ +#include "Robot/PilotComponent/RobotPilotSO100Component.h" + +URobotPilotSO100Component::URobotPilotSO100Component() +{ + +} + +void URobotPilotSO100Component::BeginPlay() +{ + Super::BeginPlay(); +} + +void URobotPilotSO100Component::TickComponent(float DeltaTime, enum ELevelTick TickType, + FActorComponentTickFunction* ThisTickFunction) +{ + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); +} + +void URobotPilotSO100Component::StartAnimation(const FRobotActuators& NewAnimationTarget) +{ + // Super::StartAnimation(NewAnimationTarget); +} diff --git a/Source/LuckyWorldV2/Private/Robot/RobotPawn.cpp b/Source/LuckyWorldV2/Private/Robot/RobotPawn.cpp new file mode 100644 index 00000000..2fbebec2 --- /dev/null +++ b/Source/LuckyWorldV2/Private/Robot/RobotPawn.cpp @@ -0,0 +1,68 @@ +#include "Robot/RobotPawn.h" + +#include "Robot/PilotComponent/RobotPilotMultiRotorDrone.h" +#include "Robot/PilotComponent/RobotPilotSO100Component.h" + +ARobotPawn::ARobotPawn() +{ +} + +void ARobotPawn::BeginPlay() +{ + Super::BeginPlay(); + InitRobot(); // TODO Maybe move to GameInstance to control when we initialize the robot completely +} + +void ARobotPawn::InitRobot() +{ + InitPilotComponent(); + // Other initialization tasks +} + +void ARobotPawn::InitPilotComponent() +{ + // Initialize pilot component based on robot type + switch (RobotType) + { + case ERobotsName::None: + break; + + case ERobotsName::SO100Robot: + RobotPilotComponent = NewObject(GetOwner()); + break; + + case ERobotsName::DJIDrone: + RobotPilotComponent = NewObject(GetOwner()); + break; + + case ERobotsName::Luck_e: + break; // TODO or remove from enum + case ERobotsName::Stretch: + break; // TODO or remove from enum + case ERobotsName::LuckyDrone: + break; // TODO or remove from enum + case ERobotsName::ArmLucky: + break; // TODO or remove from enum + case ERobotsName::UnitreeG1: + break; // TODO or remove from enum + case ERobotsName::StretchRobotV1: + break; // TODO or remove from enum + case ERobotsName::PandaArmRobot: + break; // TODO or remove from enum + case ERobotsName::PuralinkRobot: + break; // TODO or remove from enum + case ERobotsName::UnitreeGo2: + break; // TODO or remove from enum + case ERobotsName::RevoluteRobot: + break; // TODO or remove from enum + case ERobotsName::BostonSpotRobot: + break; // TODO or remove from enum + } + + // Register if this Robot has a Pilot Component + if (RobotPilotComponent) + { + RobotPilotComponent->RegisterComponent(); + RobotPilotComponent->InitPilotComponent(); + } +} diff --git a/Source/LuckyWorldV2/Public/Robot/PilotComponent/RobotPilotComponent.h b/Source/LuckyWorldV2/Public/Robot/PilotComponent/RobotPilotComponent.h new file mode 100644 index 00000000..fdebb7f1 --- /dev/null +++ b/Source/LuckyWorldV2/Public/Robot/PilotComponent/RobotPilotComponent.h @@ -0,0 +1,46 @@ +#pragma once +#include "CoreMinimal.h" +#include "RobotPilotComponent.generated.h" + +USTRUCT(BlueprintType) +struct FRobotActuators +{ + GENERATED_BODY() + // Do we need a prent struct? + // What will be in common? +}; + +class ARobotPawn; + +UCLASS(Blueprintable) +class LUCKYWORLDV2_API URobotPilotComponent : public UActorComponent + + +{ + GENERATED_BODY() + +public: + URobotPilotComponent(); + + virtual void BeginPlay() override; + virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; + virtual void InitPilotComponent(); + +private: + // Only to easy access within the component + TWeakObjectPtr RobotOwner = nullptr; + + // ---------------- + // ----- ANIM ----- + // ---------------- +public: + virtual void StartAnimation(const FRobotActuators& NewAnimationTarget); + +private: + virtual void AnimateActuators(float SimulationTime); // Bound to the PhysicProxy post-update delegate + float AnimationDuration = 0.f; + float AnimationStartTime = 0.f; + FRobotActuators CurrentRobotActuators; // This will be updated by the post-physic delegate + FRobotActuators AnimStartRobotActuators; + FRobotActuators AnimTargetRobotActuators; +}; diff --git a/Source/LuckyWorldV2/Public/Robot/PilotComponent/RobotPilotMultiRotorDrone.h b/Source/LuckyWorldV2/Public/Robot/PilotComponent/RobotPilotMultiRotorDrone.h new file mode 100644 index 00000000..3452ea19 --- /dev/null +++ b/Source/LuckyWorldV2/Public/Robot/PilotComponent/RobotPilotMultiRotorDrone.h @@ -0,0 +1,13 @@ +#pragma once +#include "CoreMinimal.h" +#include "Robot/PilotComponent/RobotPilotComponent.h" +#include "RobotPilotMultiRotorDrone.generated.h" + +UCLASS(Blueprintable) +class LUCKYWORLDV2_API URobotPilotMultiRotorDrone : public URobotPilotComponent +{ + GENERATED_BODY() + +public: + URobotPilotMultiRotorDrone(); +}; diff --git a/Source/LuckyWorldV2/Public/Robot/PilotComponent/RobotPilotSO100Component.h b/Source/LuckyWorldV2/Public/Robot/PilotComponent/RobotPilotSO100Component.h new file mode 100644 index 00000000..2859ea22 --- /dev/null +++ b/Source/LuckyWorldV2/Public/Robot/PilotComponent/RobotPilotSO100Component.h @@ -0,0 +1,50 @@ +#pragma once +#include "CoreMinimal.h" +#include "Robot/PilotComponent/RobotPilotComponent.h" +#include "RobotPilotSO100Component.generated.h" + +USTRUCT(BlueprintType) +struct FSo100Actuators : public FRobotActuators +{ + GENERATED_BODY() + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float Rotation = 0.f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float Pitch = 0.f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float Elbow = 0.f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float WristPitch = 0.f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float WristRoll = 0.f; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float Jaw = 0.f; +}; + +UCLASS(Blueprintable) +class LUCKYWORLDV2_API URobotPilotSO100Component : public URobotPilotComponent +{ + GENERATED_BODY() + + public: + URobotPilotSO100Component(); + + virtual void BeginPlay() override; + virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; + + UFUNCTION(BlueprintCallable) + virtual void StartAnimation(const FRobotActuators& NewAnimationTarget) override; + + // Here let's write the code trying to match with Constantin class + // After both classes have been designed around specific needs, see what can be migrated in the parent class and update both children + + // Tick where it can have targets + // Open Claw (ClawIndex) + // Presets to move certain joints into certain positions -> HardCode + // Move the arm myself JB + Capture LOG +}; diff --git a/Source/LuckyWorldV2/Public/Robot/RobotPawn.h b/Source/LuckyWorldV2/Public/Robot/RobotPawn.h new file mode 100644 index 00000000..93cf8a54 --- /dev/null +++ b/Source/LuckyWorldV2/Public/Robot/RobotPawn.h @@ -0,0 +1,37 @@ +#pragma once +#include "CoreMinimal.h" +#include "SharedDef.h" +#include "RobotPawn.generated.h" + +class AMujocoVolumeActor; +class URobotPilotComponent; + +// Enum of bots + +UCLASS(Blueprintable) +class LUCKYWORLDV2_API ARobotPawn : public APawn // Should be an actor? +{ + GENERATED_BODY() + +public: + ARobotPawn(); + + virtual void BeginPlay() override; + + // TODO Called by GameInstance after robot has been spawned + void InitRobot(); + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + ERobotsName RobotType = ERobotsName::None; // This value must be set in the pawn + + UPROPERTY(EditAnywhere, BlueprintReadWrite) // TODO Remove UPROPERTY once we migrate physics proxy initialization from Pawn + TWeakObjectPtr PhysicSceneProxy; + + // ------------------- + // ------ PILOT ------ + // ------------------- + UPROPERTY(EditAnywhere, BlueprintReadWrite) + URobotPilotComponent* RobotPilotComponent = nullptr; + UFUNCTION(BlueprintCallable) + void InitPilotComponent(); // This should have Robot type as parameter? +};